dotfiles/nixos/hm-modules/emacs/.emacs.d/org/base.org
2021-02-01 12:00:24 +01:00

36 KiB

Magic_RB's Emacs configuration

Stuff That Needs Work

TODO Spell checking

TODO Calc mode

TODO Org Agenda

Make it work on my phone

TODO Org Roam

Stuff

  (when (not (string= (system-name) "fractal"))
    (use-package elcord
:straight t
:config
(elcord-mode)))

  (when (not (string= (system-name) "localhost"))
    (use-package tree-sitter
:straight t
:after (tree-sitter-langs)
:config
(global-tree-sitter-mode)
(add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode))
    (use-package tree-sitter-langs
:straight t))

  (use-package pdf-tools
    :straight t
    :hook (('TeX-mode-hook . visual-line-mode))
    :config
    ;; initialise
    (pdf-tools-install)
    (setq TeX-PDF-mode 1)
    ;; open pdfs scaled to fit page
    (setq-default pdf-view-display-size 'fit-page)
    ;; automatically annotate highlights
    (setq pdf-annot-activate-created-annotations t))

		     ;  (use-package auctex
		     ;    :ensure t)

  (use-package w3m
    :straight t)

Enable all-the-icons, it's used by treemacs and doom-modeline.

  (use-package all-the-icons
    :straight t)

Set ispell program to hunspell, this is very much a TODO, since the spelling configuration is rather minimal at this point in time.

  (setq ispell-program-name "hunspell")

Look & Feel

Color Themes

Enable doom-themes, with bold and italics. Then apply the doom-colors theme to Treemacs and improve org's native fontification somewhat.

  (use-package doom-themes
:straight t
:config
;; Global settings (defaults)
(setq doom-themes-enable-bold t    
   doom-themes-enable-italic t) 

;; Enable Treemacs doom theme
(setq doom-themes-treemacs-theme "doom-colors")
(doom-themes-treemacs-config)

;; Corrects (and improves) org-mode's native fontification.
(doom-themes-org-config))

You can also enable visual bell on error, or C-g, probably other events. But I don't like. So it's disabled :.

  (doom-themes-visual-bell-config)

First make load-theme unload all currently loaded themes and reapply fonts afterwards, then create a magic_rb/theme-select hydra bound to F6. Available themes are:

  • od for Doom One Dark
  • ol for Doom One Light
  • dr for Doom Dracula
  • mv for Modus Vivendi
  • mo for Modus Operandi
  (with-eval-after-load 'hydra
(defun magic_rb/unload-all-themes ()
"Unloads all themes."
(mapc #'disable-theme custom-enabled-themes))

(advice-add 'load-theme :before #'(lambda (orig-fun &rest args) (magic_rb/unload-all-themes)))
(advice-add 'load-theme :after #'(lambda (orig-fun &rest args) (magic_rb/apply-fonts)))

(defhydra magic_rb/theme-select (:color blue)
("od" (progn
(load-theme 'doom-one t)))
("ol" (progn
(load-theme 'doom-one-light t)))
("mv" (progn
(load-theme 'modus-vivendi t)))
("mo" (progn
(load-theme 'modus-operandi t))))

(global-set-key (kbd "<f6>") 'magic_rb/theme-select/body))

Create a function, which applies my font settings, and call it. Also branch on whether PGtk is in use, as fonts are a bit bigger with it.

  (defvar magic_rb/fixed-width-font "Fira Code")
  (defvar magic_rb/variable-pitch-font "Overpass")

  (with-eval-after-load 'dash
(defun magic_rb/apply-fonts ()
(if (-contains? (split-string system-configuration-features) "PGTK")
   (set-face-attribute 'default nil :family magic_rb/fixed-width-font :height 110)
 (set-face-attribute 'default nil :family magic_rb/fixed-width-font :height 120))
(set-face-attribute 'fixed-pitch nil :family magic_rb/fixed-width-font :height 1.0)
(set-face-attribute 'variable-pitch nil :family magic_rb/variable-pitch-font :height 1.0))
(magic_rb/apply-fonts))

Load Modus Vivendi, but change the background color to not-black, it's a bit less depressing and in my opinion nicer on the eyes.

  (setq modus-vivendi-theme-override-colors-alist 
 '(("bg-main" . "#111519")))
  (with-eval-after-load 'doom-themes
(load-theme 'doom-one t))

Dashboard

Enable the Emacs dashboard, pretty much useless but much better looking than the default. And the jokes are funny. Also if you actually properly use org-agenda the agenda of the day section might prove useful.

  (use-package dashboard
:straight t
:after (all-the-icons)
:config
(dashboard-setup-startup-hook)
(setq dashboard-items '((recents . 5)
(projects . 5)
(agenda . 5))
   dashboard-center-content t
   dashboard-set-heading-icons t
   dashboard-set-file-icons t
   dashboard-set-init-info t))

Inhibit startup screen and scratch buffer, it conflicts with emacs-dashboard

  (setq inhibit-startup-screen t
 initial-buffer-choice nil
 initial-scratch-message ";; ready\n\n")

Modeline

Enable doom-modeline, much better than the default and unline powerline it's usable with TRAMP, so that's great.

  (use-package doom-modeline
:straight t
:config
(doom-modeline-mode))

You can also control, whether doom-modeline uses all-the-icons on a per frame basis. Especially useful when running Emacs in daemon mode.

  (make-variable-buffer-local 'doom-modeline-icon)
  (add-hook 'after-make-frame-hook
(lambda ()
(setq doom-modeline-icon (display-graphic-p))))

Show battery status and time in modeline. But don't show load average. Useful when using EXWM, without a external bar.

  (display-time-mode)
  (setq display-time-load-average nil)

  (display-battery-mode)

Only show buffer encoding conditionally, there's no reason to have LF UTF-8 down there, rather only show when the encoding is something we don't expect, like CRLF or UTF-16. Inspired by tecosaur.

  (defun tecosaur/doom-modeline-conditional-buffer-encoding ()
"We expect the encoding to be LF UTF-8, so only show the modeline when this is not the case"
(setq-local doom-modeline-buffer-encoding
  (unless (or (eq buffer-file-coding-system 'utf-8-unix)
(eq buffer-file-coding-system 'utf-8)))))

  (add-hook 'after-change-major-mode-hook #'tecosaur/doom-modeline-conditional-buffer-encoding)

Miscelanious

Disable GTK decorations, as they are not "cool" as member of the Emacs mailing list would put it. Or actually my reasoning, I don't want Emacs to be influenced by GTK theming, as I don't use almost any GTK programs.

  (if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
  (menu-bar-mode -1)
  (scroll-bar-mode -1)

Enable compositor based transparency, low values will make text hard to read as everything, not just the background is made transparent. It's also possible to set the alpha separately for when a frame is in focus and when it's not.

  (add-to-list 'default-frame-alist '(alpha 100 100))
  (set-frame-parameter (selected-frame) 'alpha '(100 . 100))

Load all-the-icons, it's required used by treemacs and doom-modeline. You also must run all-the-icons-install-fonts if you haven't already.

  (use-package all-the-icons
:straight t)

Languages

Nix Expression Language

Enable nix-mode.

  (use-package nix-mode
:straight t
:mode ("\\.nix\\'" . nix-mode))

Haskell Programming Language

Enable haskell-mode.

  (use-package haskell-mode
:straight t)

HashiCorp

HashiCorp Configuration Language
  (use-package hcl-mode
:straight t)
Terraform Configuration Language
  (use-package terraform-mode
:straight t)

YAML Configuration Language

Enable yaml-mode.

  (use-package yaml-mode
:straight t
:mode ("\\.yml\\'" . yaml-mode)
:mode ("\\.yaml\\'" . yaml-mode))

Dockerfile Configuration Language

Enable dockerfile-mode

  (use-package dockerfile-mode
:straight t
:mode ("Dockerfile\\'" . dockerfile-mode))

SCAD Programming Language

Enable scad-mode

  (use-package scad-mode
:straight t)

Web Development

HTML Markup Language

Enable web-mode for .html, .xhtml and hook lsp-mode on it.

  (use-package web-mode
:straight t
:mode ("\\.html\\'" . web-mode)
:mode ("\\.xhtml\\'" . web-mode)
:hook (web-mode . lsp-mode))
CSS Style Sheet Language

Enable css-mode for .css, .scss and hook lsp-mode on it. Also make flycheck happy.

  (use-package css-mode
:mode ("\\.css\\'" . css-mode)
:mode ("\\.scss\\'". css-mode)
:hook (css-mode . lsp-mode)
:config
(with-eval-after-load "flycheck"
(flycheck-add-mode 'javascript-eslint 'web-mode)))
Javascript Programming Language

I do not personally do much Javascript development, so this mode might be completely broken or a better alternative might be available.

Enable rjsx-mode instead of javascript-mode or js2-mode as it properly handles inline HTML.

  (use-package rjsx-mode
:straight t
:config
:mode ("\\.js\\'" . rjsx-mode)
:mode ("\\.jsx\\'" . rjsx-mode)
:hook (rjsx-mode . lsp-mode))
Typescript Programming Language

Enable typescript-mode for .ts, .tsx and hook lsp-mode on it. It doesn't specifically support inline HTML, but aside from minor indentation issues it works fine.

  (use-package typescript-mode
:straight t
:config
:mode ("\\.ts\\'" . typescript-mode)
:mode ("\\.tsx\\'" . typescript-mode)
:hook (typescript-mode . lsp-mode))

Scala Programming Language

Enable scala-mode for .scala, .sbt and hook lsp-mode on it.

  (use-package scala-mode
:straight t
:mode ("\\.s\\(cala\\|bt\\)$" . scala-mode)
:hook (scala-mode . lsp-mode))

Enable sbt-mode, it's used for sbt buffers.

  (use-package sbt-mode
:straight t
:commands sbt-start sbt-command
:config
;; WORKAROUND: https://github.com/ensime/emacs-sbt-mode/issues/31
;; allows using SPACE when in the minibuffer
(substitute-key-definition
'minibuffer-complete-word
'self-insert-command
minibuffer-local-completion-map)
;; sbt-supershell kills sbt-mode:  https://github.com/hvesalai/emacs-sbt-mode/issues/152
(setq sbt:program-options '("-Dsbt.supershell=false")))

Rust Programming Language

Enable rustic and more feature-full alternative to rust-mode, actually a rather distant fork of it. Also hook lsp-mode on it.

  (use-package rustic
:straight t
:hook (rustic-mode . lsp-mode)
:mode ("\\.rs\\'" . rustic-mode))

LSP

lsp-mode

Increase GC threshold to avoid random freezes on garbage collection.

  (setq gc-cons-threshold 100000000)

Increase the amount of data Emacs reads from a process in one go, default is 4KB, but some LSP servers produce responses up to 3MB.

  (setq read-process-output-max (* (* 1024 1024) 3))

Switch completion provider to capf, even though it should be the default, but just to make sure it. company-lsp is what lsp-mode switched away from.

  (setq lsp-completion-provider :capf)

Set the minimum delay between LSP refreshes, should help with performance when typing really fast.

  (setq lsp-idle-delay 0.500) ;; adjust me

Setup rustic to prefer rust-analyzer instead of rls and also don't format on save, it's really annoying.

  (setq rustic-lsp-server 'rust-analyzer)
  (setq rustic-compile-command "cargo build")
  (setq rustic-format-trigger nil);'on-save

Enable inline type hints and disable chaining and parameter hints for Rust.

  (setq lsp-rust-analyzer-display-chaining-hints nil)
  (setq lsp-rust-analyzer-display-parameter-hints nil)
  (setq lsp-rust-analyzer-server-display-inlay-hints t)

Finally enable lsp-mode.

  (use-package lsp-mode
:straight t
:config
(setq lsp-prefer-flymake nil)
;; (lsp-mode . lsp-lens-mode)
;; :hook (tex-mode . lsp-mode)
;; (lsp-mode . display-fill-column-indicator-mode)
;; (python-mode . lsp)			;
;; (lsp-mode . origami-mode)
;; :hook (rustic . lsp-rust-analyzer-inlay-hints-mode) ;
:config
<<lsp-rustic>>
<<lsp-rust-analyzer>>

<<gc-cons-threshold>>
<<read-process-output-max>>
<<lsp-completion-provider>>
<<lsp-idle-delay>>
<<lsp-typescript-tramp>>
<<lsp-scala-tramp>>)

TRAMP support

None of the LSP client packages (many are included with lsp-mode) don't feature remote client definitions. It's rather easy to add them. I've only added the one necessary for Javascript and Scala as that are the only languages

  (lsp-register-client
   (make-lsp-client :new-connection (lsp-tramp-connection (lambda ()
				`("typescript-language-server"
				  "--tsserver-path"
				  "tsserver"
				  ,@lsp-clients-typescript-server-args)))
:activation-fn 'lsp-typescript-javascript-tsx-jsx-activate-p
:priority -2
:completion-in-comments? t
:initialization-options (lambda ()
		  (list :plugins lsp-clients-typescript-plugins
			:logVerbosity lsp-clients-typescript-log-verbosity
			:tsServerPath (lsp-package-path 'typescript)))
:ignore-messages '("readFile .*? requested by TypeScript but content not available")
:server-id 'ts-ls
:remote? t))
  (lsp-register-client
   (make-lsp-client :new-connection (lsp-tramp-connection 'lsp-metals--server-command)
:major-modes '(scala-mode)
:priority -1
:initialization-options '((decorationProvider . t)
		  (inlineDecorationProvider . t)
		  (didFocusProvider . t)
		  (executeClientCommandProvider . t)
		  (doctorProvider . "html")
		  (statusBarProvider . "on")
		  (debuggingProvider . t)
		  (treeViewProvider . t))
:notification-handlers (ht ("metals/executeClientCommand" #'lsp-metals--execute-client-command)
		   ("metals/publishDecorations" #'lsp-metals--publish-decorations)
		   ("metals/treeViewDidChange" #'lsp-metals-treeview--did-change)
		   ("metals-model-refresh" #'lsp-metals--model-refresh)
		   ("metals/status" #'lsp-metals--status-string))
:action-handlers (ht ("metals-debug-session-start" (-partial #'lsp-metals--debug-start :json-false))
	     ("metals-run-session-start" (-partial #'lsp-metals--debug-start t)))
:server-id 'metals
:remote? t
:initialized-fn (lambda (workspace)
	  (lsp-metals--add-focus-hooks)
	  (with-lsp-workspace workspace
	    (lsp--set-configuration
	     (lsp-configuration-section "metals"))))
:after-open-fn (lambda ()
	 (add-hook 'lsp-on-idle-hook #'lsp-metals--did-focus nil t))
:completion-in-comments? t))

lsp-pyright

Enable lsp-pyright, the best Python language server, all of them are a bit lackluster, this one is the best option.

  (use-package lsp-pyright
:straight t
:hook (python-mode . lsp))

lsp-metals

Enable lsp-metals for Scala. It's actually really good and makes emacs into a very competent IDE.

  (use-package lsp-metals
:straight t
:config)

company

Enable company, I'd expect it to be loaded by default, but apparently not.

  (use-package company
:straight t
:config
;; aligns annotation to the right hand side
(setq company-tooltip-align-annotations t)
(setq company-show-numbers t)
(add-hook 'evil-normal-state-entry-hook #'company-abort) ;; make aborting less annoying
(add-hook 'after-init-hook 'global-company-mode))

lsp-ui

Enable lsp-ui, it adds doc frames, code actions at the side and other cool things, some of them are annoying and need disabling.

  (use-package lsp-ui
:straight t
:after (company-box)
:config
;; disable focus on mouse over
(push '(no-accept-focus . t) lsp-ui-doc-frame-parameters)
(push '(no-accept-focus . t) company-box-frame-parameters)

(add-to-list 'lsp-ui-doc-frame-parameters '(no-accept-focus . t))
(add-to-list 'company-box-frame-parameters '(no-accept-focus . t))
(setq mouse-autoselect-window nil))
  (add-hook 'after-init-hook 'global-company-mode)

flycheck

Enable flycheck for in-buffer hints and errors and warning and things.

  (use-package flycheck
:straight t
:init (global-flycheck-mode))

yasnippet

Enable yasnippet.

  (use-package yasnippet
:straight t
:config
(yas-global-mode 1))

origami

Enable origami. It allows one to fold and unfold a section with zc and zo in evil-mode. Hook it on both conf-mode and prog-mode;

  (use-package origami
:straight t
:hook ((prog-mode . origami-mode)
    (conf-mode . origami-mode)))

Enable origami-lsp. Some LSP servers specify these folding ranges and this package makes origami understand that and work with it.

  (use-package lsp-origami
:straight t
:hook (lsp-after-open-hook lsp-origami-try-enable))

Org Mode

Enable org-roam. It implements the Zettelkasten method in Emacs and uses a backing sqlite database, therefore sqlite must be on your path, at least for Emacs.

  (use-package org-roam
    :straight t
    :config
    (setq org-roam-directory "~/org")
    (add-hook 'after-init-hook 'org-roam-mode))

Enable additional languages for org-babel, namely Python.

  (org-babel-do-load-languages
   'org-babel-load-languages
   '((python . t)
(R . t)
(shell . t)
(dot . t)
(latex . t)))

Enable tangle on save, big thanks to Diego Zamboni for his amazing booklet about Literate Configuration.

  (add-hook 'org-mode-hook
     (lambda () (add-hook 'after-save-hook #'org-babel-tangle
	    :append :local)))

Also enable reloading of inline images on babel-execute, speeds up visual workflow significantly

  (eval-after-load 'org
    (add-hook 'org-babel-after-execute-hook 'org-redisplay-inline-images))

Enable fancy UTF-8 characters for headings with org-superstar.

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

Enable bigger headings for org-mode, this in my opinion makes it a bit easier to read org-mode buffer.

  (custom-set-faces
   '(fixed-pitch ((t (:family "Fira Code 9"))))
   '(org-level-1 ((t (:inherit outline-1 :height 1.25))))
   '(org-level-2 ((t (:inherit outline-2 :height 1.2))))
   '(org-level-3 ((t (:inherit outline-3 :height 1.15))))
   '(org-level-4 ((t (:inherit outline-4 :height 1.10))))
   '(org-level-5 ((t (:inherit outline-5 :height 1.05)))))

Enable the "vertical ruler" specifically for org-mode, TODO: it is worth considering to enable this for all text-mode buffers.

  (add-hook 'org-mode-hook (lambda ()
	(set-fill-column 120)
	(display-fill-column-indicator-mode)))

Enable org-agenda, used for task management and things like that. TODO: Currently it's underutilized and underconfigured. TODO: Also should I have a separate folder for school related things? Do I even have that folder?

  (setq org-agenda-files '("~/org" "~/org/school"))

  (setq org-agenda-custom-commands
 '(("h" "Agenda and Home-related tasks"
    ((agenda "")
     (tags-todo "home")
     (tags "garden")))
   ("o" "Agenda and Office-related tasks"
    ((agenda "")
     (tags-todo "work")
     (tags "office")))
   ("i" "Agenda and School-related tasks"
    ((agenda "")
     (tags-todo "school")
     (tags "school")))))

  (setq org-highest-priority ?A)
  (setq org-lowest-priority ?E)
  (setq org-default-priority ?B)

(Dis)enable alerts and notifications, which should hook into org-agenda notify

  (require 'org-alert)
  (require 'notifications)

Increase org-preview size

  (setq org-format-latex-options (plist-put org-format-latex-options :scale 1.75))

Enable org-tikz previews, imagemagick must be installed.

  (add-to-list 'org-latex-packages-alist
 '("" "tikz" t)
 '("" "bytefield" t))

  (eval-after-load "preview"
    '(add-to-list 'preview-default-preamble "\\PreviewEnvironment{tikzpicture}" t))

  (setq org-latex-create-formula-image-program 'imagemagick)

Install org-fragtop, it will automatically toggle previews for LaTex segments under point.

  (use-package org-fragtog
    :straight t
    :hook (org-mode . org-fragtog-mode))

TODO ESS

Required for R

  (use-package ess
:straight t
:init (require 'ess-r-mode))

Org Linkz

Based on org-linkz. Remove validation link from exported html file. Currently doesn't work for somer reason, must debug why.

  (setq org-html-validation-link nil)
  (require 'org-protocol)
  (setq org-capture-templates
 '(
   ("o" "Link capture" entry
    (file+headline "~/org/linkz.org" "INBOX")
    "* %a %U"
    :immediate-finish t)
   ))
  (setq org-protocol-default-template-key "o")

Then a .desktop file is needed for Firefox/Chromium

  [Desktop Entry]
  Name=org-protocol
  Exec=emacsclient -n %u
  Type=Application
  Terminal=fale
  Categories=System;
  MimeType=x-scheme-handler/org-protocol;

Then a bookmark must be added into firefox with this location

  javascript:location.href="org-protocol:///capture?url="+encodeURIComponent(location.href)+"&title="+encodeURIComponent(document.title||"[untitled page]")

Org Variable Pitch

Enable org-variable-pitch, it makes org-mode feel like a proper writing instrument, I'm not sure if I like it though. Disable for now, cool idea, but messes with horizontal alignment…

  (use-package org-variable-pitch
:straight t
:disabled t
:hook org-mode)

Smart Tabs

The goal of smart tabs, is to use <TAB> for indentation and <SPC> for alignment, so for example.

  fn main() {
  --if 1 == 1 &&
  --...2 == 2 &&
  --...3 != 5 {
  ----println!("Stugg");
  --}
  }

-- represents a <TAB> and . a <SPC>

And while the idea is nice, I couldn't get it to work for Rust and that's the only language I use. Therefore it's disable for now.

  (setq whitespace-display-mappings
 '((tab-mark 9 [65293] [92 9])))
  (setq whitespace-style '(tab-mark))
  (use-package smart-tabs-mode
    :straight t
    :config
    (smart-tabs-add-language-support rust rustic-hook
		((c-indent-line . c-basic-offset)
		 (c-indent-region . c-basic-offset)))
    (smart-tabs-insinuate 'c 'javascript 'rust))

Ivy

Ivy is a lighter and actually maintained altrenative to Helm. I used to use helm, but I switched to it when I started using EXWM, as I had to disable my floating Helm window and since Helm doesn't use minibuffers, the window above the popup would get scrolled. So enable it.

  (use-package ivy
    :straight t
    :config
    (ivy-mode 1)
    ;; (setq ivy-use-virtual-buffers t)
    ;; (setq enable-recursive-minibuffers t)
    )

Enable ivy-prescient for fuzzy matching, from the author of selectrum and straight.el. For splitting completion parts, separate them with a <SPC>.

  (use-package ivy-prescient
    :straight t
    :config
    (ivy-prescient-mode 1))

counsel adds specific functions for common Emacs commands, like find-file and makes them more Helm like.

  (use-package counsel
    :straight t
    :config
    (counsel-mode 1)
    :bind ("C-x b" . counsel-switch-buffer))

ivy-rich and all-the-icons compatibility.

  (use-package all-the-icons-ivy-rich
    :straight t
    :hook (after-init . all-the-icons-ivy-rich-mode))

ivy-rich add more stuff into switch-to-buffer, but has some issues when working over TRAMP. It gets a little slow. TODO

  (use-package ivy-rich
    :straight t
    :config
    (ivy-rich-mode 1))

ivy-hydra adds Helm like extended actions.

  (use-package ivy-hydra
    :straight t)

Magit

magit is literally the best package right after OrgMode of course. Therefore enable it.

  (use-package magit
    :straight t)

Also enable evil-magit for evil-style keybindings in Magit.

  (use-package evil-magit
    :straight t
    :after (evil magit)
    :config
    (setq evil-magit-state 'motion)
    (evil-define-key 'motion magit-status-mode-map ";" 'magit-log)
    (evil-define-key 'motion magit-status-mode-map "k" 'evil-previous-line)
    (evil-define-key 'motion magit-status-mode-map "l" 'evil-next-line)
    (evil-define-key 'normal magit-status-mode-map "l" 'evil-next-line)
    (evil-define-key 'visual magit-status-mode-map "l" 'evil-next-line)

    (evil-define-key 'motion magit-log-mode-map ";" 'magit-log)
    (evil-define-key 'motion magit-log-mode-map "k" 'evil-previous-line)
    (evil-define-key 'motion magit-log-mode-map "l" 'evil-next-line)
    (evil-define-key 'normal magit-log-mode-map "l" 'evil-next-line)
    (evil-define-key 'visual magit-log-mode-map "l" 'evil-next-line))

Enable magit-todos and hook them on lsp-mode and also org-mode, because it acts like a project local org-agenda, sort of.

  (use-package magit-todos
    :straight t
    :hook
    (lsp-mode . hl-todo-mode)
    (org-mode . hl-todo-mode))

Popwin

Enable popwin, it creates a minibuffer-esque window at the bottom of the currently focused frame, when specific buffer are to be raised. For example, when you go to compile a Rust project with C-c C-c C-b, the compilation buffer won't take up your whole frame and it also won't split your current window, rather it'll pop up at the bottom like in all those fancy mainstream IDEs.

  (use-package popwin
    :straight t
    :config
    (push '(rustic-compilation-mode :noselect t) popwin:special-display-config)
    (push '(rustic-cargo-test-mode :noselect t) popwin:special-display-config)
    (push '("*Warnings*" :noselect t) popwin:special-display-config)
    (popwin-mode 1))

Projectile

Enable projectile.

  (use-package projectile
    :straight t
    :config
    (projectile-mode +1)
    (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map))

VTerm

vterm is fun, but it does not play well with evil, at least by default. Therefore we need to make it cooperate. Most of the following ELisp was taken from an issue on VTerm's github.

  (defun vterm-evil-insert ()
    (interactive)
    (vterm-goto-char (point))
    (call-interactively #'evil-insert))

  (defun vterm-evil-append ()
    (interactive)
    (vterm-goto-char (1+ (point)))
    (call-interactively #'evil-append))

  (defun vterm-evil-delete ()
    "Provide similar behavior as `evil-delete'."
    (interactive)
    (let ((inhibit-read-only t)
   )
(cl-letf (((symbol-function #'delete-region) #'vterm-delete-region))
 (call-interactively 'evil-delete))))

  (defun vterm-evil-change ()
    "Provide similar behavior as `evil-change'."
    (interactive)
    (let ((inhibit-read-only t))
(cl-letf (((symbol-function #'delete-region) #'vterm-delete-region))
 (call-interactively 'evil-change))))


  (evil-define-key 'normal vterm-mode-map
    (kbd "d") (lambda () (interactive) (vterm-evil-delete)))
  (evil-define-key 'normal vterm-mode-map
    (kbd "s") (lambda () (interactive) (vterm-evil-delete) (vterm-evil-insert)))
  (evil-define-key 'normal vterm-mode-map
    (kbd "i") (lambda () (interactive) (vterm-evil-insert)))
  (evil-define-key 'normal vterm-mode-map
    (kbd "a") (lambda () (interactive) (vterm-evil-append)))
  (evil-define-key 'normal vterm-mode-map
    (kbd "c") (lambda () (interactive) (vterm-evil-change)))
  (evil-define-key 'normal vterm-mode-map
    (kbd "<left>") (lambda () (interactive) (vterm-send-left)))
  (evil-define-key 'normal vterm-mode-map
    (kbd "<right>") (lambda () (interactive) (vterm-send-right)))
  (evil-define-key 'normal vterm-mode-map
    (kbd "<up>") (lambda () (interactive) (vterm-send-up)))
  (evil-define-key 'normal vterm-mode-map
    (kbd "<down>") (lambda () (interactive) (vterm-send-down)))
  (evil-define-key 'insert vterm-mode-map
    (kbd "<left>") (lambda () (interactive) (vterm-send-left)))
  (evil-define-key 'insert vterm-mode-map
    (kbd "<right>") (lambda () (interactive) (vterm-send-right)))
  (evil-define-key 'insert vterm-mode-map
    (kbd "<up>") (lambda () (interactive) (vterm-send-up)))
  (evil-define-key 'insert vterm-mode-map
    (kbd "<down>") (lambda () (interactive) (vterm-send-down)))

  (defun evil-collection-vterm-escape-stay ()
    "Go back to normal state but don't move
  cursor backwards. Moving cursor backwards is the default vim behavior but it is
  not appropriate in some cases like terminals."
    (setq-local evil-move-cursor-back nil))

  ;; :hook ((vterm-mode-hook . evil-collection-vterm-escape-stay))

And enable vterm.

  (use-package vterm
    :straight t
    :after (evil)
    :config
    <<vterm-evil-fix>>
    )

Edit Server

This awesome package when paired with a free software browser extension, available for both Chromium and Firefox, allows one to edit text areas in their browser in Emacs.

  (use-package edit-server
    :straight t
    :init
    (edit-server-start))

Spray

spray sprays words on screen at a certain rate.

  (use-package spray
    :straight t)

Random Bits and Bobs

Set default major mode to org mode, it's much more useful than fundamental.

  (setq-default major-mode 'org-mode)

Delete files by moving to trash.

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

Equalize windows after split.

  (setq-default window-combination-resize t)

Increase undo limit to 80MB and enable fine undo, Evil will no longer chunk all edits in INSERT mode into one big undo blob.

  (setq undo-limit 80000000
 evil-want-fine-undo t)

For now, don't autosave. Because editing on remote disks, not TRAMP, but just NFS or CIFS, becomes extremely painful.

  (setq auto-save-default t)

Enable line numbers for both programming buffers (Rust, C, and such) and configuration buffers (Nix, Yaml, Json, and such).

  (add-hook 'conf-mode-hook 'display-line-numbers-mode)
  (add-hook 'prog-mode-hook 'display-line-numbers-mode)

Improve scrolling by:

  1. disabling acceleration
  2. making it so that the window under the pointer is scroller no matter the focused window
  3. changing default scroll amount to 5 lines and 1 when shift is pressed
  (setq mouse-wheel-scroll-amount '(5 ((shift) . 1)))
  (setq mouse-wheel-progressive-speed nil)
  (setq mouse-wheel-follow-mouse 't)

Enable perentheses highlighting and pairing.

  (show-paren-mode 1) 
  (electric-pair-mode)

Set fill colum, horizontal indicator, for both fill-paragraph=(=M-q) and the visual horizontal indicator.

  (setq-default display-fill-column-indicator-column 120
  fill-column 120)

Start Emacs server, unless it's already running. Starting a new Emacs instance while debugging and getting an error about a server already running can be a bit annoying.

  (load "server")
  (unless (server-running-p) (server-start))
  (setq backup-directory-alist
 `(("." . ,(concat user-emacs-directory "backups"))))

Windows

As tecosaur has it in his configuration, I was to be asked which window to should be brought up when I split a window in Emacs. So create a new advice which will run after evil split commands and brings up the buffer selector.

  (defadvice evil-window-vsplit (after activate compile)
(counsel-switch-buffer))
  (defadvice evil-window-split (after activate compile)
(counsel-switch-buffer))