From 238a9f4fc1766382eeb9485149f23a96b84a33c7 Mon Sep 17 00:00:00 2001 From: chase Date: Wed, 21 May 2025 23:32:37 -0400 Subject: [PATCH] Add emacs config --- flake.nix | 4 +- home/emacs/early-init.el | 59 ++++ home/emacs/init.el | 550 ++++++++++++++++++++++++++++++++++++++ home.nix => home/home.nix | 3 + 4 files changed, 614 insertions(+), 2 deletions(-) create mode 100644 home/emacs/early-init.el create mode 100644 home/emacs/init.el rename home.nix => home/home.nix (97%) diff --git a/flake.nix b/flake.nix index ab83bc5..19eecfe 100644 --- a/flake.nix +++ b/flake.nix @@ -33,7 +33,7 @@ { home-manager.backupFileExtension = "backup"; home-manager.useGlobalPkgs = true; - home-manager.users.chase = ./home.nix; + home-manager.users.chase = ./home/home.nix; } ]; }; @@ -48,7 +48,7 @@ { home-manager.backupFileExtension = "backup"; home-manager.useGlobalPkgs = true; - home-manager.users.chase = ./home.nix; + home-manager.users.chase = ./home/home.nix; } ]; }; diff --git a/home/emacs/early-init.el b/home/emacs/early-init.el new file mode 100644 index 0000000..d149583 --- /dev/null +++ b/home/emacs/early-init.el @@ -0,0 +1,59 @@ +;;; early-init.el --- early init configuration by chase. -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; temporarily increase garbage collection threshold +(setq gc-cons-threshold most-positive-fixnum + gc-cons-percentage 0.6) + +;; temporarily clear file-name-handler-alist to speed up init +(defvar old-file-name-handler file-name-handler-alist) + +(setq file-name-handler-alist nil) + +;; temporarily clear vc-handled-backends to speed up init +(defvar old-vc-handled-backends vc-handled-backends) + +(setq vc-handled-backends nil) + +;; reset file-name-handler and garbage collection after init +(add-hook 'after-init-hook (lambda () + (setq file-name-handler-alist old-file-name-handler + vc-handled-backends old-vc-handled-backends + gc-cons-threshold 16777216 ; 16mb + gc-cons-percentage 0.1))) + +;; avoid loading old byte code +(setq load-prefer-newer t) + +;; load path +(add-to-list 'load-path "~/.emacs.d/work/") + +;; set & load custom file +(setq custom-file (expand-file-name "custom.el" user-emacs-directory)) +(when (file-exists-p custom-file) + (load custom-file)) + +;; backup directory instead of loose files +(setq backup-directory-alist '(("." . "~/.emacs.d/backups"))) +(setq backup-by-copying t) + +;; defer package initialize +(setq package-enable-at-startup nil) + +;; prevent resizing of the frame +(setq frame-inhibit-implied-resize t) + +;; no bars +(menu-bar-mode -1) +(tool-bar-mode -1) +(scroll-bar-mode -1) + +;; no startup screen +(setq inhibit-startup-screen t) + +;; wrapping up +(provide 'early-init) +;;; early-init.el ends here diff --git a/home/emacs/init.el b/home/emacs/init.el new file mode 100644 index 0000000..7339360 --- /dev/null +++ b/home/emacs/init.el @@ -0,0 +1,550 @@ +;;; init.el --- Emacs configuration by chase. -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: +;; display startup time +(defun chase/display-startup-time () + "Write init time and number of garbage collections to message buffer." + (message "Emacs loaded in %s with %d garbage collections" + (emacs-init-time) gcs-done)) + +(add-hook 'emacs-startup-hook #'chase/display-startup-time) + +;; set repos and bootstrap use-package +;; (require 'package) + +;; (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) + +;; (package-initialize) + +;; (eval-when-compile + ;; (require 'use-package)) + +;; +;; bootstrap straight +(defvar bootstrap-version) +(let ((bootstrap-file + (expand-file-name + "straight/repos/straight.el/bootstrap.el" + (or (bound-and-true-p straight-base-dir) + user-emacs-directory))) + (bootstrap-version 7)) + (unless (file-exists-p bootstrap-file) + (with-current-buffer + (url-retrieve-synchronously + "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" + 'silent 'inhibit-cookies) + (goto-char (point-max)) + (eval-print-last-sexp))) + (load bootstrap-file nil 'nomessage)) + +(setq straight-use-package-by-default t) + +;; always install missing packages +;; (require 'use-package-ensure) +;; (setq use-package-always-ensure t) +(setq use-package-always-demand t + use-package-compute-statistics t) + +(require 'bind-key) + +(use-package diminish) + +;; benchmark +(use-package benchmark-init + :config + (add-hook 'after-init-hook #'benchmark-init/deactivate)) + +;; auto-update packages +;; (use-package auto-package-update +;; :custom +;; (setq auto-package-update-delete-old-versions t +;; auto-package-update-hide-results t +;; auto-package-update-interval 7) +;; :config +;; (auto-package-update-maybe) +;; (auto-package-update-at-time "09:30")) + +;; set locale +(set-language-environment "UTF-8") +(prefer-coding-system 'utf-8-unix) +(setq-default buffer-file-coding-system 'utf-8-unix) + +;; a few basic config points +(setq use-short-answers t) +(setq native-comp-async-report-warnings-errors 'silent) + +;; date & time stuff +(use-package calendar + :config + (setq calendar-week-start-day 1)) ;; Monday + +(use-package time + :after doom-modeline + :init + (setq display-time-default-load-average nil + display-time-24hr-format t) + (display-time-mode)) + +;; battery +(use-package fancy-battery + :after doom-modeline) + +;; anzu +(use-package anzu + :config + (global-anzu-mode)) + +;; become evil +(use-package evil + :init + (setq evil-want-keybinding nil + evil-want-integration t + evil-respect-visual-line-mode t + evil-undo-system 'undo-redo + evil-want-fine-undo t) + :config + (evil-mode)) + +(use-package evil-anzu + :after (evil anzu)) + +(use-package evil-collection + :after evil + :diminish evil-collection-unimpaired-mode + :config + (evil-collection-init)) + +;; prevent laggy icons +(setq inhibit-compacting-font-caches t) + +;; make Emacs pretty +(use-package nerd-icons + :custom + (nerd-icons-font-family "BlexMono Nerd Font")) + +(use-package nerd-icons-completion + :config + (nerd-icons-completion-mode)) + +(use-package nerd-icons-dired + :hook + (dired-mode . nerd-icons-dired-mode)) + +(use-package nerd-icons-ibuffer + :hook + (ibuffer-mode . nerd-icons-ibuffer-mode)) + +;; theme stuff +(use-package catppuccin-theme + :config + (load-theme 'catppuccin :no-confirm) + (add-hook 'server-after-make-frame-hook #'catppuccin-reload)) + +;; colourize colour names +(use-package rainbow-mode + :ensure nil ;; built-in package + :hook + (org-mode . rainbow-mode) + (text-mode . rainbow-mode)) + +;; make parentheses colourful +(use-package rainbow-delimiters + :hook + (prog-mode . rainbow-delimiters-mode)) + +;; misc aesthetic settings +(global-hl-line-mode) +(column-number-mode) + +;; line numbers, not quite everywhere +(add-hook 'prog-mode-hook #'display-line-numbers-mode) +(add-hook 'text-mode #'display-line-numbers-mode) + +;; center cursor +;; (use-package centered-cursor-mode +;; :config +;; (global-centered-cursor-mode)) + +;; move cursor to new help windows +(setq help-window-select t) + +;; less blinky cursor +(setq blink-cursor-blinks 3) + +;; move between windows easier +(windmove-default-keybindings) + +;; doom-modeline +(use-package doom-modeline + :hook + (after-init . doom-modeline-mode)) + +;; tab behaviour +(setq-default indent-tabs-mode nil) +(setq-default tab-width 4) + +;; electric pair +(electric-pair-mode t) + +;; use ibuffer instead of Buffer Menu, it looks nicer +(require 'ibuf-ext) + +(global-set-key (kbd "C-x C-b") 'ibuffer) + +(setq ibuffer-saved-filter-groups + '(("Default" + ("Terminal" (name . "^\\*terminal\\*$")) + ("Code" (or + (mode . c-ts-mode) + (mode . c++-ts-mode) + (mode . js-ts-mode) + (mode . makefile-gmake-mode) + (mode . python-ts-mode) + (mode . rust-ts-mode))) + ("Dired" (mode . dired-mode)) + ("Org" (mode . org-mode)) + ("Magit" (name . "^magit")) + ("Emacs" (or + (name . "^\\*Completions\\*$") + (name . "^\\*Help\\*$") + (name . "^\\*info\\*$") + (name . "^\\*Messages\\*$") + (name . "^\\*scratch\\*$")))))) + +(add-hook 'ibuffer-mode-hook + (lambda () + (ibuffer-switch-to-saved-filter-groups "Default"))) + +;; git stuff +(use-package magit) + +(use-package magit-todos + :after magit) + +(use-package forge + :after magit + :init + (setq forge-add-default-bindings nil)) + +(use-package git-modes) + +(use-package editorconfig + :config + (editorconfig-mode 1)) + +;; treemacs stuff +(use-package treemacs + :bind (:map global-map + ("M-0" . treemacs-select-window) + ("C-x t t" . treemacs)) + :config + (setq treemacs-persist-file "~/.cache/emacs/treemacs-persist" + treemacs-width 25)) + +(use-package treemacs-evil + :after (treemacs evil)) + +(use-package treemacs-magit + :after (treemacs magit)) + +(use-package treemacs-nerd-icons + :after (treemacs nerd-icons) + :config + (treemacs-load-theme "nerd-icons")) + +;; company +(use-package company + :bind (:map company-active-map + ("C-n" . company-select-next) + ("C-p" . company-select-previous)) + :init + (global-company-mode) + :config + (setq company-idle-delay 0.1)) ;; faster autocomplete + +;; yasnippet config +(use-package yasnippet + :defer t + :hook + (prog-mode . yas-minor-mode) + :config + (setq yas-snippet-dirs + '("~/.emacs.d/snippets" ;; personal + "~/.emacs.d/work"))) ;; keep em separated + +;; nix +(use-package nix-ts-mode + :defer t + :mode "\\.nix\\'") + +;; c +(use-package c-ts-mode + :straight nil + :defer t + :config + (setq c-ts-mode-indent-style 'k&r) + (setq c-ts-mode-indent-offset 4)) + +;; python +(use-package python + :defer t + :config + (setq python-flymake-command '("flake8" "-"))) + +;; eglot +(use-package eglot + :straight nil + :hook + (c-ts-mode . eglot-ensure) + (python-ts-mode . eglot-ensure) + :config + (setq eldoc-echo-area-display-truncation-message nil + eldoc-echo-area-prefer-doc-buffer t + max-mini-window-height 2)) + +;; treesit-auto +(use-package treesit-auto + :custom + (treesit-auto-install 'prompt) + :config + (treesit-auto-add-to-auto-mode-alist 'all) + (setq treesit-font-lock-level 4) + (global-treesit-auto-mode)) + +;; CSV mode +(use-package csv-mode + :defer t) + +;; markdown +(use-package markdown-mode + :defer t + :mode + ("README\\.md\\'" . gfm-mode) + :config + (setq markdown-gfm-uppercase-checkbox t + markdown-enable-wiki-links t)) + +;; powershell support +(use-package powershell + :defer t) + +;; yaml +(use-package yaml + :defer t) + +;; portage config for gentoo +(use-package portage-modes + :defer t) + +;; pdf tools +(use-package pdf-tools + :defer t + :pin manual ;; don't reinstall when package updates + :mode + ("\\.pdf\\'" . pdf-view-mode) + :hook + (pdf-view-mode-hook . (internal-show-cursor nil nil)) + :config + (setq-default pdf-view-display-size 'fit-page) + (setq pdf-annot-activate-created-annotations t) + (pdf-tools-install :no-query) + (require 'pdf-occur)) + +;; helm +(use-package helm + :config + (global-set-key (kbd "M-x") #'helm-M-x) + (global-set-key (kbd "C-x r b") #'helm-filtered-bookmarks) + (global-set-key (kbd "C-x C-f") #'helm-find-files) + (setq helm-ff-auto-update-initial-value non-nil) + (helm-mode 1)) + +;; org stuff +(use-package org + :mode + ("\\.\\(org\\|org_archive\\|txt\\)\\'" . org-mode) + :hook + (org-mode . visual-line-mode) + (org-mode . (lambda () (add-hook 'after-save-hook #'org-babel-tangle :append :local))) + :diminish visual-line-mode + :config + ;; looks + (setq org-ellipsis "⤵" + org-hide-emphasis-markers t + org-startup-folded 'content + org-src-fontify-natively t + org-edit-src-content-indentation 0) + + ;; keybinds + (define-key global-map "\C-cl" #'org-store-link) + (define-key global-map "\C-ca" #'org-agenda) + (global-set-key (kbd "C-c c") 'org-capture) + + ;; agenda + (require 'find-lisp) + (setq org-directory "~/org") + (setq chase/org-agenda-directory + (expand-file-name "gtd/" org-directory)) + (setq org-agenda-files + (find-lisp-find-files chase/org-agenda-directory "\.org$")) + + (setq org-capture-templates + '(("i" "Inbox" entry (file "gtd/inbox.org") + "* TODO %?\n") + ("n" "Note" entry (file "~/org/inbox.org") + "* %? :NOTE:\n"))) + + ;; TODO + (setq org-log-done 'time) + (setq org-todo-keywords + '((sequence "TODO(t)" "NEXT(n)" "HOLD(h)" "|" "DONE(d)" "|" "Cancelled(c)"))) + + (setq org-tag-alist '(("@errand" . ?e) + ("@office" . ?o) + ("@home" . ?h))) + + (setq org-refile-allow-creating-parent-nodes 'confirm + org-refile-targets '(("projects.org" . (:level . 1)))) + +;; source blocks + (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")) + (add-to-list 'org-structure-template-alist '("py" . "src python")) + (add-to-list 'org-structure-template-alist '("sh" . "src shell")) + (add-to-list 'org-structure-template-alist '("ts" . "src typescript")) + (add-to-list 'org-structure-template-alist '("json" . "src json")) + (add-to-list 'org-structure-template-alist '("yaml" . "src yaml")) + + ;; fix yaml fontify + (add-to-list 'org-src-lang-modes '("yaml" . yaml-ts)) + + ;; export + (setq org-export-with-toc nil + org-export-with-section-numbers nil) + + ;; LaTeX + (setq org-latex-compiler "xelatex") + (setq org-latex-listings 'minted + org-latex-pdf-process + '("latexmk -shell-escape -f -pdf -%latex -interaction=nonstopmode -output-directory=%o %f")) + + (use-package evil-org + :after org + :hook + (org-mode . evil-org-mode) + :diminish evil-org-mode + :init + (setq evil-want-C-i-jump nil) + :config + (require 'evil-org-agenda) + (evil-org-set-key-theme '(navigation insert textobjects additional calendar)) + (evil-org-agenda-set-keys)) + + (use-package org-roam + :after org + :custom + (org-roam-directory "~/org-roam") + :bind + (("C-c n l" . org-roam-buffer-toggle) + ("C-c n f" . org-roam-node-find) + ("C-c n g" . org-roam-graph) + ("C-c n i" . org-roam-node-insert) + ("C-c n c" . org-roam-capture) + ;; Dailies + ("C-c n j" . org-roam-dailies-capture-today)) + :config + (require 'org-roam-protocol) + (require 'org-roam-export) + (org-roam-db-autosync-mode) + (setq org-roam-capture-templates + '(("m" "main" plain "%?" + :if-new + (file+head "main/${slug}.org" "#+title: ${title}\n") + :unnarrowed t) + ("r" "reference" plain "%?" + :if-new + (file+head "reference/${title}.org" "#+title: ${title}\n") + :unnarrowed t))) + + (setq org-roam-capture-ref-templates + '(("r" "ref" plain "%?" :target + (file+head "reference/${slug}.org" "#+title: ${title}\n${body}\n") + :unnarrowed t)))) + + (use-package org-bullets + :after org + :hook + (org-mode . org-bullets-mode)) + + (use-package org-appear + :after org + :hook + (org-mode . org-appear-mode) + :config + (setq org-appear-autolinks t)) + + ;; GitHub flavoured markdown export + (use-package ox-gfm + :after org) + + ;; hugo markdown export + (use-package ox-hugo + :after org) + + ;; HTML syntax highlighting + (use-package htmlize + :after org) + + (use-package ox-moderncv + :after org + :straight + (org-cv :type git :host gitlab :repo "Titan-C/org-cv")) + +(use-package ox-hugocv + :after org + :straight + (org-cv :type git :host gitlab :repo "Titan-C/org-cv"))) + +;; spell checking +(use-package ispell + :custom + (ispell-program-name "aspell") + (ispell-silently-savep t)) + +(use-package flyspell + :defer t + :hook + (org-mode . flyspell-mode) + :diminish flyspell-mode) + +;; enlighten flymake to the load path +(setq elisp-flymake-byte-compile-load-path load-path) + +;; windows printer +(setq ps-printer-name t) +(setq ps-lpr-command "C:/Program Files/gs/gs10.03.1/bin/gswin64c.exe") +(setq ps-lpr-switches '("-q" "-dNOPAUSE" "-dBATCH" "-sDEVICE=mswinpr2" + "-sPAPERSIZE=a7")) + +;; exwm +;; (use-package exwm + ;; :config + ;; (add-hook 'exwm-update-class-hook + ;; (lambda () (exwm-workspace-rename-buffer exwm-class-name))) + ;; (setq exwm-input-global-keys + ;; `(([?\s-r] . exwm-reset) + ;; ([?\s-w] . exwm-workspace-switch) + ;; ([?\s-&] . (lambda (cmd) + ;; (interactive (list (read-shell-command "$ "))) + ;; (start-process-shell-command cmd nil cmd))) + ;; ,@(mapcar (lambda (i) + ;; `(,(kbd (format "s-%d" i)) + ;; (lambda () + ;; (interactive) + ;; (exwm-workspace-switch-create ,i)))) + ;; (number-sequence 0 9)))) + ;; (exwm-enable)) + +(provide 'init) +;;; init.el ends here diff --git a/home.nix b/home/home.nix similarity index 97% rename from home.nix rename to home/home.nix index 65217de..909e8c0 100644 --- a/home.nix +++ b/home/home.nix @@ -12,6 +12,9 @@ userDirs.enable = true; }; + home.file.".emacs.d/early-init.el".source = ./emacs/early-init.el; + home.file.".emacs.d/init.el".source = ./emacs/init.el; + programs.alacritty = { enable = true; settings = {