dotfiles

my active dotfiles
git clone git://git.jakekoroman.com/dotfiles
Log | Files | Refs | README

init.el (18104B)


      1 ;;; -*- lexical-binding: t -*-
      2 
      3 (setq custom-file (concat user-emacs-directory "custom.el"))
      4 (add-to-list 'load-path "~/.config/emacs/local")
      5 (add-to-list 'custom-theme-load-path "~/.config/emacs/local")
      6 (when (file-exists-p custom-file)
      7   (load custom-file))
      8 
      9 (load "odin-mode.el")
     10 
     11 ;;; Appearance and basic functionality
     12 (menu-bar-mode -1)
     13 (tool-bar-mode -1)
     14 (scroll-bar-mode -1)
     15 
     16 (setq jrk/font-name "Iosevka-")
     17 (setq jrk/font-size 12)
     18 (setq jrk/font-big-size 24)
     19 (setq jrk/font (concat jrk/font-name (number-to-string jrk/font-size)))
     20 (modify-all-frames-parameters `((font . ,jrk/font)))
     21 (load-theme 'gruber-darker t)
     22 
     23 (set-default 'truncate-lines nil)
     24 
     25 (add-hook 'before-save-hook 'delete-trailing-whitespace)
     26 
     27 ;; no tabs in lisp files
     28 (add-hook 'scheme-mode-hook (lambda () (setq indent-tabs-mode nil)))
     29 (add-hook 'emacs-lisp-mode-hook (lambda () (setq indent-tabs-mode nil)))
     30 
     31 ;; tab-width 2 in html and js files
     32 (add-hook 'mhtml-mode-hook (lambda () (setq tab-width 2)))
     33 (add-hook 'js-mode-hook (lambda ()
     34                           (setq js-indent-level 2)
     35                           (setq tab-width 2)))
     36 
     37 (add-hook 'Info-mode-hook (lambda () (display-line-numbers-mode -1)))
     38 
     39 (setq display-buffer-alist
     40       '(
     41         ((or "\\*Help\\*"
     42              "\\*Occur\\*")
     43          (display-buffer-reuse-mode-window display-buffer-below-selected))
     44         ))
     45 
     46 (setq-default tab-width 4
     47               require-final-newline t)
     48 (setq inhibit-splash-screen t
     49       inhibit-startup-message t
     50       scroll-step 3
     51       auto-save-default nil
     52       make-backup-files nil
     53       blink-cursor-mode nil
     54       ring-bell-function 'ignore
     55       display-line-numbers-type 'relative
     56       dired-listing-switches "-alh --group-directories-first"
     57       compilation-scroll-output t
     58       gc-cons-threshold 100000000
     59       compilation-ask-about-save nil
     60       frame-resize-pixelwise t
     61       mouse-drag-mode-line-buffer 1
     62       display-time-24hr-format t
     63       use-short-answers t
     64       read-answer-short 'auto
     65       visible-cursor nil ;; no cursor blink in tui
     66       )
     67 
     68 ;; (global-hl-line-mode 1)
     69 (global-display-line-numbers-mode)
     70 
     71 (require 'package)
     72 (add-to-list 'package-archives
     73              '("melpa" . "https://melpa.org/packages/") t)
     74 
     75 (use-package icomplete
     76   :ensure nil
     77   :config
     78   (setq completion-auto-select t
     79         completions-sort 'historical
     80         completions-max-height 20
     81         completions-format 'one-column
     82         completion-ignore-case t)
     83   (fido-vertical-mode))
     84 
     85 (use-package ediff
     86   :ensure nil
     87   :config
     88   (setq ediff-window-setup-function 'ediff-setup-windows-plain)
     89   (setq ediff-split-window-function 'split-window-horizontally))
     90 
     91 (use-package compile
     92   :ensure nil
     93   :config
     94   ;; pascal compilation errors
     95   (add-to-list 'compilation-error-regexp-alist
     96                '("^\\(.*\\)(\\([0-9]+\\)+\\,\\([0-9]+\\)).*" 1 2 3)))
     97 
     98 (use-package modus-themes
     99   :ensure nil
    100   :config
    101   (setq modus-themes-org-blocks 'gray-background))
    102 
    103 (use-package ef-themes
    104   :ensure t)
    105 
    106 (use-package minions
    107   :ensure t
    108 
    109   :custom
    110   (minions-mode-line-delimiters (cons "" ""))
    111 
    112   :config
    113   (defun +set-minions-mode-line-lighter ()
    114     (setq minions-mode-line-lighter
    115           (if (display-graphic-p) "⚙" "#")))
    116 
    117   (add-hook 'server-after-make-frame-hook #'+set-minions-mode-line-lighter)
    118   (display-time-mode 1)
    119   (display-battery-mode 1)
    120   (minions-mode 1))
    121 
    122 (use-package olivetti
    123   :ensure t
    124   :config
    125   (add-hook 'olivetti-mode-on-hook (lambda () (olivetti-set-width 144))))
    126 
    127 (use-package zenburn-theme
    128   :ensure t)
    129 
    130 (use-package savehist
    131   :ensure nil
    132   :init
    133   (savehist-mode))
    134 
    135 (use-package eat
    136   :ensure t)
    137 ;; (add-hook 'eshell-first-time-mode-hook #'eat-eshell-mode))
    138 
    139 (use-package eshell
    140   :ensure nil
    141   :config
    142   (setq eshell-cp-interactive-query t)  (add-to-list 'eshell-modules-list 'eshell-elecslash)
    143   :hook (eshell-mode . (lambda ()
    144                          (display-line-numbers-mode -1))))
    145 
    146 (use-package vertico
    147   :ensure t
    148   :init
    149   ;; (vertico-mode 1)
    150   (setq vertico-cycle t))
    151 
    152 (use-package completion-preview
    153   :ensure nil
    154   :bind
    155   (:map completion-preview-active-mode-map
    156         ("M-n" . completion-preview-next-candidate)
    157         ("M-p" . completion-preview-prev-candidate))
    158   :hook
    159   (emacs-lisp-mode . (lambda () (completion-preview-mode))))
    160 
    161 (use-package orderless
    162   :ensure t
    163   :custom
    164   (completion-styles '(orderless basic))
    165   (completion-category-overrides '((file (styles basic partial-completion)))))
    166 
    167 (use-package dired
    168   :ensure nil
    169   :bind
    170   (:map dired-mode-map
    171         ("o" . dired-find-file)
    172         ("n" . dired-up-directory))
    173   :config
    174   (setq dired-clean-up-buffers-too t
    175         dired-dwim-target t
    176         dired-recursive-copies 'always
    177         dired-recursive-deletes 'top
    178         global-auto-revert-non-file-buffers t
    179         auto-revert-verbose nil))
    180 
    181 (use-package marginalia
    182   :ensure t
    183   :init
    184   (marginalia-mode))
    185 
    186 (use-package company
    187   :ensure t
    188   :config
    189   (setq company-idle-delay nil)
    190   (global-company-mode)
    191   :bind
    192   ("C-<return>" . company-complete)
    193   ("C-<tab>"    . dabbrev-expand))
    194 
    195 (use-package yasnippet
    196   :ensure t
    197   :config
    198   (require 'company)
    199   ;; Add yasnippet support for all company backends
    200   ;; https://github.com/syl20bnr/spacemacs/pull/179
    201   (defvar company-mode/enable-yas t
    202     "Enable yasnippet for all backends.")
    203 
    204   (defun company-mode/backend-with-yas (backend)
    205     (if (or (not company-mode/enable-yas) (and (listp backend) (member 'company-yasnippet backend)))
    206         backend
    207       (append (if (consp backend) backend (list backend))
    208               '(:with company-yasnippet))))
    209   (setq company-backends (mapcar #'company-mode/backend-with-yas company-backends))
    210   (yas-global-mode 1))
    211 
    212 (use-package dumb-jump
    213   :ensure t
    214   :config
    215   (setq xref-show-definitions-function #'xref-show-definitions-completing-read)
    216   (add-hook 'xref-backend-functions #'dumb-jump-xref-activate))
    217 
    218 (use-package magit :ensure t)
    219 
    220 (use-package go-mode :ensure t)
    221 
    222 (use-package lua-mode :ensure t)
    223 
    224 (use-package rust-mode :ensure t)
    225 
    226 (use-package glsl-mode :ensure t)
    227 
    228 (use-package htmlize :ensure t)
    229 
    230 (use-package zig-mode
    231   :ensure t
    232   :config
    233   (setq zig-format-on-save nil))
    234 
    235 (use-package org
    236   :ensure nil
    237   :config
    238   (setq org-directory "~/org")
    239   (setq org-agenda-files (list org-directory))
    240   (setq org-html-validation-link nil)
    241   (setq org-insert-heading-respect-content t)
    242   (org-babel-do-load-languages
    243    'org-babel-load-languages
    244    '((shell . t)))
    245   :hook (org-mode . (lambda ()
    246                       (display-line-numbers-mode -1))))
    247 
    248 (use-package org-tempo
    249   :ensure nil
    250   :after (org)
    251   :config
    252   (add-to-list 'org-structure-template-alist
    253                '("el" . "src emacs-lisp")))
    254 
    255 (use-package org-bullets
    256   :ensure t
    257   :after (org))
    258   ;; :hook
    259   ;; (org-mode . (lambda ()
    260   ;;               (org-bullets-mode))))
    261 
    262 (use-package ido
    263   :ensure t
    264   :config
    265   (setq ido-enable-flex-matching t
    266         ido-everywhere t
    267         ido-show-dot-for-dired t
    268         ido-auto-merge-work-directories-length -1)
    269   (ido-mode 0))
    270 
    271 (use-package message
    272   :ensure nil
    273   :config
    274   (setq message-kill-buffer-on-exit t))
    275 
    276 (use-package notmuch
    277   :ensure t
    278   :hook
    279   (message-setup . (lambda () (mml-secure-sign-pgpmime)))
    280   :bind
    281   ("C-c n" . notmuch)
    282   :config
    283   (setq send-mail-function 'sendmail-send-it
    284         sendmail-program "msmtp"
    285         ;; msmtp read from address to determine which smtp account to use
    286         message-sendmail-extra-arguments '("--read-envelope-from")
    287         ;; removes the very evil --from
    288         message-sendmail-f-is-evil t)
    289 
    290   (setq notmuch-identities '("Jake Koroman <jake@jakekoroman.com>"
    291                              "Jake Koroman <koromanj@miltonhydro.com>"))
    292   (setq notmuch-fcc-dirs '(("jake@jakekoroman.com" . "personal/Sent")
    293                            ("koromanj@miltonhydro.com" . "work/Sent")))
    294   (setq notmuch-always-prompt-for-sender t)
    295   (setq notmuch-draft-folder "drafts"))
    296 
    297 (setq-default c-basic-offset 4
    298               c-default-style '((java-mode . "java")
    299                                 (awk-mode . "awk")
    300                                 (other . "bsd")))
    301 (c-set-offset 'case-label '+)
    302 
    303 (font-lock-add-keywords 'c-mode
    304                         '(("internal" . font-lock-keyword-face)
    305                           ("global" . 'font-lock-keyword-face)))
    306 
    307 (use-package web-mode
    308   :ensure t)
    309   ;; :hook
    310   ;; (web-mode . (lambda ()
    311   ;;               (setq tab-width 2
    312   ;;                     web-mode-style-padding 2
    313   ;;                     web-mode-script-padding 2
    314   ;;                     web-mode-markup-indent-offset 2
    315   ;;                     web-mode-code-indent-offset 2
    316   ;;                     setq web-mode-css-indent-offset 2))))
    317 
    318 (defun jrk/eshell ()
    319   "Open eshell in other window"
    320   (interactive)
    321   (split-window-sensibly)
    322   (other-window 1)
    323   (eshell))
    324 
    325 (defun jrk/indent-buffer ()
    326   "Run indent-region on entire buffer"
    327   (interactive)
    328   (indent-region (point-min) (point-max) nil))
    329 ;; (add-hook 'before-save-hook 'indent-buffer)
    330 
    331 (defun jrk/find-corresponding-file ()
    332   "Find the file that corresponds to this one."
    333   (interactive)
    334   (setq CorrespondingFileName nil)
    335   (setq BaseFileName (file-name-sans-extension buffer-file-name))
    336   (if (string-match "\\.c" buffer-file-name)
    337       (setq CorrespondingFileName (concat BaseFileName ".h")))
    338   (if (string-match "\\.h" buffer-file-name)
    339       (if (file-exists-p (concat BaseFileName ".c"))
    340           (setq CorrespondingFileName (concat BaseFileName ".c"))
    341         (setq CorrespondingFileName (concat BaseFileName ".cpp"))))
    342   (if (string-match "\\.hin" buffer-file-name)
    343       (setq CorrespondingFileName (concat BaseFileName ".cin")))
    344   (if (string-match "\\.cin" buffer-file-name)
    345       (setq CorrespondingFileName (concat BaseFileName ".hin")))
    346   (if (string-match "\\.cpp" buffer-file-name)
    347       (setq CorrespondingFileName (concat BaseFileName ".h")))
    348   (if CorrespondingFileName (find-file CorrespondingFileName)
    349     (error "Unable to find a corresponding file")))
    350 
    351 (defun jrk/find-corresponding-file-other-window ()
    352   "Finds the file that corresponds to this and opens it in the other window."
    353   (interactive)
    354   (find-file-other-window buffer-file-name)
    355   (find-corresponding-file))
    356 
    357 (defun jrk/gud ()
    358   "Run gud-gdb in other window"
    359   (interactive)
    360   (let* ((files (directory-files (file-name-directory buffer-file-name)))
    361         (input (completing-read "executable: " files)))
    362     (split-window-sensibly)
    363     (other-window 1)
    364     (gud-gdb (concat "gdb --fullname " input))))
    365 
    366 ;; Sets the default compile command based on OS
    367 (if (string= system-type "windows-nt")
    368     (setq compile-command "build.bat")
    369   (setq compile-command "./build.sh"))
    370 
    371 (defun jrk/disable-all-themes ()
    372   "Disables all active themes."
    373   (interactive)
    374   (dolist (i custom-enabled-themes)
    375     (disable-theme i)))
    376 
    377 (defun jrk/load-theme-proper ()
    378   "Disables all active themes and loads new one"
    379   (interactive)
    380   (let ((theme (completing-read "Load custom theme: " (custom-available-themes))))
    381     (jrk/disable-all-themes)
    382     (load-theme (intern theme) t)))
    383 
    384 (defun jrk/update-theme ()
    385   "Set theme based on time of day"
    386   (interactive)
    387   (let ((hour (nth 2 (parse-time-string (current-time-string)))))
    388     (disable-all-themes)
    389     (if (and (> hour 9)
    390              (< hour 18))
    391         (load-theme 'zenburn t)
    392       (load-theme 'gruber-darker t))))
    393 
    394 (defun jrk/swap-theme ()
    395   "Swaps theme to either zenburn or gruber-darker"
    396   (interactive)
    397   (let ((theme (nth 0 custom-enabled-themes)))
    398     (disable-all-themes)
    399     (if (string= theme "gruber-darker")
    400         (load-theme 'zenburn t)
    401       (load-theme 'gruber-darker t))))
    402 
    403 (defun jrk/transparency (value)
    404   "Sets the transparency of the frame window. 0=transparent/100=opaque"
    405   (interactive "nTransparency Value 0 - 100 opaque: ")
    406   (set-frame-parameter (selected-frame) 'alpha-background value))
    407 
    408 (defun jrk/toggle-big-font ()
    409   "Toggles on/off a bigger font for hidpi or presentations"
    410   (interactive)
    411   (if (eq (aref (font-info (face-attribute 'default :font)) 2) (* 2 jrk/font-size))
    412       (setq jrk/font (concat jrk/font-name (number-to-string jrk/font-big-size)))
    413     (setq jrk/font (concat jrk/font-name (number-to-string jrk/font-size))))
    414   (set-frame-font jrk/font))
    415 
    416 (defun jrk/meow-setup-colemakdh ()
    417   (setq meow-cheatsheet-layout meow-cheatsheet-layout-colemak-dh)
    418   (meow-motion-overwrite-define-key
    419    '("i" . meow-prev)
    420    '("e" . meow-next)
    421    '(";" . meow-temp-normal)
    422    '("/" . meow-visit)
    423    '("v" . meow-search)
    424    '("<escape>" . ignore))
    425   (meow-leader-define-key
    426    '("?" . meow-cheatsheet)
    427    '("." . find-file)
    428    '("," . switch-to-buffer)
    429    '(">" . find-file-other-window)
    430    '("<" . switch-to-buffer-other-window)
    431    '("q" . compile)
    432    '("d" .  dired-jump)
    433    '("o" .  other-window)
    434    '("1" . meow-digit-argument)
    435    '("2" . meow-digit-argument)
    436    '("3" . meow-digit-argument)
    437    '("4" . meow-digit-argument)
    438    '("5" . meow-digit-argument)
    439    '("6" . meow-digit-argument)
    440    '("7" . meow-digit-argument)
    441    '("8" . meow-digit-argument)
    442    '("9" . meow-digit-argument)
    443    '("0" . meow-digit-argument))
    444   (meow-normal-define-key
    445    '("0" . meow-expand-0)
    446    '("1" . meow-expand-1)
    447    '("2" . meow-expand-2)
    448    '("3" . meow-expand-3)
    449    '("4" . meow-expand-4)
    450    '("5" . meow-expand-5)
    451    '("6" . meow-expand-6)
    452    '("7" . meow-expand-7)
    453    '("8" . meow-expand-8)
    454    '("9" . meow-expand-9)
    455    '("-" . negative-argument)
    456    '(";" . meow-reverse)
    457    '("," . meow-inner-of-thing)
    458    '("." . meow-bounds-of-thing)
    459    '("[" . meow-beginning-of-thing)
    460    '("]" . meow-end-of-thing)
    461    '("/" . meow-visit)
    462    '("a" . meow-append)
    463    '("A" . meow-open-below)
    464    '("b" . meow-back-word)
    465    '("B" . meow-back-symbol)
    466    '("c" . meow-change)
    467    '("i" . meow-prev)
    468    '("I" . join-line)
    469    '("f" . meow-find)
    470    '("g" . meow-cancel-selection)
    471    '("G" . meow-grab)
    472    '("n" . meow-left)
    473    '("N" . meow-left-expand)
    474    '("o" . meow-right)
    475    '("O" . meow-right-expand)
    476    '("j" . meow-join)
    477    '("k" . meow-kill)
    478    '("l" . meow-line)
    479    '("L" . meow-goto-line)
    480    '("h" . meow-mark-word)
    481    '("H" . meow-mark-symbol)
    482    '("e" . meow-next)
    483    '("E" . meow-next-expand)
    484    '("m" . meow-block)
    485    '("M" . meow-to-block)
    486    '("p" . meow-yank)
    487    '("q" . meow-quit)
    488    '("r" . meow-replace)
    489    '("s" . meow-insert)
    490    '("S" . meow-open-above)
    491    '("t" . meow-till)
    492    '("u" . meow-undo)
    493    '("U" . meow-undo-in-selection)
    494    '("v" . meow-search)
    495    '("w" . meow-next-word)
    496    '("W" . meow-next-symbol)
    497    '("x" . meow-delete)
    498    '("X" . meow-backward-delete)
    499    '("y" . meow-save)
    500    '("z" . meow-pop-selection)
    501    '("'" . repeat)
    502    '("<escape>" . ignore)))
    503 
    504 (global-set-key (kbd "M-n") 'next-error)
    505 (global-set-key (kbd "M-p") 'previous-error)
    506 (global-set-key (kbd "<f2>") 'olivetti-mode)
    507 
    508 (use-package meow
    509   :ensure t
    510   :config
    511   (add-to-list 'meow-mode-state-list '(notmuch-hello-mode . motion))
    512   (add-to-list 'meow-mode-state-list '(notmuch-search-mode . motion))
    513   (add-to-list 'meow-mode-state-list '(godoc-mode . normal))
    514   (add-to-list 'meow-mode-state-list '(ediff-mode . insert))
    515   (setq meow-use-clipboard t)
    516   (setq meow-keypad-self-insert-undefined nil)
    517   (jrk/meow-setup-colemakdh)
    518   (meow-setup-indicator)
    519   (meow-global-mode 1))
    520 
    521 (setq jrk/mpv-cmd "mpv")
    522 (setq jrk/ytdlp-cmd "yt-dlp")
    523 (setq jrk/ytdlp-cmd-args '("--embed-chapters" "--sponsorblock-remove" "Sponsor" "-P" "~/videos"))
    524 
    525 (defun jrk/elfeed-show-running-cmd ()
    526   (let ((cmd browse-url-generic-program)
    527         (args browse-url-generic-args)
    528         (format-str "opening with %s")
    529         (arg-str ""))
    530     (dolist (arg args)
    531       (setf arg-str (concat arg-str " " arg)))
    532     (message (format format-str
    533                      (concat cmd arg-str)))))
    534 
    535 (defun jrk/clear-browse-url-progam ()
    536   (setq browse-url-generic-program nil)
    537   (setq browse-url-generic-args nil))
    538 
    539 (defun jrk/elfeed-show-open-mpv ()
    540   (interactive)
    541   (setq browse-url-generic-program jrk/mpv-cmd)
    542   (jrk/elfeed-show-running-cmd)
    543   (elfeed-show-visit 1)
    544   (jrk/clear-browse-url-progam))
    545 
    546 (defun jrk/elfeed-search-open-mpv ()
    547   (interactive)
    548   (setq browse-url-generic-program jrk/mpv-cmd)
    549   (jrk/elfeed-show-running-cmd)
    550   (elfeed-search-browse-url 1)
    551   (jrk/clear-browse-url-progam))
    552 
    553 (defun jrk/elfeed-show-open-ytdlp ()
    554   (interactive)
    555   (setq browse-url-generic-program jrk/ytdlp-cmd)
    556   (setq browse-url-generic-args jrk/ytdlp-cmd-args)
    557   (jrk/elfeed-show-running-cmd)
    558   (elfeed-show-visit 1)
    559   (jrk/clear-browse-url-progam))
    560 
    561 (defun jrk/elfeed-search-open-ytdlp ()
    562   (interactive)
    563   (setq browse-url-generic-program jrk/ytdlp-cmd)
    564   (setq browse-url-generic-args jrk/ytdlp-cmd-args)
    565   (jrk/elfeed-show-running-cmd)
    566   (elfeed-search-browse-url 1)
    567   (jrk/clear-browse-url-progam))
    568 
    569 (use-package elfeed
    570   :ensure t
    571   :bind
    572   (("C-c r" . elfeed)
    573    :map elfeed-show-mode-map
    574    ("m" . jrk/elfeed-show-open-mpv)
    575    ("d" . jrk/elfeed-show-open-ytdlp)
    576 
    577    :map elfeed-search-mode-map
    578    ("m" . jrk/elfeed-search-open-mpv)
    579    ("d" . jrk/elfeed-search-open-ytdlp)
    580 
    581    )
    582   :config
    583   (setq elfeed-feeds
    584         '(
    585           ("https://www.youtube.com/feeds/videos.xml?channel_id=UCLtREJY21xRfCuEKvdki1Kw" youtube)
    586           ("https://www.youtube.com/feeds/videos.xml?channel_id=UCqNpjt_UcMPgm_9gphZgHYA" youtube)
    587           ("https://www.youtube.com/feeds/videos.xml?channel_id=UCk9RA3G-aVQXvp7-Q4Ac9kQ" youtube)
    588 
    589           ("https://suckless.org/atom.xml" suckless news)
    590           ("https://www.gentoo.org/feeds/news.xml" gentoo news)
    591           ("https://voidlinux.org/atom.xml" void news)
    592           )
    593         ))
    594 
    595 (defun send-cmd-to-geiser-repl (cmd)
    596   "Sends a cmd to the current geiser repl"
    597   (geiser-repl--switch-to-repl)
    598   (geiser-repl--send cmd))
    599 
    600 (defun geiser-load-current-buffer-in-repl ()
    601   "Loads current buffer into the current geiser repl"
    602   (interactive)
    603   (send-cmd-to-geiser-repl (concat ",load " (buffer-file-name))))
    604 
    605 ;; Startup time
    606 ;; (defun efs/display-startup-time ()
    607 ;;   (message
    608 ;;    "Emacs loaded in %s with %d garbage collections."
    609 ;;    (format
    610 ;;  "%.2f seconds"
    611 ;;  (float-time
    612 ;;   (time-subtract after-init-time before-init-time)))
    613 ;;    gcs-done))
    614 ;; (add-hook 'emacs-startup-hook #'efs/display-startup-time)