;; -*- lexical-binding: t; -*- (require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (require 'use-package) (require 'use-package-ensure) (require 'bind-key) ; If startup times are slow ; (setq use-package-verbose t) (add-to-list 'load-path (concat (file-name-parent-directory user-init-file) "local-lisp/")) (use-package emacs) (setq tab-bar-show nil) (setq inhibit-startup-message t) (setq initial-scratch-message nil) (setq ring-bell-function 'ignore) (add-hook 'window-setup-hook 'toggle-frame-maximized t) (defalias 'yes-or-no-p 'y-or-n-p) (setq make-backup-files nil) (setq custom-file (concat user-emacs-directory "custom.el")) (unless (file-exists-p custom-file) (make-empty-file custom-file)) (load custom-file) (scroll-bar-mode -1) (tool-bar-mode -1) (menu-bar-mode -1) (delete-selection-mode 1) (electric-pair-mode 1) (add-hook 'before-save-hook 'delete-trailing-whitespace) (setq reb-re-syntax 'string) (setq default-tab-width 4) (setq-default tab-width 4) (set-face-attribute 'default nil :height 160 :family "Berkeley Mono") (global-hl-line-mode 1) (setq use-package-always-ensure t) (setq mac-command-modifier 'control) (setq is-mac (string= system-type "darwin")) (setq-default cursor-type 'bar) (defun hgh/disable-bar-cursor () (blink-cursor-mode -1)) (defun hgh/enable-bar-cursor () (blink-cursor-mode 1)) (add-hook 'activate-mark-hook 'hgh/disable-bar-cursor) (add-hook 'deactivate-mark-hook 'hgh/enable-bar-cursor) (when is-mac (setq dired-use-ls-dired t insert-directory-program "gls" dired-listing-switches "-aBhl --group-directories-first")) ;; Add .asdf to exec-path (when (file-exists-p (file-truename "~/.asdf")) (setq env-changed t) (push (file-truename "~/.asdf/shims") exec-path) (push (file-truename "~/.asdf/bin") exec-path)) ;; Remove "/mnt/c/" for WSL PATH (setq exec-path (cl-remove-if (lambda (s) (and (< 5 (length s)) (string= (substring s 0 6) "/mnt/c") (setq env-changed t))) exec-path)) (when exec-path (setenv "PATH" (string-join exec-path ":"))) (defun hgh/visit-init-file () (interactive) (find-file user-init-file)) (defun hgh/project-ripgrep (regexp) (interactive (list (read-from-minibuffer "Search (regexp): " (thing-at-point 'symbol)))) (rg regexp "*" (project-root (project-current)))) (defun hgh/current-date-time () (interactive) (insert (format-time-string "%Y-%m-%d %H:%M:%S"))) (add-hook 'compilation-filter-hook 'ansi-color-compilation-filter) (defun hgh/next-error () (interactive) (if (eglot-managed-p) (flymake-goto-next-error) (next-error))) ;; key bindings (keymap-global-set "M-o" #'other-window) (keymap-global-set "M-i" #'imenu) (keymap-global-set "" #'compile) (keymap-global-set "C-c r r" #'revert-buffer) (keymap-global-set "C-c C-c" #'comment-or-uncomment-region) (keymap-global-set "M-]" #'forward-paragraph) (keymap-global-set "M-[" #'backward-paragraph) (keymap-global-set "C-h h" #'eldoc) (keymap-global-set "C-]" #'hgh/next-error) (keymap-global-set "C-c e i" #'hgh/visit-init-file) (keymap-global-set "C-c c" #'compile) (keymap-global-set "C-x C-b" #'ibuffer) (keymap-global-set "M-0" #'delete-window) (keymap-global-set "M-1" #'delete-other-windows) (keymap-global-set "M-2" #'split-window-below) (keymap-global-set "M-3" #'split-window-right) (require 'dired) (setq dired-dwim-target t) (keymap-set dired-mode-map "C-c C-c" #'wdired-change-to-wdired-mode) (load-theme 'modus-vivendi t) (use-package exec-path-from-shell :when is-mac :config (exec-path-from-shell-initialize)) (use-package man :when is-mac :custom (manual-program "gman")) (use-package magit :defer t) (use-package tree-sitter :mode ((" \\.tsx\\'" . tsx-ts-mode) (" \\.js\\'" . typescript-ts-mode) (" \\.mjs\\'" . typescript-ts-mode) (" \\.mts\\'" . typescript-ts-mode) (" \\.cjs\\'" . typescript-ts-mode) (" \\.ts\\'" . typescript-ts-mode) (" \\.jsx\\'" . tsx-ts-mode) (" \\.json\\'" . json-ts-mode)) :custom (treesit-extra-load-path '("~/repos/tree-sitter-module/dist"))) (use-package tree-sitter-langs :defer t) (use-package haskell-mode :defer t) (use-package company) (defun enable-parinfer () (let ((buf (or (buffer-file-name) (buffer-name) ""))) (when (and (not (s-contains? "sbcl" buf)) (not (s-contains? "ocicl" buf)) (not (string-prefix-p "*sly" buf))) (parinfer-rust-mode 1) (electric-quote-mode 1)))) (use-package parinfer-rust-mode :hook ((lisp-mode emacs-lisp-mode) . enable-parinfer) :config (setq parinfer-rust-disable-troublesome-modes t)) (use-package sly :defer t :custom (inferior-lisp-program "/opt/homebrew/bin/sbcl")) (use-package project :bind (("C-x p s" . hgh/project-ripgrep) ("C-x p S" . project-shell))) (use-package vertico :custom (vertico-cycle t) :config (vertico-mode 1)) (use-package savehist :init (savehist-mode)) (use-package marginalia :config (marginalia-mode 1)) (use-package orderless :init (setq completion-styles '(orderless basic) completion-category-overrides '((file (styles basic partial-completion))))) (use-package corfu :custom (corfu-auto t) (corfu-cycle t) :config (global-corfu-mode 1)) (use-package cape :init (add-to-list 'completion-at-point-functions #'cape-dabbrev)) (use-package browse-kill-ring :bind (("C-c y" . browse-kill-ring))) (defun hgh/org-mode-visual-fill () (setq visual-fill-column-width 120 visual-fill-column-center-text t) (visual-fill-column-mode 1)) (use-package visual-fill-column :hook (org-mode . hgh/org-mode-visual-fill)) (use-package eglot :hook ((clojure-mode . eglot-ensure) (go-mode . eglot-ensure) (rust-ts-mode . eglot-ensure) (typescript-ts-base-mode . eglot-ensure) (elixir-ts-mode . eglot-ensure) (heex-ts-mode . eglot-ensure) (java-ts-mode . eglot-ensure) (svelte-mode . eglot-ensure) (haskell-mode . eglot-ensure) (terraform-mode . eglot-ensure) (odin-mode . eglot-ensure)) :bind (:map eglot-mode-map ("C-c r" . eglot-rename) ("C-c a" . eglot-code-actions) ("C-c f" . eglot-format-buffer) ("C-c d" . xref-find-definitions)) :init (setq eglot-events-buffer-size 0) :config ;; Set up using clippy with rust analyzer (setf eglot-server-programs (cl-remove-if (lambda (c) (equal (car c) 'rust-mode)) eglot-server-programs)) (setf eglot-server-programs (append (list (list '(rust-ts-mode rust-mode) "rust-analyzer" :initializationOptions '(:checkOnSave (:command "clippy"))) '(svelte-mode "svelteserver" "--stdio") '(haskell-mode "haskell-language-server-wrapper" "--lsp")) eglot-server-programs))) (setenv "DOTNET_ROOT" "~/.local/share/mise/installs/dotnet/9") (push '("\\.csproj$" . xml-mode) auto-mode-alist) (push '("\\.vs$" . c-mode) auto-mode-alist) (push '("\\.fs$" . c-mode) auto-mode-alist) (push '("\\.sbclrc" . lisp-mode) auto-mode-alist) ;; paredit ; (autoload 'enable-paredit-mode "paredit" "Turn on pseudo-structural editing of Lisp code." t) (defun setup-paredit () (load (string-join (list user-emacs-directory "paredit.el"))) (setcdr paredit-mode-map nil) (define-key paredit-mode-map (kbd "M-'") #'paredit-forward-slurp-sexp) (define-key paredit-mode-map (kbd "M-;") #'paredit-backward-slurp-sexp) (define-key paredit-mode-map (kbd "M-\"") #'paredit-forward-barf-sexp) (define-key paredit-mode-map (kbd "M-:") #'paredit-backward-barf-sexp) (enable-paredit-mode)) (defvar lisp-mode-hooks nil) (setf lisp-mode-hooks '((emacs-lisp-mode-hook emacs-lisp-mode) (clojure-mode-hook clojure-mode) (lisp-mode-hook lisp-mode) (sly-mode-hook sly-mode))) (defun hgh/rg (search) (interactive "sSearch: ") (compilation-start (concat "rg --no-heading '" search "'") 'compilation-mode (lambda (s) (concat "*" (file-name-nondirectory (directory-file-name default-directory)) " rg*")))) (use-package multiple-cursors :init (add-hook 'multiple-cursors-mode-enabled-hook (lambda () (remove-hook 'activate-mark-hook 'hgh/disable-bar-cursor) (remove-hook 'deactivate-mark-hook 'hgh/disable-bar-cursor) (blink-cursor-mode 1))) (add-hook 'multiple-cursors-mode-disabled-hook (lambda () (add-hook 'activate-mark-hook 'hgh/disable-bar-cursor) (add-hook 'deactivate-mark-hook 'hgh/disable-bar-cursor) (blink-cursor-mode 1))) :config (global-set-key (kbd "C->") 'mc/mark-next-like-this) (global-set-key (kbd "C-<") 'mc/mark-previous-like-this)) (use-package yasnippet :diminish :defer t :config (yas-global-mode 1)) (use-package yasnippet-snippets :after (yasnippet)) (use-package markdown-mode :ensure t) ;; Run Prettier only in certain major-modes before saving: (defvar hgh/prettier-modes '(tsx-ts-mode typescript-ts-mode typescript-ts-base-mode json-ts-mode javascript-mode js2-mode typescript-mode web-mode) "List of major modes where Prettier should auto-run on save.") (defun hgh/run-prettier-if-appropriate () "Run Prettier on the buffer’s file if `major-mode` is in `my/prettier-modes`." (when (and (buffer-file-name) (member major-mode hgh/prettier-modes)) ;; call the prettier CLI; output errors to *Prettier Errors* buffer (call-process "prettier" nil "*Prettier Errors*" t "--write" (buffer-file-name)) ;; reload the buffer if prettier modified the file (revert-buffer :ignore-auto :noconfirm :preserve-modes))) (add-hook 'after-save-hook #'hgh/run-prettier-if-appropriate) (use-package terraform-mode) (use-package cider :defer t) (use-package org :defer t :custom (org-todo-keywords '((sequence "TODO" "INPROGRESS" "DONE"))) (org-support-shift-select t) (org-html-validation-link nil) (org-html-head-include-default-style nil) (org-html-head-include-scripts nil) (org-html-head "") :config (org-indent-mode) (require 'ox-publish) (org-babel-do-load-languages 'org-babel-load-languages '((shell . t))) (setq org-publish-use-timestamps-flag nil) (setq org-publish-project-alist (list (list "writings" :base-directory "~/Documents/writings/content" :publishing-directory "~/Documents/writings/public" :exclude "~/Documents/writings/notes" :recursive t :time-stamp-file nil :section-numbers nil :with-creator t :with-author nil)))) (use-package dumber-jump :init (add-hook 'xref-backend-functions #'dumber-jump-xref-activate)) (use-package flycheck) ; :init (global-flycheck-mode) (use-package idris-mode) (use-package htmlize) (use-package zig-mode) (use-package fsharp-mode) (use-package caddyfile-mode) (use-package dockerfile-mode) (use-package odin-mode :ensure nil) (use-package codex :ensure nil)