Skip to content

abroekhof/dotemacs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

Initialization

Performance improvements

Taken from https://emacs-lsp.github.io/lsp-mode/page/performance/ to improve LSP performance.

  ;; Prevent stale elisp bytecode from shadowing more up-to-date source files
(setq load-prefer-newer t)

;; Increase warning threshold
(setq large-file-warning-threshold (* 64 1000000))

;; Set undo limit to 64 MB
(setq undo-outer-limit (* 64 1000000))

;; Increase the amount of data which Emacs reads from subprocesses
(setq read-process-output-max (* 1024 1024)) ; 1 MB

Make sure Emacs uses the shell PATH

(when (memq window-system '(mac ns))
  (use-package exec-path-from-shell
    :config (exec-path-from-shell-initialize)))

Get rid of tabs

(setq-default indent-tabs-mode nil)   ;; don't use tabs to indent
(setq-default tab-width 8)            ;; but maintain correct appearance

Delete the selection with a keypress

(delete-selection-mode t)

Better scrolling

  ;; Smooth scrolling
(setq-default mouse-wheel-scroll-amount '(1 ((shift) . 1))
              mouse-wheel-progressive-speed t
              mouse-wheel-follow-mouse t
              scroll-conservatively 10000
              scroll-step 1
              scroll-margin 1
              scroll-preserve-screen-position 1)

Enable y/n answers

(fset 'yes-or-no-p 'y-or-n-p)

Backups

(setq
 make-backup-files nil
 auto-save-default nil
 create-lockfiles nil)

OSX Behavior

Taken from the Spacemacs OSX module

(when (equal system-type 'darwin)
  ;; Treat option as meta and command as super
  (setq mac-option-key-is-meta t)
  (setq mac-command-key-is-meta nil)
  (setq mac-command-modifier 'super)
  (setq mac-option-modifier 'meta))

Whitespace cleanup

(add-hook 'before-save-hook 'delete-trailing-whitespace)

Revert buffers automatically when underlying files are changed externally

(global-auto-revert-mode t)

Fix C&P quirk in iTerm

(setq xterm-extra-capabilities '(setSelection))

UI settings

Font

(when (member "Hack" (font-family-list))
  (set-face-attribute 'default nil
                      :family "Hack"
                      :height 120
                      :weight 'normal
                      :width 'normal))

Turn off the scroll bar and the tool bar and the menu bar.

(scroll-bar-mode -1)
(menu-bar-mode -1)
(when (fboundp 'tool-bar-mode)
  (tool-bar-mode -1))

Use a nice theme

(use-package leuven-theme
  :config
  (load-theme 'leuven t))

Turn on blinking cursor

(blink-cursor-mode t)

Highlight current line

(global-hl-line-mode)

Enable column numbers

(column-number-mode)

Diminish

(use-package diminish)

Rainbow delimiters

(use-package rainbow-delimiters
  :hook (prog-mode . rainbow-delimiters-mode)
  :diminish rainbow-delimiters-mode)

Which Key

(use-package which-key
:demand t
:config
(progn
  (which-key-setup-side-window-bottom)
  (which-key-mode)))

Movement

Avy (navigation)

(use-package avy
  :bind (("C-c j" . avy-goto-char-timer))
  :config
  (setq avy-background -1))

Switch window

(use-package switch-window
    :bind ("C-x o" . switch-window))

(use-package ace-window
  :bind* ("M-o" . ace-window)
  :init
  (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
  (custom-set-faces
   '(aw-leading-char-face
     ((t (:inherit ace-jump-face-foreground :height 3.0))))))

(use-package windmove
  :config (windmove-default-keybindings 'shift))

Buffer moving

(use-package buffer-move
  :bind (
         ("C-M-h" . buf-move-left)
         ("C-M-j" . buf-move-down)
         ("C-M-k" . buf-move-up)
         ("C-M-l" . buf-move-right)))

Editor behavior

Hippie expand settings

(use-package hippie-exp
  :bind ("M-/" . hippie-expand)
  :init (setq hippie-expand-try-functions-list '(try-expand-dabbrev
                                                 try-expand-dabbrev-all-buffers
                                                 try-expand-dabbrev-from-kill
                                                 try-complete-file-name-partially
                                                 try-complete-file-name
                                                 try-expand-all-abbrevs
                                                 try-expand-list
                                                 try-expand-line
                                                 try-complete-lisp-symbol-partially
                                                 try-complete-lisp-symbol)))

YASnippet

(use-package yasnippet
  :config
  (yas-global-mode 1))

Smart Parentheses

(use-package smartparens
  :init
  (smartparens-global-mode 1)
  (show-smartparens-global-mode 1)
  :diminish smartparens-mode)

Uniquify

(use-package uniquify
  :straight nil
  :config
  (setq uniquify-buffer-name-style 'forward)
  (setq uniquify-separator "/")
  (setq uniquify-after-kill-buffer-p t)    ; rename after killing uniquified
  (setq uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers
  )

Savehist keeps track of some history

(use-package savehist
  :init
  (progn
    (setq savehist-file "~/.emacs.d/savehist")
    (setq savehist-additional-variables '(search-ring regexp-search-ring)
          savehist-autosave-interval 60
          history-length t
          history-delete-duplicates t
          savehist-save-minibuffer-history 1)
    (savehist-mode +1)))

Save recent files

(use-package recentf
  :init (progn(setq recentf-max-saved-items 500
                    recentf-max-menu-items 15)
              (recentf-mode +1)))

Crux

crux has useful functions extracted from Emacs Prelude. Set C-a to move to the first non-whitespace character on a line, and then to toggle between that and the beginning of the line.

(use-package crux)

(global-set-key (kbd "C-a") #'crux-move-beginning-of-line)
(global-set-key (kbd "C-<backspace>") #'crux-kill-line-backwards)

Anzu replace

(use-package anzu
  :diminish anzu-mode
  :bind (("M-%" . anzu-query-replace)
         ("C-M-%" . anzu-query-replace-regexp))
  :init (global-anzu-mode 1))

Undo tree

(use-package undo-tree
  :diminish undo-tree-mode
  :init (progn(setq undo-tree-visualizer-diff t
                    undo-tree-visualizer-timestamps t)
              (setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo")))
              (global-undo-tree-mode)))

Expand region

(use-package expand-region
  :commands er/expand-region
  :bind ("M-2" . er/expand-region))

Highlight symbol

When you hover on a symbol, it will highlight other occurrences in the buffer.

(use-package highlight-symbol
  :diminish
  :hook (prog-mode . highlight-symbol-mode)
  :config
  (setq highlight-symbol-idle-delay 0.25))

Narrowing

Vertico

(use-package vertico
  :straight (:files
             (:defaults "extensions/*")
             :includes (vertico-buffer
                        vertico-directory
                        vertico-flat
                        vertico-indexed
                        vertico-mouse
                        vertico-quick
                        vertico-repeat
                        vertico-reverse))
  :init
  (vertico-mode))

;; Configure directory extension.
(use-package vertico-directory
  :after vertico
  :ensure nil
  ;; More convenient directory navigation commands
  :bind (:map vertico-map
              ("RET" . vertico-directory-enter)
              ("DEL" . vertico-directory-delete-char)
              ("M-DEL" . vertico-directory-delete-word))
  ;; Tidy shadowed file names
  :hook (rfn-eshadow-update-overlay . vertico-directory-tidy))

Orderless

(use-package orderless
  :ensure t
  :custom
  (completion-styles '(orderless basic))
  (completion-category-overrides '((file (styles basic partial-completion)))))

Marginalia

Enable richer annotations using the Marginalia package

(use-package marginalia
  ;; Either bind `marginalia-cycle` globally or only in the minibuffer
  :bind (("M-A" . marginalia-cycle)
         :map minibuffer-local-map
         ("M-A" . marginalia-cycle))

  :init
  ;; Must be in the :init section of use-package such that the mode gets
  ;; enabled right away. Note that this forces loading the package.
  (marginalia-mode))

Consult

  (use-package consult
  ;; Replace bindings. Lazily loaded due by `use-package'.
  :bind (;; C-c bindings (mode-specific-map)
         ("C-c h" . consult-history)
         ("C-c m" . consult-mode-command)
         ("C-c k" . consult-kmacro)
         ;; C-x bindings (ctl-x-map)
         ("C-x M-:" . consult-complex-command)     ;; orig. repeat-complex-command
         ([remap switch-to-buffer] . consult-buffer)
         ([remap switch-to-buffer-other-window] . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
         ([remap switch-to-buffer-other-frame] . consult-buffer-other-frame)  ;; orig. switch-to-buffer-other-frame
         ([remap bookmark-jump] . consult-bookmark)            ;; orig. bookmark-jump
         ([remap project-switch-to-buffer] . consult-project-buffer)      ;; orig. project-switch-to-buffer
         ;; Custom M-# bindings for fast register access
         ("M-#" . consult-register-load)
         ("M-'" . consult-register-store)          ;; orig. abbrev-prefix-mark (unrelated)
         ("C-M-#" . consult-register)
         ;; Other custom bindings
         ([remap yank-pop] . consult-yank-pop)                ;; orig. yank-pop
         ("<help> a" . consult-apropos)            ;; orig. apropos-command
         ;; M-g bindings (goto-map)
         ("M-g e" . consult-compile-error)
         ("M-g f" . consult-flymake)               ;; Alternative: consult-flycheck
         ("M-g g" . consult-goto-line)             ;; orig. goto-line
         ("M-g M-g" . consult-goto-line)           ;; orig. goto-line
         ("M-g o" . consult-outline)               ;; Alternative: consult-org-heading
         ("M-g m" . consult-mark)
         ("M-g k" . consult-global-mark)
         ("M-g i" . consult-imenu)
         ("M-g I" . consult-imenu-multi)
         ;; M-s bindings (search-map)
         ("M-s d" . consult-find)
         ("M-s D" . consult-locate)
         ("M-s g" . consult-grep)
         ("M-s G" . consult-git-grep)
         ([remap project-find-regexp] . consult-ripgrep)
         ("C-s" . consult-line)
         ("M-s L" . consult-line-multi)
         ("M-s m" . consult-multi-occur)
         ("M-s k" . consult-keep-lines)
         ("M-s u" . consult-focus-lines)
         ;; Isearch integration
         ("M-s e" . consult-isearch-history)
         :map isearch-mode-map
         ("M-e" . consult-isearch-history)         ;; orig. isearch-edit-string
         ("M-s e" . consult-isearch-history)       ;; orig. isearch-edit-string
         ("M-s l" . consult-line)                  ;; needed by consult-line to detect isearch
         ("M-s L" . consult-line-multi)            ;; needed by consult-line to detect isearch
         ;; Minibuffer history
         :map minibuffer-local-map
         ("M-s" . consult-history)                 ;; orig. next-matching-history-element
         ("M-r" . consult-history))                ;; orig. previous-matching-history-element

  ;; Enable automatic preview at point in the *Completions* buffer. This is
  ;; relevant when you use the default completion UI.
  :hook (completion-list-mode . consult-preview-at-point-mode)

  ;; The :init configuration is always executed (Not lazy)
  :init

  ;; Optionally configure the register formatting. This improves the register
  ;; preview for `consult-register', `consult-register-load',
  ;; `consult-register-store' and the Emacs built-ins.
  (setq register-preview-delay 0.5
        register-preview-function #'consult-register-format)

  ;; Optionally tweak the register preview window.
  ;; This adds thin lines, sorting and hides the mode line of the window.
  (advice-add #'register-preview :override #'consult-register-window)

  ;; Optionally replace `completing-read-multiple' with an enhanced version.
  (advice-add #'completing-read-multiple :override #'consult-completing-read-multiple)

  ;; Use Consult to select xref locations with preview
  (setq xref-show-xrefs-function #'consult-xref
        xref-show-definitions-function #'consult-xref)

  ;; Configure other variables and modes in the :config section,
  ;; after lazily loading the package.
  :config

  ;; Optionally configure preview. The default value
  ;; is 'any, such that any key triggers the preview.
  ;; (setq consult-preview-key 'any)
  ;; (setq consult-preview-key (kbd "M-."))
  ;; (setq consult-preview-key (list (kbd "<S-down>") (kbd "<S-up>")))
  ;; For some commands and buffer sources it is useful to configure the
  ;; :preview-key on a per-command basis using the `consult-customize' macro.
  (consult-customize
   consult-theme
   :preview-key '(:debounce 0.2 any)
   consult-ripgrep consult-git-grep consult-grep
   consult-bookmark consult-recent-file consult-xref
   consult--source-bookmark consult--source-recent-file
   consult--source-project-recent-file
   :preview-key (kbd "M-."))

  (consult-customize
   consult-line
   :add-history (seq-some #'thing-at-point '(region symbol)))

  (defalias 'consult-line-thing-at-point 'consult-line)

  (consult-customize
   consult-line-thing-at-point
   :initial (thing-at-point 'symbol))

  ;; Optionally configure the narrowing key.
  ;; Both < and C-+ work reasonably well.
  (setq consult-narrow-key "<") ;; (kbd "C-+")

  ;; Optionally make narrowing help available in the minibuffer.
  ;; You may want to use `embark-prefix-help-command' or which-key instead.
  ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)
)

Org settings

(use-package org
  :hook ((org-mode . org-indent-mode)
         (auto-save . org-save-all-org-buffers))
  :config
  (setq org-src-fontify-natively t)
  (setq org-fontify-whole-heading-line t)
  (setq org-src-tab-acts-natively t)
  (setq org-log-done 'time)
  (setq org-export-backends '(ascii html icalendar latex md odt))

  (setq org-directory "~/notes")
  (setq org-agenda-files (quote ("~/notes")))
  (setq org-default-notes-file "~/notes/inbox.org")

  (define-key global-map (kbd "C-c c") 'counsel-org-capture)
  (define-key global-map (kbd "C-c a") 'org-agenda)
  (define-key global-map (kbd "C-c C-x C-j") 'org-clock-goto)

  ;; Resolve open-clocks if idle
  (setq org-clock-idle-time 10)

  (global-set-key [remap org-set-tags-command] #'counsel-org-tag)

  (org-babel-do-load-languages
   'org-babel-load-languages
   '((calc . t)
     (dot . t)))

  (setq org-capture-templates
        '(("t" "Todo" entry (file+headline org-default-notes-file "Tasks")
           "* TODO %?\n%u\n")
          ("m" "Meeting" entry (file+headline org-default-notes-file "Meetings")
           "* MEETING %? :meeting:\n%T")
          ("a" "Append to clocked in" item (clock))
          ("n" "Note" entry (file+headline org-default-notes-file "Notes")
           "* NOTE %?\n%U" :empty-lines 1) ))

  (setq org-todo-keywords
        '((sequence "TODO(t)" "NEXT(n)" "HOLD(h)" "|" "DONE(d)" "CANCELLED(c)")))
  (defun log-todo-next-creation-date (&rest ignore)
    "Log NEXT creation time in the property drawer under the key 'ACTIVATED'"
    (when (and (string= (org-get-todo-state) "NEXT")
               (not (org-entry-get nil "ACTIVATED")))
      (org-entry-put nil "ACTIVATED" (format-time-string "[%Y-%m-%d]"))))
  (add-hook 'org-after-todo-state-change-hook #'log-todo-next-creation-date)

  (setq org-refile-targets (quote ((nil :maxlevel . 9)
                                   (org-agenda-files :maxlevel . 9))))
  (setq org-refile-use-outline-path 'file)
  (setq org-outline-path-complete-in-steps nil)
  (setq org-refile-allow-creating-parent-nodes 'confirm))

org-download

(use-package org-download
  :after org
  :defer nil
  :custom
  (org-download-method 'directory)
  (org-download-image-dir "images")
  (org-download-heading-lvl nil)
  (org-download-timestamp "%Y%m%d-%H%M%S_")
  (org-image-actual-width 300)
  (org-download-screenshot-method "/usr/local/bin/pngpaste %s")
  :bind
  ("C-M-y" . org-download-screenshot)
  :config
  (require 'org-download))

org-bullets

(use-package org-bullets
  :hook (org-mode . org-bullets-mode))

Org exporting

Prevent underscores from being escaped

(setq org-export-with-sub-superscripts '{})

Github-flavored Markdown

(use-package ox-gfm
  :after (org))

Org Roam

(use-package org-roam
  :ensure t
  :init
  (setq org-roam-v2-ack t)
  :custom
  (org-roam-directory "~/mineral/notes")
  (org-roam-completion-everywhere t)
  (org-roam-dailies-capture-templates
   '(("d" "default" entry "* %<%I:%M %p>: %?"
      :if-new (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n"))))
  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n i" . org-roam-node-insert)
         :map org-mode-map
         ("C-M-i" . completion-at-point)
         :map org-roam-dailies-map
         ("Y" . org-roam-dailies-capture-yesterday)
         ("T" . org-roam-dailies-capture-tomorrow))
  :bind-keymap
  ("C-c n d" . org-roam-dailies-map)
  :config
  (require 'org-roam-dailies) ;; Ensure the keymap is available
  (org-roam-db-autosync-mode))

Olivetti mode

Try to make text buffers more readable on a big screen

(use-package olivetti
  :hook (text-mode . olivetti-mode)
  :config
  (setq-default olivetti-body-width 120))

Version control

Magit

(use-package magit
  :bind ("C-x g" . magit-status)
  :init
  (setq magit-diff-refine-hunk t)
  :config
  (setq git-commit-fill-column 70))

Git Gutter

(use-package diff-hl
  :hook (prog-mode . diff-hl-mode))

Project

;; Returns the parent directory containing a .project.el file, if any,
;; to override the standard project.el detection logic when needed.
(defun zkj-project-override (dir)
  (let ((override (locate-dominating-file dir ".projectile")))
    (if override
        (cons 'vc override)
      nil)))

(use-package project
  :bind-keymap ("C-x p" . project-prefix-map))

Company

(use-package company
  :diminish
  :config
  (add-hook 'after-init-hook 'global-company-mode)
  (setq company-dabbrev-downcase nil)
  (setq company-minimum-prefix-length 1)
  (setq company-idle-delay 0.15)
  (add-to-list 'company-backends 'company-capf))

Programming modes

Treesitter

(use-package tree-sitter
  :ensure t
  :hook
  (tree-sitter-after-on . tree-sitter-hl-mode)
  :config
  (global-tree-sitter-mode))

(use-package tree-sitter-langs
  :ensure t)

Fill column

(setq-default fill-column 80)

Compilation

(setq shell-file-name "bash")
(setq shell-command-switch "-lc")
(setq compilation-scroll-output t)

C/C++

Behavior

Use a better indentation for C code.

(use-package google-c-style
  :straight (:type git :host github :repo "google/styleguide"
                   :files ("google-c-style.el"))
  :config
  (add-hook 'c-mode-common-hook 'google-set-c-style)
  (add-hook 'c-mode-common-hook 'google-make-newline-indent))

Eglot

Note that LSP basically only works for my work environment, and emacs must be started from a shell with the proper env variables set.

(use-package flymake)
(use-package eglot
      :ensure t
      :commands (eglot eglot-ensure)
      :hook ((c-mode . eglot-ensure)
             (c++-mode . eglot-ensure)))

Python

(use-package python-mode
  :custom
  (python-shell-interpreter "python3"))

  (use-package pyvenv
    :after python-mode
    :config
    (pyvenv-mode 1))

  (use-package blacken)

Protocol Buffers

(use-package protobuf-mode
  :mode "\\.proto\\'"
  :config
  (defconst my-protobuf-style
    '((c-basic-offset . 2)
      (indent-tabs-mode . nil)))
  (add-hook 'protobuf-mode-hook
            (lambda () (c-add-style "my-style" my-protobuf-style t)))
  )

Makefiles

;; (use-package makefile-mode
;;   :straight nil
;;   :mode "\\.mak\\")

GN files

(use-package gn-mode
  :mode "\\.gni*$")

CSV

(use-package csv-mode
  :mode "\\.csv$")

Go

(use-package go-mode)

Flyspell

(use-package flyspell
  :diminish
  :if (executable-find "aspell")
  :hook
  ((org-mode yaml-mode markdown-mode git-commit-mode) . flyspell-mode)
  (prog-mode . flyspell-prog-mode)
  (before-save-hook . flyspell-buffer)
  (flyspell-mode . (lambda ()
                     (dolist (key '("C-;" "C-," "C-."))
                       (unbind-key key flyspell-mode-map))))
  :custom
  (flyspell-issue-message-flag nil)
  (ispell-program-name "aspell")
  (ispell-extra-args '("--sug-mode=ultra" "--lang=en_US" "--run-together"))
  :config
  (use-package flyspell-correct-ivy
    :bind ("C-M-:" . flyspell-correct-at-point)
    :config
    (when (eq system-type 'darwin)
      (progn
        (global-set-key (kbd "C-M-;") 'flyspell-correct-at-point)))
    (setq flyspell-correct-interface #'flyspell-correct-ivy)))

Very Large Files

(use-package vlf
  :config (progn
            (require 'vlf-setup)))

Elfeed

(use-package elfeed
  :commands (elfeed))

(use-package elfeed-org
  :after elfeed
  :config
  (setq rmh-elfeed-org-files (list "~/.emacs.d/README.org"))
  (elfeed-org))

Blogs

Music

Pitchfork

News

Cooking

Cycling

Bikepacking

Architecture

Custom functions

Copy the current buffer’s file path or dired path to `kill-ring’.

Result is full path. If `universal-argument’ is called first, copy only the dir path.

If in dired, copy the file/dir cursor is on, or marked files.

If a buffer is not file and not dired, copy value of `default-directory’ (which is usually the “current” dir when that buffer was created)

URL `http://ergoemacs.org/emacs/emacs_copy_file_path.html’ Version 2017-09-01

(defun xah-copy-file-path (&optional @dir-path-only-p)
  (interactive "P")
  (let (($fpath
         (if (string-equal major-mode 'dired-mode)
             (progn
               (let (($result (mapconcat 'identity (dired-get-marked-files) "\n")))
                 (if (equal (length $result) 0)
                     (progn default-directory )
                   (progn $result))))
           (if (buffer-file-name)
               (buffer-file-name)
             (expand-file-name default-directory)))))
    (kill-new
     (if @dir-path-only-p
         (progn
           (message "Directory path copied: 「%s" (file-name-directory $fpath))
           (file-name-directory $fpath))
       (progn
         (message "File path copied: 「%s" $fpath)
         $fpath )))))

The end.

VTerm

Requires modifying .bashrc as well, so go to the website to see what the latest is

(use-package vterm
  :config
  (setq vterm-max-scrollback 100000)
  (setq vterm-shell "/bin/zsh"))

multi-vterm

This seems to now be required to start up multiple vterm instances?

(use-package multi-vterm)

Web Mode

(use-package web-mode
  :mode
  (
   ".html?$"
   ".vue$"
   ".tsx$"
   )
  :config
  (setq
   web-mode-markup-indent-offset 2
   web-mode-css-indent-offset 2
   web-mode-code-indent-offset 2
   web-mode-enable-auto-closing t
   web-mode-enable-auto-opening t
   web-mode-enable-auto-pairing t
   web-mode-enable-auto-indentation t))
(setq js-indent-level 2)

LaTeX

(use-package tex-site
  :straight auctex)

Releases

No releases published

Packages

No packages published