emacs config
Go to file
diego 6fee8643a4 update 2023-08-02 19:57:17 +02:00
.gitignore Added c-eldoc-mode 2020-07-09 21:36:16 +02:00
LICENSE Added license 2020-06-07 15:53:24 +02:00
config.org update 2023-08-02 19:57:17 +02:00
init.el Cleaned init.el because let's be honest. That thing is completly 2020-07-06 21:09:57 +02:00
readme.org readme.org 2020-06-07 12:29:58 +02:00


emacs config

suragu's Emacs config

This is my Emacs configuration, if you don't like it, that's ok because I made it thinking of myself. the code here is tidy so anyone could modify it without great pain.


Just copy this repository to your emacs configuration path. Nothing else is needed.


  • I can
  • I don't like doom emacs
  • I don't like spacemacs
  • I don't want to learn doom emacs
  • I don't want to learn spacemacs
  • I don't like Vim


  ;; Minimize garbage collection during startup
  (setq gc-cons-threshold most-positive-fixnum)

  ;; Lower threshold back to 8 MiB (default is 800kB)
  (add-hook 'emacs-startup-hook
       (lambda ()
            (setq gc-cons-threshold (expt 2 23))))

melpa crap, and basic packages installation

melpa, where you get the packages. This also installs use-package, and other packages I use.

  (require 'package)
  (let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
                      (not (gnutls-available-p))))
             (proto (if no-ssl "http" "https")))
       ;; Comment/uncomment these two lines to enable/disable MELPA and MELPA Stable as desired
       (add-to-list 'package-archives (cons "melpa" (concat proto "://melpa.org/packages/")) t)
       ;;(add-to-list 'package-archives (cons "melpa-stable" (concat proto "://stable.melpa.org/packages/")) t)
       (when (< emacs-major-version 24)
            ;; For important compatibility libraries like cl-lib
            (add-to-list 'package-archives '("gnu" . (concat proto "://elpa.gnu.org/packages/")))))

  (if (< emacs-major-version 27)
  (unless (package-installed-p 'use-package)
       (package-install 'use-package))

Generic packages

Here I install some packages that don't need configuration. Remember to run M-x all-the-icons-install-fonts after the first init to install the fonts.

  (use-package markdown-mode
       :defer 1
       :ensure t
       :init(add-hook 'markdown-mode-hook 'auto-fill-mode))
  (use-package all-the-icons
       :defer 1
       :ensure t)
  (use-package which-key
       :ensure t
       :init (which-key-mode))


C-c n for indent-buffer. I don't use the rest.

  (setq-default tab-width 5)
  (defvaralias 'sgml-basic-offset 'tab-width)
  (add-hook 'html-mode-hook
       (lambda ()
            (set-fill-column 100)))
  (add-hook 'markdown-mode-hook
       (lambda ()
            (set-fill-column 75)))

  (defun indent-buffer ()
            (indent-region (point-min) (point-max) nil)))
  (global-set-key (kbd "C-c n") 'indent-buffer)
  ;; C bullshit
  (c-set-offset 'arglist-cont-nonempty '+)


Probably this overwrites another keybinding. But since I overwrited it. I don't think i'd ever use the overwritten.

  (global-set-key (kbd "M-m") 'mark-whole-buffer)
  (global-set-key (kbd "C-c m") 'man)
  (define-key org-mode-map (kbd "C-c p") 'org-publish-current-file)
  (set-frame-font "Monospace 12")

No idea

  (setq package-enable-at-startup nil) (package-initialize)
  (setq make-backup-files nil) ; stop creating backup~ files
  (setq auto-save-default nil) ; stop creating #autosave# files
  (put 'upcase-region 'disabled nil)
  (defun contextual-menubar (&optional frame)
       "Display the menubar in FRAME (default: selected frame) if on a
  graphical display, but hide it if in terminal."
       (set-frame-parameter frame 'menu-bar-lines
            (if (display-graphic-p frame)
                 1 0)))
  (add-hook 'after-make-frame-functions 'contextual-menubar)
  (use-package zencoding-mode
       :ensure t
       :defer 1)

My functions

Functions I wrote because emacs lisp is cool and useful.

  (defun sosa/goto-previous-buffer ()
       "Switch to the previous buffer."
       (switch-to-buffer (other-buffer)))

  (defun sosa/kill-inner-word ()
       "Unlike (kill-word) function, this function actually kill a world."
       (forward-char 1)
       (kill-word 1))
  (defun sosa/no-lines()
       "Locally disable number line mode, useful hooks."
       (display-line-numbers-mode -1))

  (defun sosa/git-pushall ()
       "Call the git pushall shell command."
       (shell-command "git pushall"))

  (defun sosa/goto-dashboard ()
       "Goes to the dashboard buffer"
       (switch-to-buffer "*dashboard*")

  (setq org-publish-project-alist
              :base-directory "~/docs/qorg_qorg/"
              :publishing-directory "~/docs/mounts/sites/suragu.net"
              :section-numbers nil
              :publishing-function org-html-publish-to-html
              :table-of-contents nil
              :recursive t

  (defun sosa/make-website ()
       "Publish the .org files of suragu.net to the sshfs mountpoint"
       (org-publish "suragu.net"))

  (defun run-current-file ()
       "Execute or compile the current file.
  For example, if the current buffer is the file x.pl,
  then it'll call “perl x.pl” in a shell.
  The file can be php, perl, python, bash, java.
  File suffix is used to determine what program to run."
       (let (ext-map file-name file-ext prog-name cmd-str)
                                          ; get the file name
                                          ; get the program name
                                          ; run it
            (setq ext-map
                       ("php" . "php")
                       ("pl" . "perl")
                       ("py" . "python")
                       ("p6" . "raku")
                       ("raku" . "raku")
                       ("sh" . "bash")
                       ("java" . "javac")
            (setq file-name (buffer-file-name))
            (setq file-ext (file-name-extension file-name))
            (setq prog-name (cdr (assoc file-ext ext-map)))
            (setq cmd-str (concat prog-name " " file-name))
            (shell-command cmd-str)))

  (defun sosa/repos ()
       (dired "/home/diego/Escritorio/zpool/repos/"))
  (global-set-key (kbd "C-c r") 'sosa/repos)


Emacs customization, Here is where most of the configuration is.


Sane defaults!!!

  (tool-bar-mode -1)
  (menu-bar-mode -1)
  (scroll-bar-mode -1)
  (set-face-background hl-line-face "#434343")
  (setq-default cursor-type 'box)
  (blink-cursor-mode 1)
  (setq-default major-mode 'text-mode)
  (defalias 'yes-or-no-p 'y-or-n-p)
  ;; Are you experienced?

  (set-face-background 'line-number nil)
  (set-face-background 'line-number-current-line nil)
  (setq-default Man-notify-method 'pushy)

Highlight matching parentheses

Useful for programming in lisp. I don't program in Lisp, but well.

  (show-paren-mode 1)
  (setq show-paren-style 'mixed)

  (setq startup/gc-cons-threshold gc-cons-threshold)
  (setq gc-cons-threshold most-positive-fixnum)
  (defun startup/reset-gc () (setq gc-cons-threshold startup/gc-cons-threshold))
  (add-hook 'emacs-startup-hook 'startup/reset-gc)

Tramp mode shit

(basically) no limit for remote files.

  (set-variable 'tramp-copy-size-limit 122222222222)
  (set-variable 'tramp-inline-compress-start-size 12222222222222)

Lines and columns

Show relative lines in each file. Also display the column in the minibuffer.

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


Flycheck is a syntax validator and lintern for programming.

  (use-package flycheck
       :ensure t
       (add-hook 'after-init-hook #'global-flycheck-mode))

And for raku

  (use-package flycheck-raku
       :ensure t
       (add-hook 'raku-mode 'flycheck-raku-mode))


vterm is better than ansi-term and shit, despite it's kinda slow, it's a price i'm willing to pay. Remember that to compile VTerm you need cmake installed. See the error buffer that is created everytime you try to copmile vterm for further information.

It should use your default shell by default.

  (use-package "vterm"
       :ensure t)

And to have multiple buffers

  (use-package multi-vterm
       :ensure t
       :bind("C-x C-t" . multi-vterm))


  (use-package "base16-theme"
       :ensure t
       :init(load-theme 'base16-black-metal-bathory t)
  (set-cursor-color "purple")


So, you know, C-s in emacs sucks, so this is a repleacement for that.

  (use-package ctrlf
       :ensure t
       :defer 1
       (ctrlf-mode +1))

Company and Irony

Some shit for autocompletion and that kind of shit.

Programming language things


Parentheses highlight in lisp modes. So you can easily identify them.

  (use-package rainbow-delimiters
       :ensure t
       (add-hook 'emacs-lisp-mode-hook 'rainbow-delimiters-mode)
       (add-hook 'lisp-mode-hook 'rainbow-delimiters-mode)
       (add-hook 'scheme-mode-hook 'rainbow-delimiters-mode))

  (setq lisp-indent-offset 5)


I use LSP for perl.

  (setq perl-indent-level 5)
  (defalias 'perl-mode 'cperl-mode)
  (add-hook 'perl-mode-hook (lambda ()
                                 (irony-mode -1)))
  (load-file "~/.config/emacs/perltidy.el")


This use c-eldoc mode so it prints the function's prototype in the minibuffer. Which is very useful since Irony works when it wants to. LSP is also used for further Programming.

  (use-package c-eldoc
       :ensure t
       (add-hook 'c-mode-hook 'c-turn-on-eldoc-mode))
  (setq c-default-style "k&r")
  (add-hook 'c-mode-hook (lambda ()
                              (irony-mode -1)))


Raku, the cornerstone of any well designed programming language.

  (setq raku-indent-offset 5)
  (setq raku-exec-path "/home/diego/.local/bin/raku")

HTML & CSS offset

  (setq css-indent-offset 5)
  (setq sgml-basic-offset 5)


  (setq org-ellipsis " ")
  (setq org-src-fontify-natively t)
  (setq org-src-tab-acts-natively t)
  (setq org-confirm-babel-evaluate nil)
  (setq org-export-with-smart-quotes t)
  (setq org-src-window-setup 'current-window)
  (add-hook 'org-mode-hook 'org-indent-mode)
  (add-hook 'org-mode-hook 'sosa/no-lines) 
  ;; Syntax highlighting in exports
  (use-package htmlize
       :ensure t)
  (setq org-html-head ""
       org-html-head-extra ""
       org-html-head-include-default-style nil
       org-html-head-include-scripts nil
       org-html-preamble nil
       org-html-postamble nil
       org-html-use-infojs nil)


Here I put functions I won't bother to document because they're so simple.

  (global-set-key (kbd "M-d") 'sosa/kill-inner-word)
  (global-set-key (kbd "M-.") 'repeat)
  (global-set-key (kbd "C-x k") 'kill-buffer)
  (global-set-key (kbd "C-x C-k") 'kill-current-buffer)
  (global-unset-key (kbd "C-x C-b"))
  (global-set-key (kbd "C-x C-b") 'sosa/goto-previous-buffer)


For some reason, there is no ispell spanish in void linux. so i had to fallback to hunspell. which does the same.

  (defvar ispell-program-name "hunspell") ;; Or whatever you use
  ;; (ispell, aspell...)


Ahhh, the emacs file browser, better than ranger and others… Hide dotfiles:

  (use-package dired-hide-dotfiles
       :ensure t
       (defun my-dired-mode-hook ()
            "My `dired' mode hook."
            ;; To hide dot-files by default

            ;; To toggle hiding
            (define-key dired-mode-map "." #'dired-hide-dotfiles-mode))

       (add-hook 'dired-mode-hook #'my-dired-mode-hook))
  (use-package async
       :ensure t
       :init (dired-async-mode 1))
  (add-hook 'dired-mode-hook
       (lambda ()

Now let's make the thing lysergic

  (set-face-foreground dired-directory-face "orange")
  (set-face-foreground dired-symlink-face "cyan")
  (set-face-foreground dired-mark-face "green")
  (set-face-foreground dired-marked-face "blue")

Good sorting

(setq dired-listing-switches "-aBhl  --group-directories-first")

kill ring popup

  (use-package popup-kill-ring
       :ensure t
       :bind ("M-y" . popup-kill-ring))


Scroll by lines rather than by pages.

  (setq scroll-step 1)
  (setq scroll-conservatively 10000)
  (setq auto-window-vscroll nil)
  (scroll-bar-mode 1)


  (add-hook 'shell-mode-hook 'yas-minor-mode)
  (add-hook 'shell-mode-hook 'flycheck-mode)
  (add-hook 'shell-mode-hook 'company-mode)

  (defun shell-mode-company-init ()
       (setq-local company-backends '((company-shell

  (use-package company-shell
       :ensure t
       (require 'company)
       (add-hook 'shell-mode-hook 'shell-mode-company-init))

Mark multiple

Multiple cursors :DD

  (use-package "multiple-cursors"
       :ensure t
       :bind ("C-x q" . 'mc/mark-next-like-this))

Highlight indent guides

I don't really know, it looks cool.

  (use-package "highlight-indent-guides"
       :ensure t
       :init (add-hook 'prog-mode-hook 'highlight-indent-guides-mode)
       (setq highlight-indent-guides-method 'bitmap))

Ace jump mode

Run, live to fly Fly to live, do or die Won't you run, live to fly Fly to live, aces high

  (use-package "ace-jump-mode"
       :ensure t
       :bind("C-l" . 'ace-jump-mode))

And same but jumping between frames

  (use-package "ace-window"
       :ensure t
       :bind("M-l" . 'ace-window)
       :bind("M-o" . 'ace-delete-window))
  ;; Gotta remove the bad habits
  (global-unset-key (kbd "C-x o"))

Expand region

  (use-package expand-region
       :ensure t
       :init(global-unset-key (kbd "C-q"))
       (global-set-key (kbd"C-q") 'er/expand-region))

  (defun sosa/mark-words-between-quotes ()
       "Does that."
       (er/expand-region 2))

  (global-set-key (kbd "C-c q") 'sosa/mark-words-between-quotes)

Beacon mode

  (use-package "beacon"
       :ensure t
       :init(beacon-mode 1))


Le language server

  (use-package "lsp-mode"
       :ensure t)
  (use-package "lsp-ui"
       :ensure t
       :init(add-hook 'lsp-mode-hook 'lsp-ui-mode))


I am tired of M-x auto-fill-mode in some modes

  (add-hook 'org-mode-hook 'auto-fill-mode)
  (add-hook 'text-mode-hook 'auto-fill-mode)
  (add-hook 'sgml-mode-hook 'auto-fill-mode)
  (add-hook 'sgml-mode-hook 'zencoding-mode)
  (add-hook 'Man-mode-hook 'sosa/no-lines)
  (add-hook 'speedbar-mode-hook 'sosa/no-lines)

Hungry delete

Having to delete multiple whitespaces is one of the things I hate, thankfully there's this thing.

  (use-package "hungry-delete"
       :ensure t


  (use-package "yasnippet"
       :ensure t
       (use-package "yasnippet-snippets"
            :ensure t)

Org-mode customization

  (use-package "org-bullets"
       :ensure t
       (add-hook 'org-mode-hook 'org-bullets-mode))
  (local-unset-key (kbd"C-c C-q"))
  (set-face-font 'org-level-1 "IBM Plex Mono 16")
  (set-face-font 'org-level-2 "IBM Plex Mono 15")
  (set-face-font 'org-level-3 "IBM Plex Mono 14")
  (set-face-font 'org-level-4 "IBM Plex Mono 14")
  (set-face-font 'org-level-5 "IBM Plex Mono 14")
  (setq org-hide-emphasis-markers t)


It's like ace-whatever but for zapping characters. zap-to-char

  (use-package zzz-to-char
       :ensure t
       :bind("M-z" . 'zzz-up-to-char))


Better \*help\* buffer

  (use-package helpful
       :ensure t
       :bind ("C-h f". #'helpful-callable)
       :bind ("C-h v". #'helpful-variable)
       :bind ("C-h k". #'helpful-key))


Sidebar xdxd

  (use-package treemacs
       :ensure t
       :defer t
       (with-eval-after-load 'winum
            (define-key winum-keymap (kbd "M-0") #'treemacs-select-window))
            (setq treemacs-collapse-dirs                   (if treemacs-python-executable 3 0)
                 treemacs-deferred-git-apply-delay        0.5
                 treemacs-directory-name-transformer      #'identity
                 treemacs-display-in-side-window          t
                 treemacs-eldoc-display                   'simple
                 treemacs-file-event-delay                5000
                 treemacs-file-extension-regex            treemacs-last-period-regex-value
                 treemacs-file-follow-delay               0.2
                 treemacs-file-name-transformer           #'identity
                 treemacs-follow-after-init               t
                 treemacs-expand-after-init               t
                 treemacs-find-workspace-method           'find-for-file-or-pick-first
                 treemacs-git-command-pipe                ""
                 treemacs-goto-tag-strategy               'refetch-index
                 treemacs-indentation                     2
                 treemacs-indentation-string              " "
                 treemacs-is-never-other-window           nil
                 treemacs-max-git-entries                 5000
                 treemacs-missing-project-action          'ask
                 treemacs-move-forward-on-expand          nil
                 treemacs-no-png-images                   nil
                 treemacs-no-delete-other-windows         t
                 treemacs-project-follow-cleanup          nil
                 treemacs-persist-file                    (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
                 treemacs-position                        'left
                 treemacs-read-string-input               'from-child-frame
                 treemacs-recenter-distance               0.1
                 treemacs-recenter-after-file-follow      nil
                 treemacs-recenter-after-tag-follow       nil
                 treemacs-recenter-after-project-jump     'always
                 treemacs-recenter-after-project-expand   'on-distance
                 treemacs-litter-directories              '("/node_modules" "/.venv" "/.cask")
                 treemacs-show-cursor                     nil
                 treemacs-show-hidden-files               t
                 treemacs-silent-filewatch                nil
                 treemacs-silent-refresh                  nil
                 treemacs-sorting                         'alphabetic-asc
                 treemacs-select-when-already-in-treemacs 'move-back
                 treemacs-space-between-root-nodes        t
                 treemacs-tag-follow-cleanup              t
                 treemacs-tag-follow-delay                1.5
                 treemacs-text-scale                      nil
                 treemacs-user-mode-line-format           nil
                 treemacs-user-header-line-format         nil
                 treemacs-wide-toggle-width               70
                 treemacs-width                           25
                 treemacs-width-increment                 1
                 treemacs-width-is-initially-locked       t
                 treemacs-workspace-switch-cleanup        nil)

            ;; The default width and height of the icons is 22 pixels. If you are
            ;; using a Hi-DPI display, uncomment this to double the icon size.
            ;;(treemacs-resize-icons 44)

            (treemacs-follow-mode t)
            (treemacs-filewatch-mode t)
            (treemacs-fringe-indicator-mode 'always)

            (pcase (cons (not (null (executable-find "git")))
                        (not (null treemacs-python-executable)))
                 (`(t . t)
                      (treemacs-git-mode 'deferred))
                 (`(t . _)
                      (treemacs-git-mode 'simple)))

            (treemacs-hide-gitignored-files-mode nil))
       (:map global-map
            ("M-0"       . treemacs-select-window)
            ("C-x t 1"   . treemacs-delete-other-windows)
            ("C-x t t"   . treemacs)
            ("C-x t d"   . treemacs-select-directory)
            ("C-x t B"   . treemacs-bookmark)
            ("C-x t C-t" . treemacs-find-file)
            ("C-x t M-t" . treemacs-find-tag)))

  (use-package treemacs-projectile
       :after (treemacs projectile)
       :ensure t)

  (use-package treemacs-icons-dired
       :hook (dired-mode . treemacs-icons-dired-enable-once)
       :ensure t)

  (use-package treemacs-tab-bar ;;treemacs-tab-bar if you use tab-bar-mode
       :after (treemacs)
       :ensure t
       :config (treemacs-set-scope-type 'Tabs))


Projectile is a project manager which helps you with git and stuff.

  (use-package projectile
       :ensure t


Ack is a replacement for grep(1) written in Perl, it's fast and stuff. And has support for Perl regular expressions. Because it is written in Perl.

  (use-package "ack"
       :ensure t)


Useful for makefiles.

(use-package "whitespace-cleanup-mode"
	:ensure t
	:init(add-hook 'after-init-hook 'whitespace-cleanup-mode))



  (use-package nyan-mode
       :ensure t


  (use-package orderless
    :ensure t
    (completion-styles '(orderless basic))
    (completion-category-overrides '((file (styles basic partial-completion)))))


  (use-package web-mode
       :ensure t
       (define-key web-mode-map (kbd "C-c C-e") 'web-mode-element-close)
       (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
       (define-key web-mode-map (kbd "C-c C-o") 'web-mode-element-insert))


Better interactive selection minibuffer. Alternative to ido and helm. This also installs marginalia-mode. So you can have further information of the commands, files and stuff in the minibuffer.

  (use-package marginalia
       :ensure t)

  (use-package vertico

       :ensure t

       ;; Different scroll margin
       (setq vertico-scroll-margin 10)
       ;; Show more candidates
       (setq vertico-count 10)
       ;; Grow and shrink the Vertico minibuffer
       (setq vertico-resize nil)
       ;; Optionally enable cycling for `vertico-next' and `vertico-previous'.
       (setq vertico-cycle nil))
  ;; Persist history over Emacs restarts. Vertico sorts by history position.
  (use-package savehist

  ;; A few more useful configurations
  (use-package emacs
       :ensure t
       ;; Add prompt indicator to `completing-read-multiple'.
       ;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma.
       (defun crm-indicator (args)
            (cons (format "[CRM%s] %s"
                            "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
                       (car args))
                 (cdr args)))
       (advice-add #'completing-read-multiple :filter-args #'crm-indicator)

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

       ;; Emacs 28: Hide commands in M-x which do not work in the current mode.
       ;; Vertico commands are hidden in normal buffers.
       ;; (setq read-extended-command-predicate
       ;;       #'command-completion-default-include-p)

       ;; Enable recursive minibuffers
       (setq enable-recursive-minibuffers t))
  (advice-add #'vertico--format-candidate :around
       (lambda (orig cand prefix suffix index _start)
            (setq cand (funcall orig cand prefix suffix index _start))
                 (if (= vertico--index index)
                      (propertize "-> " 'face 'vertico-current)
                      "  ")
  (defun vertico-resize--minibuffer ()
       (add-hook 'window-size-change-functions
            (lambda (win)
                 (let ((height (window-height win)))
                      (when (/= (1- height) vertico-count)
                           (setq-local vertico-count (1- height))
            t t))

  (advice-add #'vertico--setup :before #'vertico-resize--minibuffer)


This thing add sane shortcuts for emacs

  (use-package "crux"
       :ensure t
       :bind("C-k" . 'crux-smart-kill-line)
       :bind("C-c o" . 'crux-open-with)
       :bind("C-c D" . 'crux-delete-buffer-and-file)
       :bind("C-x C-r" . 'crux-reopen-as-root)
       :bind("C-x C-d" . 'crux-duplicate-current-line-or-region)
       :bind("C-c u" . 'crux-view-url)
       :bind("C-c s" . 'crux-create-scratch-buffer))


The dashboard is a good index for your things. So it's useful to have it

Here is an useful function I wrote so you can go to the dashboard (Or create it in case you accidentally killed the buffer)

  (global-set-key (kbd "C-c C-d") 'sosa/goto-dashboard)
  (use-package dashboard
       :ensure t
       (setq dashboard-items '(
                                   (recents	. 7)
                                   (bookmarks . 7)
       (setq dashboard-startup-banner 'logo)
       (setq dashboard-banner-logo-title "Welcome to Editor MACroS")
       (setq dashboard-startup-banner "~/.emacs.d/img/banner.png")
       (setq dashboard-set-heading-icons t)
       (setq dashboard-set-file-icons t))


  (use-package "doom-modeline"
       :ensure t
       (setq doom-modeline-height 25)
       (setq doom-modeline-hud nil)
       (setq doom-modeline-icon t)
       (setq doom-modeline-major-mode-icon nil)
       (setq doom-modeline-time-icon nil)
       (setq doom-modeline-env-version t)
       (setq doom-modeline-env-python-executable "python")
       (setq doom-modeline-env-perl-executable "perl")