;;;; post-init.el --- Init -*- no-byte-compile: t; lexical-binding: t; -*- (add-to-list 'exec-path "~/.local/bin") (add-to-list 'exec-path "~/bin") (setq tls-checktrust t) (setq gnutls-verify-error t) (setq tab-always-indent 'complete) (setq completion-cycle-threshold 3) ; Always show candidates in menu-bar-lines (keymap-global-set " " #'ibuffer-list-buffers) ;;(setq-default search-whitespace-regexp ".*") (delete-selection-mode t) ; make typing override text selection (setq bookmark-save-flag t case-fold-search t clean-buffer-list-delay-general t dabrev-case-fold-search t file-name-shadow-mode 1 help-window-select t ns-use-native-fullscreen nil save-abbrevs 'silent save-interprogram-paste-before-kill t select-active-regions t set-mark-command-repeat-pop t tooltip-delay 1.5 tooltip-use-echo-area t view-read-only t) ;; (electric-indent-mode -1) ;;(setq next-error-message-highlight t) ;;(setq recenter-positions '(top middle bottom)) ;;(setq visual-line-fringe-indicators '(left-curly-arrow right-curly-arrow)) (setq tab-bar-show nil) (auto-compression-mode t) (global-subword-mode t) (global-so-long-mode t) (global-hl-line-mode -1) (setq display-line-numbers-type 'relative) (setq display-line-numbers-grow-only t) (global-display-line-numbers-mode 1) (when (fboundp 'winner-mode) (winner-mode 1)) ;; show line numbers on the left side of a window (pending-delete-mode t) ;;(toggle-save-place-globally 1) (transient-mark-mode t) (setq password-cache t password-cache-expiry 3600) (setq mode-require-final-newline 'visit-save) (defvar sys-tools "/opt") (if (eq system-type 'windows-nt) (setq sys-tools "c:\\utils")) (setq auth-sources '((:source "~/.emacs.d/.authinfo.gpg"))) (require 'semantic/db-file) (setq custom-file null-device) ;; TODO (advice-add 'jsonrpc--log-event :override #'ignore) (add-hook 'before-save-hook 'whitespace-cleanup) (use-package diminish :ensure t :config (diminish 'lisp-interaction-mode " iElisp") (diminish 'emacs-lisp-mode " Εlisp") (diminish 'word-wrap-mode "Щ") (diminish 'eldoc-mode)) (use-package general :ensure t) (use-package which-key :ensure t :demand t :diminish :custom (which-key-sort-order 'which-key-prefix-then-key-order) (which-key-add-column-padding 2) (which-key-popup-type 'side-window) (which-key-max-display-columns nil) (which-key-separator " ") :config (which-key-mode) (which-key-setup-minibuffer)) (use-package xdg :ensure nil :config (let ((backup-dir (expand-file-name "emacs/backup/" (xdg-data-home))) (autosave-dir (expand-file-name "emacs/autosave/" (xdg-cache-home)))) (mkdir backup-dir t) (mkdir autosave-dir t) (setq backup-directory-alist `(("." . ,backup-dir))) (setq tramp-backup-directory-alist backup-directory-alist) (setq auto-save-file-name-transforms `((".*" ,autosave-dir t)))) (setq tramp-auto-save-directory (expand-file-name "tramp-autosave/" (xdg-cache-home))) ;;(setq custom-file (expand-file-name "emacs/custom.el" (xdg-data-home))) (setq auto-save-list-file-prefix (expand-file-name "emacs/auto-save-list/.saves-" (xdg-cache-home))) (setq url-history-file (expand-file-name "emacs/url/history" (xdg-data-home))) (setq save-place-file (expand-file-name "saveplace" (xdg-data-home)))) ;;(setq-default line-spacing 0.12) ;(set-face-attribute 'default nil :family "0xProto" :height 130) ;(set-face-attribute 'fixed-pitch nil :family "0xProto" :height 130) ;(set-face-attribute 'fixed-pitch-serif nil :family "0xProto" :height 130) ;(set-face-attribute 'variable-pitch nil :family "0xProto" :height 130) (set-face-attribute 'default nil :family "MonaspiceNe Nerd Font Mono" :height 130) (set-face-attribute 'variable-pitch nil :family "MonaspiceRn Nerd Font Propo" :height 130) (set-face-attribute 'fixed-pitch nil :family "MonaspiceAr Nerd Font Propo" :height 130) (set-face-attribute 'fixed-pitch-serif nil :family "MonaspiceXe Nerd Font" :height 130) ;;(set-face-attribute 'variable-pitch nil :family "Monaspace Radon" :height 130) ;;(set-face-attribute 'fixed-pitch nil :family "Monaspace Argon" :height 130) ;;(set-face-attribute 'fixed-pitch-serif nil :family "Monaspace Xenon" :height 130) (use-package mixed-pitch :after org :hook (org-mode . mixed-pitch-mode)) (use-package all-the-icons :ensure t :defer t :config (defun unpackaged/disable-all-the-icons () "Disable all-the-icons." (all-the-icons-dired-mode 0)) (defun unpackaged/restore-all-the-icons () "Restore all-the-icons." (all-the-icons-dired-mode 1)) (advice-add 'wdired-change-to-wdired-mode :before #'unpackaged/disable-all-the-icons) (advice-add 'wdired-finish-edit :after #'unpackaged/restore-all-the-icons) (advice-add 'wdired-abort-changes :after #'unpackaged/restore-all-the-icons)) (use-package all-the-icons-completion :after (marginalia all-the-icons) :hook (marginalia-mode . all-the-icons-completion-marginalia-setup) :init (all-the-icons-completion-mode)) (use-package all-the-icons-nerd-fonts :after all-the-icons :config (all-the-icons-nerd-fonts-prefer)) (use-package telephone-line :demand t :ensure t :config (setq telephone-line-primary-left-separator 'telephone-line-gradient telephone-line-secondary-left-separator 'telephone-line-nil telephone-line-primary-right-separator 'telephone-line-gradient telephone-line-secondary-right-separator 'telephone-line-nil) (setq telephone-line-height 28 telephone-line-evil-use-short-tag t) (setq telephone-line-lhs '((evil . (telephone-line-evil-tag-segment)) (accent . (telephone-line-major-mode-segment telephone-line-process-segment)) (nil . (telephone-line-project-segment)) (nil . (telephone-line-buffer-segment)))) (setq telephone-line-rhs '((nil . (telephone-line-flymake-segment telephone-line-misc-info-segment)) (evil . (telephone-line-vc-segment )))) (telephone-line-mode t)) (use-package modus-themes :ensure t :defer t :config (setq modus-themes-italic-constructs t modus-themes-bold-constructs t modus-themes-mixed-fonts t modus-themes-subtle-line-numbers nil modus-themes-deuteranopia t modus-themes-tabs-accented nil modus-themes-variable-pitch-ui t modus-themes-inhibit-reload t) (setq modus-themes-fringes 'intense) (setq modus-themes-lang-checkers '(straight-underline text-also)) ;(setq modus-themes-mode-line '(borderless (padding . 4) (height . 1.1))) (setq modus-themes-markup '(background italic intense)) (setq modus-themes-syntax '(yellow-comments green-strings alt-syntax)) (setq modus-themes-hl-line '(accented)) (setq modus-themes-paren-match '(bold intense)) (setq modus-themes-links '(neutral-underline background)) (setq modus-themes-prompts '(intense bold background)) (setq modus-themes-completions '((matches . (extrabold)) (selection . (semibold accented)) (popup . (accented intense)))) (setq modus-themes-mail-citations nil) (setq modus-themes-region '(accented bg-only no-extend)) (setq modus-themes-diffs 'desaturated) (setq modus-themes-org-blocks 'gray-background) (setq modus-themes-org-agenda '((header-block . (variable-pitch 1.3)) (header-date . (grayscale workaholic bold-today 1.1)) (event . (accented varied)) (scheduled . uniform) (habit . traffic-light))) (setq modus-themes-headings '((0 . (variable-pitch rainbow 1.9)) (1 . (variable-pitch rainbow 1.8)) (2 . (variable-pitch rainbow 1.7)) (3 . (variable-pitch rainbow bold 1.6)) (t . (variable-pitch semilight 1.1)))) (setq modus-themes-scale-headings nil) ;;(modus-themes-load-themes) ;;(modus-themes-load-vivendi) ;;(modus-themes-load-operandi) ) (use-package ef-themes :ensure t :defer t :general (private/set-leader-keys "Tn" '(ef-themes-select-dark :wk "night") "Td" '(ef-themes-select-light :wk "day")) :config (setq ef-themes-region '('intense no-extend neutral)) (setq ef-themes-headings ; read the manual's entry or the doc string '((0 . (variable-pitch light 1.9)) (1 . (variable-pitch light 1.8)) (2 . (variable-pitch light 1.7)) (3 . (variable-pitch semilight 1.6)) (4 . (variable-pitch semilight 1.5)) (5 . (variable-pitch regular 1.4)) (6 . (variable-pitch regular 1.3)) (7 . (variable-pitch 1.2)) ; absence of weight means `bold' (agenda-date . (semilight 1.5)) (agenda-structure . (variable-pitch light 1.9)) (t . (variable-pitch 1.1)))) (setq ef-themes-mixed-font t ef-themes-variable-pitch-ui t) (defun my-ef-themes-custom-faces () (modify-all-frames-parameters `((right-divider-width . 1) ;(internal-border-width . 1) (scroll-bar-width . 0))) (ef-themes-with-colors (custom-set-faces `(aw-leading-char-face ((,c :height 3.5))) `(header-line ((,c :box (:line-width 6 :color ,bg-main :style nil)))) `(header-line-highlight ((,c :box (:color ,bg-main)))) ;;`(mode-line ((,c :box (:line-width 0 :color ,bg-main :style nil)))) ;;`(mode-line-active ((,c :box (:line-width 0 :color ,bg-main :style nil)))) ;;`(mode-line-highlight ((,c :box (:line-width 0 :color ,bg-main)))) ;;`(mode-line-inactive ((,c :box (:line-width 0 :color ,bg-main :style nil)))) `(fringe ((t :background ,bg-main))) `(window-divider ((,c :background ,bg-main :foreground ,bg-main))) `(window-divider-first-pixel ((,c :background ,bg-main :foreground ,bg-main))) `(window-divider-last-pixel ((,c :background ,bg-main :foreground ,bg-main))) `(ocaml-help-face ((,c :foreground ,comment))) `(ocaml-link-face ((,c :foreground ,link :background ,bg-main))) `(peek-overlay-content-face ((,c :background ,bg-main)))))) ;;(set-face-foreground 'window-divider-first-pixel (face-attribute 'default :foreground)) ;;(set-face-foreground 'window-divider-last-pixel (face-attribute 'default :foreground)) (add-hook 'ef-themes-post-load-hook #'my-ef-themes-custom-faces) ;(add-to-list 'ef-themes-collection 'ef-monokai-pro) ;(add-to-list 'ef-themes-dark-themes 'ef-monokai-pro) ) (with-eval-after-load 'ef-themes (put 'ef-monokai-pro 'theme-properties (list :background-mode 'dark :kind 'color-scheme :family 'ef)) (add-to-list 'ef-themes-collection 'ef-monokai-pro) (add-to-list 'ef-themes-dark-themes 'ef-monokai-pro) ) (with-eval-after-load 'ef-themes (put 'ef-catppuccin-mocha 'theme-properties (list :background-mode 'dark :kind 'color-scheme :family 'ef)) (add-to-list 'ef-themes-collection 'ef-catppuccin-mocha) (add-to-list 'ef-themes-dark-themes 'ef-catppuccin-mocha) ) (with-eval-after-load 'ef-themes (put 'ef-catppuccin-macchiatto 'theme-properties (list :background-mode 'dark :kind 'color-scheme :family 'ef)) (add-to-list 'ef-themes-collection 'ef-catppuccin-macchiatto) (add-to-list 'ef-themes-dark-themes 'ef-catppuccin-macchiatto) (add-to-list 'ef-themes-light-themes 'ef-catppuccin-macchiatto)) (with-eval-after-load 'ef-themes (put 'ef-catppuccin-frappe 'theme-properties (list :background-mode 'dark :kind 'color-scheme :family 'ef)) (add-to-list 'ef-themes-collection 'ef-catppuccin-frappe) (add-to-list 'ef-themes-dark-themes 'ef-catppuccin-frappe) ) (with-eval-after-load 'ef-themes (put 'ef-catppuccin-latte 'theme-properties (list :background-mode 'light :kind 'color-scheme :family 'ef)) (add-to-list 'ef-themes-collection 'ef-catppuccin-latte) (add-to-list 'ef-themes-light-themes 'ef-catppuccin-latte) ) (ef-themes-select 'ef-dream) ;;(ef-themes-select 'ef-catppuccin-macchiatto) ;;(ef-themes-select 'ef-catppuccin-mocha) ;;(ef-themes-select 'ef-catppuccin-frappe) ;;(ef-themes-select 'ef-catppuccin-latte) (use-package general :ensure t :commands (private/set-leader-keys) :demand t :config (general-evil-setup t) (general-def [f5] #'compile [f6] #'recompile) (general-create-definer private/set-leader-keys :states '(normal insert visual emacs) :prefix "SPC" :global-prefix "C-SPC") (general-def "C-h W" 'which-key-show-top-level) (general-def "M-o" #'other-window "M-O" #'tab-bar-switch-to-recent-tab) (private/set-leader-keys "f" '(:ignore t :which-key "find") "s" '(:ignore t :which-key "search") "x" '(:ignore t :which-key "application") "b" '(:ignore t :which-key "buffers") "bw" '(:ignore t :which-key "windows") "c" '(:ignore t :which-key "code") "e" '(:ignore t :which-key "edit") "ee" '(:ignore t :which-key "encoding") "h" '(:ignore t :which-key "help") "g" '(:ignore t :which-key "go to") "m" '(:ignore t :which-key "bookmark") "r" '(:ignore t :which-key "register")) (private/set-leader-keys "" #'tab-switch "-" #'dired-jump) (private/set-leader-keys "hf" 'describe-function "hf" 'describe-function "hb" 'describe-bindings "hv" 'describe-variable "ha" 'apropos "hk" 'describe-key "hm" 'describe-mode "hd" 'apropos-documentation) (private/set-leader-keys "!" #'shell-command "xq" #'restart-emacs "xp" #'list-processes "xP" #'proced "xk" #'package-list-packages "B" 'ibuffer "bR" 'read-only-mode "bwu" 'winner-undo "bwr" 'winner-redo "bx" 'kill-buffer "bX" 'kill-buffer-and-window "e SPC" 'whitespace-cleanup "eg" 'mark-whole-buffer "r SPC" 'point-to-register "rj" 'jump-to-register "rw" 'window-configuration-to-register "Tf" 'toggle-frame-fullscreen "Tm" 'toggle-frame-maximized "Tt" 'text-scale-adjust)) ;; evil-want-keybinding must be declared before Evil and Evil Collection (setq evil-want-keybinding nil) (use-package evil :ensure t :demand t :init (setq evil-want-integration t) (setq evil-want-keybinding nil) :diminish evil-escape-mode :custom (evil-want-C-u-scroll t) ;;(evil-want-C-d-scroll t) ;(evil-want-C-i-jump t) (evil-want-C-h-delete t) (evil-want-Y-yank-to-eol t) (evil-respect-visual-line-mode t) (evil-want-fine-undo t) (evil-kill-on-visual-paste nil) (evil-auto-balance-windows t) (evil-auto-indent t) ;; Move back the cursor one position when exiting insert mode (evil-move-cursor-back nil) (evil-move-beyond-eol nil) :general (general-def "C-M-u" #'universal-argument) ;(general-def "" 'keyboard-escape-quit) (general-imap "C-g" #'evil-normal-state) ;; exit out of a transient with escape (general-def :keymaps 'transient-map "" #'transient-quit-one) ;;(general-def :keymaps 'evil-ex-search-keymap "" 'keyboard-escape-quit) ;;(general-def :keymaps 'evil-ex-search-keymap "C-g" 'keyboard-escape-quit) ;;(general-imap "C-h" 'evil-delete-backward-char-and-join) ;;(general-mmap "j" 'evil-next-visual-line) ;;(general-mmap "k" 'evil-previous-visual-line) (general-mmap "zn" #'narrow-to-defun) (general-vmap "zn" #'narrow-to-region) (general-mmap "zw" #'widen) (general-nmap "-" #'dired-jump) (:keymaps 'evil-ex-map "wq" 'unpackaged/save-and-kill-buffer "tp" 'tab-previous "tn" 'tab-next) (:keymaps 'evil-window-map "f" #'tab-bar-new-tab) ;; Use visual line motions even outside of visual-line-mode buffers (general-mmap "j" 'evil-next-visual-line "k" 'evil-previous-visual-line) (private/set-leader-keys "" #'evil-ex-nohighlight "u" 'universal-argument "w" '(evil-window-map :which-key "window") "S" '(evil-write-all :which-key "save all") "`" 'evil-switch-to-windows-last-buffer) (general-vmap :prefix "SPC" "y" (general-simulate-key "\"+y" :state 'visual) "P" (general-simulate-key "\"_dP" :state 'visual) "d" (general-simulate-key "\"_d" :state 'visual)) (general-nmap :prefix "SPC" "y" (general-simulate-key "\"+y" :state 'normal) "Y" (general-simulate-key "\"+Y" :state 'normal) "d" (general-simulate-key "\"_d" :state 'normal)) :config (evil-set-undo-system 'undo-redo) (evil-set-initial-state 'eat-mode 'insert) ;; this mirrors the minibuffer in nvim better escape should exit the minibuffer (add-hook 'minibuffer-mode-hook (lambda () (evil-local-set-key 'insert (kbd "") 'keyboard-escape-quit) (evil-local-set-key 'normal (kbd "") 'keyboard-escape-quit))) (defun sjb/evil-scroll-line-to-center (&rest _) (evil-scroll-line-to-center nil)) (advice-add 'evil-search-next :after #'sjb/evil-scroll-line-to-center) (advice-add 'evil-search-previous :after #'sjb/evil-scroll-line-to-center) (advice-add 'evil-scroll-down :after #'sjb/evil-scroll-line-to-center) (advice-add 'evil-scroll-up :after #'sjb/evil-scroll-line-to-center) (defalias #'forward-evil-word #'forward-evil-symbol) ;; make evil-search-word look for symbol rather than word boundaries (setq evil-symbol-word-search t) (evil-define-operator my-evil-comment-or-uncomment (beg end) "Toggle comment for the region between BEG and END." (interactive "") (comment-or-uncomment-region beg end)) (evil-define-key 'normal 'global (kbd "gc") 'my-evil-comment-or-uncomment) (defun unpackaged/save-and-kill-buffer () (interactive) (save-buffer) (kill-this-buffer)) (setq org-fold-core-style 'overlays) (evil-mode +1) ;; Make evil serch more like vim (evil-select-search-module 'evil-search-module 'evil-search) (setq search-invisible 'open)) (use-package evil-collection :ensure t :after evil :hook ((eshell-first-time-mode . evil-collection-eshell-setup) (after-init . evil-collection-init)) :custom (evil-collection-outline-bind-tab-p t) (evil-collection-setup-minibuffer t) (forge-add-default-bindings nil) (evil-collection-magit-use-z-for-folds nil) :general ;;(general-def :keymaps 'evil-window-map "d" 'evil-window-delete) ;;(general-def :keymaps 'evil-window-map "=" 'balance-windows-area) (private/set-leader-keys "'" '(evil-collection-consult-mark :wk "list mark")) :config (with-eval-after-load 'dired (evil-collection-define-key 'normal 'dired-mode-map "h" 'dired-single-up-directory "l" 'dired-single-buffer) (evil-collection-define-key 'normal 'dired-mode-map "i" 'wdired-change-to-wdired-mode "gF" 'multi-dired-find-file "C-o" 'dired-find-file-below)) (with-eval-after-load 'mu4e (evil-collection-define-key 'motion 'mu4e-view-mode-map "go" 'mu4e-view-go-to-url "gO" 'mu4e-view-go-to-url-gui)) (with-eval-after-load 'epa (evil-collection-define-key 'normal 'epa-key-list-mode-map "m" 'epa-mark-key "u" 'epa-unmark-key))) (use-package evil-matchit :ensure t :defer 1 :hook (after-init . global-evil-matchit-mode) :after evil) (use-package evil-surround :ensure t :defer t :commands global-evil-surround-mode :hook (after-init . global-evil-surround-mode) :after evil) (use-package evil-multiedit :ensure t :after evil :defer t :custom (evil-multiedit-use-symbols 1) :general (general-evil-define-key 'normal 'global (kbd "M-d") #'evil-multiedit-match-symbol-and-next (kbd "M-D") #'evil-multiedit-match-symbol-and-prev) (general-evil-define-key 'visual 'global "R" #'evil-multiedit-match-all (kbd "M-d") #'evil-multiedit-match-and-next (kbd "M-D") #'evil-multiedit-match-and-prev) (general-evil-define-key '(visual normal) 'global (kbd "C-M-d") #'evil-multiedit-restore) (general-evil-define-key 'multiedit 'global (kbd "M-d") #'evil-multiedit-match-and-next (kbd "M-S-d") #'evil-multiedit-match-and-prev (kbd "RET") #'evil-multiedit-toggle-or-restrict-region) (general-evil-define-key '(multiedit multiedit-insert) 'global (kbd "C-n") #'evil-multiedit-next (kbd "C-p") #'evil-multiedit-prev)) (use-package evil-textobj-tree-sitter :vc (evil-textobj-tree-sitter :url "https://github.com/meain/evil-textobj-tree-sitter.git" :branch "auto-update-queries") :ensure t :defer t :general (:keymaps 'evil-outer-text-objects-map "a" (evil-textobj-tree-sitter-get-textobj "parameter.outer") "b" (evil-textobj-tree-sitter-get-textobj "block.outer") "c" (evil-textobj-tree-sitter-get-textobj "class.outer") "f" (evil-textobj-tree-sitter-get-textobj "function.outer") "l" (evil-textobj-tree-sitter-get-textobj ("conditional.outer" "loop.outer")) "#" (evil-textobj-tree-sitter-get-textobj "comment.outer") "=" (evil-textobj-tree-sitter-get-textobj "assignment.outer") "m" (evil-textobj-tree-sitter-get-textobj "import" '((python-ts-mode . [(import_statement) @import]) (rust-ts-mode . [(use_declaration) @import])))) (:keymaps 'evil-inner-text-objects-map "a" (evil-textobj-tree-sitter-get-textobj "parameter.inner") "b" (evil-textobj-tree-sitter-get-textobj "block.inner") "c" (evil-textobj-tree-sitter-get-textobj "class.inner") "f" (evil-textobj-tree-sitter-get-textobj "function.inner") "l" (evil-textobj-tree-sitter-get-textobj ("conditional.inner" "loop.inner")) "#" (evil-textobj-tree-sitter-get-textobj "comment.inner")) (general-nmap "]m" '((lambda () (interactive) (evil-textobj-tree-sitter-goto-textobj "function.outer")) :wk "function") "[m" '((lambda () (interactive) (evil-textobj-tree-sitter-goto-textobj "function.outer" t)) :wk "function") "]M" '((lambda () (interactive) (evil-textobj-tree-sitter-goto-textobj "function.outer" nil t)) :wk "function") "[M" '((lambda () (interactive) (evil-textobj-tree-sitter-goto-textobj "function.outer" t t)) :wk "function") "]a" '((lambda () (interactive) (evil-textobj-tree-sitter-goto-textobj "parameter.outer")) :wk "param") "[a" '((lambda () (interactive) (evil-textobj-tree-sitter-goto-textobj "parameter.outer" t)) :wk "param") "]A" '((lambda () (interactive) (evil-textobj-tree-sitter-goto-textobj "parameter.outer" nil t)) :wk "param") "[A" '((lambda () (interactive) (evil-textobj-tree-sitter-goto-textobj "parameter.outer" t t)) :wk "param")) ) (use-package evil-visualstar :after evil :ensure t :defer t :commands global-evil-visualstar-mode :hook (after-init . global-evil-visualstar-mode)) (use-package exato :defer t :ensure t) (use-package vdiff :ensure t :defer t :commands (vdiff-buffers vdiff-buffers3 vdiff-quit vdiff-files vdiff-files3) :custom (vdiff-auto-refine t) (vdiff-only-highlight-refinements t)) (use-package fido-vertical-mode :ensure nil :defer t :hook (after-init . fido-vertical-mode)) (use-package cape ;; Bind dedicated completion commands :ensure t :defer t :commands (cape-dabbrev cape-file cape-keyword cape-sgml cape-elisp-block) :general ("C-c p" '(:keymap cape-prefix-map :wk "cape")) (private/set-leader-keys "k" '(:ignore t :which-key "cape") "kp" 'completion-at-point "kt" 'complete-tag "kd" 'cape-dabbrev "kf" 'cape-file "kk" 'cape-keyword "ks" 'cape-symbol "ka" 'cape-abbrev "kl" 'cape-line "kw" 'cape-dict "k\\" 'cape-tex "k>" 'cape-sml "kr" 'cape-rfc1345) :init ;; Add `completion-at-point-functions', used by `completion-at-point'. (add-to-list 'completion-at-point-functions #'cape-file) (add-to-list 'completion-at-point-functions #'cape-dabbrev) (add-to-list 'completion-at-point-functions #'cape-keyword) (add-to-list 'completion-at-point-functions #'cape-sgml) (add-to-list 'completion-at-point-functions #'cape-elisp-block) ;;(add-to-list 'completion-at-point-functions #'cape-rfc1345) ;;(add-to-list 'completion-at-point-functions #'cape-abbrev) ;;(add-to-list 'completion-at-point-functions #'cape-ispell) ;;(add-to-list 'completion-at-point-functions #'cape-dict) ;;(add-to-list 'completion-at-point-functions #'cape-symbol) ;;(add-to-list 'completion-at-point-functions #'cape-line) ;; Silence then pcomplete capf, no errors or messages! (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent) ;; Ensure that pcomplete does not write to the buffer ;; and behaves as a pure `completion-at-point-function'. (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify) ) (defun my/ignore-elisp-keywords (cand) (or (not (keywordp cand)) (eq (char-after (car completion-in-region--data)) ?:))) (defun my/setup-elisp () (setq-local completion-at-point-functions (list (cape-capf-super (cape-capf-predicate #'elisp-completion-at-point #'my/ignore-elisp-keywords) #'cape-dabbrev #'cape-file)) cape-dabbrev-min-length 5)) (add-hook 'emacs-lisp-mode-hook #'my/setup-elisp) (use-package consult :ensure t :demand t :commands (sjb-embark-preview) :hook (completion-list-mode . consult-preview-at-point-mode) :general ;;(general-nmap "/" 'consult-isearch) ("C-S-s" 'consult-line-multi "C-c h" 'consult-history "C-c m" 'consult-mode-command "C-c b" 'consult-bookmark "C-c k" 'consult-kmacrO "C-x M-:" 'consult-complex-command "C-x b" 'consult-buffer "C-x 4 b" 'consult-buffer-other-window "C-x 5 b" 'consult-buffer-other-frame "M-#" 'consult-register-load "M-'" 'consult-register-store "C-M-#" 'consult-register) ;; Other custom bindings ("M-y" 'consult-yank-pop) ;; orig. yank-pop (general-nmap "g:" #'consult-goto-line) (general-def :keymaps 'minibuffer-local-map "C-;" #'sjb-embark-preview) (general-def :keymaps '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) ;; required by consult-line to detect isearch (private/set-leader-keys "I" '(consult-imenu-multi :wk "find workspace symbols") "i" '(consult-imenu :wk "find symbols") "sb" '(consult-bookmark :wk "find bookmark") "se" '(consult-compile-error :wk "find compiler error") "sl" '(consult-line :wk "search line") "sh" '(consult-org-heading :wk "search heading") "sm" '(consult-mark :wk "mark") "sr" '(consult-ripgrep :wk "grep") "sG" '(consult-git-grep :wk "git grep") "sK" '(consult-keep-lines :wk "keep lines") "sL" '(consult-focus-lines :wk "focus lines") "sM" '(consult-global-mark :wk "global mark") "sO" '(consult-outline :wk "search outline")) (private/set-leader-keys "SPC" '(consult-buffer :wk "buffers") "fc" '(consult-flymake :wk "flymake") "ff" '(consult-find :wk "find file") "fl" '(consult-locate :wk "find locate") "fh" '(consult-man :wk "find man")) :custom (consult-line-numbers-widen t) (register-preview-function #'consult-register-format) (xref-show-xrefs-function #'consult-xref) (xref-show-definitions-function #'consult-xref) (xref-search-program #'ripgrep) ;;(consult-preview-key nil) :init (with-eval-after-load 'project (setq consult-project-root-function (lambda () (when-let (project (project-current)) (car (project-roots project)))))) :config (defun sjb-embark-preview () "Previews candidate in vertico buffer, unless it's a consult command" (interactive) (unless (bound-and-true-p consult--preview-function) (save-selected-window (let ((embark-quit-after-action nil)) (embark-dwim)))))) (use-package consult :defer t :commands (consult-typhoon) :general (private/set-leader-keys "j" '(consult-typhoon :wk "typhoon")) :config (require 'consult) (require 'project) (autoload 'org-buffer-list "org") (defvar consult--source-org `(:name "Org File" :narrow ?o :category file :history file-name-history :face consult-file :state ,#'consult--file-state :items ,(lambda () (mapcar #'buffer-name (org-buffer-list))) :action ,(lambda (cand) (find-file cand)))) (defvar consult-project-sjb--source-file `(:name "Project File" :narrow (?p . "Project File") :category file :history file-name-history :face consult-file :state ,#'consult--file-state :action ,(lambda (cand) (find-file cand)) :enabled ,#'project-current :items ,(lambda () (let* ((project (project--find-in-directory (project-root (project-current)))) (files (project-files project))) files)))) (defcustom consult-typhoon-sources '(consult-project-sjb--source-file consult--source-buffer consult--source-bookmark consult--source-recent-file consult--source-org) "Sources used by `consult-typhoon'." :type '(repeat symbol)) (defvar consult--typhoon-history nil) (defun consult-typhoon (&optional sources) "Enhanced `switch-to-*` command" (interactive) (let ((selected (consult--multi (or sources consult-typhoon-sources) :require-match (confirm-nonexistent-file-or-buffer) :prompt "Switch to: " :history 'consult--typhoon-history :sort nil))) (unless (plist-get (cdr selected) :match) (consult--buffer-action (car selected)))))) (use-package consult-project-extra :ensure t :after consult :general (general-def [remap project-find-file] #'consult-project-extra-find) (general-def :keymaps 'project-prefix-map "o" #'consult-project-extra-find-other-window)) (use-package consult-dir :ensure t :defer t :general (general-def [remap dired] #'consult-dir) (:keymaps 'minibuffer-local-completion-map "C-x C-d" 'consult-dir "C-x C-j" 'consult-dir-jump-file)) (use-package consult-eglot :ensure t :defer t :after (consult eglot) :general (:keymaps 'eglot-mode-map [remap xref-find-apropos] #'consult-eglot-symbols) (private/set-leader-keys :keymaps 'eglot-mode-map "/" '(consult-eglot-symbols :wk "symbols"))) (use-package consult-eglot-embark :ensure t :after (consult-eglot) :config (consult-eglot-embark-mode)) (use-package corfu :general (general-def :keymaps 'corfu-map [remap evil-complete-next] 'corfu-next [remap evil-complete-previous] 'corfu-previous "RET" nil "" nil "TAB" nil "C-" #'corfu-insert "M-d" #'corfu-popupinfo-toggle "M-n" #'corfu-popupinfo-scroll-up "M-p" #'corfu-popupinfo-scroll-down "C-g" #'corfu-quit "M-l" #'corfu-show-location) (general-def :keymaps '(corfu-map general-override-mode-map) :states 'insert "C-y" #'corfu-complete "\M-q" #'corfu-quick-complete "\C-q" #'corfu-quick-insert "\M-m" #'corfu-move-to-minibuffer "M-SPC" #'corfu-insert-separator) :custom ;; Works with `indent-for-tab-command'. Make sure tab doesn't indent when you ;; want to perform completion (corfu-auto t) (corfu-auto-prefix 3) (corfu-auto-delay 0.5) (corfu-echo-documentation 0.25) ; Already use corfu-doc (corfu-min-width 80) (corfu-max-width corfu-min-width) ; Always have the same width (corfu-count 14) (corfu-scroll-margin 4) (corfu-cycle t) (corfu-separator ?\s) ; Necessary for use with orderless (corfu-quit-no-match 'separator) (corfu-quit-at-boundary 'separator) (corfu-preview-current 'insert) ; Preview current candidate? ;;(corfu-preselect-first t) ; Preselect first candidate? (read-extended-command-predicate #'command-completion-default-include-p) ;; Disable Ispell completion function. As an alternative try `cape-dict'. (text-mode-ispell-word-completion nil) (tab-always-indent 'complete) :init (require 'corfu-quick) (require 'corfu-history) (require 'corfu-popupinfo) (global-corfu-mode 1) (corfu-history-mode 1) (corfu-popupinfo-mode 1) ;;(eldoc-add-command #'corfu-insert) (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))) ;; (setq-local corfu-auto nil) Enable/disable auto completion (corfu-mode 1))) (add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer) (defun corfu-move-to-minibuffer () (interactive) (let ((completion-extra-properties corfu--extra) completion-cycle-threshold completion-cycling) (apply #'consult-completion-in-region completion-in-region--data))) ) (use-package embark :ensure t :general (general-def "C-h B" #'embark-bindings "C-S-a" #'embark-act) (general-def :keymaps 'minibuffer-local-map "C-." #'embark-act "C-," #'embark-become) (:keymaps 'completion-list-mode-map "C-S-a" #'embark-minimal-act) ([remap describe-bindings] #'embark-bindings) (:keymaps 'embark-collect-mode-map "." #'embark-act "C-a" #'embark-act "M-t" #'toggle-truncate-lines) :custom (prefix-help-command #'embark-prefix-help-command) :config ;;(setq embark-prompter 'embark-completing-read-prompter) (defun embark-hide-which-key-indicator (fn &rest args) "Hide the which-key indicator immediately when using the completing-read prompter." (which-key--hide-popup-ignore-command) (let ((embark-indicators (remq #'embark-which-key-indicator embark-indicators))) (apply fn args))) (defun embark-which-key-indicator () "An embark indicator that displays keymaps using which-key. The which-key help message will show the type and value of the current target followed by an ellipsis if there are further targets." (lambda (&optional keymap targets prefix) (if (null keymap) (which-key--hide-popup-ignore-command) (which-key--show-keymap (if (eq (plist-get (car targets) :type) 'embark-become) "Become" (format "Act on %s '%s'%s" (plist-get (car targets) :type) (embark--truncate-target (plist-get (car targets) :target)) (if (cdr targets) "…" ""))) (if prefix (pcase (lookup-key keymap prefix 'accept-default) ((and (pred keymapp) km) km) (_ (key-binding prefix 'accept-default))) keymap) nil nil t (lambda (binding) (not (string-suffix-p "-argument" (cdr binding)))))))) ;; Embark actions for this buffer/file (defun embark-target-this-buffer-file () (cons 'this-buffer-file (buffer-name))) (add-to-list 'embark-target-finders #'embark-target-this-buffer-file 'append) (unless (member 'embark-target-this-buffer-file embark-target-finders) (setq embark-target-finders (append (butlast embark-target-finders 2) '(embark-target-this-buffer-file) (last embark-target-finders 2)))) (setq embark-indicators '(embark-which-key-indicator embark-highlight-indicator embark-isearch-highlight-indicator)) (setq embark-collect-initial-view-alist '((consult-yank . zebra) (consult-register . zebra) (consult-grep . list) (consult-location . list) (kill-ring . zebra) (file . list) (buffer . list) (symbol . list) (t . list))) (defun sudo-find-file (file) "Open FILE as root." (interactive "FOpen file as root: ") (when (file-writable-p file) (user-error "File is user writeable, aborting sudo")) (find-file (if (file-remote-p file) (concat "/" (file-remote-p file 'method) ":" (file-remote-p file 'user) "@" (file-remote-p file 'host) "|sudo:root@" (file-remote-p file 'host) ":" (file-remote-p file 'localname)) (concat "/sudo:root@localhost:" file)))) (defun sudo-this-file () "Open the current file as root." (interactive) (sudo-find-file (file-truename buffer-file-name))) (defun my/split-window-right (&optional size) "Split the selected window into two windows, one above the other. The selected window is below. The newly split-off window is below and displays the same buffer. Return the new window." (interactive "P") (split-window-right size) (other-window 1)) (defun my/split-window-below (&optional size) "Split the selected window into two side-by-side windows. The selected window is on the left. The newly split-off window is on the right and displays the same buffer. Return the new window." (interactive "P") (split-window-below size) (other-window 1)) (eval-when-compile (defmacro my/embark-ace-action (fn) `(defun ,(intern (concat "my/embark-ace-" (symbol-name fn))) () (interactive) (with-demoted-errors "%s" (require 'ace-window) (let ((aw-dispatch-always t)) (aw-switch-to-window (aw-select nil)) (call-interactively (symbol-function ',fn))))))) (eval-when-compile (defmacro my/embark-split-below-action (fn) `(defun ,(intern (concat "my/embark-below-" (symbol-name fn))) () (interactive) (split-window-below) (other-window 1) (call-interactively (symbol-function ',fn))))) (eval-when-compile (defmacro my/embark-split-right-action (fn) `(defun ,(intern (concat "my/embark-right" (symbol-name fn))) () (interactive) (split-window-right) (other-window 1) (call-interactively (symbol-function ',fn))))) (general-def :keymaps 'embark-file-map "a" (my/embark-ace-action find-file) "2" (my/embark-split-below-action find-file) "3" (my/embark-split-right-action find-file)) (general-def :keymaps 'embark-buffer-map "a" (my/embark-ace-action switch-to-buffer) "2" (my/embark-split-below-action switch-to-buffer) "3" (my/embark-split-right-action switch-to-buffer)) (general-def :keymaps 'embark-bookmark-map "a" (my/embark-ace-action bookmark-jump) "2" (my/embark-split-below-action bookmark-jump) "3" (my/embark-split-right-action bookmark-jump)) ;; 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 :ensure t :demand t :hook (embark-collect-mode . consult-preview-at-point-mode)) (use-package avy-embark-collect :ensure t :after embark :general (:keymaps 'embark-collect-mode-map "C-'" 'avy-embark-collect-choose "C-," 'avy-embark-collect-act)) (use-package marginalia :ensure t :hook (after-init . marginalia-mode) :custom (margnalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil)) (marginalia-max-relative-age 0) (marginalia-align 'right) :general (:keymaps 'minibuffer-local-map "M-A" 'marginalia-cycle)) (use-package orderless :ensure t :after corfu :custom (completion-styles '(orderless basic)) (completion-category-defaults nil) (completions-detailed t) (completion-category-overrides '((file (styles partial-completion)))) (orderless-component-separator 'orderless-escapable-split-on-space) :config (with-eval-after-load 'selectrum (setq selectrum-highlight-candidates-function #'orderless-highlight-matches)) (setq orderless-matching-styles '(orderless-prefixes orderless-initialism orderless-regexp)) (defun first-initialism (pattern index _total) (if (= index 0) 'orderless-initialism)) (defun flex-if-twiddle (pattern _index _total) (when (string-suffix-p "~" pattern) `(orderless-flex . ,(substring pattern 0 -1)))) (defun without-if-bang (pattern _index _total) (cond ((equal "!" pattern) '(orderless-literal . "")) ((string-prefix-p "!" pattern) `(orderless-without-literal . ,(substring pattern 1))))) (defun orderless-literal-dispatcher (pattern _index _total) (when (string-suffix-p "=" pattern) `(orderless-literal . ,(substring pattern 0 -1)))) (defun orderless-initialism-dispatcher (pattern _index _total) (when (string-suffix-p "," pattern) `(orderless-strict-leading-initialism . ,(substring pattern 0 -1)))) (setq orderless-style-dispatchers '(flex-if-twiddle without-if-bang orderless-literal-dispatcher orderless-initialism-dispatcher))) (use-package s :defer t :ensure t) (use-package tabnine :vc (tabnine :url "https://github.com/SjB/tabnine.git" :branch "change-completion-keybinding") :hook ((prog-mode . tabnine-mode) (kill-emacs . tabnine-kill-process)) :after cape :preface (add-to-list 'completion-at-point-functions #'tabnine-completion-at-point) :custom (tabnine-wait 2.0) (tabnine-idle-delay 1.0) :config (set-face-attribute 'tabnine-overlay-face nil :family "MonaspiceKr Nerd Font Propo") :general (private/set-leader-keys :keymaps 'tabnine-completion-map "z" #'tabnine-accept-completion)) (use-package gptel :defer t :ensure t) (use-package chatgpt-shell :ensure t :general (general-define-key :states 'visual :prefix "SPC" :global-prefix "C-SPC" "es" #'chatgpt-shell-proofread-region "ev" #'chatgpt-shell-write-git-commit) :config (setq chatgpt-shell-model-versions '("gpt-3.5-turbo")) (setq chatgpt-shell-prompt-query-response-style 'inline) (setq chatgpt-shell-openai-key (auth-source-pick-first-password :host "api.openai.com"))) (use-package treesit :demand t :commands (treesit-install-language-grammar nf/treesit-install-all-languages) :ensure nil :init ;;(add-to-list 'treesit-extra-load-path (expand-file-name "tree-sitter" user-emacs-directory)) :config (defun nf/treesit-install-all-languages () "Install all languages specified by `treesit-language-source-alist'." (interactive) (let ((languages (mapcar 'car treesit-language-source-alist))) (dolist (lang languages) (treesit-install-language-grammar lang) (message "`%s' parser was installed." lang) (sit-for 0.75))))) (use-package treesit-auto :defer 1 :config (setq my-elisp-ts-auto-recipe (make-treesit-auto-recipe :lang 'emacs-lisp :ts-mode 'elisp-ts-mode :remap '(elisp-mode emacs-lisp-mode) :url "https://github.com/Wilfred/tree-sitter-elisp.git" :revision "master" :source-dir "src")) (add-to-list 'treesit-auto-recipe-list my-elisp-ts-auto-recipe) (setq my-php-ts-auto-recipe (make-treesit-auto-recipe :lang 'php :ts-mode 'php-ts-mode :remap '(php-mode) :url "https://github.com/tree-sitter/tree-sitter-php" :revision "master" :source-dir "src")) (add-to-list 'treesit-auto-recipe-list my-php-ts-auto-recipe) (setq my-svelte-ts-auto-recipe (make-treesit-auto-recipe :lang 'svelte :ts-mode 'svlte-ts-mode :remap '(svelte-mode) :url "https://github.com/Himujjal/tree-sitter-sveltet" :revision "master" :source-dir "src")) (add-to-list 'treesit-auto-recipe-list my-svelte-ts-auto-recipe) (setq my-sql-ts-auto-recipe (make-treesit-auto-recipe :lang 'sql :ts-mode 'sql-ts-mode :remap '(sql-mode) :url "https://github.com/Himujjal/tree-sitter-sveltet" :revision "master" :source-dir "src")) (add-to-list 'treesit-auto-recipe-list my-sql-ts-auto-recipe) (setq my-zig-ts-auto-recipe (make-treesit-auto-recipe :lang 'zig :ts-mode 'zig-ts-mode :remap '(zig-mode) :url "https://github.com/GrayJack/tree-sitter-zig" :revision "master" :source-dir "src")) (add-to-list 'treesit-auto-recipe-list my-zig-ts-auto-recipe) (setq my-vue-ts-auto-recipe (make-treesit-auto-recipe :lang 'vue :ts-mode 'vue-ts-mode :remap '(vue-mode) :url "https://github.com/ikatyang/tree-sitter-vue.git" :revision "master" :source-dir "src")) (add-to-list 'treesit-auto-recipe-list my-vue-ts-auto-recipe) (setq my-ocaml-ts-auto-recipe (make-treesit-auto-recipe :lang 'ocaml :ts-mode 'ocaml-ts-mode :remap '(caml-mode tuareg-mode) :url "https://github.com/tree-sitter/tree-sitter-ocaml.git" :revision "master" :source-dir "src")) (add-to-list 'treesit-auto-recipe-list my-ocaml-ts-auto-recipe) (setq treesit-auto-install 'prompt) (global-treesit-auto-mode)) ;; `M-x combobulate' (or `C-c o o') to start using Combobulate (use-package combobulate :defer t :ensure t :vc (:fetcher github :repo "mickeynp/combobulate") ;; Optional, but recommended. ;; ;; You can manually enable Combobulate with `M-x ;; combobulate-mode'. ;;:hook (prog-mode . combobulate-mode) ;; Amend this to the directory where you keep Combobulate's source ;; code. ) (defun setup-shell() (setq-local show-trailing-whitespace nil) (ansi-color-for-comint-mode-on)) (add-hook 'shell-mode-hook 'setup-shell) (add-hook 'term-mode-hook 'setup-shell) ;;(setq epg-pinentry-mode 'loopback) ; This will fail if gpg>=2.1 is not available. ;;(pinentry-start) (with-eval-after-load 'tramp (setenv "SHELL" "/bin/bash") (setq tramp-shell-prompt-pattern "\\(?:^\\| \\)[^]#$%>\n]*#?[]#$%>] *\\(\\[[0-9;]*[a-zA-Z] *\\)*")) ;;(eval-after-load 'shell '(setenv "TERM" "xterm-256color")) (add-to-list 'comint-output-filter-functions 'ansi-color-process-output) (use-package shell :ensure nil :hook (shell-mode . my-shell-mode-hook-func) :defer t :config (defun my-shell-mode-hook-func () (set-process-sentinel (get-buffer-process (current-buffer)) 'my-shell-mode-kill-buffer-on-exit)) (defun my-shell-mode-kill-buffer-on-exit (process state) (message "%s" state) (if (or (string-match "exited abnormally with code.*" state) (string-match "finished" state)) (kill-buffer (current-buffer))))) (use-package term :commands term :init (setenv "SHELL" "/bin/bash") (setenv "PAGER" "cat") (setenv "EDITOR" "emacsclient") (setq explicit-shell-file-name "/bin/bash") (when (eq system-type 'windows-nt) (setq explicit-shell-file-name "powershell.exe") (setq explicit-powershell.exe-args '())) (add-hook 'term-mode-hook (lambda () (goto-address-mode) (define-key term-raw-map (kbd "M-o") 'other-window) (setq yas-dont-activate t))) :config (setq term-prompt-regexp "^[^#$%>\n]*[#$%>] *")) (use-package xterm-color :ensure t :after eshell) (use-package eat :ensure t :defer t :hook (eshell-load-hook . (eat-eshell-mode eat-eshell-visual-command-mode))) (use-package eshell :commands (eshell configure-eshell) :hook (eshell-directory-change . sjb/sync-dir-in-buffer-name) :custom (eshell-scroll-to-bottom-on-input t) (eshell-highlight-prompt nil) (eshell-history-size 1024) (eshell-hist-ignoredups t) ;;(eshell-input-filter 'sjb/eshell-input-filter) (eshell-cd-on-directory t) (eshell-list-files-after-cd nil) ;;(eshell-error-if-no-glob t) ;;(eshell-review-quick-commands nil) (eshell-prefer-lisp-functions t) (eshell-prefer-lisp-variables t) (eshell-ls-use-colors t) ;;(ffap-shell-prompt-regexp nil) (eshell-destroy-buffer-when-process-dies t) ;;(eshell-prompt-regexp "^$ ") (eshell-buffer-maximum-lines 10000) :general (private/set-leader-keys "xe" 'eshell) (:keymaps 'eshell-mode-map "C-c >" 'sjb/eshell-redirect-input) (:keymaps 'eshell-hist-mode-map "M-r" 'consult-history) :init (add-hook 'eshell-mode-hook (lambda () (setq-local completion-styles '(basic)) (setq-local corfu-count 2) (setq-local completion-at-point-function '(pcomplete-completions-at-point cape-file cape-history)) (setq-local show-trailing-whitespace nil) (setq-local outline-regexp eshell-prompt-regexp) (evil-normalize-keymaps) )) ;; We want to use xterm-256color when running interactive commands ;; in eshell but not during other times when we might be launching ;; a shell command to gather its output. (add-hook 'eshell-pre-command-hook #'(lambda () (setenv "TERM" "xterm-256color"))) (add-hook 'eshell-post-command-hook #'(lambda () (setenv "TERM" "dumb"))) :config (require 'em-tramp) ;;(require 'em-smart) ;;(setq eshell-where-to-jump 'begin ;; eshell-review-quick-commands nil ;; eshell-scroll-to-bottom-on-input nil ;; eshell-smart-space-goes-to-end t) ;; If the above does not work, try uncommenting this. ;; (add-to-list 'eshell-modules-list 'eshell-smart) (setq eshell-directory-name (expand-file-name "emacs/eshell" (xdg-data-home))) (setq eshell-visual-commands '("tail" "top" "htop")) (add-to-list 'eshell-modules-list 'eshell-tramp) ;;(add-to-list 'eshell-modules-list 'eshell-smart) ;;(add-to-list 'eshell-output-filter-functions 'eshell-truncate-buffer) (defun sjb/sync-dir-in-buffer-name () "Update eshell buffer to show directory path. Stolen from aweshell." (if (project-current) (let* ((root (project-root (project-current))) (root-name (project-name (project-current)))) (rename-buffer (format "*eshell %s* %s" root-name (s-chop-prefix root default-directory)) t)) (rename-buffer (format "*eshell %s*" default-directory) t))) (defun eshell/gst (&rest args) (magit-status (pop args) nil) (eshell/echo)) ;; The echo command suppresses output (defun eshell/clear () "Clear the eshell buffer." (let ((inhibit-read-only t)) (erase-buffer) (eshell-send-input))) (if (eq system-type 'darwin) ;; The 'ls' executable requires the Gnu version on the Mac (let ((ls (if (file-exists-p "/usr/local/bin/gls") "/usr/local/bin/gls" "/bin/ls"))) (eshell/alias "ll" (concat ls " -AlohG --color=always")))) ) (use-package eshell-syntax-highlighting :ensure t :defer t :commands unpackaged/eshell-syntax-highlighting-init :hook (eshell-first-time-mode . unpackaged/eshell-syntax-highlighting-init) :config (defun unpackaged/eshell-syntax-highlighting-init () (eshell-syntax-highlighting-global-mode +1))) (use-package eshell-z :ensure t :after eshell) (use-package eshell-bookmark :hook (eshell-mode . eshell-bookmark-setup) :after eshell) (use-package eshell-toggle :ensure t :defer t :custom (eshell-toggle-find-project-root-package nil) :general (general-def "C-x C-z" 'smart-eshell-toggle) :config (defun smart-eshell-toggle () "Detect if we are in a project and dwim" (interactive) (if (project-current) (setq eshell-toggle-find-project-root-package 'project) (setq eshell-toggle-find-project-root-package nil)) (eshell-toggle)) ) (use-package eshell-git-prompt :after eshell) (use-package ace-link :ensure t :defer t :general ((elfeed-show-mode-map org-mode-map) "M-o" 'ace-link-org) :config (ace-link-setup-default)) (use-package ace-window :ensure t :hook (after-init . ace-window-posframe-mode) :commands (ace-window-prefix) :general ("C-x 4 o" 'ace-window-prefix) ([remap other-window] 'ace-window) (private/set-leader-keys "a" 'ace-window) :init (setq aw-char-position 'left) ;;(setq aw-frame-size nil) ;;(setq aw-frame-offset '(13 . 23)) (with-eval-after-load 'evil (general-define-key :keymaps 'evil-window-map "a" 'ace-window "c" 'ace-swap-window "x" 'ace-delete-window "m" 'ace-maximize-window)) :config (defun ace-window-prefix () "Use `ace-window' to display the buffer of the next command. The next buffer is the buffer displayed by the next command invoked immediately after this command (ignoring reading from the minibuffer). Creates a new window before displaying the buffer. When `switch-to-buffer-obey-display-actions' is non-nil, `switch-to-buffer' commands are also supported." (interactive) (display-buffer-override-next-command (lambda (buffer _) (let (window type) (setq window (aw-select (propertize " ACE" 'face 'mode-line-highlight)) type 'reuse) (cons window type))) nil "[ace-window]") (message "Use `ace-window' to display next command buffer...")) (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)) (setq aw-dispatch-always nil)) (use-package alert :ensure t :commands (alert) :init (when (or (eq system-type 'gnu/linux) (eq system-type 'linux)) (setq alert-default-style 'notifications)) (when (eq system-type 'darwin) (setq alert-default-style 'osx-notifier))) (use-package async :ensure t :defer t :init (async-bytecomp-package-mode 1) :commands (async-start)) (use-package avy :ensure t :defer t :hook (after-init . avy-setup-default) :general (:keymaps 'isearch-mode-map "M-j" 'avy-isearch) ;(general-nmap "gr" '(avy-resume :wk "avy resume")) (private/set-leader-keys "ec" 'avy-copy-region "ek" 'avy-kill-region "em" 'avy-move-region) :config (setq avy-background t avy-highlight-first t avy-style 'at-full) (setq avy-orders-alist '((avy-goto-char-2 . avy-order-closest) (avy-goto-word-1 . avy-order-closest) (avy-goto-symbol-1 . avy-order-closest) (avy-goto-word-or-subword-1 . avy-order-closest))) (with-eval-after-load 'embark (defun avy-action-embark (pt) (unwind-protect (save-excursion (goto-char pt) (embark-act)) (select-window (cdr (ring-ref avy-ring 0)))) t) (setf (alist-get ?\. avy-dispatch-alist) 'avy-action-embark)) (defun avy-action-kill-whole-line (pt) (save-excursion (goto-char pt) (kill-whole-line)) (select-window (cdr (ring-ref avy-ring 0))) t) (setf (alist-get ?k avy-dispatch-alist) 'avy-action-kill-stay) (setf (alist-get ?K avy-dispatch-alist) 'avy-action-kill-whole-line) ;; Copy text (defun avy-action-copy-whole-line (pt) (save-excursion (goto-char pt) (cl-destructuring-bind (start . end) (bounds-of-thing-at-point 'line) (copy-region-as-kill start end))) (select-window (cdr (ring-ref avy-ring 0))) t) (setf (alist-get ?w avy-dispatch-alist) 'avy-action-copy) (setf (alist-get ?W avy-dispatch-alist) 'avy-action-copy-whole-line) ;; Yank text (defun avy-action-yank-whole-line (pt) (avy-action-copy-whole-line pt) (save-excursion (yank)) t) (setf (alist-get ?y avy-dispatch-alist) 'avy-action-yank) (setf (alist-get ?Y avy-dispatch-alist) 'avy-action-yank-whole-line) ;; Transpose/Move text (defun avy-action-teleport-whole-line (pt) (avy-action-kill-whole-line pt) (save-excursion (yank)) t) (setf (alist-get ?t avy-dispatch-alist) 'avy-action-teleport) (setf (alist-get ?T avy-dispatch-alist) 'avy-action-teleport-whole-line) ;; Mark text (defun avy-action-mark-to-char (pt) (activate-mark) (goto-char pt)) (setf (alist-get ?m avy-dispatch-alist) 'avy-action-mark-to-char) ;; Flyspell words (defun avy-action-flyspell (pt) (save-excursion (goto-char pt) (when (require 'flyspell nil t) (flyspell-auto-correct-word))) (select-window (cdr (ring-ref avy-ring 0))) t) ;; Bind to semicolon (flyspell uses C-;) (setf (alist-get ?s avy-dispatch-alist) 'avy-action-flyspell) (with-eval-after-load 'dictionary (defun dictionary-search-dwim (&optional arg) "Search for definition of word at point. If region is active, search for contents of region instead. If called with a prefix argument, query for word to search." (interactive "P") (if arg (dictionary-search nil) (if (use-region-p) (dictionary-search (buffer-substring-no-properties (region-beginning) (region-end))) (if (thing-at-point 'word) (dictionary-lookup-definition) (dictionary-search-dwim '(4)))))) (defun avy-action-define (pt) (save-excursion (goto-char pt) (dictionary-search-dwim)) (select-window (cdr (ring-ref avy-ring 0))) t) (setf (alist-get ?\= avy-dispatch-alist) 'dictionary-search-dwim)) ;; Get Elisp Help ;; Replace with your package manager or help library of choice (with-eval-after-load 'helpful (defun avy-action-helpful (pt) (save-excursion (goto-char pt) (helpful-at-point)) (select-window (cdr (ring-ref avy-ring 0))) t) (setf (alist-get ?H avy-dispatch-alist) 'avy-action-helpful)) ;; Isearch in other windows (defun isearch-forward-other-window (prefix) "Function to isearch-forward in other-window." (interactive "P") (unless (one-window-p) (save-excursion (let ((next (if prefix -1 1))) (other-window next) (isearch-forward) (other-window (- next)))))) (defun isearch-backward-other-window (prefix) "Function to isearch-backward in other-window." (interactive "P") (unless (one-window-p) (save-excursion (let ((next (if prefix 1 -1))) (other-window next) (isearch-backward) (other-window (- next)))))) (define-key global-map (kbd "C-M-s") 'isearch-forward-other-window) (define-key global-map (kbd "C-M-r") 'isearch-backward-other-window) (with-eval-after-load 'lsp-mode (defun avy-action-lsp-describe (pt) (save-excursion (goto-char pt) (lsp-describe-thing-at-point)) (select-window (cdr (ring-ref avy-ring 0))) t) (setf (alist-get ?L avy-dispatch-alist) 'avy-action-lsp-describe))) (use-package evil-avy :ensure t :general (general-def [remap evil-find-char] 'evil-avy-goto-char) (general-def [remap evil-find-char-to] 'evil-avy-goto-word-or-subword-1) ;;(general-nmap "g:" '(evil-avy-goto-line :wk "go to line")) (general-nmap "gs" '(evil-avy-goto-symbol-1 :wk "go to symbol")) (private/set-leader-keys "gw" '(evil-avy-goto-word-0 :wk "jump to word") "gl" '(evil-avy-goto-line :wk "jump to line"))) ;; (with-eval-after-load 'eww-mode ;; (general-def 'motion eww-mode-map ;; "S" 'evil-avy-goto-char-timer ;; "s" 'evil-avy-goto-char-in-line)) (use-package beginend :ensure t :hook (prog-mode . beginend-prog-mode)) (use-package bookmark :defer t :custom (bookmark-sort-flag nil) :preface (setq bookmark-default-file (expand-file-name "emacs/bookmarks.el" (xdg-data-home))) (defun jump-to-numbered-bookmark (num) "Jump to the bookmark with the given numeric prefix." (let ((bookmark (nth num bookmark-alist))) (when bookmark (bookmark-jump bookmark)))) :general (private/set-leader-keys "mm" 'bookmark-set "mS" 'bookmark-save "ml" 'bookmark-bmenu-list "@" '(point-to-register :wk "mark") ";" '(jump-to-register :wk "jump") "," '((lambda () (interactive) (bookmark-set (sjb/get-bookmark-name))) :wk "bookmark")) ;; (private/set-leader-keys ;; "0" '(bookmark-bmenu-list :wk "view harpoon list") ;; "1" '((lambda () (interactive) (jump-to-numbered-bookmark 0)) :wk "harpoon 1") ;; "2" '((lambda () (interactive) (jump-to-numbered-bookmark 1)) :wk "harpoon 2") ;; "3" '((lambda () (interactive) (jump-to-numbered-bookmark 2)) :wk "harpoon 3") ;; "4" '((lambda () (interactive) (jump-to-numbered-bookmark 3)) :wk "harpoon 4") ;; "5" '((lambda () (interactive) (jump-to-numbered-bookmark 4)) :wk "harpoon 5") ;; "6" '((lambda () (interactive) (jump-to-numbered-bookmark 5)) :wk "harpoon 6") ;; "7" '((lambda () (interactive) (jump-to-numbered-bookmark 6)) :wk "harpoon 7") ;; "8" '((lambda () (interactive) (jump-to-numbered-bookmark 7)) :wk "harpoon 8") ;; "9" '((lambda () (interactive) (jump-to-numbered-bookmark 8)) :wk "harpoon 9")) :init (add-hook 'bookmark-bmenu-mode-hook #'hl-line-mode) (defun sjb/get-bookmark-name () (let* ((name (if (treesit-language-at (point)) (treesit-add-log-current-defun) " ")) (mark (concat (format-mode-line "harpoon| %b:%l [%p] ") name))) (message "%s" mark) mark))) (use-package bookmark-in-project :ensure t :defer t :general (private/set-leader-keys "mn" 'bookmark-in-project-jump-next "mp" 'bookmark-in-project-jump-previous "mg" 'bookmark-in-project-jump "z" 'bookmark-in-project-toggle)) (use-package breadcrumb-mode :after eglot :vc (:fetcher github :repo "joaotavora/breadcrumb") :hook (eglot-managed-mode . breadcrumb-local-mode)) (use-package buffer-name-relative :after project :config (buffer-name-relative-mode)) (use-package bufler :ensure t :defer 1 :general (general-def [remap list-buffers] 'bufler) (general-nmap :keymaps 'bufler-list-mode-map "gr" '(bufler :wk "Refresh") "m" '(bufler-mode :wk "Toggle mode") "q" '(quit-window :wk "Quit") "SPC" '(bufler-list-buffer-peek :wk "Peek at") "RET" '(bufler-list-buffer-switch :wk "Switch to") "x" '(bufler-list-buffer-kill :wk "Kill") "C-x C-s" '(bufler-list-buffer-save :wk "Save") "N" '(bufler-list-buffer-name-workspace :wk "Named workspace") "f" '(bufler-list-group-frame :wk "Focus on") "F" '(bufler-list-group-make-frame :wk "Make frame"))) (use-package burly :ensure t :defer 1 :general (private/set-leader-keys "mw" '(burly-bookmark-windows :wk "burly window") "mr" '(burly-open-bookmark :wk "burly open"))) (use-package cheat-sh :ensure t :general (private/set-leader-keys "hc" 'cheat-sh)) (use-package dired :ensure nil :defer t :hook (dired-mode . unpackaged/dired-startup-init) :commands (dired dired-find-file-below multi-dired-find-file wdired-change-to-wdired-mode unpackaged/dired-startup-init) :general ("C-x j" 'dired-jump "C-x C-j" 'dired-jump-other-window) :custom (dired-dwim-target t) (dired-listing-switches "-agho --group-directories-first") :config (defun unpackaged/dired-startup-init () (dired-hide-details-mode t) (auto-revert-mode)) (defun dired-clean-files () "Perform a bunch of operations on the whitespace content of a file. Including indent-buffer, which should not be called automatically on save." (interactive) (dired-map-over-marks (funcall 'dired-clean-file) nil t) (dired-unmark-all-marks)) (defun dired-clean-file () (let ((file (dired-get-filename))) (unpackaged/process-on-file-buffer file 'unpackaged/cleanup-buffer))) (defun unpackaged/process-on-file-buffer (file func) "Process func on file" (message "%s" file) (find-file file) (funcall func) (save-buffer) (kill-buffer)) (defun dired-find-file-below () "Displays file at point in a new window below current" (interactive) (display-buffer-below-selected (find-file-noselect (dired-get-file-for-visit)) nil)) (defun multi-dired-find-file (&optional arg) "Open each of the marked files, or the file under the point, or when prefix arg, the next N files " (interactive "P") (let* ((fn-list (dired-get-marked-files nil arg))) (mapc 'find-file fn-list)))) (use-package envrc :ensure t :hook (after-init . envrc-global-mode)) (use-package mise :ensure t :hook (after-init . global-mise-mode) :custom (mise-update-on-eshell-directory-change t) :config (setenv "PATH" (concat (expand-file-name "mise/shims" (xdg-data-home)) ":" (getenv "PATH"))) (add-to-list 'exec-path '((expand-file-name "mise/shims" (xdg-data-home))))) (use-package drag-stuff :ensure t :general (general-vmap "J" #'drag-stuff-down "K" #'drag-stuff-up)) (use-package all-the-icons-dired :ensure t :hook (dired-mode . all-the-icons-dired-mode)) (use-package nerd-icons-corfu :ensure t :defer 1 :after corfu :config (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) (use-package nerd-icons-completion :after marginalia :defer 1 :config (add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup) (nerd-icons-completion-mode)) (use-package discover-my-major :ensure t :commands (discover-my-mode discover-my-major) :general ("C-h C-m" 'discover-my-major "C-h M-m" 'discover-my-mode)) (use-package docker :ensure t :defer t :init (with-eval-after-load 'evil (evil-set-initial-state 'docker-images-mode 'emacs) (evil-set-initial-state 'docker-containers-mode 'emacs) (evil-set-initial-state 'docker-volumes-mode 'emacs) (evil-set-initial-state 'docker-machines-mode 'emacs) (evil-set-initial-state 'docker-netowkrs-mode 'emacs))) (use-package dogears ;; These bindings are optional, of course: :defer 1 :hook (after-init . dogears-mode) :general (private/set-leader-keys "." 'dogears-remember "fd" 'dogears-go "gd" 'dogears-list "gD" 'dogears-sidebar) (general-nmap :keymaps 'dogears-list-mode-map "d" #'dogears-list-delete "" #'dogears-list-go) :custom ;;(dogears-idle 5) (dogears-functions nil)) (use-package elfeed :ensure t :commands elfeed :general (general-nmap 'elfeed-search-mode-map "c" 'elfeed-db-compact "gu" 'elfeed-unjam) (private/set-leader-keys "xf" 'elfeed) :config (elfeed-org)) (use-package elfeed-org :ensure t :after elfeed :config (setq rmh-elfeed-org-files (list "~/.dotfiles/elfeed.org"))) (use-package ement :vc (:fetcher github :repo "alphapapa/ement.el") :general (private/set-leader-keys "xc" 'ement-connect)) (use-package emojify :hook (ement-room-mode . emojify-mode) (markdown-mode . emojify-mode)) (use-package elisp-slime-nav :ensure t :commands (elisp-slime-nav-mode elisp-slime-nav-describe-elisp-thing-at-point) :init (dolist (hook '(emacs-lisp-mode-hook ielm-mode-hook)) (add-hook hook 'elisp-slime-nav-mode)) (with-eval-after-load 'evil (evil-define-key 'normal emacs-lisp-mode-map (kbd "K") 'elisp-slime-nav-describe-elisp-thing-at-point)) :config (with-eval-after-load 'which-key (which-key-add-key-based-replacements "C-c C-d" "elisp slime"))) (use-package engine-mode :ensure t :defer t :general (private/set-leader-keys "sw" '(:keymap engine-mode-prefixed-map :wk "web search")) :config (setq engine/browser-function 'browse-url-default-browser) (defengine duckduckgo "http://www.duckduckgo.com/?q=%s" :keybinding "d") (defengine startpage "https://www.startpage.com/do/dsearch?query=%s" :keybinding "s") (defengine gowalker "https://gowalker.org/search?q=%s" :keybinding "w") (defengine github "https://github.com/search?ref=simplesearch&q=%s" :keybinding "g") (defengine godoc "https://godoc.org/?q=%s") (defengine golang "https://golang.org/?q=%s" :keybinding "z") (defengine rustlang "https://doc.rust-lang.org/std/?search=%s" :keybinding "R") (defengine docsrs "https://docs.rs/releases/search?query=%s&i-am-feeling-lucky=1" :keybinding "r") (defengine msdn "https://docs.microsoft.com/en-us/dotnet/api/?view=netframework-4.7.1&term=%s" :keybinding "m")) (use-package erc :ensure t :defer t :commands (erc-znc/dogmatix erc) :general (private/set-leader-keys "xi" 'erc-znc/dogmatix) :config (require 'erc-ring) (erc-ring-mode t) (setq erc-prompt-for-password t) ;;(make-variable-buffer-local 'erc-fill-column) ;; (add-hook 'window-configuration-change-hook ;; '(lambda () ;; (save-excursion ;; (walk-windows ;; (lambda (w) ;; (let ((buffer (window-buffer w))) ;; (set-buffer buffer) ;; (when (eq major-mode 'erc-mode) ;; (setq erc-fill-column (- (window-width w) 2))))))))) (defun erc-znc-connect (user host port) (let ((pass (auth-source-pass-get 'secret (format "znc/%s@%s" user host)))) (erc :server host :port port :nick user :password (format "%s:%s" user pass)))) (defun erc-znc/dogmatix () "Connect to freenode via ZNC server at dogmatix" (interactive) (erc-znc-connect "sjb" "dogmatix.nca.uwo.ca" 1234)) (setq erc-fill-function 'erc-fill-static erc-fill-static-center 15) ;; (erc-autojoin-mode 1) ;; (setq erc-autojoin-channels-alist ;; '((".*\\.freenode.net" "#emacs" "#snappy" "#lxcontainers" "#go-nuts" "#Node.js" "#docker" "#linaro" "#linaro-tcwg"))) (erc-track-mode 1) (setq erc-track-exclude-type '("JOIN" "NICK" "PART" "QUIT" "MODE" "324" "329" "332" "333" "353" "477")) (setq erc-prompt (lambda () (concat "[" (buffer-name) "]"))) ;;(setq erc-prompt ">") (setq erc-hide-list '("JOIN" "PART" "QUIT" "NICK") erc-lurker-hide-list '("JOIN" "PART" "QUIT")) (setq erc-default-server "irc.libera.chat") (setq erc-prompt-for-nickserv-password t) (setq erc-auto-query 'bury erc-join-buffer 'bury erc-interpret-mirc-color t erc-rename-buffers t erc-track-enable-keybindings nil erc-track-visibility nil ; Only use the selected frame for visibility erc-fill-column 80 erc-fill-function 'erc-fill-static erc-fill-static-center 20 erc-autojoin-channels-alist '(("libera.chat" "#emacs" "#guix")) erc-quit-reason (lambda (s) (or s "Fading out...")) erc-modules '(autoaway autojoin button completion fill irccontrols keep-place list match menu move-to-prompt netsplit networks noncommands readonly ring stamp track))) (use-package empv :ensure t :defer t :config (add-to-list 'empv-mpv-args "--ytdl-format=best")) (use-package ess :ensure t :defer t :mode "\\.R\\'" :config (setq ess-eval-visibly nil ess-ask-for-ess-directory nil)) (use-package eww :ensure t :defer t :general (private/set-leader-keys "gu" 'browse-last-url-in-browser) :commands browse-last-url-in-browser :hook (eww-mode . toggle-word-wrap) :custom (browse-url-browser-function '(("." . browse-url-default-browser))) :config ;;(setq browse-url-secondary-browser-function 'eww-browse-url) (setq browse-url-secondary-browser-function 'browse-url-xdg-open) ;;(setq browse-url-default-browser 'browser-url-firefox) (defun browse-last-url-in-browser () (interactive) (save-excursion (ffap-next t t)))) (use-package exec-path-from-shell :if (memq window-system '(mac ns x)) :ensure t :defer 1 :custom (exec-path-from-shell-variables '("SSH_AUTH_SOCK" "PATH" "MANPATH" "GOPATH" "PYTHONPATH")) :config (exec-path-from-shell-initialize)) (use-package expand-region :ensure t :defer t :commands (er/expand-region) :general (general-vmap "v" 'er/expand-region) :config (with-eval-after-load 'evil (setq expand-region-contract-fast-key "z"))) (use-package expreg :ensure t :defer t :general (general-vmap "." 'expreg-expand) (general-vmap "C-." 'expreg-contract)) (use-package gitignore-templates :defer t :ensure t) (use-package goto-chg :ensure t :defer 1) (use-package harpoon :ensure t :config (setq harpoon-cache-file (expand-file-name "emacs/harpoon/" (xdg-data-home))) :general (private/set-leader-keys "ta" #'harpoon-add-file "tf" #'harpoon-toggle-file "tc" #'harpoon-clear "0" #'harpoon-toggle-quick-menu "1" #'harpoon-go-to-1 "2" #'harpoon-go-to-2 "3" #'harpoon-go-to-3 "4" #'harpoon-go-to-4 "5" #'harpoon-go-to-5 "6" #'harpoon-go-to-6 "7" #'harpoon-go-to-7 "8" #'harpoon-go-to-8 "9" #'harpoon-go-to-9)) (use-package helpful :ensure t :general (general-def [remap describe-command] #'helpful-command [remap describe-function] #'helpful-callable [remap describe-key] #'helpful-key [remap describe-symbol] #'helpful-symbol [remap describe-variable] #'helpful-variable) ("C-h f" 'helpful-callable "C-h v" 'helpful-variable "C-h K" 'describe-keymap) (:keymaps 'helpful-mode-map [remap revert-buffer] #'helpful-update) (private/set-leader-keys "h." 'helpful-at-point) :init (setq-default read-symbol-positions-list nil) (with-eval-after-load 'evil (add-to-list 'evil-motion-state-modes 'helpful-mode))) (use-package hippie-exp :ensure nil :general (general-def [remap dabbrev-expand] 'hippie-expand) :custom (hippie-expand-try-functions-list '(try-complete-file-name-partially try-complete-file-name try-expand-dabbrev try-expand-dabbrev-all-buffers try-expand-dabbrev-from-kill))) (use-package iedit :ensure t :general ("C-;" 'iedit-mode) ; also note: C-' toggles focus of matches (:keymaps 'iedit-mode-keymap "C-g" 'iedit-mode) ; so I can exit iedit with C-g :config (advice-add #'iedit--get-scope ; switch default to function scope :filter-args (defun my/iedit-defun-by-default (arg) (cond ((eq (car arg) nil) '(0)) ((eq (car arg) 0) '(nil)) (t arg))))) (use-package jinx :ensure t :defer t :general ("M-$" 'jinx-correct "C-M-$" 'jinx-languages) :config (with-eval-after-load 'vertico (add-to-list 'vertico-multiform-categories '(jinx grid (vertico-grid-annotate . 20))) (vertico-multiform-mode 1))) (use-package kind-icon :after corfu ;; Add hook to reset cache so the icon colors match my theme ;; NOTE 2022-02-05: This is a hook which resets the cache whenever I switch ;; the theme using my custom defined command for switching themes. If I don't ;; do this, then the backgound color will remain the same, meaning it will not ;; match the background color corresponding to the current theme. Important ;; since I have a light theme and dark theme I switch between. This has no ;; function unless you use something similar :hook (after-load-theme . (lambda () (interactive) (kind-icon-reset-cache))) :custom (kind-icon-use-icons t) (kind-icon-default-face 'corfu-default) ; Have background color be the same as `corfu' face background (kind-icon-blend-background nil) ; Use midpoint color between foreground and background colors ("blended")? (kind-icon-blend-frac 0.08) :config (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter) ; Enable `kind-icon' (add-to-list 'kind-icon-mapping '(tabnine "ai" :icon "cloud" :face shadow) t)) (use-package link-hint :ensure t :defer t :general (private/set-leader-keys "elo" 'link-hint-open-link "elc" 'link-hist-open-copy)) (use-package lxc :defer t :ensure t) (use-package lxc-tramp :defer 1 :ensure t) (use-package lxd-tramp :defer 1 :ensure t) (use-package incus-tramp :ensure nil :after tramp :config (incus-tramp-add-method) (tramp-set-completion-function incus-tramp-method '((incus-tramp-completion-function-alist))) ) (setq mail-user-agent 'mu4e-user-agent) (use-package mu4e :if (eq system-type 'gnu/linux) :ensure nil :defer t :hook (mu4e-compose-mode . turn-on-auto-fill) :general (private/set-leader-keys "xm" 'mu4e) :custom (mu4e-maildir "~/.maildir") (mu4e-maildir-shortcuts nil) (mu4e-view-prefer-html t) (shr-color-visible-luminance-min 70) (shr-color-visible-distance-min 80) (mu4e-sent-messages-behavior 'sent) (mu4e-html-renderer 'w3m) (mu4e-change-filenames-when-moving t) (mu4e-view-show-addresses t) (mu4e-attachment-dir "~/Downloads") (mu4e-get-mail-command "mbsync -a") (mu4e-update-interval (* 5 60)) (mu4e-decryption-policy t) (mu4e-compose-signature-auto-include 't) (mu4e-compose-format-flowed t) (mml-secure-smime-sign-with-sender t) :config (require 'mu4e-contrib) (require 'org-mu4e) ;;(setq epg-debug t) ;;(setq mu4e-html2text-command "w3m -dump -T text/html") ;;(setq mu4e-html2text-command 'mu4e-shr2text) (setq smtpmail-stream-type 'starttls smtpmail-smtp-service 587) (setq smtpmail-queue-mail nil) (setq send-mail-function 'smtpmail-send-it message-send-mail-function 'smtpmail-send-it) (add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode) ;; don't keep message buffers around (setq message-kill-buffer-on-exit t)) (use-package nov :ensure t :mode ("\\.epub\\'" . nov-mode) :custom (nov-save-place-file (expand-file-name "emacs/nov-places" (xdg-cache-home))) :config (with-eval-after-load 'evil (evil-set-initial-state 'nov-mode 'emacs)) :preface (defun my-nov-setup () (visual-line-mode 1) (face-remap-add-relative 'variable-pitch :family "Times New Roman" :height 1.5) (if (fboundp 'olivetti-mode) (olivetti-mode 1))) :hook (nov-mode . my-nov-setup)) (use-package obsidian :ensure t :defer t :custom ;; This directory will be used for `obsidian-capture' if set. (obsidian-inbox-directory "Inbox") (obsidian-templates-directory "Templates") (obsidian-daily-notes-directory "Dailies") :general (private/set-leader-keys "no" #'obsidian-roam-capture "s#" '(obsidian-search :wk "obsidian search") "f#" '(obsidian-tag-find :wk "obsidian find")) (private/set-leader-keys :keymaps 'obsidian-mode-map "go" #'obsidian-jump) (:keymaps 'obsidian-mode-map ;; Replace C-c C-o with Obsidian.el's implementation. It's ok to use another key binding. "C-c C-o" #'obsidian-follow-link-at-point ;; Jump to backlinks "C-c C-b" #'obsidian-backlink-jump ;; If you prefer you can use `obsidian-insert-link' "C-c C-l" #'obsidian-insert-wikilink) :config (defun obsidian-roam-capture () "Create new obsidian note. In the `obsidian-inbox-directory' if set otherwise in `obsidian-directory' root." (interactive) (let* ((title (read-from-minibuffer "Title: ")) (date (format-time-string "%Y%m%d%H%M%S")) (filename (s-concat obsidian-directory "/" obsidian-inbox-directory "/" date "-" title ".md")) (clean-filename (s-replace "//" "/" filename))) (find-file (expand-file-name clean-filename) t) (save-buffer) (add-to-list 'obsidian-files-cache clean-filename))) (obsidian-specify-path "~/Documents/nca-notes") (global-obsidian-mode t)) (use-package paren :ensure nil :hook (prog-mode . show-paren-mode)) (use-package pass :ensure t :defer t) (use-package auth-source-pass ;; passwdstring ;; host: host.domain.com ;; user: user@domain.com ;; port: 993 :ensure t :hook (after-init . auth-source-pass-enable) :config (defun auth-pass-restart () "Restart the auth-password-store package" (interactive) (auth-pass-enable))) (use-package ob-d2 :after org :vc (:fetcher github :repo "dmacvicar/ob-d2") :config (org-babel-do-load-languages 'org-babel-load-languages '((d2 . t)))) (use-package plantuml-mode :ensure t :after org :custom (org-plantuml-jar-path "/usr/share/java/plantuml/plantuml.jar") :init (add-to-list 'org-src-lang-modes '("plantuml" . plantuml)) (org-babel-do-load-languages 'org-babel-load-languages '((plantuml . t)))) (use-package pdf-tools :mode ("\\.[pP][dD][fF]\\'" . pdf-view-mode) :magic ("%PDF" . pdf-view-mode) :custom ;; PDF Files (doc-view-continuous t) (pdf-view-display-size 'fit-page) (pdf-annot-activate-created-annotations t) :preface (defun my-pdf-set-midnight-colors () (setq pdf-view-midnight-colors `(,(face-foreground 'default) . ,(face-background 'default)))) ;; Workaround for pdf-tools not reopening to last-viewed page ;; https://github.com/politza/pdf-tools/issues/18 (defun my-pdf-set-last-viewed-bookmark () (interactive) (when (eq major-mode 'pdf-view-mode) (bookmark-set (my-pdf-generate-bookmark-name)))) (defun my-pdf-jump-last-viewed-bookmark () (when (my-pdf-has-last-viewed-bookmark) (bookmark-jump (my-pdf-generate-bookmark-name)))) (defun my-pdf-has-last-viewed-bookmark () (assoc (my-pdf-generate-bookmark-name) bookmark-alist)) (defun my-pdf-generate-bookmark-name () (concat "LAST-VIEWED: " (buffer-name))) (defun my-pdf-set-all-last-viewed-bookmarks () (dolist (buf (buffer-list)) (with-current-buffer buf (my-pdf-set-last-viewed-bookmark)))) :hook ((after-load-theme . my-pdf-set-midnight-colors) (kill-buffer . my-pdf-set-last-viewed-bookmark) (pdf-view-mode . my-pdf-jump-last-viewed-bookmark) (kill-emacs . (lambda () (unless noninteractive ; as `save-place-mode' does (my-pdf-set-all-last-viewed-bookmarks))))) :config (require 'pdf-occur) (define-pdf-cache-function pagelabels) ;; (pdf-tools-install t nil t t) ;; swiper doesn't work with pdf-tools so use normal isearch (define-key pdf-view-mode-map (kbd "C-s") 'isearch-forward)) (use-package popper :ensure t :general (general-nmap "gp" 'popper-toggle) (general-def "M-`" 'popper-cycle) (private/set-leader-keys "bc" 'popper-cycle "bp" 'popper-toggle-type "bk" '(popper-kill-latest-popup :wk "kill popper") "Tp" '(popper-toggle-latest :wk "popper")) :defer 1 :config (setq popper-reference-buffers '("\\*Messages\\*" "^\\*Warnings\\*" "[Oo]utput\\*$" "^\\*Compile-Log\\*" "^\\*Backtrace\\*" "^\\*evil-registers``*" "^\\*Apropos" "^Calc:" "^\\*Shell Command Output\\*" "\\*[Wo]*Man.*\\*" cheat-sh-mode dogears-list-mode bm-show-mode help-mode man-mode helpful-mode ibuffer-mode occur-mode eldoc-mode deadgrep-mode rg-mode inferior-scheme-mode term-mode shell-mode eshell-mode magit-stash-mode magit-status-mode "magit: .*" "\\*eshell\\*" process-menu-mode compilation-mode)) (setq popper-group-function #'popper-group-by-project) (setq popper-display-control nil) (popper-echo-mode 1) (popper-mode +1)) (use-package project :ensure t :demand t :general (private/set-leader-keys "gp" '(project-switch-project :wk "project") "p" '(:keymap project-prefix-map :wk "project")) (general-def :keymaps 'project-prefix-map "a" 'sjb/project-add-git-repo "." #'flymake-show-project-diagnostics "L" 'project-remember-projects-under "X" 'project-forget-project "Z" 'project-forget-zombie-projects) :config (defun sjb/set-tab-bar-name-to-project (&rest _) (when (project-current) (tab-bar-rename-tab (project-root (project-current))))) (advice-add 'project-switch-project :after #'sjb/set-tab-bar-name-to-project) (with-eval-after-load 'magit (defun sjb/set-frame-name-to-project (&rest _) (set-frame-name (concat "Project|" (project-root (project-current))))) (advice-add 'project-switch-project :after #'sjb/set-frame-name-to-project) (require 'magit) (defun sjb/project-add-git-repo () (interactive) (let ((project-root (magit-toplevel))) (if (and project-root (not (member `(,project-root) project--list))) (add-to-list 'project--list `(,project-root)) (message "Project already in the list.")) (project-current nil project-root) (sjb/set-frame-name-to-project)))) ;; Make sure project is initialized (project--ensure-read-project-list)) (use-package project-x :vc (:fetcher github :repo "karthink/project-x") :after project :custom (project-x-save-interval nil) ;Save project state every 5 min :init (with-eval-after-load 'project (add-to-list 'project-switch-commands '(?j "Restore windows" project-x-windows) t) (project-x-mode 1))) (use-package proced :ensure nil :defer t :custom (proced-enable-color-flag t) (proced-tree-flag t)) (use-package rainbow-delimiters :ensure t :hook (prog-mode . rainbow-delimiters-mode)) (use-package rainbow-mode :ensure t :hook (org-mode . rainbow-mode) (css-mode . rainbow-mode) (scss-mode . rainbow-mode) (sass-mode . rainbow-mode) (vue-mode . rainbow-mode)) (use-package ranger :ensure t :defer t :commands (ranger deer) :general (private/set-leader-keys "xr" 'ranger "xD" 'deer) :config (setq ranger-hide-cursor nil)) (use-package recentf :ensure nil :defer 1 :hook (after-init . recentf-mode) :config (defun my/recent-file-truename (file) (if (or (file-remote-p file nil t) (not (file-remote-p file))) (file-truename file) file)) (setq recentf-filename-handlers '(substring-no-properties ;; strip out lingering text properties my/recent-file-truename ;; resolve symlinks of local files abbreviate-file-name) ;; replace $HOME with ~ recentf-save-file (expand-file-name "recentf" user-emacs-directory) recentf-auto-cleanup 'never recentf-max-menu-items 0) ;; Exclude these from recentf (dolist (ex '("\\.gpg$" "^/scp:" "^/ssh:" "^/su:" "^/tmp/" "^/sudo:")) (add-to-list 'recentf-exclude ex)) (add-hook 'dired-mode-hook (lambda () (recentf-add-file default-directory))) (add-hook 'kill-emacs-hook #'recentf-cleanup) (setq recentf-save-file (expand-file-name "emacs/recentf" (xdg-cache-home)))) (use-package request :ensure t :defer t :custom (request-storage-directory (expand-file-name "emacs/request" (xdg-data-home)))) (use-package restclient :defer t :ensure t) (use-package ob-restclient :ensure t :defer t :after org :init (with-eval-after-load 'org (require 'ob-restclient))) (use-package rg :ensure t :defer t :general (private/set-leader-keys "s'" 'rg "s." 'rg-dwim)) (use-package saveplace :hook ((after-init . savehist-mode) (after-init . save-place-mode)) :custom (save-place t)) (use-package sidecar-locals :defer 1 :hook (after-init . sidecar-locals-mode) :config (setq sidecar-locals-paths-allow (list "/home/sjb/Projects/"))) (use-package shackle :ensure :diminish :hook (after-init . shackle-mode) :config (defun my-split-window-sensibly (&optional window) "replacement `split-window-sensibly' function which prefers vertical splits" (interactive) (let ((window (or window (selected-window)))) (or (and (window-splittable-p window t) (with-selected-window window (split-window-right))) (and (window-splittable-p window) (with-selected-window window (split-window-below)))))) (setq split-window-preferred-function #'split-window-sensibly) (setq shackle-rules '( ("\\*Cargo.*" :regexp t :other t :select nil) ("*Messages*" :select t :same nil :other t :popup t :inhibit-window-quit nil) ("*Warnings*" :select nil :other t :popup t :inhibit-window-quit nil) ("*go-guru-output*" :select t :same t) ("*Proced*" :select t :popup t :align below) ("*eldoc*" :select t :popup t :align right :size 0.4) ("*Buffer List*" :select t :align below :popup t :size 0.4) ("*evil-register* " :select nil :popup t :size 0.33) (ibuffer-mode :same nil :select t :popup t :size 0.33) (git-commit-mode :size 0.3 :popup t :select t) (magit-status-mode :select t :other t :align left :size 0.33) (magit-log-mode :align left :size 0.33 :select t) (magit-revision-mode :same t) (magit-process-mode :frame nil :popup t) (magit-mode-diff :popup t :same nil :other t) ("*Calendar*" :select t :size 0.3 :align below) ("\\*[Wo]*Man.*\\*" :regexp t :select t :inhibit-window-quit nil :popup t :align left) ("*info*" :select t :inhibit-window-quit t :same t) ("\\*Async Shell.*\\*" :regexp t :ignore t ) (" *transient*" :frame nil :popup t :select nil :align below) ; Magit helper popups ;; ** Proced ** (" *Marked Processes*" :frame nil :popup t :select t) ;; ** Byte-compiler ("*Compile-Log*" :frame nil :popup t :select t) ;; ** Local variables warning ** ("*Local Variables*" :same t :frame nil :popup t :select t) ;; ** Misc ** ("*Org PDF LaTeX Output*" :select nil) ("*Org Preview LaTeX Output*" :select nil) (" *undo-tree*" :frame nil) ("*Register Preview*" :frame nil :noselect t) (flycheck-error-list-mode :select t :align below :size 0.33) (dired-mode :select t :other t :same t) ((helpful-mode help-mode) :popup t :align right :inihibit-window-quit nil) ("^\\*Dictionary\\*" :popup t :size 0.12) (apropos-mode :select nil :popup nil :align below :size 0.2) (special-mode :select t :popup t :size 0.33 :inhibit-window-quit nil) (rg-mode :select t :popup t :size 0.33) (grep-mode :select t :popup t :size 0.33) (occur-mode :select t :popup t :size 0.33) (completion-list-mode :select nil :popup t :align below :size 0.12) (process-menu-mode :popup t :align below) (compilation-mode :select nil :align below :size 0.2 :inhibit-window-quit nil))) (setq shackle-select-reused-windows nil) ; default nil (setq shackle-default-alignment 'right) ; default below (setq shackle-default-size 0.4) ; default 0.5 (setq shackle-default-rule nil)) (use-package super-save :ensure t :hook (after-init . super-save-mode)) (use-package texfrag :ensure t :hook (markdown-mode . texfrag-mode)) (use-package time :ensure nil :hook (after-init . display-time) :custom (display-time-day-and-date t) (display-time-24hr-format t) ;; TODO (display-time-default-load-average t) (display-time-use-mail-icon t) (display-time-interval 10)) (use-package vterm :ensure t :defer t :commands vterm :config ;; Speed up vterm (setq vterm-timer-delay 0.01)) (use-package vundo :defer t :ensure t :custom (vundo-glyph-alist vundo-unicode-symbols)) (use-package uniquify :ensure nil :defer t :custom ;; TODO (uniquify-buffer-name-style 'reverse) (uniquify-separator " • ") (uniquify-after-kill-buffer-p t) (uniquify-ignore-buffers-re "^\\*")) (use-package wgrep :ensure t :commands wgrep-change-to-wgrep-mode :general (:keymaps 'grep-mode-map "C-c C-q" 'wgrep-change-to-wgrep-mode)) (use-package yasnippet :ensure t :defer 1 :hook (after-init . yas-global-mode) :diminish (yas-minor-mode . "γ") :general (general-def :keymaps 'yas-minor-mode-map "" #'yas-expand) (general-def :keymaps 'yas-keymap "C-e" 'yas/goto-end-of-active-field "C-a" 'yas/goto-start-of-active-field "C-n" 'yas-next-field-or-maybe-expand "C-p" 'yas-prev-field)) (use-package yasnippet-snippets :ensure t :after yasnippet) (use-package yankpad :ensure t :commands (yankpad-expand) :config (setq yankpad-file "~/.dotfiles/yankpad.org") (yankpad-reload)) (use-package zoxide :hook (find-file . zoxide-add) :general (general-nmap "gZ" 'zoxide-find-file)) (use-package zoom-window :ensure t :commands zoom-window-zoom :general (:keymaps 'evil-window-map "z" 'zoom-window-zoom)) (setq electric-pair-preserve-balance nil) (defun comment-auto-fill () (setq-local comment-auto-fill-only-comments t) (auto-fill-mode 1)) (defun default-prog-env-setup () (display-line-numbers-mode 1) ;; TODO (setq-local indent-tabs-mode nil) (subword-mode t) (comment-auto-fill)) ;;(setq font-lock-maximum-decoration '((c-mode . 2) (c++-mode . 2) (t . t))) (add-hook 'prog-mode-hook #'default-prog-env-setup) (add-to-list 'auto-mode-alist '("\\.ino\\'" . c-mode)) (setq gdb-many-windows t gdb-show-main t) (require 'ansi-color) (add-hook 'compilation-filter-hook 'ansi-color-compilation-filter) (add-hook 'comint-mode-hook 'ansi-color-for-comint-mode-on) (general-define-key :keymaps '(prog-mode-map c-mode-base-map) (kbd "C-c k") 'kill-compilation) ;;(setq compilation-environment '("TERM=tmux-256color")) (setq compilation-max-output-line-length nil) (add-hook 'compilation-mode-hook (lambda () ;; TODO (setq-local compilation-scroll-output t) (setq-local scroll-conservatively most-positive-fixnum) (setq-local scroll-margin 0))) (use-package eglot-booster :after eglot :hook (eglot-managed-mode . eglot-booster-mode) :vc (:fetcher github :repo "sjb/eglot-booster")) (use-package eglot :hook (eglot-managed-mode . sjb/setup-eglot) :after cape :general (general-evil-define-key 'normal eglot-mode-map "g=" 'eglot-format-buffer) (general-evil-define-key 'visual eglot-mode-map "g=" 'eglot-format) (general-evil-define-key 'normal eglot-mode-map [remap previous-error] 'flymake-goto-previous-error [remap next-error] 'flymake-goto-next-error) (private/set-leader-keys :keymaps 'eglot-mode-map "ca" '(eglot-code-actions :wk "code actions") "cA" '(eglot-code-action-inline :wk "code action") "ci" '(eglot-code-action-organize-imports :wk "organize imports") "ce" '(eglot-code-action-extract :wk "extract") "cw" '(eglot-code-action-rewrite :wk "rewrite") "cq" '(eglot-code-action-quickfix :wk "quickfix") "cr" '(eglot-rename :wk "rename") "cT" '(:ignore t :wk "toggle") "cTi" '(eglot-inlay-hints-mode :wk "inlay hints")) :custom (eglot-events-buffer-size 0) (eglot-sync-connect nil) (eglot-report-progress nil) (eglot-connect-timeout nil) (eglot-autoshutdown t) (eglot-send-changes-idle-timeout 1) (completion-category-defaults nil) (eldoc-echo-area-prefer-doc-buffer t) ;; display eldoc only in buffer not in minibuffer ;;(eldoc-display-functions '(eldoc-display-in-buffer)) (eldoc-documentation-strategy #'eldoc-documentation-compose) :init (defun sjb/setup-eglot () ;; Optionally configure the cape-capf-buster. ;;(add-hook 'flymake-diagnostic-functions #'eglot-flymake-backend nil t) ;; Show flymake diagnostics first. ;; (setq eldoc-documentation-functions ;; (cons #'flymake-eldoc-function ;; (remove #'flymake-eldoc-function eldoc-documentation-functions))) ;; Show all eldoc feedback. ;;(setq eldoc-documentation-strategy #'eldoc-documentation-compose) ;;(eldoc-mode 1) ;;(flymake-mode 1) ;;(setq-local font-lock-maximum-decoration nil) (setq-local completion-at-point-functions (list (cape-capf-super #'tabnine-completion-at-point #'eglot-completion-at-point)))) :config (fset #'jsonrpc--log-event #'ignore) ;; (setq jsonrpc-event-hook nil) ;; disable eldoc ;;(add-to-list 'eglot-stay-out-of 'eldoc) ;;(add-to-list 'eglot-stay-out-of 'flymake) ;;(setq eglot-ignored-server-capabilities '(:documentHighlightProvider)) ;; TODO (set-face-attribute 'eglot-inlay-hint-face nil :family "MonaspiceRn Nerd Font" :weight 'thin) (add-to-list 'eglot-server-programs '((c++-ts-mode c-ts-mode) . ("clangd" "-j=8" "--compile-commands-dir=build" "--background-index" "--cross-file-rename" "--completion-style=detailed" "--inlay-hints" "--pch-storage=memory" "--clang-tidy"))) ) (use-package dape :defer t :vc (:fetcher github :repo "svaante/dape")) (use-package compile-multi :vc (:fetcher github :repo "mohkale/compile-multi") :ensure t :defer t :general (general-def [remap compile] #'compile-multi) :config (with-eval-after-load 'project (defun sjb/project-current-root () (when-let (project (project-current)) (car (project-roots project)))) (setq compile-multi-default-directory #'sjb/project-current-root)) (setq compile-multi-config '(((file-exists-p "CMakeLists.txt") ("cmake:create" . "cmake -B build .") ("cmake:all" . "cmake --build build --target all") ("cmake:test" . "cmake --build build --target test")) ((file-exists-p "Makefile") ("make:build" . "make build") ("make:push" . "make push") ("make:all" . "make all")) ((file-exists-p "Cargo.toml") ("cargo:build" . "cargo build") ("cargo:run" . "cargo run") ("cargo:clean" . "cargo clean") ("cargo:test" . "cargo test") ("cargo:check" . "cargo check")) ((file-exists-p "build.zig") ("zig:build" . "zig build") ("zig:run" . "zig run")) ((file-expand-wildcards "*.sln") ("dotnet:build" . "dotnet build") ("dotnet:clean" . "dotnet clean") ("dotnet:nuget" . "dotnet nuget locals -c all") ("dotnet:pack" . "dotnet pack"))))) (use-package consult-compile-multi :ensure t :after consult :after compile-multi :defer 1 :config (consult-compile-multi-mode)) (use-package compile-multi-all-the-icons :ensure t :after all-the-icons-completion :after compile-multi :demand t) (use-package compile-multi-embark :ensure t :after embark :after compile-multi :demand t :config (compile-multi-embark-mode +1)) (use-package dumb-jump :hook (prog-mode . dumb-jump-mode) ;;(xref-backend-functions . dumb-jump-xref-activate) :general (general-nmap "g." #'dumb-jump-go) (private/set-leader-keys "gq" #'dumb-jump-quick-look) :custom (dumb-jump-disable-obsolete-warning t) ;;(xref-show-definitions-function #'xref-show-definitions-completing-read) :ensure t) (use-package editorconfig :ensure t :hook (prog-mode . editorconfig-mode) :custom (editorconfig-get-properties-function 'editorconfig-core-get-properties-hash)) (use-package hideshow :ensure t :hook ((prog-mode emacs-lisp-mode sh-mode) . hs-minor-mode) :config (defvar hs-overlay-map (make-sparse-keymap) "Keymap for hs minor mode overlay.") (defun hs-abstract-overlay (ov) (let* ((start (overlay-start ov)) (end (overlay-end ov)) (str (format " <%d lines> " (count-lines start end))) text) (setq text (propertize str 'face 'hs-block-flag-face 'help-echo (buffer-substring (1+ start) end))) (overlay-put ov 'display text) (overlay-put ov 'pointer 'hand) (overlay-put ov 'keymap hs-overlay-map))) (setq hs-set-up-overlay 'hs-abstract-overlay) (setq hs-isearch-open t)) (use-package ansible :ensure t :defer t) (use-package conf-mode :mode (;; systemd ("\\.service\\'" . conf-unix-mode) ("\\.timer\\'" . conf-unix-mode) ("\\.target\\'" . conf-unix-mode) ("\\.mount\\'" . conf-unix-mode) ("\\.automount\\'" . conf-unix-mode) ("\\.slice\\'" . conf-unix-mode) ("\\.socket\\'" . conf-unix-mode) ("\\.path\\'" . conf-unix-mode) ;; general ("conf\\(ig\\)?$" . conf-mode) ("rc\\(_local\\)?$" . conf-mode))) (use-package c-ts-mode :ensure t :defer t :custom (gdb-many-windows t) (gdb-show-main t)) (use-package clang-format :ensure t :general (c-mode-base-map "C-c C-f" 'clang-format-region) (private/set-leader-keys :keymaps 'c-mode-base-map "bf" 'clang-format-buffer) (general-evil-define-key 'normal c-mode-base-map "g=" 'clang-format-buffer) (general-evil-define-key 'visual c-mode-base-map "g=" 'clang-format-region) :init (setq clang-format-executable "clang-format")) (use-package cmake-ts-mode :ensure t :mode ("\\(?:CMakeLists\\.txt\\|\\.cmake\\)\\'" . cmake-ts-mode) :general (cmake-mode-map "C-h C-g" 'cmake-help)) (use-package cmake-ide :ensure t :hook (c-mode-common-hook . unpackaged/cmake-ide-setup) :commands (unpackaged/cmake-ide-setup) :general (c-mode-base-map "C-c D" 'invoke-gdb "C-c c" 'cmake-ide-compile) :config (defun unpackaged/cmake-ide-setup () (let ((root (ignore-errors (project-current)))) (when root (when (file-exists-p (expand-file-name "CMakeLists.txt" root)) (setq-local cmake-ide-build-dir (expand-file-name "build" root)) (message "cmake : %s" root) (cmake-ide-setup))))) (defun invoke-gdb () (interactive) (cd (cmake-ide--get-build-dir)) (gud-gdb (concat "gdb -i=mi --fullname " (cmake-ide--get-build-dir))))) (use-package disaster :ensure t :general (c-mode-base-map "C-c a" 'disaster)) (add-to-list 'auto-mode-alist '("\\.definition\\'" . nxml-mode)) (add-to-list 'auto-mode-alist '("\\.csproj\\'" . nxml-mode)) (use-package csharp-mode :ensure :init (with-eval-after-load 'eglot (add-to-list 'eglot-server-programs '(csharp-ts-mode . ("csharp-ls")))) :mode ("\\.cs\\'" . csharp-ts-mode) ("\\.cake\\'" . csharp-ts-mode)) (use-package dotnet :ensure t :defer t :init (setq dotnet-mode-keymap-prefix (kbd "C-c n"))) (use-package csv-mode :ensure t :defer t) (use-package dart-mode :ensure t :custom (dart-sdk-path (concat (getenv "HOME") "/.flutter/bin/cache/dark-sdk/")) :defer t) (use-package hover :ensure t :general (:keymaps 'dart-mode-map "C-M-z" #'hover-run-or-hot-reload "C-M-x" #'hover-run-or-hot-restart "C-M-p" #'hover-take-screenshot) :init (setq flutter-sdk-path (concat (getenv "HOME") "/.flutter") hover-command-path (concat (getenv "HOME") "/go/bin/hover") hover-hot-reload-on-save t hover-screenshot-path (concat (getenv "HOME") "/Pictures") hover-screenshot-prefix "flutter-hover-" hover-observatory-uri "http://localhost:50300" hover-clear-buffer-on-hot-restart t)) (use-package ein :defer t :custom (ein:jupyter-server-use-subcommand "notebook") (ein:output-area-inlined-images t) :config (require 'ein) (require 'ein-notebook)) (use-package go-ts-mode :ensure t :mode ("\\.go\\'" . go-ts-mode) :general (go-mode-map "C-c C-r" 'go-run-main "C-c C-d" 'godoc-at-point "C-h C-g" 'godoc) :custom (go-play-browse-function 'browse-url) :init (defvar go-tools-gopath (expand-file-name "go" (getenv "HOME"))) (defvar go-tools-bin (expand-file-name "bin" go-tools-gopath)) :config (setq exec-path (append exec-path (list go-tools-bin))) (setq gofmt-command (cond ((executable-find "goimports") "goimports") (t "gofmt")))) (use-package js :mode ("\\.js\\'" . js-ts-mode) :init (setq js-chain-indent t) (setq js-indent-level 2) (setq js-indent-first-init 'dynamic)) (use-package json-mode :ensure t :defer t :mode "\\.json\\'" :config (with-eval-after-load 'flycheck (setq-default flycheck-disabled-checkers (append flycheck-disabled-checkers '(json-jsonlist))))) (use-package json-ts-mode :ensure t :mode ("\\.json\\'" . json-ts-mode)) (use-package julia-ts-mode :ensure t :mode ("\\.jl\\'" . julia-ts-mode)) (use-package julia-repl :ensure t :hook (julia-ts-mode julia-repl-mode)) (use-package kotlin-ts-mode :ensure t :mode ("\\.kt\\'" . kotlin-ts-mode)) (use-package lua-mode :ensure t :mode "\\.lua\\'") (use-package matlab-mode :ensure t :mode "\\.m\\'" :defer t :custom (matlab-shell-command "~/.local/bin/matlab") (matlab-shell-command-switches (list "-nodisplay -nosplash")) :config (matlab-cedet-setup)) (use-package markdown-mode :ensure t :commands (markdown-mode gfm-mode) :custom (markdown-enable-math t) (markdown-enable-html t) (markdown-fontify-code-block-natively t) (markdown-fontify-whole-heading-line t) (markdown-hide-markup t) :mode (("README\\.md\\'" . gfm-mode) ("\\.md\\'" . markdown-mode) ("\\.text\\'" . markdown-mode) ("\\.markdown\\'" . markdown-mode))) (use-package nix-mode :ensure t :mode ("\\.nix\\'" . nix-mode) :config (use-package nix-ts-mode :ensure t)) (use-package php-mode :ensure t :mode "\\.php\\'") (use-package pyvenv :ensure t :defer t :custom (pyvenv-menu t) :hook ((python-ts-mode . pyvenv-mode) (pyvenv-post-activate . pyvenv-restart-python)) :config ;; Setting work on to easily switch between environments (setq pyvenv-workon "emacs") (setenv "WORKON_HOME" (expand-file-name "~/.cache/envs/")) (pyvenv-tracking-mode 1)) (use-package qml-mode :ensure t :mode "\\.qml\\'") (use-package r-ts-mode :mode ("\\.R\\'" . r-ts-mode) :vc (:fetcher github :repo "sje30/r-ts-mode") :ensure t) ;; rust-ide (use-package rust-mode :mode ("\\.rs\\'" . rust-mode) :ensure t :defer t :custom (rust-mode-treesitter-derive t) :init (setq rust-mode-treesitter-derive t) :config (require 'rust-compile) (require 'rust-cargo) (require 'rust-playpen) (require 'rust-rustfmt) (with-eval-after-load 'eglot (add-to-list 'eglot-server-programs '((rust-ts-mode rust-mode) . ("rust-analyzer" :initializationOptions ( :procMacro (:enable t) :cargo ( :buildScripts (:enable t) :features "all"))))))) (use-package cargo :ensure t :hook ((rust-mode rust-ts-mode) . cargo-minor-mode) :config (setq exec-path (append exec-path '("~/.cargo/bin")))) (use-package toml-mode :ensure t :mode "\\.toml\\'") (use-package swift-mode :ensure t :mode "\\.swift\\'") (use-package typescript-ts-mode :ensure t :mode ("\\.ts\\'" . typescript-ts-mode) :config (setq typescript-indent-level 4)) (use-package svelte-mode :defer t :ensure t :custom (svelte-basic-offset 4)) (define-derived-mode vue-mode web-mode "Vue" "Major mode for editing Vue code.") (add-to-list 'auto-mode-alist '("\\.vue\\'" . vue-mode)) (with-eval-after-load 'web-mode (add-to-list 'web-mode-comment-formats '("javascript" . "//"))) (setq imenu-generic-expression '(("html" "^