aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVaino Kauppila <vaino@vke.fi>2026-09-10 14:42:46 +0300
committerVaino Kauppila <vaino@vke.fi>2026-09-10 14:42:46 +0300
commit02cf1cb1eb8e5611a30b8089228623493fbc771d (patch)
tree861bc665f0488e82a8b9a77e74e15d748530e7ff
downloademacs_setup-02cf1cb1eb8e5611a30b8089228623493fbc771d.tar.gz
emacs_setup-02cf1cb1eb8e5611a30b8089228623493fbc771d.zip
Import existing ~/.emacs as baseline, add tracking tooling
Byte-identical import of the live ~/.emacs (Emacs 31.1, loads clean in batch and GUI apart from warnings noted in README). Tooling: check.sh (batch-load validation), install.sh (backup + symlink ~/.emacs -> emacs.el), Makefile, README.
-rw-r--r--.gitignore2
-rw-r--r--Makefile10
-rw-r--r--README.md58
-rwxr-xr-xcheck.sh30
-rw-r--r--emacs.el645
-rwxr-xr-xinstall.sh36
6 files changed, 781 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..33721c7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.elc
+backups/
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..1e765db
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,10 @@
+.PHONY: check install status
+
+check: ## Validate emacs.el loads cleanly in batch Emacs
+ ./check.sh
+
+install: ## Symlink ~/.emacs to this repo's emacs.el
+ ./install.sh
+
+status: ## Show uncommitted changes to your config
+ @git status --short && git diff --stat
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8b2718a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,58 @@
+# emacs_setup
+
+Git-tracked Emacs configuration. `emacs.el` is the source of truth;
+`~/.emacs` is a symlink to it, so the live config is always the latest
+version in this repo.
+
+## Layout
+
+| File | Purpose |
+|--------------|--------------------------------------------------|
+| `emacs.el` | The init file itself (what `~/.emacs` points to) |
+| `check.sh` | Validate the config loads cleanly |
+| `install.sh` | Back up old config, symlink `~/.emacs` → `emacs.el` |
+| `backups/` | Pre-install backups (gitignored) |
+
+## Usage
+
+```sh
+./install.sh # one-time: symlink ~/.emacs -> emacs.el (backs up the old file)
+./check.sh # or: make check -- run before committing
+make status # see uncommitted drift
+```
+
+### Workflow after installing
+
+- Edit the config either in Emacs (`C-x C-f ~/.emacs`) or here — same file.
+- Changes made by `M-x customize` (custom-set-variables) land directly
+ in this working tree; review with `git diff`, commit when happy.
+- To try a change: save, `./check.sh`, then restart Emacs.
+- To roll back: `git checkout <commit> -- emacs.el` — the symlink picks
+ it up immediately, no reinstall.
+- To restore the pre-repo config entirely: copy the newest file from
+ `backups/` back to `~/.emacs` (replacing the symlink).
+
+## Findings from the initial check (2026-09-10)
+
+Fixed in a follow-up commit:
+
+1. **Missing `lexical-binding` cookie** — startup warning on every launch. Added
+ `-*- lexical-binding: t; -*-` to line 1 (verified the file loads cleanly
+ under lexical binding).
+2. **Unguarded Verilog LSP client** — the config registers `verible-verilog-ls`
+ and hooks `lsp` into `verilog-mode`, but the binary is not installed, so
+ opening Verilog files errored. Now registered only when the binary exists
+ (`executable-find`). Install `verible` to re-enable.
+
+Known quirks left as-is (deliberate-looking choices — revisit if annoying):
+
+- **`lsp-mode` and `eglot` are both active**: lsp-mode owns C/C++/Verilog/VHDL/
+ LaTeX, eglot owns Java/Scala/Python/Clojure. The C/C++ overlap is noted in
+ the config itself. Works, but pick one eventually.
+- **`jdtls` is not installed**, so Java files will fail to start eglot.
+ Install `jdtls` (or drop java-mode from the eglot hook).
+- **`flycheck-c/c++-gcc-executable` is set to `/usr/bin/avr-gcc`** in
+ `custom-set-variables` — flycheck uses avr-gcc for *all* C files, not just
+ AVR projects. Consider moving it to per-project `.dir-locals.el`.
+- helm and vertico/consult are both configured (two completion stacks);
+ helm is only used for gtags navigation.
diff --git a/check.sh b/check.sh
new file mode 100755
index 0000000..d243171
--- /dev/null
+++ b/check.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+# Validate emacs.el by loading it in a batch Emacs.
+# Run this before committing changes to your config.
+#
+# PASS = file loads with exit 0 and no errors.
+# Warnings are shown but do not fail the check.
+set -uo pipefail
+
+REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+INIT="$REPO_DIR/emacs.el"
+OUTPUT=$(mktemp)
+trap 'rm -f "$OUTPUT"' EXIT
+
+timeout 180 emacs --batch -l "$INIT" >"$OUTPUT" 2>&1
+STATUS=$?
+
+echo "--- emacs --batch -l emacs.el (exit $STATUS) ---"
+cat "$OUTPUT"
+echo "--- end output ---"
+
+ERRORS=$(grep -cE "^(Error|error|Cannot open|File mode specification error)" "$OUTPUT")
+WARNINGS=$(grep -c "^Warning" "$OUTPUT" || true)
+
+if [ "$STATUS" -eq 0 ] && [ "$ERRORS" -eq 0 ]; then
+ echo "PASS: config loads cleanly ($WARNINGS warning(s))"
+ exit 0
+else
+ echo "FAIL: config has errors (see output above)"
+ exit 1
+fi
diff --git a/emacs.el b/emacs.el
new file mode 100644
index 0000000..fbed920
--- /dev/null
+++ b/emacs.el
@@ -0,0 +1,645 @@
+;;; .emacs --- My .emacs config file
+;;; Commentary: Optimized configuration by Claude
+
+;;; Code:
+
+;;; ============================================================================
+;;; PERFORMANCE OPTIMIZATIONS
+;;; ============================================================================
+
+;; Minimize garbage collection during startup
+(setq gc-cons-threshold most-positive-fixnum)
+
+;; Lower threshold back to 8 MiB after startup
+(add-hook 'emacs-startup-hook
+ (lambda ()
+ (setq gc-cons-threshold (* 50 1024 1024))))
+
+;; Keep LSP and redisplay responsive on slower machines.
+(setq read-process-output-max (* 4 1024 1024)
+ redisplay-skip-fontification-on-input t)
+
+;; Reduce unnecessary redraw work in inactive windows.
+(setq-default cursor-in-non-selected-windows nil
+ highlight-nonselected-windows nil)
+
+;; Fast scrolling
+(setq fast-but-imprecise-scrolling t)
+(pixel-scroll-precision-mode 1)
+
+;;; ============================================================================
+;;; UI CONFIGURATION
+;;; ============================================================================
+
+;; Remove UI clutter
+(setq inhibit-startup-message t)
+(tool-bar-mode -1)
+(menu-bar-mode -1)
+(scroll-bar-mode -1)
+(global-hl-line-mode t)
+
+;; Line numbers
+(setq-default display-line-numbers 'relative)
+(global-display-line-numbers-mode)
+
+;; Font configuration
+(set-frame-font "Consolas 12" nil t)
+(add-to-list 'default-frame-alist '(font . "Consolas 12"))
+(set-face-attribute 'default t :font "Consolas 12")
+
+;; Theme
+;; Theme is loaded after package initialization so package themes are available.
+
+;;; ============================================================================
+;;; PACKAGE MANAGEMENT
+;;; ============================================================================
+
+(setq package-enable-at-startup nil)
+(setq package-install-upgrade-built-in t)
+
+(require 'cl-lib)
+(require 'package)
+(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
+(package-initialize)
+
+;; Install and require essential packages
+(defvar vaino-required-packages
+ '(use-package modus-themes avk-emacs-themes ef-themes helm org
+ hl-todo general doom-modeline flycheck pyvenv latex-extra
+ gscholar-bibtex haskell-mode meson-mode glsl-mode
+ org-autolist lsp-mode kind-icon diff-hl helm-xref lsp-latex
+ yasnippet verilog-mode corfu corfu-candidate-overlay
+ helm-gtags lsp-java jtsx vertico orderless marginalia
+ consult))
+
+(unless (cl-every #'package-installed-p vaino-required-packages)
+ (package-refresh-contents))
+
+(dolist (package vaino-required-packages)
+ (unless (package-installed-p package)
+ (package-install package)))
+
+(load-theme 'ef-elea-dark t)
+
+(require 'use-package)
+(setq use-package-always-ensure t)
+
+;;; ============================================================================
+;;; GENERAL SETTINGS
+;;; ============================================================================
+
+;; Indentation
+(setq-default indent-tabs-mode nil
+ tab-width 4
+ c-basic-offset 4
+ c-default-style "linux"
+ lisp-indent-offset 4)
+
+(setq tab-always-indent 'complete)
+
+;; Word wrap and auto-fill
+(setq-default word-wrap t
+ fill-column 72)
+(add-hook 'text-mode-hook #'auto-fill-mode)
+
+;; Backup files
+(setq backup-directory-alist `(("." . "~/.emacs.d/saves")))
+
+;; Misc
+(delete-selection-mode 1)
+(require 'font-lock)
+(global-font-lock-mode 1)
+(setq font-lock-maximum-decoration t)
+(save-place-mode 1)
+(recentf-mode 1)
+(savehist-mode 1)
+(global-so-long-mode 1)
+
+(setq recentf-max-saved-items 200
+ recentf-auto-cleanup 'never)
+
+;;; ============================================================================
+;;; KEY BINDINGS
+;;; ============================================================================
+
+(global-set-key (kbd "C-<tab>") 'completion-at-point)
+(global-set-key (kbd "C-c l") #'org-store-link)
+(global-set-key (kbd "C-c a") #'org-agenda)
+(global-set-key (kbd "C-c c") #'org-capture)
+
+(define-key emacs-lisp-mode-map (kbd "C-c C-b") 'eval-buffer)
+
+;;; ============================================================================
+;;; MINIBUFFER STACK
+;;; ============================================================================
+
+(use-package vertico
+ :custom
+ (enable-recursive-minibuffers t)
+ (read-file-name-completion-ignore-case t)
+ (read-buffer-completion-ignore-case t)
+ (completion-ignore-case t)
+ :init
+ (vertico-mode 1)
+ :bind (:map vertico-map
+ ("RET" . vertico-directory-enter)
+ ("DEL" . vertico-directory-delete-char)
+ ("M-DEL" . vertico-directory-delete-word))
+ :config
+ (require 'vertico-directory))
+
+(use-package orderless
+ :custom
+ (completion-styles '(orderless basic))
+ (completion-category-defaults nil)
+ (completion-category-overrides '((file (styles basic partial-completion)))))
+
+(use-package marginalia
+ :init
+ (marginalia-mode 1))
+
+(use-package consult
+ :bind (("C-x b" . consult-buffer)
+ ("C-x C-r" . consult-recent-file)
+ ("M-y" . consult-yank-pop)
+ ("M-g g" . consult-goto-line)
+ ("M-g i" . consult-imenu)
+ ("M-s l" . consult-line)
+ ("M-s r" . consult-ripgrep))
+ :config
+ (setq xref-show-xrefs-function #'consult-xref
+ xref-show-definitions-function #'consult-xref))
+
+;; Helm gtags
+(add-hook 'c-mode-hook 'helm-gtags-mode)
+(add-hook 'c++-mode-hook 'helm-gtags-mode)
+(add-hook 'asm-mode-hook 'helm-gtags-mode)
+
+(with-eval-after-load "helm-gtags"
+ (define-key helm-gtags-mode-map (kbd "M-t") 'helm-gtags-find-tag)
+ (define-key helm-gtags-mode-map (kbd "M-r") 'helm-gtags-find-rtag)
+ (define-key helm-gtags-mode-map (kbd "M-s") 'helm-gtags-find-symbol)
+ (define-key helm-gtags-mode-map (kbd "M-g M-p") 'helm-gtags-parse-file)
+ (define-key helm-gtags-mode-map (kbd "C-c <") 'helm-gtags-previous-history)
+ (define-key helm-gtags-mode-map (kbd "C-c >") 'helm-gtags-next-history)
+ (define-key helm-gtags-mode-map (kbd "M-,") 'helm-gtags-pop-stack))
+
+;;; ============================================================================
+;;; COMPLETION (CORFU)
+;;; ============================================================================
+
+(use-package corfu
+ :custom
+ (corfu-auto nil)
+ (corfu-quit-at-boundary nil)
+ (corfu-quit-no-match nil)
+ :init
+ (global-corfu-mode))
+
+(use-package corfu-candidate-overlay
+ :after corfu
+ :config
+ (corfu-candidate-overlay-mode +1)
+ (global-set-key (kbd "C-<iso-lefttab>") 'corfu-candidate-overlay-complete-at-point))
+
+(use-package kind-icon
+ :after corfu
+ :custom
+ (kind-icon-default-face 'corfu-default)
+ (kind-icon-use-icons t)
+ :config
+ (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
+
+
+;;; ============================================================================
+;;; LSP MODE
+;;; ============================================================================
+
+(use-package lsp-mode
+ :hook ((c-mode c++-mode) . lsp)
+ :commands lsp)
+
+(use-package lsp-ui
+ :commands lsp-ui-mode)
+
+;; LSP Python settings
+(setq lsp-pylsp-plugins-black-enabled t)
+
+;; LSP Latex
+(use-package lsp-latex
+ :hook (((tex-mode
+ plain-tex-mode
+ latex-mode
+ TeX-mode
+ LaTeX-mode) . lsp-deferred)))
+
+;; LSP for Verilog
+(with-eval-after-load 'lsp-mode
+ (add-to-list 'lsp-language-id-configuration '(verilog-mode . "verilog"))
+ (lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection "verible-verilog-ls")
+ :major-modes '(verilog-mode)
+ :server-id 'verible-ls)))
+
+(add-hook 'verilog-mode-hook 'lsp)
+
+(use-package vhdl-mode
+ :defer t
+ :config
+ (setq lsp-vhdl-server 'ghdl-ls
+ lsp-vhdl-server-path (executable-find "ghdl-ls")
+ lsp-vhdl--params nil)
+ (require 'lsp-vhdl)
+ :hook (vhdl-mode . (lambda()
+ (lsp t)
+ (flycheck-mode t))))
+
+;;; ============================================================================
+;;; EGLOT (ALTERNATIVE LSP CLIENT)
+;;; ============================================================================
+
+(use-package eglot
+ :hook (((clojure-mode clojurec-mode clojurescript-mode
+ java-mode scala-mode python-mode) . eglot-ensure)
+ ((cider-mode eglot-managed-mode) . eglot-disable-in-cider))
+ :preface
+ (defun eglot-disable-in-cider ()
+ (when (eglot-managed-p)
+ (if (bound-and-true-p cider-mode)
+ (progn
+ (remove-hook 'completion-at-point-functions 'eglot-completion-at-point t)
+ (remove-hook 'xref-backend-functions 'eglot-xref-backend t))
+ (add-hook 'completion-at-point-functions 'eglot-completion-at-point nil t)
+ (add-hook 'xref-backend-functions 'eglot-xref-backend nil t))))
+ :custom
+ (eglot-autoshutdown t)
+ (eglot-events-buffer-size 0)
+ (eglot-extend-to-xref nil)
+ (eglot-ignored-server-capabilities '(:colorProvider :foldingRangeProvider))
+ (eglot-stay-out-of '(yasnippet)))
+
+;; Eglot for C/C++ (alternative to lsp-mode setup above)
+;; Note: You're using both lsp-mode and eglot for C/C++, choose one
+(with-eval-after-load 'eglot
+ (add-to-list 'eglot-server-programs '((c++-mode c-mode) "clangd")))
+
+;;; ============================================================================
+;;; PROGRAMMING MODES
+;;; ============================================================================
+
+;; C/C++
+(use-package cc-mode
+ :init
+ (add-hook 'c-mode-hook
+ (lambda ()
+ (add-to-list 'auto-mode-alist '("\\.h\\'" . c-mode))
+ (setq-local c-default-style "linux")))
+ (add-hook 'c++-mode-hook
+ (lambda ()
+ (add-to-list 'auto-mode-alist '("\\.hpp\\'" . c++-mode))
+ (setq-local c-default-style "linux")))
+ :mode (("\\.c\\'" . c-mode)
+ ("\\.cpp\\'" . c++-mode)
+ ("\\.cu\\'" . c++-mode)))
+
+;; Yasnippet
+(add-hook 'prog-mode-hook #'yas-minor-mode)
+(yas-global-mode 1)
+(yas-reload-all)
+
+;; Flycheck
+(add-hook 'after-init-hook #'global-flycheck-mode)
+
+;; Haskell - disable eldoc
+(add-hook 'haskell-mode-hook #'(lambda () (eldoc-mode -1)))
+
+;; Octave
+(add-to-list 'auto-mode-alist '("\\.m\\'" . octave-mode))
+
+;;; ============================================================================
+;;; HL-TODO
+;;; ============================================================================
+
+(setq hl-todo-keyword-faces
+ '(("TODO" . "#FF0000")
+ ("FIXME" . "#FF0000")
+ ("DEBUG" . "#A020F0")
+ ("GOTCHA" . "#FF4500")
+ ("STUB" . "#1E90FF")
+ ("STARTED" . "#E6B400")))
+
+(global-hl-todo-mode)
+
+(use-package diff-hl
+ :hook ((prog-mode text-mode conf-mode) . diff-hl-mode))
+
+;;; ============================================================================
+;;; DOOM MODELINE
+;;; ============================================================================
+
+(use-package doom-modeline
+ :init
+ (setq doom-modeline-height 28
+ doom-modeline-bar-width 4
+ doom-modeline-window-width-limit 110
+ doom-modeline-buffer-file-name-style 'relative-to-project
+ doom-modeline-icon t
+ doom-modeline-major-mode-icon t
+ doom-modeline-major-mode-color-icon t
+ doom-modeline-buffer-state-icon t
+ doom-modeline-buffer-modification-icon t
+ doom-modeline-minor-modes nil
+ doom-modeline-check 'auto
+ doom-modeline-lsp t
+ doom-modeline-project-name t
+ doom-modeline-modal t
+ doom-modeline-battery nil
+ doom-modeline-time t
+ doom-modeline-time-icon t
+ doom-modeline-buffer-encoding nil
+ doom-modeline-indent-info nil
+ doom-modeline-position-column-line-format '("%l:%c")
+ display-time-24hr-format t
+ display-time-default-load-average nil)
+ :config
+ (display-time-mode 1)
+ (doom-modeline-mode 1))
+
+;;; ============================================================================
+;;; ORG MODE
+;;; ============================================================================
+
+(setq org-element-use-cache nil)
+
+;; Hide #+TITLE:
+(setq org-hidden-keywords '(title))
+
+;; Org appearance
+(setq org-startup-indented t
+ org-pretty-entities t
+ org-hide-emphasis-markers t
+ org-startup-with-inline-images t
+ org-image-actual-width '(300))
+
+;; Org autolist
+(add-hook 'org-mode-hook (lambda () (org-autolist-mode)))
+
+;; Org agenda
+(setq org-todo-keywords '((sequence "TODO" "NEXT" "REVISE" "HOLD" "DONE")))
+
+;; Org babel
+(org-babel-do-load-languages
+ 'org-babel-load-languages
+ '((ditaa . t)))
+
+;; Custom org-dblock for weekly time tracking
+(require 'cl-lib)
+(require 'org-clock)
+
+(defun org-dblock-write:weekly (params)
+ (cl-flet ((fmttm (tm) (format-time-string (org-time-stamp-format t t) tm)))
+ (let ((file (or (plist-get params :file) (buffer-file-name)))
+ (start (seconds-to-time (org-matcher-time (plist-get params :tstart))))
+ (end (seconds-to-time (org-matcher-time (plist-get params :tend)))))
+ (while (time-less-p start end)
+ (let ((next-week (time-add start (date-to-time "1970-01-08T00:00Z")))
+ (week-begin (line-beginning-position))
+ (daysworksum 0))
+ (insert "\nWeekly Table from " (fmttm start) "\n")
+ (insert "| Day of Week | Time |\n|-\n")
+ (while (time-less-p start next-week)
+ (let* ((next-day (time-add start (date-to-time "1970-01-02T00:00Z")))
+ (minutes
+ (with-current-buffer (find-file-noselect file)
+ (cadr (org-clock-get-table-data
+ file
+ (list :maxlevel 0
+ :tstart (fmttm start)
+ :tend (fmttm next-day)))))))
+ (insert "|" (format-time-string "%a" start)
+ "|" (format "%d" minutes) "|\n")
+ (org-table-align)
+ (setq daysworksum (+ minutes daysworksum))
+ (setq start next-day)))
+ (insert "| Avg. | " (format "%.2f" (float (/ daysworksum 7))) "|\n")
+ (org-table-align)
+ (when (equal daysworksum 0)
+ (delete-region week-begin (line-beginning-position))))))))
+
+;;; ============================================================================
+;;; LATEX/AUCTEX
+;;; ============================================================================
+
+(require 'latex)
+
+(setq TeX-auto-save t
+ TeX-parse-self t
+ latex-run-command "latexmk"
+ TeX-process-asynchronous t
+ TeX-check-TeX nil
+ TeX-engine 'default
+ TeX-engine-alist
+ '((default
+ "Tectonic"
+ "latexmk -pdf -shell-escape -interaction=nonstopmode -f %t"
+ "latexmk -pdf -shell-escape -interaction=nonstopmode -f %t"
+ nil)))
+(setq-default TeX-master nil)
+
+(defun vaino-tectonic-command (file)
+ (concat "tectonic -Z search-path=$(dirname $(kpsewhich biblatex.sty)) " file))
+
+(add-hook 'LaTeX-mode-hook
+ (lambda ()
+ (add-to-list 'TeX-command-list
+ '("XeLaTeX" "%`xelatex%(mode)%' -shell-escape %t" TeX-run-TeX nil t))
+ (add-to-list 'TeX-command-list
+ `("Tectonic" ,(vaino-tectonic-command "%t") TeX-run-TeX nil
+ (latex-mode doctex-mode) :help "Run Tectonic"))
+ (setq TeX-command-default "LaTeX"
+ TeX-save-query nil
+ TeX-show-compilation t)
+ (TeX-fold-mode 1)))
+
+;; LaTeX source correlation
+(add-hook 'LaTeX-mode-hook #'TeX-source-correlate-mode)
+(with-eval-after-load 'latex
+ (define-key TeX-source-correlate-map [C-down-mouse-1] #'TeX-view-mouse))
+
+;;; ============================================================================
+;;; CUSTOM VARIABLES (GENERATED BY CUSTOM)
+;;; ============================================================================
+
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(LaTeX-command-style '(("" "%(latex)")))
+ '(TeX-command-Biber "Biber")
+ '(TeX-command-list
+ '(("XeLaTeX" "%`xelatex%(mode)%' -shell-escape %t" TeX-run-TeX nil t)
+ ("TeX"
+ "%(PDF)%(tex) %(file-line-error) %`%(extraopts) %S%(PDFout)%(mode)%' %(output-dir) %t"
+ TeX-run-TeX nil
+ (plain-tex-mode texinfo-mode ams-tex-mode) :help
+ "Run plain TeX")
+ ("LaTeX"
+ "latexmk -pdf -shell-escape -interaction=nonstopmode -f %t"
+ TeX-run-TeX nil (latex-mode doctex-mode) :help
+ "Run LaTeX")
+ ("Makeinfo" "makeinfo %(extraopts) %(o-dir) %t"
+ TeX-run-compile nil (texinfo-mode) :help
+ "Run Makeinfo with Info output")
+ ("Makeinfo HTML" "makeinfo %(extraopts) %(o-dir) --html %t"
+ TeX-run-compile nil (texinfo-mode) :help
+ "Run Makeinfo with HTML output")
+ ("AmSTeX"
+ "amstex %(PDFout) %`%(extraopts) %S%(mode)%' %(output-dir) %t"
+ TeX-run-TeX nil (ams-tex-mode) :help "Run AMSTeX")
+ ("ConTeXt"
+ "%(cntxcom) --once --texutil %(extraopts) %(execopts)%t"
+ TeX-run-TeX nil (context-mode) :help "Run ConTeXt once")
+ ("ConTeXt Full" "%(cntxcom) %(extraopts) %(execopts)%t"
+ TeX-run-TeX nil (context-mode) :help
+ "Run ConTeXt until completion")
+ ("BibTeX" "bibtex %(O?aux)" TeX-run-BibTeX nil
+ (plain-tex-mode latex-mode doctex-mode context-mode
+ texinfo-mode ams-tex-mode)
+ :help "Run BibTeX")
+ ("Biber" "/usr/bin/vendor_perl/biber %(output-dir) %s.bcf"
+ TeX-run-Biber nil
+ (plain-tex-mode latex-mode doctex-mode texinfo-mode
+ ams-tex-mode)
+ :help "Run Biber")
+ ("Texindex" "texindex %s.??" TeX-run-command nil
+ (texinfo-mode) :help "Run Texindex")
+ ("Texi2dvi" "%(PDF)texi2dvi %t" TeX-run-command nil
+ (texinfo-mode) :help "Run Texi2dvi or Texi2pdf")
+ ("View" "%V" TeX-run-discard-or-function t t :help
+ "Run Viewer")
+ ("Print" "%p" TeX-run-command t t :help "Print the file")
+ ("Queue" "%q" TeX-run-background nil t :help
+ "View the printer queue" :visible TeX-queue-command)
+ ("File" "%(o?)dvips %d -o %f " TeX-run-dvips t
+ (plain-tex-mode latex-mode doctex-mode texinfo-mode
+ ams-tex-mode)
+ :help "Generate PostScript file")
+ ("Dvips" "%(o?)dvips %d -o %f " TeX-run-dvips nil
+ (plain-tex-mode latex-mode doctex-mode texinfo-mode
+ ams-tex-mode)
+ :help "Convert DVI file to PostScript")
+ ("Dvipdfmx" "dvipdfmx -o %(O?pdf) %d" TeX-run-dvipdfmx nil
+ (plain-tex-mode latex-mode doctex-mode texinfo-mode
+ ams-tex-mode)
+ :help "Convert DVI file to PDF with dvipdfmx")
+ ("Ps2pdf" "ps2pdf %f %(O?pdf)" TeX-run-ps2pdf nil
+ (plain-tex-mode latex-mode doctex-mode texinfo-mode
+ ams-tex-mode)
+ :help "Convert PostScript file to PDF")
+ ("Glossaries" "makeglossaries %(d-dir) %s" TeX-run-command
+ nil
+ (plain-tex-mode latex-mode doctex-mode texinfo-mode
+ ams-tex-mode)
+ :help "Run makeglossaries to create glossary file")
+ ("Index" "makeindex %(O?idx)" TeX-run-index nil
+ (plain-tex-mode latex-mode doctex-mode texinfo-mode
+ ams-tex-mode)
+ :help "Run makeindex to create index file")
+ ("upMendex" "upmendex %(O?idx)" TeX-run-index t
+ (plain-tex-mode latex-mode doctex-mode texinfo-mode
+ ams-tex-mode)
+ :help "Run upmendex to create index file")
+ ("Xindy" "texindy %s" TeX-run-command nil
+ (plain-tex-mode latex-mode doctex-mode texinfo-mode
+ ams-tex-mode)
+ :help "Run xindy to create index file")
+ ("Check" "lacheck %s" TeX-run-compile nil (latex-mode) :help
+ "Check LaTeX file for correctness")
+ ("ChkTeX" "chktex -v6 %s" TeX-run-compile nil (latex-mode)
+ :help "Check LaTeX file for common mistakes")
+ ("Spell" "(TeX-ispell-document \"\")" TeX-run-function nil t
+ :help "Spell-check the document")
+ ("Clean" "TeX-clean" TeX-run-function nil t :help
+ "Delete generated intermediate files")
+ ("Clean All" "(TeX-clean t)" TeX-run-function nil t :help
+ "Delete generated intermediate and output files")
+ ("Other" "" TeX-run-command t t :help
+ "Run an arbitrary command")))
+ '(TeX-view-program-list
+ '(("Sioyek"
+ ("sioyek %o --reuse-window"
+ (mode-io-correlate
+ " --forward-search-file %b --forward-search-line %n --inverse-search \"emacsclient --no-wait +%2:%3 %1\""))
+ "sioyek")))
+ '(TeX-view-program-selection
+ '(((output-dvi has-no-display-manager) "dvi2tty")
+ ((output-dvi style-pstricks) "dvips and gv")
+ (output-dvi "xdvi") (output-pdf "Sioyek")
+ (output-html "xdg-open")))
+ '(bibtex-dialect 'biblatex)
+ '(custom-safe-themes
+ '("e410458d3e769c33e0865971deb6e8422457fad02bf51f7862fa180ccc42c032"
+ "6b912e025527ffae0feb76217f1a3e494b0699e5219ab59ea4b3a36c319cea17"
+ "36b57dcbe8262c52d3123ed30fa34e5ef6b355881674142162a8ca8e26124da9"
+ "11873c4fbf465b956889adfa9182495db3bf214d9a70c0f858f07f6cc91cbd47"
+ "eb7cd622a0916358a6ef6305e661c6abfad4decb4a7c12e73d6df871b8a195f8"
+ "c414f69a02b719fb9867b41915cb49c853489930be280ce81385ff7b327b4bf6"
+ "02fff7eedb18d38b8fd09a419c579570673840672da45b77fde401d8708dc6b5"
+ default))
+ '(dired-listing-switches "-alFh")
+ '(fast-but-imprecise-scrolling t)
+ '(flycheck-c/c++-gcc-executable "/usr/bin/avr-gcc")
+ '(flycheck-clang-language-standard nil)
+ '(flycheck-python-flake8-executable "python3")
+ '(flycheck-python-pycompile-executable "python3")
+ '(flycheck-python-pylint-executable "python3")
+ '(ignored-local-variable-values '((org-fontify-quote-and-verse-blocks . 1)))
+ '(kind-icon-use-icons t)
+ '(lsp-clients-svlangserver-formatCommand "/tools/verible-verilog-format")
+ '(lsp-clients-svlangserver-launchConfiguration "/tools/verilator -sv --lint-only -Wall")
+ '(magit-todos-scanner nil)
+ '(org-agenda-files
+ '("/home/vaino/git/orgs/vke.org" "/home/vaino/git/aalto/README.org"
+ "/home/vaino/git/thesis/README.org"
+ "/home/vaino/git/elec_e2530_project/README.org"
+ "/home/vaino/git/orgs/main.org"))
+ '(package-selected-packages
+ '(all-the-icons avk-emacs-themes corfu-candidate-overlay dashboard
+ diff-hl dockerfile-mode doom-modeline ef-themes elpher
+ feature-mode flycheck-rust general glsl-mode go-mode
+ gscholar-bibtex haskell-mode helm-gtags helm-xref jinx jtsx
+ julia-mode kind-icon latex-extra lsp-java lsp-julia lsp-latex
+ lsp-ui magit-todos marginalia meson-mode micromamba mozc
+ olivetti orderless org-autolist outline-magic outshine
+ protobuf-mode px pyvenv rust-mode scala-mode texfrag
+ theme-changer verilog-ext vertico))
+ '(safe-local-variable-values
+ '((eval setq flycheck-clang-include-path
+ (list (expand-file-name "/usr/avr/include/")))
+ (python-shell-interpreter . "./pysph_env/bin/python")
+ (flycheck-python-flake8-executable
+ . "/home/vaino/git/sph/pysph_env/bin/python")
+ (flycheck-python-pylint-executable
+ . "/home/vaino/git/sph/pysph_env/bin/python")))
+ '(send-mail-function 'sendmail-send-it)
+ '(warning-suppress-types
+ '(((flycheck syntax-checker)) ((flycheck syntax-checker))
+ ((flycheck syntax-checker)) ((flycheck syntax-checker)))))
+
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(org-column ((t nil))))
+
+(put 'upcase-region 'disabled nil)
+
+;;; PSL tree-sitter mode
+(add-to-list 'load-path "~/.emacs.d/psl-ts-mode")
+(require 'psl-ts-mode)
+
+(provide '.emacs)
+;;; .emacs ends here
diff --git a/install.sh b/install.sh
new file mode 100755
index 0000000..8a25c20
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+# Deploy emacs.el from this repo as ~/.emacs.
+#
+# Uses a symlink instead of a copy, so ~/.emacs is ALWAYS the latest
+# version in this repo -- no reinstall needed after pulls or commits.
+# Bonus: edits made inside Emacs (e.g. M-x customize writing
+# custom-set-variables) land in this repo's working tree and show up
+# in `git diff`, ready to be committed.
+set -euo pipefail
+
+REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+SOURCE="$REPO_DIR/emacs.el"
+TARGET="$HOME/.emacs"
+BACKUP_DIR="$REPO_DIR/backups"
+
+if [ ! -f "$SOURCE" ]; then
+ echo "ERROR: $SOURCE not found" >&2
+ exit 1
+fi
+
+# Already installed?
+if [ "$(readlink "$TARGET" 2>/dev/null || true)" = "$SOURCE" ]; then
+ echo "~/.emacs already points at this repo. Nothing to do."
+ exit 0
+fi
+
+# Back up any existing config before replacing it
+if [ -e "$TARGET" ] || [ -L "$TARGET" ]; then
+ mkdir -p "$BACKUP_DIR"
+ BACKUP="$BACKUP_DIR/emacs-$(date +%Y%m%d-%H%M%S)"
+ mv "$TARGET" "$BACKUP"
+ echo "Backed up existing config to $BACKUP"
+fi
+
+ln -s "$SOURCE" "$TARGET"
+echo "Installed: ~/.emacs -> $SOURCE"