Skip to content

mdallastella/.emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Emacs configuration

Early init file

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.

;; Profile emacs startup
(add-hook 'emacs-startup-hook
          (lambda ()
            (message "*** Emacs loaded in %s seconds with %d garbage collections."
                     (emacs-init-time "%.2f")
                     gcs-done)))

Init

File header

;;; init.el --- Emacs configuration -*- lexical-binding: t -*-

custom.el

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)

Maximize windows by default.

(add-hook 'emacs-startup-hook 'toggle-frame-maximized)

Native compilation

Native compilation tweaks.

;; Silence compiler warnings as they can be pretty disruptive
(setq native-comp-async-report-warnings-errors nil
      byte-compile-warnings nil)

Package management

Just good old use-package and vc-use-package:

(require 'package)

(setq package-archives '(("elpa" . "https://elpa.gnu.org/packages/")
                         ("melpa" . "https://melpa.org/packages/")
                         ("nongnu" . "https://elpa.nongnu.org/nongnu/")
                         ("gnu-devel" . "https://elpa.gnu.org/devel/")))

(setq package-archive-priorities
      '(("gnu-elpa" . 3)
        ("melpa" . 2)
        ("nongnu" . 1)))

(setq use-package-always-ensure t
      package-native-compile t)

(package-initialize)

(unless package-archive-contents
  (package-refresh-contents))

(unless (package-installed-p 'vc-use-package)
  (package-vc-install "https://github.com/slotThe/vc-use-package"))

(require 'vc-use-package)

(use-package use-package-ensure-system-package)

Start server

Start an Emacs daemon (server)

(use-package server
  :commands (server-running-p)
  :init
  (unless (server-running-p)
    (server-start)))

Benchmark init

Enable benchmarking only when needed.

(use-package benchmark-init
  :disabled
  :config
  (add-hook 'after-init-hook 'benchmark-init/deactivate))

Keep .emacs.d nice and clean

Use no-littering to keep our directory clean.

;; Keep .emacs.d clean
(use-package no-littering
  :ensure t
  :config
  (setq create-lockfiles nil
        delete-old-versions t
        kept-new-versions 6
        kept-old-versions 2
        version-control t))

Store backups and autosave 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)))

Hide byte compiler warnings

(add-to-list 'display-buffer-alist
             '("\\`\\*\\(Warnings\\|Compile-Log\\)\\*\\'"
               (display-buffer-no-window)
               (allow-no-window . t)))

General settings

My personal information

(setq user-full-name "Marco Dalla Stella"
      user-mail-address "[email protected]")

Access to shell PATH

Ensure environment variables inside Emacs look the same as in the user’s shell.

(use-package exec-path-from-shell
  :config
  (exec-path-from-shell-initialize))

Save history

(use-package savehist
  :ensure nil
  :config
  (setq history-length 10000
        history-delete-duplicates t
        savehist-save-minibuffer-history t
        savehist-additional-variables '(kill-ring
                                        search-ring
                                        regexp-search-ring))
  (savehist-mode t))

Auto Revert

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))

Recent files

Save recent files

(use-package recentf
  :ensure nil
  :config
  (setq recentf-max-saved-items 50
        recentf-max-menu-items 15))

Unbind Ctrl-z

I don’t like to hide Emacs.

(global-unset-key (kbd "C-z"))

Scratch buffer

Use emacs-lisp-mode instead of lisp-interaction-mode for scratch buffer.

(setq initial-major-mode 'emacs-lisp-mode
      initial-scratch-message ";; Happy coding!\n\n")

Delete moves to trash

Move deleted files to trash, you never know…

(setq delete-by-moving-to-trash t)

Recursive minibuffer

Enable the use of minibuffer in the minibuffer

(setq enable-recursive-minibuffers t)
(minibuffer-depth-indicate-mode)

Dired settings

Some Dired settings I find useful.

(setq dired-auto-revert-buffer t
      dired-kill-when-opening-new-dired-buffer t)

Keybindings

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.

ESC cancel all

