Created
August 1, 2025 16:29
-
-
Save vinikira/ecdf3427a6fd4e41dbbb749d01060ae5 to your computer and use it in GitHub Desktop.
Minimal Emacs config (30.1). No dependencies, ready to go!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;;; early-init.el --- Early init file -*- lexical-binding: t -*- | |
| ;;; Commentary: | |
| ;;; Code: | |
| (let ((gc-cp gc-cons-percentage) | |
| (fha file-name-handler-alist)) | |
| (add-hook 'after-init-hook | |
| (lambda () | |
| (setopt gc-cons-threshold (* 2 1000 1000) ;; 2MB | |
| gc-cons-percentage gc-cp | |
| file-name-handler-alist fha)))) | |
| (setq load-prefer-newer noninteractive | |
| initial-major-mode 'fundamental-mode | |
| initial-scratch-message nil | |
| inhibit-startup-echo-area-message user-login-name | |
| native-comp-async-report-warnings-errors nil | |
| native-comp-jit-compilation t | |
| gc-cons-threshold most-positive-fixnum | |
| gc-cons-percentage 0.8 | |
| file-name-handler-alist nil | |
| frame-resize-pixelwise t | |
| frame-inhibit-implied-resize t | |
| use-dialog-box t | |
| use-file-dialog nil | |
| inhibit-splash-screen t | |
| inhibit-startup-screen t | |
| inhibit-x-resources t | |
| inhibit-startup-buffer-menu t | |
| frame-inhibit-implied-resize t) | |
| (dolist (var '(default-frame-alist initial-frame-alist)) | |
| (push '(scroll-bar . 0) var) | |
| (push '(menu-bar-lines . 0) var) | |
| (push '(tool-bar-lines . 0) var) | |
| (push '(vertical-scroll-bars . nil) var) | |
| (push '(scroll-bar-width . 12) var)) | |
| (menu-bar-mode -1) | |
| (tool-bar-mode -1) | |
| ;;; early-init.el ends here |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;;; init.el --- Emacs configuration -*- lexical-binding: t -*- | |
| ;;; Commentary: | |
| ;;; Code: | |
| (use-package emacs | |
| :ensure nil | |
| :custom | |
| (confirm-kill-emacs 'y-or-n-p) | |
| (modus-themes-italic-constructs t) | |
| (modus-themes-bold-constructs t) | |
| (modus-themes-mixed-fonts t) | |
| (custom-file (expand-file-name "custom.el" user-emacs-directory)) | |
| (exec-path (append | |
| exec-path | |
| `("/usr/local/bin/" | |
| ,(expand-file-name "~/.local/bin") | |
| ,(expand-file-name "~/.asdf/shims")))) | |
| :hook | |
| (before-save . #'delete-trailing-whitespace) | |
| (text-mode . (lambda () | |
| (setq-local show-trailing-whitespace t) | |
| (auto-fill-mode 1) | |
| (display-line-numbers-mode 1) | |
| (hl-line-mode 1))) | |
| (after-init-hook . (lambda () | |
| (global-auto-revert-mode 1) | |
| (show-paren-mode 1) | |
| (column-number-mode 1) | |
| (winner-mode 1) | |
| (global-so-long-mode 1) | |
| (savehist-mode 1) | |
| (recentf-mode 1) | |
| (pixel-scroll-precision-mode 1) | |
| (electric-pair-mode t) | |
| (blink-cursor-mode -1) | |
| (load-theme 'modus-vivendi-tinted t) | |
| (load custom-file t t) | |
| (fset 'yes-or-no-p 'y-or-n-p) | |
| (let* ((font "Iosevka Nerd Font Mono") | |
| (font-with-size (format "%s-16" font))) | |
| (when (member font (font-family-list)) | |
| (set-frame-font font-with-size t t))))) | |
| :bind | |
| ("C-x C-b" . #'ibuffer) | |
| ("M-D" . #'duplicate-dwim) | |
| ("M-u" . #'upcase-dwim) | |
| ("M-l" . #'downcase-dwim) | |
| ("M-c" . #'capitalize-dwim) | |
| :config | |
| (when (eq system-type 'darwin) | |
| (setopt mac-command-modifier 'meta | |
| mac-option-modifier 'hyper)) | |
| (with-current-buffer "*scratch*" | |
| (emacs-lock-mode 'kill)) | |
| (when (and (fboundp 'server-running-p) | |
| (not (server-running-p))) | |
| (server-start)) | |
| (defun vs/--setup-theme () | |
| "Configure theme." | |
| (load-theme 'modus-vivendi-tinted t)) | |
| (if (daemonp) | |
| (add-hook 'server-after-make-frame-hook 'vs/--setup-theme))) | |
| (use-package compile | |
| :ensure nil | |
| :commands (compile) | |
| :bind | |
| (("C-x c" . (lambda () | |
| (interactive) | |
| (let ((current-prefix-arg '(4))) | |
| (call-interactively 'project-compile))))) | |
| :custom | |
| (compilation-scroll-output t) | |
| :hook | |
| (compilation-filter . ansi-color-compilation-filter)) | |
| (use-package dired | |
| :ensure nil | |
| :commands (dired) | |
| :custom | |
| (dired-mouse-drag-files t) | |
| (mouse-drag-and-drop-region-cross-program t) | |
| (dired-listing-switches "-alh") | |
| (delete-by-moving-to-trash t) | |
| (dired-dwim-target t) | |
| (dired-guess-shell-alist-user | |
| '(("\\.\\(png\\|jpe?g\\|tiff\\)" "feh" "xdg-open" "open") | |
| ("\\.\\(mp[34]\\|m4a\\|ogg\\|flac\\|webm\\|mkv\\)" "mpv" "xdg-open" "open") | |
| (".*" "xdg-open" "open"))) | |
| :hook | |
| (window-setup . | |
| (lambda () | |
| (put 'dired-find-alternate-file 'disabled nil))) | |
| :bind | |
| (:map dired-mode-map | |
| ("e" . dired-create-empty-file) | |
| ("RET" . dired-find-alternate-file))) | |
| (use-package flymake | |
| :ensure nil | |
| :hook (prog-mode . flymake-mode) | |
| :bind (:map flymake-mode-map | |
| ("C-c ! n" . flymake-goto-next-error) | |
| ("C-c ! p" . flymake-goto-prev-error) | |
| ("C-c ! L" . flymake-show-project-diagnostics) | |
| ("C-c ! l" . flymake-show-buffer-diagnostics))) | |
| (use-package flyspell | |
| :ensure nil | |
| :commands (flyspell-mode) | |
| :bind (:map flyspell-mode-map | |
| ("C-;" . nil) | |
| ("<f12>" . flyspell-auto-correct-previous-word))) | |
| (use-package project | |
| :ensure nil | |
| :custom ((project-compilation-buffer-name-function | |
| 'project-prefixed-buffer-name)) | |
| :config | |
| (fset 'project-shell 'vs/vterm-in-project)) | |
| (use-package grep | |
| :ensure nil | |
| :defer t | |
| :config | |
| (when (executable-find "rg") | |
| (setf (nth 0 grep-files-aliases) '("all" . "*.*")) | |
| (grep-apply-setting | |
| 'grep-template | |
| "rg --no-heading -H -uu -g '<F>' <R> <D>"))) | |
| (use-package xref | |
| :ensure nil | |
| :defer t | |
| :custom ((xref-search-program 'ripgrep))) | |
| (use-package tempo | |
| :ensure nil | |
| :commands (tempo-forward-mark | |
| tempo-backward-mark | |
| tempo-complete-tag | |
| vs/insert-tempo-template) | |
| :custom ((tempo-interactive t)) | |
| :bind | |
| (("M-]" . tempo-forward-mark) | |
| ("M-[" . tempo-backward-mark) | |
| ("S-<tab>" . tempo-complete-tag) | |
| ("C-c I" . vs/insert-tempo-template)) | |
| :init | |
| (defun vs/insert-tempo-template () | |
| "Reads a template from a completion list and call it. | |
| Based on https://www.n16f.net/blog/templating-in-emacs-with-tempo/." | |
| (interactive) | |
| (let* ((tags-data | |
| (mapcar (lambda (entry) | |
| (let ((function (cdr entry))) | |
| (list function (documentation function)))) | |
| (tempo-build-collection))) | |
| (completion-extra-properties | |
| `(:annotation-function | |
| (lambda (string) | |
| (let* ((data (alist-get string minibuffer-completion-table | |
| nil nil #'string=)) | |
| (description (car data))) | |
| (format " %s" description))))) | |
| (function-name (completing-read "Template: " tags-data)) | |
| (function (intern function-name))) | |
| (funcall function)))) | |
| (use-package tab-bar | |
| :ensure nil | |
| :defer t | |
| :custom | |
| (tab-bar-new-tab-choice "*scratch*") | |
| (tab-bar-tab-name-function 'tab-bar-tab-name-current) | |
| (tab-bar-close-button-show nil) | |
| (tab-bar-new-button-show nil) | |
| (tab-bar-auto-width nil) | |
| (tab-bar-separator " ") | |
| (tab-bar-format | |
| '(tab-bar-format-tabs-groups | |
| tab-bar-separator | |
| tab-bar-format-add-tab)) | |
| (tab-bar-tab-group-format-function | |
| (lambda (tab _i &optional current-p) | |
| (propertize | |
| (concat (funcall tab-bar-tab-group-function tab)) | |
| 'face (if current-p 'tab-bar-tab-group-current 'tab-bar-tab-group-inactive)))) | |
| :init | |
| (defun vs/tab-group-from-project () | |
| "Call `tab-group` with the current project name as the group." | |
| (interactive) | |
| (call-interactively #'tab-new) | |
| (call-interactively #'project-switch-project) | |
| (when-let* ((proj (project-current)) | |
| (name (project-name proj))) | |
| (tab-group (format "[%s]" name)))) | |
| (defun vs/close-project-tab () | |
| "Closes the current project tab." | |
| (interactive) | |
| (unless (project-current) | |
| (user-error "The current tab has no open projects")) | |
| (project-kill-buffers) | |
| (when (> (length (tab-bar-tabs)) 1) | |
| (tab-bar-close-tab))) | |
| :bind | |
| ("C-x t P" . vs/tab-group-from-project) | |
| ("C-x t g" . vs/tab-switch-to-group) | |
| ("C-x p K" . vs/close-project-tab)) | |
| (use-package prog-mode | |
| :ensure nil | |
| :hook | |
| (prog-mode . flyspell-prog-mode) | |
| (prog-mode . subword-mode) | |
| (prog-mode . prettify-symbols-mode) | |
| (prog-mode . display-line-numbers-mode) | |
| (prog-mode . hl-line-mode)) | |
| (use-package eglot | |
| :ensure nil | |
| :bind | |
| (:map eglot-mode-map | |
| ("C-c e a" . eglot-code-actions) | |
| ("C-c e f" . eglot-format) | |
| ("C-c e r" . eglot-rename) | |
| ("C-c e R" . eglot-reconnect) | |
| ("C-c e o" . eglot-code-action-organize-imports) | |
| ("C-c e D" . eglot-find-declaration) | |
| ("C-c e i" . eglot-find-implementation) | |
| ("C-c e d" . eglot-find-typeDefinition) | |
| ("C-c e h" . eldoc)) | |
| :custom | |
| (eglot-autoshutdown t)) | |
| (use-package minibuffer | |
| :hook (after-init . minibuffer-depth-indicate-mode) | |
| :custom | |
| (enable-recursive-minibuffers t) | |
| (read-file-name-completion-ignore-case t) | |
| (read-buffer-completion-ignore-case t)) | |
| (use-package icomplete | |
| :demand t | |
| :custom | |
| (completion-styles '(partial-completion substring)) | |
| (completion-category-overrides '((file (styles basic substring)))) | |
| (completions-format 'one-column) | |
| (completions-sort 'historical) | |
| (completions-max-height 20) | |
| (completion-ignore-case t) | |
| (tab-always-indent 'complete) | |
| (icomplete-delay-completions-threshold 0) | |
| (icomplete-compute-delay 0) | |
| (icomplete-show-matches-on-no-input t) | |
| (icomplete-prospects-height 10) | |
| (icomplete-with-completion-tables t) | |
| (icomplete-in-buffer t) | |
| (icomplete-max-delay-chars 0) | |
| (icomplete-scroll t) | |
| :config | |
| (advice-add 'completion-at-point | |
| :after #'minibuffer-hide-completions) | |
| (fido-mode -1) | |
| (icomplete-mode) | |
| (icomplete-vertical-mode) | |
| :bind (:map icomplete-minibuffer-map | |
| ("TAB" . icomplete-force-complete) | |
| ("C-n" . icomplete-forward-completions) | |
| ("C-p" . icomplete-backward-completions) | |
| ("C-v" . icomplete-vertical-toggle))) | |
| (use-package treesit | |
| :defer t | |
| :init | |
| (setq treesit-language-source-alist | |
| '((clojure . ("https://github.com/sogaiu/tree-sitter-clojure")) | |
| (elisp . ("https://github.com/Wilfred/tree-sitter-elisp")) | |
| (html . ("https://github.com/tree-sitter/tree-sitter-html")) | |
| (javascript . (("https://github.com/tree-sitter/tree-sitter-javascript" "master" "src"))) | |
| (json . ("https://github.com/tree-sitter/tree-sitter-json")) | |
| (haskell . ("https://github.com/tree-sitter/haskell-tree-sitter")) | |
| (markdown . ("https://github.com/ikatyang/tree-sitter-markdown")) | |
| (python . ("https://github.com/tree-sitter/tree-sitter-python")) | |
| (java . ("https://github.com/serenadeai/java-tree-sitterl")) | |
| (elixir . ("https://github.com/elixir-lang/tree-sitter-elixir")) | |
| (heex . ("https://github.com/phoenixframework/tree-sitter-heex")) | |
| (docker . ("https://github.com/camdencheek/tree-sitter-dockerfile")) | |
| (bash . ("https://github.com/tree-sitter/tree-sitter-bash")) | |
| (c . ("https://github.com/tree-sitter/tree-sitter-c")) | |
| (cmake . ("https://github.com/uyha/tree-sitter-cmake")) | |
| (common-lisp . ("https://github.com/theHamsta/tree-sitter-commonlisp")) | |
| (cpp . ("https://github.com/tree-sitter/tree-sitter-cpp")) | |
| (css . ("https://github.com/tree-sitter/tree-sitter-css")) | |
| (csharp . ("https://github.com/tree-sitter/tree-sitter-c-sharp")) | |
| (go . ("https://github.com/tree-sitter/tree-sitter-go")) | |
| (go-mod . ("https://github.com/camdencheek/tree-sitter-go-mod")) | |
| (html . ("https://github.com/tree-sitter/tree-sitter-html")) | |
| (lua . ("https://github.com/Azganoth/tree-sitter-lua")) | |
| (make . ("https://github.com/alemuller/tree-sitter-make")) | |
| (markdown . ("https://github.com/ikatyang/tree-sitter-markdown")) | |
| (python . ("https://github.com/tree-sitter/tree-sitter-python")) | |
| (rust . ("https://github.com/tree-sitter/tree-sitter-rust")) | |
| (toml . ("https://github.com/tree-sitter/tree-sitter-toml")) | |
| (tsx . (("https://github.com/tree-sitter/tree-sitter-typescript") ("master") ("tsx/src"))) | |
| (typescript . (("https://github.com/tree-sitter/tree-sitter-typescript") ("master") ("typescript/src"))) | |
| (yaml . ("https://github.com/ikatyang/tree-sitter-yaml"))))) | |
| (use-package elixir-ts-mode | |
| :mode ("\\.elixir\\'" "\\.ex\\'" "\\.exs\\'" "mix\\.lock") | |
| :custom (prettify-symbols-alist . '((">=" . ?\u2265) | |
| ("<=" . ?\u2264) | |
| ("!=" . ?\u2260) | |
| ("==" . ?\u2A75) | |
| ("=~" . ?\u2245) | |
| ("<-" . ?\u2190) | |
| ("->" . ?\u2192) | |
| ("|>" . ?\u25B7))) | |
| :config | |
| (unless (treesit-language-available-p 'elixir) | |
| (treesit-install-language-grammar 'elixir)) | |
| (unless (treesit-language-available-p 'heex) | |
| (treesit-install-language-grammar 'heex))) | |
| (use-package dockerfile-ts-mode | |
| :mode (("\\Dockerfile\\'" . dockerfile-ts-mode) | |
| ("\\.dockerignore\\'" . dockerfile-ts-mode)) | |
| :config | |
| (unless (treesit-language-available-p 'docker) | |
| (treesit-install-language-grammar 'docker))) | |
| (use-package typescript-ts-mode | |
| :mode "\\.tsx?\\'" | |
| :config | |
| (unless (treesit-language-available-p 'typescript) | |
| (treesit-install-language-grammar 'typescript)) | |
| (unless (treesit-language-available-p 'tsx) | |
| (treesit-install-language-grammar 'tsx))) | |
| (use-package javascript-ts-mode | |
| :mode "\\.jsx?\\'" | |
| :config | |
| (unless (treesit-language-available-p 'javascript) | |
| (treesit-install-language-grammar 'javascript))) | |
| (use-package yaml-ts-mode | |
| :mode "\\.ya?ml\\'" | |
| :config | |
| (unless (treesit-language-available-p 'yaml) | |
| (treesit-install-language-grammar 'yaml))) | |
| (use-package json-ts-mode | |
| :mode "\\.json\\'" | |
| :config | |
| (unless (treesit-language-available-p 'json) | |
| (treesit-install-language-grammar 'json))) | |
| ;;; init.el ends here |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment