This org file is used as the configuration source for my emacs. Additional packages may be found at emacs.nix (those that cannot be directly installed from use-package
). Though declared in emacs lisp, they actually are completely managed by the nix
package manager, by parsing the declarations on this file and using them to fetch the packages, which I think is really cool.
This makes it such that it is trivial to handle complex configurations, such as pylsp with plugins or treesitter grammars installation process (which usually envolves some stateful installations outside of emacs).
In order to run this emacs configuration locally, all you need to do is run the following command:
nix run github:o-santi/emacs --experimental-features "nix-command" --experimental-features "flakes"
Though you probably shouldn’t, because it will most likely build all of emacs from scratch (which takes a little while).
You can also use it as a nixosModule
, in order to add additional packages like fonts.
(menu-bar-mode -1)
(tool-bar-mode -1)
(setq use-short-answers t)
(setq ring-bell-function 'ignore)
(setq-default indent-tabs-mode nil)
(load-theme 'modus-operandi-tinted t)
(set-face-attribute 'default nil
:family "Iosevka Nerd Font"
:width 'normal
:weight 'normal)
(setq
backup-by-copying t ; don't clobber symlinks
backup-directory-alist '(("." . "~/.saves/")) ; don't litter my fs tree
delete-old-versions t
kept-new-versions 6
kept-old-versions 2
version-control t)
Remove background on terminal, and add transparency on GUI
(defun on-after-init ()
(unless (display-graphic-p (selected-frame))
(set-face-background 'default "unspecified-bg" (selected-frame))))
(add-hook 'window-setup-hook 'on-after-init)
(set-frame-parameter nil 'alpha-background 70)
(add-to-list 'default-frame-alist '(alpha-background . 70))
Works through nixosModules.
(use-package all-the-icons
:if (and (display-graphic-p) @isnixosmodule@))
(use-package all-the-icons-completion
:if (and (display-graphic-p) @isnixosmodule@)
:after all-the-icons
:hook (marginalia-mode . all-the-icons-completion-mode))
To integrate with nix shells.
(use-package direnv
:custom (direnv-always-show-summary nil)
:config (direnv-mode))
Configurations for magit
(use-package magit
:custom (magit-process-finish-apply-ansi-colors t))
Pretty minibuffer support
(use-package vertico
:config (vertico-mode))
(use-package orderless
:custom
(completion-styles '(orderless basic))
(completion-category-defaults nil)
(completion-category-overrides '((file (styles basic partial-completion)))))
(use-package marginalia
:config (marginalia-mode))
(use-package ctrlf
:config (ctrlf-mode +1))
Better help defaults
(use-package helpful
:config (global-set-key (kbd "C-h f") #'helpful-callable)
:config (global-set-key (kbd "C-h v") #'helpful-variable)
:config (global-set-key (kbd "C-h x") #'helpful-command))
(use-package which-key
:config (which-key-mode))
I wanna test out winner-mode
(use-package winner-mode
:config (winner-mode))
(use-package bind-key)
Language server support. Already comes installed but used to configure additional language servers.
(use-package eglot
:config (add-to-list 'eglot-server-programs '(nix-mode . ("nil"))))
Completion popup system
(use-package corfu
:config (global-corfu-mode)
:custom
(corfu-auto t)
(corfu-cycle t)
(corfu-separator ?\s)
(corfu-quit-no-match t))
(use-package vterm)
Add support for ansi escape codes in compilation
(use-package ansi-color
:hook (compilation-filter . ansi-color-compilation-filter))
(use-package exwm
:config
:disable t
(setq exwm-workspace-number 9)
(add-hook 'exwm-update-class-hook
(lambda ()
(exwm-workspace-rename-buffer exwm-class-name)))
(require 'exwm-randr)
(setq exwm-randr-workspace-output-plist '((1 . "DP-1") (2 . "HDMI-1")))
(add-hook 'exwm-randr-screen-change-hook
(lambda ()
(start-process-shell-command
"xrandr" nil "xrandr --output DP-1 --mode 2560x1080 --rate 75.00 --pos 0x1080 --output HDMI-1 --mode 1920x1080 --pos 320x0")))
(require 'exwm-systemtray)
(exwm-systemtray-enable))
I try to mostly use the new Treesitter modes, which comes builtin with the new emacs 29.
The package already comes builtin, so we only instantiate it to define the hooks and remap the default package for the new one.
It also relies on python lsp server with builtin ruff support.
(add-to-list 'major-mode-remap-alist '(python-mode . python-ts-mode))
(add-hook 'python-ts-mode-hook #'eglot-ensure)
(use-package nix-mode
:hook (nix-mode . eglot-ensure))
Try to use the package.
(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-ts-mode))
(add-hook 'rust-ts-mode-hook #'eglot-ensure)
(setq rust-ts-mode-indent-offset 2)
(use-package markdown-mode
:mode "\\.md\\'")
(use-package elfeed
:bind ("C-c r e" . elfeed)
:custom
(elfeed-feeds '("https://planet.emacslife.com/atom.xml"
"https://fasterthanli.me/index.xml"
"https://nullprogram.com/feed/"
"https://without.boats/index.xml"
"https://smallcultfollowing.com/babysteps/atom.xml"
"https://surma.dev/index.xml")))
(use-package org
:hook (org-mode . org-indent-mode)
:bind ("C-c a" . org-agenda)
:custom
(org-ellipsis " …")
(org-hide-emphasis-markers nil)
(org-fontify-quote-and-verse-blocks t)
(org-image-actual-width nil)
(org-indirect-buffer-display 'other-window)
(org-confirm-babel-evaluate nil)
(org-edit-src-content-indentation 0)
(org-agenda-files '("~/agenda.org"))
(org-agenda-window-setup 'current-window)
(org-agenda-restore-windows-after-quit t)
(org-agenda-block-separator nil)
(org-agenda-sticky t)
(org-agenda-time-grid
'((daily today require-timed)
()
"......" "----------------"))
;; :config
;; (when (display-graphic-p)
;; (setq org-agenda-category-icon-alist
;; `(
;; ("Trabalho" ,(list (all-the-icons-material "work")) nil nil :ascent center)
;; ("Pessoal" ,(list (all-the-icons-material "account_box")) nil nil :ascent center)
;; ("Faculdade" ,(list (all-the-icons-material "school")) nil nil :ascent center))))
)
Trying to use mu4e
(setq epg-pinentry-mode 'loopback)
Helper functions, to try to discover which mail pertains to which account.
(defun personal-p (msg)
(string-prefix-p "/personal/" (mu4e-message-field msg :maildir)))
(defun university-p (msg)
(string-prefix-p "/university/" (mu4e-message-field msg :maildir)))
(defun work-p (msg)
(string-prefix-p "/work/" (mu4e-message-field msg :maildir)))
Actual mu4e definition
(use-package mu4e
:bind ("C-c m" . mu4e)
:custom
(read-mail-command 'mu4e)
(mu4e-index-cleanup nil)
(mu4e-index-lazy-check t)
(mu4e-use-fancy-chars (display-graphic-p))
(mu4e-confirm-quit nil)
(mu4e-change-filenames-when-moving t)
(mu4e-update-interval (* 5 60))
(mu4e-get-mail-command "parallel mbsync ::: personal work university")
(mu4e-headers-fields
'((:human-date . 10)
(:flags . 6)
(:topic . 10)
(:from-or-to . 22)
(:subject . nil)))
(mu4e-drafts-folder (lambda (msg)
(cond
((personal-p msg) "/personal/[Gmail]/Rascunhos")
((university-p msg) "/university/[Gmail]/Rascunhos")
((work-p msg) "/work/[Gmail]/Drafts"))))
(mu4e-sent-folder (lambda (msg)
(cond
((personal-p msg) "/personal/[Gmail]/Enviados")
((university-p msg) "/university/[Gmail]/Enviados")
((work-p msg) "/work/[Gmail]/Sent"))))
(mu4e-refile-folder (lambda (msg)
(cond
((personal-p msg) "/personal/[Gmail]/'Todos os e-mails'")
((university-p msg) "/university/[Gmail]/'Todos os e-mails'")
((work-p msg) "/work/[Gmail]/'All mail'"))))
(mu4e-trash-folder (lambda (msg)
(cond
((personal-p msg) "/personal/[Gmail]/Lixeira")
((university-p msg) "/university/[Gmail]/Lixeira")
((work-p msg) "/work/[Gmail]/Trash"))))
:config
(add-to-list 'mu4e-bookmarks
'(:name "Inboxes"
:query "m:/personal/Inbox OR m:/work/Inbox OR m:/university/Inbox"
:key ?i))
(add-to-list 'mu4e-header-info-custom
'(:topic
:name "Topic"
:shortname "Topic"
:function (lambda (msg)
(cond
((personal-p msg) "Personal")
((university-p msg) "University")
((work-p msg) "Work"))))))