1031 lines
32 KiB
EmacsLisp
1031 lines
32 KiB
EmacsLisp
;;; EMACS init file -*- lexical-binding:t -*-
|
|
|
|
(eval-and-compile
|
|
(defconst my-is-nixos (file-exists-p "/nix")
|
|
"Whether or not Emacs is running on NixOS."))
|
|
|
|
(when my-is-nixos
|
|
(setq auth-sources '("/run/agenix/authinfo")))
|
|
|
|
(require 'cl-lib)
|
|
|
|
(with-eval-after-load 'package
|
|
(add-to-list 'package-archives
|
|
'("melpa" . "https://melpa.org/packages/"))
|
|
(package-initialize))
|
|
|
|
(setq use-package-always-ensure (not my-is-nixos)
|
|
use-package-always-defer t
|
|
use-package-expand-minimally t)
|
|
(require 'use-package)
|
|
|
|
(let ((emacs-tmp-dir (expand-file-name (format "emacs%d" (user-uid))
|
|
temporary-file-directory)))
|
|
(setq auto-save-file-name-transforms `((".*" ,emacs-tmp-dir t))
|
|
auto-save-list-file-prefix emacs-tmp-dir
|
|
backup-directory-alist (setq undo-tree-history-directory-alist
|
|
`((".*" . ,emacs-tmp-dir)))
|
|
org-preview-latex-image-directory (expand-file-name "ltximg" emacs-tmp-dir)))
|
|
|
|
(setq backup-by-copying t
|
|
inhibit-splash-screen t
|
|
custom-file (expand-file-name "custom.el" temporary-file-directory))
|
|
|
|
(defun my-inhibit-hl-line-mode ()
|
|
"Disable `gobal-hl-line-mode' for the current buffer."
|
|
(setq-local global-hl-line-mode nil))
|
|
|
|
(use-package f
|
|
:demand t)
|
|
|
|
(use-package dash
|
|
:demand t
|
|
:hook (emacs-lisp-mode . dash-fontify-mode)
|
|
:init
|
|
(with-eval-after-load 'info-look
|
|
(dash-register-info-lookup)))
|
|
|
|
(use-package undo-fu
|
|
:demand t
|
|
:config
|
|
(global-unset-key (kbd "C-/"))
|
|
(global-unset-key (kbd "C-?"))
|
|
(global-set-key (kbd "C-/") #'undo-fu-only-undo)
|
|
(global-set-key (kbd "C-?") #'undo-fu-only-redo))
|
|
|
|
(use-package vundo)
|
|
|
|
(use-package god-mode
|
|
:demand t
|
|
:bind
|
|
("<escape>" . god-mode-all)
|
|
("ESC ESC ESC" . god-mode-all)
|
|
("C-S-h" . help-command)
|
|
("C-h" . my--god-del)
|
|
(:map god-local-mode-map
|
|
("i" . god-mode-all)
|
|
("<escape>" . my--god-c-g)
|
|
("ESC ESC ESC" . keyboard-escape-quit)
|
|
("z" . repeat)
|
|
("q" . my--god-c-q))
|
|
(:map minibuffer-local-map
|
|
("<escape>" . abort-minibuffers)
|
|
("ESC ESC ESC" . keyboard-escape-quit))
|
|
:custom
|
|
(god-exempt-major-modes nil)
|
|
(god-exempt-predicates (list #'god-exempt-mode-p))
|
|
(god-mode-enable-function-key-translations nil)
|
|
(god-mode-alist '((nil . "C-")
|
|
("g" . "M-")
|
|
("m" . "C-M-")))
|
|
:config
|
|
(defun my--god-c-q ()
|
|
(interactive)
|
|
(let ((god-local-mode nil))
|
|
(if-let* ((buffer-read-only)
|
|
(ret (key-binding (read-kbd-macro "q")))
|
|
((not (or (eq ret #'self-insert-command) (and (boundp lispy-mode) lispy-mode)))))
|
|
(call-interactively ret)
|
|
(switch-to-prev-buffer))))
|
|
(cl-macrolet ((define-kmacro-wrapper (name key)
|
|
`(defun ,name ()
|
|
(interactive)
|
|
(call-interactively (key-binding (read-kbd-macro ,key))))))
|
|
(define-kmacro-wrapper my--god-del "DEL")
|
|
(define-kmacro-wrapper my--god-c-g "C-g"))
|
|
(with-eval-after-load 'catppuccin-theme
|
|
(add-hook 'god-mode-enabled-hook
|
|
(lambda ()
|
|
(face-spec-set 'cursor `((t (:background ,(catppuccin-get-color 'rosewater)))))
|
|
(unless (display-graphic-p)
|
|
(send-string-to-terminal "\e[2 q"))))
|
|
(add-hook 'god-mode-disabled-hook
|
|
(lambda ()
|
|
(face-spec-set 'cursor `((t (:background ,(catppuccin-get-color 'mauve)))))
|
|
(unless (display-graphic-p)
|
|
;; Escape codes for hbar cursor in insert mode
|
|
(send-string-to-terminal "\e[4 q")))))
|
|
(god-mode))
|
|
|
|
(use-package multiple-cursors
|
|
:bind
|
|
("C-S-c" . mc/edit-lines)
|
|
("C->" . mc/mark-next-like-this)
|
|
("C-<" . mc/mark-previous-like-this)
|
|
("C-+" . mc/mark-all-like-this)
|
|
("C-|" . mc/mark-pop)
|
|
("C-c c" . mc/mark-all-in-region)
|
|
("C-c C" . mc/mark-all-in-region-regexp)
|
|
("C-c u" . mc/mark-all-like-this-dwim)
|
|
("C-c U" . mc/mark-all-dwim)
|
|
("C-S-<mouse-1>" . mc/add-cursor-on-click)
|
|
:custom
|
|
(mc/always-run-for-all t)
|
|
:init
|
|
;; NOTE: For SOME REASON lispy also defvars the mc cmds list to nil when
|
|
;; sourced so they need to be modified twice
|
|
(let ((add-cmds (lambda ()
|
|
(dolist (f '(god-local-mode
|
|
god-mode-all
|
|
god-global-mode))
|
|
(add-to-list 'mc/cmds-to-run-once f)))))
|
|
;; Because multiple-cursors-core is what actually gets autoloaded
|
|
(eval-after-load 'multiple-cursors-core add-cmds)
|
|
(eval-after-load 'lispy add-cmds)))
|
|
|
|
(use-package expand-region
|
|
:bind ("C-=" . er/expand-region))
|
|
|
|
(use-package avy
|
|
:bind
|
|
("C-'" . avy-goto-char)
|
|
("C-," . avy-goto-char-2)
|
|
("C-\"" . avy-goto-char-timer)
|
|
("M-g f" . avy-goto-line)
|
|
("M-g w" . avy-goto-word-1)
|
|
("M-g e" . avy-goto-word-0)
|
|
:custom
|
|
(avy-timeout-seconds 0.3))
|
|
|
|
(use-package lispy
|
|
:hook
|
|
emacs-lisp-mode
|
|
ielm-mode
|
|
lisp-mode
|
|
scheme-mode
|
|
clojure-mode
|
|
:config
|
|
(add-to-list 'lispy-compat 'god-mode)
|
|
(add-to-list 'lispy-compat 'magit-blame-mode)
|
|
(when (boundp 'god-local-mode-map)
|
|
(push (assoc 'god-local-mode minor-mode-map-alist) minor-mode-map-alist)))
|
|
|
|
(use-package ace-window
|
|
:bind ("C-c w" . ace-window)
|
|
:custom
|
|
(aw-dispatch-always t)
|
|
(aw-scope 'frame)
|
|
(aw-keys '(?a ?w ?d ?f ?g ?h ?k ?l))
|
|
:config
|
|
(with-eval-after-load 'catppuccin-theme
|
|
(face-spec-set 'aw-leading-char-face `((t (:foreground
|
|
,(catppuccin-get-color 'crust)
|
|
:background
|
|
,(catppuccin-get-color 'red)
|
|
:weight bold))))
|
|
(face-spec-set 'aw-background-face `((t (:foreground
|
|
,(catppuccin-get-color 'overlay1)))))))
|
|
|
|
(use-package goggles
|
|
:hook prog-mode
|
|
:config
|
|
(setq-default goggles-pulse t)
|
|
(with-eval-after-load 'catppuccin-theme
|
|
(let ((new-spec `((t (:background ,(catppuccin-get-color 'surface1))))))
|
|
(dolist (f '(goggles-added
|
|
goggles-removed
|
|
goggles-changed))
|
|
(face-spec-set f new-spec))))
|
|
(setcar (cdr (assq 'goggles-mode minor-mode-alist)) " O-O"))
|
|
|
|
(defun my--set-tab-width-2 ()
|
|
(setq tab-width 2))
|
|
|
|
(use-package treesit
|
|
:ensure nil
|
|
:mode
|
|
("\\.ts\\'" . typescript-ts-mode)
|
|
("\\.tsx\\'" . tsx-ts-mode)
|
|
("\\.rs\\'" . rust-ts-mode)
|
|
("\\.ya?ml\\'" . yaml-ts-mode)
|
|
("/Dockerfile\\'" . dockerfile-ts-mode)
|
|
("\\(/CMakeLists.txt\\|\\.cmake\\)\\'" . cmake-ts-mode)
|
|
:hook
|
|
(typescript-ts-mode . my--set-tab-width-2)
|
|
(tsx-ts-mode . my--set-tab-width-2)
|
|
:init
|
|
(add-to-list 'major-mode-remap-alist '(sh-mode . bash-ts-mode))
|
|
(add-to-list 'major-mode-remap-alist '(css-mode . css-ts-mode))
|
|
(add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode))
|
|
(add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode))
|
|
(add-to-list 'major-mode-remap-alist '(csharp-mode . csharp-ts-mode))
|
|
(add-to-list 'major-mode-remap-alist '(java-mode . java-ts-mode))
|
|
(add-to-list 'major-mode-remap-alist '(python-mode . python-ts-mode))
|
|
(add-to-list 'major-mode-remap-alist '(ruby-mode . ruby-ts-mode))
|
|
(add-to-list 'major-mode-remap-alist '(html-mode . html-ts-mode))
|
|
(add-to-list 'major-mode-remap-alist '(js-mode . js-ts-mode))
|
|
(add-to-list 'major-mode-remap-alist '(js-json-mode . json-ts-mode))
|
|
(add-to-list 'major-mode-remap-alist '(conf-toml-mode . toml-ts-mode))
|
|
:config
|
|
(unless my-is-nixos
|
|
(add-to-list 'treesit-extra-load-path (expand-file-name "tree-sitter-module/dist/"
|
|
user-emacs-directory))))
|
|
|
|
(use-package dtrt-indent
|
|
:demand t
|
|
:config
|
|
(setcar (cdr (assq 'dtrt-indent-mode minor-mode-alist)) " dtrt")
|
|
(dtrt-indent-global-mode))
|
|
|
|
(use-package aggressive-indent
|
|
:custom
|
|
(aggressive-indent-sit-for-time 0.1)
|
|
:hook
|
|
emacs-lisp-mode
|
|
ielm-mode
|
|
lisp-mode
|
|
scheme-mode
|
|
clojure-mode
|
|
nix-mode)
|
|
|
|
(use-package rainbow-delimiters
|
|
:hook prog-mode sly-mrepl-mode racket-repl-mode)
|
|
|
|
(use-package highlight-indent-guides
|
|
:hook (prog-mode . my-maybe-highlight-indent-guides)
|
|
:custom
|
|
(highlight-indent-guides-auto-enabled nil)
|
|
(highlight-indent-guides-method 'character)
|
|
:config
|
|
(defun my-maybe-highlight-indent-guides ()
|
|
(interactive)
|
|
(unless (> (count-lines (point-min) (point-max)) 10000)
|
|
(highlight-indent-guides-mode))))
|
|
|
|
(use-package which-key
|
|
:demand t
|
|
:custom
|
|
(which-key-idle-delay 0.2)
|
|
:config
|
|
(with-eval-after-load 'god-mode
|
|
(which-key-enable-god-mode-support))
|
|
(which-key-mode))
|
|
|
|
(use-package flymake
|
|
:ensure nil
|
|
:bind (:map flymake-mode-map
|
|
("M-n" . flymake-goto-next-error)
|
|
("M-p" . flymake-goto-prev-error)))
|
|
|
|
(use-package eglot
|
|
:ensure nil
|
|
:bind (:map eglot-mode-map
|
|
("C-c e c" . eglot-code-actions)
|
|
("C-c e r" . eglot-rename)
|
|
("C-c e f" . eglot-format)
|
|
("C-c e s" . eglot-shutdown)
|
|
("C-c e S" . eglot-shutdown-all)
|
|
("C-c e R" . eglot-reconnect))
|
|
:hook
|
|
(c-mode . eglot-ensure)
|
|
(c-ts-mode . eglot-ensure)
|
|
(c++-mode . eglot-ensure)
|
|
(c++-ts-mode . eglot-ensure)
|
|
(haskell-mode . eglot-ensure)
|
|
(java-mode . eglot-ensure)
|
|
(java-ts-mode . eglot-ensure)
|
|
(js-mode . eglot-ensure)
|
|
(js-ts-mode . eglot-ensure)
|
|
(lua-mode . eglot-ensure)
|
|
(nix-mode . eglot-ensure)
|
|
(python-mode . eglot-ensure)
|
|
(python-ts-mode . eglot-ensure)
|
|
(rust-ts-mode . eglot-ensure)
|
|
(typescript-ts-mode . eglot-ensure)
|
|
(tsx-ts-mode . eglot-ensure)
|
|
:custom
|
|
(eglot-autoshutdown t)
|
|
:config
|
|
(setq-default eglot-workspace-configuration
|
|
'((haskell
|
|
(formattingProvider . "floskell")))))
|
|
|
|
(use-package eglot-booster
|
|
:ensure nil
|
|
:after eglot
|
|
:demand t
|
|
:custom
|
|
(eglot-booster-no-remote-boost t)
|
|
:config
|
|
(eglot-booster-mode))
|
|
|
|
(use-package eglot-java
|
|
:hook java-mode java-ts-mode)
|
|
|
|
(use-package yasnippet
|
|
:config
|
|
(advice-add #'yas-expand-snippet
|
|
:around
|
|
(lambda (oldfun &rest r)
|
|
(let ((org-src-tab-acts-natively nil))
|
|
(apply oldfun r)))
|
|
'((name . my--yas-expand-disable-org-tab-native)))
|
|
(yas-global-mode))
|
|
|
|
(use-package yasnippet-snippets)
|
|
|
|
(use-package consult
|
|
:bind
|
|
("M-s r" . consult-ripgrep)
|
|
("M-s d" . consult-find)
|
|
("C-x M-:" . consult-complex-command)
|
|
("C-x b" . consult-buffer)
|
|
("C-x r b" . consult-bookmark))
|
|
|
|
(use-package consult-yasnippet
|
|
:bind
|
|
("C-c s" . consult-yasnippet)
|
|
("C-c S" . consult-yasnippet-visit-snippet-file))
|
|
|
|
(use-package embark
|
|
:bind
|
|
("C-." . embark-act)
|
|
("C-;" . embark-dwim))
|
|
|
|
(use-package embark-consult)
|
|
|
|
(use-package orderless
|
|
:demand t
|
|
:custom
|
|
(completion-styles '(orderless basic))
|
|
(completion-category-defaults nil)
|
|
(completion-category-overrides '((file (styles basic partial-completion)))))
|
|
|
|
(use-package marginalia
|
|
:demand t
|
|
:bind (:map minibuffer-local-map ("M-a" . marginalia-cycle))
|
|
:config
|
|
(marginalia-mode))
|
|
|
|
(use-package vertico
|
|
:demand t
|
|
:config
|
|
(vertico-mode)
|
|
(vertico-mouse-mode))
|
|
|
|
(use-package corfu
|
|
:demand t
|
|
:custom
|
|
(corfu-auto t)
|
|
(corfu-cycle t)
|
|
(corfu-preselect-first nil)
|
|
(corfu-scroll-margin 3)
|
|
(tab-always-indent 'complete)
|
|
:config
|
|
(add-hook 'minibuffer-setup-hook
|
|
(lambda ()
|
|
(when (where-is-internal #'completion-at-point
|
|
(list (current-local-map)))
|
|
(setq-local corfu-echo-display nil
|
|
corfu-popupinfo-delay nil)
|
|
(corfu-mode))))
|
|
(global-corfu-mode))
|
|
|
|
(use-package cape)
|
|
|
|
(use-package all-the-icons)
|
|
(use-package all-the-icons-completion
|
|
:demand t
|
|
:hook (marginalia-mode . all-the-icons-completion-marginalia-setup)
|
|
:config
|
|
(require 'marginalia)
|
|
;; NOTE: https://github.com/iyefrat/all-the-icons-completion/pull/33
|
|
(add-hook 'all-the-icons-completion-mode-hook
|
|
(lambda ()
|
|
(if all-the-icons-completion-mode
|
|
(advice-add (compat-function completion-metadata-get)
|
|
:around
|
|
#'all-the-icons-completion-completion-metadata-get)
|
|
(advice-remove (compat-function completion-metadata-get)
|
|
#'all-the-icons-completion-completion-metadata-get))))
|
|
(all-the-icons-completion-mode))
|
|
|
|
(use-package treemacs)
|
|
(use-package treemacs-all-the-icons
|
|
:after treemacs
|
|
:demand t
|
|
:config
|
|
(treemacs-load-theme 'all-the-icons))
|
|
|
|
(use-package doom-modeline
|
|
:demand t
|
|
:custom
|
|
(doom-modeline-continuous-word-count-modes '(markdown-mode gfm-mode org-mode))
|
|
(doom-modeline-enable-word-count t)
|
|
(doom-modeline-indent-info t)
|
|
(doom-modeline-minor-modes t)
|
|
(doom-modeline-battery nil)
|
|
:config
|
|
(doom-modeline-mode))
|
|
|
|
(use-package minions
|
|
:demand t
|
|
:config
|
|
(minions-mode))
|
|
|
|
(use-package dirvish
|
|
:after dired
|
|
:demand t
|
|
:custom
|
|
(dired-auto-revert-buffer t)
|
|
(dirvish-attributes '(all-the-icons))
|
|
:config
|
|
(dirvish-override-dired-mode))
|
|
|
|
(use-package persp-mode
|
|
:if nil
|
|
:bind ("C-c p" . persp-key-map)
|
|
:custom
|
|
(persp-keymap-prefix nil)
|
|
:init
|
|
(when (daemonp)
|
|
(require 'persp-mode))
|
|
:config
|
|
(with-eval-after-load 'consult
|
|
(consult-customize consult--source-buffer :hidden t :default nil)
|
|
(add-to-list 'consult-buffer-sources
|
|
(list :name "Perspective"
|
|
:narrow ?s
|
|
:category 'buffer
|
|
:state #'consult--buffer-state
|
|
:history 'buffer-name-history
|
|
:default t
|
|
:items (lambda ()
|
|
(consult--buffer-query :sort 'visibility
|
|
:predicate (lambda (buf)
|
|
(memq buf (persp-buffer-list)))
|
|
:as #'buffer-name)))))
|
|
(persp-mode))
|
|
|
|
(use-package alert
|
|
:ensure nil
|
|
:custom
|
|
(alert-default-style 'libnotify)
|
|
(alert-libnotify-command (expand-file-name "scripts/emacs-hyprland-notify"
|
|
user-emacs-directory)))
|
|
|
|
(use-package pdf-tools
|
|
:mode ("\\.pdf\\'" . pdf-view-mode)
|
|
:bind (:map pdf-view-mode-map ("/" . #'isearch-forward))
|
|
:config
|
|
(pdf-tools-install))
|
|
|
|
(defun my-double-space-sentence ()
|
|
(setq-local sentence-end-double-space t))
|
|
|
|
(use-package engrave-faces)
|
|
|
|
(use-package org
|
|
:hook
|
|
(org-mode . auto-fill-mode)
|
|
(org-mode . my-inhibit-hl-line-mode)
|
|
(org-mode . my-double-space-sentence)
|
|
:custom
|
|
(org-startup-with-inline-images t)
|
|
(org-special-ctrl-a/e t)
|
|
(org-insert-heading-respect-content t)
|
|
(org-list-allow-alphabetical t)
|
|
(org-hide-emphasis-markers t)
|
|
(org-pretty-entities t)
|
|
(org-babel-load-languages '((emacs-lisp . t)
|
|
(ruby . t)
|
|
(python . t)
|
|
(shell . t)
|
|
(C . t)))
|
|
(org-agenda-files '("~/Agenda"))
|
|
;; NixOS minimal LaTeX setup
|
|
(org-latex-compiler "lualatex")
|
|
(org-preview-latex-default-process 'dvisvgm)
|
|
(org-latex-src-block-backend 'engraved)
|
|
:config
|
|
(setq org-format-latex-options (plist-put org-format-latex-options :scale 1.1)
|
|
org-modules (append '(org-tempo org-habit) org-modules))
|
|
(with-eval-after-load 'catppuccin-theme
|
|
(face-spec-set 'org-block `((t (:foreground ,(catppuccin-get-color 'text)))))))
|
|
|
|
(use-package org-alert
|
|
:init
|
|
(when (daemonp)
|
|
(run-with-idle-timer 10 nil #'require 'org-alert))
|
|
:config
|
|
(setq org-alert-notification-title "org-alert"
|
|
org-alert-notify-cutoff 30)
|
|
(org-alert-enable))
|
|
|
|
(use-package org-modern
|
|
:hook
|
|
org-mode
|
|
(org-agenda-finalize . org-modern-agenda)
|
|
:config
|
|
(with-eval-after-load 'catppuccin-theme
|
|
(face-spec-set 'org-modern-done `((t (:foreground
|
|
,(catppuccin-get-color 'text)
|
|
:background
|
|
,(catppuccin-get-color 'surface0)))))
|
|
(face-spec-set 'org-modern-date-inactive `((t (:foreground
|
|
,(catppuccin-get-color 'subtext0)
|
|
:background
|
|
,(catppuccin-get-color 'surface0)))))
|
|
(face-spec-set 'org-modern-horizontal-rule `((t (:strike-through
|
|
,(catppuccin-get-color 'overlay1)))))
|
|
(face-spec-set 'org-modern-tag `((t (:foreground
|
|
,(catppuccin-get-color 'base)
|
|
:background
|
|
,(catppuccin-get-color 'sapphire)))))
|
|
(face-spec-set 'org-modern-time-active `((t (:foreground
|
|
,(catppuccin-get-color 'base)
|
|
:background
|
|
,(catppuccin-get-color 'overlay2)))))
|
|
(face-spec-set 'org-modern-time-inactive `((t (:foreground
|
|
,(catppuccin-get-color 'base)
|
|
:background
|
|
,(catppuccin-get-color 'surface0)))))))
|
|
|
|
(use-package org-modern-indent
|
|
:ensure nil
|
|
:hook org-modern-mode)
|
|
|
|
(use-package djvu)
|
|
|
|
(use-package nov
|
|
:mode ("\\.epub\\'" . nov-mode))
|
|
|
|
(use-package org-pdftools
|
|
:hook (org-mode . org-pdftools-setup-link))
|
|
|
|
(use-package editorconfig
|
|
:demand t
|
|
:config
|
|
(editorconfig-mode)
|
|
(setcar (cdr (assq 'editorconfig-mode minor-mode-alist)) " EdConf"))
|
|
|
|
(use-package envrc
|
|
:bind ("C-c v" . envrc-command-map)
|
|
:hook (after-init . envrc-global-mode))
|
|
|
|
(use-package sly
|
|
:custom
|
|
(sly-symbol-completion-mode nil)
|
|
:config
|
|
(setq inferior-lisp-program "sbcl")
|
|
(defun my--sly-add-project-root-to-asdf (old-init)
|
|
(let ((dir (if-let* ((proj (project-current))
|
|
(root (project-root proj)))
|
|
root
|
|
default-directory)))
|
|
(if (directory-files dir nil "\\.asd\\'" t 1)
|
|
(let ((old-init-list (read old-init)))
|
|
(setf (cddadr old-init-list)
|
|
(cons `(push (pathname ,(sly-to-lisp-filename dir))
|
|
(symbol-value
|
|
(read-from-string "asdf:*central-registry*")))
|
|
(cddadr old-init-list)))
|
|
(format "%S\n\n" old-init-list))
|
|
old-init)))
|
|
(advice-add #'sly-init-using-asdf :filter-return #'my--sly-add-project-root-to-asdf)
|
|
(sly-setup))
|
|
|
|
(use-package sly-asdf)
|
|
(use-package sly-named-readtables)
|
|
|
|
(use-package racket-mode
|
|
:hook (racket-mode . racket-xp-mode))
|
|
|
|
(use-package haskell-mode
|
|
:hook (haskell-mode . interactive-haskell-mode)
|
|
:custom
|
|
(haskell-process-show-debug-tips nil))
|
|
|
|
(use-package lua-mode
|
|
:custom
|
|
(lua-indent-level 4)
|
|
(lua-indent-nested-block-content-align nil)
|
|
(lua-indent-close-paren-align nil))
|
|
|
|
(use-package nix-mode)
|
|
|
|
(use-package markdown-mode
|
|
:mode ("README\\.md\\'" . gfm-mode)
|
|
:custom
|
|
(markdown-command '("pandoc" "--from=markdown" "--to=html5")))
|
|
|
|
(use-package csv-mode)
|
|
|
|
(use-package meson-mode)
|
|
|
|
(use-package jinx
|
|
:hook text-mode)
|
|
|
|
(use-package minimap
|
|
:custom-face
|
|
(minimap-active-region-background ((t (:background unspecified :inherit hl-line))))
|
|
:hook (minimap-sb-mode . turn-on-solaire-mode))
|
|
|
|
(use-package magit
|
|
:hook (git-commit-setup . git-commit-turn-on-auto-fill))
|
|
|
|
(use-package forge
|
|
:after magit
|
|
:demand t)
|
|
|
|
(use-package tramp
|
|
:custom
|
|
(remote-file-name-inhibit-cache nil)
|
|
(tramp-verbose 1)
|
|
:config
|
|
(setq vc-ignore-dir-regexp (format "%s\\|%s"
|
|
vc-ignore-dir-regexp
|
|
tramp-file-name-regexp)))
|
|
|
|
(use-package eat
|
|
:bind
|
|
("C-c t" . eat)
|
|
(:map eat-mode-map
|
|
("<escape>" . eat-self-input))
|
|
:hook (eat-mode . my-inhibit-hl-line-mode)
|
|
:config
|
|
(with-eval-after-load 'god-mode
|
|
(add-to-list 'god-exempt-major-modes 'eat-mode)))
|
|
|
|
(use-package circe
|
|
:hook (circe-channel-mode . enable-lui-autopaste)
|
|
:custom
|
|
(circe-default-nick "eriedaberrie")
|
|
(circe-default-user "eriedaberrie")
|
|
(circe-default-realname "eriedaberrie")
|
|
(circe-format-self-say ">>> {body}")
|
|
(lui-time-stamp-position 'right-margin)
|
|
(lui-fill-type nil)
|
|
(lui-time-stamp-format "%T")
|
|
:config
|
|
(--when-let (nth 0 (auth-source-search :max 1
|
|
:require '(:user :secret)
|
|
:host "irc.libera.chat"
|
|
:port 6697))
|
|
(let ((user (plist-get it :user))
|
|
(secret (plist-get it :secret)))
|
|
(setq circe-network-options
|
|
`(("Libera Chat"
|
|
:tls t
|
|
:nick ,user
|
|
:sasl-username ,user
|
|
:sasl-password ,(if (functionp secret)
|
|
(funcall secret)
|
|
secret)
|
|
:channels ("#emacs" "#nixos" "#lisp" "#commonlisp"))))))
|
|
(add-hook 'lui-mode-hook
|
|
(lambda ()
|
|
(visual-line-mode)
|
|
(setq-local fringes-outside-margins t
|
|
right-margin-width 8
|
|
wrap-prefix " ")
|
|
(setcdr (assoc 'continuation fringe-indicator-alist) nil))))
|
|
|
|
(use-package circe-notifications
|
|
:hook (circe-server-connected . enable-circe-notifications))
|
|
|
|
(use-package mpv)
|
|
(use-package lingva
|
|
:custom
|
|
(lingva-instance "lingva.garudalinux.org"))
|
|
|
|
(use-package mastodon
|
|
:custom
|
|
(mastodon-instance-url "https://fosstodon.org")
|
|
(mastodon-active-user "eriedaberrie")
|
|
(mastodon-toot-timestamp-format "%F %-I:%M %p"))
|
|
|
|
(use-package elfeed
|
|
:custom
|
|
(elfeed-feeds '(("https://archlinux.org/feeds/news/" arch-linux)
|
|
("https://nixos.org/blog/announcements-rss.xml" nixos))))
|
|
|
|
(use-package xkcd)
|
|
|
|
(use-package page-break-lines
|
|
:hook
|
|
emacs-lisp-mode
|
|
lisp-mode
|
|
scheme-mode
|
|
compilation-mode
|
|
outline-mode
|
|
help-mode)
|
|
|
|
(use-package hl-todo
|
|
:hook prog-mode)
|
|
|
|
(use-package gruvbox-theme)
|
|
(use-package catppuccin-theme
|
|
:demand t
|
|
:custom-face
|
|
(line-number-current-line ((t (:inherit (hl-line default)))))
|
|
:custom
|
|
(catppuccin-flavor 'mocha)
|
|
(catppuccin-highlight-matches t)
|
|
(catppuccin-italic-comments t)
|
|
(catppuccin-italic-blockquotes t)
|
|
(catppuccin-italic-variables t))
|
|
|
|
(defun my-load-theme-with-solaire ()
|
|
(load-theme 'catppuccin t)
|
|
(catppuccin-reload)
|
|
(face-spec-set 'font-lock-variable-name-face `((t (:foreground
|
|
,(catppuccin-get-color 'flamingo)))))
|
|
(solaire-global-mode)
|
|
(when (daemonp)
|
|
(remove-hook 'server-after-make-frame-hook #'my-load-theme-with-solaire)))
|
|
|
|
(use-package solaire-mode
|
|
:demand t
|
|
:custom
|
|
(solaire-mode-real-buffer-fn (lambda ()
|
|
(and (solaire-mode-real-buffer-p)
|
|
(or (custom-theme-enabled-p 'gruvbox)
|
|
(not (memq 'minimap-sb-mode
|
|
local-minor-modes))))))
|
|
:config
|
|
(if (daemonp)
|
|
(add-hook 'server-after-make-frame-hook #'my-load-theme-with-solaire)
|
|
(my-load-theme-with-solaire)))
|
|
|
|
(use-package with-editor
|
|
:bind
|
|
([remap async-shell-command] . with-editor-async-shell-command)
|
|
([remap shell-command] . with-editor-shell-command)
|
|
:hook
|
|
(shell-mode . with-editor-export-editor)
|
|
(eshell-mode . with-editor-export-editor)
|
|
(term-exec . with-editor-export-editor))
|
|
|
|
(use-package nyan-mode
|
|
:custom
|
|
(nyan-animate-nyancat t)
|
|
(nyan-wavy-trail t))
|
|
|
|
(use-package smtpmail
|
|
:ensure nil
|
|
:custom
|
|
(smtpmail-smtp-service 587)
|
|
(smtpmail-stream-type 'starttls)
|
|
(smtpmail-default-smtp-server "smtp.gmail.com")
|
|
(message-send-mail-function #'smtpmail-send-it)
|
|
(message-citation-line-function #'message-insert-formatted-citation-line)
|
|
(message-kill-buffer-on-exit t))
|
|
|
|
(use-package mu4e
|
|
:if my-is-nixos
|
|
:ensure nil
|
|
:bind
|
|
("C-c m m" . mu4e)
|
|
("C-c m c" . mu4e-compose-new)
|
|
("C-c m u" . mu4e-update-mail-and-index)
|
|
:hook
|
|
(mu4e-view-mode . my-inhibit-hl-line-mode)
|
|
(message-mode . my-double-space-sentence)
|
|
:custom
|
|
(mail-user-agent 'mu4e-user-agent)
|
|
(mu4e-get-mail-command "mbsync -a")
|
|
(mu4e-sent-messages-behavior 'delete)
|
|
(mu4e-change-filenames-when-moving t)
|
|
(mu4e-view-show-images t)
|
|
(mu4e-use-fancy-chars t)
|
|
(mu4e-attachment-dir "~/Downloads")
|
|
(mu4e-context-policy 'ask)
|
|
(mu4e-compose-context-policy 'ask-if-none)
|
|
(mu4e-confirm-quit nil)
|
|
(mu4e-completing-read-function #'completing-read)
|
|
:init
|
|
(let ((age-file "/run/agenix/email.json"))
|
|
(when (file-exists-p age-file)
|
|
(defvar my--agenix-email-json-data
|
|
(with-temp-buffer
|
|
(insert-file-contents age-file)
|
|
(json-parse-buffer :object-type 'alist)))
|
|
(pcase-let ((`((address . ,address) (name . ,name) ,_)
|
|
(alist-get 'personal my--agenix-email-json-data)))
|
|
(setq user-mail-address address
|
|
user-full-name name))))
|
|
:config
|
|
(when (boundp 'my--agenix-email-json-data)
|
|
(setq mu4e-contexts
|
|
(--map (pcase-let ((`(,type (address . ,address) (name . ,name) ,_) it))
|
|
(make-mu4e-context
|
|
:name (symbol-name type)
|
|
:enter-func (lambda ()
|
|
(mu4e-message (format "Entering \"%s\" context"
|
|
type)))
|
|
:leave-func (lambda ()
|
|
(mu4e-message (format "Leaving \"%s\" context"
|
|
type)))
|
|
:match-func (lambda (msg)
|
|
(when msg
|
|
(mu4e-message-contact-field-matches
|
|
msg
|
|
:to address)))
|
|
:vars (cl-labels ((folder-name (folder-type)
|
|
(format "/%s/[Gmail]/%s" type folder-type)))
|
|
`((user-mail-address . ,address)
|
|
(user-full-name . ,name)
|
|
(mu4e-drafts-folder . ,(folder-name "Drafts"))
|
|
(mu4e-sent-folder . ,(folder-name "Sent Mail"))
|
|
(mu4e-trash-folder . ,(folder-name "Trash"))
|
|
(smtpmail-smtp-server . "smtp.gmail.com")
|
|
(smtpmail-smtp-user . ,address)))))
|
|
my--agenix-email-json-data)))
|
|
(when (fboundp 'imagemagick-register-types)
|
|
(imagemagick-register-types)))
|
|
|
|
(use-package org-msg
|
|
:after message
|
|
:demand t
|
|
:custom
|
|
(org-msg-convert-citation t)
|
|
(org-msg-greeting-fmt "\nHi%s,\n\n"))
|
|
|
|
(use-package emacs-everywhere
|
|
:custom
|
|
(emacs-everywhere-app-info-function
|
|
(lambda ()
|
|
(let* ((string-data (emacs-everywhere-call "hyprctl" "-j" "activewindow"))
|
|
(window-data (json-parse-string string-data
|
|
:object-type 'plist
|
|
:array-type 'list
|
|
:null-object nil
|
|
:false-object nil))
|
|
(window-id (plist-get window-data :address))
|
|
(app-id (plist-get window-data :class))
|
|
(window-title (plist-get window-data :title))
|
|
(window-geometry (append (plist-get window-data :at)
|
|
(plist-get window-data :size))))
|
|
(make-emacs-everywhere-app
|
|
:id window-id
|
|
:class app-id
|
|
:title window-title
|
|
:geometry window-geometry))))
|
|
(emacs-everywhere-window-focus-command '("hyprctl" "dispatch" "focuswindow" "address:%w"))
|
|
:config
|
|
(dolist (f '((alpha-background . 1.0) (width . 120) (height . 20)))
|
|
(add-to-list 'emacs-everywhere-frame-parameters f)))
|
|
|
|
(use-package prettify-symbols
|
|
:ensure nil
|
|
:hook prog-mode org-mode
|
|
:custom
|
|
(prettify-symbols-unprettify-at-point t))
|
|
|
|
(use-package electric-pair-mode
|
|
:ensure nil
|
|
:hook
|
|
(prog-mode . electric-pair-local-mode)
|
|
(eval-expression-minibuffer-setup . electric-pair-local-mode)
|
|
(sly-mrepl-mode . electric-pair-local-mode)
|
|
(racket-repl-mode . electric-pair-local-mode))
|
|
|
|
(use-package ffap
|
|
:ensure nil
|
|
:demand t
|
|
:config
|
|
(ffap-bindings))
|
|
|
|
(use-package eldoc
|
|
:ensure nil
|
|
:custom
|
|
(eldoc-documentation-strategy #'eldoc-documentation-compose-eagerly))
|
|
|
|
(use-package ibuffer
|
|
:ensure nil
|
|
:bind ("C-x C-b" . ibuffer))
|
|
|
|
(use-package info
|
|
:ensure nil
|
|
:hook (Info-mode . my-inhibit-hl-line-mode))
|
|
|
|
(use-package tool-bar
|
|
:ensure nil
|
|
:config
|
|
(tool-bar-mode 0))
|
|
(use-package menu-bar
|
|
:ensure nil
|
|
:config
|
|
(menu-bar-mode 0))
|
|
(use-package scroll-bar
|
|
:ensure nil
|
|
:config
|
|
(scroll-bar-mode 0))
|
|
|
|
(setq pixel-scroll-precision-large-scroll-height 40
|
|
fast-but-imprecise-scrolling t)
|
|
(pixel-scroll-precision-mode)
|
|
|
|
(setcar mouse-wheel-scroll-amount 3)
|
|
|
|
(setq server-client-instructions nil
|
|
scroll-step 1
|
|
scroll-margin 8
|
|
scroll-conservatively 9999
|
|
python-indent-guess-indent-offset nil
|
|
read-file-name-completion-ignore-case t
|
|
read-buffer-completion-ignore-case t
|
|
completion-ignore-case t
|
|
sentence-end-double-space nil
|
|
custom-safe-themes t
|
|
x-stretch-cursor t)
|
|
|
|
(setq-default c-basic-offset 4
|
|
c-ts-mode-indent-offset 4
|
|
json-ts-mode-indent-offset 4
|
|
sgml-basic-offset 4
|
|
tab-width 4
|
|
fill-column 78)
|
|
;; Because python-mode sets tab-width to 8 for some reason
|
|
(add-hook 'python-mode-hook (lambda () (setq tab-width 4)))
|
|
|
|
(column-number-mode)
|
|
(size-indication-mode)
|
|
|
|
(global-hl-line-mode)
|
|
|
|
(defun my-relative-linenum (&optional toggle)
|
|
"Simply enables relative line numbers."
|
|
(interactive "p")
|
|
(setq display-line-numbers (if (and toggle display-line-numbers) nil 'relative)))
|
|
(dolist (hook '(prog-mode-hook
|
|
conf-mode-hook))
|
|
(add-hook hook #'my-relative-linenum))
|
|
|
|
(defun my-use-spaces-for-indent ()
|
|
"Simply turn off `indent-tabs-mode'."
|
|
(setq indent-tabs-mode nil))
|
|
(dolist (hook '(emacs-lisp-mode-hook
|
|
lisp-mode-hook
|
|
scheme-mode-hook
|
|
clojure-mode-hook))
|
|
(add-hook hook #'my-use-spaces-for-indent))
|
|
|
|
(add-hook 'text-mode-hook #'word-wrap-whitespace-mode)
|
|
(add-hook 'text-mode-hook #'visual-line-mode)
|
|
|
|
(defun scroll-down-3 ()
|
|
"Scroll down by 3."
|
|
(interactive)
|
|
(scroll-down 3))
|
|
|
|
(defun scroll-up-3 ()
|
|
"Scroll up by 3."
|
|
(interactive)
|
|
(scroll-up 3))
|
|
|
|
(defun my-frame-make-detect-term (&optional frame)
|
|
"Check when FRAME are made in order to make terminal-only configurations."
|
|
(unless (display-graphic-p frame)
|
|
(xterm-mouse-mode)
|
|
(global-set-key (kbd "<mouse-4>") #'scroll-down-3)
|
|
(global-set-key (kbd "<mouse-5>") #'scroll-up-3)
|
|
(remove-hook 'after-make-frame-functions #'my-frame-make-detect-term)))
|
|
|
|
(if (daemonp)
|
|
(add-to-list 'after-make-frame-functions #'my-frame-make-detect-term)
|
|
(my-frame-make-detect-term))
|
|
|
|
(defun my-sudo-edit ()
|
|
"Edit current file as root."
|
|
(interactive)
|
|
(unless (and buffer-file-name
|
|
(file-writable-p buffer-file-name))
|
|
(find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name))))
|
|
|
|
(setq auto-mode-alist
|
|
(append '(("\\.yuck\\'" . lisp-mode)
|
|
("/flake\\.lock\\'" . js-json-mode))
|
|
auto-mode-alist
|
|
'(("/qutebrowser-editor-" . text-mode))))
|
|
|
|
(when (daemonp)
|
|
(with-current-buffer "*scratch*"
|
|
(cd "~/")))
|
|
|
|
(defvar my-ac-previous-status t
|
|
"Whether connected to AC during last check.")
|
|
|
|
(require 'battery)
|
|
(defun my-bat-check ()
|
|
"Check if battery status has changed.
|
|
Used to toggle `goggles-pulse', `pixel-scroll-precision-mode', and `nyan-mode'."
|
|
(let ((ac-status (not (string=
|
|
(cdr (assq ?B (funcall battery-status-function)))
|
|
"discharging"))))
|
|
(unless (eq ac-status my-ac-previous-status)
|
|
(setq my-ac-previous-status ac-status)
|
|
(when (boundp 'goggles-pulse)
|
|
(setq goggles-pulse ac-status))
|
|
(when nyan-mode
|
|
(if ac-status
|
|
(nyan-start-animation)
|
|
(nyan-stop-animation)))
|
|
(setq nyan-animate-nyancat ac-status
|
|
nyan-wavy-trail ac-status)
|
|
(pixel-scroll-precision-mode (if ac-status 1 0)))))
|
|
|
|
(when battery-status-function
|
|
(run-with-timer 0 30 #'my-bat-check))
|