;; -*- lexical-binding: t -*- ;;; UI customization ;;; (column-number-mode) (electric-pair-mode) (global-so-long-mode) (menu-bar-mode -1) (scroll-bar-mode -1) (show-paren-mode) (tool-bar-mode -1) (setq frame-title-format "%b — Emacs") (setq uniquify-buffer-name-style 'forward) (setq-default truncate-lines t) (load-theme 'monokai t) ;; <102 or >109 will make Ioveska look squished rather than tall, ;; narrow, and beautiful. (set-face-attribute 'default nil :height 104) ;; Disabling bidirectional text will make Emacs less slow with very ;; long lines. (setq bidi-paragraph-direction 'left-to-right) (setq bidi-inhibit-bpa t) ;;; Utility functions ;;; ;; Set an environment variable value for a single buffer. (defun setenv-local (variable &optional value substitute-env-vars) ;; If process-environment is the global one, make a copy of it. (when (eq process-environment (default-value 'process-environment)) (make-local-variable 'process-environment) (setq process-environment (mapcar 'concat process-environment))) (setenv variable value substitute-env-vars)) (defun enable-ansi-color () (setenv-local "TERM" "dumb-emacs-ansi")) ;;; Major modes ;;; (add-to-list 'auto-mode-alist '("\\.adoc\\'" . adoc-mode)) (add-to-list 'auto-mode-alist '("\\.quirks\\'" . conf-unix-mode)) (add-to-list 'auto-mode-alist '("\\.tmac\\'" . nroff-mode)) (add-to-list 'auto-mode-alist '("/Cargo.lock\\'" . toml-mode)) ;;; CC Mode ;;; (with-eval-after-load 'cc-styles ;; Default to kernel style. (add-to-list 'c-default-style '(other . "linux"))) ;;; Comint ;;; ;; This relies on an Emacs patch to apply to async-shell-command. (setq comint-terminfo-terminal "dumb-emacs-ansi") ;;; Diff Mode ;;; ;; Unbind M-DEL from scroll-down-command, so it does the same thing as ;; in the rest of Emacs (backward-kill-word). (with-eval-after-load 'diff-mode (define-key diff-mode-map (kbd "M-DEL") nil)) ;;; Dired ;;; (with-eval-after-load 'dired (setq dired-listing-switches (combine-and-quote-strings `(,dired-listing-switches "-h")))) ;;; Direnv ;;; (direnv-mode) (global-set-key (kbd "C-c d") 'direnv-update-environment) ;;; Ediff ;;; ;; Don't make a new frame for Ediff controls. (setq ediff-window-setup-function 'ediff-setup-windows-plain) ;;; Eglot ;;; (with-eval-after-load 'eglot ;; Override default LSPs for languages. (add-to-list 'eglot-server-programs '(rust-mode "rust-analyzer")) (add-to-list 'eglot-server-programs '((c++-mode c-mode) "clangd"))) ;;; Environment ;;; ;; Provide a way to turn paging back on for modes like terminal emulators. (let ((pager (getenv "PAGER"))) (defun enable-pager () (setenv-local "PAGER" pager))) ;; Set PAGER to the empty string, which Git and journalctl will ;; interpret as an explicit opt-out of paging. (setenv "PAGER" "") ;;; Eshell ;;; (add-hook 'eshell-mode-hook #'enable-ansi-color) ;;; Ibuffer ;;; ;; Open ibuffer in other window, to match behaviour of the default ;; list-buffers. (global-set-key (kbd "C-x C-b") (lambda () (interactive) (ibuffer t))) ;;; ispell ;;; ;; System locale is Esperanto, but I write in English much more, and ;; spelling in Esperanto is easy anyway. ;) (setq ispell-dictionary "english") ;;; Magit ;;; (setq magit-delete-by-moving-to-trash delete-by-moving-to-trash) (setq magit-repository-directories `((,(expand-file-name "~/src") . 1))) (global-set-key (kbd "C-x g") 'magit-status) (global-set-key (kbd "C-x M-g") 'magit-dispatch) (with-eval-after-load "magit" ;; Add a --no-gpg-sign option to Magit. This is only useful with ;; commit.gpgsign=true. It would be nice if commit.gpgsign=true just ;; meant that Magit showed the --gpg-sign option as enabled by ;; default, and disabling it would make Magit pass --no-gpg-sign to ;; git, but that's not currently the case, so we need a seperate ;; option for --no-gpg-sign. See ;; . (dolist (command '(magit-commit magit-merge magit-cherry-pick magit-revert magit-am magit-rebase)) (transient-append-suffix command ["-S"] '("=S" "Don't sign using gpg" "--no-gpg-sign")))) ;;; Man ;;; ;; Open man pages in the current window. I don't really care what ;; happens when I do M-x man, but I don't want my whole frame to be ;; taken over with man buffers if I'm following a bunch of ;; cross-references. (setq Man-notify-method 'pushy) ;;; Rainbow Delimiters ;;; (add-hook 'prog-mode-hook #'rainbow-delimiters-mode) ;;; Revert buffers ;;; (global-set-key (kbd "C-c r") 'revert-buffer) ;;; Rust ;;; ;; Indent with spaces in Rust code. (add-hook 'rust-mode-hook (lambda () (setq indent-tabs-mode nil))) (with-eval-after-load 'rust-mode ;; Cargo keybindings (define-key rust-mode-map (kbd "C-c c b") 'rust-compile) (define-key rust-mode-map (kbd "C-c c c") 'rust-check) (define-key rust-mode-map (kbd "C-c c r") 'rust-run) (define-key rust-mode-map (kbd "C-c c t") 'rust-test)) ;;; save-some-buffers ;;; ;; Allow reverting buffers directly from the "Save file ...?" message. (add-to-list 'save-some-buffers-action-alist `(?r ,(lambda (buf) (with-current-buffer buf (revert-buffer t t))) ,(purecopy "revert this buffer"))) ;;; sendmail ;;; ;; Use the system "sendmail" program to send mail. (setq send-mail-function 'sendmail-send-it) ;;; Term ;;; (add-hook 'term-mode-hook #'enable-pager) ;;; Transient ;;; ;; Make all Magit options available, even those that are disabled by ;; default because they're too obscure. (setq transient-default-level 7) ;;; with-editor ;;; (add-hook 'eshell-mode-hook 'with-editor-export-editor) (add-hook 'shell-mode-hook 'with-editor-export-editor) (add-hook 'term-exec-hook 'with-editor-export-editor)