;;; -*- lexical-binding: t -*- ;; Time-stamp: <2026-08-27 14h00 BST (82909977)> ;; ----------------------------------------------------------------------------- ;; General setup ;; Always split horizontally when compiling ;; (defadvice compile (around split-horizontally activate) ;; (let ((split-width-threshold 0) ;; (split-height-threshold nil)) ;; ad-do-it)) ;; Resize to fill column (and a little bit) ;; (defadvice compile (after resize-window-properly activate) ;; (let ((ww (window-width))) ;; (when (< ww (+ 5 fill-column)) ;; (enlarge-window-horizontally (- (+ 5 fill-column) ww))))) (defun align-to-equals (begin end) "Align region to equal signs" (interactive "r") (align-regexp begin end "\\(\\s-*\\)=" 1 1 )) (use-package eglot :defer :config (add-to-list 'eglot-server-programs '(bqn-mode . ("bqnlsp"))) (add-to-list 'eglot-server-programs '(python-ts-mode . ("basedpyright-langserver" "--stdio"))) (add-to-list 'eglot-server-programs '((typescript-ts-mode tsx-ts-mode) . ("typescript-language-server" "--stdio"))) ) (setopt treesit-auto-install-grammar 'ask treesit-enabled-modes '(python-ts-mode typescript-ts-mode tsx-ts-mode json-ts-mode toml-ts-mode)) (use-package centered-window :defer :ensure) (use-package treesit-fold :ensure t :demand t :bind (:map treesit-fold-mode-map ("C-^" . treesit-fold-toggle)) :config (global-treesit-fold-mode)) (use-package dtrt-indent :ensure :defer :config (dtrt-indent-global-mode t)) (use-package eat :ensure :defer) (defun programming-setup () (interactive) (setq line-spacing 6) (spell-fu-mode -1) (subword-mode 1) (electric-pair-local-mode) (set-fill-column 80) (display-line-numbers-mode 1) (visual-line-mode 1) (when (not (eq major-mode 'python-ts-mode)) (keymap-set (current-local-map) "M-/" 'completion-at-point)) ) (add-hook 'prog-mode-hook #'programming-setup) ;; ----------------------------------------------------------------------------- ;; Specific packages (use-package comment-dwim-2 :ensure :defer :bind (("M-;" . comment-dwim-2)) :config (setq comment-multi-line t comment-style 'extra-line)) (use-package aggressive-indent :ensure :defer :config (setq aggressive-indent-sit-for-time 1)) (use-package elec-pair :defer :config (setq electric-pair-delete-adjacent-pairs t electric-pair-skip-self 'electric-pair-default-skip-self electric-pair-preserve-balance t electric-pair-skip-whitespace t electric-pair-inhibit-predicate 'electric-pair-default-inhibit)) ;; ----------------------------------------------------------------------------- ;; C (use-package clang-format :ensure :defer :config (setq clang-format-style "file")) (use-package cc-mode :defer :bind (:map c-mode-map ("M-m" . lh-matching-delim)) :hook ((c-mode c++-mode) . (lambda () (auto-fill-mode) (aggressive-indent-mode) (set-fill-column 80) (abbrev-mode 0) (eglot-ensure) ;; clangd seems pretty good! (c-toggle-hungry-state 1) (c-toggle-electric-state 1) (c-toggle-syntactic-indentation 1))) :config (c-add-style "gnu-mod" '("gnu" (c-basic-offset . 2) ; Guessed value (c-offsets-alist (block-close . 0) ; Guessed value (case-label . +) ; Guessed value (defun-block-intro . +) ; Guessed value (defun-close . 0) ; Guessed value (statement . 0) ; Guessed value (statement-block-intro . +) ; Guessed value (statement-case-intro . 0) ; Guessed value (substatement . +) ; Guessed value (topmost-intro . 0) ; Guessed value (access-label . -) (annotation-top-cont . 0) (annotation-var-cont . +) (arglist-close . c-lineup-close-paren) (arglist-cont c-lineup-gcc-asm-reg 0) (arglist-cont-nonempty . c-lineup-arglist) (arglist-intro . +) (block-open . 0) (brace-entry-open . 0) (brace-list-close . 0) (brace-list-entry . 0) (brace-list-intro . +) (brace-list-open . 0) (c . c-lineup-C-comments) (catch-clause . 0) (class-close . 0) (class-open . 0) (comment-intro . c-lineup-comment) (composition-close . 0) (composition-open . 0) (cpp-define-intro c-lineup-cpp-define +) (cpp-macro . -1000) (cpp-macro-cont . +) (defun-open . 0) (do-while-closure . 0) (else-clause . 0) (extern-lang-close . 0) (extern-lang-open . 0) (friend . 0) (func-decl-cont . +) (inclass . +) (incomposition . +) (inexpr-class . +) (inexpr-statement . +) (inextern-lang . +) (inher-cont . c-lineup-multi-inher) (inher-intro . +) (inlambda . 0) (inline-close . 0) (inline-open . +) (inmodule . +) (innamespace . +) (knr-argdecl . 0) (knr-argdecl-intro . +) (label . 2) (lambda-intro-cont . +) (member-init-cont . c-lineup-multi-inher) (member-init-intro . +) (module-close . 0) (module-open . 0) (namespace-close . 0) (namespace-open . 0) (objc-method-args-cont . c-lineup-ObjC-method-args) (objc-method-call-cont c-lineup-ObjC-method-call-colons c-lineup-ObjC-method-call +) (objc-method-intro . [0]) (statement-case-open . 0) (statement-cont . +) (stream-op . c-lineup-streamop) (string . -1000) (substatement-label . 2) (substatement-open . +) (template-args-cont c-lineup-template-args +) (topmost-intro-cont . c-lineup-topmost-intro-cont)))) (setq c-default-style '((java-mode . "java") (awk-mode . "awk") (other . "gnu-mod")))) ;; ----------------------------------------------------------------------------- ;; Python (use-package reformatter :ensure) (reformatter-define ruff-fix :program "ruff" :args (list "check" "--fix" input-file) :stdout nil :stdin nil) (reformatter-define ruff-format :program "ruff" :args (list "format" input-file) :stdout nil :stdin nil) (use-package highlight-indent-guides :ensure :defer :config (setq highlight-indent-guides-auto-odd-face-perc 3 highlight-indent-guides-auto-even-face-perc 5)) (use-package python :hook (python-ts-mode . (lambda () (require 'highlight-indent-guides) (highlight-indent-guides-mode t) (ruff-format-on-save-mode) (ruff-fix-on-save-mode) (eglot-ensure) (visual-line-mode))) :bind (:map python-ts-mode-map ("C-c C-f" . nil) ("M-/" . hippie-expand))) ;; ----------------------------------------------------------------------------- ;; Rust (use-package cargo :ensure :defer) (use-package rust-mode :ensure :defer :init (setq rust-mode-treesitter-derive t) :bind (:map rust-mode-map ("C-c l b" . lh-backward-delim) ("C-c l f" . lh-forward-delim) ("C-c l m" . lh-matching-delim) ("M-p" . beginning-of-defun) ("M-n" . end-of-defun) ("C-c r c" . rust-compile) ("C-c r r" . rust-run)) :hook (rust-mode . (lambda () (cargo-minor-mode) ;; Pair {} in rust format strings ... ? (setq-local electric-pair-text-pairs (cons '(?{ . ?}) electric-pair-pairs)) (eglot-ensure))) :config (setq rust-indent-offset 4 rust-indent-method-chain t rust-indent-where-clause t rust-format-on-save t rust-rustfmt-switches '("--edition" "2024"))) ;; ------------------------------------------------------------------- ;; Misc languages (use-package json-ts-mode :ensure :defer :hook (json-ts-mode . (lambda () (programming-setup) (setq standard-indent 2) (setq js-indent-level 2) (setq tab-width 2 indent-tabs-mode nil))) :bind (:map json-ts-mode-map ("C-c C-f" . nil))) (reformatter-define oxfmt :program "pnpm" :args (list "exec" "oxfmt" "--stdin-filepath" (or buffer-file-name (buffer-name)))) (defun my-jtsx-setup () (eglot-ensure) (programming-setup) (oxfmt-on-save-mode 1)) (use-package jtsx :ensure t :defer t :mode (("\\.jsx?\\'" . jtsx-jsx-mode) ("\\.tsx\\'" . jtsx-tsx-mode) ("\\.ts\\'" . jtsx-typescript-mode)) :commands jtsx-install-treesit-language :hook ((jtsx-jsx-mode . my-jtsx-setup) (jtsx-tsx-mode . my-jtsx-setup) (jtsx-typescript-mode . my-jtsx-setup))) (use-package lua-mode :ensure :defer) (use-package zig-mode :ensure t :defer :hook (zig-mode . (lambda () (eglot-ensure))) :init (defun my-zig-run () (interactive) (zig--run-cmd "build run")) :bind (:map zig-mode-map ("C-c l b" . lh-backward-delim) ("C-c l f" . lh-forward-delim) ("C-c l m" . lh-matching-delim) ("M-p" . beginning-of-defun) ("M-n" . end-of-defun) ("C-c C-c" . zig-compile) ("C-c r" . zig-run) ("C-c C-r" . my-zig-run)) :config (setq zig-ts-mode-hook zig-mode-hook)) (use-package uiua-ts-mode :ensure :defer) (use-package bqn-mode :ensure :defer :bind (:map bqn-mode-map ("M-TAB" . expand-abbrev) ("C-c r r" . bqn-comint-eval-dwim) ("C-c r b" . bqn-comint-eval-buffer)) :hook (bqn-mode . (lambda () (eglot-ensure) (abbrev-mode) (bqn-comint-buffer))) :config (require 'bqn-keymap-mode) (require 'bqn-glyph-mode) (setq save-abbrevs 'silently) (define-abbrev-table 'bqn-mode-abbrev-table '( ;; funtions ("abs" "│") ("assert" "!") ("ceiling" "⌈") ("classify" "⊐") ("conj" "∧") ("couple" "≍") ("deduplicate" "⍷") ("depth" "≡") ("deshape" "⥊") ("dgrade" "⍒") ("disj" "∨") ("divide" "÷") ("drop" "↓") ("dsort" "∧") ("enlist" "⋈") ("find" "⍷") ("floor" "⌊") ("group" "⊔") ("gt" ">") ("gte" "≥") ("indices" "/") ("join" "∾") ("left" "⊣") ("length" "≠") ("lshift" "«") ("lt" "<") ("lte" "≤") ("match" "≡") ("maximum" "⌈") ("member" "∊") ("minimum" "⌊") ("minus" "¯") ("modulus" "│") ("multiply" "×") ("neg" "¬") ("neq" "≠") ("nmatch" "≢") ("occurrence" "⊒") ("pair" "⋈") ("pick" "⊑") ("power" "⋆") ("prefix" "↑") ("range" "↕") ("recip" "÷") ("replicate" "/") ("reshape" "⥊") ("reverse" "⌽") ("right" "⊢") ("root" "√") ("rshift" "»") ("select" "⊏") ("shape" "≢") ("sign" "×") ("solo" "≍") ("span" "¬") ("sqrt" "√") ("suffix" "↓") ("take" "↑") ("transpose" "⍉") ("ugrade" "⍋") ("usort" "∨") ;; combinators ("atop" "∘") ("catch" "⎊") ("choose" "◶") ("constant" "˙") ("lhook" "⊸") ("over" "○") ("rhook" "⟜") ("self" "˜") ("swap" "˜") ("under" "⌾") ("valence" "⊘") ;; 1-modifiers ("cell" "˘") ("each" "¨") ("fold" "´") ("insert" "˝") ("scan" "`") ("table" "⌜") ("undo" "⁼") ;; 2-modifiers ("depth" "⚇") ("rank" "⎉") ("repeat" "⍟") ;; syntax ("define" "←") ("export" "⇐") ("change" "↩") ("nothing" "·") ("sep" "⋄") ;; constants ("pi" "π") ("infty" "∞") )))