347 lines
9.2 KiB
EmacsLisp
347 lines
9.2 KiB
EmacsLisp
;; -*- lexical-binding: t; -*-
|
|
|
|
(load-file "~/.config/emacs/init-elpaca.el")
|
|
|
|
(defun git-tracked-file-p (filename)
|
|
"Check whether the file FILENAME is tracked by git."
|
|
(let ((dirname (file-name-parent-directory filename)))
|
|
(zerop (call-process "git" nil nil nil
|
|
"-C" dirname "ls-files" "--error-unmatch" filename))))
|
|
|
|
(defun should-auto-save-current-buffer-p ()
|
|
"Check whether the current buffer should be autosaved."
|
|
(when buffer-file-name
|
|
(git-tracked-file-p buffer-file-name)))
|
|
|
|
(defun find-init-file ()
|
|
"Find the user's init file"
|
|
(interactive)
|
|
(find-file user-init-file))
|
|
|
|
(use-package emacs
|
|
:ensure nil
|
|
:bind (("C-z" . nil)
|
|
("C-z i" . find-init-file)
|
|
("C-z f" . ffap))
|
|
:hook ((after-save . executable-make-buffer-file-executable-if-script-p)
|
|
(xref-after-update . outline-minor-mode))
|
|
:init
|
|
(setq load-path (append (list
|
|
(expand-file-name "~/.config/emacs/site-lisp/")
|
|
(expand-file-name "~/Projects/lilypond/elisp")
|
|
)
|
|
load-path))
|
|
:config
|
|
; keep-sorted start
|
|
(defalias 'yes-or-no-p 'y-or-n-p)
|
|
(display-battery-mode)
|
|
(display-time-mode)
|
|
(load "lilypond-init.el")
|
|
(prefer-coding-system 'utf-8)
|
|
(progn (which-key-mode) (with-eval-after-load 'diminish (diminish 'which-key-mode)))
|
|
(put 'dired-find-alternate-file 'disabled nil)
|
|
(set-default-file-modes #o750)
|
|
(windmove-default-keybindings 'super)
|
|
; keep-sorted end
|
|
:custom
|
|
; keep-sorted start
|
|
(auto-save-interval 20)
|
|
(auto-save-visited-mode t)
|
|
(auto-save-visited-predicate #'should-auto-save-current-buffer)
|
|
(column-number-mode t)
|
|
(dired-dwim-target 'dired-dwim-target-next)
|
|
(display-time-24hr-format t)
|
|
(display-time-day-and-date t)
|
|
(global-auto-revert-mode t)
|
|
(global-auto-revert-non-file-buffers t)
|
|
(inhibit-startup-screen t)
|
|
(show-paren-context-when-offscreen 'overlay)
|
|
(xref-search-program 'ripgrep)
|
|
; keep-sorted end
|
|
)
|
|
|
|
(use-package diminish)
|
|
|
|
(use-package better-defaults
|
|
:ensure (:repo "https://git.sr.ht/~technomancy/better-defaults"))
|
|
|
|
(use-package treemacs-icons-dired
|
|
:hook (dired-mode . treemacs-icons-dired-mode))
|
|
|
|
(use-package dired-subtree
|
|
:after dired
|
|
:bind (:map dired-mode-map
|
|
("<tab>" . dired-subtree-toggle)
|
|
("<C-tab>" . dired-subtree-cycle)
|
|
("<S-iso-lefttab>" . dired-subtree-remove))
|
|
:config
|
|
; keep-sorted start
|
|
(defadvice dired-subtree-cycle (after add-icons activate) (revert-buffer))
|
|
(defadvice dired-subtree-toggle (after add-icons activate) (revert-buffer))
|
|
; keep-sorted end
|
|
:custom
|
|
(dired-subtree-use-backgrounds nil))
|
|
|
|
(use-package undo-tree
|
|
:ensure (:repo "https://gitlab.com/tsc25/undo-tree")
|
|
:init (global-undo-tree-mode)
|
|
:custom
|
|
(undo-tree-history-directory-alist '(("." . "~/.config/emacs/undo-tree")))
|
|
:diminish undo-tree-mode
|
|
)
|
|
|
|
(use-package transient)
|
|
|
|
(use-package cond-let
|
|
:ensure (:repo "https://github.com/tarsius/cond-let"))
|
|
(use-package magit
|
|
:bind (("C-x g" . magit-status)
|
|
("C-x M-g" . magit-list-repositories))
|
|
:init
|
|
(require 'magit-extras)
|
|
:custom
|
|
(magit-repository-directories
|
|
'(("~/" . 0)
|
|
("~/Projects/" . 1))))
|
|
|
|
(use-package nyan-mode
|
|
:init
|
|
(nyan-mode 1)
|
|
:custom
|
|
(nyan-animate-nyancat t)
|
|
(nyan-wavy-trail t))
|
|
|
|
(use-package mozc
|
|
:bind (("C-c m" . mozc-mode)))
|
|
|
|
(use-package material-theme
|
|
:config
|
|
(load-theme 'material t))
|
|
|
|
(use-package windmove
|
|
:ensure nil
|
|
:bind (("s-w" . windmove-up)
|
|
("s-a" . windmove-left)
|
|
("s-s" . windmove-down)
|
|
("s-d" . windmove-right)))
|
|
|
|
(use-package counsel
|
|
:bind (("C-s" . swiper-isearch)
|
|
("M-x" . counsel-M-x)
|
|
("M-y" . counsel-yank-pop)
|
|
("<f1> f" . counsel-describe-function)
|
|
("<f1> v" . counsel-describe-variable)
|
|
("C-x C-f" . counsel-find-file)
|
|
("C-x b" . ivy-switch-buffer)
|
|
("C-x d" . counsel-dired)
|
|
("C-c u" . counsel-unicode-char)
|
|
("C-c v" . ivy-push-view)
|
|
("C-c V" . ivy-pop-view)
|
|
:map ivy-minibuffer-map
|
|
("C-<return>" . ivy-immediate-done))
|
|
:init
|
|
(ivy-add-actions 'project-find-file '(("x" counsel-locate-action-extern "open externally")))
|
|
:config
|
|
(setq ivy-re-builders-alist
|
|
'((t . ivy--regex-ignore-order)))
|
|
:custom
|
|
(ivy-mode 1)
|
|
(ivy-count-format "(%d/%d) "))
|
|
|
|
(use-package org
|
|
:ensure nil
|
|
:bind (("C-c l" . org-store-link)
|
|
("C-c c" . org-capture)
|
|
("C-c a" . org-agenda)
|
|
("C-c b" . org-switchb)
|
|
:map org-mode-map
|
|
("M-." . org-open-at-point)
|
|
("M-," . org-mark-ring-goto))
|
|
:custom
|
|
; keep-sorted start block=yes
|
|
(org-agenda-start-on-weekday 0)
|
|
(org-agenda-weekend-days '(5 6))
|
|
(org-default-notes-file "~/Documents/notes.org")
|
|
(org-agenda-files (list org-default-notes-file))
|
|
(org-capture-templates
|
|
'(
|
|
("i" "Thoughts on Debugging and Research" entry
|
|
(file+headline org-default-notes-file "Inquiries")
|
|
"** %?\n %U\n*** Failures and possible solutions")
|
|
("t" "Task" entry
|
|
(file+headline org-default-notes-file "Tasks")
|
|
"** TODO %?\n %U")
|
|
))
|
|
(org-clock-sound "~/Music/single-ding.wav")
|
|
; keep-sorted end
|
|
)
|
|
|
|
(use-package org-contrib)
|
|
(use-package org-contacts
|
|
:after org-contrib)
|
|
|
|
(use-package age
|
|
:custom
|
|
(age-default-identity "~/.age/key")
|
|
(age-default-recipient "~/.age/key.pub")
|
|
:config
|
|
(age-file-enable))
|
|
|
|
;; EPUB reader
|
|
(use-package nov
|
|
:init
|
|
(setq auto-mode-alist
|
|
(map-merge 'list
|
|
'(("\\.epub\\'" . nov-mode))
|
|
auto-mode-alist))
|
|
)
|
|
|
|
(use-package company
|
|
:init (global-company-mode)
|
|
:diminish company-mode)
|
|
|
|
(use-package apt-mode
|
|
:disabled t)
|
|
|
|
(use-package docker
|
|
:bind ("C-c d" . docker)
|
|
:custom
|
|
(docker-command "podman")
|
|
(docker-network-columns
|
|
'((:name "Network ID" :width 20 :template "{{ json .ID }}" :sort nil :format nil)
|
|
(:name "Name" :width 50 :template "{{ json .Name }}" :sort nil :format nil)
|
|
(:name "Driver" :width 10 :template "{{ json .Driver }}" :sort nil :format nil))))
|
|
|
|
(use-package iedit)
|
|
(use-package wgrep)
|
|
|
|
(use-package apheleia
|
|
:config
|
|
(apheleia-global-mode)
|
|
(setf (alist-get 'emacs-lisp-mode apheleia-mode-alist nil 'remove) nil)
|
|
(setf (alist-get 'ruff-isort apheleia-formatters)
|
|
'("ruff" "check"
|
|
"-n"
|
|
"--select" "I"
|
|
"--select" "F401"
|
|
"--fix" "--fix-only"
|
|
"--stdin-filename" filepath
|
|
"-"))
|
|
(setf (alist-get 'python-mode apheleia-mode-alist)
|
|
'(ruff-isort ruff))
|
|
(setf (alist-get 'python-ts-mode apheleia-mode-alist)
|
|
'(ruff-isort ruff))
|
|
:diminish apheleia-mode
|
|
)
|
|
|
|
(use-package flymake
|
|
:ensure nil
|
|
:bind (:map flymake-mode-map
|
|
("C-c C-l" . flymake-show-buffer-diagnostics)
|
|
("C-x C-l" . flymake-show-project-diagnostics)
|
|
("C-c C-n" . flymake-goto-next-error)
|
|
("C-c C-p" . flymake-goto-prev-error))
|
|
:custom
|
|
(flymake-show-diagnostics-at-end-of-line t)
|
|
)
|
|
|
|
; Note: debugging Python in a virtualenv requires debugpy to be installed inside the venv
|
|
(use-package dape)
|
|
|
|
; Requires poetry to be installed
|
|
(use-package poetry)
|
|
|
|
(defun load-python-env ()
|
|
"Set up the Python IDE in the current project."
|
|
(interactive)
|
|
(when (derived-mode-p 'python-mode)
|
|
(progn
|
|
(poetry-venv-workon)
|
|
(eglot-ensure))))
|
|
|
|
(use-package python
|
|
:bind (:map python-mode-map
|
|
("C-c C-p" . nil)
|
|
("C-c C-l" . nil)
|
|
("C-c t" . elpy-test))
|
|
:hook (hack-local-variables . load-python-env)
|
|
:config
|
|
(load "python-tests.el")
|
|
:custom
|
|
(elpy-test-runner 'elpy-test-pytest-runner)
|
|
)
|
|
|
|
;; Jupyter notebook integration
|
|
(use-package ein
|
|
:bind (("C-z j" . ein:run)
|
|
:map ein:notebook-mode-map
|
|
("C-c C-x k" . ein:notebook-switch-kernel))
|
|
:config
|
|
(require 'ein-notebook)
|
|
:custom
|
|
; keep-sorted start
|
|
(ein:jupyter-default-notebook-directory "~/Projects/notebooks")
|
|
(ein:output-area-inlined-images t)
|
|
; keep-sorted end
|
|
)
|
|
|
|
(use-package direnv
|
|
:config
|
|
(direnv-mode))
|
|
|
|
(use-package rustic
|
|
:custom
|
|
(rustic-lsp-client 'eglot)
|
|
)
|
|
|
|
(use-package go-config
|
|
:ensure nil
|
|
:hook
|
|
(go-ts-mode . eglot-ensure)
|
|
:init
|
|
(setq auto-mode-alist
|
|
(map-merge 'list
|
|
'(("\\.go\\'" . go-ts-mode)
|
|
("/go\\.mod\\'" . go-mod-ts-mode)
|
|
("/go\\.work\\'" . go-work-ts-mode))
|
|
auto-mode-alist))
|
|
)
|
|
|
|
(use-package gptel
|
|
:custom
|
|
; keep-sorted start
|
|
(gptel-backend (gptel-get-backend "Claude"))
|
|
(gptel-default-mode 'org-mode)
|
|
(gptel-model 'claude-3-5-haiku-20241022)
|
|
; keep-sorted end
|
|
:preface
|
|
(gptel-make-anthropic "Claude"
|
|
:stream t
|
|
:key 'gptel-api-key-from-auth-source
|
|
)
|
|
)
|
|
|
|
(use-package power-mode)
|
|
|
|
(use-package emms
|
|
:config
|
|
(require 'emms-setup)
|
|
(emms-all)
|
|
:custom
|
|
; keep-sorted start
|
|
(emms-info-functions '(emms-info-native))
|
|
(emms-player-list '(emms-player-mpv))
|
|
; keep-sorted end
|
|
)
|
|
|
|
(defun my-qr-selection ()
|
|
(interactive)
|
|
(if (use-region-p)
|
|
(qrencode-region (region-beginning) (region-end))
|
|
(let ((url (thing-at-point-url-at-point)))
|
|
(if (null url)
|
|
(call-interactively #'qrencode-string)
|
|
(qrencode--encode-to-buffer url)))))
|
|
|
|
(use-package qrencode
|
|
:bind (("C-z q" . my-qr-selection)))
|