(global-set-key (kbd "<escape>") 'keyboard-escape-quit)

Generic

(defun my/open-config ()
  "Open the current Emacs configuration."
  (interactive)
  (find-file (expand-file-name "config.org" user-emacs-directory)))

(defun my/ibuffer ()
  (interactive)
  (ibuffer t))

(defun get-string-from-file (file-path)
  "Return file content as string."
  (with-temp-buffer
    (insert-file-contents file-path)
    (buffer-string)))

(use-package emacs
  :bind
  (;; Buffers
   ("C-c b k" . kill-this-buffer)
   ("C-c b r" . revert-buffer)
   ("C-c b l" . my/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)))

which-key

Which-key – Emacs package that displays available keybindings in popup.

(use-package which-key
  :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))

Editing

Default fill-column

I use 80 characters.

(setq-default fill-column 80)
(auto-fill-mode t)

Default coding system

(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))

Use spaces to indent, no tabs

(setq-default indent-tabs-mode nil           ; Never use tabs
              tab-always-indent 'complete    ; Indent or complete
              tab-width 2)                   ; Show eventual tabs as 4 spaces

Delete selected region

When the region is active and you type text into the buffer, Emacs will delete the selected text first.

(setq delete-selection-mode t)

Deal with whitespaces

(use-package whitespace
  :ensure nil
  :hook
  (before-save . whitespace-cleanup))

Delete / replace selected text

(use-package delsel
  :ensure nil
  :hook (after-init . delete-selection-mode))

Multiple cursors

Multiple cursors for Emacs

(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

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

wgrep.el - allows you to edit a grep buffer and apply those changes to the file buffer.

(use-package wgrep)

Parenthesis

Electric Pair

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

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))
  :init
  (puni-global-mode))

Jump around

avy is a GNU Emacs package for jumping to visible text using a char-based decision tree.

(use-package avy)

Symbol overlay

Highlight symbols with overlays while providing a keymap for various operations about highlighted symbols.

(use-package symbol-overlay
  :bind-keymap
  ("C-c o" . symbol-overlay-map)
  :hook
  ((text-mode prog-mode) . symbol-overlay-mode))

UI

Frame title

Show the current buffer name and the full path of the file on the app title bar.

(setq-default frame-title-format "%b (%f)")

Font setup

Set my favorite font.

(use-package emacs
  :config
  (set-face-attribute 'default nil
                      :family "Iosevka NFM"
                      :weight 'normal
                      :height 120)
  (set-face-attribute 'variable-pitch nil
                      :family "Iosevka Aile"
                      :weight 'normal
                      :height 120))

Theme

GitHub - doomemacs/themes: A megapack of themes for GNU Emacs.

(use-package doom-themes
  :config
  (setq doom-themes-enable-bold t
        doom-themes-enable-italic t
        doom-themes-padded-modeline t)
  (load-theme 'doom-solarized-dark-high-contrast t)
  (doom-themes-visual-bell-config)
  (doom-themes-org-config))

Modeline

Mdeline from Doom

(use-package minions
  :config
  (minions-mode))

(use-package doom-modeline
  :hook
  (after-init . doom-modeline-mode)
  :config
  (setq doom-modeline-buffer-file-name-style 'buffer-name
        doom-modeline-minor-modes nil
        doom-modeline-icon t
        doom-modeline-project-detection 'project
        doom-modeline-major-mode-color-icon t
        doom-modeline-height 15))

;; (use-package moody
;;   :config
;;   (setq moody-mode-line-height 16)
;;   (moody-replace-mode-line-front-space)
;;   (moody-replace-mode-line-buffer-identification)
;;   (moody-replace-vc-mode))

Show matching parenthesis

(use-package paren
  :config
  (setq show-paren-when-point-inside-paren t
        show-paren-when-point-in-periphery t)
  (show-paren-mode t))

(use-package rainbow-delimiters
  :hook
  ((prog-mode cider-repl-mode) . rainbow-delimiters-mode))

Use icons

all-the-icons.el: A utility package to collect various Icon Fonts and propertize them within Emacs.

(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)
  :config
  (all-the-icons-completion-mode))

nerd-icons.el: is a library for easily using Nerd Font icons inside Emacs, an alternative to all-the-icons. This is needed for doom-modeline, sigh…

(use-package nerd-icons)

Increase line-spacing

