diff --git a/emacs.d/init.el b/emacs.d/init.el index 36b6cca..a9a3946 100644 --- a/emacs.d/init.el +++ b/emacs.d/init.el @@ -1,4 +1,4 @@ -;; Disable package.el early so it won't start loading packages before init is loaded +; Disable package.el early so it won't start loading packages before init is loaded (setq package-enable-at-startup nil) ;; No thanks @@ -14,8 +14,8 @@ ;; Visible bell (setq visible-bell t) -; Font -(set-face-attribute 'default nil :font "Hack" :height 110) +; Font - Does nothing if mixed-pitch package is used +;(set-face-attribute 'default nil :font "ibm plex mono light" :height 100) ;; Make ESC quit prompts (global-set-key (kbd "") 'keyboard-escape-quit) @@ -50,18 +50,18 @@ (global-set-key (kbd "S-C-") 'shrink-window) (global-set-key (kbd "S-C-") 'enlarge-window) -;; Improve scrolling -(setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) ; one line at a time -(setq mouse-wheel-progressive-speed nil) ; don't accelerate scrolling -(setq mouse-wheel-follow-mouse 't) ; scroll window under mouse -(setq scroll-step 1) ; keyboard scroll one line at a time +;; scrolling +(setq mouse-wheel-scroll-amount '(4 ((shift) . 1))) ; 1: lines to scroll, 2: while holding shift +(setq mouse-wheel-progressive-speed nil) ; acceleration +(setq mouse-wheel-follow-mouse 't) ; scroll window under cursor +(setq scroll-step 1) ; keyboard scrolling ;; Tabs (setq-default indent-tabs-mode nil) (setq-default tab-width 4) (setq indent-line-function 'insert-tab) -;;Line numbers +;; Line numbers (setq column-number-mode t) (dolist (mode '(text-mode-hook prog-mode-hook @@ -72,10 +72,6 @@ (setq-default fill-column 80) (add-hook 'prog-mode-hook #'display-fill-column-indicator-mode) -; No line numbers in org-mode -(dolist (mode '(org-mode-hook)) - (add-hook mode (lambda () (display-line-numbers-mode 0)))) - ;; Install and load straight.el (defvar bootstrap-version) (let ((bootstrap-file @@ -124,17 +120,13 @@ ;; (use-package everforest ;; :straight (:type git :repo "https://git.sr.ht/~theorytoe/everforest-theme")) -;; (use-package gruvbox-theme -;; :config -;; (load-theme 'gruvbox-dark-soft t)) - (add-to-list 'custom-theme-load-path "~/.cache/emacs/custom/everforest-theme") (load-theme 'everforest-hard-dark t) ;; Help distinguish work buffers from others like sidebars and terminal -(use-package solaire-mode - :init - (solaire-global-mode t)) +;; (use-package solaire-mode +;; :init +;; (solaire-global-mode t)) ;; Icons (use-package all-the-icons) @@ -178,66 +170,254 @@ :config (setq which-key-idle-delay 0.3)) -;; Navigation: Ivy/Counsel/Swiper -(use-package ivy +;; Save history over restarts +(use-package savehist :init - (ivy-mode 1) - :config - (setq ivy-use-virtual-buffers t) - (setq ivy-wrap t) - (setq ivy-count-format "(%d/%d) ") + (savehist-mode)) + +;; Completion with vertico/consult + +(use-package vertico + :init + (vertico-mode) + + ;; Different scroll margin + ;; (set vertico-scroll-margin 0) + + ;; Show more candidates + ;; (setq vertico-count 20) + + ;; Grow and shrink the Vertico minibuffer + ;; (setq vertico-resize t) + + ;; Optionally enable cycling for `vertico-next' and `vertico-previous'. + ;; (setq vertico-cycle t) + ) + +(use-package emacs + :init + ;; Add prompt indicator to `completing-read-multiple'. + (defun crm-indicator (args) + (cons (format "[CRM%s] %s" + (replace-regexp-in-string + "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" + crm-separator) + (car args)) + (cdr args))) + (advice-add #'completing-read-multiple :filter-args #'crm-indicator) + ;; Do not allow the cursor in the minibuffer prompt + (setq minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) + ;; Emacs 28: Hide commands in M-x which do not work in the current mode. + ;; Vertico commands are hidden in normal buffers. + (setq read-extended-command-predicate + #'command-completion-default-include-p) (setq enable-recursive-minibuffers t)) -(use-package ivy-rich - :after ivy - :hook (counsel-mode . ivy-rich-mode) +(use-package consult + :bind (;; C-c bindings (mode-specific-map) + ("C-c h" . consult-history) + ("C-c m" . consult-mode-command) + ("C-c k" . consult-kmacro) + ;; C-x bindings (ctl-x-map) + ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("C-x b" . consult-buffer) ;; orig. switch-to-buffer + ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("C-x r b" . consult-bookmark) ;; orig. bookmark-jump + ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + (" a" . consult-apropos) ;; orig. apropos-command + ;; M-g bindings (goto-map) + ("M-g e" . consult-compile-error) + ;; ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck + ("M-g f" . consult-flycheck) + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ("M-g m" . consult-mark) + ("M-g k" . consult-global-mark) + ("M-g i" . consult-imenu) + ("M-g I" . consult-imenu-multi) + ;; M-s bindings (search-map) + ("M-s d" . consult-find) + ("M-s D" . consult-locate) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s r" . consult-ripgrep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s m" . consult-multi-occur) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch + ;; Minibuffer history + :map minibuffer-local-map + ("M-s" . consult-history) ;; orig. next-matching-history-element + ("M-r" . consult-history)) ;; orig. previous-matching-history-element + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. + :hook (completion-list-mode . consult-preview-at-point-mode) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Optionally configure the register formatting. This improves the register + ;; preview for `consult-register', `consult-register-load', + ;; `consult-register-store' and the Emacs built-ins. + (setq register-preview-delay 0.5 + register-preview-function #'consult-register-format) + + ;; Optionally tweak the register preview window. + ;; This adds thin lines, sorting and hides the mode line of the window. + (advice-add #'register-preview :override #'consult-register-window) + + ;; Use Consult to select xref locations with preview + (setq xref-show-xrefs-function #'consult-xref + xref-show-definitions-function #'consult-xref) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. :config - (setq ivy-rich-parse-remote-buffer nil)) -(use-package counsel - :after ivy - :config - (counsel-mode 1) - (setq ivy-initial-inputs-alist nil)) + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + (setq consult-preview-key (kbd "M-.")) + ;; (setq consult-preview-key (list (kbd "") (kbd ""))) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-theme :preview-key '(:debounce 0.2 any) + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + consult--source-bookmark consult--source-file-register + consult--source-recent-file consult--source-project-recent-file + ;; :preview-key (kbd "M-.") + :preview-key '(:debounce 0.4 any)) -(use-package swiper - :after ivy - :bind (("C-s" . swiper))) + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; (kbd "C-+") -(use-package treemacs - :bind - (:map global-map - ("M-0" . treemacs-select-window) - ("C-x t 1" . treemacs-delete-other-windows) - ("C-x t t" . treemacs) - ("C-x t B" . treemacs-bookmark) - ("C-x t C-t" . treemacs-find-file) - ("C-x t M-t" . treemacs-find-tag))) + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) -(use-package lsp-treemacs - :config - (lsp-treemacs-sync-mode 1)) + ;; By default `consult-project-function' uses `project-root' from project.el. + ;; Optionally configure a different project root function. + ;; There are multiple reasonable alternatives to chose from. + ;;;; 1. project.el (the default) + ;; (setq consult-project-function #'consult--default-project--function) + ;;;; 2. projectile.el (projectile-project-root) + ;; (autoload 'projectile-project-root "projectile") + ;; (setq consult-project-function (lambda (_) (projectile-project-root))) + ;;;; 3. vc.el (vc-root-dir) + ;; (setq consult-project-function (lambda (_) (vc-root-dir))) + ;;;; 4. locate-dominating-file + ;; (setq consult-project-function (lambda (_) (locate-dominating-file "." ".git"))) + ) -;; Git +(use-package consult-flycheck) -(use-package magit - :bind ("C-M-;" . magit-status) - :commands (magit-status magit-get-current-branch) +(use-package consult-git-log-grep :custom - (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) + (consult-git-log-grep-open-function #'magit-show-commit)) -;; Project management +(use-package consult-company + :bind + (:map company-mode-map + ([remap completion-at-point] . consult-company))) -(use-package projectile - :init - (projectile-mode +1) - :bind-keymap - (("C-M-p" . projectile-find-file) - ("C-c p" . projectile-command-map)) - :bind (:map projectile-mode-map - ("C-c p" . projectile-command-map))) +(use-package consult-lsp + :bind + (:map lsp-mode-map + ([remap xref-find-apropos] . consult-lsp-symbols))) -;; LSP & debugging +;; (use-package consult-projectile) + +(use-package consult-yasnippet) + +;; Alternate completion style + +(use-package orderless + :init + ;; Configure a custom style dispatcher (see the Consult wiki) + ;; (setq orderless-style-dispatchers '(+orderless-dispatch) + ;; orderless-component-separator #'orderless-escapable-split-on-space) + (setq completion-styles '(orderless basic) + completion-category-defaults nil + completion-category-overrides '((file (styles partial-completion))))) + +;; Contextual actions + +(use-package marginalia + :config + (marginalia-mode)) + +(use-package embark + :bind + (("C-." . embark-act) ;; pick some comfortable binding + ("C-;" . embark-dwim) ;; good alternative: M-. + ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings' + :init + ;; Optionally replace the key help with a completing-read interface + (setq prefix-help-command #'embark-prefix-help-command) + :config + ;; Hide the mode line of the Embark live/completions buffers + (add-to-list 'display-buffer-alist + '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" + nil + (window-parameters (mode-line-format . none))))) + +(use-package embark-consult + :hook + (embark-collect-mode . consult-preview-at-point-mode)) + +;; Org-mode + +; No line numbers in org-mode +(dolist (mode '(org-mode-hook)) + (add-hook mode (lambda () (display-line-numbers-mode 0)))) + +(setq org-startup-indented t ; Indentation + org-pretty-entities t ; Rich text/Special chars + org-hide-emphasis-markers t ; Hide markup - see org-appear + org-startup-with-inline-images t ; Image previews + org-image-actual-width '(300)) + +(use-package org-appear + :hook (org-mode . org-appear-mode)) + +(use-package mixed-pitch + :hook + (text-mode . mixed-pitch-mode) + :config + (set-face-attribute 'default nil :font "IBM Plex Mono Light" :height 105) + (set-face-attribute 'fixed-pitch nil :font "IBM Plex Mono Light") + (set-face-attribute 'variable-pitch nil :font "DejaVu Sans")) +;(add-hook 'mixed-pitch-mode-hook #'solaire-mode-reset) + +(use-package org-superstar + :hook + (org-mode . org-superstar-mode) + :config + (setq org-superstar-special-todo-items t)) + +;; LSP (use-package lsp-mode :init @@ -257,8 +437,20 @@ (web-mode . lsp) (zig-mode . lsp) (lsp-mode . lsp-enable-which-key-integration)) + :custom + (lsp-eldoc-render-all t) + (lsp-idle-delay 0.6) + ;; (lsp-rust-analyzer-cargo-watch-command "clippy") + ;; (lsp-rust-analyzer-server-display-inlay-hints t) + ;; (lsp-rust-analyzer-display-lifetime-elision-hints-enable "skip_trivial") + ;; (lsp-rust-analyzer-display-chaining-hints t) + ;; (lsp-rust-analyzer-display-lifetime-elision-hints-use-parameter-names nil) + ;; (lsp-rust-analyzer-display-closure-return-type-hints t) + ;; (lsp-rust-analyzer-display-parameter-hints nil) + ;; (lsp-rust-analyzer-display-reborrow-hints nil) :config - (setq lsp-prefer-flymake nil)) ;prefer lsp-ui (flycheck) to flymake + (setq lsp-prefer-flymake nil)) ; prefer lsp-ui (flycheck) to flymake +; (setq lsp-disabled-clients '(clangd))) ; prefer ccls to clangd ; :bind ; (:map lsp-mode-map ; ("TAB" . completion-at-point))) @@ -273,7 +465,7 @@ (setq lsp-ui-doc-position 'bottom-and-right) (setq lsp-ui-doc-include-signature t) (setq lsp-ui-sideline-enable t) - (setq lsp-ui-sideline-show-hover nil) + (setq lsp-ui-sideline-show-hover t) (setq lsp-ui-flycheck-enable t) (setq lsp-ui-flycheck-list-position 'right) (setq lsp-ui-flycheck-live-reporting t) @@ -282,28 +474,13 @@ (setq lsp-ui-peek-peek-height 25) (lsp-ui-doc-show)) -(use-package dap-mode - :after lsp-mode - :commands dap-debug - :config - (dap-ui-mode 1) - (dap-tooltip-mode 1) - (eval-when-compile - (require 'cl-lib)) - (require 'dap-python) - ;(require 'dap-node) - (require 'dap-lldb) - :bind - (:map dap-mode-map - ("" . dap-debug) - ("" . dap-next) - ("" . dap-step-in) - ("S-" . dap-disconnect) - ("C-S-" . dap-debug-restart))) + +;; Text completion (use-package company :config (global-company-mode 1) + (setq company-global-modes '(not gud-mode)) :custom (company-idle-delay 0) (company-minimum-prefix-length 1) @@ -317,6 +494,67 @@ ("C-n" . company-select-next) ("C-p" . company-select-previous))) +;; Debugging + +(use-package dap-mode + :after lsp-mode + :commands dap-debug + :config + (dap-ui-mode 1) + (dap-tooltip-mode 1) + (eval-when-compile + (require 'cl-lib)) + (require 'dap-python) + ;(require 'dap-node) + (require 'dap-lldb) + (require 'dap-gdb-lldb) + (dap-gdb-lldb-setup) + (dap-register-debug-template + "Rust :: LLDB Run Configuration" + (list :type "lldb" + :request "launch" + :name "LLDB::Run" + :gdbpath "rust-lldb")) + :bind + (:map dap-mode-map + ("" . dap-debug) + ("" . dap-next) + ("" . dap-step-in) + ("S-" . dap-disconnect) + ("C-S-" . dap-debug-restart))) + +(use-package realgud) + +(use-package realgud-lldb) + +;; Treemacs +(use-package treemacs + :bind + (:map global-map + ("M-0" . treemacs-select-window) + ("C-x t 1" . treemacs-delete-other-windows) + ("C-x t t" . treemacs) + ("C-x t B" . treemacs-bookmark) + ("C-x t C-t" . treemacs-find-file) + ("C-x t M-t" . treemacs-find-tag))) + +(use-package lsp-treemacs + :config + (lsp-treemacs-sync-mode 1)) + +;; Syntax checking +(use-package flycheck + :hook (lsp-mode . flycheck-mode) + :config + (setq flycheck-python-flake8-executable "flake8")) + +;; Git +(use-package magit + :bind ("C-M-;" . magit-status) + :commands (magit-status magit-get-current-branch) + :custom + (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) + ;;; Languages/Tools ;; Highlighting/Formatting @@ -339,13 +577,13 @@ (setq-default c-default-style "k&r") (setq-default c-basic-offset 2) -;(use-package ccls -; :hook ((c-mode c++-mode objc-mode cuda-mode) . -; (lambda () (require 'ccls) (lsp)))) +;; (use-package ccls +;; :hook ((c-mode c++-mode objc-mode cuda-mode) . +;; (lambda () (require 'ccls) (lsp)))) ;(use-package modern-cpp-font-lock ; :config - ; (modern-c++-font-lock-global-mode)) +; (modern-c++-font-lock-global-mode)) ;; Golang @@ -359,35 +597,35 @@ ;; JavaScript/TypeScript, HTML, CSS -;; (setq css-indent-level 2) -;; (setq css-indent-offset 2) -;; (setq js-indent-level 2) +(setq css-indent-level 2) +(setq css-indent-offset 2) +(setq js-indent-level 2) -;; (add-to-list 'auto-mode-alist '("\\.mjs\\'" . js-mode)) +(add-to-list 'auto-mode-alist '("\\.mjs\\'" . js-mode)) -;; (use-package js2-mode -;; :config -;; (add-to-list 'interpreter-mode-alist '("#!/usr/bin/env node" . js2-mode)) -;; ;(setq js2-strict-missing-semi-warning t) -;; (setq js2-mode-show-strict-warnings t) -;; :hook (js-mode . js2-minor-mode)) +(use-package js2-mode + :config + (add-to-list 'interpreter-mode-alist '("#!/usr/bin/env node" . js2-mode)) + ;(setq js2-strict-missing-semi-warning t) + (setq js2-mode-show-strict-warnings t) + :hook (js-mode . js2-minor-mode)) -;; (use-package typescript-mode -;; :config -;; (setq typescript-indent-level 2) -;; :mode ("\\.ts\\'" . typescript-mode) -;; ("\\.tsx\\'" . typescript-mode)) +(use-package typescript-mode + :config + (setq typescript-indent-level 2) + :mode ("\\.ts\\'" . typescript-mode) + ("\\.tsx\\'" . typescript-mode)) ;; (use-package restclient ;; :init ;; (use-package company-restclient) ;; :mode ("\\.http\\'" . restclient-mode)) -;; (use-package rainbow-mode -;; :hook -;; ((js-mode . rainbow-mode) -;; (typescript-mode . rainbow-mode) -;; (web-mode . rainbow-mode))) +(use-package rainbow-mode + :hook + ((js-mode . rainbow-mode) + (typescript-mode . rainbow-mode) + (web-mode . rainbow-mode))) ;; (use-package skewer-mode ;; :init @@ -404,25 +642,25 @@ ;; (use-package simple-httpd) -;; (use-package web-mode -;; :config -;; (setq web-mode-code-indent-offset 2) -;; (setq web-mode-markup-indent-offset 2) -;; (setq web-mode-attribute-indent-offset 2) -;; :mode -;; (("\\.phtml\\'" . web-mode) -;; ("\\.tpl\\.php\\'" . web-mode) -;; ("\\.jsp\\'" . web-mode) -;; ("\\.as[cp]x\\'" . web-mode) -;; ("\\.erb\\'" . web-mode) -;; ("\\.mustache\\'" . web-mode) -;; ("\\.djhtml\\'" . web-mode) -;; ("\\.jst.ejs\\'" . web-mode) -;; ("\\.html?\\'" . web-mode))) +(use-package web-mode + :config + (setq web-mode-code-indent-offset 2) + (setq web-mode-markup-indent-offset 2) + (setq web-mode-attribute-indent-offset 2) + :mode + (("\\.phtml\\'" . web-mode) + ("\\.tpl\\.php\\'" . web-mode) + ("\\.jsp\\'" . web-mode) + ("\\.as[cp]x\\'" . web-mode) + ("\\.erb\\'" . web-mode) + ("\\.mustache\\'" . web-mode) + ("\\.djhtml\\'" . web-mode) + ("\\.jst.ejs\\'" . web-mode) + ("\\.html?\\'" . web-mode))) -;; (use-package jsdoc -;; :straight (jsdoc :type git :host github :repo "isamert/jsdoc.el") -;; :bind ("C-c C-n" . jsdoc)) +(use-package jsdoc + :straight (jsdoc :type git :host github :repo "isamert/jsdoc.el") + :bind ("C-c C-n" . jsdoc)) ;; LaTeX @@ -464,7 +702,41 @@ ;; Rust -;(use-package rust-mode) +(use-package rustic + :ensure + :bind (:map rustic-mode-map + ("M-j" . lsp-ui-imenu) + ("M-?" . lsp-find-references) + ("C-c C-c l" . flycheck-list-errors) + ("C-c C-c a" . lsp-execute-code-action) + ("C-c C-c r" . lsp-rename) + ("C-c C-c q" . lsp-workspace-restart) + ("C-c C-c Q" . lsp-workspace-shutdown) + ("C-c C-c s" . lsp-rust-analyzer-status) + ("C-c C-c e" . lsp-rust-analyzer-expand-macro) + ("C-c C-c d" . dap-hydra) + ("C-c C-c h" . lsp-ui-doc-glance))) + :config + ;; uncomment for less flashiness + ;; (setq lsp-eldoc-hook nil) + ;; (setq lsp-enable-symbol-highlighting nil) + ;; (setq lsp-signature-auto-activate nil) + + ;; comment to disable rustfmt on save +;; (add-hook 'rustic-mode-hook 'rk/rustic-mode-hook)) + +;; (defun rk/rustic-mode-hook () +;; ;; so that run C-c C-c C-r works without having to confirm, but don't try to +;; ;; save rust buffers that are not file visiting. Once +;; ;; https://github.com/brotzeit/rustic/issues/253 has been resolved this should +;; ;; no longer be necessary. +;; (when buffer-file-name +;; (setq-local buffer-save-without-query t)) +;; (add-hook 'before-save-hook 'lsp-format-buffer nil t)) + +;; TOML config files + +(use-package toml-mode) ;; Zig @@ -477,12 +749,6 @@ ; :major-modes '(zig-mode) ; :server-id 'zls)) -;; Syntax checking -(use-package flycheck - :hook (lsp-mode . flycheck-mode) - :config - (setq flycheck-python-flake8-executable "flake8")) - ;; Templating (use-package yasnippet :bind