;;; init.el --- Modern Emacs configuration -*- lexical-binding: t -*-
;;; Commentary:
;; Core initialization and package management
;;; Code:
;; Fix home dir when it is a symlink (and other directories)
;; Always resolve symlinks in file buffers
(add-hook 'find-file-hook
(lambda ()
(when buffer-file-name
(setq default-directory
(file-name-directory (file-truename buffer-file-name))))))
;; Canonicalize home directory on startup
(setq default-directory (file-truename default-directory))
;; Performance and startup optimizations
(setq gc-cons-threshold 100000000) ; 100mb
(setq gc-cons-percentage 0.6)
(add-hook 'focus-out-hook #'garbage-collect)
(setq read-process-output-max (* 1024 1024)) ; 1mb
(setq process-adaptive-read-buffering nil) ; Disable adaptive buffering
;; File handling
;; You already have create-lockfiles nil and backup settings, so skip those
;; Display optimizations
(setq bidi-inhibit-bpa t) ; Disable bidirectional parenthesis
(setq-default bidi-paragraph-direction 'left) ; Disable bidirectional rendering
(setq bidi-display-reordering nil) ; Disable reordering of bidirectional text
(setq inhibit-compacting-font-caches t) ; Don't compact font caches during GC
;; Terminal responsiveness and scrolling behavior
(setq redisplay-skip-fontification-on-input t)
(setq fast-but-imprecise-scrolling t)
(setq echo-keystrokes 0.01)
(setq scroll-conservatively 101)
(setq scroll-margin 0)
(setq scroll-preserve-screen-position nil)
(setq auto-window-vscroll nil)
;; Minibuffer optimizations (add to your existing completion settings)
(setq enable-recursive-minibuffers t)
(setq read-buffer-completion-ignore-case t)
(setq read-file-name-completion-ignore-case t)
(setq completions-detailed t)
;; Basic UI settings without use-package
(menu-bar-mode -1)
(when (fboundp 'tool-bar-mode)
(tool-bar-mode -1))
(when (fboundp 'scroll-bar-mode)
(scroll-bar-mode -1))
(delete-selection-mode t)
(save-place-mode t)
;; Basic settings that don't need use-package
(setq inhibit-startup-screen t
use-dialog-box nil
frame-title-format '("Emacs: %f")
icon-title-format "Emacs - %b"
case-fold-search t
column-number-mode t
create-lockfiles nil
indent-tabs-mode nil
standard-indent 4
large-file-warning-threshold nil)
;; Package setup
(require 'package)
(setq package-archives
'(("gnu" . "https://elpa.gnu.org/packages/")
("melpa" . "https://melpa.org/packages/")
("nongnu" . "https://elpa.nongnu.org/nongnu/")))
(setq package-enable-at-startup nil)
(package-initialize)
;; Built-in use-package and bind-key
(require 'use-package)
(require 'bind-key)
;; Diminish for clean mode line (must load before any :diminish usage)
(use-package diminish
:ensure t)
;; Direct Emacs Custom writes to a separate file, away from init.el
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(load custom-file 'noerror)
;; Helper macro for conditional library loading
(defmacro with-library (symbol &rest body)
`(when (require ,symbol nil t)
,@body))
(put 'with-library 'lisp-indent-function 1)
;; UTF-8 configuration
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(setenv "LANG" "en_US.UTF-8")
;; Path setup
(defvar home-dir (expand-file-name "~"))
(let ((my-paths (list
"/usr/local/go/bin"
"/opt/homebrew/bin"
(concat home-dir "/bin")
(concat home-dir "/python/bin"))))
(dolist (path my-paths)
(add-to-list 'exec-path path)
(setenv "PATH" (concat path path-separator (getenv "PATH")))))
;; Backup settings
(use-package files
:defer 5
:custom
(backup-by-copying t)
(backup-directory-alist '(("." . "~/.emacs.d/autosaves/")))
(delete-old-versions t)
(kept-new-versions 6)
(kept-old-versions 3))
(use-package exec-path-from-shell
:ensure t
:config
(when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize)))
;; Default simple settings
(setq-default tab-width 4)
(setopt use-short-answers t)
;; Load the rest of the configuration
(add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
(load "ui-config")
(load "dev-config")
(load "org-config")
(load "shell-config")
(load "keybindings")
;; trying to catch when this changes
(add-variable-watcher 'indent-tabs-mode
(lambda (symbol newval operation where)
(message "indent-tabs-mode changed to %s in buffer %s by %s"
newval
(buffer-name where)
operation)))
(provide 'init)
;;; init.el ends here