(setq-default line-spacing 0.2)

Show column

(column-number-mode)

Prettify symbols

(global-prettify-symbols-mode t)

Window margins and line numbers

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)

Highlight uncommitted changes

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))
  :config
  (global-diff-hl-mode))

ace-window

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))

Tools

Perspective

The Perspective package provides multiple named workspace (or β€œperspectives”) in Emacs.

(use-package perspective
  :disabled t
  :bind
  (("C-c x x" . persp-switch)
   ("C-c x r" . persp-rename)
   ("C-c x k" . persp-kill))
  :config
  (setq persp-suppress-no-prefix-key-warning t
        persp-initial-frame-name "main")
  (persp-mode))

Tabspace

Tabspaces leverages tab-bar.el and project.el for workspaces.

(use-package tabspaces
  :hook (after-init . tabspaces-mode) ;; use this only if you want the minor-mode loaded at startup.
  :commands (tabspaces-switch-or-create-workspace
             tabspaces-open-or-create-project-and-workspace)
  :config
  (setq tabspaces-use-filtered-buffers-as-default t
        tabspaces-default-tab "main"
        tabspaces-remove-to-default t
        tabspaces-include-buffers '("*scratch*")
        tabspaces-initialize-project-with-todo nil
        tabspaces-session nil
        tab-bar-new-tab-choice "*scratch*"))

envrc

(use-package envrc
  :config
  (envrc-global-mode))

mise

I use mise-en-place to manage my dev environments.

(use-package mise
  :hook (after-init . global-mise-mode))

Vertico, Orderless, Consult, Marginalia, Embark

Orderless

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 partial-completion)
        completion-category-defaults nil
        completion-category-overrides nil))

Vertico

Vertico: provides a performant and minimalistic vertical completion UI based on the default completion system.

(use-package vertico
  :config
  (vertico-mode))

Consult

Consult provides practical commands based on the Emacs completion function completing-read.

(use-package consult
  :bind
  (("M-g g" . consult-goto-line)
   ("M-g G" . consult-goto-line-numbers)
   ("M-g o" . consult-outline)
   ("M-g m" . consult-mark)
   ("M-g k" . consult-global-mark)
   ("C-c h" . consult-history)
   ("C-c b b" . consult-buffer)
   ("C-c c c" . consult-imenu)
   ("C-c c f" . consult-flymake)
   ("C-c c r" . consult-recent-file)
   ("C-c c e" . consult-compile-error)
   ("C-c c m" . consult-mode-command)
   ("C-c f g" . consult-ripgrep))
  :config
  (recentf-mode t)
  (consult-customize consult--source-buffer :hidden t :default nil)
  ;; (add-to-list 'consult-buffer-sources 'persp-consult-source)
  (setq consult-preview-key "M-."))

Marginalia

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
  :config
  (marginalia-mode))

Embark

(use-package embark
  :ensure t

  :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
  :ensure t ; only need to install it, embark loads it after consult if found
  :hook
  (embark-collect-mode . consult-preview-at-point-mode))

Spell checking

jinx

(use-package jinx
  :hook
  (emacs-startup . global-jinx-mode)
  :bind
  ("C-c s s" . jinx-correct)
  ("C-c s l" . jinx-languages)
  :config
  (setq jinx-languages "en_US it_IT"))

Completion

corfu

Corfu enhances completion at point with a small completion popup.

(use-package corfu
  :config
  (setq corfu-auto t)
  :init
  (global-corfu-mode))

hippie-expand

Use hippie-expand instead of dabbrev-expand.

(use-package hippie-exp
  :bind*
  ("M-/" . hippie-expand))

Helpful

Helpful is an alternative to the built-in Emacs help that provides much more contextual information.

