/dotfiles

Primary LanguageEmacs Lisp

Usage info

Exclude entries from tangling by commenting them out using org-toggle-comment (C-c ;).

Use S-TAB to fold all headings (optionally with numeric prefix see org-cycle-content).

Personally, I keep this file in my ~/git/dotfiles directory, and create a symlink from my .emacs.d dir to the init.el file in that dotfile dir.

Package management

To prevent Emacs from printing that packages have been installed already, we define a simple helper function. And instead of using package-install we use use in this file.

(defun use (package)
  (unless (package-installed-p package)
    (package-install package))
  (package-activate package))

General

Add Melpa archive

Some packages are only available from Melpa

(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
;; (package-initialize)

Custom file

Because we overwrite the init.el on each tangle, we should define a separate <a href=”info:emacs#Saving Customizations”>custom file.

(setq custom-file "~/git/dotfiles/custom.el")
(load custom-file)

Lexical binding

In Emacs we should add the following initial comment to each file by default, see Lexical Binding.

;;; -*- lexical-binding: t; -*-

Hide gui-elements

(scroll-bar-mode -1)
(tool-bar-mode -1)
(menu-bar-mode -1)

Cursor config

(blink-cursor-mode -1)

Show tabs

(global-tab-line-mode)

Fix scrolling

(setq scroll-conservatively 101)

ESC quit

(global-set-key (kbd "<escape>") 'keyboard-escape-quit)

Tab complete

(setq tab-always-indent 'complete)

Describe select help window

(setq help-window-select t)

Elisp development

Set package archive directory

(add-to-list 'package-archives '("personal" . "/home/dalanicolai/emacs/pkg-archive"))

(with-eval-after-load
    (setq package-archive-upload-base "/home/dalanicolai/emacs/pkg-archive"))

Global config

Start emacs server

(require 'server)

;; prevent display warning when server is running
(unless (server-running-p)
  (server-start))

Find special files/buffers

(defun find-init-file ()
  (interactive)
  (let* ((true-init (file-truename user-init-file))
   (init-true-dir (file-name-directory true-init)))
  (find-file (concat init-true-dir "README.org"))))

(defun load-init-file ()
  (interactive)
  (load-file user-init-file))

(defun pop-to-messages ()
  (interactive)
  (switch-to-buffer (get-buffer-create "*Messages*")))

(defun pop-to-scratch ()
  (interactive)
  (switch-to-buffer (get-scratch-buffer-create)))

Auto insert mode

In order to never forget inserting the lexical-binding variable in elisp files, we simply use auto-insert-mode

(auto-insert-mode)

Store command history

(savehist-mode)

Store file history

(recentf-mode)

Cursor format (color/shape)

(setq evil-normal-state-cursor "DarkGoldenrod2"
evil-insert-state-cursor '("chartreuse3" bar)
evil-emacs-state-cursor '("SkyBlue2" box)
evil-visual-state-cursor '("gray" (hbar . 2))
evil-motion-state-cursor '("plum3" box))
;;                                  ("hybrid" "SkyBlue2" (bar . 2))
;;                                  ("replace" "chocolate" (hbar . 2))
;;                                  ("evilified" "LightGoldenrod3" box)
;;                                  ("lisp" "HotPink1" box)
;;                                  ("iedit" "firebrick1" box)
;;                                  ("iedit-insert" "firebrick1" (bar . 2)))
;;   "Colors assigned to evil states with cursor definitions.
;; To add your own, use `spacemacs/add-evil-curosr'.")

Core packages

evil

Init

 (use 'evil)

 (setq evil-want-integration t ;; This is optional since it's already set to t by default.
	evil-want-keybinding nil
	evil-want-C-i-jump t
	evil-respect-visual-line-mode t
	evil-undo-system 'undo-redo
	evil-symbol-word-search t)

 (evil-mode)

 (add-to-list 'evil-motion-state-modes 'special-mode)

Evil leader

(defvar my-leader-map (make-sparse-keymap))
(defvar-local my-local-leader-map nil)
(defun local-leader-map-init ()
  (setq my-local-leader-map (make-sparse-keymap)))

(dolist (s (list evil-normal-state-map
		   evil-motion-state-map))
  (keymap-set s "SPC" (cons "root" my-leader-map)))

(dolist (s (list evil-insert-state-map
		   evil-emacs-state-map))
  (keymap-set s "M-SPC" (cons "root" my-leader-map)))

Helper functions

;; (defun keymap-set-key-recursively (map keyseq cmd)
;;   (unless (memq nil (mapcar (lambda (ch)
;;                             (and (numberp ch)
;;                                  (<= 0 ch 127)))
;;                           (key-parse keyseq)))
;;     (setq keyseq (kbd keyseq)))
;;   (cond ((= (length keyseq) 1)
;;          (keymap-set map (if (string= keyseq " ") "SPC" keyseq) cmd))
;;         (t (let* ((key (substring keyseq 0 1))
;;                   (child-map (keymap-lookup map key)))
;;              (unless child-map
;;                (setq child-map (make-sparse-keymap))
;;                (keymap-set map key child-map))
;;              (keymap-set-key-recursively child-map (substring keyseq 1) cmd)))))

(defun keymap-set-multi (map &rest bindings)
  (while bindings
    (pcase-let ((`(,key ,cmd) bindings))
      ;; (keymap-set-key-recursively map key cmd))
      (define-key map key cmd))
    (setq bindings (cddr bindings))))

