Skip to content

Latest commit

 

History

History
314 lines (290 loc) · 10.3 KB

README.org

File metadata and controls

314 lines (290 loc) · 10.3 KB

My emacs literate configuration

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.

Core

Remove bar mode

(menu-bar-mode -1)
(tool-bar-mode -1)

(setq use-short-answers t)

(setq ring-bell-function 'ignore)
(setq-default indent-tabs-mode nil)

Theme and font

(load-theme 'modus-operandi-tinted t)

(set-face-attribute 'default nil
  :family "Iosevka Nerd Font"
  :width 'normal
  :weight 'normal)

Backups

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

Background opacity

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

Utility

All the Icons

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

Direnv

To integrate with nix shells.

(use-package direnv
  :custom (direnv-always-show-summary nil)
  :config (direnv-mode))

Magit

Configurations for magit

Use Magit

(use-package magit
  :custom (magit-process-finish-apply-ansi-colors t))

Vertico, Orderless, Marginalia

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

Helpful and which key

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

Windows

I wanna test out winner-mode

(use-package winner-mode
  :config (winner-mode))

Bind key

(use-package bind-key)

Eglot

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

Corfu

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

Vterm

(use-package vterm)

Compilation

Add support for ansi escape codes in compilation

(use-package ansi-color
  :hook (compilation-filter . ansi-color-compilation-filter))

Exwm

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

Languages

I try to mostly use the new Treesitter modes, which comes builtin with the new emacs 29.

Python

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)

Nix

(use-package nix-mode
  :hook (nix-mode . eglot-ensure))

Rust

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)

Markdown

(use-package markdown-mode
  :mode "\\.md\\'")

Personal

RSS reader

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

Org mode and agenda.

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

Email

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