Let’s increase emacs
’ garbage collector threshold and inhibit font
cache compression:
(setq gc-cons-threshold (* 100 1024 1024)
inhibit-compacting-font-caches t)
This little snippet from System Crafters helps us track
emacs
initialization time
(defun fb/display-startup-time ()
(message "Emacs loaded in %s with %d garbage collections."
(format "%.2f seconds"
(float-time
(time-subtract after-init-time before-init-time)))
gcs-done))
(add-hook 'emacs-startup-hook #'fb/display-startup-time)
The first thing we need to do is initialize emacs
’s package
system. That’s achieved with the following elisp
code.
(require 'package)
(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")
(add-to-list 'package-archives
'("melpa" . "http://melpa.org/packages/"))
(add-to-list 'package-archives
'("elpa" . "https://elpa.gnu.org/packages/"))
(package-initialize)
This is where I’ll setup some basic defaults for emacs
. Things
like user-full-name
, user-mail-address
and similar will be
here.
(setq user-full-name "Felipe Balbi"
user-mail-address "[email protected]"
calendar-latitude 60.17
calendar-longitude 24.94
calendar-location-name "Helsinki, FI"
inhibit-startup-screen t
make-backup-files nil)
(global-prettify-symbols-mode t)
If I’m running on windows, let’s make things a little saner.
(if (eq system-type 'windows-nt)
(setq-default visible-bell t
buffer-file-coding-system 'utf-8-unix))
Depending on the machine I am, I might need some extra
configuration. For example, at the office I need a proxy to get
through to the outside world. To cope with that, I’ll add an
optional site-local.el
file on such machines and conditionally
load it.
(let ((filename (concat "~/.emacs.d/" (system-name) ".org.gpg")))
(if (file-exists-p filename)
(org-babel-load-file filename)))
I tend to hit C-x C-c
by accident all the time. This little trick
helps me a lot
(setq confirm-kill-emacs 'yes-or-no-p)
(setq fill-column 80)
(column-number-mode)
(add-hook 'prog-mode-hook #'display-line-numbers-mode)
(add-hook 'tex-mode-hook #'display-line-numbers-mode)
Some indentation configuration using mode-specific hooks
(add-hook 'sh-mode-hook
(lambda ()
(setq sh-basic-offset 2)))
(add-hook 'ruby-mode-hook
(lambda ()
(setq ruby-indent-level 2)))
(add-hook 'js-mode-hook
(lambda ()
(setq js-indent-level 2)
(setq indent-tabs-mode nil)))
(add-hook 'rust-mode-hook
(lambda ()
(setq indent-tabs-mode nil)))
(add-hook 'sgml-mode-hook
(lambda ()
(setq indent-tabs-mode nil)))
(add-hook 'c-mode-hook
(lambda ()
(c-set-style "linux")
(setq c-basic-offset 8
c-block-comment-prefix "* ")
(c-set-offset 'arglist-intro '++)
(c-set-offset 'arglist-cont '++)
(c-set-offset 'arglist-cont-nonempty '++)
(setq indent-tabs-mode t)))
(add-hook 'c++-mode-hook
(lambda ()
(c-set-style "gnu")
(setq c-basic-offset 4)
(setq c-block-comment-prefix "* ")
(setq indent-tabs-mode nil)))
(add-hook 'lisp-mode-hook
(lambda ()
(setq indent-tabs-mode nil)))
(add-hook 'scheme-mode-hook
(lambda ()
(setq indent-tabs-mode nil)))
(add-hook 'awk-mode-hook
(lambda ()
(c-set-style "awk")))
And I like to highlight current line
(global-hl-line-mode)
I wanna see a simple clock in my modeline, so let’s enable
display-time-mode
(setq display-time-24hr-format t)
(display-time-mode 1)
Better grep:
(setq grep-command "grep --color -nH -e")
(setq vc-follow-symlinks t)
(setq create-lockfiles nil)
Well, I don’t want custom
touching my beautiful init.el
. Let’s give
it a dumping ground.
(unless (file-exists-p "~/.emacs.d/custom.el")
(with-temp-buffer (write-file "~/.emacs.d/custom.el")))
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file)
We really don’t need bars for everything when you’re using keyboard only.
(scroll-bar-mode -1)
(horizontal-scroll-bar-mode -1)
(menu-bar-mode -1)
(tool-bar-mode -1)
(tooltip-mode -1)
(setq native-comp-deferred-compilation t)
(setq native-comp-async-report-warnings-errors nil)
use-package
let’s me quickly and easily rebuild my configuration
by simply cloning this repository and opening emacs
. The first
time, it will install all required packages.
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(eval-when-compile
(require 'use-package))
While at that, also make sure that use-package
will ensure and
defer by default
(setq use-package-always-ensure t
use-package-always-defer t)
I like to use Iosevka Comfy
for pretty much everything.
(use-package fontaine
:ensure t
:init
(setq fontaine-latest-state-file
(locate-user-emacs-file "fontaine-latest-state.eld"))
(fontaine-set-preset (or (fontaine-restore-latest-preset) 'regular))
(add-hook 'kill-emacs-hook #'fontaine-store-latest-preset)
(add-hook 'modus-themes-after-load-theme-hook #'fontaine-apply-current-preset)
:bind
(("C-c f" . fontaine-set-preset)
("C-c F" . fontaine-set-face-font))
:custom
(fontaine-presets
'((tiny
:default-family "Iosevka Comfy Wide Fixed"
:default-height 100)
(small
:default-family "Iosevka Comfy Fixed"
:default-height 120)
(regular
:default-height 140)
(medium
:default-height 160)
(large
:default-weight semilight
:default-height 180
:bold-weight extrabold)
(presentation
:default-weight semilight
:default-height 180
:bold-weight extrabold)
(jumbo
:default-weight semilight
:default-height 200
:bold-weight extrabold)
(t
:default-family "Iosevka Comfy"
:default-weight regular
:default-height 140
:fixed-pitch-family nil ; falls back to :default-family
:fixed-pitch-weight nil ; falls back to :default-weight
:fixed-pitch-height 1.0
:fixed-pitch-serif-family nil ; falls back to :default-family
:fixed-pitch-serif-weight nil ; falls back to :default-weight
:fixed-pitch-serif-height 1.0
:variable-pitch-family "Iosevka Comfy Duo"
:variable-pitch-weight nil
:variable-pitch-height 1.0
:bold-family nil ; use whatever the underlying face has
:bold-weight bold
:italic-family nil
:italic-slant italic
:line-spacing nil))))
Always set PATH
and MANPATH
from shell, even when initialized
from GUI helpers like dmenu
or Spotlight
(use-package exec-path-from-shell
:unless (string-equal system-type "windows-nt")
:demand t
:init
(exec-path-from-shell-initialize)
(exec-path-from-shell-copy-envs '("LANG" "GPG_AGENT_INFO" "SSH_AUTH_SOCK")))
I like to have auto-fill-mode
enabled on all my text
buffers. Easiest way of achieve that is to add turn-on-auto-fill
to text-mode-hook
(add-hook 'text-mode-hook 'turn-on-auto-fill)
The ef-themes
package is created and maintained by Prot. Very
pleasing to look at.
(use-package ef-themes
:defer nil
:ensure t
:custom
(ef-themes-to-toggle '(ef-melissa-light ef-melissa-dark))
(ef-themes-headings
'((0 . (variable-pitch light 1.9))
(1 . (variable-pitch light 1.8))
(2 . (variable-pitch regular 1.7))
(3 . (variable-pitch regular 1.6))
(4 . (variable-pitch regular 1.5))
(5 . (variable-pitch 1.4))
(6 . (variable-pitch 1.3))
(7 . (variable-pitch 1.2))
(t . (variable-pitch 1.1))))
(ef-themes-mixed-fonts t)
(ef-themes-variable-pitch-ui t)
(ef-themes-region '(intense no-extend neutral))
:config
(ef-themes-select 'ef-melissa-light)
:bind ("<f5>" . ef-themes-toggle))
guile
is a language that lately I’ve been trying to get acquainted to
and, as such, I need a cool way of communicating with a REPL
from
inside emacs
. gueiser
seems to be a good choice for that
(use-package geiser
:custom
(geiser-active-implementations '(mit guile racket)))
(use-package geiser-guile
:after geiser)
(use-package geiser-mit
:after geiser)
(use-package geiser-racket
:after geiser)
This is probably the most awkward mode to get used to. Still, it’s so darn helpful that I just have to use it.
(use-package paredit
:hook ((emacs-lisp-mode
ielm-mode
lisp-mode
lisp-interaction-mode
scheme-mode) . enable-paredit-mode)
:init
(add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode))
This makes it a lot easier to see matching parens
(show-paren-mode 1)
As a complement to paredit
I want my parens to be easy to see, hence rainbow-delimiters
(use-package rainbow-delimiters
:hook
((emacs-lisp-mode
ielm-mode
lisp-mode
lisp-interaction-mode
scheme-mode) . rainbow-delimiters-mode))
I like to have nice looking lambda
characters on all my lisp-y
modes. Let’s push the lambda
character to other mode hooks too.
We also have a rather cute symbol for function
on js-mode
.
(defun push-pretty-characters ()
"Push pretty characters to mode-specific prettify-symbols-alist"
(push '("lambda" . #x03bb) prettify-symbols-alist))
(add-hook 'emacs-lisp-mode-hook #'push-pretty-characters)
(add-hook 'eval-expression-minibuffer-setup-hook #'push-pretty-characters)
(add-hook 'ielm-mode-hook #'push-pretty-characters)
(add-hook 'lisp-mode-hook #'push-pretty-characters)
(add-hook 'lisp-interaction-mode-hook #'push-pretty-characters)
(add-hook 'scheme-mode-hook #'push-pretty-characters)
(add-hook 'js-mode-hook (lambda ()
(push '("function" . ?ƒ) prettify-symbols-alist)))
Okay, I’m a bit tired of helm
. Let’s switch over to vertico
and
figure out what I’ve been missing.
(use-package vertico
:demand t
:custom
(vertico-cycle t)
:init
(vertico-mode t))
(use-package orderless
:demand t
:after vertico
:custom
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles basic partial-completion)))))
(use-package consult
:demand t
:after vertico
:config
;; Use `consult-completion-in-region' if Vertico is enabled.
;; Otherwise use the default `completion--in-region' function.
(setq completion-in-region-function
(lambda (&rest args)
(apply (if vertico-mode
#'consult-completion-in-region
#'completion--in-region)
args)))
:bind (("C-s" . consult-line)
("C-r" . consult-line)
("C-c g" . consult-git-grep)
("C-c o" . consult-imenu)
("C-x b" . consult-buffer)
("C-x C-d" . project-find-file)
("M-y" . consult-yank-pop)
("M-g M-g" . consult-goto-line)
("C-h a" . consult-apropos)
:map minibuffer-local-map
("C-r" . consult-history)))
(use-package marginalia
:demand t
:after vertico
:init
(marginalia-mode t))
(use-package corfu
:after vertico
:custom
(corfu-cycle t)
(corfu-auto t)
(corfu-separator ?\s)
(corfu-quit-no-match 'separator)
:init
(global-corfu-mode))
(use-package emacs
:init
(setq completion-cycle-threshold 5)
(setq read-extended-command-predicate
#'command-completion-default-include-p)
;; Enable indentation+completion using the TAB key.
;; `completion-at-point' is often bound to M-TAB.
(setq tab-always-indent 'complete))
(use-package spacious-padding
:if (display-graphic-p)
:custom
(spacious-padding-widths
'(:internal-border-width 15
:header-line-width 4
:mode-line-width 6
:tab-width 4
:right-divider-width 30
:scroll-bar-width 8
:fringe-width 8))
(spacious-padding-subtle-mode-line
'(:mode-line-active default
:mode-line-inactive window-divider))
:init
(spacious-padding-mode 1))
org
is emacs
’s organizer package. I use it a lot and really enjoy
it. Let’s set it up.
First we will be using our local copy of org git tree:
(defun fb/org-habit-find-file ()
"Open my personal habits file. It's always placed under
`org-directory' named `habit.org"
(interactive)
(let ((habit-file-name (concat (file-name-as-directory org-directory) "habit.org")))
(find-file habit-file-name)))
(use-package org
:hook (org-mode . (lambda () (org-indent-mode t)))
:bind
(("C-c l" . org-store-link)
("C-c a" . org-agenda)
("C-c c" . org-capture)
("C-c b" . org-switchb)
("C-c h" . fb/org-habit-find-file))
:custom
(org-directory "~/workspace/org")
(org-id-track-globally t)
(org-agenda-skip-deadline-if-done t)
(org-agenda-skip-scheduled-if-done t)
(org-return-follows-link t)
(org-ellipsis "⤵")
(org-startup-folded 'content)
(org-src-fontify-natively t)
(org-src-tab-acts-natively t)
(org-enforce-todo-dependencies t)
(org-enforce-todo-checkbox-dependencies t)
(org-agenda-dim-blocked-tasks t)
(org-highlight-latex-and-related '(native latex script))
(org-confirm-babel-evaluate
(lambda (lang body)
(not (memq (intern lang) '(c shell python dot ditaa)))))
;; Log timestamp upon completion
(org-log-done 'time)
;; Priorities
(org-highest-priority ?A)
(org-lowest-priority ?E)
(org-default-priotiy ?E)
;; Keywords
(org-todo-keywords
'((sequence "TODO(t)" "IN PROGRESS(p)" "|"
"DONE(d)" "CANCELED(c)"
"BLOCKED(b)" "AWAITING(a)")))
:config
(require 'org-tempo nil t)
(require 'ox-odt nil t)
(require 'ox-md nil t)
(setq org-latex-pdf-process
'("latexmk -xelatex -bibtex -shell-escape -f -pdf %f"))
(setq org-latex-listings 'minted)
(setq org-latex-minted-options
'(("linenos=true")))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("cc" . "src c"))
(add-to-list 'org-structure-template-alist '("rs" . "src rust"))
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
(add-to-list 'org-structure-template-alist '("hs" . "src haskell"))
(add-to-list 'org-structure-template-alist '("js" . "src js"))
(add-to-list 'org-modules 'org-habit)
(org-babel-do-load-languages 'org-babel-load-languages '((emacs-lisp . t)
(C . t)
(python . t)
(shell . t)
(sql . t)
(dot . t)))
(add-to-list 'org-latex-classes
'("scrreprt" "\\documentclass[11pt]{scrreprt}"
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
(add-to-list 'org-latex-classes
'("scrbook" "\\documentclass[11pt]{scrbook}"
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
(add-to-list 'org-latex-classes
'("scrartcl" "\\documentclass[11pt]{scrartcl}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))
(use-package org-bullets
:hook (org-mode . org-bullets-mode)
:custom
(org-hide-leading-stars t))
ox-ioslide
helps us exporting org
documents to Google I/O HTML5
slides. This can come in very handy ;-)
(use-package ox-ioslide)
ox-rst
will be used to export org
documents to ReST
format which
is used as Linux’ documentation source.
(use-package ox-rst)
(use-package org-roam
:init
(setq org-roam-v2-ack t)
:custom
(org-roam-directory "~/workspace/org/roam/")
(org-roam-completion-everywhere t)
(org-roam-completion-system 'default)
(org-roam-dailies-directory "daily/")
(org-roam-capture-templates
'(("d" "default" plain "\n\n- tags :: \n\n%?"
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
"#+title: ${title}\n")
:unnarrowed t)
("b" "Book " plain
"\n- Author: %^{Author}\n- Year: %^{Year}\n- tags :: [[id:c18f7b2a-0b63-4d74-b420-c2fd997d4b93][Book]] [[id:00b5343e-e227-4cf1-b64e-c516e4151fe1][Reading]]\n\n%?"
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
:unnarrowed t)
("p" "Person " plain
"\n\n- tags :: [[id:55532c03-7cbd-4193-bed3-6752c37a22db][People]]\n- Email: %^{Email}\n\n%?"
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
:unnarrowed t)
("m" "Meeting " plain
"\n\n- Date :: %<%Y-%m-%d>\n- Attendees :: %?\n- tags :: [[id:e6d9bbff-585a-47fd-9559-8728458faf8a][Meeting]]\n* Agenda\n\n-"
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
:unnarrowed t)))
:bind (("C-c n l" . org-roam-buffer-toggle)
("C-c n e" . org-roam-extract-subtree)
("C-c n f" . org-roam-node-find)
("C-c n g" . org-roam-graph)
("C-c n i" . org-roam-node-insert)
("C-c n c" . org-roam-capture)
("C-c n r" . org-roam-ref-add)
("C-c n R" . org-roam-ref-remove)
("C-c n t" . org-roam-tag-add)
("C-c n T" . org-roam-tag-remove)
("C-c n a" . org-roam-alias-add)
("C-c n A" . org-roam-alias-remove)
;; Dailies
("C-c n d" . org-roam-dailies-goto-date)
("C-c n j" . org-roam-dailies-goto-today)
("C-c n y" . org-roam-dailies-goto-yesterday))
:config
(add-to-list 'display-buffer-alist
'("\\*org-roam\\*"
(display-buffer-in-direction)
(direction . right)
(window-width . 0.5)
(window-height . fit-window-to-buffer)))
(org-roam-db-autosync-enable))
(use-package org-roam-ui
:after org-roam
:config
(setq org-roam-ui-sync-theme t
org-roam-ui-follow t
org-roam-ui-update-on-save t
org-roam-ui-open-on-start t)
;; normally we'd recommend hooking orui after org-roam, but since
;; org-roam does not have a hookable mode anymore, you're advised to
;; pick something yourself if you don't care about startup time, use:
;;
;; :hook (after-init . org-roam-ui-mode)
)
This is simple to configure.
(use-package magit
:config (setq magit-diff-use-overlays nil
magit-commit-arguments '("--signoff"))
:bind ("C-x g" . magit-status))
Really not much here, I just need a key chord to start eshell
at will
(use-package eshell
:bind ("C-c t" . eshell))
(defun eshell-fn-on-files (f1 f2 files)
(unless (null files)
(let ((filenames (flatten-list files)))
(funcall f1 (car filenames))
(when (cdr filenames)
(mapcar f2 (cdr filenames)))
"")))
(defun eshell/less (&rest files)
"Improved less functionality using `view-file'."
(eshell-fn-on-files 'view-file
'view-file-other-window files))
(defun eshell/e (&rest files)
"Call `find-file' on the arguments."
(eshell-fn-on-files 'find-file
'find-file-other-window files))
(defalias 'eshell/emacs 'eshell/e)
engine-mode
helps me starting out searches from within emacs
. It’s
a bit useful and I kinda like it.
(use-package engine-mode
:config
(engine/set-keymap-prefix (kbd "C-c s"))
(defengine duckduckgo
"https://duckduckgo.com/?q=%s"
:keybinding "d")
(defengine google
"https://www.google.com/search?ie=utf-8&oe=utf-8&q=%s"
:keybinding "g")
(defengine wikipedia
"https://en.wikipedia.org/w/index.php?title=Special:Search&go=Go&search=%s"
:keybinding "w")
(defengine wolfram-alpha
"https://www.wolfram-alpha.com/input/?i=%s")
(defengine youtube
"https://www.youtube.com/results?aq=f&oq=&search_query=%s"
:keybinding "y")
(defengine 17track
"http://www.17track.net/en/track?nums=%s"
:keybinding "t")
(engine-mode t))
Using notmuch
as my email client and indexer
(use-package notmuch
;; :ensure nil
:config
(require 'smtpmail)
(add-hook 'message-setup-hook 'mml-secure-message-sign-pgpmime)
(setq-default message-kill-buffer-on-exit t
mail-specify-envelope-from t
message-send-mail-function 'message-smtpmail-send-it
mml-secure-smime-sign-with-sender t
mml-secure-openpgp-sign-with-sender t
smtpmail-smtp-server "mail.kernel.org"
smtpmail-smtp-service 587
smtpmail-smtp-user "balbi"
notmuch-crypto-process-mime t
notmuch-show-stash-mlarchive-link-alist '(("Lore" . "https://lore.kernel.org/r/")
("Gmane" . "https://mid.gmane.org/")
("MARC" . "https://marc.info/?i=")
("Mail Archive, The" . "https://mid.mail-archive.com/"))
notmuch-show-indent-content nil)) ; my saved searches are missing. Should they be in site-local.el ?
I use ledger-mode
for managing my finances.
(use-package ledger-mode
:config
(add-to-list 'auto-mode-alist '("\\.ledger\\'" . ledger-mode))
(setq ledger-clear-whole-transactions t
ledger-reconcile-default-commodity "€"
ledger-reconcile-force-window-bottom t
ledger-master-file "~/workspace/accounting/general.ledger"
ledger-reports '(("bal" "%(binary) -f %(ledger-file) bal -B")
("reg" "%(binary) -f %(ledger-file) reg")
("payee" "%(binary) -f %(ledger-file) reg @%(payee)")
("account" "%(binary) -f %(ledger-file) reg %(account)"))))
Well, maybe I could play a bit with restclient
every now and again
:-)
(use-package restclient)
Use *.m
as default extension for octave files
(add-to-list 'auto-mode-alist '("\\.m$" . octave-mode))
(use-package markdown-mode
:mode (("README\\.md\\'" . gfm-mode)
("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode))
:init (setq markdown-command "pandoc"))
(use-package yasnippet
:demand t
:config
(setq yas-verbosity 1
yas-wrap-around-region t)
(with-eval-after-load 'yasnippet
(setq yas-snippet-dirs (list "~/.emacs.d/personal-snippets")))
(yas-reload-all)
(yas-global-mode))
I’ve started reading Land Of Lisp and will, therefore, play around
with Common Lisp. For that, I’ll be using sly
with sbcl
(use-package sly
:custom
(inferior-lisp-program "sbcl"))
Learning me some haskell.
(use-package haskell-mode
:init
(add-hook 'haskell-mode-hook #'interactive-haskell-mode)
(add-hook 'haskell-mode-hook #'haskell-indentation-mode))
(use-package multiple-cursors
:demand t
:bind (("C->" . mc/mark-next-like-this)
("C-<" . mc/mark-previous-like-this)
("C-c C-<" . mc/mark-all-like-this)
("C-S-c C-S-c" . mc/edit-lines)))
(use-package dts-mode
:pin elpa)
I have a few projects using cmake
as the build system,
cmake-mode
at least gives me a sensible mode for editting those
files.
(use-package cmake-mode)
(use-package erc-hl-nicks
:after erc)
(use-package erc-image
:after erc)
(use-package erc-hl-nicks
:after erc)
(use-package erc
:commands erc
:custom
(erc-nick '("balbi" "balbi_" "felipebalbi"))
(erc-user-full-name "Felipe Balbi")
(erc-interpret-mirc-color t)
(erc-lurker-hide-list '("JOIN" "PART" "QUIT"))
(erc-track-exclude-types '("JOIN" "NICK" "QUIT" "MODE"))
(erc-track-enable-keybindings nil)
(erc-track-visibility nil) ; Only use the selected frame for visibility
(erc-fill-column 80)
(erc-fill-function 'erc-fill-static)
(erc-fill-static-center 20)
(erc-default-server "irc.libera.chat")
(erc-autojoin-channels-alist '(("libera.chat" "#emacs" "#guix" "#systemcrafters")))
(erc-quit-reason (lambda (s) (or s "Later...")))
(erc-modules
'(autoaway autojoin button completion image fill irccontrols keep-place
list match menu move-to-prompt netsplit networks noncommands
readonly ring stamp track hl-nicks)))
Should we play with some openscad
?
(use-package scad-mode)
Proof general is used to communicate with proof assistants. As I
want to work through the Software Foundations Books, I’ll rely on
proof-general
to communicate with Coq.
(use-package proof-general
:ensure t)
Let’s play with rust
(use-package rust-mode
:config
(setq indent-tabs-mode nil)
:custom
(rust-format-on-save t))
(use-package cargo
:after rust-mode
:hook (rust-mode . cargo-minor-mode)
:bind
("C-c C-c n" . cargo-process-new))
(use-package rustic
:after rust-mode
:config
(setq rustic-format-on-save t)
(setq rustic-lsp-client 'eglot)
(setq rustic-lsp-server 'rust-analyzer)
(setq rustic-rustfmt-config-alist '((edition . "2021"))))
(use-package eglot
:hook ((rust-mode python-mode) . eglot-ensure)
:config
(add-to-list 'eglot-server-programs '(rust-mode . ("rust-analyzer"))))
(use-package elec-pair
:hook ((c-mode cc-mode rust-mode) . electric-pair-local-mode))
(use-package nov
:ensure t)
(use-package all-the-icons)
(use-package all-the-icons-dired
:hook (dired-mode . all-the-icons-dired-mode))
These are super helpful for day to day use
(define-key global-map (kbd "C-1") 'text-scale-increase)
(define-key global-map (kbd "C-0") 'text-scale-decrease)
Few commands I want to use but are disabled by default
(put 'narrow-to-region 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)
(put 'dired-find-alternate-file 'disabled nil)
We’re gonna tell emacs
to use gpg2
(setq epg-gpg-program "/usr/bin/gpg2")
(setq gc-cons-threshold (* 2 1024 1024))