2024-07-06 12:47:22 +00:00
#+TITLE : Emacs literate configuration
2024-07-05 00:57:55 +00:00
#+AUTHOR : Anthony Rodriguez
2024-07-06 12:47:22 +00:00
#+PROPERTY : header-args:emacs-lisp :tangle ~/.emacs.d/init.el
* Table of Contents :TOC:
- [[#packages-initialization ][Packages initialization ]]
- [[#vc-use-package ][vc-use-package ]]
- [[#general-config ][General config ]]
2024-07-06 13:18:51 +00:00
- [[#move-temporary-files-to-tmpusername ][Move temporary files to /tmp/{username} ]]
2024-07-06 12:47:22 +00:00
- [[#minimal-interface ][Minimal interface ]]
2024-07-08 22:01:10 +00:00
- [[#mode-line ][Mode line ]]
2024-07-06 12:47:22 +00:00
- [[#match-fish-shells-path ][Match fish shell's path ]]
- [[#bell ][Bell ]]
- [[#font ][Font ]]
- [[#visual-mode ][Visual mode ]]
- [[#theme ][Theme ]]
- [[#completion ][Completion ]]
- [[#which-key ][which-key ]]
- [[#org-mode ][Org mode ]]
- [[#pretty-bullets-and-headlines ][Pretty bullets and headlines ]]
- [[#toc-org ][toc-org ]]
- [[#programming ][Programming ]]
- [[#eglot ][Eglot ]]
- [[#autocompletion ][Autocompletion ]]
- [[#snippets ][Snippets ]]
- [[#magit ][Magit ]]
- [[#docker ][Docker ]]
2024-07-17 01:03:35 +00:00
- [[#popper ][popper ]]
2024-07-06 12:47:22 +00:00
- [[#languages ][Languages ]]
2024-07-05 00:57:55 +00:00
* Packages initialization
Here, we're initializing MELPA, as well as package.el and use-package.
2024-07-06 12:47:22 +00:00
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
(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))
(require 'use-package)
(setq use-package-always-ensure t)
#+end_src
** vc-use-package
2024-07-06 12:52:49 +00:00
vc-use-package integrates package-vc-install, which allows installing packages from git repositories, into use-package. It won't be needed from Emacs 30, as it will integrate natively.
2024-07-05 00:57:55 +00:00
2024-07-06 12:47:22 +00:00
#+begin_src emacs-lisp
2024-07-06 12:52:49 +00:00
(if (< emacs-major-version 30)
(unless (package-installed-p 'vc-use-package)
(package-vc-install "https://github.com/slotThe/vc-use-package"))
(require 'vc-use-package))
#+end_src
2024-07-05 00:57:55 +00:00
* General config
2024-07-06 13:18:51 +00:00
** Move temporary files to /tmp/{username}
2024-07-06 12:47:22 +00:00
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
2024-07-05 21:20:34 +00:00
(defvar user-temporary-file-directory
(concat temporary-file-directory user-login-name "/"))
(make-directory user-temporary-file-directory t)
(setq backup-by-copying t)
(setq backup-directory-alist
`(("." . ,user-temporary-file-directory)
(,tramp-file-name-regexp nil)))
(setq auto-save-list-file-prefix
(concat user-temporary-file-directory ".auto-saves-"))
(setq auto-save-file-name-transforms
`((".*" ,user-temporary-file-directory t)))
2024-07-05 00:57:55 +00:00
#+end_src
** Minimal interface
We disable a lot of interface elements, to make the editor more minimal looking.
2024-07-06 12:47:22 +00:00
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
(setq inhibit-startup-message t)
(scroll-bar-mode -1)
(tool-bar-mode -1)
(tooltip-mode -1)
(set-fringe-mode 10)
(menu-bar-mode -1)
#+end_src
2024-07-08 22:01:10 +00:00
** Mode line
#+begin_src emacs-lisp
(use-package moody
:config
(moody-replace-mode-line-front-space)
(moody-replace-mode-line-buffer-identification)
(moody-replace-vc-mode))
#+end_src
2024-07-05 00:57:55 +00:00
** Match fish shell's path
#+begin_src emacs-lisp
(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)
#+end_src
** Bell
I don't like any visual or sound bell.
2024-07-06 12:47:22 +00:00
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
(setq ring-bell-function 'ignore)
#+end_src
** Font
I use two different fonts in Emacs : my sans serif font for anything where variable fonts wouldn't matter, and monospace for fixed width text (such as code, org blocks and org tables). I like to use the generic sans-serif and monospace fonts, as it allows me to define them system-wide, which I highly prefer.
2024-07-06 12:47:22 +00:00
Besides the font settings, I use the package fixed-pitch, which sets up hooks automatically for all the modes that require fixed width fonts. This allows me to have my sans serif everywhere else.
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
(custom-theme-set-faces
'user
2024-07-07 22:20:54 +00:00
;; global faces
'(default ((t (:family "monospace" :height 125))))
2024-07-07 22:37:22 +00:00
'(variable-pitch ((t (:family "DejaVu Sans" :height 125))))
'(fixed-pitch ((t (:family "monospace" :height 125))))
2024-07-07 22:20:54 +00:00
;; org mode specific faces
2024-07-05 00:57:55 +00:00
'(org-block ((t (:inherit fixed-pitch))))
'(org-code ((t (:inherit (shadow fixed-pitch)))))
'(org-table ((t (:inherit fixed-pitch :foreground "#83a598")))))
2024-07-07 22:20:54 +00:00
2024-07-05 00:57:55 +00:00
(use-package fixed-pitch
:vc ( :fetcher github :repo cstby/fixed-pitch-mode))
#+end_src
*** Ligatures
#+begin_src emacs-lisp
(use-package ligature
:config
(ligature-set-ligatures 't '("www"))
(ligature-set-ligatures '(prog-mode tsx-ts-mode) '("--" "---" "==" "= ==" "!= " "!==" "= !="
"=:= " "=/= " "<=" " >=" "&&" "&&&" "&= " "++" "+ ++" "***" ";;" "!!"
"??" "???" "?:" "?." "?=" "<:" ":<" ": >" ">:" "<:<" "<>" "<<<" " >>>"
"<<" " >>" "||" "-|" "_|_ " "|-" "||-" "|=" "||= " "##" "###" "####"
"#{" "#[" "]#" "#(" "#?" "#_" "#_ (" "#:" "#!" "#=" "^= " "<$ >" "<$"
"$>" "<+ >" "<+" "+ >" "<* >" "<*" "* >" "</" "</ >" "/>" "<!--" "<#--"
"-->" "->" "->>" "<<-" "<-" "<=<" "= <<" "<<=" "<= =" "<= >" "<== >"
"==>" "= >" "=>>" ">= >" ">>=" ">>-" ">-" "-<" "-<<" " >->" "<-<" "<-|"
"<=|" "|= >" "|->" "<- >" "<~~" "<~ " "<~ >" "~~" "~ ~>" "~ >" "~-" "-~ "
"~@" "[||]" "|]" "[|" "|}" "{|" "[<" " >]" "|>" "<|" "|| >" "<||"
"|||>" "<|||" "<| >" "..." ".." ".=" "..<" ".?" "::" ":::" ":= " "::="
":?" ":?>" "//" "/ //" "/ *" "* /" "/ =" "//= " "/==" "@_" "__" "???"
"<:<" ";;;"))
(global-ligature-mode t))
#+end_src
** Visual mode
We turn on visual mode, so that lines can wrap nicely and not go beyond my Emacs buffer size.
2024-07-06 12:47:22 +00:00
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
(global-visual-line-mode t)
#+end_src
** Theme
I use catppuccin as my theme, as I find it comfortable to work with (the Frappe flavor).
2024-07-06 12:47:22 +00:00
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
(use-package catppuccin-theme
:init
(setq catppuccin-flavor 'frappe)
:config
(load-theme 'catppuccin :no-confirm))
#+end_src
** 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.
2024-07-06 12:47:22 +00:00
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
(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))
(use-package orderless
:ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles basic partial-completion)))))
#+end_src
** which-key
which-key is a nice little package that allows to have a minibuffer showing which keybinds are available under prefixes.
2024-07-06 12:47:22 +00:00
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
(use-package which-key
:config
2024-07-05 15:19:20 +00:00
(which-key-mode)
(which-key-add-key-based-replacements ;; naming prefixes
"C-c l" "lsp"))
2024-07-05 00:57:55 +00:00
#+end_src
* Org mode
2024-07-07 22:37:22 +00:00
#+begin_src emacs-lisp
(use-package org
:hook
(org-mode . variable-pitch-mode))
#+end_src
2024-07-05 00:57:55 +00:00
** Pretty bullets and headlines
I use org-superstar-mode, as it makes headlines and bullets look really nice.
2024-07-06 12:47:22 +00:00
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
(use-package org-superstar
2024-07-06 12:47:22 +00:00
:defer t
2024-07-05 00:57:55 +00:00
:hook (org-mode . org-superstar-mode))
#+end_src
2024-07-06 12:47:22 +00:00
** toc-org
This allows generating the table of contents you can find at the beginning of this file.
#+begin_src emacs-lisp
(use-package toc-org
:hook (org-mode . toc-org-mode))
#+end_src
2024-07-05 00:57:55 +00:00
* Programming
** Eglot
Eglot is a built in LSP client for Emacs. I prefer it to LSP as it's more lightweight and more straightforward to setup correctly.
2024-07-06 12:47:22 +00:00
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
2024-07-05 15:19:20 +00:00
(use-package eglot
2024-07-06 12:47:22 +00:00
:defer t
2024-07-06 13:18:51 +00:00
:config
2024-07-06 13:22:48 +00:00
(setq eglot-events-buffer-size 0) ;; important performance fix (https://www.gnu.org/software/emacs/manual/html_node/eglot/Performance.html)
2024-07-05 15:19:20 +00:00
:bind (:map eglot-mode-map
2024-07-05 21:32:56 +00:00
("C-c l h" . eldoc)
("C-c l r" . eglot-rename)
("C-c l f" . eglot-format-buffer))
2024-07-05 15:19:20 +00:00
:hook ((tsx-ts-mode . eglot-ensure)
2024-07-05 19:41:47 +00:00
(typescript-ts-mode . eglot-ensure)
2024-07-05 21:20:34 +00:00
(python-ts-mode . eglot-ensure)
2024-07-08 21:40:11 +00:00
(go-ts-mode . eglot-ensure)
2024-07-05 21:32:56 +00:00
(eglot--managed-mode . electric-pair-mode)
(eglot--managed-mode . (lambda ()
2024-07-06 13:18:51 +00:00
(add-hook 'after-save-hook #'eglot-format-buffer nil t)))
(eglot--managed-mode . display-line-numbers-mode)))
2024-07-05 15:19:20 +00:00
(setq-default eglot-workspace-configuration '(:typescript (:format (:indentSize 2
:convertTabsToSpaces t
:semicolons "remove"))))
;; makes eglot faster using a rust wrapper, needs to be in PATH
(use-package eglot-booster
2024-07-06 12:47:22 +00:00
:defer t
2024-07-05 21:32:56 +00:00
:vc (:fetcher github :repo jdtsmith/eglot-booster)
2024-07-05 15:19:20 +00:00
:after eglot
:config
(eglot-booster-mode))
2024-07-05 00:57:55 +00:00
#+end_src
** Autocompletion
#+begin_src emacs-lisp
2024-07-05 15:19:20 +00:00
2024-07-05 00:57:55 +00:00
(use-package corfu
2024-07-06 12:47:22 +00:00
:defer t
2024-07-05 00:57:55 +00:00
:custom
(corfu-auto t)
:init
(global-corfu-mode)
(setq corfu-popupinfo-delay 0.2)
(corfu-popupinfo-mode))
2024-07-07 22:20:54 +00:00
(use-package nerd-icons-corfu
:after corfu
:config
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
2024-07-05 00:57:55 +00:00
#+end_src
** Snippets
#+begin_src emacs-lisp
(use-package yasnippet
2024-07-06 12:47:22 +00:00
:defer t
2024-07-05 00:57:55 +00:00
:ensure t
:diminish yas-minor-mode
:hook (prog-mode . yas-minor-mode)
:bind (:map yas-minor-mode-map
("C-c C-e" . yas-expand)))
#+end_src
** Magit
Magit is a git client in Emacs.
2024-07-06 12:47:22 +00:00
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
2024-07-06 12:47:22 +00:00
(use-package magit
:defer t)
2024-07-05 00:57:55 +00:00
#+end_src
** Docker
#+begin_src emacs-lisp
(use-package docker
2024-07-06 12:47:22 +00:00
:defer t
2024-07-05 00:57:55 +00:00
:ensure t
:bind ("C-c d" . docker))
#+end_src
2024-07-06 12:47:22 +00:00
2024-07-17 01:03:35 +00:00
** popper
Popper is a package that allows us to have popup buffers. This is really useful when working with REPL languages such as Javascript or Go.
#+begin_src emacs-lisp
(use-package popper
:ensure t ; or :straight t
:bind (("C-c p t" . popper-toggle)
("C-c p c" . popper-cycle)
2024-07-17 01:13:25 +00:00
("C-c p w" . popper-toggle-type)
("C-c p k" . popper-kill-latest-popup))
2024-07-17 01:03:35 +00:00
:init
(setq popper-reference-buffers
'("\\*Messages\\* "
"Output\\*$"
"\\*Async Shell Command\\* "
help-mode
compilation-mode
"^\\*eshell.* \\*$" eshell-mode
"^\\*shell.* \\*$" shell-mode
"^\\*term.* \\*$" term-mode
"^\\*vterm.* \\*$" vterm-mode))
2024-07-17 01:12:35 +00:00
(which-key-add-key-based-replacements
"C-c p" "popper")
2024-07-17 01:03:35 +00:00
(popper-mode)
(popper-echo-mode))
#+end_src
2024-07-05 00:57:55 +00:00
** Languages
*** tree-sitter
Tree-sitter is a built-in Emacs package that allows us to have extremely well integrated language grammar. Here, we're setting up the list of sources, most of them being on tree-sitter's official GitHub, as well as hooking up the languages to their different modes.
2024-07-06 12:47:22 +00:00
2024-07-05 00:57:55 +00:00
#+begin_src emacs-lisp
2024-07-06 00:59:26 +00:00
(setq treesit-font-lock-level 4) ;; more coloring!
(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")
2024-07-08 21:40:11 +00:00
(gomod "https://github.com/camdencheek/tree-sitter-go-mod")
2024-07-06 00:59:26 +00:00
(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")
2024-07-07 22:20:54 +00:00
(templ "https://github.com/vrischmann/tree-sitter-templ")
2024-07-06 00:59:26 +00:00
(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")))
;; mode bindings to file extensions
2024-07-07 22:20:54 +00:00
(setq auto-mode-alist
(append '(("\\.ts\\'" . tsx-ts-mode)
("\\.tsx\\'" . tsx-ts-mode)
2024-07-08 21:40:11 +00:00
("\\.py\\'" . python-ts-mode)
("\\.go\\'" . go-ts-mode))
2024-07-07 22:20:54 +00:00
auto-mode-alist))
2024-07-05 00:57:55 +00:00
#+end_src
2024-07-16 21:42:02 +00:00
;; Local Variables:
;; eval: (add-hook 'after-save-hook (lambda ()(if (y-or-n-p "Reload?")(load-file user-init-file))) nil t)
;; eval: (add-hook 'after-save-hook (lambda ()(if (y-or-n-p "Tangle?")(org-babel-tangle))) nil t)
;; End: