Skip to content

Latest commit

 

History

History
1343 lines (1189 loc) · 52.9 KB

config.org

File metadata and controls

1343 lines (1189 loc) · 52.9 KB

Emacs configuration

About this file

This is an org-mode file, so you can read it directly from emacs.

Startup

Set the garbage collection to a better number for the load. Also, a message with the time and garbage collection is showed.

    ;; Profile emacs startup
    ;; The default is 800 kilobytes.  Measured in bytes. (setq gc-cons-threshold (* 50 1000 1000))
    (add-hook 'emacs-startup-hook
              (lambda ()
                (message "*** Emacs loaded in %s with %d garbage collections."
                         (format "%.2f seconds"
                                 (float-time
                                  (time-subtract after-init-time before-init-time)))
                         gcs-done)))
(setq comp-deferred-compilation t)
  (setq comp-async-report-warnings-errors nil)

Use-package

use-package is a macro set to install and configure packages.

(require 'package)
;; Allows to install packages from melpa
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t)
			
  ;;(setq package-archives
  ;;      '(("melpa" . "https://raw.githubusercontent.com/d12frosted/elpa-mirror/master/melpa/")
  ;;        ("org"   . "https://raw.githubusercontent.com/d12frosted/elpa-mirror/master/org/")
  ;;        ("gnu"   . "https://raw.githubusercontent.com/d12frosted/elpa-mirror/master/gnu/")))
      (package-initialize)
      (add-to-list 'load-path "~/.emacs.d/external/")

      ;; If not here, install use-package
      (unless (package-installed-p 'use-package)
        (package-refresh-contents)
        (package-install 'use-package))

      ;; Automatically download all packages. To prevent this, add ~:ensure nil~
      (setq use-package-always-ensure t)
    ;;  (setq use-package-verbose t)

Basic configurations

UI and QOL configurations

This include a lot of configurations so Emacs doesn’t look like a very ugly notepad.

  (require 'frame)
;;  (defun set-cursor-hook (frame)
;;    (modify-frame-parameters
;;     frame (list (cons 'cursor-color "#ffffff"))))

;; (add-hook 'after-make-frame-functions 'set-cursor-hook)
    (tool-bar-mode -1)
    (scroll-bar-mode -1)
    (menu-bar-mode -1)
    (global-set-key (kbd "M-m") 'menu-bar-mode) ; Opens the menu with M-m, very KDE-ish
    (column-number-mode 1) ; The modeline shows the column number at the end
(setq  cursor-in-non-selected-windows nil     ; Hide the cursor in inactive windows
       select-enable-clipboard t              ; Merge system's and Emacs' clipboard
        x-stretch-cursor t)                    ; Stretch cursor to the glyph width

This enables the line numbers at the left. It adds some customization to look fine even with variable-pitch fonts.

(global-display-line-numbers-mode)
(setq display-line-numbers-type 'relative)

(set-face-attribute 'line-number nil :inherit nil)
(set-face-attribute 'line-number-current-line nil :inherit nil)

;; Disable line numbers for some modes
(dolist (mode '(org-mode-hook
                org-agenda-mode-hook
                term-mode-hook
                vterm-mode-hook
                shell-mode-hook
                treemacs-mode-hook
                elpher-mode-hook
                eshell-mode-hook))
  (add-hook mode (lambda () (display-line-numbers-mode 0))))

( kdjfkjasdklfjadk fklasd jfkaj ) Configure the match-paren feature to highlight the entire expression

(use-package paren
  :ensure nil
  :config
  (set-face-attribute 'show-paren-match-expression nil :inherit nil :weight 'semibold :background "snow4")
  (setq show-paren-delay 0)
  (setq show-paren-style 'expression)
  (setq show-paren-when-point-in-periphery t)
  (setq show-paren-when-point-inside-paren nil)
  (show-paren-mode t)) ; Highlight the matching parenthesis

More QOL features

(blink-cursor-mode 1) ; Disable the blinking
;; Press y/n instead of the whole word
(defalias 'yes-or-no-p 'y-or-n-p)
;; Scroll line by line. Cursor doesn't stays at the center of the screen. Can be laggy
(setq scroll-conservatively 100)
;; Disable backups. I'm not sure I want this disabled, but opening files it's veeeery slow
(setq make-backup-files nil) 
(setq backup-directory-alist
      `((".*" . ,"~/.emacs.d/backups/")))
(setq auto-save-file-name-transforms
      `((".*" ,"~/.emacs.d/backups/")))
(setq auto-save-list-file-prefix nil)
(setq auto-save-default nil)

(defun config-visit ()
  (interactive)
  (find-file "~/.emacs.d/config.org"))
(global-set-key (kbd "C-c e") 'config-visit)

;; Updates the config fiel with C-c r
(defun config-reload ()
  (interactive)
  (load-file user-init-file))
(global-set-key (kbd "C-c r") 'config-reload)

(global-visual-line-mode 1) ; wrap lines to the size of the buffer

;; Disables the ugly splash screen 
(setq inhibit-splash-screen t)
(setq initial-scratch-message nil) ; Disable the scratch mesage
(setq initial-major-mode (quote org-mode)) ; Change the mode of the scratch buffer

;; With this, emacs will not ask if I want to edit the symlink every time
(setq vc-follow-symlinks nil)

;; This is necessary on 27+ to write accents (needed to write spanish). They say it's a feature... not for me!
(require 'iso-transl)

;; When a split is done, follow it.
(defun split-and-follow-horizontally ()
  (interactive)
  (split-window-below)
  (balance-windows)
  (other-window 1))
(global-set-key (kbd "C-c i") 'split-and-follow-horizontally)

(defun split-and-follow-vertically ()
  (interactive)
  (split-window-right)
  (balance-windows)
  (other-window 1))
(global-set-key (kbd "C-c o") 'split-and-follow-vertically)

Fonts

Fonts are a face. You can set different faces. I define three kind of fonts here:

  • Default: The default font
  • fixed-pitch: The monospace font
  • Variable-pitch: The “normal” font
(set-face-attribute 'default nil :family "FiraCode Nerd Font" :height 100 :weight 'semibold)
(set-face-attribute 'fixed-pitch nil :family "FiraCode Nerd Font" :height 100 :weight 'semibold)
(set-face-attribute 'variable-pitch nil :family "Fira Sans" :height 102 :weight 'medium)

Emojis

To be able to see emojis on emacs the following packages are needeed 🦀

(use-package emojify
  :config
  (global-emojify-mode))

Keybindings

Evil

Evil it’s a layer to use vim-like keybindings on Emacs.It’s basically, VIM inside Emacs. There some functions of VIM that doesn’t work inside Evil though or it does but different. Evil-mode calls the vim modes “states”, because Emacs has his own meaning for the word “mode”.

To undo, undo-tree is needed.

(use-package undo-tree
  :ensure t
  :config
(global-undo-tree-mode 1))
(use-package evil
  :ensure t
  :init
  ;;; This variable has issues with some commands, example, ~vi~ to append text at the beggining of the lines.
  (setq evil-want-keybinding nil)
  :custom
  ;;; This variable needs to be setted by ~customize-group RET evil~. That's why use :custom instead of (setq).
  ;;; this is needed to the undo feature
  (evil-undo-system 'undo-tree)
  :config
  (setq-default evil-cross-lines t)
  (evil-mode 1))

Evil collection and friends

Evil does works fine with text, but some modes has special keybindings or are interactive buffers, so Evil conflict with them. That’s why evil-collection exists. Basically, it’s a collection of key-maps for different modes.

(use-package evil-collection
  :after evil
  :ensure t
  :config
  (evil-collection-init))

There’s some modes not supported by evil-collection.

(use-package evil-org
  :ensure t
  :after org
  :hook ((org-mode . evil-org-mode)
         (evil-org-mode . (lambda ()
      		      (evil-org-set-key-theme))))
  :config
  (require 'evil-org-agenda)
  (evil-org-agenda-set-keys)
  ;; This are keybindings for org-agenda
  (evil-define-key 'motion org-agenda-mode-map
    (kbd "C-p") 'org-agenda-earlier
    (kbd "C-n") 'org-agenda-later))

By defaut, evil moves on physical lines instead of visual lines. This is annoying, because most of the time I work with text and visual-line-mode enabled. This fix it.

(define-key evil-normal-state-map (kbd "<remap> <evil-next-line>") 'evil-next-visual-line)
(define-key evil-normal-state-map (kbd "<remap> <evil-previous-line>") 'evil-previous-visual-line)
(define-key evil-motion-state-map (kbd "<remap> <evil-next-line>") 'evil-next-visual-line)
(define-key evil-motion-state-map (kbd "<remap> <evil-previous-line>") 'evil-previous-visual-line)
(define-key evil-motion-state-map (kbd "C-u") 'evil-scroll-up)

Global keybindings

I’m using general to create keybindings using a leader key.

(global-unset-key (kbd "C-z"))
  (use-package general
    :config
    (general-create-definer my/leader-keys
       :keymaps '(normal insert visual emacs)
       :prefix "SPC"
      :global-prefix "C-SPC")

    (my/leader-keys
     "SPC" '(find-file :which-key "Open a file")
     "k" '(kill-current-buffer :which-key "Kill buffer")
     "b" '(consult-buffer :which-key "Switch buffer")
     "s" '(consult-line :which-key "Search")
     "p" '(projectile-find-file :which-key "Projectile, find file")
     "P" '(projectile-switch-project :which-key "Projectile, switch project")
     "g" '(magit :which-key "Magit")
     "v" '(visual-line-mode :which-key "Activate visual-line-mode")
     "c" '(org-capture :which-key "Capture with org")
     "u" '(winner-undo :which-key "Undo layout")
     "r" '(winner-redo :which-key "Redo layout")
     "RET" '((lambda () (interactive) (shell-command "alacritty > /dev/null 2>&1 & disown")))))

Since Evil it’s working now, this is a good moment to define some personal keybindings.

(global-set-key (kbd "C-x k") 'kill-current-buffer)
(global-set-key (kbd "C-c v") 'visual-line-mode)
(global-set-key (kbd "<f5>")  'ispell-word)

Selectrum

Selectrum is my completion framework of choice, very light and faster than ivy

(use-package selectrum
  :ensure t
  :init
  (selectrum-mode +1))

(use-package savehist
  :init
  (savehist-mode))

(use-package orderless
  :init
  (setq completion-styles '(orderless))
  (setq orderless-skip-highlighting (lambda () selectrum-is-active))
  (setq selectrum-highlight-candidates-function #'orderless-highlight-matches))
;;
(use-package marginalia
  :after selectrum
  :ensure t
  :custom
  (marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
  :init
  (marginalia-mode))
;;
(use-package consult
  :ensure t
  :bind (
         ("C-s" . consult-line)
         ("C-x b" . consult-buffer)))

Utilities

There a lot of usefull packages, and they work excellent out of the box.

Which key

A helper to remember keybindings. If I wait a moment, a mini-buffer appears with some keybindings after I press a keychord. Not very useful.

(use-package which-key
  :defer 0
  :ensure t
  :init
  (which-key-mode))

Magit

The best client for git, only on Emacs.

(use-package magit
  :commands magit-status
  :ensure t
  :config
  (global-set-key (kbd "C-x C-g") 'magit))

Rainbow mode

If an hexagesimal color is on screen, you can see the actual color as the background of the string.

(use-package rainbow-mode
  :defer t
  :ensure t
  :init 
  (rainbow-mode 1))

Rainbow delimiters

Parenthesis are colored, so it’s easy to identify matching parenthesis.

(use-package rainbow-delimiters
  :ensure t
  :hook (prog-mode . rainbow-delimiters-mode))

Yasnippet

Snippets are templates that are called interactively. I can write my own snippets.

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

Company

Adds some autocompletions. It can be slower than the actual typing tho.

(use-package company
  :ensure t
  :config
  (global-company-mode 1))

Helpful

Add some extra text to the describe buffers

(use-package helpful
  :ensure t
  :custom
  (describe-function-function #'helpful-callable)
  (describe-variable-function #'helpful-variable)
  :bind
  ([remap describe-function] . helpful-function)
  ([remap describe-command] . helpful-command)
  ([remap describe-variable] . helpful-variable)
  ([remap describe-key] . helpful-key))

Writeroom-mode

When enabled, the text it’s centered and the modeline disappears. Excellent to long writing sessions.

(use-package writeroom-mode
  :ensure t
  :bind ("<f6>" . writeroom-mode)
  :config
  (setq writeroom-fullscreen-effect 'fullboth))

Dired

Dired it’s the Emacs buit-in file manager. Dired it’s awesome, it does a lot out of the box liike compress, copy, move (“rename” in dired language), delete, and of course, edit files. There’s some extensions to add more functionality, so you can have a very powerfull file manager, even better than ranger, nnn or lf.

Dired it’s great, but while dired is awesome inside Emacs, maybe you’ll have problems trying to open files externally, let’s say videos or LibreOffice files. Right now, I think I have a good setup and I can use it.

Lets configure this thing!

(use-package dired
  :ensure nil ; it's a built-in package
  :commands (dired dired-jump)
  :bind (("C-x C-j" . dired-jump) ; To quickly open a dired buffer on the file path
         ("C-<return>" . (lambda () (interactive) (shell-command "alacritty > /dev/null 2>&1 & disown")))) ; To quickly open a Terminal window
  :hook (
         (dired-mode . dired-hide-details-mode)
         (dired-mode . hl-line-mode))
  :config
  (setq dired-listing-switches "-AgGhovF --group-directories-first") ; man ls to details
  (setq dired-recursive-copies 'always)
  (setq dired-recursive-deletes 'always)
  (setq delete-by-moving-to-trash t) ;It uses the trash bin
  (setq dired-dwim-target 'dired-dwim-target-next-visible) ; If I have two buffers or frames open and I try to copy a file from one buffer, it understand that I want to copy it to the other buffer.

  ;; Some keybindings. It makes use of the ~evil-collection~ key-map and (maybe) replaces some default keybindings.
  (evil-collection-define-key 'normal 'dired-mode-map
    "h" 'dired-single-up-directory
    "l" 'dired-open-file
    "nd" 'dired-create-directory
    "nf" 'dired-create-empty-file
    "/" 'swiper
    "gj" 'counsel-bookmark))

By default dired creates a new buffer for every directory open. This will create a mess of buffers with a lot of dired buffers open. This packages try to avoid this, but dired still creates some buffers.

(use-package dired-single
  :after dired
  :ensure t)

As I said before, the integration with external tools can be improved. This package tries to do that. The main problem with this is you need to specify the extension, so this list it’ll be huge very easily. There’s a variable to use xdg-open instead but it has problems. If only I could use mime types instead.

(use-package dired-open
  :after dired
  :ensure t
  :config
  (setq dired-open-extensions '(
                                ;; Images
                                ("png" . "rifle_sxiv.sh")
                                ("jpg" . "rifle_sxiv.sh")
                                ;; Multimedia
                                ("mp4" . "mpv")
                                ("mkv" . "mpv")
                                ("mp3" . "mpv")
                                ("aac" . "mpv")
                                ("ogg" . "mpv")
                                ("avi" . "mpv")
                                ("mov" . "mpv")
                                ("flac" . "mpv")
                                ;; libreoffice
                                ("odt" . "libreoffice")
                                ("odf" . "libreoffice")
                                ("ods" . "libreoffice")
                                ("xlsx" . "libreoffice")
                                ("odp" . "libreoffice")
                                ;; Otros
                                ("pdf" . "zathura")
                                )))

Dired shows your dotfiles or it doesn’t. This packages allows to toggle the directories that starts with a period. I added a keybinding to toggle it.

  (use-package dired-hide-dotfiles
    :ensure t
    :hook (dired-mode . dired-hide-dotfiles-mode)
    :config
    (evil-collection-define-key 'normal 'dired-mode-map
      "zh" 'dired-hide-dotfiles-mode)
)

This is an interesting package. It adds a tree layout to dired, so I can navigate directories in a similar fashion to org-mode.

(use-package dired-subtree
  :after dired
  :ensure t
  :config
  (setq dired-subtree-use-backgrounds nil)
  ;; this snippet adds icons from all-the-icons to the subtree
  (advice-add 'dired-subtree-toggle :after (lambda ()
					       (interactive)
					       (when all-the-icons-dired-mode
						 (revert-buffer)))))

This is needed to launch dired with a keybinding from my window manager

(defun dired-frame ()
  (interactive)
  (dirvish-dired)
  (delete-other-windows))

UI and appeareance stuff

Doom-modeline

The default modeline it’s fine, but ugly and with a lot of useless information for me. I could customize it, but it’s easier to just install doom-modeline the default modeline of doom-emacs. Most of this is a copy-paste from the official README.

;    (use-package doom-modeline
;      :ensure t
;      :config
;      (add-hook 'window-selection-change-functions #'doom-modeline-set-selected-window)
;      (setq doom-modeline-height 25)
;      (setq doom-modeline-bar-width 4)
;      (setq doom-modeline-buffer-file-name-style 'relative-from-project)
;      (setq doom-modeline-icon t)
;      (setq doom-modeline-major-mode-icon t)
;      (setq doom-modeline-modal-icon t)
;      (setq doom-modeline-major-mode-color-icon t)
;      (setq doom-modeline-minor-modes nil)
;      (setq doom-modeline-buffer-encoding nil)
;      (setq doom-modeline-enable-word-count t)
;      (setq doom-modeline-checker-simple-format t)
;      (setq doom-modeline-persp-name t)
;      (setq doom-modeline-lsp nil)
;      (setq doom-modeline-github nil)
;      (setq doom-modeline-env-version t)
;      (setq doom-modeline-env-enable-python t)
;      (setq doom-modeline-env-enable-ruby t)
;      (setq doom-modeline-env-enable-perl t)
;      (setq doom-modeline-env-enable-go t)
;      (setq doom-modeline-env-enable-elixir t)
;      (setq doom-modeline-env-enable-rust t)
;      (setq doom-modeline-env-python-executable "python")
;      (setq doom-modeline-env-ruby-executable "ruby")
;      (setq doom-modeline-env-perl-executable "perl")
;      (setq doom-modeline-env-go-executable "go")
;      (setq doom-modeline-env-elixir-executable "iex")
;      (setq doom-modeline-env-rust-executable "rustc")
;      (setq doom-modeline-mu4e t)
;      (setq doom-modeline-irc t)
;      (setq doom-modeline-irc-stylize 'identity))
;  (doom-modeline-mode 1)    

Modeline?

(use-package moody
  :ensure t
  :config
  (setq x-underline-at-descent-line t)

  (setq-default mode-line-format
                '(" "
                  mode-line-front-space
                  mode-line-client
                  mode-line-frame-identification
                  mode-line-buffer-identification " " mode-line-position
                  (vc-mode vc-mode)
                  (multiple-cursors-mode mc/mode-line)
                  " " mode-line-modes
                  mode-line-end-spaces))

  (use-package minions
    :ensure t
    :config
    (minions-mode +1))

  ;; Disabled: Trying out clock outside Emacs
  ;; (use-package time
  ;;   :validate-custom
  ;;   (display-time-24hr-format t)
  ;;   (display-time-day-and-date t)
  ;;   (display-time-world-list '(("Europe/Paris" "Paris")
  ;;                              ("Europe/London" "London")
  ;;                              ("America/Los_Angeles" "Los Angeles")))
  ;;   (display-time-string-forms
  ;;    '((format "%s %s %s, %s:%s"
  ;;              dayname
  ;;              monthname day
  ;;              24-hours minutes)))
  ;;   :config
  ;;   (display-time))

  (setq global-mode-string (remove 'display-time-string global-mode-string))

  (moody-replace-mode-line-buffer-identification)
  (moody-replace-vc-mode))

Themes

Emacs has a lot of themes available on internet. It’s possible to set one with (load-theme). Check the heaven&hell package below.

Doom-themes

A collection of themes designated for doom-emacs.

(use-package doom-themes
  :ensure t
  :config
  (setq doom-themes-enable-bold t    ; if nil, bold is universally disabled
        doom-themes-enable-italic t) ; if nil, italics is universally disabled
  (setq doom-gruvbox-dark-variant "hard")

  (doom-themes-visual-bell-config)
  (doom-themes-neotree-config)
  (doom-themes-treemacs-config)
  (doom-themes-org-config))

Modus themes

Per theme configuration

(defun my-demo-modus-vivendi ()
  (modus-themes-with-colors
    (custom-set-faces
     `(default ((,class :background ,"#242424")))
     `(fringe ((,class :background ,"#242424")))
     `(cursor ((,class :background ,"#6C605A")))
     `(hl-line ((,class :background ,"#303030")))
     `(show-paren-match-expression ((,class :background ,"#191a1b")))
     `(selectrum-current-candidate ((,class :background ,"#191a1b")))
     `(mode-line ((,class :background ,"#303030")))
     `(org-block ((,class :background ,"#303030")))
     `(org-block-end-line ((,class :background ,"#303030")))
     `(org-block-begin-line ((,class :background ,"#303030"))))))

(defun my-demo-modus-operandi ()
  (modus-themes-with-colors
    (custom-set-faces
     `(default ((,class :background ,"#fafafa")))
     `(fringe ((,class :background ,"#fafafa")))
     `(cursor ((,class :background ,"#6C605A")))
     `(hl-line ((,class :background ,"#d4d4d4")))
     `(show-paren-match-expression ((,class :background ,"#e4e4e4")))
     `(selectrum-current-candidate ((,class :background ,"#D4D4D4")))
     `(mode-line ((,class :background ,"#ebebeb")))
     `(org-block ((,class :background ,"#ebebeb" :foreground ,"#3A3A3A")))
     `(org-block-end-line ((,class :background ,"#ebebeb")))
     `(org-block-begin-line ((,class :background ,"#ebebeb"))))))

(defun load-vivendi ()
  (interactive)
  (load-theme 'modus-vivendi t)
  (my-demo-modus-vivendi))

(defun load-operandi ()
  (interactive)
  (load-theme 'modus-operandi t)
  (my-demo-modus-operandi))

(defun my-demo-modus-themes-toggle ()
(interactive)
(if (eq (car custom-enabled-themes) 'modus-operandi)
    (load-vivendi)
  (load-operandi)))
(use-package modus-themes
  :ensure t
  :config
(setq modus-themes-mode-line 'moody)
  (setq modus-themes-org-blocks 'gray-background)
  (setq modus-themes-subtle-line-numbers t)
  (setq modus-themes-vivendi-color-overrides
        '((bg-main . "#303030")))
  (setq modus-themes-operandi-color-overrides
        '((bg-main . "#ebebeb"))))
;;  (load-vivendi)
  (global-set-key (kbd "<f7>") 'my-demo-modus-themes-toggle) 

Heaven and Hell

This packages allow to quicky change between two themes. The recommended setup, a light and a dark theme.

;          (use-package heaven-and-hell
;            :ensure t
;            :init
;            (setq heaven-and-hell-theme-type 'light)
;            (setq heaven-and-hell-load-theme-no-confirm t)
;            (setq heaven-and-hell-themes
;                  '((light . modus-operandi)
;                    (dark . modus-vivendi)))
;            :hook (after-init . heaven-and-hell-init-hook)
;            :bind (("C-c <f7>" . heaven-and-hell-load-default-theme)
;                   ("<f7>" . heaven-and-hell-toggle-theme)))

GNOME integration

What the hell?

;; (use-package dbus
;;   :demand t
;;   :init
;;   (defun theme-switcher (value)
;;      (pcase value
;;           ;; No Preference
;;       (0 (shell-command "gsettings set org.gnome.desktop.interface gtk-theme \"adw-gtk3\"")
;;          (load-operandi))
;;            ;; Prefers dark
;;        (1 (shell-command "gsettings set org.gnome.desktop.interface gtk-theme \"adw-gtk3-dark\"")
;;          (load-vivendi))
;;            ;; Prefers light. Not currently used by Gnome
;;        (2 (shell-command "gsettings set org.gnome.desktop.interface gtk-theme \"adw-gtk3\"")
;;          (load-operandi))
;;            (_ (message "Invalid key value"))))

;;   (defun handler (value)
;;     (theme-switcher (car (car value))))

;;   (defun signal-handler (namespace key value)
;;     (if (and
;;          (string-equal namespace "org.freedesktop.appearance")
;;          (string-equal key "color-scheme"))
;;         (theme-switcher (car value))))
;;   :config
;;   (dbus-call-method-asynchronously
;;    :session
;;    "org.freedesktop.portal.Desktop"
;;    "/org/freedesktop/portal/desktop"
;;    "org.freedesktop.portal.Settings"
;;    "Read"
;;    #'handler
;;    "org.freedesktop.appearance"
;;    "color-scheme")

;;   (dbus-register-signal
;;    :session
;;    "org.freedesktop.portal.Desktop"
;;    "/org/freedesktop/portal/desktop"
;;    "org.freedesktop.portal.Settings"
;;    "SettingChanged"
;;    #'signal-handler))

All the icons

Cool icons! It adds icons to doom-modeline, dired and ivy. Remember to run all-the-icons-install-font to actually see the icons.

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

;; Icons for dired
(use-package all-the-icons-dired
  :ensure t
  :hook (dired-mode . (lambda ()
                        (interactive)
                        (unless (file-remote-p default-directory)
                          (all-the-icons-dired-mode)))))

Org-mode

The killer feature of Emacs and the reason why I started to use Emacs. Org-mode it’s a note taking and schedulling format with some markup capabilities. This “markup” it’s more powerful than any other. You can create tables, spreadsheets, run code (just see this config file), export to a lot of formats, the integration with LaTeX it’s awesome, and there’s a lot of plugins and packages to extend it. If you want an idea of the potential of org-mode, my thesis was written almost entirely on org-mode with cites, bibliography, images, tables and everything else; just the final design (fonts, colors and things like that) was made with LibreOffice, and that’s beacause I didn’t knew a lot of LaTeX back then.

I spend most of the time on org-mode. Since I’m not a developer it takes the place of word processors, simple spreadsheets and any calendar and todo application. SO this section it’ll be long, but the most important to me.

Fonts

It’s possible to mix monospace fonts with variable-spaced fonts. To activate this behaviour, enable variable-pitch-mode. This uses the fonts declared at the beggining of the document.

(defun my/org-font-setup ()
  (require 'org-faces) 
  (set-face-attribute 'org-block nil :foreground nil :inherit '(fixed-pitch))
  (set-face-attribute 'org-code nil :inherit '(fixed-pitch))
  (set-face-attribute 'org-table nil :inherit '(fixed-pitch))
  (set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
  (set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
  (set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
  (set-face-attribute 'org-checkbox nil :inherit '(fixed-pitch))
  ;; THIS defun CONTINUES BELOW

Now, let’s make a more elegant style, without colors for title and with different sizes.

  ;;; Remove the word #+TITLE:
  (setq org-hidden-keywords '(title))
  ;; set basic title font
  (set-face-attribute 'org-level-8 nil :weight 'bold :inherit 'default)
  ;; Low levels are unimportant => no scaling
  (set-face-attribute 'org-level-7 nil :inherit 'org-level-8)
  (set-face-attribute 'org-level-6 nil :inherit 'org-level-8)
  (set-face-attribute 'org-level-5 nil :inherit 'org-level-8)
  (set-face-attribute 'org-level-4 nil :inherit 'org-level-8)
  ;; Top ones get scaled the same as in LaTeX (\large, \Large, \LARGE)
  (set-face-attribute 'org-level-3 nil :inherit 'org-level-8 :height 1.1) ;\large
  (set-face-attribute 'org-level-2 nil :inherit 'org-level-8 :height 1.2) ;\Large
  (set-face-attribute 'org-level-1 nil :inherit 'org-level-8 :height 1.3) ;\LARGE
  ;; Only use the first 4 styles and do not cycle.
  (setq org-cycle-level-faces nil)
  (setq org-n-level-faces 4)
  ;; Document Title, (\huge)
  (set-face-attribute 'org-document-title nil
                      :height 1.3
                      :foreground 'unspecified
                      :inherit 'org-level-8)
) ;; <=== org-font-setup ends here

org-mode configuration

Here’s some configuration I made to org-mode, the actual package.

(defun my/org-mode-setup ()
  (org-indent-mode)
  (variable-pitch-mode 1)
  (visual-line-mode 1))

  (use-package org
    :ensure nil
    :hook ((org-mode . my/org-mode-setup)
           (org-mode . my/org-font-setup))
    :config
    ;;(add-hook 'org-mode-hook 'my/org-font-setup)
    ;; Removes the ellipsis at the end and replaces it with a string
    (setq org-ellipsis "")
    (add-to-list 'org-file-apps '("\\.pdf" . "evince %s"))
    ;; Now you can put [[color:red][red text]] when export to html
    (org-add-link-type
      "color"
      (lambda (path)
        (message (concat "color "
                         (progn (add-text-properties
                                 0 (length path)
                                 (list 'face `((t (:foreground ,path))))
                                 path) path))))
      (lambda (path desc format)
        (cond
         ((eq format 'html)
          (format "<span style=\"color:%s;\">%s</span>" path desc))
         ((eq format 'latex)
          (format "{\\color{%s}%s}" path desc)))))

    ;; If you have many subtask, when you mark it as DONE, the main task remain unchaged. With this function, if all the subtask are marked as DONE, the main task is marked as well.
    (defun org-summary-todo (n-done n-not-done)
      "Switch entry to DONE when all subentries are done, to TODO otherwise."
      (let (org-log-done org-log-states)   ; turn off logging
        (org-todo (if (= n-not-done 0) "DONE" "PROJ"))))
    (add-hook 'org-after-todo-statistics-hook 'org-summary-todo)
    ;; This keybinding uses org-store-link to store a postition on a document, so you can link it on other document.
    (global-set-key (kbd "C-c l") 'org-store-link)

;; Activate org-beamer
(org-beamer-mode)

    ;; You can add blocks pressing C-, and then the corresponding key.
  (require 'org-tempo)
  (setq org-structure-template-alist
     '(("el" . "src emacs-lisp")
       ("a" . "export ascii")
       ("c" . "center")
       ("C" . "comment")
       ("e" . "example")
       ("E" . "export")
       ("h" . "export html")
       ("x" . "export latex")
       ("q" . "quote")
       ("s" . "src")
       ("v" . "verse")))

;; NOTE: THE USE PACKAGE MACRO CONTINUES

LaTeX

LaTeX uses some templates to define classes. You can write your own classes. I have this, one used on my thesis, the other copied from the org-wiki because it looks nice.

(require 'ox-extra)
(ox-extras-activate '(ignore-headlines))

(setq org-format-latex-header "\\documentclass{article} \\usepackage[usenames]{color} \\usepackage[default]{cantarell} \\pagestyle{empty} \\setlength{\\textwidth}{\\paperwidth} \\addtolength{\\textwidth}{-3cm} \\setlength{\\oddsidemargin}{1.5cm} \\addtolength{\\oddsidemargin}{-2.54cm} \\setlength{\\evensidemargin}{\\oddsidemargin} \\setlength{\\textheight}{\\paperheight} \\addtolength{\\textheight}{-\\headheight} \\addtolength{\\textheight}{-\\headsep} \\addtolength{\\textheight}{-\\footskip} \\addtolength{\\textheight}{-3cm} \\setlength{\\topmargin}{1.5cm} \\addtolength{\\topmargin}{-2.54cm}")

(use-package ox-latex
  :ensure nil
  :config
  (setq org-latex-pdf-process
        '("pdflatex -interaction nonstopmode -output-directory %o %f"
          "bibtex %b"
          "pdflatex -interaction nonstopmode -output-directory %o %f"
          "pdflatex -interaction nonstopmode -output-directory %o %f"))
  (setq org-latex-with-hyperref nil) ;; stop org adding hypersetup{author..} to latex export
  ;; (setq org-latex-prefer-user-labels t)

  ;; deleted unwanted file extensions after latexMK
  (setq org-latex-logfiles-extensions
        (quote ("lof" "lot" "tex~" "aux" "idx" "log" "out" "toc" "nav" "snm" "vrb" "dvi" "fdb_latexmk" "blg" "brf" "fls" "entoc" "ps" "spl" "bbl" "xmpi" "run.xml" "bcf" "acn" "acr" "alg" "glg" "gls" "ist")))

  (unless (boundp 'org-latex-classes)
    (setq org-latex-classes nil)))
(add-to-list 'org-latex-classes
      '("koma-article"
        "\\documentclass{scrartcl}"
        "\\usepackage[left=3cm,right=4.5cm,bottom=3cm,top=10cm]{geometry}"
        ("\\section{%s}" . "\\section*{%s}")
        ("\\subsection{%s}" . "\\subsection*{%s}")
        ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
        ("\\paragraph{%s}" . "\\paragraph*{%s}")
        ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))

  ;; https://github.com/philipphoman
      '("mybeamerposter"
        "\\documentclass[final]{beamer}
                 \\usepackage[orientation=portrait,size=letter]
                 \\usepackage[absolute,overlay]{textpos}
                       \\usepackage[authoryear]{natbib}
                       [NO-DEFAULT-PACKAGES]"))


) ;; <=== The use-package org ends here

Center buffers

This centers some buffers. Just aesthetics. First, lets define the function.

  (defun my/org-mode-visual-fill ()
    (setq visual-fill-column-width 100
          visual-fill-column-center-text t)
    (visual-fill-column-mode 1))

;    (use-package visual-fill-column
;      :hook (
;      (org-agenda-mode . my/org-mode-visual-fill)
;      (org-mode . my/org-mode-visual-fill)
;      (elpher-mode . my/org-mode-visual-fill)))

More export formats

Though org-mode has a long range of formats, we can add more.

;; Pandoc support
(use-package ox-pandoc
  :after org
  :ensure t)

Superstar

It replaces the stars for bullets and unicode glyphs. It looks nice and it’s easier to read. Also, changes some TODO keywords.

(use-package org-superstar
  :ensure t
  :config
  (setq superstar-special-todo-items t))

(defun my/org-enable-prettify ()
  (setq prettify-symbols-alist
        '(("DROP" . ?✖)
          ("EMISION" . ?✒)
          ("FINALIZADO" . ?✔)
          ("LIKE" . ?❤)))
  (prettify-symbols-mode 1))
(add-hook 'org-mode-hook 'my/org-enable-prettify)
;;
;; This hook enables org-superstar 
(add-hook 'org-mode-hook
          (lambda ()
            (org-superstar-mode 1)))

Org-tree-slide

Want to make a presentation with slides but don’t want to use PowerPoint, beamer or some ridiculous web-based slides? Just use Emacs and org-mode to show your slides. The slides are, basically, narrowed org buffers, so they’re editable and you can use the complete power of org-mode and Emacs.

(use-package org-tree-slide
  :ensure t
  :defer t
  :config
  (setq org-tree-slide-header t)
  (setq org-tree-slide-slide-in-effect nil)
  )

;; This packages hides the modeline because I don't know how to hide it without it.
(use-package hide-mode-line
  :defer t
  :ensure t)

;; This keys are to go to the next or previous slide. It uses ~evil-collection key-map
(evil-define-key 'normal 'org-tree-slide-mode-map
  "{"  'org-tree-slide-move-previous-tree
 
  "}"  'org-tree-slide-move-next-tree)

When showing your slides you want to remove all distractions right? This hooks do it.

(eval-after-load "org-tree-slide"
  '(progn
     (add-hook 'org-tree-slide-play-hook
		 (lambda ()
		   (org-display-inline-images 1)
		   (hide-mode-line-mode 1)
		   (display-line-numbers-mode -1)
		   (variable-pitch-mode 1)))
     (add-hook 'org-tree-slide-stop-hook
		 (lambda ()
		   (org-display-inline-images -1)
		   (hide-mode-line-mode -1)
		   (display-line-numbers-mode 1)
		   (variable-pitch-mode -1)))))

Agenda

Org-mode is a TODO and scheduling format. So it has an integrated agenda. You can configure it and make it looks like you want it.

Let’s define some basic stuff first

;; (setq org-directory "/mnt/Data/ORG") ; The directory of your files
;; (setq org-agenda-files '(
;;                          ("/mnt/data/Nextcloud/ORG/sync/TODO.org")
;;                          ("/mnt/data/Nextcloud/ORG/escuela.org")))
 (global-set-key (kbd "C-c a") 'org-agenda) ; Keybinding to open the agenda buffer

 ;; by default the agenda takes the current buffer. With this it'll create its own buffer
 (setq org-agenda-window-setup 'other-window)
 (setq org-agenda-span 7) ; Only shows next 3 days
 (setq org-agenda-start-on-weekday nil) ;;Agenda start on monday
 (setq org-agenda-start-with-log-mode t)
 (setq org-log-done 'time)
 (setq org-log-into-drawer t)

 ;; Since I speak spanish as my mother language, I want the days and months in spanish. Without this it'll remain on english.
 (setq calendar-day-name-array ["domingo" "lunes" "martes" "miércoles" "jueves" "viernes" "sábado"])
 (setq calendar-month-name-array ["enero" "febrero" "marzo" "abril" "mayo" "junio" "julio" "agosto" "septiembre" "octubre" "noviembre" "diciembre"])

 ;; Activate hl-line-mode on agenda buffers
 (add-hook 'org-agenda-mode-hook 'hl-line-mode)

Now, this is pure eye-candy

;; Removes the ~======~ between blocks. It's ugly IMO
(setq org-agenda-block-separator (string-to-char " "))
(setq org-agenda-window-setup 'current-window)

;;Remove ths strings ~SCHEDULED:~ and ~DEADLINE:~ 
(setq org-agenda-scheduled-leaders '("" ""))
(setq org-agenda-deadline-leaders '("🕓" "En %d días:" "Hace %d días:"))

;; Custom fonts! I'm using Ubuntu fonts here... I'm not sure why.
(custom-theme-set-faces 'user
                        '(org-agenda-date-today ((t (:weight bold :height 130)))) ; Today
                        '(org-agenda-structure ((t (:underline nil :weight bold :height 150 :width normal)))) ; Titles
                        '(org-agenda-calendar-event ((t (:inherit (default)))))
                        '(org-agenda-calendar-sexp ((t (:inherit (default))))));Rest of the text

This is my own agenda. It has the modules I want, the way I want. To run it, press o.

(setq org-agenda-custom-commands
      '(("o" "My Agenda"
         ((agenda "" (
                      (org-agenda-files '("/mnt/data/Nextcloud/ORG/sync/TODO.org"))
                      (org-agenda-overriding-header "📅 Calendario\n")
                      (org-agenda-skip-scheduled-if-done t)
                      (org-agenda-skip-timestamp-if-done t)
                      (org-agenda-skip-deadline-if-done t)
                      (org-agenda-skip-deadline-prewarning-if-scheduled nil)
                      (org-agenda-start-day "+0d")
                      (org-agenda-span 7)
                      (org-agenda-prefix-format "  %?-t %T %?5s")
                      (org-agenda-repeating-timestamp-show-all t)
                      ;;(concat "  %-3i  %-15b %t%s" org-agenda-hidden-separator)
                      (org-agenda-remove-tags t)
                 (org-agenda-todo-keyword-format " ")
                  (org-agenda-time)
                  (org-agenda-current-time-string "⮜┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ ahora")
                  ;(org-agenda-deadline-leaders '("" ""))
                  (org-agenda-time-grid (quote ((today require-timed) (800 1000 1200 1400 1600 1800 2000 2200) "      " "┈┈┈┈┈┈┈┈┈┈┈┈┈")))))

          (todo "NEXT" (
                        (org-agenda-files '("/mnt/data/Nextcloud/ORG/sync/TODO.org"))
                        (org-agenda-overriding-header "⭐ Siguientes\n")
                        (org-agenda-remove-tags nil)
                        (org-agenda-hide-tags-regexp "^\@")
                        (org-agenda-todo-ignore-scheduled 'future)
                        (org-agenda-prefix-format "%T %?-s")
                        (org-agenda-todo-keyword-format "")))

          (todo "ESPERANDO" (
                        (org-agenda-files '("/mnt/data/Nextcloud/ORG/sync/TODO.org"))
                        (org-agenda-overriding-header "🕘 Esperando\n")
                        (org-agenda-remove-tags nil)
                        (org-agenda-hide-tags-regexp "^\@")
                        (org-agenda-todo-ignore-scheduled 'future)
                        (org-agenda-prefix-format "%T %?-s")
                        (org-agenda-todo-keyword-format "")))


          (todo "PROJ" (
                        (org-agenda-files '("/mnt/data/Nextcloud/ORG/sync/TODO.org"))
                        (org-agenda-overriding-header "✈ Proyectos\n")
                        (org-agenda-remove-tags nil)
                        (org-agenda-hide-tags-regexp "^\@")
                        (org-agenda-todo-ignore-scheduled 'future)
                        (org-agenda-prefix-format "%T %?-s")
                        (org-agenda-todo-keyword-format "")))

          (todo "" (
                        (org-agenda-files '("/mnt/data/Nextcloud/ORG/sync/TODO.org"))
                        (org-agenda-overriding-header "☑ Tareas\n")
                        (org-agenda-remove-tags nil)
                        (org-agenda-todo-ignore-scheduled 'future)
                        (org-agenda-prefix-format "%?-s")
                        (org-agenda-todo-keyword-format "%-1s")))))

        ("h" "Horario escolar"
         ((agenda "" (
                      (org-agenda-files '("/mnt/data/CIMB/horario.org"))
                      (org-agenda-overriding-header "🗓 Horario\n")
                      (org-agenda-skip-scheduled-if-done t)
                      (org-agenda-skip-timestamp-if-done t)
                      (org-agenda-skip-deadline-if-done t)
                      (org-agenda-skip-deadline-prewarning-if-scheduled nil)
                      (org-agenda-start-day "+0d")
                      (org-agenda-span 1)
                      (org-agenda-prefix-format "  %?-t %T %?5s")
                      (org-agenda-repeating-timestamp-show-all t)
                      ;;(concat "  %-3i  %-15b %t%s" org-agenda-hidden-separator)
                      (org-agenda-remove-tags t)
                 (org-agenda-todo-keyword-format " ")
                  (org-agenda-time)
                  (org-agenda-current-time-string "⮜┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ ahora")
                  ;(org-agenda-deadline-leaders '("" ""))
                  (org-agenda-time-grid (quote ((today require-timed) (800 1000 1200 1400 1600 ) "      " "┈┈┈┈┈┈┈┈┈┈┈┈┈")))))))))

Finally, this function it’s needed to spawn a floating agenda with my Window Manger

(defun agenda-frame ()
  (interactive)
  (org-agenda nil "o")
  (delete-other-windows))

Refile

 (setq org-refile-targets
	'(("../DONE.org" :maxlevel . 1)))

 (advice-add 'org-refile :after 'org-save-all-org-buffers)

calfw

Org-agenda shows your entries as a list. If you want a calendar view, then you need to rely on this awesome package called calfw. To run it, run cfw:open-calendar-buffer or cfw:open-org-calendar.

(use-package calfw
  :ensure t)
(use-package calfw-org
  :ensure t)

Org-capture

Org-capture allows to capture text at any moment, just call the buffer, write text and automatically it will be appended to the selected file. This are my templates.

(global-set-key (kbd "C-c c") 'org-capture)
   (setq org-capture-templates
         '(
           ("i" "Inbox" entry
            (file "/mnt/data/Nextcloud/ORG/sync/Inbox.org"))
           ("d" "Diario de clase")
           ("de" "Tercero")
           ("dea" "Bitácora de 3A" plain
            (file+olp+datetree "/mnt/data/Nextcloud/ORG/journal.org")
             "**** %? :3A:\n")
           ("deb" "Bitácora de 3B" plain
            (file+olp+datetree "/mnt/data/Nextcloud/ORG/journal.org")
             "**** %? :3B:\n")
           ("dec" "Bitácora de 3C" plain
            (file+olp+datetree "/mnt/data/Nextcloud/ORG/journal.org")
             "**** %? :3C:\n")
           ("ded" "Bitácora de 3D" plain
            (file+olp+datetree "/mnt/data/Nextcloud/ORG/journal.org")
             "**** %? :3D:\n")))

It’s possible to call org-capture from anywhere using the Window Manager. To have a floating window, this snippet its needed

;; Org capture flotante
(defadvice org-capture-finalize
(after delete-capture-frame activate)
"Advise capture-finalize to close the frame"
(if (equal "capture" (frame-parameter nil 'name))
(delete-frame)))

(defadvice org-capture-destroy
(after delete-capture-frame activate)
"Advise capture-destroy to close the frame"
(if (equal "capture" (frame-parameter nil 'name))
(delete-frame)))

(defadvice org-switch-to-buffer-other-window
    (after supress-window-splitting activate)
  "Delete the extra window if we're in a capture frame"
  (if (equal "capture" (frame-parameter nil 'name))
      (delete-other-windows)))

(defadvice org-capture-finalize
    (after delete-capture-frame activate)
  "Advise capture-finalize to close the frame"
  (if (equal "capture" (frame-parameter nil 'name))
      (delete-frame))) 

(defun capture-frame ()
  (interactive)
  (org-capture)
  (delete-other-windows))

org babel

Org-babel allows to run code inside Emacs and print the output right after the code block. Babel it’s used to create this config file. You need the required compilers and everything if you add more languages here. By default, babel only evaluates elisp.

(org-babel-do-load-languages
 'org-babel-load-languages
 '((python . t)
   (shell . t)))
 ;; Automatically tangle our Emacs.org config file when we save it
 (defun my/org-babel-tangle-config ()
   (when (string-equal (file-name-directory (buffer-file-name))
			(expand-file-name user-emacs-directory))
     ;; Dynamic scoping to the rescue
     (let ((org-confirm-babel-evaluate nil))
	(org-babel-tangle))))

 (add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'my/org-babel-tangle-config))) 

Org appear

This package hides the emphasis characters. Similar to the conceal feature of vim.

(use-package org-appear
  :config
  ;; This is needed to org-appear
  (setq org-hide-emphasis-markers t)
  (setq org-pretty-entities t)
  (setq org-link-descriptive t)
  (setq org-appear-autoentities t)
  (setq org-appear-autoemphasis t)
  (setq org-appear-autolinks t)
  (setq org-appear-autosubmarkers t)
  :hook (org-mode . org-appear-mode))

Org reveal

(use-package ox-reveal
  :ensure t
  :config
  ;(setq org-re-reveal-center t)
  (setq org-reveal-root "file:///home/juan/.repos/reveal.js"))

Markdown

Fonts

It’s possible to mix monospace fonts with variable-spaced fonts. To activate this behaviour, enable variable-pitch-mode. This uses the fonts declared at the beggining of the document. This is entirely based on org mode configuration.

(set-face-attribute 'markdown-blockquote-face nil :foreground nil :inherit '(fixed-pitch))
(set-face-attribute 'markdown-code-face nil :inherit '(fixed-pitch))
(set-face-attribute 'markdown-table-face nil :inherit '(fixed-pitch))
(set-face-attribute 'markdown-italic-face nil :slant 'italic :weight 'medium :inherit 'default)
;; set basic title font
(set-face-attribute 'markdown-header-face-6 nil :weight 'bold :inherit 'default)
;; Low levels are unimportant => no scaling
(set-face-attribute 'markdown-header-face-5 nil :inherit 'markdown-header-face-6)
(set-face-attribute 'markdown-header-face-4 nil :inherit 'markdown-header-face-6)
;; Top ones get scaled the same as in LaTeX (\large, \Large, \LARGE)
(set-face-attribute 'markdown-header-face-3 nil :inherit 'markdown-header-face-6 :height 1.1) ;\large
(set-face-attribute 'markdown-header-face-2 nil :inherit 'markdown-header-face-6 :height 1.3) ;\Large
(set-face-attribute 'markdown-header-face-1 nil :inherit 'markdown-header-face-6 :height 1.5) ;\LARGE
(setq markdown-hide-markup t)
(setq markdown-header-scaling t)

Other formats, languages and programs

Lua support

I don’t code too much LUA, but it’s good to have, at least, color syntax.

(use-package lua-mode
  :mode "\\.lua\\'"
  :ensure t)

(use-package luarocks
  :after (lua)
  :ensure t)

Markdown

Though I don’t use markdown a lot on Emacs, it’s fine to have syntax highlightning and some functionality with pandoc. It needs pandoc installed. If you’re on arch and you doesn’t work with Haskell, download pandoc-bin from AUR and evade the +750Mb of haskell libraries.

(use-package markdown-mode
  :ensure t
  :mode (("README\\.md\\'" . gfm-mode)
	   ("\\.md\\'" . markdown-mode)
	   ("\\.markdown\\'" . markdown-mode))
  :init (setq markdown-command "multimarkdown"))
(setq markdown-command "/usr/bin/pandoc")

Ledger

Ledger it’s a program to keep track of your expenses. It’s very unix-y, it reads a text file with a very simple and human-readable format and prints out information about your balance. This is a mode to easily write the transactions and run ledger directly from Emacs.

(use-package ledger-mode
  :ensure t
  :mode "\\.lgr\\'"
  :config
  (evil-define-key 'normal ledger-mode-map (kbd "SPC r") 'ledger-report)
  (evil-define-key 'normal ledger-mode-map (kbd "SPC i") 'ledger-add-transaction))

(use-package evil-ledger
  :ensure t
  :after ledger-mode
  :hook
  (ledger-mode . evil-ledger-mode))

Beancount

; (add-to-list 'load-path "~/.emacs.d/packages/")
; (require 'beancount)
; (add-to-list 'auto-mode-alist '("\\.beancount\\'" . beancount-mode))

Kdeconnect

A kdeconnect client inside emacs. I want to integrate it with dired.

(use-package kdeconnect
  :ensure t
  :config
  (setq kdeconnect-devices "7843123afa92d0a8")
  (setq kdeconnect-active-device "7843123afa92d0a8"))

Gemini

A better web.. Adds colorscheme for gmi files

(use-package gemini-mode)

Runtime Performance

Dial the GC threshold back down so that garbage collection happens more frequently but in less time.

;; Make gc pauses faster by decreasing the threshold.
(setq gc-cons-threshold (* 2 1000 1000))