flocon/private_dot_emacs.d/config.org

11 KiB

Emacs config

Packages initialization

Here, we're initializing MELPA, as well as package.el and use-package.

    (require 'package)
  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
  ;; Comment/uncomment this line to enable MELPA Stable if desired.  See `package-archive-priorities`
  ;; and `package-pinned-packages`. Most users will not need or want to do this.
  ;;(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)

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

  (unless (package-installed-p 'use-package)
    (package-install 'use-package))

  (require 'use-package)
  (setq use-package-always-ensure t)

General config

no-littering

no-littering is a useful package that allows to put all of the autosave files and temporary files in one directory (the files ending with ~ for instance)

  (use-package no-littering)

Minimal interface

We disable a lot of interface elements, to make the editor more minimal looking.

  (setq inhibit-startup-message t)
  (scroll-bar-mode -1)
  (tool-bar-mode -1)
  (tooltip-mode -1)
  (set-fringe-mode 10)
  (menu-bar-mode -1)

Match fish shell's path

    (defun set-exec-path-from-shell-PATH ()
    "Set up Emacs' `exec-path' and PATH environment variable to match
  that used by the user's shell.

  This is particularly useful under Mac OS X and macOS, where GUI
  apps are not started from a shell."
    (interactive)
    (let ((path-from-shell (replace-regexp-in-string
			    "[ \t\n]*$" "" (shell-command-to-string
					    "/usr/bin/fish --login -c 'string join : $PATH'"
						      ))))
      (setenv "PATH" path-from-shell)
      (setq exec-path (split-string path-from-shell path-separator))))

  (set-exec-path-from-shell-PATH)

Bell

I don't like any visual or sound bell.

  (setq ring-bell-function 'ignore)

Font

I use the default monospace font, as it allows me to configure it system wide and have everything coherent. We just make it bigger here for readability.

  (set-face-attribute 'default nil :font "monospace" :height 125)
Ligatures
  (use-package ligature
    :config
    (ligature-set-ligatures '(prog-mode tsx-ts-mode) '("--" "---" "==" "===" "!=" "!==" "=!="
							"=:=" "=/=" "<=" ">=" "&&" "&&&" "&=" "++" "+++" "***" ";;" "!!"
							"??" "???" "?:" "?." "?=" "<:" ":<" ":>" ">:" "<:<" "<>" "<<<" ">>>"
							"<<" ">>" "||" "-|" "_|_" "|-" "||-" "|=" "||=" "##" "###" "####"
							"#{" "#[" "]#" "#(" "#?" "#_" "#_(" "#:" "#!" "#=" "^=" "<$>" "<$"
							"$>" "<+>" "<+" "+>" "<*>" "<*" "*>" "</" "</>" "/>" "<!--" "<#--"
							"-->" "->" "->>" "<<-" "<-" "<=<" "=<<" "<<=" "<==" "<=>" "<==>"
							"==>" "=>" "=>>" ">=>" ">>=" ">>-" ">-" "-<" "-<<" ">->" "<-<" "<-|"
							"<=|" "|=>" "|->" "<->" "<~~" "<~" "<~>" "~~" "~~>" "~>" "~-" "-~"
							"~@" "[||]" "|]" "[|" "|}" "{|" "[<" ">]" "|>" "<|" "||>" "<||"
							"|||>" "<|||" "<|>" "..." ".." ".=" "..<" ".?" "::" ":::" ":=" "::="
							":?" ":?>" "//" "///" "/*" "*/" "/=" "//=" "/==" "@_" "__" "???"
							"<:<" ";;;"))
    (global-ligature-mode t))

Visual mode

We turn on visual mode, so that lines can wrap nicely and do go beyond my Emacs buffer size.

  (visual-line-mode t)

Theme

I use catppuccin as my theme, as I find it comfortable to work with (the Frappe flavor).

  (use-package catppuccin-theme
    :init
    (setq catppuccin-flavor 'frappe)
    :config
    (load-theme 'catppuccin :no-confirm))

Modeline

I use doom-modeline as my modeline, as I find it really clean and minimal.

  (use-package doom-modeline
  :ensure t
  :init (doom-modeline-mode 1)
  :config
  (setq doom-modeline-height 30)
  (setq nerd-icons-font-family "monospace"))

Completion

I use vertico as my completion framework. It's minimal, fast and tells me all I need to know and even sorts by history.

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

      ;; Different scroll margin
      ;; (setq vertico-scroll-margin 0)

      ;; Show more candidates
      ;; (setq vertico-count 20)

      ;; Grow and shrink the Vertico minibuffer
      (setq vertico-resize t)

      ;; Optionally enable cycling for `vertico-next' and `vertico-previous'.
      (setq vertico-cycle t))

    ;; Persist history over Emacs restarts. Vertico sorts by history position.
    (use-package savehist
      :init
      (savehist-mode))

    ;; A few more useful configurations...
    (use-package emacs
      :init
      ;; Add prompt indicator to `completing-read-multiple'.
      ;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma.
      (defun crm-indicator (args)
	(cons (format "[CRM%s] %s"
		      (replace-regexp-in-string
		       "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
		       crm-separator)
		      (car args))
	      (cdr args)))
      (advice-add #'completing-read-multiple :filter-args #'crm-indicator)

      ;; Do not allow the cursor in the minibuffer prompt
      (setq minibuffer-prompt-properties
	    '(read-only t cursor-intangible t face minibuffer-prompt))
      (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)

      ;; Support opening new minibuffers from inside existing minibuffers.
      (setq enable-recursive-minibuffers t)

      ;; Emacs 28 and newer: Hide commands in M-x which do not work in the current
      ;; mode.  Vertico commands are hidden in normal buffers. This setting is
      ;; useful beyond Vertico.
      (setq read-extended-command-predicate #'command-completion-default-include-p))

    ;; Optionally use the `orderless' completion style.
  (use-package orderless
    :init
    ;; Configure a custom style dispatcher (see the Consult wiki)
    ;; (setq orderless-style-dispatchers '(+orderless-consult-dispatch orderless-affix-dispatch)
    ;;       orderless-component-separator #'orderless-escapable-split-on-space)
    (setq completion-styles '(orderless basic)
	  completion-category-defaults nil
	  completion-category-overrides '((file (styles partial-completion)))))

which-key

which-key is a nice little package that allows to have a minibuffer showing which keybinds are available under prefixes.

  (use-package which-key
    :config
    (which-key-mode))

quelpa

quelpa is a package that allows to build packages from source.

  (unless (package-installed-p 'quelpa)
    (with-temp-buffer
      (url-insert-file-contents "https://raw.githubusercontent.com/quelpa/quelpa/master/quelpa.el")
      (eval-buffer)
      (quelpa-self-upgrade)))

use-package integration with quelpa.

  (quelpa
     '(quelpa-use-package
     :fetcher git
     :url "https://github.com/quelpa/quelpa-use-package.git"))
  (require 'quelpa-use-package)

Reload org config config on save

This allows to tangle automatically when saving the config. This is mostly for convenience.

  (use-package org-auto-tangle
    :hook (org-mode . org-auto-tangle-mode)
  :config
  (defun my/reload-config-on-save ()
    (when (string-equal (buffer-file-name)
			(expand-file-name "~/.emacs.d/config.org"))
      (load-file (expand-file-name "~/.emacs.d/config.el"))))
    (add-hook 'after-save-hook #'my/reload-config-on-save))

Org mode

Pretty bullets and headlines

I use org-superstar-mode, as it makes headlines and bullets look really nice.

  (use-package org-superstar
    :hook (org-mode . org-superstar-mode))

Programming

LSP

  (defun my-lsp-mode-setup ()
    "Enable lsp-mode except in org-mode and emacs-lisp-mode."
    (unless (or (derived-mode-p 'org-mode)
		(derived-mode-p 'emacs-lisp-mode))
      (lsp)))

  (use-package lsp-mode
    :hook (prog-mode . my-lsp-mode-setup)
    (lsp-mode . lsp-enable-which-key-integration)
    :init
    (setq lsp-keymap-prefix "C-c l")
    (setq read-process-output-max (* 1024 1024))
    (setq gc-cons-threshold 100000000))
  (use-package lsp-ui)

Projectile

  (use-package projectile
    :config
    (projectile-mode +1)
    (setq projectile-project-search-path '("~/projects"))
    :bind
    ("C-c p" . 'projectile-command-map))

Autocompletion

  (use-package company
    :config
    (setq company-idle-delay 0))

Snippets

  (use-package yasnippet
    :ensure t
    :diminish yas-minor-mode
    :hook (prog-mode . yas-minor-mode)
    :bind (:map yas-minor-mode-map
		("C-c C-e" . yas-expand)))

Magit

Magit is a git client in Emacs.

  (use-package magit)

Languages

Rust
  (use-package rust-mode
    :init
    (setq rust-format-on-save t))
Typst
  (use-package typst-ts-mode
    :quelpa (typst-ts-mode :fetcher git :url "https://git.sr.ht/~meow_king/typst-ts-mode" :files ("*.el"))
    :custom
    (typst-ts-mode-grammar-location (expand-file-name "tree-sitter/libtree-sitter-typst.so" user-emacs-directory)))
tree-sitter
  (setq treesit-language-source-alist
	'((bash "https://github.com/tree-sitter/tree-sitter-bash")
	  (cmake "https://github.com/uyha/tree-sitter-cmake")
	  (css "https://github.com/tree-sitter/tree-sitter-css")
	  (elisp "https://github.com/Wilfred/tree-sitter-elisp")
	  (go "https://github.com/tree-sitter/tree-sitter-go")
	  (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")
	  (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")
	  (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")
	  (typst "https://github.com/uben0/tree-sitter-typst")
	  (yaml "https://github.com/ikatyang/tree-sitter-yaml")))

  (add-to-list 'auto-mode-alist '("\\.ts\\'" . tsx-ts-mode))
  (add-to-list 'auto-mode-alist '("\\.tsx\\'" . tsx-ts-mode))
  npm install -g typescript-language-server
Alapheia
  (use-package apheleia
    :ensure t
    :config
    (apheleia-global-mode +1)
    (setf (alist-get 'prettier apheleia-formatters)
	  '(npx "prettier" file))
    (setf (alist-get 'prettier-typescript apheleia-formatters)
	  '(npx "prettier" file)))
  (use-package dtrt-indent)
expand-region
  (use-package expand-region
    :bind ("C-=" . er/expand-region))