Before anything, symlink this directory to .emacs.d
. Then just start emacs and it will bootstrap itself.
- Bootstrap
- Text editing
- Modal editing
- Indentation
- Scrolling
- Crux - or better move-beginning-of-line
- Parenthesis
- Show line numbers
- Show hex colors
- Keymap to toggle line wrap
- Keep files clear of trailing whitespaces
- Up/downcase region commands
- Better undo
- Spell checking
- Completion
- Automatically reload change files
- Increment number package
- Quality of Life
- Navigation
- Programming
- Writing
- GUI
- Other
(setq gc-cons-threshold 100000000)
We’ll also install diminish.el to use with use-package
.
(use-package diminish :straight t)
Let’s define some utils to write our config. First, a function to get the cache root dir and another to get and create subdirs inside the cache dir.
(defun my/cache-dir ()
(let ((d (file-name-as-directory (or (getenv "XDG_CACHE_HOME") (concat (file-name-as-directory (getenv "HOME")) ".cache/emacs.d")))))
(when (not (file-directory-p d))
(make-directory d t))
d))
(defun my/app-cache-dir (app-name)
(let ((d (file-name-as-directory (concat (my/cache-dir) app-name))))
(when (not (file-directory-p d))
(mkdir d))
d))
[TODO test meow instead]
We’ll use evil for modal editing.
First, let’s define a key to be the leader. There’s a package for that but I’m not sure if I need it yet.
(defcustom my/evil-leader-key
"'"
"Key to be used as prefix for a number of commands."
:type "key"
:group 'my/evil
)
(defvar my/evil-leader-key-map
(let ((m (make-sparse-keymap)))
(define-key m "f" 'find-file)
(define-key m "b" 'switch-to-buffer)
(define-key m "x" 'execute-extended-command)
(define-key m "k" 'kill-buffer)
(define-key m "o" 'other-window)
(define-key m "?" 'xref-find-references)
m))
We’ll need to initialize general.el so we can have a leader key taking precedence over evil-collection stuff:
(use-package general :straight t
:init
(setq general-override-states '(insert
emacs
hybrid
normal
visual
motion
operator
replace)))
Now the actual package:
(use-package evil :straight t
:after (general)
:init
(setq evil-want-keybinding nil)
(setq evil-undo-system 'undo-tree)
(setq evil-want-fine-undo t)
:config
(evil-mode 1)
(general-define-key
:states '(normal visual motion)
:keymaps 'override
my/evil-leader-key my/evil-leader-key-map)
:bind
(:map evil-normal-state-map
("." . nil)
("C-." . nil)
:map evil-motion-state-map
("H" . nil)
("L" . nil)
:map evil-insert-state-map
("C-k" . nil)))
(use-package evil-collection :straight t
:after (evil)
:custom
(evil-collection-setup-minibuffer t)
:init
(evil-collection-init))
We’ll also add evil-visualstar so we can search text that is selected using visual mode:
(use-package evil-visualstar :straight t
:config
(global-evil-visualstar-mode +1))
Let’s start by setting indent to spaces by default.
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(setq scroll-step 1)
We’ll install crux basically for the crux-move-beginning-of-line
.
(use-package crux :straight t
:bind
([remap move-beginning-of-line] . crux-move-beginning-of-line))
Coloring them:
(use-package rainbow-delimiters :straight t
:hook (prog-mode . rainbow-delimiters-mode))
Showing the matching one:
(show-paren-mode 1)
(set-face-attribute 'show-paren-match nil :weight 'extra-bold)
(set-face-attribute 'show-paren-mismatch nil :weight 'extra-bold)
(use-package display-line-numbers
:init
(setq display-line-numbers-type 'relative)
:config
(global-display-line-numbers-mode t))
rainbow-mode matches the background color to the color represented by a text (eg the hex “#efefef”)
(use-package rainbow-mode :straight t)
Useful when reading logs
(global-set-key (kbd "C-c $") 'toggle-truncate-lines)
We delete whitespaces on the save hook:
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)
(use-package undo-tree :straight t
:diminish undo-tree-mode
:init
(setq undo-tree-auto-save-history t)
(setq undo-tree-history-directory-alist (list (cons ".*" (my/app-cache-dir "undo-tree"))))
:config
(global-undo-tree-mode 1))
We’ll use ispell.
(use-package ispell :straight t
:init
(setq ispell-dictionary "american"))
Associated with flyspell to highlight spelling errors.
(use-package flyspell
:straight t
:hook ((prog-mode . flyspell-prog-mode)
(text-mode . flyspell-mode))
:bind (:map flyspell-mode-map
("C-;" . nil)
("C-." . nil))
:diminish flyspell-mode flyspell-prog-mode)
[TODO: flyspell defines C-M i
which clashes with autocompletions]
I’ve used helm for maybe 8 years now, so it’s time to try something new, so let’s try vertico. Its main selling point for me is the simplicity and that it ties to the default completion framework built in to Emacs.
(use-package vertico :straight t
:bind
(:map vertico-map
("C-j" . vertico-next)
("C-k" . vertico-previous))
:init
(vertico-mode))
(use-package vertico-directory
:load-path "straight/build/vertico/extensions"
:requires (vertico)
:bind
(:map vertico-map
("M-h" . vertico-directory-up)))
(use-package emacs
:init
;; 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))
And let’s use orderless as the completion style (it’s a fuzzy matching style of completing, instead of the default prefix match).
(use-package orderless :straight t
:init
(setq completion-styles '(orderless)
completion-category-defaults nil
completion-category-overrides '((file (styles partial-completion)))))
(TODO: test prescient.el instead of orderless)
And marginalia:
(use-package marginalia :straight t
;; Either bind `marginalia-cycle` globally or only in the minibuffer
:bind (("M-A" . marginalia-cycle)
:map minibuffer-local-map
("M-A" . marginalia-cycle))
;; The :init configuration is always executed (Not lazy!)
:init
;; Must be in the :init section of use-package such that the mode gets
;; enabled right away. Note that this forces loading the package.
(marginalia-mode))
We’ll also need embark for actions on the completing candidates:
(use-package embark :straight t
:bind
(("C-." . embark-act)
("C-;" . embark-dwim))
:config
;; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
Now let’s install yasnippet.
(use-package yasnippet :straight t
:diminish yas-minor-mode
:bind (:map my/evil-leader-key-map
("y" . yas-insert-snippet))
:config
(yas-global-mode 1))
Finally, for a better completion command:
(global-set-key (kbd "C-;") #'completion-at-point)
(auto-revert-mode +1)
This gives us commands to increment/decrement numbers at point.
(use-package shift-number :straight t
:bind (:map my/evil-leader-key-map
("+" . shift-number-up)
("-" . shift-number-down)))
Set browser function to find the default OS browser to open URLs.
(setq browse-url-browser-function 'browse-url-default-browser)
Well, emacs has a mode for saving history of stuff written in the minibuffer. Let’s enable that
(use-package savehist
:init
(savehist-mode))
(setq initial-major-mode 'markdown-mode)
(defalias 'yes-or-no-p 'y-or-n-p)
Never saw the need for that
(setq create-lockfiles nil)
One annoying thing is the temporary files that emacs creates on the same folder as our source. We’ll instruct emacs to store these files in a temporary dir.
(setq backup-directory-alist
`((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
`((".*" ,temporary-file-directory t)))
(global-set-key (kbd "C-x C-m") 'execute-extended-command)
(global-set-key (kbd "M-x") nil)
Great mode for completing the next keys you can enter after a prefix.
(use-package which-key :straight t
:config
(which-key-mode))
Tells eldoc to show documentation from different sources concatenated.
(use-package eldoc :straight t
:diminish eldoc-mode
:custom
(eldoc-echo-area-prefer-doc-buffer t)
:config
(global-eldoc-mode 1)
(setq eldoc-documentation-function #'eldoc-documentation-compose))
(use-package helpful
:straight t
:bind (("C-h f" . helpful-callable)
("C-h v" . helpful-variable)
("C-h k" . helpful-key)
("C-h f" . helpful-function)
("C-h c" . helpful-command)))
(use-package project
:after (evil general)
:config
<<project-el-kill-buffers>>
<<project-el-override-leader-key>>)
We are making use of a custom command to save all buffers from the project:
;; copied predicate from project.el
(defun my/project-buffer-p (project buf)
(let ((root (expand-file-name (file-name-as-directory (project-root project)))))
(string-prefix-p root (expand-file-name
(buffer-local-value 'default-directory buf)))))
;; let's define a function to save all buffers from a project
(defun my/project-save-buffers ()
"Save buffers for a given project"
(interactive)
(let ((pr (project-current)))
(save-some-buffers nil (lambda () (my/project-buffer-p pr (current-buffer))))))
(define-key project-prefix-map "s" #'my/project-save-buffers)
And finally let’s define a prefix for the project key map:
(general-define-key
:states '(normal visual motion)
:keymaps 'override
"SPC" project-prefix-map)
This is done using winner-mode
(winner-mode 1)
(use-package avy :straight t
:after (evil)
:bind (("M-g e" . avy-goto-word-0)
:map evil-normal-state-map
("`" . avy-goto-word-0)))
(use-package consult :straight t
:after (evil project)
:bind
(:map project-prefix-map
("/" . consult-ripgrep)
:map evil-normal-state-map
("Q" . consult-goto-line)
:map my/evil-leader-key-map
("/" . consult-ripgrep))
:init
(setq completion-in-region-function (lambda (&rest args)
(apply (if vertico-mode
#'consult-completion-in-region
#'completion--in-region)
args))))
And since we’re using embark, let’s also install embark-consult
:
(use-package embark-consult :straight t)
I use Eglot for almost every language I program.
(use-package eglot
:bind
(:map my/evil-leader-key-map
("e r" . eglot-code-actions)
("e e" . eglot-reconnect)
("e m" . eglot-rename)
("e I" . eglot-organize-imports))
:config
(add-to-list 'eglot-stay-out-of "eldoc-documentation-function$")
(add-to-list 'eglot-stay-out-of 'eldoc-documentation-strategy)
:hook
(before-save . (lambda () (when (eglot-managed-p) (with-demoted-errors "Error when eglot-format-buffer: %s" (eglot-format-buffer))))))
(use-package flymake
:diminish flymake-mode
:bind (:map my/evil-leader-key-map
(">" . flymake-goto-next-error)
("<" . flymake-goto-prev-error))
:hook (prog-mode . flymake-mode))
Seems pretty useful to share settings between editors, so let’s configure it:
(use-package editorconfig
:straight t
:config
(editorconfig-mode 1))
Let’s install magit first.
(use-package magit
:straight t
:after (project)
:bind
(("C-c m s" . magit-status)
("C-c m b" . magit-blame-addition)
:map magit-mode-map
("<SPC>" . nil))
:init
(setq magit-last-seen-setup-instructions "1.4.0")
(setq magit-git-executable "git")
;; See https://github.com/magit/magit/issues/2541
(setq magit-display-buffer-function
(lambda (buffer)
(display-buffer
buffer (if (and (derived-mode-p 'magit-mode)
(memq (with-current-buffer buffer major-mode)
'(magit-process-mode
magit-revision-mode
magit-diff-mode
magit-stash-mode
magit-status-mode)))
nil
'(display-buffer-same-window)))))
(defun my/project-magit ()
(interactive)
(magit-status (car (project-roots (project-current)))))
(define-key project-prefix-map (kbd "g") 'my/project-magit)
(add-to-list 'project-switch-commands '(my/project-magit "Magit Status")))
Now to configure the commit buffer with spellcheck and markdown:
(use-package flyspell :straight t
:after (magit)
:hook
(git-commit-mode . turn-on-flyspell))
(use-package markdown-mode :straight t
:after (magit)
:hook
(git-commit-mode . markdown-mode))
(use-package evil-cleverparens :straight t)
(use-package evil-surround :straight t
:config (global-evil-surround-mode 1))
(use-package symex :straight t
:bind (:map my/evil-leader-key-map
(";" . symex-mode-interface))
:config
(symex-initialize))
Let’s list all the language grammars we have:
(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")
(elixir "https://github.com/elixir-lang/tree-sitter-elixir")
(go "https://github.com/tree-sitter/tree-sitter-go")
(gleam "https://github.com/gleam-lang/tree-sitter-gleam")
(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"
"v0.20.3"
"tsx/src")
(typescript "https://github.com/tree-sitter/tree-sitter-typescript"
"v0.20.3"
"typescript/src")
(yaml "https://github.com/ikatyang/tree-sitter-yaml")))
And a command to install all the listed grammars:
(defun my/install-all-language-grammars ()
(interactive)
(mapc #'treesit-install-language-grammar (mapcar #'car treesit-language-source-alist)))
Now I can call it interactively any time I want to refresh my language grammars.
Cool for making uml charts.
(use-package plantuml-mode
:straight t
:mode ("\\.puml\\'" . plantuml-mode)
:config
(setq plantuml-jar-path "~/.local/plantuml/plantuml.jar")
(setq plantuml-default-exec-mode 'jar))
Very useful inside org-mode, so let’s install the org babel extension:
(use-package ob-plantuml
:config
(setq org-plantuml-jar-path "~/utils/jars/plantuml.jar"))
(use-package direnv :straight t
:config
(direnv-mode))
We’ll install json and jsonnet modes:
(use-package json-mode :straight t
:config
(add-to-list 'auto-mode-alist '("\\.json.base\\'" . json-mode)))
(use-package jsonnet-mode :straight t
:config
(add-to-list 'auto-mode-alist '("\\.libjsonnet\\'" . jsonnet-mode)))
(use-package markdown-mode :straight t
:mode
("\\.markdown\\'" . markdown-mode)
("\\.md\\'" . markdown-mode))
(use-package yaml-mode :straight t)
(use-package protobuf-mode :straight t
:mode ("\\.proto$" . protobuf-mode))
(use-package terraform-mode :straight t)
(use-package cc-mode :straight t
:hook
(c-c++-mode . (lambda () (setq require-final-newline t)))
:init
(setq c-default-style "linux"
c-basic-offset 4))
(use-package cmake-mode :straight t)
(use-package go-mode :straight t
:after (eglot)
:hook
(go-ts-mode . eglot-ensure)
(go-mode . eglot-ensure)
:config
(unless (treesit-language-available-p 'go)
(treesit-install-language-grammar 'go))
(add-to-list 'major-mode-remap-alist '(go-mode . go-ts-mode)))
Let’s also add a helper package to run go tests:
(use-package gotest :straight t)
# -*- mode: snippet -*-
# name: Tabular test boilerplate
# key: tc
# --
testCases := []struct {
name string
$1
}{$2}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
$3
})
}
# -*- mode: snippet -*-
# name: Error wrapper func
# key: wrapErr
# --
wrapErr := func(err error) error {
return fmt.Errorf("$1: %w", err)
}
This is the final configuration:
(use-package web-mode :demand t
:after (eglot)
:straight t
:mode (("\\.html?\\'" . web-mode))
:config
(setq web-mode-enable-auto-closing t)
(setq web-mode-enable-auto-pairing t)
(setq web-mode-code-indent-offset 2)
(setq web-mode-markup-indent-offset 2)
(setq web-mode-enable-literal-interpolation t))
(require 'eglot)
(require 'web-mode)
(define-derived-mode my/svelte-mode web-mode "svelte"
"Major mode for editing .svelte files using web-mode and LSP support")
(add-to-list 'auto-mode-alist '("\\.svelte\\'" . my/svelte-mode))
(add-hook 'my/svelte-mode-hook #'eglot-ensure)
(add-to-list 'eglot-server-programs '(my/svelte-mode . ("svelteserver" "--stdio")))
Let’s configure the basics first:
(use-package typescript-ts-mode
:straight t
:mode (("\\.ts\\'" . typescript-ts-mode)
("\\.tsx\\'" . tsx-ts-mode)))
Now the LS
(use-package typescript-ts-mode
:after (eglot)
:hook
(typescript-ts-mode . eglot-ensure)
(tsx-ts-mode . eglot-ensure))
# -*- mode: snippet -*-
# name: react-fc-ts
# key: fct
# --
import * as React from "react"
export interface ${1:component}Props {}
const $1: React.FC<$1Props> = (props) => {
$2
}
export default $1;
# -*- mode: snippet -*-
# name: react-storybook-ts
# key: tstory
# --
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import ${1:MyComponent}, { $1Props } from '.';
export default {
component: $1,
} as ComponentMeta<typeof $1>;
export const Basic: ComponentStory<typeof $1> = () => (<$1 />);
(use-package dockerfile-mode :straight t)
Let’s add clojure-mode and cider:
(use-package clojure-mode :straight t
:after (eglot evil-cleverparens)
:hook
(clojure-mode . eglot-ensure)
(clojure-mode . evil-cleverparens-mode))
(use-package cider :straight t)
(use-package tuareg :straight t
:after (eglot)
:hook (tuareg-mode . eglot-ensure))
(use-package scala-mode :straight t
:after (eglot)
:hook (scala-mode . eglot-ensure))
(use-package nix-mode :straight t
:mode "\\.nix\\'"
:after (eglot)
:hook (nix-mode . eglot-ensure))
(use-package bazel :straight t)
Well that’s something I’ll rarely use, but it’s nice to have the syntax highlighting for examples:
(use-package wkt-mode
:straight (:type git
:repo "https://github.com/orontee/wkt-mode"))
(use-package lua-mode :straight t)
(use-package elixir-mode :straight t)
(use-package elixir-ts-mode :straight t)
(use-package eglot :straight t
:after (elixir-mode)
:config
:hook
(elixir-mode . eglot-ensure)
(elixir-ts-mode . eglot-ensure)
:config
(add-to-list 'eglot-server-programs
`((elixir-ts-mode heex-ts-mode elixir-mode) .
("~/.local/elixir-ls/language_server.sh"))))
(use-package inf-elixir :straight t)
(use-package ob-elixir :straight t)
Github copilot works great, but I hate that it doesn’t plug into company mode. This made me try alternatives and I found this.
(use-package codeium
:straight '(:type git :host github :repo "Exafunction/codeium.el")
:init
(add-to-list 'completion-at-point-functions #'codeium-completion-at-point)
:config
;; (setq use-dialog-box nil) ;; do not use popup boxes
;; get codeium status in the modeline
(setq codeium-mode-line-enable
(lambda (api) (not (memq api '(CancelRequest Heartbeat AcceptCompletion)))))
(add-to-list 'mode-line-format '(:eval (car-safe codeium-mode-line)) t)
;; alternatively for a more extensive mode-line
;; (add-to-list 'mode-line-format '(-50 "" codeium-mode-line) t)
;; use M-x codeium-diagnose to see apis/fields that would be sent to the local language server
(setq codeium-api-enabled
(lambda (api)
(memq api '(GetCompletions Heartbeat CancelRequest GetAuthToken RegisterUser auth-redirect AcceptCompletion)))))
Let’s jump in the bandwagon…
(use-package copilot
:straight (:host github :repo "zerolfx/copilot.el" :files ("dist" "*.el"))
:ensure t
:hook (prog-mode . copilot-mode)
:bind (:map copilot-completion-map
("C-y" . copilot-accept-completion)
("M-n" . copilot-next-completion)
("M-p" . copilot-previous-completion)))
(use-package rust-mode :straight t
:after (eglot)
:hook (rust-mode . eglot-ensure))
(use-package zig-mode :straight t
:after (eglot)
:hook (zig-mode . eglot-ensure))
First the basic mode setup.
(use-package gleam-ts-mode
:straight (:host github :repo "gleam-lang/gleam-mode" :branch "gleam-ts-mode")
:config
(add-to-list 'auto-mode-alist '("\\.gleam\\'" . gleam-ts-mode)))
Now treesit:
(use-package gleam-ts-mode
:after (treesit)
:config
(add-to-list 'treesit-language-source-alist '(gleam "https://github.com/gleam-lang/tree-sitter-gleam"))
(unless (treesit-language-available-p 'gleam)
(treesit-install-language-grammar 'gleam)))
And finally eglot;
(use-package gleam-ts-mode
:after (eglot)
:hook (gleam-ts-mode . eglot-ensure))
We install org-mode using straight so we get the newest version
(use-package org :straight t
:init
(setq org-log-done 'time
org-src-fontify-natively t
org-log-into-drawer t
org-confirm-babel-evaluate nil
org-src-preserve-indentation nil
org-edit-src-content-indentation 0)
:hook
(org-babel-after-execute . org-redisplay-inline-images)
:config
;; load basic languages I use regularly inside org blocks
(org-babel-do-load-languages
'org-babel-load-languages
'((dot . t) ; graphviz
(shell . t)
(lisp . t)
(emacs-lisp . t)
(gnuplot . t)
(plantuml . t)))
(add-to-list 'org-export-backends 'md))
Github-flavored markdown exporter:
(use-package ox-gfm :straight t
:after (org)
:config
(require 'ox-gfm))
One cool little tool is toc-org. It maintains an up to date TOC for us - very nice for seeing org files on Github.
(use-package toc-org :straight t
:after (org)
:hook
(org-mode . toc-org-enable))
I plan on using org-roam to start taking better notes.
(use-package org-roam :straight t
:after (org)
:init
(setq org-roam-directory "~/reps/caioaao/slipbox")
:config
(org-roam-db-autosync-mode)
:bind
(("C-c n f" . org-roam-node-find)
:map org-mode-map
("C-c n l" . org-roam-buffer-toggle)
("C-c n i" . org-roam-node-insert))
:catch (lambda (keyword error)
(message (error-message-string error))))
Let’s install the theme first:
(use-package doom-themes :straight t
:config (load-theme 'doom-nord t))
Let’s remove all the window decorations here. We don’t need stuff for clicking if we don’t use mouse!
(setq default-frame-alist '((undecorated . t)
(drag-internal-border . 1)
(internal-border-width . 5)))
(tool-bar-mode -1)
(menu-bar-mode -1)
(scroll-bar-mode -1)
We also don’t need the startup screen or the scratch message:
(setq-default inhibit-startup-screen t)
(setq-default initial-scratch-message nil)
Now highlight current line everywhere
(global-hl-line-mode +1)
And the mode-line now. I really like what awesome-tray’s author had to say about the mode-line:
I don’t like mode-line, it’s too high, affect me to read the code. With Emacs, we only need to focus on very little information, such as time, current mode, git branch. Excessive information can seriously interfere with our attention.
Because of that, I decided to tray the more minimalistic ‘awesome-tray’.
(use-package awesome-tray
:straight (:type git :host github :repo "manateelazycat/awesome-tray")
:after (doom-themes)
:init
(setq awesome-tray-active-modules '("location" "evil" "buffer-name" "git" "mode-name"))
(setq awesome-tray-mode-line-inactive-color (doom-lighten (doom-color 'bg) 0.2))
(setq awesome-tray-mode-line-active-color (doom-lighten (doom-color 'bg) 0.5))
:config
(awesome-tray-mode 1))
Let’s copy locale variables and the exec path.
(use-package exec-path-from-shell :straight t
:config
(setq exec-path-from-shell-check-startup-files nil)
(exec-path-from-shell-initialize)
(exec-path-from-shell-copy-envs '("LANG" "LC_ALL")))
Lest add more switches to dired, and also remove the bindings that clash with my own/evil’s
(use-package dired
:after (evil evil-collection)
:bind (:map dired-mode-map
("<SPC>" . nil))
:config
(setq dired-listing-switches "-alh")
:hook (evil-collection-setup . (lambda (&rest args) (evil-define-key 'normal 'dired-mode-map "<SPC>" nil))))
In Ubuntu we need to copy SSH_AUTH_SOCK
variable for some reason, so let’s use exec-path-from-shell
(use-package exec-path-from-shell :straight t
:config
(exec-path-from-shell-copy-env "SSH_AUTH_SOCK"))
When I’m pairing remotely I need to set the font face bigger, so let’s add a keybind for that.
(define-minor-mode my/presentation-toggle-mode
"Controls a toggle for 'presentation' mode.")
(defvar my/presentation-on? nil)
(defun my/presentation-toggle () (interactive)
(if my/presentation-on?
(progn (set-face-attribute 'default nil :height 100)
(setq my/presentation-on? nil))
(set-face-attribute 'default nil :height 200)
(setq my/presentation-on? t)))
;; 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: