diff options
Diffstat (limited to 'user/emacs/init.el')
-rw-r--r-- | user/emacs/init.el | 306 |
1 files changed, 180 insertions, 126 deletions
diff --git a/user/emacs/init.el b/user/emacs/init.el index 22a9094e..bec96ede 100644 --- a/user/emacs/init.el +++ b/user/emacs/init.el @@ -1,7 +1,18 @@ ;;; init --- user init file -*- lexical-binding: t; -*- (eval '(setq inhibit-startup-echo-area-message "alan")) (defvar default-file-name-handler-alist file-name-handler-alist) -(setq file-name-handler-alist nil) +(setq file-name-handler-alist nil + gc-cons-threshold most-positive-fixnum + gc-cons-percentage 0.6 + read-process-output-max (* 4 1024 1024)) +(defun set-max-gc-cons () + (setq gc-cons-threshold most-positive-fixnum)) +(defun set-default-gc-cons () + (setq gc-cons-threshold (* 16 1024 1024) + gc-cons-percentage 0.1)) +(add-hook 'minibuffer-setup-hook #'set-max-gc-cons) +(add-hook 'minibuffer-exit-hook #'set-default-gc-cons) +(add-hook 'after-init-hook #'set-default-gc-cons) (defun restore-file-name-handler-alist () (setq file-name-handler-alist default-file-name-handler-alist)) @@ -27,7 +38,7 @@ (defmacro quietly (&rest body) `(let ((inhibit-message t)) - ,@body)) + ,@body)) (defun quiet (original-function &rest args) (quietly (apply original-function args))) @@ -104,10 +115,11 @@ (setq doom-modeline-buffer-file-name-style 'relative-from-project doom-modeline-buffer-encoding 'nondefault doom-modeline-buffer-modification-icon nil - doom-modeline-checker-simple-format t + doom-modeline-check-simple-format t doom-modeline-percent-position nil doom-modeline-project-detection 'project doom-modeline-vcs-max-length 24 + doom-modeline-env-version nil doom-modeline-height 28) (let ((foreground (face-attribute 'font-lock-comment-face :foreground))) (set-face-attribute 'doom-modeline-buffer-modified nil :foreground foreground)))) @@ -244,12 +256,14 @@ With two prefix arguments, write out the day and month name." read-buffer-completion-ignore-case t read-file-name-completion-ignore-case t completion-styles '(flex substring basic) - completion-category-defaults nil - completion-category-overrides '((file (styles basic partial-completion)))) + completion-category-overrides '((file (styles basic partial-completion)))) (use-package orderless :config (progn - (add-to-list 'completion-styles 'orderless))) + (add-to-list 'completion-styles 'orderless) + (setq orderless-matching-styles '(orderless-literal-prefix + orderless-prefixes + orderless-regexp)))) (use-package consult :general ([remap isearch-forward] #'consult-line @@ -435,9 +449,9 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve :after evil :defer 2 :config (progn - (add-hook 'js-ts-mode-hook (lambda () - (define-and-bind-quoted-text-object "slash" "/" "\\/" "\\/") - (push '(?\/ . ("/" . "/")) evil-surround-pairs-alist))) + (add-hook 'js-base-mode-hook (lambda () + (define-and-bind-quoted-text-object "slash" "/" "\\/" "\\/") + (push '(?\/ . ("/" . "/")) evil-surround-pairs-alist))) (add-hook 'emacs-lisp-mode-hook (lambda () (push '(?` . ("`" . "'")) evil-surround-pairs-alist))) (global-evil-surround-mode +1))) @@ -447,7 +461,7 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve :after evil-surround :ghook ('LaTex-mode-hook #'embrace-LaTeX-mode-hook) :ghook ('org-mode-hook #'embrace-org-mode-hook) - :ghook ('ruby-ts-mode-hook #'embrace-ruby-mode-hook) + :ghook ('ruby-base-mode-hook #'embrace-ruby-mode-hook) :ghook ('emacs-lisp-mode-hook #'embrace-emacs-lisp-mode-hook) :config (progn (setq evil-embrace-show-help-p nil) @@ -464,6 +478,12 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve :defer 2 :config (evil-commentary-mode +1)) +(use-package evil-lion + :after evil + :defer 10 + :config (progn + (evil-lion-mode +1))) + (use-package evil-matchit :after evil :defer 2 @@ -528,7 +548,9 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve corfu-auto-delay 0.1 corfu-auto-prefix 3 corfu-on-exact-match nil - corfu-preselect 'valid) + corfu-preview-current nil + corfu-preselect 'prompt + corfu-on-exact-match 'quit) (defun corfu-enable-in-minibuffer () "Enable Corfu in the minibuffer if `completion-at-point' is bound." (when (where-is-internal #'completion-at-point (list (current-local-map))) @@ -555,7 +577,9 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (use-package tabnine :config (progn (setq tabnine-binaries-folder "~/.local/tabnine") - (global-tabnine-mode) + (with-demoted-errors "TabNine error: %s" + (when (tabnine--executable-path) + (global-tabnine-mode))) (define-key tabnine-completion-map (kbd "TAB") #'tabnine-accept-completion) (define-key tabnine-completion-map (kbd "<tab>") #'tabnine-accept-completion) @@ -574,8 +598,10 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (add-hook 'kill-emacs-hook #'tabnine-kill-process))) (use-package tempel - :bind (("M-+" . tempel-complete) ;; Alternative tempel-expand - ("M-*" . tempel-insert)) + :general ("M-+" #'tempel-complete ;; Alternative tempel-expand + "M-*" #'tempel-insert + :keymaps 'tempel-mode-map + "<tab>" #'tempel-next) :config (progn (global-tempel-abbrev-mode +1))) @@ -623,6 +649,16 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (setq delete-by-moving-to-trash t) +(defun my/delete-file-and-buffer () + "Kill the current buffer and deletes the file it is visiting." + (interactive) + (let ((filename (buffer-file-name))) + (when filename + (when (y-or-n-p (format "Are you sure you want to delete %s? " filename)) + (delete-file filename delete-by-moving-to-trash) + (message "Deleted file %s" filename) + (kill-buffer))))) + (use-package goto-chg :defer 1) @@ -714,9 +750,9 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve ;;; Editing -(setq-default indent-tabs-mode nil - tab-width 2 - tab-always-indent 'complete) +(setq-default tab-always-indent 'complete + indent-tabs-mode nil + tab-width 4) (electric-pair-mode +1) @@ -737,22 +773,13 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve ;;; Major modes -(setq major-mode-remap-alist '((c-mode . c-ts-mode) - (c++-mode . c++-ts-mode) - (c-or-c++-mode . c-or-c++-ts-mode) - (cmake-mode . cmake-ts-mode) - (csharp-mode . csharp-ts-mode) - (dockerfile-mode . dockerfile-ts-mode) - (go-mode . go-ts-mode) - (java-mode . java-ts-mode) - (python-mode . python-ts-mode) - (ruby-mode . ruby-ts-mode) - (toml-mode . toml-ts-mode) - (yaml-mode . yaml-ts-mode))) +;;;; tree-sitter +(use-package treesit-auto + :config (progn + (global-treesit-auto-mode) + (treesit-auto-add-to-auto-mode-alist))) ;;;; golang -(with-eval-after-load 'go-ts-mode - (setq go-ts-mode-indent-offset tab-width)) (with-eval-after-load 'project (add-to-list 'project-vc-extra-root-markers "go.mod")) @@ -763,29 +790,10 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (add-to-list 'eglot-server-programs '(nim-mode "nimlsp")))) -;;;; rust -(use-package rustic - :mode (("\\.rs\\'" . rustic-mode)) - :if (package-installed-p 'rustic) - :config (progn - (setq rustic-format-on-save t) - (with-eval-after-load 'flycheck - (add-to-list 'flycheck-checkers 'rustic-clippy)))) -(add-to-list 'major-mode-remap-alist '(rust-mode . rust-ts-mode)) - ;;;; js -(setq js-indent-level 2 - js-enabled-frameworks '(javascript)) -(add-to-list 'major-mode-remap-alist '(js-mode . js-ts-mode)) -(add-to-list 'major-mode-remap-alist '(json-mode . json-ts-mode)) +(setq js-enabled-frameworks '(javascript)) ;;;; typescript -(use-package typescript-mode - :mode (("\\.tsx\\'" . tsx-ts-mode)) - :config (progn - (setq typescript-indent-level 2 - typescript-ts-mode-indent-offset 2))) -(add-to-list 'major-mode-remap-alist '(typescript-mode . typescript-ts-mode)) (use-package astro-ts-mode :mode (("\\.astro\\'" . astro-ts-mode))) @@ -805,8 +813,7 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (add-to-list 'auto-mode-alist '("\\.zsh\\'" . shell-script-mode)) (add-to-list 'auto-mode-alist '("zshenv\\'" . shell-script-mode)) (add-to-list 'auto-mode-alist '("zshrc\\'" . shell-script-mode)) -(setq sh-shell-file "/usr/bin/env zsh" - sh-basic-offset 2) +(setq sh-shell-file "/usr/bin/env zsh") (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on) @@ -818,16 +825,14 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve :config (progn (setq fish-enable-auto-indent t))) -;;;; make -(general-add-hook 'makefile-mode-hook - (lambda () - (setq-local indent-tabs-mode t))) - ;;;; nix (with-eval-after-load 'nix-mode (setq nix-mode-use-smie t nix-indent-function #'smie-indent-line)) +(use-package nix-ts-mode + :mode (("\\.nix\\'" . nix-ts-mode))) + (use-package nix-update :commands (nix-update-fetch)) @@ -844,6 +849,10 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (use-package gitignore-mode :mode ((".dockerignore\\'" . gitignore-mode))) +;;;; gitolite +(use-package gl-conf-mode + :defer t) + ;;;; lisps (use-package racket-mode @@ -858,11 +867,6 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve :ghook '(clojure-mode-hook emacs-lisp-mode-hook)) -(use-package lispy - :ghook '(emacs-lisp-mode-hook - clojure-mode-hook - racket-mode-hook)) - (use-package lispyville :ghook '(emacs-lisp-mode-hook clojure-mode-hook @@ -880,20 +884,15 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve ;;;; web modes (html) (use-package css-mode - :defer t - :config (progn - (setq css-indent-offset 2))) -(add-to-list 'major-mode-remap-alist '(css-mode . css-ts-mode)) + :defer t) (use-package web-mode - :mode (("\\.html?.erb\\'" . web-mode)) + :mode (("\\.html?.erb\\'" . web-mode) + ("\\.tmpl\\'" . web-mode)) :config (setq web-mode-enable-auto-pairing nil - web-mode-code-indent-offset 2 - web-mode-markup-indent-offset 2 - web-mode-css-indent-offset 2 web-mode-style-padding 2 web-mode-script-padding 2 - web-mode-engines-alist '(("go" . "\\.html?\\'")))) + web-mode-engines-alist '(("go" . "\\.tmpl\\'")))) (use-package emmet-mode :ghook '(web-mode-hook sgml-mode-hook)) @@ -948,21 +947,6 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (evil-ex-define-cmd "pb" #'project-switch-to-buffer) (evil-ex-define-cmd "psw[itch]" #'project-switch-project)))) -(use-package ibuffer-project - :config (progn - (defun ibuffer-project-set-filter-groups () - (setq ibuffer-filter-groups (ibuffer-project-generate-filter-groups)) - (unless (eq ibuffer-sorting-mode 'project-file-relative) - (ibuffer-do-sort-by-project-file-relative))) - (add-hook 'ibuffer-hook #'ibuffer-project-set-filter-groups) - (add-to-list 'ibuffer-project-root-functions '(file-remote-p . "Remote")) - (setq ibuffer-formats '((mark modified read-only locked " " - (name 18 18 :left :elide) - " " - (size 9 -1 :right) - " " - (mode 16 16 :left :elide) - " " project-file-relative))))) (use-package consult-ghq :defer 5 :general (:keymaps 'project-prefix-map @@ -974,13 +958,12 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (use-package envrc :defer 2 :config (progn + (setq envrc-show-summary-in-minibuffer nil) (envrc-global-mode))) (use-package magit :defer 5 :commands (magit-status magit-dispatch) - :init (progn - (customize-set-value 'magit-auto-revert-mode nil)) :general ([remap project-vc-dir] #'magit-project-status) (:keymaps 'project-prefix-map "m" #'magit-project-status) :init (progn @@ -988,7 +971,8 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (add-to-list 'project-switch-commands '(magit-project-status "Magit") t))) :config (progn (setq magit-section-visibility-indicator nil - magit-diff-refine-hunk 'all + magit-diff-refine-hunk t + magit-auto-revert-immediately t magit-display-buffer-function #'magit-display-buffer-fullcolumn-most-v1) (remove-hook 'magit-status-sections-hook 'magit-insert-tags-header) (remove-hook 'magit-section-highlight-hook 'magit-section-highlight) @@ -996,10 +980,6 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (remove-hook 'magit-section-highlight-hook 'magit-diff-highlight) (require 'magit-extras))) -(use-package magit-filenotify - :after magit - :ghook '(magit-status-mode-hook)) - (use-package git-gutter-fringe :defer 5 :config (progn @@ -1025,7 +1005,9 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (use-package editorconfig :defer 2 - :config (editorconfig-mode +1)) + :config (progn + (editorconfig-mode +1) + (setq editorconfig-lisp-use-default-indent t))) (setq-default ispell-dictionary "en_GB-ise-w_accents") (setq ispell-extra-args '("--sug-mode=ultra" "--camel-case")) @@ -1037,45 +1019,58 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve conf-mode-hook)) :general ([remap ispell-word] #'jinx-correct-word [remap evil-prev-flyspell-error] #'jinx-previous - [remap evil-next-flyspell-error] #'jinx-next)) + [remap evil-next-flyspell-error] #'jinx-next) + :config (progn + (advice-add 'jinx--load-dicts :after (lambda () + (unless jinx--dicts + (global-jinx-mode -1)))))) (use-package feature-mode :defer t :config (progn (setq feature-cucumber-command "cucumber-js {options} \"{feature}\""))) -(use-package treemacs - :defer t - :config (progn - (setq treemacs-no-png-images t))) +(defvaralias 'typescript-ts-mode-hook 'typescript-mode-hook) + +(defvaralias 'dockerfile-ts-mode-hook 'dockerfile-mode-hook) + +(defvaralias 'yaml-ts-mode-hook 'yaml-mode-hook) + +(defvaralias 'go-ts-mode-hook 'go-mode-hook) + +(defvaralias 'nix-ts-mode-hook 'nix-mode-hook) (use-package eglot :defer 3 :general (:states 'normal :keymaps 'eglot-mode-map - "gd" #'xref-find-definitions "gr" #'xref-find-references "C-t" #'xref-pop-marker-stack) - :ghook ('(typescript-ts-mode-hook - dockerfile-ts-mode-hook - yaml-ts-mode-hook - js-ts-mode-hook - css-ts-mode-hook - go-ts-mode-hook + :ghook ('(typescript-mode-hook + dockerfile-mode-hook + yaml-mode-hook + js-base-mode-hook + css-base-mode-hook lua-mode-hook nim-mode-hook - scss-mode-hook html-mode-hook nix-mode-hook + toml-ts-mode-hook haskell-mode-hook) #'eglot-ensure) :config (progn + (when (assoc 'nix-mode eglot-server-programs) + (setf (car (assoc 'nix-mode eglot-server-programs)) '(nix-mode nix-ts-mode))) + (nconc eglot-server-programs '((toml-ts-mode "taplo" "lsp" "stdio"))) + (advice-add 'eglot--message :before-while (lambda (formatstring &rest rest) + (s-starts-with-p "Connected!" formatstring))) (defun my/setup-eglot-eldoc () (push 'flymake-eldoc-function eldoc-documentation-functions)) (add-hook 'eglot-managed-mode-hook 'my/setup-eglot-eldoc) (setq-default eglot-workspace-configuration - '(:yaml (:keyOrdering nil) - :nix (:autoArchive t)) - eglot-ignored-server-capabilities '(:documentHighlightProvider)) + '( :yaml (:keyOrdering nil) + :nix (:autoArchive t) + :gopls ( :staticcheck t + :usePlaceholders t))) (defun my/eglot-capf () (setq-local completion-at-point-functions (list (cape-capf-super @@ -1093,40 +1088,99 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve :commands (consult-eglot-symbols) :after eglot) +(use-package lsp-mode + :defer 3 + :ghook ('(go-mode-hook) + #'lsp-deferred) + ('lsp-mode-hook #'lsp-enable-which-key-integration) + ('lsp-completion-mode-hook #'my/lsp-mode-setup-completion) + :general (:states 'normal :keymaps 'lsp-mode-map + "gr" #'xref-find-references + "C-t" #'xref-pop-marker-stack) + :config (progn + (setq lsp-auto-guess-root t + lsp-auto-execute-action nil + lsp-headerline-breadcrumb-enable nil + lsp-enable-suggest-server-download nil + lsp-completion-provider :none ; value `:capf' is actually for company :( + lsp-diagnostics-provider t ; this means prefer flymake over flycheck, why‽ + ) + + (defun my/lsp-mode-setup-completion () + (setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults)) + '(flex))) + + (lsp-register-custom-settings + '(("golangci-lint.command" + ["golangci-lint" "run" "--out-format" "json" "--issues-exit-code=1"]))) + + (lsp-register-client + (make-lsp-client :new-connection (lsp-stdio-connection + '("golangci-lint-langserver")) + :activation-fn (lsp-activate-on "go") + :language-id "go" + :priority 0 + :server-id 'golangci-lint + :add-on? t + :library-folders-fn #'lsp-go--library-default-directories + :initialization-options (lambda () + (gethash "golangci-lint" + (lsp-configuration-section "golangci-lint"))))))) + +(use-package yasnippet + :after lsp-mode + :ghook ('lsp-completion-mode-hook #'yas-minor-mode)) + +(defun my/ls-rename () + (interactive) + (if lsp-mode + (call-interactively #'lsp-rename) + (call-interactively #'eglot-rename))) + ;; Inside a javascript project, it's common to install tools locally to ;; the project. This will allows emacs to find their executables. (use-package add-node-modules-path :config (setq add-node-modules-max-depth 6) - :ghook ('(feature-mode-hook js2-mode-hook json-ts-mode-hook typescript-ts-mode-hook) #'add-node-modules-path)) + :ghook ('(feature-mode-hook + js-base-mode-hook + json-ts-mode-hook + typescript-ts-mode-hook) + #'add-node-modules-path)) ;;;; Reformat on save (use-package format-all :defer 10 - :ghook ('(clojure-mode-hook - dockerfile-ts-mode-hook - emacs-lisp-mode-hook - json-ts-mode-hook - markdown-mode-hook - sql-mode-hook - toml-mode-hook)) + :ghook ('prog-mode-hook) :gfhook #'format-all-ensure-formatter :init (progn (advice-add 'format-all-ensure-formatter :around #'quiet) (defun turn-off-format-all-mode () - (format-all-mode -1))) + (when (bound-and-true-p format-all-mode) + (format-all-mode -1)))) :config (progn - (setq format-all-show-errors 'never))) + (setq format-all-show-errors nil))) (use-package apheleia - :defer 10 + :defer 11 ; load after format-all for hook ordering? + :ghook 'prog-mode-hook :config (progn (setf (alist-get 'shfmt apheleia-formatters) '("shfmt")) - (setf (alist-get 'nixfmt apheleia-formatters) - '("nixpkgs-fmt")) + (setq apheleia-formatters + (append apheleia-formatters '((nixpkgs-fmt "nixpkgs-fmt") + (golines "golines") + (prettier-gotmpl + "prettier" "--stdin-filepath" filepath + "--parser=go-template" (apheleia-formatters-indent "--use-tabs" "--tab-width"))))) + (setf (alist-get 'go-ts-mode apheleia-mode-alist) + '(golines) + (alist-get 'web-mode apheleia-mode-alist) + '(prettier-gotmpl)) + (setq apheleia-mode-alist (append apheleia-mode-alist '((nix-ts-mode . nixpkgs-fmt) + (nix-mode . nixpkgs-fmt)))) (add-hook 'apheleia-mode-hook #'turn-off-format-all-mode)) :init (progn (apheleia-global-mode +1))) @@ -1141,6 +1195,7 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve "x" '(:keymap ctl-x-map) "c" (general-simulate-key "C-c") "j" #'consult-eglot-symbols + "r" #'my/ls-rename "q" #'evil-delete-buffer "p" '(:keymap project-prefix-map :package project) "v" #'split-window-right @@ -1157,7 +1212,7 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve "fs" #'save-buffer "ff" #'find-file "fw" #'write-file - "fd" #'delete-file + "fd" #'my/delete-file-and-buffer "fr" #'crux-rename-file-and-buffer "gs" #'magit-status "gm" #'vc-msg-show @@ -1169,7 +1224,6 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve "go" #'git-gutter:revert-hunk "gt" #'git-timemachine "gl" #'magit-log-buffer-file - "bi" #'ibuffer "bz" #'bury-buffer "iu" #'insert-char "xe" #'eval-last-sexp |