(use-package helpful
  :custom
  (counsel-describe-function-function #'helpful-callable)
  (counsel-describe-variable-function #'helpful-variable)
  :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))

Dictionary

Use built-in dictionary-el.

(use-package dictionary
  :ensure nil
  :defer t
  :bind
  ("C-c s d" . dictionary-search)
  :config
  (set-face-attribute 'dictionary-word-definition-face nil
                      :family "Iosevka Aile"
                      :weight 'light)
  (setq dictionary-server "dict.org"
        dictionary-use-single-buffer t))

Programming

Indenting

(setq-default c-basic-offset 2
              tab-width 2
              intent-tabs-mode nil
              java-ts-mode-indent-offset 2)

Tree-Sitter

Remap some major mode with their tree-sitter implementation.

(use-package treesit-auto
  :custom
  (treesit-auto-install 'prompt)
  :config
  (treesit-auto-add-to-auto-mode-alist 'all)
  (global-treesit-auto-mode))

Project

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

Magit - A Git porcelain inside Emacs.

(use-package magit
  :defer t
  :bind
  (("C-c g g" . magit-status)
   ("C-c g l" . magit-log)
   ("C-c g r" . vc-refresh-state))
  :config
  (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))

eldoc

(use-package eldoc
  :defer t
  :config
  (setq eldoc-echo-area-display-truncation-message nil
        eldoc-echo-area-use-multiline-p nil))

LSP

(use-package jsonrpc :ensure t)

Eglot: The Emacs Client for the Language Server Protocol

(setq package-pinned-packages '((eglot . "gnu-devel")))

(use-package eglot
  :defer t
  :bind
  (("C-c l e" . eglot-rename)
   ("C-c l a" . eglot-code-actions)
   ("C-c l d" . xref-find-definitions)
   ("C-c l e" . eldoc-doc-buffer))
  :config
  (setq eglot-send-changes-idle-time (* 60 60)
        read-process-output-max (* 1024 1024)
        eglot-extend-to-xref t
        eglot-connect-timeout 180
        eglot-inlay-hints-mode nil
        eglot-ignored-server-capabilities '(:inlayHintProvider)))

The emacs-lsp-booster project provides a rust-based wrapper program which substantially speeds up emacs’ interactions with lsp servers. This small package enables eglot to use it.

(use-package eglot-booster
  :vc (:fetcher github :repo jdtsmith/eglot-booster)
  :after eglot
  :init
  (eglot-booster-mode))

Dape

Dape - Debug Adapter Protocol for Emacs

(use-package dape
  :defer t
  :config
  (setq dape-buffer-window-arrangement 'right)
  (add-hook 'dape-on-stopped-hooks 'dape-info)
  (add-hook 'dape-on-stopped-hooks 'dape-repl)

  ;; By default dape uses gdb keybinding prefix
  ;; If you do not want to use any prefix, set it to nil.
  ;; (setq dape-key-prefix "\C-x\C-a")

  (add-hook 'dape-compile-compile-hooks 'kill-buffer)
  (add-hook 'dape-on-start-hooks
             (defun dape--save-on-start ()
               (save-some-buffers t t))))

Clojure

Clojure settings for Emacs

Neil

Neil - A CLI to add common aliases and features to deps.edn-based projects.

(use-package neil
  :defer t
  :config
  (setq neil-prompt-for-version-p nil
        neil-inject-dep-to-project-p t))

Cider

(use-package cider
  :defer t
  :hook
  ((cider-mode . eldoc-mode)
   (clojure-mode . cider-mode)
   (clojure-mode . subword-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))

Clojure Flycheck

Flycheck using clj-kondo.

(use-package flycheck-clj-kondo)

(use-package clojure-mode
  :defer t
  :config
  (require 'flycheck-clj-kondo))

Font-locking for Clojure mode

(use-package clojure-mode-extra-font-locking
  :after clojure-mode)

Code formatting

I like my code to be formatted following standard conventions. Thanks to Manuel Uberti.

(defun my/cljfmt-format-buffer ()
  "Format current buffer with `cljfmt'."
  (when (derived-mode-p 'clojure-mode)
    (let* ((pr (project-root (project-current)))
           (cfg-dir (locate-dominating-file pr "cljfmt.edn"))
           (cfg-edn (expand-file-name "cljfmt.edn" cfg-dir))
           (cmd (if (file-exists-p cfg-edn)
                    (format "cljfmt -c %s %s" cfg-edn buffer-file-name)
                  (format "cljfmt %s" buffer-file-name))))
      (shell-command-to-string cmd))
    (revert-buffer t t)))

(defun my/cider-format-buffer ()
  "Automatically format current buffer after saving."
  (add-hook 'after-save-hook #'my/cljfmt-format-buffer nil t))

(add-hook 'cider-mode-hook #'my/cider-format-buffer)

REPL buffer position

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)))

Clay

(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)))

JavaScript

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))

HTML & CSS

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))

VUE

Derive vue-mode from web-mode and add lsp support.

(define-derived-mode vue-mode web-mode "Vue mode")
(add-to-list 'auto-mode-alist '("\\.vue\\'" . vue-mode))

(with-eval-after-load 'eglot
  (add-to-list 'eglot-server-programs
               '(vue-mode . ("vls" "--stdio"))))

Astro

Derive astro-mode from web-mode and add lsp support.

(define-derived-mode astro-mode web-mode "Astro mode")
(add-to-list 'auto-mode-alist '("\\.astro\\'" . astro-mode))

(with-eval-after-load 'eglot
  (add-to-list 'eglot-server-programs
               '(astro-mode . ("astro-ls" "--stdio"
                               :initializationOptions
                               (:typescript (:tsdk "./node_modules/typescript/lib"))))))

YAML

(use-package yaml-ts-mode
  :defer t)

JSON

(use-package json-mode
  :defer t
  :mode "\\.json\\'"
  :bind
  (:map json-mode-map
        ("C-c C-j" . jq-interactively)))

(use-package jq-mode :after json-mode)

Docker

(use-package docker :defer t)
(use-package dockerfile-mode :defer t)

REST

Verb - Verb is a package for Emacs which allows you to organize and send HTTP requests.

(use-package verb
  :after org
  :defer t
  :config
  (setq verb-auto-kill-response-buffers t)
  (define-key org-mode-map (kbd "C-c C-r") verb-command-map))

Python

Python virtual environment

  (use-package pyvenv
  :defer t)

(use-package pyvenv-auto
  :defer t
  :hook (python-mode . pyvenv-auto-run))

Java

(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))

PHP

I have to deal with this s**t sometimes… :(

(use-package php-mode
  :defer t)

Structrizr DSL

An emacs mode for syntax highlighting structurizr dsl files.

(use-package structurizr-mode
  :vc (structurizr-mode :url "https://github.com/gilesp/structurizr-mode"))

Typst

Tree Sitter support for Typst.

(use-package typst-ts-mode
  :vc
  (typst-ts-mode :url "https://codeberg.org/meow_king/typst-ts-mode/")
  :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))

Productivity

markdown

(use-package markdown-mode
  :defer t
  :init
  (setq markdown-hide-urls t)
  :mode ("\\.md" . gfm-mode))

org-mode

settings

(use-package org
  :ensure nil
  :defer t
  :hook (org-mode . org-indent-mode)
  :bind
  (("C-c n c" . org-capture)
   ("C-c n a" . org-agenda-list)
   ("C-c n t" . org-todo-list)
   (:map org-mode-map
         ("C-c m h" . consult-org-heading)
         ("C-c m t" . org-tags-view)
         ("C-c m c" . org-cycle-global)))
  :config
  (setq org-directory "~/org"
        my/org-latex  (concat org-directory "/templates")
        org-todo-keywords '((sequence "TODO(t)" "WAITING(w)" "DOING(g)" "|" "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 . 2)))
        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))

Latex templates for org-mode

(with-eval-after-load 'ox-latex
  (add-to-list 'org-latex-classes
               '("7bint"
                 "\\documentclass[11pt]{article}
                  [NO-DEFAULT-PACKAGES]
                  [EXTRA]
                  \\input{/home/mds/org/templates/7bint.tex}"
                 ("\\section{%s}" . "\\section*{%s}")
                 ("\\subsection{%s}" . "\\subsection*{%s}")
                 ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))

org-capture

Org capture configuration

(setq org-capture-templates
      '(("t" "Todo" entry (file "todo.org")
         "* TODO %? %^G\nSCHEDULED: %^t")
        ("i" "Inbox" entry (file "inbox.org")
         "* %? %^G")
        ("d" "Done" entry (file+datetree "done.org")
         "* %? %^G")
        ("p" "Project note" entry (file "projects.org")
         "* %?\n")
        ("a" "Area note" entry (file "areas.org")
         "* %?\n")
        ("r" "Resource note" entry (file "resources.org")
         "* %?\n")))

