See Early Init File on Emacs manual.
;;; early-init.el --- Early Init File -*- lexical-binding: t -*-
;; Do not resize the frame at this early stage.
(setq frame-inhibit-implied-resize t)
;; Increase the garbage collector threshold
(setq gc-cons-threshold most-positive-fixnum)
;; Disable some stuff
(setq inhibit-startup-screen t
inhibit-startup-message t
inhibit-startup-buffer-menu t
use-file-dialog nil
visual-bell t)
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(blink-cursor-mode -1)
(fset 'yes-or-no-p 'y-or-n-p)
;; Speed up startup
;; Temporarily increase the garbage collection threshold to speed up the startup
;; time.
(setq gc-cons-threshold most-positive-fixnum)
(defvar my/emacs-gc-cons-threshold (* 16 1024 1024)
"The value of `gc-cons-threshold' after Emacs startup.")
;; Same idea as above for ~file-name-handler-alist~
(defvar tmp--file-name-handler-alist file-name-handler-alist)
(setq file-name-handler-alist nil)
;; Restore everything at the end
(add-hook 'emacs-startup-hook
(lambda ()
(setq gc-cons-threshold my/emacs-gc-cons-threshold
file-name-handler-alist tmp--file-name-handler-alist)))
;; Measure the startup time.
(add-hook 'emacs-startup-hook
(lambda ()
(message "*** Emacs loaded in %s seconds with %d garbage collections."
(emacs-init-time "%.2f")
gcs-done)));;; init.el --- Emacs configuration -*- lexical-binding: t -*-(require 'epa-file)
(epa-file-enable)
(load-file (locate-user-emacs-file "personal.el.gpg"))
(require 'personal)
(require 'plstore)
(setq plstore-cache-passphrase-for-symmetric-encryption t)
(add-to-list 'plstore-encrypt-to my/gpg-key)Store custom.el in a separate file
(setq custom-file (locate-user-emacs-file "custom.el"))
(load custom-file :no-error-if-file-is-missing)(add-hook 'emacs-startup-hook 'toggle-frame-maximized)Native compilation tweaks.
;; Silence compiler warnings as they can be pretty disruptive
(setq native-comp-async-report-warnings-errors nil
byte-compile-warnings nil)Just good old use-package and vc-use-package:
(require 'package)
(setq package-vc-register-as-project nil) ; Emacs 30
(add-hook 'package-menu-mode-hook #'hl-line-mode)
(add-to-list 'package-archives
'("gnu-devel" . "https://elpa.gnu.org/devel/"))
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/"))
(require 'use-package-ensure)
(setq use-package-always-ensure t)
(setq package-check-signature nil)Enable benchmarking only when needed.
(use-package benchmark-init
:disabled t
:config
(add-hook 'after-init-hook 'benchmark-init/deactivate))Use no-littering to keep our directory clean.
;; Keep .emacs.d clean
(unless (package-installed-p 'no-littering)
(package-install 'no-littering))
(use-package no-littering
:config
(setq create-lockfiles nil
delete-old-versions t
kept-new-versions 6
kept-old-versions 2
version-control t)
;; Store backups and autosaves files in /tmp.
(setq backup-directory-alist
`((".*" . ,(no-littering-expand-var-file-name "backup/")))
auto-save-file-name-transforms
`((".*" ,(no-littering-expand-var-file-name "auto-save/") t))))(add-to-list 'display-buffer-alist
'("\\`\\*\\(Warnings\\|Compile-Log\\)\\*\\'"
(display-buffer-no-window)
(allow-no-window . t)))Ensure environment variables inside Emacs look the same as in the userβs shell.
(use-package exec-path-from-shell
:config
(dolist (var '("SSH_AUTH_SOCK" "SSH_AGENT_PID" "GPG_AGENT_INFO" "LANG" "LC_CTYPE" "NPM_CONFIG_PREFIX"))
(add-to-list 'exec-path-from-shell-variables var))
(exec-path-from-shell-initialize))(use-package savehist
:ensure nil
:init
(savehist-mode t)
:config
(setq history-length 10000
history-delete-duplicates t
savehist-save-minibuffer-history t
savehist-additional-variables '(kill-ring
search-ring
regexp-search-ring)))Automatically reload changes on a file if needed.
(use-package autorevert
:ensure nil
:config
(setq global-auto-revert-non-file-buffers t
auto-revert-use-notify nil)
(global-auto-revert-mode t))Save recent files
(use-package recentf
:ensure nil
:config
(setq recentf-max-saved-items 50
recentf-max-menu-items 15))I donβt like to hide Emacs.
(global-unset-key (kbd "C-z"))Use emacs-lisp-mode instead of lisp-interaction-mode for scratch buffer.
(setq initial-major-mode 'emacs-lisp-mode
initial-scratch-message ";; Remember why you're doing it.\n\n")Move deleted files to trash, you never knowβ¦
(setq delete-by-moving-to-trash t)Enable the use of minibuffer in the minibuffer
(setq enable-recursive-minibuffers t)
(minibuffer-depth-indicate-mode)Some Dired settings I find useful.
(setq dired-auto-revert-buffer t
dired-kill-when-opening-new-dired-buffer t
dired-listing-switches "-alh")
(global-set-key (kbd "M-g d") 'dired-jump-other-window)(defun my/read-file-contents (file)
"Read the content of a file and return a string"
(with-temp-buffer
(insert-file-contents file)
(buffer-string)))Use notify-send to send notifications.
(defun my/notify (title message)
"Display a Linux notification using notify-send."
(if (executable-find "notify-send")
(call-process "notify-send" nil nil nil title message)
(message "%s: %s" title message)))The most frequent keybindings are structured in a mnemonic way for me. C-c is
the βleaderβ, then a letter that identify the scope: c for generic functions, b
for buffers, d for directories, f for files, p for projects, m for the active
major-modes and so on.
(defun my/open-config ()
"Open the current Emacs configuration."
(interactive)
(find-file (expand-file-name "config.org" user-emacs-directory)))
(use-package emacs
:ensure nil
:bind
(;; Buffers
("C-c k" . kill-current-buffer)
("C-c b r" . revert-buffer)
("C-c b l" . ibuffer)
;; Files
("C-c f f" . find-file)
("C-c f d" . dired-jump)
("C-c f P" . my/open-config)
;; Utility
("C-c u p l" . package-list-packages)
("C-c u p i" . package-install)
("C-c u p d" . package-delete)
("C-c u p u" . package-update-all)
("C-c u p v" . package-vc-upgrade-all)
;; Personal binds
("M-#" . mark-end-of-sentence)))Which-key β Emacs package that displays available keybindings in popup.
(use-package which-key
:ensure nil
:diminish
:config
(setq which-key-sort-order 'which-key-key-order-alpha
which-key-add-column-padding 1
which-key-min-display-lines 6)
(which-key-setup-side-window-bottom)
(which-key-mode t))I use 80 characters.
(setq-default fill-column 80)
(auto-fill-mode t)(use-package isearch
:ensure nil
:config
(setq isearch-allow-motion t
isearch-allow-scroll t))(set-charset-priority 'unicode)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(setq-default buffer-file-coding-system 'utf-8)
(setq default-process-coding-system '(utf-8-unix . utf-8-unix))(setq-default indent-tabs-mode nil ; Never use tabs
tab-always-indent 'complete ; Indent or complete
tab-width 2) ; Show eventual tabs as 4 spacesWhen the region is active and you type text into the buffer, Emacs will delete the selected text first.
(setq delete-selection-mode t)(use-package whitespace
:ensure nil
:hook
(before-save . whitespace-cleanup))(use-package delsel
:ensure nil
:hook (after-init . delete-selection-mode))(use-package multiple-cursors
:defer t
:bind
(("C-c > n" . mc/mark-next-like-this)
("C-c > p" . mc/mark-previous-like-this)
("C-c > a" . mc/mark-all-like-this)
("C-c > >" . mc/edit-lines)))undo-fu - Simple, stable undo with redo for emacs.
(use-package undo-fu
:bind (("C-z" . undo-fu-only-undo)
("C-M-z" . undo-fu-only-redo)))wgrep.el - allows you to edit a grep buffer and apply those changes to the file buffer.
(use-package wgrep)Electric Pair: provides a way to easily insert matching delimiters: parentheses, braces, brackets, etc.
(use-package elec-pair
:ensure nil
:hook
(prog-mode . (lambda ()
(setq-local electric-pair-pairs
(append electric-pair-pairs '((?\{ . ?\}))))))
:config
(setq electric-pair-preserve-balance t
electric-pair-delete-adjacent-pairs t)
(electric-pair-mode))Puni: soft deletion keeping the parentheses balanced.
(use-package puni
:commands puni-global-mode
:bind*
(:map puni-mode-map
("C-<right>" . puni-slurp-forward)
("C-<left>" . puni-barf-forward)
("C-<up>" . puni-raise))
:hook (after-init-hook . puni-global-mode))avy is a GNU Emacs package for jumping to visible text using a char-based decision tree.
(use-package avy
:init
(setq avy-background t
avy-styles-alist '((avy-go-to-char-timer . at-full))
avy-all-windows nil)
:bind
(("M-g l" . avy-goto-line)
("M-j" . avy-goto-char-timer)))Highlight symbols with overlays while providing a keymap for various operations about highlighted symbols.
(use-package symbol-overlay
:commands symbol-overlay-mode
:bind-keymap
("C-c o" . symbol-overlay-map)
:config
(add-hook 'prog-mode-hook #'symbol-overlay-mode)
(add-hook 'text-mode-hook #'symbol-overlay-mode))expand-region.el β Expand region selection.
(use-package expand-region
:bind ("C-/" . er/expand-region))Show the current buffer name and the full path of the file on the app title bar.
(setq-default frame-title-format "%b (%f)")Set my favorite font.
(use-package emacs
:ensure nil
:config
(set-face-attribute 'default nil
:family "Iosevka NFM"
:weight 'light
:height 120)
(set-face-attribute 'variable-pitch nil
:family "Iosevka Aile"
:weight 'light
:height 120))(use-package catppuccin-theme
:init
(setq catppuccin-flavor 'mocha)
:config
(setq catppuccin-italic-comments t
catppuccin-highlight-matches t)
(load-theme 'catppuccin t))(use-package minions
:config
(minions-mode))(use-package paren
:ensure nil
:config
(setq show-paren-when-point-inside-paren t
show-paren-when-point-in-periphery t)
(show-paren-mode t))
(use-package rainbow-delimiters
:commands rainbow-delimiters-mode
:hook (prog-mode-hook . rainbow-delimiters-mode))all-the-icons.el: A utility package to collect various Icon Fonts.
(use-package all-the-icons)all-the-icons-completion: adds icons to completion candidates using the built in completion metadata functions.
(use-package all-the-icons-completion
:hook
((marginalia-mode . all-the-icons-completion-marginalia-setup)
(after-init-hook . all-the-icons-completion-mode)))(use-package all-the-icons-ibuffer
:hook (ibuffer-mode . all-the-icons-ibuffer-mode))(setq-default line-spacing 0.2)(column-number-mode)(global-prettify-symbols-mode t)I like to have some space on the left and right edge of the window.
(setq-default left-margin-width 3
right-margin-width 3)Use the diff-hl package to highlight changed-and-uncommitted lines when programming.
(use-package diff-hl
:hook ((magit-pre-refresh . diff-hl-magit-pre-refresh)
(magit-post-refresh . diff-hl-magit-post-refresh)
(after-init-hook . global-diff-hl-mode)))ace-window
(use-package ace-window
:bind
("M-o" . ace-window)
:config
(setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)
aw-dispatch-always t))(use-package ibuffer-vc
:defer t)
(use-package ibuffer
:config
(setq ibuffer-expert t
ibuffer-display-summary nil
ibuffer-show-empty-filter-groups nil
ibuffer-use-header-line t
ibuffer-default-sorting-mode 'vc-status))A couple of custom function to ease my workflow.
(defun my/split-window-vertically-and-focus ()
"Split the current window vertically and move focus to the new window."
(interactive)
(split-window-vertically)
(other-window 1))
(defun my/split-window-horizontally-and-focus ()
"Split the current window horizontally and move focus to the new window."
(interactive)
(split-window-horizontally)
(other-window 1))
(global-set-key (kbd "C-c v") 'my/split-window-vertically-and-focus)
(global-set-key (kbd "C-c h") 'my/split-window-horizontally-and-focus)Tabspaces leverages tab-bar.el and project.el for workspaces.
(use-package tabspaces
:hook (after-init . tabspaces-mode)
:commands (tabspaces-switch-or-create-workspace
tabspaces-open-or-create-project-and-workspace)
:bind
(("M-g w" . tabspaces-switch-or-create-workspace)
("M-g p" . tabspaces-open-or-create-project-and-workspace))
:config
(setq tabspaces-use-filtered-buffers-as-default t
tabspaces-default-tab "main"
tabspaces-session nil
tabspaces-session-auto-restore nil
tabspaces-remove-to-default t
tabspaces-include-buffers '("*scratch*" "*Messages*")
tabspaces-initialize-project-with-todo nil
tab-bar-new-tab-choice "*scratch*"))(use-package envrc
:hook (after-init . envrc-global-mode))I use mise-en-place to manage my dev environments.
;; (use-package mise
;; :config
;; (global-mise-mode))Emacs-libvterm (vterm) is fully-fledged terminal emulator inside GNU Emacs based on libvterm, a C library. As a result of using compiled code (instead of elisp), emacs-libvterm is fully capable, fast, and it can seamlessly handle large outputs.
(use-package vterm
:bind ("C-c u t" . vterm-other-window)
:config
(setq vterm-kill-buffer-on-exit t))Orderless provides an orderless completion style that divides the pattern into
space-separated components, and matches all the components in any order.
(use-package orderless
:config
(setq completion-styles '(orderless basic)
completion-category-overrides '((file (styles basic partial-completion)))))Vertico: provides a performant and minimalistic vertical completion UI based on the default completion system.
(use-package vertico
:config
(setq vertico-sort-function 'vertico-sort-history-alpha)
:hook (after-init-hook . vertico-mode))Consult provides practical commands based on the Emacs completion function completing-read.
(use-package consult
:bind
(("M-g l" . consult-goto-line)
("M-g b" . consult-buffer)
("M-g i" . consult-imenu)
("M-g f" . consult-flymake)
("M-g g" . consult-ripgrep)
("M-g o" . consult-org-heading))
:config
(recentf-mode t)
(setq consult-buffer-sources '(consult--source-project-buffer
consult--source-buffer
consult--source-hidden-buffer
consult--source-project-recent-file))
(setq consult-preview-key "M-."))Marginalia: provides marks or annotations placed at the margin of the page of a book or in this case helpful colorful annotations placed at the margin of the minibuffer for your completion candidates.
(use-package marginalia
:hook (after-init-hook . marginalia-mode))(use-package embark
:bind
(("C-." . embark-act) ;; pick some comfortable binding
("C-;" . embark-dwim) ;; good alternative: M-.
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
:init
;; Optionally replace the key help with a completing-read interface
(setq prefix-help-command #'embark-prefix-help-command)
:config
;; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
(use-package embark-consult
:after (consult embark)
:hook
(embark-collect-mode . consult-preview-at-point-mode))(use-package jinx
:hook (after-init-hook . global-jinx-mode)
:bind
("C-c s s" . jinx-correct)
("C-c s l" . jinx-languages)
:config
(setq jinx-languages "en_US it_IT"))Corfu enhances completion at point with a small completion popup.
(use-package corfu
:config
(setq corfu-auto t)
:hook ((prog-mode . corfu-mode)
(prog-mode . corfu-history-mode)))Use hippie-expand instead of dabbrev-expand.
(use-package hippie-exp
:bind*
("M-/" . hippie-expand))Helpful is an alternative to the built-in Emacs help that provides much more contextual information.
(use-package helpful
:bind
([remap describe-function] . helpful-function)
([remap describe-symbol] . helpful-symbol)
([remap describe-variable] . helpful-variable)
([remap describe-command] . helpful-command)
([remap describe-key] . helpful-key)
:custom
(counsel-describe-function-function #'helpful-callable)
(counsel-describe-variable-function #'helpful-variable))Use built-in dictionary-el.
(use-package dictionary
:bind
("C-c s d" . dictionary-search)
:config
(setq dictionary-server "dict.org"
dictionary-use-single-buffer t))yankpad - Organize snippets in a org-mode file
(use-package yasnippet)
(use-package yankpad
:bind
(("C-c y e" . yankpad-edit)
("C-c y i" . yankpad-insert)
("C-c y m" . yankpad-map)
("C-c y r" . yankpad-reload)
("C-c y x" . yankpad-expand))
:config
(setq yankpad-file (expand-file-name "yankpad.org"
user-emacs-directory)
yankpad-use-yasnippet t))(setq-default c-basic-offset 2
tab-width 2
indent-tabs-mode nil
java-ts-mode-indent-offset 2)Remap some major mode with their tree-sitter implementation.
(use-package treesit-auto
:hook (after-init-hook . global-treesit-auto-mode)
:custom
(treesit-auto-install 'prompt)
:config
(treesit-auto-add-to-auto-mode-alist 'all))Flycheck is a modern on-the-fly syntax checking extension.
(use-package flycheck
:defer t)Letβs use the built-in module to manage different projects.
(use-package project
:ensure nil
:commands project-root
:bind-keymap
("C-c p" . project-prefix-map))Magit - A Git porcelain inside Emacs.
(use-package magit
:defer t
:bind
(("M-g m" . magit-status)
("C-c g g" . magit-status)
("C-c g l" . magit-log)
("C-c g r" . vc-refresh-state))
:config
(push 'magit-refs-mode emojify-inhibit-major-modes)
(setq magit-save-repository-buffers 'dontask
magit-refs-show-commit-count 'all
magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1
magit-bury-buffer-function #'magit-restore-window-configuration))(use-package eldoc
:ensure nil
:config
(setq eldoc-echo-area-display-truncation-message nil
eldoc-echo-area-use-multiline-p nil))Eglot: The Emacs Client for the Language Server Protocol
(use-package jsonrpc :ensure nil)
(use-package eglot
:pin gnu-devel
:defer t
:bind
(("C-c l l" . eglot)
("C-c l r" . eglot-rename)
("C-c l a" . eglot-code-actions)
("C-c l d" . xref-find-definitions)
("C-c l e" . eldoc-doc-buffer)
("C-c l E" . eglot-events-buffer)
("C-c l q" . eglot-shutdown))
:config
(setq eglot-sync-connect 0
eglot-autoshutdown t
jsonrpc-event-hook nil
eglot-extend-to-xref t
eglot-code-action-indicator " β
"
eglot-ignored-server-capabilities '(:inlayHintProvider)))Dape - Debug Adapter Protocol for Emacs
(use-package dape
:defer t
:config
(setq dape-buffer-window-arrangement 'right)
:hook ((dape-on-stopped-hooks . dape-info)
(dape-on-stopped-hooks . dape-repl)
(dape-compile-compile-hooks . kill-buffer)))Clojure settings for Emacs
(use-package clojure-ts-mode
:mode ("\\.clj\\'" "\\.cljs\\'" "\\.bb\\'" "\\.edn\\'")
:hook
((clojure-ts-mode . cider-mode)
(clojure-ts-mode . subword-mode)))Neil - A CLI to add common aliases and features to deps.edn-based projects.
(use-package neil
:defer t
:after clojure-ts-mode
:config
(setq neil-prompt-for-version-p nil
neil-inject-dep-to-project-p t))(use-package cider
:defer t
:after clojure-ts-mode
:hook
((cider-mode . eldoc-mode)
(cider-repl-mode . eldoc-mode)
(cider-repl-mode . subword-mode)
(cider-mode . cider-enable-flex-completion)
(cider-repl-mode . cider-enable-flex-completion))
:bind
(:map clojure-mode-map
("C-c m j" . cider-jack-in-clj)
("C-c m J" . cider-jack-in-cljs)
("C-c m d" . neil-find-clojure-package)
("C-c m n" . cider-repl-set-ns)
:map cider-repl-mode-map
("C-c m l" . cider-repl-clear-buffer)
("RET" . cider-repl-newline-and-indent)
("C-<return>" . cider-repl-return))
:config
(setq cider-eldoc-display-for-symbol-at-point nil
cider-font-lock-dynamically t
cider-save-file-on-load t
cider-repl-pop-to-buffer-on-connect 'display-only
cider-repl-history-file (locate-user-emacs-file "cider-repl-history")
cider-repl-display-help-banner nil))(use-package clojure-mode-extra-font-locking
:after clojure-mode)I want the REPL always on the right side.
(add-to-list 'display-buffer-alist
'((derived-mode . cider-repl-mode)
(display-buffer-pop-up-window)
(side . right)
(window-width . 0.5)))(use-package clay
:after clojure-mode
:defer t
:bind
(:map clojure-mode-map
("C-c m c s" . clay-start)
("C-c m c m" . clay-make-ns-html)
("C-c m c k" . clay-make-last-sexp)
("C-c m c q" . clay-make-ns-quarto-html)))SLY is a Common Lisp IDE for Emacs.
(use-package sly
:defer t
:config
(setq inferior-lisp-program "sbcl"))js2-mode: Improved JavaScript editing mode for GNU Emacs.
(use-package rjsx-mode
:defer t
:mode "\\.[mc]?js\\'"
:mode "\\.es6\\'"
:mode "\\.pac\\'"
:interpreter "node"
:config
(setq js-chain-indent t
;; These have become standard in the JS community
js2-basic-offset 2
;; Don't mishighlight shebang lines
js2-skip-preprocessor-directives t
;; let flycheck handle this
js2-mode-show-parse-errors nil
js2-mode-show-strict-warnings nil
;; Flycheck provides these features, so disable them: conflicting with
;; the eslint settings.
js2-strict-missing-semi-warning nil
;; maximum fontification
js2-highlight-level 3
js2-idle-timer-delay 0.15))web-mode: an emacs major mode for editing HTML files.
(use-package web-mode
:defer t
:mode
("\\.njk\\'" "\\.tpl\\.php\\'"
"\\.[agj]sp\\'" "\\.as[cp]x\\'"
"\\.erb\\'" "\\.mustache\\'"
"\\.djhtml\\'" "\\.[t]?html?\\'"
"\\.js\\'")
:config
(setq web-mode-markup-indent-offset 2
web-mode-css-indent-offset 2
web-mode-code-indent-offset 2
web-mode-script-padding 0
web-mode-enable-auto-pairing nil))Derive vue-mode from web-mode and add lsp support. NOTE: As November 2025, this works only with vue-language-server 2.2.8, not with the new 3.x.
(define-derived-mode vue-mode web-mode "Vue mode")
(add-to-list 'auto-mode-alist '("\\.vue\\'" . vue-mode))
(defun vue-eglot-init-options ()
(let* ((no-warnings "NODE_NO_WARNINGS=1 ")
(filter "| head -n1")
(base "npm list --parseable typescript ")
(global "npm list --global --parseable typescript ")
(tsdk-base-path (string-trim-right (shell-command-to-string (concat no-warnings base filter))))
(tsdk-global-path (string-trim-right (shell-command-to-string (concat no-warnings global filter))))
(tsdk-path (expand-file-name "lib" (if (string-empty-p tsdk-base-path)
tsdk-global-path
tsdk-base-path))))
`(:typescript (:tsdk ,tsdk-path)
:vue (:hybridMode :json-false))))
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
`(vue-mode . ("vue-language-server" "--stdio"
:initializationOptions ,(vue-eglot-init-options)))))(use-package yaml-ts-mode
:defer t)(use-package json-mode
:defer t
:mode ("\\.json\\'" "\\.jsonc\\'")
:bind
(:map json-mode-map
("C-c C-j" . jq-interactively))
:config
(setq js-indent-level 2))
(use-package jq-mode :after json-mode)(use-package docker :defer t)
(use-package dockerfile-mode :defer t)(setq major-mode-remap-alist
'((python-mode . python-ts-mode)))
(use-package pyvenv
:after python-ts-mode
:defer t)
(use-package pyvenv-auto
:defer t
:hook ((python-mode python-ts-mode) . pyvenv-auto-run))(use-package jarchive
:init
(jarchive-mode))
(defun my/jdtls-setup (_interactive project)
(list "jdtls"
"-configuration" (file-name-concat (xdg-cache-home) "jdtls")
"-data" (expand-file-name (md5 (project-root project))
(locate-user-emacs-file "jdtls-cache"))
"--jvm-arg=-javaagent:/usr/lib/lombok-common/lombok.jar"))
(with-eval-after-load 'eglot
(push '((java-mode java-ts-mode) . my/jdtls-setup)
eglot-server-programs))
(use-package java-ts-mode
:config
(setq java-ts-mode-indent-offset 2))I have to deal with this s**t sometimes⦠:(
(use-package php-mode :defer t)Tree Sitter support for Typst.
(use-package typst-ts-mode
:defer t
:custom
(typst-ts-watch-options "--open")
(typst-ts-mode-grammar-location (expand-file-name "tree-sitter/libtree-sitter-typst.so" user-emacs-directory))
(typst-ts-mode-enable-raw-blocks-highlight t)
:config
(keymap-set typst-ts-mode-map "C-c C-c" #'typst-ts-tmenu))Major mode to edit The KDL Document Language
(use-package kdl-mode
:mode ("\\.kdl\\'"))Rust setup
(use-package rust-mode
:defer t)Cargo
(use-package cargo-mode
:after rust-mode
:hook
(rust-mode . cargo-minor-mode)
:bind-keymap
("C-c r" . cargo-mode-command-map)
:config
(setq compilation-scroll-output t))(use-package csharp-mode
:defer t)(use-package go-mode
:defer t
:config
(setq go-ts-mode-indent-offset 2))(use-package markdown-mode
:config
(setq markdown-hide-urls t
markdown-asymmetric-header t)
:mode ("\\.md" . gfm-mode))(defun my/open-inbox ()
(interactive)
(find-file (concat org-directory "/inbox.org")))
(use-package org
:hook ((org-mode . org-indent-mode)
(org-mode . auto-fill-mode))
:bind
(("C-c t t" . org-capture)
("C-c t a" . org-agenda-list)
("C-c t i" . my/open-inbox)
(:map org-mode-map
("C-c m t" . org-tags-view)
("C-c m c" . org-cycle-global)))
:config
(setq org-directory "~/org"
org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "WAIT(w)" "|" "DONE(d)" "CANCELLED(c)"))
org-log-repeat nil
org-default-notes-file "~/org/inbox.org"
org-agenda-files (list org-directory)
org-agenda-restore-windows-after-quit t
org-archive-location (concat org-directory "/archive/archive.org::datatree/")
org-archive-mark-done t
org-refile-targets `((,(directory-files "~/org" t "\\.org$") . (:maxlevel . 3)))
org-use-tag-inheritance t
org-refile-use-cache nil
org-refile-use-outline-path 'file
org-refile-allow-creating-parent-nodes 'confirm
org-outline-path-complete-in-steps nil
org-use-speed-commands t
org-return-follows-link t
org-hide-emphasis-markers t
org-ellipsis "β¦"
org-fontify-quote-and-verse-blocks t
org-src-tab-acts-natively t
org-adapt-indentation t
org-use-sub-superscripts nil
org-ascii-headline-spacing '(0 . 0)
org-structure-template-alist '(("s" . "src")
("e" . "src emacs-lisp")
("x" . "example")
("X" . "export")
("q" . "quote"))))Org capture configuration
(setq org-capture-templates
'(("t" "Todo" entry (file "todo.org")
"* TODO %? %^G\nSCHEDULED: %^t")
("i" "Inbox" entry (file "inbox.org")
"* NEXT %? %^G\n:PROPERTIES:\n:ID: %(org-id-new)\n:END:" :prepend t)
("p" "Protocol" entry (file "inbox.org")
"* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?")
("L" "Protocol Link" entry (file "inbox.org")
"* %? [[%:link][%:description]] \nCaptured On: %U")
("j" "Journal" entry (file+olp+datetree "journal.org")
"* %U %?\n%i\n%a" :kill-buffer t :tree-type week)))(add-hook 'org-capture-after-finalize-hook #'org-save-all-org-buffers)
(add-hook 'org-after-todo-state-change-hook #'org-save-all-org-buffers)
(add-hook 'org-archive-hook #'org-save-all-org-buffers)
(advice-add 'org-refile :after 'org-save-all-org-buffers)GitHub - minad/org-modern: π¦ Modern Org Style
(use-package org-modern
:hook (after-init-hook . global-org-modern-mode)
:config
(setq org-auto-align-tags nil
org-tags-column 0
org-fold-catch-invisible-edits 'show-and-error
org-special-ctrl-a/e t
org-insert-heading-respect-content t
org-hide-emphasis-markers t
org-pretty-entities t
org-ellipsis "β¦"
;; Agenda styling
org-agenda-tags-column 0
org-agenda-block-separator ?β
org-agenda-time-grid
'((daily today require-timed)
(800 1000 1200 1400 1600 1800 2000)
" βββββ " "βββββββββββββββ")
org-agenda-current-time-string
"β now βββββββββββββββββββββββββββββββββββββββββββββββββ"))org-mode to typst configuration.
(use-package ox-typst
:defer t
:after org)wallabag.el - Emacs Wallabag client.
(use-package wallabag
:defer t
:commands wallabag
:config
(setq wallabag-host "https://wb.dallastella.name"
wallabag-search-print-items '("title" "domain" "tag" "reading-time" "date")
wallabag-search-page-max-rows 32))Elfeed is an extensible web feed reader for Emacs
(use-package elfeed
:defer t
:bind (("C-c u e" . elfeed))
:config
(setq elfeed-feeds '("https://ld.dallastella.name/feeds/da3d421812cf2636f84d9a024e2c3b0d749b194d/unread")
elfeed-search-filter "@3-week-ago"))(use-package gptel
:config
;; OpenRouter offers an OpenAI compatible API
(setq gptel-model 'mistralai/mistral-nemo
gptel-backend (gptel-make-openai "OpenRouter"
:host "openrouter.ai"
:endpoint "/api/v1/chat/completions"
:key my/openrouter-key
:models '(qwen/qwen3-4b:free
mistralai/mixtral-8x7b-instruct))))(defun my/gptel-magit-set-prompt (filename)
"Read the content of filename and set gptel-magit-commit-prompt"
(let* ((path (expand-file-name (concat "prompts/" filename) user-emacs-directory))
(content (my/read-file-contents path)))
(setq gptel-magit-commit-prompt content)))
(defun my/gptel-english-commit ()
"Set commit prompt to English, Zed style"
(interactive)
(my/gptel-magit-set-prompt "commit-message"))
(defun my/gptel-italian-commit ()
"Set commit prompt to Italian, Zed style"
(interactive)
(my/gptel-magit-set-prompt "commit-message-ita"))
(use-package gptel-magit
:after (magit gptel)
:hook (magit-mode . gptel-magit-install)
:config
(setq gptel-magit-model 'mistralai/mixtral-8x7b-instruct)
(my/gptel-english-commit))(defun my/claude-code-display-on-right (buffer)
"Display Claude buffer in right side window."
(display-buffer buffer '((display-buffer-in-side-window)
(side . right)
(window-width . 90))))
;; install required inheritenv dependency:
(use-package inheritenv
:vc (:url "https://github.com/purcell/inheritenv" :rev :newest))
(use-package claude-code
:vc (:url "https://github.com/stevemolitor/claude-code.el" :rev :newest)
:bind
(:repeat-map my-claude-code-map ("M" . claude-code-cycle-mode))
:bind-keymap ("C-c a" . claude-code-command-map)
:config
(setq claude-code-terminal-backend 'vterm
claude-code-program "~/.local/bin/ccr-code.sh"
claude-code-notification-function #'my/notify
claude-code-display-window-fn #'my/claude-code-display-on-right)
(claude-code-mode))Tidal Cycles (or just Tidal for short) is software for making patterns with code, whether live coding music at algo-raves or composing in the studio.
(use-package tidal :defer t)Automatically tangle config.org file when saving.
(defun my/org-babel-tangle-config ()
(when (string-equal (buffer-file-name) (expand-file-name "~/.emacs.d/config.org"))
(message "** Tangle config.org file...")
(let ((org-config-babel-evaluate nil))
(org-babel-tangle))))
(defun my/compile-config ()
(interactive)
(byte-compile-file (expand-file-name "~/.emacs.d/early-init.el"))
(byte-compile-file (expand-file-name "~/.emacs.d/init.el")))
(global-set-key (kbd "C-c u c") 'my/compile-config)
(add-hook 'org-mode-hook
(lambda ()
(add-hook 'after-save-hook #'my/org-babel-tangle-config)))