(require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (require 'use-package) (require 'use-package-ensure) (require 'bind-key) (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 "Monaco") (setq use-package-always-ensure t) (setq mac-command-modifier 'control) (setq is-mac (string= system-type "darwin")) (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)))) (ripgrep-regexp regexp (project-root (project-current)))) (add-hook 'compilation-filter-hook 'ansi-color-compilation-filter) ;; key bindings (keymap-global-set "M-o" #'other-window) (keymap-global-set "M-i" #'imenu) (keymap-global-set "C-M-." #'end-of-buffer) (keymap-global-set "C-M-," #'beginning-of-buffer) (keymap-global-set "C-." #'xref-find-definitions) (keymap-global-set "C-," #'xref-go-back) (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-]" #'flymake-goto-next-error) (keymap-global-set "C-c e i" #'hgh/visit-init-file) (keymap-global-set "C-c c" #'compile) (require 'dired) (keymap-set dired-mode-map "C-c C-c" #'wdired-change-to-wdired-mode) (load-theme 'modus-vivendi-tinted t) (use-package exec-path-from-shell :when is-mac :config (exec-path-from-shell-initialize)) (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) (use-package haskell-mode) (use-package company) (use-package sly :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 browse-kill-ring :bind (("C-c y" . browse-kill-ring))) (defun hgh/org-mode-setup () (org-indent-mode) (visual-line-mode 1)) (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)) :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 (cons (list '(rust-ts-mode rust-mode) "rust-analyzer" :initializationOptions '(:checkOnSave (:command "clippy"))) eglot-server-programs)) (setf eglot-server-programs (cons '(svelte-mode "svelteserver" "--stdio") eglot-server-programs)) (setf eglot-server-programs (cons '(haskell-mode "haskell-language-server-wrapper" "--lsp") eglot-server-programs))) ;; 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)) (setq 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))) (add-hook 'lisp-mode-hook (lambda () (set (make-local-variable 'lisp-indent-function) 'common-lisp-indent-function) (setup-paredit))) (use-package multiple-cursors :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) (use-package aider :custom (aider-args '("--model" "o4-mini" "--no-auto-accept-architect")) :bind ("C-c a" . #'aider-transient-menu) :config (setenv "OPENAI_API_KEY" "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")) ;; 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) (use-package org :custom (org-todo-keywords '((sequence "TODO" "INPROGRESS" "DONE"))))