save org buffers after refile

(advice-add 'org-refile :after 'org-save-all-org-buffers)

org-modern

GitHub - minad/org-modern: πŸ¦„ Modern Org Style

(use-package org-modern
  :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 ─────────────────────────────────────────────────")
  (global-org-modern-mode))

org-cliplink

A simple command that takes a URL from the clipboard and inserts an org-mode link with a title of a page found by the URL into the current buffer.

(use-package org-cliplink
  :after org
  :bind
  (:map org-mode-map
        ("C-c m l" . org-cliplink)))

org-download

org-download - This extension facilitates moving images from point A to point B.

(use-package org-download
  :defer t
  :hook (org-mode . org-download-enable))

notes on documents

pdf-tools

(use-package pdf-tools
  :defer t
  :magic ("%PDF" . pdf-view-mode)
  :config
  (pdf-tools-install))

epub - nov.el

(use-package nov
  :defer t
  :mode ("\\.epub\\'" . nov-mode))

slides

org-re-reveal - provides an export back-end for HTML presentations with reveal.js from Org mode source files.

(use-package org-re-reveal
  :after ox
  :defer t
  :config
  (setq org-re-reveal-root "../reveal"
        org-re-reveal-theme "black"
        org-re-reveal-title-slide nil
        org-re-reveal-embed-local-resources t))