Core leader keybindings

;; alternatively prefix keymap can be created using
;; `which-key-add-keymap-based-replacements'
;; (which-key-add-keymap-based-replacements my-leader-map "b" "buffers")


(keymap-set-multi my-leader-map
      (kbd "SPC")   'execute-extended-command
      (kbd "<tab>") 'evil-switch-to-windows-last-buffer
      ";"           'comment-or-uncomment-region

      "b"  '("buffer" . (keymap))
      "bb" 'switch-to-buffer
      "bd" 'kill-current-buffer
      "bm" 'pop-to-messages
      "bs" 'pop-to-scratch

      "c" '("compile" . (keymap))
      "cc" 'recompile

      "e" '("edit" . (keymap))

      "f"   '("files" . (keymap))
      "fe"  '("emacs" . (keymap))
      "fed" 'find-init-file
      "feR" 'load-init-file
      "ff"  'find-file
      "fr"  'recentf
      "fs"  'save-buffer

      "g" '("git" . (keymap))

      "h"  '("help" . (keymap))
      "hc" 'describe-char
      "hf" 'describe-function
      "hj" 'info-display-manual
      "hk" 'describe-key
      "hv" 'describe-variable
      "hK" 'describe-keymap

      "j"  '("jump" . (keymap))
      "jf" 'find-function
      "ji" 'imenu ;might get overwritten by ivy/vertico/helm section 
      "jl" 'find-library

      "l" '("lisp" . (keymap))

      "o"  '("org" . (keymap))

      "s"  '("search" . (keymap))
      "sl" 'locate

      "t"  '("toggles" . (keymap))
      "tl" 'display-line-numbers-mode

      "u" 'universal-argument

      "w"  '("windows" . (keymap))
      "w/" 'split-window-right
      "wd" 'delete-window
      "wm" 'delete-other-windows
      "ww" 'other-window

      "q"  '("quit" . (keymap))
      "qq" 'save-buffers-kill-emacs)

Evil improved keybindings

(evil-define-key 'normal 'global
  ;; (kbd "C-j") 'evil-join
  (kbd "C-f") 'evil-join
  "J" 'nil)

(evil-define-key 'motion 'global
  "J" 'evil-scroll-page-down
  "K" 'evil-scroll-page-up)

;; (evil-global-set-key 'motion (kbd "<tab>") 'indent-for-tab-command)
(evil-define-key '(motion normal emacs) 'global
  (kbd "C-.") 'next-buffer
  (kbd "C-,") 'previous-buffer)

(evil-define-key 'normal prog-mode-map (kbd "<tab>") 'indent-for-tab-command)

spacemacs-theme

(use 'spacemacs-theme)
(load-theme 'spacemacs-dark t)

which-key

(use 'which-key)
(which-key-mode)

embark

(use 'embark)
(evil-define-key '(normal) 'global (kbd "M-.") 'embark-act)

link-hint

(use 'link-hint)
(evil-define-key 'normal special-mode-map "o" 'link-hint-open-link)

outline-mode

(evil-define-key 'normal 'global
  "zA" 'outline-cycle-buffer
  "zC" 'outline-hide-sublevels
  "zO" 'outline-show-all)
(add-hook 'prog-mode-hook #'outline-minor-mode)

kill-file-path

(use 'kill-file-path)
(require 'kill-file-path)

(keymap-set-multi my-leader-map
  "fyy" 'kill-file-path
  "fyn" 'kill-file-path-basename
  "fyd" 'kill-file-path-dirname
  "fyw" 'kill-file-path-basename-without-extension)

evil

Evil collection

(use 'evil-collection)
(evil-collection-init)
;; (evil-collection-help-setup)

Evil surround

(use 'evil-surround)
(global-evil-surround-mode)

emacs-lisp

major-mode keybdingins

(defun evil-emacs-lisp-set-follow-key ()
  (dolist (m (list emacs-lisp-mode-map lisp-interaction-mode-map))
    (keymap-set (evil-get-auxiliary-keymap m 'normal t) "," (local-leader-map-init)))
  (keymap-set-multi my-local-leader-map
		      "d"  '("debug" . (keymap))
		      "dw" 'ldbg-ldbg-wrap
		      "du" 'ldbg-ldbg-unwrap

		      "e"  '("eval" . (keymap))
		      "eb" 'eval-buffer
		      "ef" 'eval-defun

		      "w" 'sp-wrap-round
		      "u" 'sp-unwrap-sexp))

(dolist (m '(emacs-lisp-mode-hook lisp-interaction-mode-hook))
  (add-hook m #'evil-emacs-lisp-set-follow-key))

smartparens

(use 'smartparens)
(smartparens-global-mode)
(keymap-set-multi my-leader-map
  "lw" 'sp-wrap-round)

Modules

org

;; (with-eval-after-load 'org (evil-collection-org-setup))

(keymap-set my-leader-map "o l" 'org-store-link)

(defun org-copy-link ()
  (interactive)
  (let ((begin (org-element-property :begin (org-element-context)))
	    (end (org-element-property :end (org-element-context))))
    (kill-ring-save begin end)))

(defun evil-org-set-follow-key ()
  (keymap-set (evil-get-auxiliary-keymap org-mode-map 'normal t) "," (local-leader-map-init))
  (keymap-set-multi my-local-leader-map
		      "d" 'org-babel-demarcate-block
		      "il" 'org-insert-link
		      "l" 'org-copy-link))

(add-hook 'org-mode-hook #'evil-org-set-follow-key)

org-superstar

(use 'org-superstar)
(add-hook 'org-mode-hook (lambda () (org-superstar-mode 1)))

Completion (ivy/vertico/helm etc.)

Company

(use 'company)
(add-hook 'after-init-hook 'global-company-mode)
;; (evil-collection-company-setup)

ivy

(use 'ivy)
(use 'counsel)
(use 'ivy-rich)
(ivy-mode)
(counsel-mode)
(ivy-rich-mode)


;; taken directly from Spacemacs
(dolist (map (list ivy-minibuffer-map
       ivy-switch-buffer-map
       ivy-reverse-i-search-map))
  (keymap-set map "C-j" 'ivy-next-line)
  (keymap-set map "C-k" 'ivy-previous-line))
(keymap-set ivy-minibuffer-map "M-." 'embark-act)
(keymap-set ivy-minibuffer-map "C-h" "DEL")
;; Move C-h to C-S-h
(keymap-set ivy-minibuffer-map "C-S-h" help-map)
(keymap-set ivy-minibuffer-map "C-l" 'ivy-alt-done)
(keymap-set ivy-minibuffer-map "<escape>"
      'minibuffer-keyboard-quit)

(keymap-set-multi my-leader-map
  "ss" 'swiper
  "/"  'counsel-rg)

Vertico

(use 'vertico)
(use 'consult)

(vertico-mode)

(keymap-set-multi my-leader-map
  "/"  'counsel-rg)

Language server

eglot

(use 'eglot)

magit

(use 'magit)
(with-eval-after-load 'magit
  (define-key magit-mode-map (kbd "SPC") nil t))
(with-eval-after-load 'magit-diff
  (define-key magit-diff-mode-map (kbd "SPC") nil t))


  ;; (with-eval-after-load 'magit-section (evil-collection-magit-section-setup))
  ;; (with-eval-after-load 'magit
  ;;   (keymap-set magit-mode-map "SPC" my-leader-map)
  ;;   (evil-collection-magit-setup))

  (keymap-set-multi my-leader-map
    "gs" 'magit)

search

rg

(use 'rg)
(keymap-set-multi my-leader-map
  "sr" 'rg)

python

(defun my-python-mode-hook ()
  (setq fill-column 80))

(add-hook 'python-mode-hook #'my-python-mode-hook)
(setq python-shell-interpreter "ipython")
(setq python-shell-interpreter-args "--simple-prompt")


(with-eval-after-load 'org
  (require 'ob-python))

User config

org-journal

(use 'org-journal)
(setq org-journal-file-type 'weekly)

doc-scroll-pymupdf

;; (load-file "/home/dalanicolai/git/doc-tools/doc-scroll-pymupdf.el")
;; (use 'doc-scroll-pymupdf)
;; (use 'doc-pymupdf-epc)
;; (require 'doc-backend)
;; (load-file "/home/dalanicolai/git/doc-tools/doc-backend.el")
(use 'epc)
(add-to-list 'load-path "/home/dalanicolai/git/emacs-doc-tools/")
(load-file "/home/dalanicolai/git/emacs-doc-tools/doc-tools-autoloads.el")
(evil-define-key 'motion doc-scroll-mode-map "j" #'doc-scroll-forward)
(evil-define-key 'motion doc-scroll-mode-map "k" #'doc-scroll-backward)
(evil-define-key 'motion doc-scroll-mode-map "J" #'doc-scroll-next-page)
(evil-define-key 'motion doc-scroll-mode-map "K" #'doc-scroll-previous-page)

ladebug

(load-file "/home/dalanicolai/git/emacs-ladebug/ladebug.el")

;; (bind-map-set-keys my-elisp-map
;;   "dw" 'ldbg-ldbg-wrap
;;   "du" 'ldbg-ldbg-unwrap)

(keymap-set-multi my-leader-map
  "bw" 'ldbg-switch-to-warning-buffer)

iedit

(use 'evil-iedit-state)
(require 'evil-iedit-state)

(keymap-set-multi my-leader-map
  "ee" 'evil-iedit-state/iedit-mode)

vterm

(use 'vterm)

(keymap-set-multi my-leader-map
  "'" 'vterm)
(evil-global-set-key 'insert (kbd "C-d") nil)

mastodon

(use 'mastodon)

(setq mastodon-instance-url "https://emacs.ch"
mastodon-active-user "dalanicolai")

all the icons

(use 'all-the-icons)

org-wc

(use 'org-wc)

imenu-list

(use 'imenu-list)

hl-todo

(use 'hl-todo)
(global-hl-todo-mode)
(setq hl-todo-exclude-modes nil)

Info

(evil-define-key 'motion Info-mode-map
  "n" 'Info-search-next
  "p" 'Info-search-backward)

fasd

(use 'fasd)

(keymap-set-multi my-leader-map
		    "fa" '("fasd" . (keymap))
		    "fas" 'fasd-find-file)

Makefile

(add-hook 'makefile-mode-hook (lambda () (setq tab-width 2)))

org-jupyter

(use 'jupyter)

org-cv

(add-to-list 'load-path "~/git/org-cv")
(require 'ox-moderncv)

counsel-make command

 (defun counsel-make ()
   (interactive)
   (let (targets)
     (with-temp-buffer
	(insert-file-contents-literally "Makefile")
	(goto-char (point-min))
	(while (search-forward-regexp "^\\([^ \n]*\\): " nil t)
	  (push (match-string-no-properties 1) targets)))

     (compile (format "make -k %s"
		       (ivy-read "Target: " (nreverse targets))))))