;;; -*- lexical-binding: t -*- (defun tangle-init () "If the current buffer is init.org the code-blocks are tangled, and the tangled file is compiled." (when (equal (buffer-file-name) (expand-file-name (concat user-emacs-directory "init.org"))) ;; Avoid running hooks when tangling. (let ((prog-mode-hook nil)) (org-babel-tangle) ;; (byte-compile-file (concat user-emacs-directory "init.el")) ))) (add-hook 'after-save-hook 'tangle-init) (setq gc-cons-percentage 0.6) (setq read-process-output-max (* 1024 1024)) ;; 1mb (setq idle-update-delay 1.0) (dolist (mode '(tool-bar-mode scroll-bar-mode menu-bar-mode blink-cursor-mode)) (funcall mode 0)) (setq ring-bell-function 'ignore initial-scratch-message nil inhibit-startup-message t use-dialog-box nil) (defvar emacs-autosave-directory (concat user-emacs-directory "autosaves/") "This variable dictates where to put auto saves. It is set to a directory called autosaves located wherever your .emacs.d/ is located.") ;; Sets all files to be backed up and auto saved in a single directory. (setq backup-directory-alist `((".*" . ,emacs-autosave-directory)) auto-save-file-name-transforms `((".*" ,emacs-autosave-directory t))) (defvar bootstrap-version) (let ((bootstrap-file (expand-file-name "straight/repos/straight.el/bootstrap.el" (or (bound-and-true-p straight-base-dir) user-emacs-directory))) (bootstrap-version 7)) (unless (file-exists-p bootstrap-file) (with-current-buffer (url-retrieve-synchronously "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" 'silent 'inhibit-cookies) (goto-char (point-max)) (eval-print-last-sexp))) (load bootstrap-file nil 'nomessage)) (straight-use-package 'use-package) (setq straight-use-package-by-default t) (use-package org :straight (:type built-in)) (defvar local-lisp (concat user-emacs-directory "local-lisp/")) (add-to-list 'load-path local-lisp) (let ((default-directory local-lisp)) (normal-top-level-add-subdirs-to-load-path)) (set-language-environment "UTF-8") (delete-selection-mode t) ;; Replace selected text when yanking (dirtrack-mode t) ;; Directory tracking in shell (global-so-long-mode t) ;; Mitigate performance for long lines (global-visual-line-mode t) ;; Break lines instead of truncating them (global-auto-revert-mode t) ;; Revert buffers automatically when they change (recentf-mode t) ;; Remember recently opened files (savehist-mode t) ;; Remember minibuffer prompt history (save-place-mode t) ;; Remember last cursor location in file (show-paren-mode t) ;; Highlight matching parentheses (setq-default tab-width 4 fill-column 80 indent-tabs-mode nil) (setq use-short-answers t) (setq initial-major-mode 'org-mode) (use-package exec-path-from-shell :straight t :config (when (daemonp) (exec-path-from-shell-initialize))) (use-package keychain-environment :straight t :init (keychain-refresh-environment)) (use-package keychain-environment :straight t :defer t :config (keychain-refresh-environment)) (defvar custom-bindings-map (make-keymap) "A keymap for custom keybindings.") (define-minor-mode custom-bindings-mode "A mode that activates custom keybindings." :init-value t :keymap custom-bindings-map) (add-to-list 'default-frame-alist '(internal-border-width . 8 )) (set-fringe-mode 4) (setq-default fringes-outside-margins 0) (setq-default indicate-buffer-boundaries nil) (setq-default indicate-empty-lines nil) (set-face-attribute 'header-line t :inherit 'default) (use-package gruvbox-theme :straight t) ;; doom needs this somehow (use-package all-the-icons :straight t) (use-package doom-themes :straight t :config (setq doom-themes-enable-bold t doom-themes-enable-italic t) (doom-themes-org-config)) (defvar nemo/dark-theme 'gruvbox-dark-medium) (defvar nemo/light-theme 'gruvbox-light-medium) (add-hook 'after-init-hook (lambda () (load-theme nemo/dark-theme t))) (defadvice load-theme (before disable-before-load (theme &optional no-confirm no-enable) activate) (mapc 'disable-theme custom-enabled-themes)) (defun nemo/set-light-theme () "load the light theme." (interactive) (load-theme nemo/light-theme t)) (defun nemo/set-dark-theme () "load the dark theme." (interactive) (load-theme nemo/dark-theme t)) (setq help-window-select t help-window-keep-selected t) (defvar nemo/font-height-mono 110) (defvar nemo/font-height-sans 120) (defun apply-if-gui (&rest action) "apply ACTION if emacs is run in GUI context, regardless of daemonp or display-graphic-p" (if (daemonp) (add-hook 'after-make-frame-functions (lambda (frame) (select-frame frame) (if (display-graphic-p frame) (apply action)))) (if (display-graphic-p) (apply action)))) (set-face-attribute 'default nil :font "monospace" :height nemo/font-height-mono) (set-face-attribute 'fixed-pitch nil :font "monospace" :height nemo/font-height-mono) (set-face-attribute 'variable-pitch nil :font "sans-serif" :height nemo/font-height-sans) ;; (when (member "SF Mono" (font-family-list)) ;; (set-face-attribute 'default nil :font "SF Mono" :height nemo/font-height-mono) ;; (set-face-attribute 'fixed-pitch nil :family "SF Mono" :height nemo/font-height-mono)) (when (member "SF Pro Text" (font-family-list)) (set-face-attribute 'variable-pitch nil :family "SF Pro Text" :height nemo/font-height-sans)) (defvar nemo/nerd-fonts-font "Symbols Nerd Font") (defun nemo/set-fallback-fonts () "Set fallback fonts for icons/symbols." (set-fontset-font t nil (font-spec :height nemo/font-height-mono :font nemo/nerd-fonts-font)) ) (apply-if-gui #'nemo/set-fallback-fonts) (use-package nerd-icons :straight t) (use-package emojify :straight t :config (when (member "Apple Color Emoji" (font-family-list)) (set-fontset-font t 'symbol (font-spec :family "Apple Color Emoji") nil 'prepend))) (use-package mixed-pitch :straight t :hook ((org-mode . mixed-pitch-mode) (LaTeX-mode . mixed-pitch-mode))) ;; Mode line setup (column-number-mode t) ;; Show current column number in mode line (setq-default mode-line-format '((:propertize "λ" face mode-line-emphasis) " " mode-line-buffer-identification " " ; read-only or modified status (:eval (cond (buffer-read-only (propertize "  " 'face 'mode-line-read-only-face)) ((buffer-modified-p) (propertize " 󰳻 " 'face 'mode-line-modified-face)) (t "  " 'face 'mode-line))) ; directory and buffer/file name (:propertize (:eval (shorten-directory default-directory 30)) face mode-line-folder-face) (:propertize "%b" face mode-line-filename-face) ;; Version control info (:eval (when-let (vc vc-mode) ;; Use a pretty branch symbol in front of the branch name (list (propertize " " 'face 'font-lock-keyword-face) (propertize (substring vc 5) 'face 'font-lock-doc-face)))) " " (:propertize mode-name) (:propertize (length local-minor-modes)) ; (global-mode-string global-mode-string) (:eval (propertize " " 'display `((space :align-to (- (+ right right-fringe right-margin) ,(+ 1 (string-width "%p %4l:%c"))))))) ;; Line and column numbers mode-line-percent-position " " (:propertize "%4l:" face mode-line-position-face) (:eval (propertize "%c" 'face (if (>= (current-column) 80) 'mode-line-80col-face 'mode-line-position-face))) )) ;; Helper function (defun shorten-directory (dir max-length) "Show up to `max-length' characters of a directory name `dir'." (let ((path (reverse (split-string (abbreviate-file-name dir) "/"))) (output "")) (when (and path (equal "" (car path))) (setq path (cdr path))) (while (and path (< (length output) (- max-length 4))) (setq output (concat (car path) "/" output)) (setq path (cdr path))) (when path (setq output (concat ".../" output))) output)) ;; Extra mode line faces (make-face 'mode-line-read-only-face) (make-face 'mode-line-modified-face) (make-face 'mode-line-folder-face) (make-face 'mode-line-filename-face) (make-face 'mode-line-position-face) (make-face 'mode-line-mode-face) (make-face 'mode-line-80col-face) (set-face-attribute 'mode-line-read-only-face nil :inherit 'mode-line-face :foreground "#4271ae" :box '(:line-width 2 :color "#4271ae")) (set-face-attribute 'mode-line-modified-face nil :inherit 'mode-line-face :foreground "#c82829" :background "#ffffff" :box '(:line-width 2 :color "#c82829")) (set-face-attribute 'mode-line-folder-face nil :inherit 'mode-line-face :foreground "gray60") (set-face-attribute 'mode-line-filename-face nil :inherit 'mode-line-face :foreground "#eab700" :weight 'bold) (set-face-attribute 'mode-line-position-face nil :inherit 'mode-line-face) (set-face-attribute 'mode-line-mode-face nil :inherit 'mode-line-face :foreground "gray80") (set-face-attribute 'mode-line-80col-face nil :inherit 'mode-line-position-face :foreground "black" :background "#eab700") (defconst nemo/leader-evil "SPC") (defconst nemo/leader-global "C-c") (defconst nemo/major-key "m") (defconst nemo/leader-major-evil (concat nemo/leader-evil " " nemo/major-key)) (defconst nemo/leader-major-global (concat nemo/leader-global " " nemo/major-key)) (use-package general :straight t :config (general-define-key :states '(emacs normal) :prefix-map 'nemo/leader-prefix-map :prefix-command 'nemo/leader-prefix-command :global-prefix nemo/leader-global :prefix nemo/leader-evil) (general-create-definer leader-def :prefix-command 'nemo/leader-prefix-command :prefix-map 'nemo/leader-prefix-map) (general-create-definer leader-other-def :states '(emacs normal) :prefix-map 'nemo/leader-prefix-map :prefix-command 'nemo/leader-prefix-command :global-prefix nemo/leader-global :prefix nemo/leader-evil ) (general-create-definer leader-major-def :states '(emacs normal) :global-prefix nemo/leader-global :prefix nemo/leader-evil ) ;; magit uses with-editor-mode to spawn the git process ;; in with the emacs client as the $EDITOR (general-def '(emacs normal) 'with-editor-mode-map ",," 'with-editor-finish) (leader-def "" #'nemo/switch-to-last-buffer "" #'completion-at-point "d" #'duplicate-line "gb" #'xref-go-back "gf" #'xref-go-forward "bk" #'switch-to-prev-buffer "bp" #'switch-to-prev-buffer "bj" #'switch-to-next-buffer "bn" #'switch-to-next-buffer "bb" #'consult-buffer "bd" #'kill-current-buffer "bs" #'scratch-buffer "wd" #'delete-window "wo" #'delete-other-windows "ff" #'find-file "fi" '("Edit init.org" . nemo/edit-init-org) "fs" '("Save" . save-buffer) "fr" '("rg" . consult-ripgrep) "fR" '("rg in dir" . nemo/consult-ripgrep-dir) ) ) (use-package engine-mode :straight t :defer t :config (defengine duckduckgo "https://duckduckgo.com/?q=%s" :keybinding "g") (defengine twitter "https://twitter.com/search?q=%s" :keybinding "x") (defengine wikipedia "https://www.wikipedia.org/search-redirect.php?language=en&go=Go&search=%s" :keybinding "w" :docstring "Searchin' the wikis.") (defengine wiktionary "https://www.wikipedia.org/search-redirect.php?family=wiktionary&language=en&go=Go&search=%s" :keybinding "d") (defengine wolfram-alpha "https://www.wolframalpha.com/input/?i=%s") (defengine youtube "https://www.youtube.com/results?aq=f&oq=&search_query=%s" :keybinding "y") (engine-mode t) ) (use-package diff-hl :straight t :config (global-diff-hl-mode)) (use-package magit :straight t :defer t :general (leader-def "gSh" 'magit-status-here "gs" #'magit-status "gSb" 'magit-blame) :config (setq magit-mode-quit-window 'magit-restore-window-configuration ediff-window-setup-function #'ediff-setup-windows-plain ediff-merge-split-window-function #'split-window-horizontally ;;magit-auto-revert-mode t )) (use-package forge :straight t :after magit) (use-package which-key :straight t :config (which-key-mode)) (use-package rainbow-delimiters :straight t :hook (prog-mode . rainbow-delimiters-mode)) (use-package evil :straight t :init (setq evil-want-C-u-scroll t) (setq evil-want-keybinding nil) (setq evil-want-integration t) (setq evil-undo-system 'undo-fu) :config (evil-mode 1) (leader-def "wj" 'evil-window-down "wk" 'evil-window-up "wh" 'evil-window-left "wl" 'evil-window-right ) (defun nemo/evil-search-forward--push-xref (&optional _regex-p _no-recursive-edit) "push current marker to xref stack when forward searching." (xref-push-marker-stack)) (advice-add #'evil-search-forward :before #'nemo/evil-search-forward--push-xref '((name . "evil-search-push-xref"))) ) (use-package evil-surround :straight t :defer t :config (global-evil-surround-mode 1)) (use-package evil-collection :after evil :straight t :init (setq evil-collection-key-blacklist '("C-c " "")) :config (evil-collection-init)) (use-package undo-fu :straight t :defer t) (use-package projectile :straight t :defer t :general (leader-def "p" '(:keymap project-prefix-map :wk "Projectile") ) :config (setq projectile-project-search-path '("~/code/")) (projectile-mode)) (use-package ripgrep :straight t :defer t) (use-package rg :straight t :defer t) (use-package wgrep :straight t :defer t) (use-package vterm :straight t) (defun nemo/abort-minibuffer-if-active () "Abort the minibuffer if it is active." (interactive) (when (active-minibuffer-window) (abort-recursive-edit))) (global-set-key (kbd "") 'nemo/abort-minibuffer-if-active) (use-package olivetti :straight t :defer t ;; :bind (:map custom-bindings-map ("C-c o" . olivetti-mode)) :hook (org-mode . olivetti-mode) :hook (olivetti-mode-on . (lambda () (olivetti-set-width 88))) :config (setq olivetti-style t)) (use-package jinx :straight t :hook (emacs-startup . global-jinx-mode) :bind (("M-$" . jinx-correct) ("C-M-$" . jinx-languages)) :config (leader-def "Ss" 'jinx-correct) (setq jinx-languages "en_GB dk_DK de_DE")) (use-package ispell :straight t :defer t :config (setq ispell-dictionary "en_GB")) (use-package auctex :straight t :hook (LaTeX-mode . turn-on-prettify-symbols-mode) (LaTeX-mode . reftex-mode) ;; (LaTeX-mode . (lambda () (corfu-mode -1))) ;; (LaTeX-mode . outline-minor-mode) (LaTeX-mode . olivetti-mode) :config (setq TeX-view-program-selection '((output-pdf "PDF Tools")) TeX-view-program-list '(("PDF Tools" TeX-pdf-tools-sync-view)) TeX-source-correlate-start-server t)) (use-package pdf-tools :straight t :defer t :mode ("\\.pdf\\'" . pdf-view-mode) :config (pdf-loader-install) (setq-default pdf-view-display-size 'fit-height) (setq pdf-view-continuous t) (setq +latex-viewers '(pdf-tools)) (leader-major-def :keymaps 'pdf-view-mode-map "g b" #'pdf-history-backward "g f" #'pdf-history-forward) (general-def :keymaps 'pdf-view-mode-map "j" (lambda() (interactive) (pdf-view-scroll-up-or-next-page 20)) "k" (lambda() (interactive) (pdf-view-scroll-down-or-previous-page 20))) ) (use-package org :straight (:type built-in) :defer t :hook (org-mode . variable-pitch-mode) ;; I basically always want to be running =visual-line-mode= anyway, but certainly in org-mode. :hook (org-mode . visual-line-mode) :hook (org-mode . nemo/prettify-symbols-setup) :general-config (general-define-key :prefix-map 'nemo/org-map "i" '(:ignore t :which-key "Insert..") "ih" '("Heading" . org-insert-heading) "is" '("Subheading" . org-insert-subheading) "ii" '("Item" . org-insert-item) "ib" '("Block..". org-insert-structure-template) "il" '("Link" . org-insert-link) ) (leader-major-def :keymaps 'org-mode-map "m" '(:keymap nemo/org-map :wk "Org") ) (general-def 'normal 'org-src-mode-map ",," 'org-edit-src-exit) (general-def 'normal 'org-mode-map "TAB" 'org-cycle "RET" 'org-open-at-point) :config (custom-set-faces '(org-document-title ((t (:height 1.8)))) '(outline-1 ((t (:height 1.35)))) '(outline-2 ((t (:height 1.3)))) '(outline-3 ((t (:height 1.2)))) '(outline-4 ((t (:height 1.1)))) '(outline-5 ((t (:height 1.1)))) '(outline-6 ((t (:height 1.1)))) '(outline-8 ((t (:height 1.1)))) '(outline-9 ((t (:height 1.1))))) (setq org-startup-folded 'content) (setq org-startup-with-latex-preview t) (setq org-startup-with-inline-images t) (plist-put org-format-latex-options :scale 1.35) (setq org-adapt-indentation t org-hide-leading-stars t org-pretty-entities-include-sub-superscripts t org-pretty-entities t) (setq org-src-fontify-natively t org-src-tab-acts-natively t org-edit-src-content-indentation 0) ) (use-package ox-epub :straight t) (use-package org-fragtog :straight t :hook (org-mode . org-fragtog-mode)) (use-package org-appear :straight t :commands (org-appear-mode) :hook (org-mode . org-appear-mode) :config (setq org-hide-emphasis-markers t) (setq org-appear-autoemphasis t ;; show /../ *..* =..= ~..~ tokens org-appear-autolinks t ;; show link hyperlinks when editing org-appear-autosubmarkers t)) ;; show _.._ and superscript markers (use-package org-modern :straight t :defer t :after org :hook (org-mode . org-modern-mode)) (defun nemo/prettify-symbols-setup () ;; org-babel (push '("#+BEGIN_SRC" . ?≫) prettify-symbols-alist) (push '("#+END_SRC" . ?≫) prettify-symbols-alist) (push '("#+begin_src" . ?≫) prettify-symbols-alist) (push '("#+end_src" . ?≫) prettify-symbols-alist) (push '("#+BEGIN_QUOTE" . ?❝) prettify-symbols-alist) (push '("#+END_QUOTE" . ?❞) prettify-symbols-alist) (prettify-symbols-mode)) (use-package svg-tag-mode :straight t :config (setq svg-tag-tags '((":TODO:" . ((lambda (tag) (svg-tag-make "TODO")))))) ) (require 'org) (setq org-agenda-start-on-weekday nil org-agenda-block-separator nil org-agenda-remove-tags t) (use-package org-super-agenda :straight t :after org :config (org-super-agenda-mode)) (setq org-agenda-files (list "~/Shared/agenda.org" "~/notes.org" "~/projects.org")) (add-hook 'emacs-startup-hook (lambda () (progn (org-agenda nil "a") (delete-other-windows) (olivetti-mode)))) (use-package move-text :straight t :defer t :bind (("M-j" . move-text-down) ("M-k" . move-text-up))) (use-package treemacs :straight t ;; hijack projectile prefix because they fit together :general (general-define-key :prefix-map 'project-prefix-map "t" '("Treemacs" . treemacs-select-window) ) :config (setq treemacs-width 25) ) (use-package treemacs-evil :after (treemacs evil) :straight t) (use-package treemacs-projectile :after (treemacs projectile) :straight t) (use-package treemacs-icons-dired :hook (dired-mode . treemacs-icons-dired-enable-once) :straight t) (use-package treemacs-magit :after (treemacs magit) :straight t) (use-package vertico :straight t :bind (:map minibuffer-local-map ("C-h" . backward-kill-sexp)) :config (vertico-mode 1) (setq vertico-count 25 completion-ignore-case t read-buffer-completion-ignore-case t read-file-name-completion-ignore-case t) (vertico-multiform-mode) ) (use-package vertico-posframe :straight t ;; Ensure posframe is always restored when exiting a minibuffer :hook (minibuffer-exit . (lambda () (vertico-posframe-mode 1))) :config (vertico-posframe-mode 1) (setq vertico-posframe-height vertico-count vertico-multiform-commands '((consult-line (:not posframe)) (consult-ripgrep (:not posframe)) (nemo/consult-ripgrep (:not posframe)) (nemo/consult-ripgrep-dir (:not posframe)) (lsp-find-references (:not posframe)) (embark-act (:not posframe)) (t posframe)) )) (use-package savehist :straight t :init (savehist-mode)) (use-package consult :straight t :bind (:map custom-bindings-map ("C-x b" . consult-buffer) ("M-g g" . consult-goto-line)) :init (setq xref-show-xrefs-function #'consult-xref xref-show-definitions-function #'consult-xref) :config ()) (defun nemo/exec-without-posframe (fn &rest args) "Execute FN with ARGS while temporarily disabling vertico-posframe-mode." (vertico-posframe-mode -1) (unwind-protect (apply fn args) (vertico-posframe-mode 1))) (defun nemo/consult-line () (interactive) (nemo/exec-without-posframe #'consult-line)) (defun nemo/consult-ripgrep (&rest args) (interactive) (apply #'consult-ripgrep args)) (defun nemo/consult-ripgrep-dir () "Call consult-ripgrep in a user-specified directory." (interactive) (let ((dir (read-directory-name "Ripgrep directory: "))) (consult-ripgrep dir)) ) (bind-key "C-s" 'consult-line custom-bindings-map) (bind-key "C-M-s" 'consult-ripgrep custom-bindings-map) (use-package marginalia :straight t :init (marginalia-mode 1)) (use-package corfu :straight t :hook ((prog-mode text-mode) . completion-preview-mode) :custom ;; Enable auto completion (corfu-auto t) ;; Enable cycling for `corfu-next/previous' (corfu-cycle t) ;; No delay (corfu-auto-delay 0) ;; Start when this many characters have been typed (corfu-auto-prefix 1) ;; Short delay (corfu-popupinfo-delay 0.5) ;; Preselect the first suggestion (corfu-preselect nil) (corfu-on-exact-match nil) ;; Don't automatically fill in the selected candidate (corfu-preview-current nil) :custom (lsp-completion-provider :none) :init (defun nemo/orderless-dispatch-flex-first (_pattern index _total) (and (eq index 0) 'orderless-flex)) (defun nemo/lsp-mode-setup-completion () (setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults)) '(orderless)) (add-hook 'orderless-style-dispatchers #'nemo/orderless-dispatch-flex-first nil 'local)) :hook (lsp-completion-mode . nemo/lsp-mode-setup-completion) :config (global-corfu-mode)) (use-package corfu-terminal :straight t :defer t :hook (before-make-frame . (lambda () (corfu-terminal-mode (if (display-graphic-p) -1 +1)))) ) ;; (use-package emacs ;; ;; :custom ;; ;; TODO ;; :init ;; ;; TAB cycle if there are only few candidates ;; ;; (setq completion-cycle-threshold 3) ;; (setq enable-recursive-minibuffers t) ;; ;; Hide commands in M-x which do not apply to the current mode. Corfu ;; ;; commands are hidden, since they are not supposed to be used via M-x. ;; (setq read-extended-command-predicate ;; #'command-completion-default-include-p) ;; (setq text-mode-ispell-word-completion nil) ;; ;; Enable indentation+completion using the TAB key. ;; ;; `completion-at-point' is often bound to M-TAB. ;; (setq tab-always-indent 'complete) ;; ) (use-package kind-icon :straight t :after corfu :config (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter)) (use-package cape :straight t ;; Bind dedicated completion commands ;; Alternative prefix keys: C-c p, M-p, M-+, ... ;; :bind (("C-c p p" . completion-at-point) ;; capf ;; ("C-c p t" . complete-tag) ;; etags ;; ("C-c p d" . cape-dabbrev) ;; or dabbrev-completion ;; ("C-c p h" . cape-history) ;; ("C-c p f" . cape-file) ;; ("C-c p k" . cape-keyword) ;; ("C-c p s" . cape-symbol) ;; ("C-c p a" . cape-abbrev) ;; ("C-c p l" . cape-line) ;; ("C-c p w" . cape-dict) ;; ("C-c p \\" . cape-tex) ;; ("C-c p _" . cape-tex) ;; ("C-c p ^" . cape-tex) ;; ("C-c p &" . cape-sgml) ;; ("C-c p r" . cape-rfc1345)) :init ;; Add `completion-at-point-functions', used by `completion-at-point'. ;; NOTE: The order matters! ;; (add-to-list 'completion-at-point-functions #'cape-capf-buster) ;; (add-to-list 'completion-at-point-functions #'cape-dabbrev) ;; (add-to-list 'completion-at-point-functions #'cape-file) ;; (add-to-list 'completion-at-point-functions #'cape-elisp-block) ;; (add-to-list 'completion-at-point-functions #'cape-history) ;; (add-to-list 'completion-at-point-functions #'cape-keyword) ;; (add-to-list 'completion-at-point-functions #'cape-tex) ;; (add-to-list 'completion-at-point-functions #'cape-dict) ;; (add-to-list 'completion-at-point-functions #'cape-sgml) ;; (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-symbol) ;; (add-to-list 'completion-at-point-functions #'cape-line) ) (use-package prescient :straight t :config (add-to-list 'completion-styles 'prescient) (add-to-list 'prescient-filter-method 'fuzzy)) (use-package orderless :straight t :config (add-to-list 'completion-styles 'orderless) (setq orderless-matching-styles '(orderless-flex) completion-category-overrides '((file (styles basic partial-completion))) orderless-component-separator "[ |]") ) (add-hook 'prog-mode-hook 'hs-minor-mode) (use-package inheritenv :straight t) (use-package envrc :straight t :hook (after-init . envrc-global-mode)) (use-package hl-todo :straight t :hook ((prog-mode) . hl-todo-mode) :config (setq hl-todo-keyword-faces '(("TODO" . "#e78a4e"))) ) (use-package copilot :straight (:host github :repo "copilot-emacs/copilot.el" :files ("*.el")) :ensure t :hook ((prog-mode markdown-mode conf-toml-mode) . copilot-mode) :bind ( ("TAB" . 'copilot-accept-completion) ("C-" . 'copilot-accept-completion) ("M-" . 'copilot-accept-completion-by-word) ("C-S-" . 'copilot-accept-completion-by-line) ) ) (use-package copilot-chat :straight (:host github :repo "chep/copilot-chat.el" :files ("*.el")) :after (org markdown-mode) :general (leader-def "cg" '("Generate commit message" . copilot-chat-insert-commit-message) "cG" '("Regenerate commit message" . copilot-chat-regenerate-commit-message) "cC" '("Open Copilot Chat" . copilot-chat-display) "cba" '("Add Buffer to Copilot" . copilot-chat-add-current-buffer) "cbd" '("Remove Buffer from Copilot" . copilot-chat-del-current-buffer) "cbw" '("Add Workspace to Copilot" . copilot-chat-add-workspace) "cbf" #'copilot-chat-add-file "cbb" '("List Buffers visible to Copilot" . copilot-chat-list) "cch" #'copilot-chat-hide "ccx" #'copilot-chat-reset "ccb" #'copilot-chat-switch-to-buffer "ccd" #'copilot-chat-doc "ccr" #'copilot-chat-review "ccm" #'copilot-chat-set-model "cy" '("Past latest code block" . copilot-chat-yank) ) ) (use-package smartparens :straight t :hook ((prog-mode text-mode markdown-mode) . smartparens-mode) :config (require 'smartparens-config)) (use-package flycheck :straight t :defer t :hook (after-init. global-flycheck-mode) :config) (use-package yasnippet :straight t :defer t :hook ((prog-mode text-mode) . yas-minor-mode)) (use-package yasnippet-snippets :straight t) (use-package lsp-mode :straight t :defer t :hook (prog-mode . lsp-deferred) :hook (lsp-mode . lsp-enable-which-key-integration) :hook (lsp-mode . lsp-inlay-hints-mode) :init (setq lsp-keymap-prefix "C-l") (add-to-list 'completion-at-point-functions #'lsp-completion-at-point) ;; (advice-add 'lsp :before #'envrc-reload) :commands lsp :general-config (leader-def "l" '(:keymap lsp-command-map :wk "LSP") ) :config (setq lsp-idle-delay 0.5 lsp-inlay-hint-enable t lsp-modeline-code-actions-enable t lsp-modeline-code-actions-segments '(name count) lsp-modeline-diagnostics-enable t lsp-completion-enable-additional-text-edit t lsp-completion-provider :capf lsp-enable-snippet t lsp-rust-server 'rust-analyzer lsp-rust-analyzer-server-display-inlay-hints t lsp-rust-analyzer-proc-macro-enable t lsp-rust-analyzer-completion-auto-import-enable t lsp-rust-analyzer-proc-macro-enable t lsp-rust-analyzer-binding-mode-hints t lsp-rust-analyzer-display-closure-return-type-hints t lsp-rust-analyzer-server-format-inlay-hints t lsp-rust-analyzer-cargo-extra-env ["RUSTFLAGS", "-Clinker=clang -Clink-arg=-fuse-ld=mold"] lsp-enable-suggest-server-download nil) (setq lsp-glsl-executable '("glsl_analyzer")) (add-to-list 'lsp-language-id-configuration '("CMakeLists.txt" . "cmake")) ) (use-package consult-lsp :straight t :general (with-eval-after-load 'lsp-mode (general-define-key :keymaps 'lsp-command-map "c s" '("Symbols" . consult-lsp-symbols) "c f" '("Symbols" . consult-lsp-file-symbols) "c d" '("Diagnostics" . consult-lsp-diagnostics) ) ) ) (use-package lsp-treemacs :straight t :commands lsp-treemacs-errors-list) (use-package lsp-ui :config (setq ;; lsp-modeline-code-actions-enable nil ;; lsp-rust-analyzer-cargo-all-targets nil ;; lsp-rust-analyzer-server-command "xwin-env rust-analyzer" lsp-ui-sideline-show-code-actions t lsp-ui-doc-enable t lsp-ui-doc-delay 0.5 lsp-ui-doc-show-with-cursor t ; lsp-ui-doc-use-childframe t ; lsp-ui-doc-use-webkit t ) :commands lsp-ui-mode) (defvar-local nemo/lsp-format-on-save t) (define-minor-mode nemo/lsp-format-on-save-mode "Run lsp-format-buffer on save." :lighter " fmt" (if nemo/lsp-format-on-save-mode (add-hook 'before-save-hook #'lsp-format-buffer nil t) (remove-hook 'before-save-hook #'lsp-format-buffer nil t) )) (defun nemo/do-lsp-format-on-save () "Format on save using LSP server." (if nemo/lsp-format-on-save (lsp-format-buffer))) (use-package wgsl-mode :straight t :ensure lsp-mode :mode "\\.wesl\\'" :hook (wgsl-mode . lsp-deferred) :init (add-to-list 'lsp-language-id-configuration '(wgsl-mode . "wgsl")) (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection "wgsl-analyzer") :activation-fn (lsp-activate-on "wgsl") :server-id 'wgsl-analyzer)) ) (use-package glsl-mode :straight t :defer t :init (add-to-list 'auto-mode-alist '("\\.vert\\'" . glsl-mode)) (add-to-list 'auto-mode-alist '("\\.glsl\\'" . glsl-mode)) (add-to-list 'auto-mode-alist '("\\.frag\\'" . glsl-mode)) ) (require 'hlsl-mode) (with-eval-after-load 'hlsl-mode (add-to-list 'auto-mode-alist '("\\.hlsl\\'" . hlsl-mode)) (add-to-list 'auto-mode-alist '("\\.frag\\'" . hlsl-mode)) ) (require 'slang-ts-mode) (add-hook 'slang-ts-mode-hook (lambda () (hs-minor-mode -1))) ;; (use-package rust-mode ;; :straight t ;; ;; :hook (rust-mode . lsp-mode) ;; :init ;; (setq rust-mode-treesitter-derive t ;; )) (use-package rustic :straight t :defer t :after (inheritenv envrc) ;; :after (rust-mode) :hook(rustic-mode . nemo/lsp-format-on-save-mode) :general-config (general-define-key :prefix-map 'nemo/rust-map "c v" '("Check" . rustic-cargo-check) "c c" '("Compile" . rustic-compile) "c b" '("Build" . rustic-cargo-build) ;;"c B" '("Build" . rust-cargo-relea) "c c" '("Clean" . rustic-cargo-clean) "c x" '("Run" . rustic-cargo-run) "c f" '("Format Buffer" . rustic-format-buffer) "t t" '("Current Test" . rustic-cargo-current-test) "t a" '("Test" . rustic-cargo-test) "c a" '("cargo-add" . rustic-cargo-add) "c r" '("cargo-rm" . rustic-cargo-remove) "c l" '("lint" . rustic-cargo-clippy) "c L" '("lint" . rustic-cargo-clippy-fix) "c n" '("new" . rustic-cargo-new) "c i" '("init" . rustic-cargo-init) "c d" '("Docs" . rustic-cargo-doc) ) (leader-major-def :keymaps 'rustic-mode-map "m" '(:keymap nemo/rust-map :wk "Cargo") ) :config (setq rust-mode-treesitter-derive t rustic-format-on-save nil ;; rustic-format-trigger 'on-save ;; rustic-format-on-save-method #'rustic-format-buffer ;; rustic-analyzer-command '("/usr/bin/rust-analyzer") ) ;; (setq nemo/lsp-format-on-save t) ) (use-package rust-playground :straight t :defer t) (use-package dap-mode :straight t :after (lsp-mode) :config ;; (require 'dap-cpptools) ;; (dap-cpptools-setup) (require 'dap-gdb-lldb) (dap-register-debug-template "Rust::GDB Run Configuration" (list :type "gdb" :request "launch" :name "GDB::Run" :gdbpath "rust-gdb" :target nil :cwd nil)) (dap-auto-configure-mode)) (use-package web-mode :straight t :defer t :mode (("\\.phtml\\'" . web-mode) ("\\.tpl\\.php\\'" . web-mode) ("\\.twig\\'" . web-mode) ("\\.xml\\'" . web-mode) ("\\.html\\'" . web-mode) ("\\.htm\\'" . web-mode) ("\\.[gj]sp\\'" . web-mode) ("\\.as[cp]x?\\'" . web-mode) ("\\.eex\\'" . web-mode) ("\\.erb\\'" . web-mode) ("\\.mustache\\'" . web-mode) ("\\.handlebars\\'" . web-mode) ("\\.hbs\\'" . web-mode) ("\\.eco\\'" . web-mode) ("\\.ejs\\'" . web-mode) ("\\.svelte\\'" . web-mode) ("\\.ctp\\'" . web-mode) ("\\.djhtml\\'" . web-mode)) :config (setq web-mode-css-indent-offset 2 web-mode-code-indent-offset 2 web-mode-attr-indent-offset 2 web-mode-markup-indent-offset 2)) (use-package clang-format :straight t :defer t) (use-package cmake-mode :straight t) (use-package zig-mode :straight t :config (add-to-list 'auto-mode-alist '("\\.zig\\'" . zig-mode)) (setq lsp-zig-enable-build-on-save t lsp-zig-enable-inlay-hints nil lsp-zig-build-on-save-step "check")) (use-package nix-mode :ensure t :mode ("\\.nix\\'" "\\.nix.in\\'") ) (defun snake-case () "convert region from PascalCase into snake_case" (interactive) (save-excursion (let ((bounds (bounds-of-thing-at-point 'symbol))) (replace-regexp "\\([A-Z]\\)" "_\\1" nil (1+ (car bounds)) (cdr bounds)) (downcase-region (car bounds) (cdr (bounds-of-thing-at-point 'word))))) ) (defun nemo/edit-init-org () "Open the init.org file." (interactive) (find-file (concat user-emacs-directory "/init.org")) ) (defun nemo/magit-dotfiles () "View Dotfiles repository with magit" (interactive) (require 'magit) (let ((magit-git-global-arguments `(,(substitute-env-vars "--git-dir=$HOME/.cfg") ,(substitute-env-vars "--work-tree=$HOME") ,@magit-git-global-arguments))) (magit-status "~") (recursive-edit))) (set-default 'tramp-default-proxies-alist (quote ((".*" "\\`root\\'" "/ssh:%h:")))) (require 'tramp) (defun sudo-edit-current-file () (interactive) (let ((position (point))) (find-alternate-file (if (file-remote-p (buffer-file-name)) (let ((vec (tramp-dissect-file-name (buffer-file-name)))) (tramp-make-tramp-file-name "sudo" (tramp-file-name-user vec) (tramp-file-name-host vec) (tramp-file-name-localname vec))) (concat "/sudo:root@localhost:" (buffer-file-name)))) (goto-char position))) (leader-def "fe" 'sudo-edit-current-file) (defun nemo/switch-to-last-buffer () (interactive) (switch-to-buffer nil) ) (define-key custom-bindings-map (kbd "C-c l") 'org-store-link) (define-key custom-bindings-map (kbd "C-c a") 'org-agenda) (define-key custom-bindings-map (kbd "C-c c") 'org-capture) (define-key custom-bindings-map (kbd "C-c t") 'org-todo) (define-key custom-bindings-map (kbd "M-h") 'org-todo)