Settings which are not package-specific
(use-package emacs
:preface
(defvar alx/indent-width 2)
(defvar alx/gc-threshold 100000000) ; 100mb
:config
(setq ring-bell-function 'ignore
gc-cons-threshold alx/gc-threshold
gc-cons-percentage 0.1)
(setq read-process-output-max (* 1024 1024)) ;; 1mb
;; Disable default toolbar and menubar
(tool-bar-mode -1)
(menu-bar-mode -1)
;; Highlight active line
(global-hl-line-mode t)
;; Use Y/N instead of yes/no
(fset 'yes-or-no-p 'y-or-n-p)
;; Comment style
(setq comment-style 'extra-line)
;; Make complation buffers follow output
(setq compilation-scroll-output t)
;; Always use spaces
(setq-default indent-tabs-mode nil
tab-width alx/indent-width
js-indent-level 2)
(setq warning-suppress-types '((comp)))
)
Store all Custom settings in a separate file so it doesn’t write into init.el
(use-package cus-edit
:straight nil
:config
(setq custom-file "~/.emacs.d/custom.el")
)
Don’t show default startup screen
(use-package "startup"
:straight nil
:config (setq inhibit-startup-screen t))
Disable scrollbar
(use-package scroll-bar
:straight nil
:config (scroll-bar-mode -1))
Enable column/line numbers in modeline
(use-package simple
:straight nil
:diminish visual-line-mode
:config
(line-number-mode +1)
(column-number-mode +1)
)
Auto-reverting files edited outside of Emacs
(use-package autorevert
:straight nil
:config
(global-auto-revert-mode +1)
(setq auto-revert-interval 3
auto-revert-check-vc-info nil
global-auto-revert-non-file-buffers t
auto-revert-verbose nil)
)
(use-package time
:straight nil
:config
(setq display-time-24hr-format t
display-time-day-and-date t
display-time-format "%H:%M"
display-time-load-average-threshold 100) ;; This makes the load always hidden
(display-time)
)
Save backups in one directory, also dont create lockfiles since they’re annoying
(setq delete-by-moving-to-trash 't)
(setq backup-directory-alist
`(("." . ,(concat user-emacs-directory "backups"))))
(setq auto-save-file-name-transforms
`((".*" ,temporary-file-directory t)))
(setq create-lockfiles nil)
Frame settings
(use-package frame
:straight nil
:config
(setq initial-frame-alist (quote ((fullscreen . maximized))))
(when (member "MesloLGS Nerd Font" (font-family-list))
(message "Font exists on system")
(set-frame-font "MesloLGS Nerd Font" t t)
)
)
(use-package dired
:straight nil
:custom
(delete-by-moving-to-trash t)
:config
(put 'dired-find-alternate-file 'disabled nil)
(setq dired-listing-switches "-alh"))
Show matching parentheses, automatically insert closing brackets.
(use-package paren
:straight nil
:init
(setq show-paren-delay 0
show-paren-when-point-inside-paren t)
:config (show-paren-mode))
(use-package elec-pair
:straight nil
:hook (prog-mode . electric-pair-mode))
(use-package cc-vars
:straight nil
:config
(setq-default c-basic-offset alx/indent-width)
(setq c-default-style '((java-mode . "java")
(awk-mode . "awk")
(other . "k&r")))
)
(use-package js
:straight nil
:config (setq js-indent-level alx/indent-width))
(use-package css-mode
:straight nil
:config (setq css-indent-offset alx/indent-width))
(use-package python
:straight nil
:config (setq python-indent-offset alx/indent-width))
(use-package python-black
:after python
:config
(add-hook 'python-mode-hook 'python-black-on-save-mode))
(use-package delsel
:straight nil
:config
(delete-selection-mode +1))
Windmove-keybinding for switching windows using <shift>+[up|down|right|left].
(use-package windmove
:straight nil
:config (windmove-default-keybindings))
Tell ediff to split windows horizontally.
(use-package ediff
:straight nil
:config
(setq ediff-split-window-function (quote split-window-horizontally))
)
(use-package eldoc
:straight nil
:diminish
:hook (prog-mode . eldoc-mode)
:config (setq eldoc-idle-delay 0.4))
Epa-file doesn’t seem to work on Mac without this option
(use-package epa
:config
(setq epa-pinentry-mode 'loopback)
)
(use-package mwheel
:straight nil
:config
(setq mouse-wheel-scroll-amount '(1 ((shift) . 1))
mouse-wheel-progressive-speed nil))
Settings for the custom Mac OS build of Emacs.
(setq ns-use-srgb-colorspace nil)
(setq mac-option-modifier 'meta)
(setq mac-command-modifier 'super)
(use-package evil
:init
(setq evil-want-abbrev-expand-on-insert-exit nil
evil-want-C-i-jump nil
evil-want-keybinding nil
evil-search-module 'isearch
evil-ex-search-vim-style-regexp t)
:config
(define-key evil-motion-state-map (kbd "TAB") nil)
(add-to-list 'evil-emacs-state-modes 'magit-mode)
(add-to-list 'evil-emacs-state-modes 'magit-blame-mode)
(add-to-list 'evil-emacs-state-modes 'xref--xref-buffer-mode)
(evil-mode)
)
(use-package evil-surround
:after evil
:config (global-evil-surround-mode 1))
(use-package evil-collection
:after evil
:diminish evil-collection-unimpaired-mode
:config
(setq evil-collection-company-use-tng nil)
(evil-collection-init '(dired)))
(use-package evil-matchit
:after evil
:config
(global-evil-matchit-mode))
Packages and settings providing visual customization to Emacs
Use “doom-dracula” theme from doom-themes package
(use-package doom-themes
:config
(load-theme 'doom-shades-of-purple t))
Using doom-modeline, it’s pretty and just works.
(use-package doom-modeline
:config
(doom-modeline-def-modeline 'alx-custom
'(eldoc bar workspace-name window-number modals matches follow buffer-info remote-host buffer-position word-count parrot selection-info)
'(compilation objed-state misc-info persp-name battery grip irc mu4e gnus github debug repl lsp minor-modes input-method indent-info buffer-encoding major-mode process check time))
(add-hook 'doom-modeline-mode-hook
(lambda ()
(doom-modeline-set-modeline 'alx-custom 'default)))
(doom-modeline-mode)
)
Beacon provides visual feedback highlighting the point after the user performs any kind of jump (switching buffers, jumping pages in a file etc.)
(use-package beacon
:diminish
:config
(beacon-mode 1))
(use-package dimmer
:config
(setq dimmer-fraction 0.4)
(dimmer-configure-posframe)
(dimmer-configure-magit)
(dimmer-configure-which-key)
(dimmer-mode))
(use-package solaire-mode
:config
(solaire-global-mode))
Minor mode for highlighting indentation levels.
(use-package highlight-indent-guides
:config
(setq highlight-indent-guides-method 'character))
(use-package all-the-icons
:config (setq all-the-icons-scale-factor 1.0))
(use-package all-the-icons-ivy
:hook (after-init . all-the-icons-ivy-setup))
Small package for displaying neat icons in Dired buffers.
(use-package all-the-icons-dired
:hook (dired-mode . all-the-icons-dired-mode))
(use-package golden-ratio
:config
(golden-ratio-mode))
(use-package spacious-padding
:config
(spacious-padding-mode))
(use-package dashboard
:config
(dashboard-setup-startup-hook)
(setq dashboard-banner-logo-title "Welcome back!")
(setq dashboard-startup-banner 'logo)
(setq dashboard-items '((recents . 5)
(projects . 5)))
)
(use-package counsel
:diminish
:hook (ivy-mode . counsel-mode))
(use-package counsel-projectile
:config (counsel-projectile-mode +1))
(use-package ivy
:diminish
:hook (after-init . ivy-mode)
:config
(define-key ivy-minibuffer-map (kbd "RET") #'ivy-alt-done)
(define-key ivy-minibuffer-map (kbd "<escape>") #'minibuffer-keyboard-quit)
(setq ivy-re-builders-alist
'((counsel-rg . ivy--regex-plus)
(counsel-projectile-rg . ivy--regex-plus)
(counsel-ag . ivy--regex-plus)
(counsel-projectile-ag . ivy--regex-plus)
(swiper . ivy--regex-plus)
(t . ivy--regex-plus)))
(setq ivy-use-virtual-buffers t
ivy-count-format "(%d/%d) "
ivy-initial-inputs-alist nil)
)
(use-package ivy-rich
:preface
(defun ivy-rich-switch-buffer-icon (candidate)
(with-current-buffer
(get-buffer candidate)
(all-the-icons-icon-for-mode major-mode)))
:init
(setq ivy-rich-display-transformers-list ; max column width sum = (ivy-poframe-width - 1)
'(ivy-switch-buffer
(:columns
((ivy-rich-switch-buffer-icon (:width 2))
(ivy-rich-candidate (:width 80))
(ivy-rich-switch-buffer-project (:width 40 :face success))
(ivy-rich-switch-buffer-major-mode (:width 40 :face warning)))
:predicate
(lambda (cand) (get-buffer cand)))
counsel-M-x
(:columns
((counsel-M-x-transformer (:width 55))
(ivy-rich-counsel-function-docstring (:width 154 :face font-lock-doc-face))))))
:config
(ivy-rich-mode +1)
(setcdr (assq t ivy-format-functions-alist) #'ivy-format-function-line))
(use-package ivy-xref
:init
;; xref initialization is different in Emacs 27 - there are two different
;; variables which can be set rather than just one
(when (>= emacs-major-version 27)
(setq xref-show-definitions-function #'ivy-xref-show-defs))
;; Necessary in Emacs <27. In Emacs 27 it will affect all xref-based
;; commands other than xref-find-definitions (e.g. project-find-regexp)
;; as well
(setq xref-show-xrefs-function #'ivy-xref-show-xrefs))
(use-package swiper
:after ivy
:config
(setq swiper-action-recenter t
swiper-goto-start-of-match t))
(use-package ivy-posframe
:after ivy
:diminish
:config
(setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-frame-center)))
(setq ivy-posframe-parameters '((internal-border-width . 10)
(left-fringe . 8)
(right-fringe . 8)))
(setq ivy-posframe-height-alist '((t . 40)))
(setq ivy-posframe-width 200)
(setq ivy-posframe-min-height 40)
(setq ivy-posframe-height 40)
(ivy-posframe-mode +1))
(use-package prescient
:custom
(prescient-filter-method '(literal regexp initialism fuzzy))
:config
(prescient-persist-mode +1))
(use-package ivy-prescient
:after (prescient ivy)
:custom
(ivy-prescient-sort-commands
'(:not swiper
counsel-projectile-rg
ivy-switch-buffer
counsel-switch-buffer))
(ivy-prescient-retain-classic-highlighting t)
:config
(ivy-prescient-mode +1))
(use-package company-prescient
:after (prescient company)
:config
(company-prescient-mode +1))
(use-package which-key
:diminish
:config
(setq which-key-idle-delay 0.5)
(which-key-mode))
(use-package exec-path-from-shell
:config
(when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize)))
(use-package magit
:config
(add-hook 'with-editor-mode-hook #'evil-insert-state)
(transient-append-suffix 'magit-commit "-A"
'("-N" "Don't sign with GPG" "--no-gpg-sign"))
)
(use-package browse-at-remote)
These packages provide various ways to navigate between buffers, windows and frames. Basically, these are used to change what’s on my screen at any given time.
(use-package projectile
:diminish
:config
(setq projectile-sort-order 'recentf
projectile-indexing-method 'hybrid
projectile-completion-system 'ivy)
(projectile-mode)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map))
(use-package treemacs)
(use-package perspective
:demand t
:config
(setq persp-modestring-short t)
(unless (equal persp-mode t)
(persp-mode)))
(use-package persp-projectile)
General.el for easily remapping keybindings
(use-package general
:demand
:config
(general-define-key
:states '(normal visual motion insert emacs)
:prefix "SPC"
:non-normal-prefix "M-SPC"
:keymaps 'override
"SPC" '(counsel-M-x :which-key "Extended command")
"R" '(ivy-resume :which-key "Resume ivy session")
;; File actions
"f" '(:ignore t :which-key "Files")
"ff" '(counsel-find-file :which-key "Find file")
"fp" '(projectile-find-file :which-key "File file in project")
"fs" '(save-buffer :which-key "Save buffer")
"fS" '(save-some-buffers :which-key "Save all buffers")
;; Dired actions
"d" '(:ignore t :which-key "Dired")
"dd" '(dired :which-key "Open dired")
"dj" '(dired-jump :which-key "Dired jump")
;; Projectile actions
"p" '(:ignore t :which-key "Projectile")
"pp" '(projectile-switch-project :which-key "Switch project")
"pf" '(projectile-find-file :which-key "Find file in project")
"pd" '(projectile-find-dir :which-key "Open directory in project")
"pK" '(projectile-kill-buffers :which-key "Kill project buffers")
"pss" '(projectile-ag :which-key "Search in project (ag)")
"psr" '(projectile-ripgrep :which-key "Search in project (ripgrep)")
"psg" '(projectile-grep :which-key "Search in project (grep)")
;; Search actions
"s" '(:ignore t :which-key "Search")
"ss" '(swiper :which-key "Swiper (ivy)")
;; Git actions
"g" '(:ignore t :which-key "Git")
"gl" '(browse-at-remote :which-key "Browse at remote")
"gs" '(magit-status :which-key "Magit status")
"gb" '(magit-blame :which-key "Magit blame")
"gmn" '(smerge-next :which-key "SMerge: Next")
"gmp" '(smerge-prev :which-key "SMerge: Prev")
"gmU" '(smerge-keep-upper :which-key "SMerge: Keep upper")
"gmL" '(smerge-keep-lower :which-key "SMerge: Keep lower")
"gmA" '(smerge-keep-all :which-key "SMerge: Keep all")
;; Buffer actions
"b" '(:ignore t :which-key "Buffers")
"bb" '(persp-ivy-switch-buffer :which-key "Buffer list (perspective)")
"bB" '(ivy-switch-buffer :which-key "Buffer list (all)")
"bk" '(kill-buffer :which-key "Kill buffer")
"bc" '(whitespace-cleanup :which-key "Whitespace cleanup")
"bs" '(scratch-buffer :which-key "Open scratch buffer")
;; Window actions
"w" '(:ignore t :which-key "Windows")
"wk" '(delete-window :which-key "Close window")
"wr" '(split-window-right :which-key "Split window right")
"wd" '(split-window-below :which-key "Split window down")
"wb" '(balance-windows :which-key "Balance windows")
;; Toggles and other adjustments
"t" '(:ignore t :which-key "Settings")
"tw" '(global-whitespace-mode :which-key "Toggle whitespace-mode")
"tf" '(global-text-scale-adjust :which-key "Adjust text size")
"tg" '(highlight-indent-guides-mode :which-key "Indent guides")
"tl" '(global-display-line-numbers-mode :which-key "Line numbers")
"td" '(dimmer-mode :which-key "Dimmer-mode")
"tR" '(rainbow-mode :which-key "Rainbow-mode")
"q" '(:ignore t :which-key "Perspective")
"qn" '(persp-next :which-key "Next perspective")
"qp" '(persp-prev :which-key "Prev. perspective")
"qs" '(persp-switch :which-key "Switch perspective")
"qk" '(persp-kill :which-key "Kill perspective")
;; Xref
"x" '(:ignore t :which-key "Xref")
"xd" '(xref-find-definitions :which-key "Find definitions")
"xD" '(xref-find-definitions-other-window :which-key "Find definitions (other window)")
"xr" '(xref-find-references :which-key "Find references")
"xR" '(lsp-treemacs-references :which-key "Show reference tree")
"xI" '(lsp-treemacs-implementations :which-key "Show implementation tree")
;; LSP
"l" '(:ignore t :which-key "LSP")
"ls" '(lsp-ivy-workspace-symbol :which-key "Find symbol")
"lS" '(lsp-ivy-global-workspace-symbol :which-key "Find symbol (global)")
"lc" '(lsp-execute-code-action :which-key "Code action")
"li" '(lsp-ui-imenu :which-key "Open imenu side window")
;; Org
"o" '(:ignore t :which-key "Org")
"oc" '(org-capture :which-key "Org Capture")
"oa" '(org-agenda :which-key "Org Agenda")
"ol" '(org-store-link :which-key "Store link")
"oL" '(org-insert-link :which-key "Insert link")
))
(use-package evil-nerd-commenter
:config
(evilnc-default-hotkeys))
(use-package anzu
:diminish
:config
(global-anzu-mode +1))
Language Server Protocol support for various languages.
(use-package lsp-mode
:hook ((java-mode
kotlin-mode
python-mode
js-mode
typescript-mode
rjsx-mode
web-mode
rust-mode
csharp-mode
elixir-mode
haskell-mode
terraform-mode
) . lsp)
:commands lsp
:config
(setq lsp-enable-links t)
(setq lsp-prefer-flymake nil)
(setq lsp-keep-workspace-alive nil)
(setq lsp-terraform-ls-prefill-required-fields t))
(use-package lsp-ivy)
(use-package lsp-treemacs
:after treemacs)
(use-package lsp-ui
:after lsp-mode
:config
(setq lsp-ui-doc-delay 0.5)
(setq lsp-ui-docs-show-with-cursor t)
(setq lsp-ui-sideline-enable nil)
)
(use-package lsp-java
:after lsp
:config
(setq lsp-java-save-action-organize-imports nil)
)
(use-package lsp-haskell
:after lsp)
(use-package company
:bind ("<backtab>" . company-complete)
:diminish
:config
(setq company-minimum-prefix-length 1
company-idle-delay 0.0)
:hook (prog-mode . company-mode)
)
(use-package flycheck
:diminish
:hook (prog-mode . flycheck-mode))
(use-package flycheck-posframe
:diminish
:config
(setq flycheck-posframe-position 'point-bottom-left-corner-upward)
(add-hook 'flycheck-mode-hook 'flycheck-posframe-mode))
Various packages providing modes for specific programming (and markup) languages
(use-package rjsx-mode
:config
(add-to-list 'auto-mode-alist '("\\.jsx?$" . rjsx-mode)))
(use-package typescript-mode
:after (typescript-mode company flycheck add-node-modules-path)
:config
(add-hook 'typescript-mode-hook #'add-node-modules-path)
(add-to-list 'auto-mode-alist '("\\.tsx?$" . typescript-mode))
)
(use-package web-mode
:after flycheck
:config
(flycheck-add-mode 'javascript-eslint 'web-mode)
;;(add-to-list 'auto-mode-alist '("\\.tsx$" . web-mode))
)
(use-package json-mode
:config
(defun my-json-indent ()
"Set tab width to 2 when entering json-mode"
(setq js-indent-level 2))
(add-hook 'json-mode-hook 'my-json-indent)
)
(use-package rust-mode
:config
(add-hook 'before-save-hook (lambda () (when (eq 'rust-mode major-mode)
(lsp-format-buffer))))
)
(use-package go-mode
:hook (go-mode . lsp)
)
(use-package elixir-mode
:config
(add-hook 'before-save-hook (lambda () (when (eq 'elixir-mode major-mode)
(lsp-format-buffer))))
)
(use-package haskell-mode)
(use-package powershell)
(use-package yaml-mode
:config
(add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode)))
(use-package dockerfile-mode
:config
(add-to-list 'auto-mode-alist '("Dockerfile\\'" . dockerfile-mode)))
(use-package terraform-mode
:config
(add-hook 'terraform-mode-hook #'terraform-format-on-save-mode))
Emacs 29 introduced native treesitter support
(use-package treesit-auto
:custom
(treesit-auto-install 'prompt)
:config
(delete 'yaml treesit-auto-langs) ;; Yaml-ts-mode is bad.
(global-treesit-auto-mode))
(use-package yasnippet-snippets
:diminish)
(use-package yasnippet
:diminish yas-minor-mode
:after yasnippet-snippets
:config
(yas-global-mode 1))
(use-package editorconfig
:diminish
:config
(editorconfig-mode 1))
(use-package rainbow-mode
:diminish)
(use-package wgrep
:diminish)
(use-package add-node-modules-path)
(use-package prettier-js
:after add-node-modules-path
:diminish
:hook ((web-mode . prettier-js-mode)
(js2-mode . prettier-js-mode)
(typescript-mode . prettier-js-mode))
:config
(eval-after-load 'web-mode
'(progn
(add-hook 'web-mode-hook #'add-node-modules-path)
(add-hook 'web-mode-hook #'prettier-js-mode)))
(eval-after-load 'typescript-mode
'(progn
(add-hook 'typescript-mode-hook #'add-node-modules-path)
(add-hook 'typescript-mode-hook #'prettier-js-mode)))
)
(use-package org
:diminish org-indent-mode
:hook ((org-mode . visual-line-mode)
(org-mode . org-indent-mode))
:config
(setq org-export-html-postamble nil
org-log-done 'time
org-ellipsis "⤵"
org-src-window-setup 'current-window)
(add-to-list 'org-modules 'org-tempo))
(use-package org-bullets
:after org
:hook (org-mode . org-bullets-mode))
I want to use `keyfreq` to identify which commands I use the most, so I can assign keybinds to common commands.
(use-package keyfreq
:init
(keyfreq-mode 1)
(keyfreq-autosave-mode 1))
(use-package diminish
:demand t)
(defun alx/reload-config ()
"Evaluate init.el file."
(interactive)
(load (expand-file-name (concat user-emacs-directory "init.el")))
)