1 ;;; config.el -*- lexical-binding: t; -*-
 
   3 ;; DOC: https://git.v0.io/hlissner/doom-emacs/src/commit/a680a4c96d2b57fcb75635bd1a918e1235e72890/docs/api.org
 
   4 ;; DOC: https://github.com/daviwil/emacs-from-scratch
 
   6 ;; Line numbers are pretty slow all around. The performance boost of
 
   7 ;; disabling them outweighs the utility of always keeping them on.
 
   8 (setq display-line-numbers-type nil)
 
   9 (global-visual-line-mode t)
 
  11 ;; Focus new window after splitting
 
  12 (setq evil-split-window-below t
 
  13       evil-vsplit-window-right t
 
  17 (setq undo-tree-auto-save-history t
 
  18       undo-tree-history-directory-alist '(("." . "~/.cache/emacs/undo"))
 
  22 (setq doom-font-increment 1
 
  24       ;doom-font-name "DejaVu Sans Mono"
 
  26       ;doom-font-name "Unifont"
 
  27       doom-font (font-spec :family doom-font-name :size doom-font-size :antialias t)
 
  28       doom-unicode-font (font-spec :family "Symbola" :antialias t)
 
  29       doom-variable-pitch-font (font-spec :family doom-font-name :antialias t)
 
  30       ivy-posframe-font (font-spec :family doom-font-name :antialias t)
 
  32 (setq x-underline-at-descent-line t)
 
  35 ;;(setq +doom-dashboard-banner-file (expand-file-name "banner.png" doom-private-dir))
 
  36 (defun bury-messages-and-scratch ()
 
  37        (mapcar #'bury-buffer '("*Messages*" "*scratch*")))
 
  38 (add-hook 'emacs-startup-hook #'bury-messages-and-scratch)
 
  41 (setq haskell-stylish-on-save nil)
 
  42 (setq lsp-haskell-formatting-provider "fourmolu")
 
  43 (setq +format-on-save-enabled-modes
 
  44       '(not emacs-lisp-mode ; works well enough without it
 
  45             sql-mode        ; sqlformat is broken
 
  46             tex-mode        ; latexindent is broken
 
  47             latex-mode      ; latexindent is broken
 
  48             bibtex-mode     ; is broken
 
  49             ess-r-mode      ; styler takes forever
 
  54 (setq doom-theme 'doom-vibrant)
 
  55 (custom-theme-set-faces! '(doom-vibrant)
 
  56   '(default :background "black" :foreground "white")
 
  57   '(hl-line :background "black")
 
  58   '(cursor :background "DarkOrange" :foreground "black")
 
  60   '(font-lock-string-face :foreground "magenta")
 
  61   '(highlight-numbers-number :foreground "DeepSkyBlue" :bold t)
 
  62   '(font-lock-comment-face :foreground "cyan3")
 
  63   '(font-lock-doc-face :foreground "cyan1")
 
  64   ;'(haskell-constructor-face :foreground "#c4451d")
 
  65   ;'(haskell-keyword-face :foreground "#af005f")
 
  66   ;'(haskell-keyword-face :foreground "RoyalBlue")
 
  67   ;'(haskell-keyword-face :foreground "#44385f")
 
  68   ;'(haskell-keyword-face :foreground "#906238" :bold t)
 
  69   ;'(haskell-keyword-face :foreground "green4" :bold t)
 
  70   '(haskell-keyword-face :foreground "LightGreen" :bold nil)
 
  71   ;'(haskell-pragma-face :foreground "#2aa198")
 
  72   '(haskell-pragma-face :foreground "#8f4e8b")
 
  73   ;'(haskell-type-face :foreground "#9e358f")
 
  74   '(haskell-operator-face :foreground "yellow" :bold nil)
 
  75   ;'(haskell-type-face :foreground "SaddleBrown")
 
  76   ;'(haskell-constructor-face :foreground "darkgoldenrod4")
 
  77   '(haskell-definition-face :foreground "white" :bold nil)
 
  78   '(swiper-line-face :background "grey15")
 
  79   '(swiper-match-face-1 :foreground "grey50" :background "black") ; what is between matches
 
  80   '(swiper-match-face-2 :foreground "black" :background "yellow2")
 
  81   '(swiper-match-face-3 :foreground "black" :background "yellow3")
 
  82   '(swiper-match-face-4 :foreground "black" :background "yellow4")
 
  83   '(swiper-background-match-face-2 :foreground "black" :background "yellow2")
 
  84   '(swiper-background-match-face-3 :foreground "black" :background "yellow3")
 
  85   '(swiper-background-match-face-4 :foreground "black" :background "yellow4")
 
  86   '(evil-ex-lazy-highlight :foreground "black" :background "yellow2")
 
  87   '(region :foreground "black" :background "yellow") ; selected area
 
  88   '(doom-modeline-buffer-modified :foreground "orange")
 
  89   '(git-gutter-fr:added :foreground "green4" :background "black")
 
  90   '(git-gutter-fr:deleted :foreground "red4" :background "black")
 
  91   '(git-gutter-fr:modified :foreground "orange4" :background "black")
 
  92   '(flycheck-fringe-error :foreground "red")
 
  93   '(flycheck-fringe-warning :foreground "orange")
 
  94   '(flycheck-fringe-info :foreground "purple")
 
  95   '(flycheck-info :underline '(:color "SkyBlue4" :style wave))
 
  96   '(flycheck-warning :underline '(:color "orange" :style wave))
 
  97   '(flycheck-error :underline '(:color "red" :style wave))
 
  98   '(warning :foreground "orange")
 
  99   '(error :foreground "red")
 
 100   '(ivy-minibuffer-match-face-1 :foreground "grey50" :background "black") ; what is between matches
 
 101   '(ivy-minibuffer-match-face-2 :foreground "black" :background "yellow2")
 
 102   '(ivy-minibuffer-match-face-3 :foreground "black" :background "yellow3")
 
 103   '(ivy-minibuffer-match-face-4 :foreground "black" :background "yellow4")
 
 105   ;'(haskell-operator-face :foreground "yellow3")
 
 106   ;'(haskell-type-face :foreground "#5a4e82")
 
 107   ;'(haskell-constructor-face :foreground "#8a4f88")
 
 108   ;'(haskell-constructor-face :foreground "#8a4c87")
 
 109   '(haskell-constructor-face :foreground "white" :bold t)
 
 110   ; Almost the same as haskell-constructor-face
 
 111   ; because that pattern does not match on type-contexts correctly
 
 112   '(haskell-type-face :foreground "white" :bold t)
 
 113   '(lsp-face-highlight-read :background "gray10")
 
 114   '(lsp-face-highlight-write :background "gray10")
 
 115   '(mode-line :background "gray20")
 
 116   '(mode-line-inactive :background "gray5")
 
 117   '(solaire-default-face :background "gray10")
 
 118   '(solaire-mode-line-face :background "gray20")
 
 119   '(solaire-mode-line-inactive-face :background "gray5")
 
 120   '(doom-modeline-project-dir :foreground "DeepSkyBlue" :bold t)
 
 121   ;'(magit-diff-context-highlight :foreground "white" :background "black")
 
 122   '(magit-diff-added-highlight :foreground "green")
 
 123   '(magit-diff-removed-highlight :foreground "red")
 
 124   ;;'(font-lock-comment-face ((t (:foreground "cyan" :italic t :slant oblique))))
 
 125   ;;'(font-lock-comment-delimiter-face ((t (:foreground "cyan"))))
 
 126   ;;'(fringe                 ((t (:foreground "red" :background "black"))))
 
 127   ;;'(whitespace-indentation ((t (:foreground "gray50" :bold t))))
 
 128   ;;'(whitespace-space       ((t (:foreground "black" :bold t))))
 
 129   ;;'(whitespace-tab         ((t (:foreground "gray50" :bold t))))
 
 130   ;;'(whitespace-trailing    ((t (:foreground "red" :bold t))))
 
 131   ;;'(font-lock-builtin-face ((t (:foreground "yellow" :weight bold))))
 
 132   ;;'(font-lock-keyword-face ((t (:foreground "yellow" :weight bold))))
 
 133   ;;'(font-lock-string-face  ((t (:foreground "magenta"))))
 
 134   ;;'(font-lock-variable-name-face ((t (:foreground "SpringGreen3" :weight bold))))
 
 135   ;;'(nix-antiquote-face     ((t (:foreground "blue"))))
 
 136   ;;'(mode-line ((t (:background "midnight blue" :box (:line-width 1 :color "blue") :height 1.0))))
 
 137   ;;'(mode-line-inactive ((t (:background "grey30" :foreground "white" :box (:line-width 1 :color "grey30") :weight light :height 1.0))))
 
 138   ;;'(mode-line ((t (:family "Noto Sans" :height 0.9))))
 
 139   ;;'(mode-line-inactive ((t (:family "Noto Sans" :height 0.9))))
 
 140   ;;'(solaire-mode-line-inactive-face ((t (:background "gray10"))))
 
 144 (use-package! polymode)
 
 145 (define-hostmode poly-haskell-hostmode
 
 147 ;; Support org tables in Haskell files
 
 148 (defun pm--org-table-tail-matcher (ahead)
 
 149     (when (re-search-forward "^[^|]" nil t ahead)
 
 150           (cons (match-beginning 0) (match-end 0))))
 
 151 (define-innermode poly-haskell-org-table-innermode
 
 154                   :tail-matcher #'pm--org-table-tail-matcher
 
 157 (define-polymode poly-haskell-mode
 
 158                  :hostmode 'poly-haskell-hostmode
 
 159                  :innermodes '(poly-haskell-org-table-innermode))
 
 161 ;; Language Server Protocol
 
 162 (setq ;+lsp-prompt-to-install-server 'quiet
 
 163       ;lsp-enable-file-watchers nil
 
 164       ;lsp-enable-indentation nil
 
 165       ;lsp-enable-on-type-formatting nil
 
 166       ;lsp-enable-symbol-highlighting nil
 
 167       lsp-enable-symbol-highlighting nil ; slow
 
 168       lsp-ui-doc-enable nil ; slow
 
 169       ;lsp-ui-sideline-enable nil ; not anymore useful than flycheck
 
 170       ;lsp-ui-peek-enable t
 
 171       ;lsp-ui-peek-always-show nil
 
 172       ;lsp-ui-flycheck-enable t
 
 173       ;lsp-ui-flycheck-live-reporting t
 
 174       ;; Disable help mouse-overs for mode-line segments (i.e. :help-echo text).
 
 175       ;; They're generally unhelpful and only add confusing visual clutter.
 
 176       mode-line-default-help-echo nil
 
 177       show-help-function nil
 
 178       global-prettify-symbols-mode nil
 
 179       prettify-symbols-mode -1
 
 180       treemacs-position 'right
 
 181       treemacs-project-follow-mode t
 
 182       lsp-treemacs-errors-position-params `((side . right))
 
 183       lsp-log-io nil ; Only for debugging
 
 184       lsp-restart 'auto-restart
 
 185       ; Only load lsp-clients to speed up loading
 
 186       ; See https://github.com/emacs-lsp/lsp-mode/pull/1498
 
 187       lsp-client-packages '(lsp-clients)
 
 188       lsp-ui-sideline-show-code-actions t
 
 191 ;; The modeline is not useful to me in the popup window.
 
 192 ;; It looks much nicer to hide it.
 
 193 (remove-hook 'emacs-everywhere-init-hooks #'hide-mode-line-mode)
 
 195 ;;(remove-hook 'window-setup-hook #'doom-init-theme-h)
 
 196 ;;(add-hook 'after-init-hook #'doom-init-theme-h 'append)
 
 197 ;;(delq! t custom-theme-load-path)
 
 199 (setq auto-save-default t ; Nobody likes to loose work, I certainly don't
 
 201       confirm-kill-processes nil
 
 202       make-backup-files nil
 
 203       password-cache-expiry nil ; I can trust my computers ... can't I?
 
 205       ;; scroll-preserve-screen-position 'always     ; Don't have `point' jump around
 
 206       truncate-string-ellipsis "…" ; Unicode ellispis are nicer than "...", and also save /precious/ space
 
 207       kill-whole-line t ; Make Ctrl-K remove the whole line, instead of just emptying it
 
 208       undo-limit 80000000 ; Raise undo-limit to 80MB
 
 209       x-stretch-cursor nil ; Disorienting
 
 213 ;(setq debug-on-quit t)
 
 216 (setq haskell-process-log nil
 
 217       haskell-interactive-popup-errors nil
 
 219 (add-hook 'haskell-mode-hook
 
 221             (set (make-local-variable 'company-backends)
 
 222                  (append '((company-capf company-dabbrev-code))
 
 224 (define-hostmode poly-haskell-hostmode
 
 228 (setq split-height-threshold nil
 
 229       split-width-threshold 160
 
 234   (set-popup-rule! "*doom:vterm-popup:*" :side 'right :size 0.33 :vslot -4 :select t :quit nil :ttl 0)
 
 235   (setq vterm-kill-buffer-on-exit t
 
 236         vterm-max-scrollback 10000
 
 241   ; flycheck-error-list-buffer
 
 242   (set-popup-rule! (rx bos "*Flycheck errors*" eos) :side 'right :size 0.33)
 
 243   ; M-x lsp-ui-flycheck-list
 
 244   (setq lsp-ui-flycheck-list-position 'right)
 
 245   (add-hook 'flycheck-error-list-mode-hook
 
 246             (lambda () (setq tabulated-list-sort-key (list "Level"))))
 
 248     flycheck-relevant-error-other-file-minimum-level 'error
 
 249     flycheck-relevant-error-other-file-show t
 
 252 ;(add-hook 'flycheck-error-list-after-refresh-hook
 
 254 ;            (with-selected-window (flycheck-get-error-list-window t)
 
 255 ;                                  (fit-window-to-buffer (flycheck-get-error-list-window t) 30))))
 
 258 (add-hook 'after-init-hook 'global-company-mode)
 
 259 ;(setq company-idle-delay nil)
 
 264 ;  (:map ivy-minibuffer-map
 
 265 ;        ("RET" . 'ivy-alt-done)
 
 266 ;        ("TAB" . 'ivy-alt-done))
 
 268 ;  (setq ivy-extra-directories nil
 
 272 ;(add-hook! 'org-mode-hook #'mixed-pitch-mode)
 
 273 ;(add-hook! 'org-mode-hook #'solaire-mode)
 
 274 ;(setq mixed-pitch-variable-pitch-cursor nil)
 
 276 ;(add-hook! org-mode :append
 
 278 ;  #'variable-pitch-mode)
 
 280 (setq doom-modeline-enable-word-count nil)
 
 282 (map! "C-x b"   #'counsel-buffer-or-recentf
 
 283       "C-x C-b" #'counsel-switch-buffer)
 
 284 (defun recentf-track-visited-file (_prev _curr)
 
 285   (and buffer-file-name
 
 286        (recentf-add-file buffer-file-name)))
 
 288   (add-hook 'switch-buffer-functions #'recentf-track-visited-file))
 
 291 ; DOC: https://rgoswami.me/posts/org-note-workflow/
 
 292 ; ToStudy: https://github.com/abo-abo/orca
 
 293 ; ToStudy: https://github.com/weirdNox/org-noter
 
 294 ; ToStudy: https://github.com/bastibe/org-journal
 
 295 ; ToStudy: https://orgmode.org/manual/Org-Crypt.html
 
 296 ; DOC: http://www.wouterspekkink.org/academia/writing/tool/doom-emacs/2021/02/27/writing-academic-papers-with-org-mode.html
 
 297 ; DOC: https://jonathanabennett.github.io/blog/2019/05/29/writing-academic-papers-with-org-mode/
 
 298 ; ToStudy: https://github.com/org-roam/org-roam-ui
 
 299 ; ToStudy: https://blog.tecosaur.com/tmio/2021-07-31-citations.html
 
 300 ; ToStudy: https://github.com/jkitchin/org-ref-cite
 
 301 (setq org-directory "~/papers/notes")
 
 302 (setq org-noter-notes-search-path '("~/notes/path/"))
 
 306         org-log-into-drawer t
 
 307         org-special-ctrl-a/e t
 
 309         ;org-hide-emphasis-markers t
 
 311   (add-to-list 'org-capture-templates
 
 312                '("e" "English" table-line ; key, name, type
 
 313                      (file "english/vocabulary.org") ; target
 
 314                      "|%^{English}|%^{Français}|%^{Registre|Courant|Soutenu|Familier}|"
 
 316   (add-to-list 'org-capture-templates
 
 317                '("x" "Expense" plain
 
 319                      "\n%(org-read-date) * send %^{Send to} %^{For why}\nExpense:Gifts  %^{Amount}\n  %^{Currency|EUR|USD|JPY}\n Assets:%^{Account||Personal|Home}"))
 
 320   ;; Firefox and Chrome
 
 321   ;(add-to-list 'org-capture-templates
 
 322   ;             `("P" "Protocol" entry ; key, name, type
 
 323   ;                   (file+headline +org-capture-notes-file "Inbox") ; target
 
 324   ;                   "* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?"
 
 325   ;                   :prepend t ; properties
 
 327   ;(add-to-list 'org-capture-templates
 
 328   ;             `("L" "Protocol Link" entry
 
 329   ;                   (file+headline +org-capture-notes-file "Inbox")
 
 330   ;                   "* %? [[%:link][%(transform-square-brackets-to-round-ones \"%:description\")]]\n"
 
 336 (map! :after counsel :map org-mode-map
 
 337   "C-c l l h" #'counsel-org-link)
 
 339   (setq counsel-outline-display-style 'title))
 
 342 ;  ;; Do not create ID if a CUSTOM_ID exists
 
 343 ;  (setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)
 
 347 ;  ;; (setq org-agenda-prefix-format
 
 348 ;  ;;       '((agenda . " %i %-12:c%?-12t% s")
 
 349 ;  ;;         ;; Indent todo items by level to show nesting
 
 350 ;  ;;         (todo . " %i %-12:c%l")
 
 351 ;  ;;         (tags . " %i %-12:c")
 
 352 ;  ;;        (search . " %i %-12:c")))
 
 353 ;  (setq org-agenda-include-diary t)
 
 356 ;(use-package! org-roam
 
 358 ;  :hook ((after-init . org-roam-mode))
 
 360 ;  (setq org-roam-directory "~/papers/notes/org-roam")
 
 362 ;  ;; Let's set up some org-roam capture templates
 
 363 ;  (setq org-roam-capture-templates
 
 364 ;        '(("d" "default" plain (function org-roam--capture-get-point)
 
 366 ;                :file-name "%<%Y-%m-%d-%H%M%S>-${slug}"
 
 367 ;                :head "#+title: ${title}\n"
 
 370 ;  ;; And now we set necessary variables for org-roam-dailies
 
 371 ;  (setq org-roam-dailies-capture-templates
 
 372 ;        '(("d" "default" entry
 
 373 ;           #'org-roam-capture--get-point
 
 375 ;           :file-name "daily/%<%Y-%m-%d>"
 
 376 ;           :head "#+title: %<%Y-%m-%d>\n\n")))
 
 379 ;(use-package! org-ref
 
 382 ;  (setq reftex-default-bibliography bibliography-files
 
 383 ;        org-ref-default-bibliography bibliography-files
 
 384 ;        org-ref-bibliography-notes "~/papers/notes/org-roam/bibnotes.org"  ;; Is this even needed?
 
 385 ;        org-ref-notes-directory "~/papers/notes/org-roam"
 
 386 ;        org-ref-notes-function 'orb-edit-notes
 
 387 ;        ;org-ref-get-pdf-filename-function 'org-ref-get-pdf-filename-helm-bibtex)
 
 390 ;(use-package! bibtex-completion
 
 393 ;  (setq bibtex-completion-notes-path "~/papers/notes/org-roam/"
 
 394 ;        bibtex-completion-pdf-field "file"
 
 395 ;        bibtex-completion-bibliography bibliography-files
 
 399 ;(defvar orb-title-format "${author-or-editor-abbrev} (${date}).  ${title}."
 
 400 ;  "Format of the title to use for `orb-templates'.")
 
 402 ;(use-package! org-roam-bibtex
 
 404 ;  :hook (org-roam-mode . org-roam-bibtex-mode)
 
 405 ;  :bind (:map org-mode-map
 
 406 ;              (("C-c n a" . orb-note-actions)))
 
 408 ;  (setq orb-preformat-keywords
 
 409 ;        '(("citekey" . "=key=") "title" "date" "author-or-editor-abbrev")
 
 412 ;           (function org-roam-capture--get-point)
 
 414 ;           :file-name "${citekey}"
 
 415 ;           :head ,(s-join "\n"
 
 417 ;                           (concat "#+TITLE: " orb-title-format)
 
 418 ;                           "#+ROAM_KEY: ${ref}"
 
 425 ;          ("n" "ref + noter" plain
 
 426 ;           (function org-roam-capture--get-point)
 
 428 ;           :file-name "${citekey}"
 
 429 ;           :head ,(s-join "\n"
 
 431 ;                           (concat "#+TITLE: " orb-title-format)
 
 432 ;                           "#+ROAM_KEY: ${ref}"
 
 436 ;                           "* Annotations :noter:"
 
 438 ;                           ":NOTER_DOCUMENT: %(orb-process-file-field \"${citekey}\")"
 
 443 ;(map! :after pdf-tools
 
 444 ;      :map pdf-view-mode-map
 
 447 ;                (if (bound-and-true-p org-noter-doc-mode)
 
 448 ;                    (org-noter-kill-session)
 
 449 ;                  (kill-current-buffer)))
 
 452 ;(use-package! org-noter
 
 453 ;  :after (:any org pdf-view)
 
 455 ;  (setq org-noter-notes-search-path '("~/papers/notes/org-roam")
 
 456 ;        org-noter-always-create-frame nil
 
 460 ;(setq lsp-lens-mode t)
 
 461 (setq doom-modeline-height 1)
 
 462 (setq doom-modeline-lsp t)
 
 463 ;(setq doom-modeline-minor-modes t)
 
 464 ;(setq lsp-modeline-diagnostics-enable t)
 
 467 (setq-default tab-width 2)
 
 468 (setq indent-tabs-mode nil)
 
 471 (global-superword-mode t)
 
 472 ; https://emacs.stackexchange.com/questions/9583/how-to-treat-underscore-as-part-of-the-word
 
 473 (modify-syntax-entry ?_ "w")
 
 474 (defun swiper-all/search-word-at-point ()
 
 476   (swiper-all (format "\\_<%s\\_>" (thing-at-point 'word))))
 
 477 ; Highlight without jumping to the next match
 
 478 ; See: https://emacs.stackexchange.com/questions/52411/evil-star-visualstar-without-moving-the-cursor
 
 479 (defun search-word-at-point ()
 
 481   (evil-search (progn (evil-ex-search-word-forward)
 
 482                       (evil-ex-search-previous)
 
 484 (defun search-unbounded-word-at-point ()
 
 486   (evil-search (progn (evil-ex-search-unbounded-word-forward)
 
 487                       (evil-ex-search-unbounded-word-previous)
 
 490   (setq case-fold-search nil ; case-sensitive search by default
 
 491         ivy-case-fold-search-default nil ; case-sensitive search by default
 
 492         ivy-count-format "(%d/%d) "
 
 494         ;; Press C-p and Enter to select current input as candidate
 
 495         ;; https://oremacs.com/2017/11/30/ivy-0.10.0/
 
 496         ivy-use-selectable-prompt t
 
 497         ivy-use-virtual-buffers t
 
 499   (add-to-list 'ivy-re-builders-alist `(swiper . ivy--regex))
 
 500   (add-to-list 'ivy-re-builders-alist `(swiper-all . ivy--regex))
 
 501   (add-to-list 'ivy-re-builders-alist `(read-file-name-internal . ivy--regex-fuzzy))
 
 504   (setq which-key-min-display-lines 15
 
 505         ; https://github.com/doomemacs/doomemacs/issues/5622#issuecomment-946760888
 
 506         which-key-allow-imprecise-window-fit nil
 
 508   ;(general-define-key "C-s" '(counsel-grep-or-swiper :which-key "search"))
 
 509   ;(general-define-key :keymaps '(swiper-map) "C-u" '(lambda () (interactive) (kill-line 0)))
 
 510   ;(general-nvmap "/" '(counsel-grep-or-swiper :which-key "search in buffer"))
 
 511   (evil-define-key 'normal global-map
 
 513                    (kbd "C-f") 'swiper-all
 
 514                    (kbd "C-/") 'swiper-all/search-word-at-point
 
 515                    (kbd "*") 'search-word-at-point
 
 516                    (kbd "g*") 'search-unbounded-word-at-point
 
 522   (setq evil-want-fine-undo t
 
 524   (customize-set-variable 'evil-want-Y-yank-to-eol nil)
 
 525   (evil-define-key 'normal global-map (kbd "K") 'evil-join)
 
 526   (evil-define-key 'insert global-map (kbd "C-u") '(lambda () (interactive) (kill-line 0)))
 
 527   (evil-define-key 'normal global-map (kbd "SPC g d") 'git-gutter:popup-hunk)
 
 529 (setq +vc-gutter-default-style nil
 
 531 (customize-set-variable 'git-gutter:update-interval 2)
 
 532 ;(customize-set-variable 'git-gutter:window-width 2)
 
 533 (after! git-gutter-fringe
 
 534   (require 'fringe-helper)
 
 535   ; Narrower vertical bar, matching the one in the "+" of git-gutter-fr:added
 
 536   (fringe-helper-define 'git-gutter-fr:modified nil
 
 545   ; Narrower horizontql bar, matching the one in the "+" of git-gutter-fr:added
 
 546   (fringe-helper-define 'git-gutter-fr:deleted nil
 
 559 (defun set-selective-display/at-point (&optional level)
 
 560   "Fold text indented same of more than the cursor.
 
 561   If level is set, set the indent level to LEVEL.
 
 562   If 'selective-display' is already set to LEVEL,
 
 563   calling it again will unset 'selective-display' by setting it to 0."
 
 565     (if (eq selective-display (1+ (current-column)))
 
 566         (set-selective-display 0)
 
 567         (set-selective-display (or level (1+ (current-column))))))
 
 569   (evil-define-key 'normal global-map
 
 570                    (kbd "C-d") 'set-selective-display/at-point)
 
 574 ;; DOC: https://github.com/noctuid/evil-guide
 
 576   (setq evil-cross-lines t
 
 577         evil-ex-search-case 'sensitive
 
 578         evil-move-cursor-back nil
 
 580         evil-want-C-i-jump nil
 
 584   (evil-define-key 'motion 'global
 
 585                    (kbd "<C-i>") 'evil-prev-buffer ; Does not work without the angles ('<' and '>')
 
 586                    (kbd "C-k") 'evil-next-buffer
 
 587                    (kbd "C-x k") 'kill-current-buffer
 
 588                    (kbd "C-m") 'counsel-switch-buffer
 
 590   ;(define-key evil-normal-state-map [tab] 'evil-prev-buffer)
 
 593   (evil-define-key 'motion 'global
 
 594                    (kbd "C-u") 'better-jumper-jump-backward
 
 595                    (kbd "C-o") 'better-jumper-jump-forward
 
 598   ;(evil-define-key '(motion normal visual) 'global
 
 599                     ;(kbd "C--") 'doom/decrease-font-size
 
 600                     ;(kbd "C-=") 'doom/increase-font-size
 
 603   ;; Moving with ijkl (instead of hjkl)
 
 604   (evil-define-key '(motion normal visual) 'global
 
 605                    (kbd "i") 'evil-previous-visual-line
 
 606                    (kbd "j") 'evil-backward-char
 
 607                    (kbd "k") 'evil-next-visual-line
 
 608                    (kbd "h") 'evil-insert
 
 611   ;; Switching windows with SPC-w + ijkl (instead of hjkl)
 
 612   (define-key evil-window-map "i" 'evil-window-up)
 
 613   (define-key evil-window-map "I" 'evil-window-move-very-top)
 
 614   (define-key evil-window-map "j" 'evil-window-left)
 
 615   (define-key evil-window-map "J" 'evil-window-move-far-left)
 
 616   (define-key evil-window-map "k" 'evil-window-down)
 
 617   (define-key evil-window-map "K" 'evil-window-move-very-bottom)
 
 618   ;(define-key evil-emacs-state-map "\C-w" 'evil-window-map)
 
 619   ;;(evil-define-key 'window global-map "l" 'evil-window-right)
 
 620   ;;(evil-define-key 'window global-map "L" 'evil-window-move-far-right)
 
 623   ;;(evil-define-key 'normal dired-mode-map "i" 'evil-previous-line)
 
 626   (evil-define-key 'motion 'global
 
 627                    (kbd "C-j") 'previous-error
 
 628                    (kbd "C-l") 'next-error
 
 630   ;(bind-key "C-j" #'previous-error)
 
 631   ;(bind-key "C-l" #'next-error)
 
 633 (after! auto-yasnippet
 
 634   (evil-define-key '(motion normal) 'global
 
 635                    (kbd "C-<tab>") 'evil-switch-to-windows-last-buffer
 
 638 (after! (evil magit evil-collection-magit)
 
 639   (evil-define-key '(motion normal) magit-mode-map
 
 640                    (kbd "C-i") 'evil-prev-buffer
 
 641                    (kbd "i") 'evil-previous-visual-line
 
 642                    (kbd "k") 'evil-next-visual-line
 
 643                    (kbd "C-k") 'evil-next-buffer
 
 644                    (kbd "j") 'magit-section-backward
 
 645                    (kbd "l") 'magit-section-forward
 
 648 (after! (evil magit git-rebase)
 
 649   (evil-define-key '(motion normal) git-rebase-mode-map
 
 650                    (kbd "C-i") 'evil-prev-buffer
 
 651                    (kbd "i") 'evil-previous-visual-line
 
 652                    (kbd "k") 'evil-next-visual-line
 
 653                    (kbd "C-k") 'evil-next-buffer
 
 654                    (kbd "j") 'evil-backward-char
 
 657 ;;(eval-after-load 'evil ; to run after evil-integration.el
 
 659 ;;   (define-key Buffer-menu-mode-map     "\C-i" 'evil-prev-buffer)
 
 660 ;;   (define-key Buffer-menu-mode-map     "\C-k" 'evil-next-buffer)
 
 661 ;;   (define-key messages-buffer-mode-map "\C-i" 'evil-prev-buffer)
 
 662 ;;   (define-key messages-buffer-mode-map "\C-k" 'evil-next-buffer)
 
 663 ;;   (define-key completion-list-mode-map "\C-i" 'evil-prev-buffer)
 
 664 ;;   (define-key completion-list-mode-map "\C-k" 'evil-next-buffer)
 
 665 ;;   ;(define-key custom-theme-mode-map    "\C-i" 'evil-prev-buffer)
 
 666 ;;   ;(define-key custom-theme-mode-map    "\C-k" 'evil-next-buffer)
 
 670 ;;(with-eval-after-load 'evil-maps
 
 671 ;;  (define-key evil-motion-state-map (kbd "TAB") nil))
 
 674 ; See also: Managing ArXiv RSS Feeds in Emacs https://cundy.me/post/elfeed/
 
 677   elfeed-enable-web-interface t
 
 680 ;(global-set-key (kbd "C-x w") 'elfeed)
 
 682 (defun elfeed-mark-all-as-read ()
 
 685   (elfeed-search-untag-all-unread))
 
 687 ; Functions to support syncing .elfeed between machines
 
 688 ; makes sure elfeed reads index from disk before launching
 
 689 (defun elfeed-load-db-and-open ()
 
 690   "Wrapper to load the elfeed db from disk before opening"
 
 694   (elfeed-search-update--force))
 
 696 ; Write to disk when quiting
 
 697 (defun elfeed-save-db-and-bury ()
 
 698   "Wrapper to save the elfeed db to disk before burying buffer"
 
 703 (defun elfeed-toggle-star ()
 
 706   (elfeed-search-tag-all '*)
 
 708 (after! (evil elfeed evil-collection-elfeed)
 
 709   (evil-define-key 'motion elfeed-search-mode-map "m" #'elfeed-toggle-star)
 
 712 (defun elfeed-org-update-incremental ()
 
 713   "Automatically update the feeds from feeds.org when updated"
 
 714    (setq my-elfeed-org-last (or (and (boundp 'elfeed-feeds) elfeed-feeds) nil))
 
 716   (setq my-elfeed-org-current elfeed-feeds)
 
 717   (let ((elfeed-feeds (-difference my-elfeed-org-current my-elfeed-org-last)))
 
 718     ;; You don't need the line below if you don't want to see a message about what feeds are being updated
 
 719     (message "%s"  elfeed-feeds)
 
 720     (mapc #'elfeed-update-feed (elfeed--shuffle (elfeed-feed-list))))
 
 721   (setq elfeed-feeds my-elfeed-org-current))