consult-notes

This is a package for easily selecting notes via consult.

(use-package consult-notes
  :defer t
  :commands
  (consult-notes consult-notes-search-in-all-notes)
  :config
  (setq consult-notes-file-dir-sources '(("Notes" ?n "/home/mds/org/"))
        consult-notes-org-headings-files (directory-files "/home/mds/org/" t "\\.org\\'"))
  (consult-notes-org-headings-mode)
  (consult-notes-denote-mode))

denote

(use-package denote
  :hook
  (dired-mode . denote-dired-mode)
  :config
  (setq denote-directory "/home/mds/Sputnik/braindump"
        denote-known-keywords '("area" "project" "resource")))

elfeed

Elfeed is an extensible web feed reader for Emacs, supporting both Atom and RSS.

(use-package elfeed-org
  :config
  (setq rmh-elfeed-org-files '("~/org/feeds.org"))
  (elfeed-org))

(use-package elfeed-goodies)

(use-package elfeed
  :defer t
  :bind
  (("C-c e e" . elfeed)
   ("C-c e u" . elfeed-update)))

Pocket

(use-package pocket-reader
  :config
  (setq pocket-reader-url-priorities '(resolved_url given_url)))

ellama

Ellama is a tool for interacting with large language models from Emacs.

(use-package ellama
  :bind
  ("C-c a" . ellama-transient-main-menu)
  :init
  (require 'llm-ollama)
  (setq ellama-provider
        (make-llm-ollama
         :chat-model "mistral"
         :embedding-model "mistral")))

Initial buffer configuration

The buffers / workspaces I want at start.

;; (defun my/initial-setup ()
;;   (interactive)
;;   (persp-switch "notes" t)
;;   (find-file "~/org/inbox.org")
;;   (persp-switch persp-initial-frame-name t))

;; (add-hook 'emacs-startup-hook 'my/initial-setup)

Tangle and compite configuration on save

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)
  (message "** Compile early-init and init files...")
  (byte-compile-file early-init-file)
  (byte-compile-file user-init-file))))

(add-hook 'org-mode-hook
    (lambda ()
  (add-hook 'after-save-hook #'my/org-babel-tangle-config)))

Packages to look at

Popper

Popper is a minor-mode to tame the flood of ephemeral windows Emacs produces, while still keeping them within arm’s reach. https://github.com/karthink/popper

Cape

Cape provides Completion At Point Extensions which can be used in combination with the Corfu completion UI or the default completion UI. https://github.com/minad/cape

Doct

doct is a function that provides an alternative, declarative syntax for describing Org capture templates. https://github.com/progfolio/doct

Releases

No releases published

Packages

No packages published