Skip to content

Latest commit

 

History

History
857 lines (774 loc) · 23.9 KB

config.org

File metadata and controls

857 lines (774 loc) · 23.9 KB

Emacs configuration

Basic settings

Settings which are not package-specific

Emacs

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

Custom file

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

Startup

Don’t show default startup screen

(use-package "startup"
  :straight nil
  :config (setq inhibit-startup-screen t))

Scrollbar

Disable scrollbar

(use-package scroll-bar
  :straight nil
  :config (scroll-bar-mode -1))

Column/line numbers

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

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

Display time in modeline

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

Backup directory and settings

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

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

Dired

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

Parentheses

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

Indentation

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

Delsel-mode

(use-package delsel
  :straight nil
  :config
  (delete-selection-mode +1))

Winner-mode/windmove

Windmove-keybinding for switching windows using <shift>+[up|down|right|left].

(use-package windmove
  :straight nil
  :config (windmove-default-keybindings))

Ediff

Tell ediff to split windows horizontally.

(use-package ediff
  :straight nil
  :config
  (setq ediff-split-window-function (quote split-window-horizontally))
  )

Eldoc

(use-package eldoc
  :straight nil
  :diminish
  :hook (prog-mode . eldoc-mode)
  :config (setq eldoc-idle-delay 0.4))

EPG

Epa-file doesn’t seem to work on Mac without this option

(use-package epa
  :config
  (setq epa-pinentry-mode 'loopback)
  )

Mouse wheel settings

(use-package mwheel
  :straight nil
  :config
  (setq mouse-wheel-scroll-amount '(1 ((shift) . 1))
        mouse-wheel-progressive-speed nil))

Mac OS settings

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)

Packages

Evil-mode

Use evil-mode

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

Visual

Packages and settings providing visual customization to Emacs

Theme

Use “doom-dracula” theme from doom-themes package

(use-package doom-themes
 :config
 (load-theme 'doom-shades-of-purple t))

Modeline

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

Highlighting

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

Indent guides

Minor mode for highlighting indentation levels.

(use-package highlight-indent-guides
  :config
  (setq highlight-indent-guides-method 'character))

Icons

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

Dired icons

Small package for displaying neat icons in Dired buffers.

(use-package all-the-icons-dired
  :hook (dired-mode . all-the-icons-dired-mode))

Window sizing

(use-package golden-ratio
  :config
  (golden-ratio-mode))

(use-package spacious-padding
  :config
  (spacious-padding-mode))

Startup dashboard

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

Ivy

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

Prescient

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

Utilities

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

Git/VC

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

Navigation

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)

Key bindings (general.el)

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

Editing

(use-package evil-nerd-commenter
  :config
  (evilnc-default-hotkeys))

(use-package anzu
  :diminish
  :config
  (global-anzu-mode +1))

LSP

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)

Autocomplete

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

Flycheck

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

Programming

Language support

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

Tree-sitter

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

Development utilities

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

Prettier integration

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

Org-mode and other stuff

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

Keyfreq

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

Diminish mode

(use-package diminish
  :demand t)

Custom functions

(defun alx/reload-config ()
  "Evaluate init.el file."
  (interactive)
  (load (expand-file-name (concat user-emacs-directory "init.el")))
  )