UP | HOME

Holymacs

Table of Contents

Specs

When adding a set feature, try to add some fast keybindings to access them (the super key is often a good choice).

Package Manager

(add-to-list 'load-path "~/.emacs.d/manual-packages/")
(require 'package)

(setq package-archives '(("melpa" . "https://melpa.org/packages/")
                         ("elpa" . "https://elpa.gnu.org/packages/")
                         ("nongnu" . "https://elpa.nongnu.org/nongnu/")))

(require 'use-package)
(require 'use-package-ensure)
(setq use-package-always-ensure t
      package-enable-at-startup t)
(package-initialize)

Main configuration

Remember to set your name and email address! Place here your real data, or use the standard Emacs customization (customize-variable 'user-full-name).

(setq user-full-name "Your username"
      user-mail-address "username@domain.net")
(setq tab-always-indent 'complete
      enable-recursive-minibuffers t
      make-backup-files nil)
(ffap-bindings)
(savehist-mode 1)
(recentf-mode 1)

Bookmarks

eww-bookmark-jump

Here add a custom bookmark handler relying on browse-url and browse-url-handlers, so even if we store a bookmark via eww, we're going to use the proper browser when opening it.

(defun browse-url-bookmark-jump (bookmark)
  "Bookmark jump handler: relies on =browse-url-handler= to pick the right browser.
  Define a custom jumper avoid to open always on EWW in case the bookmark was placed with it"
  (browse-url (bookmark-prop-get bookmark 'location)))

Dired

(require 'dired)
(setq make-backup-files nil
      tab-always-indent 'complete
      dired-dwim-target t
      dired-listing-switches "-alth"
      dired-omit-files "\\`[.]?#\\|\\`[.][.]?")
(define-key dired-mode-map (kbd "W") #'wdired-change-to-wdired-mode)
(define-key dired-mode-map (kbd "H") #'dired-omit-mode)
(define-key dired-mode-map (kbd "M-p") (lambda () (interactive) (dired-previous-line 1) (dired-display-file)))
(define-key dired-mode-map (kbd "M-n") (lambda () (interactive) (dired-next-line 1) (dired-display-file)))
(add-hook 'dired-mode-hook #'dired-hide-details-mode)
(add-hook 'dired-mode-hook #'dired-omit-mode)

Appearance

(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(setq ring-bell-function 'ignore
      visible-bell t)

Orderless

(use-package orderless
  :custom
  (completion-styles '(orderless partial-completion)))

Vertico

(use-package vertico
  :init
  (vertico-mode t)
  (setq vertico-count 20
        vertico-resize t
        vertico-cycle t))

Company

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

Embark

(use-package embark
  :config
  (add-to-list 'god-exempt-major-modes 'embark-mode)
  :bind*
  ("C-," . embark-act)
  (:map embark-general-map
        ("C-w" . browse-url))
  (:map embark-identifier-map
        ("R" . query-replace)
        ("O" . multi-occur-in-matching-buffers)
        ("c" . browse-url-chrome)
        ("f" . browse-url-firefox))
  (:map embark-url-map
        ("c" . browse-url-chrome)
        ("f" . browse-url-firefox))
  (:map  embark-file-map
         ("p" . project-find-file)
         ("b" . project-switch-to-buffer)
         ("," . append-to-previous-buffer)))

Keybindings

Custom keybindings

In vanilla Emacs the M-o keybinding is free: I'll use it as sort of an entrypoint for commands I often use, as for org commands. I'll use M-o M-o to map major-mode related commands.

(global-set-key (kbd "M-o a") #'org-agenda)
(global-set-key (kbd "M-o k") #'org-agenda-capture)
(global-set-key (kbd "M-o e") #'emoji-search)
(define-key dired-mode-map (kbd "M-o M-o h") #'dired-omit-mode)

Translations keys

(define-key key-translation-map (kbd "s-k") (kbd "M-x"))
(define-key key-translation-map (kbd "s-m") (kbd "C-x"))
(define-key key-translation-map (kbd "s-M") (kbd "C-c"))
(define-key key-translation-map (kbd "s-o") (kbd "M-o"))
(define-key key-translation-map (kbd "s-O") (kbd "M-o M-o"))

Super-key

(global-set-key (kbd "s-0") (kbd "C-x 0"))
(global-set-key (kbd "s-1") (kbd "C-x 1"))
(global-set-key (kbd "s-2") (kbd "C-x 2"))
(global-set-key (kbd "s-3") (kbd "C-x 3"))
(global-set-key (kbd "s-w") (kbd "C-x o"))
(global-set-key (kbd "s-r") (kbd "C-x z"))
(global-set-key (kbd "s-i") (kbd "C-M-i"))
(global-set-key (kbd "s-N") (kbd "C-x C-j"))
(global-set-key (kbd "s-[") (kbd "C-x <left>"))
(global-set-key (kbd "s-]") (kbd "C-x <right>"))
(global-set-key (kbd "s-,") #'switch-to-completions)
(global-set-key (kbd "s-b") #'switch-to-buffer)
(global-set-key (kbd "s-B") #'ibuffer)
(global-set-key (kbd "s-)") #'kill-this-buffer)
(global-set-key (kbd "s--") #'bookmark-jump)
(global-set-key (kbd "s-_") #'bookmark-set)
(global-set-key (kbd "s-q") #'tab-next)
(global-set-key (kbd "s-t") #'find-name-dired)
(global-set-key (kbd "s-r") #'repeat)
(global-set-key (kbd "s-p") #'project-switch-to-buffer)
(global-set-key (kbd "s-P") #'project-find-file)

god-mode

(use-package god-mode
  :init
  (defun minemacs-god-mode-enabled ()
    (setq cursor-type 'box))
  (defun minemacs-god-mode-disabled ()
    (setq cursor-type 'bar))
  :config
  (add-hook 'god-mode-enabled-hook 'minemacs-god-mode-enabled)
  (add-hook 'god-mode-disabled-hook 'minemacs-god-mode-disabled)
  (global-set-key (kbd "s-n") #'god-local-mode)
  (define-key god-local-mode-map (kbd "i") #'god-local-mode)
  (define-key god-local-mode-map (kbd "u") #'undo)
  (define-key god-local-mode-map (kbd "U") #'undo-redo)
  (define-key god-local-mode-map (kbd ">") #'end-of-buffer)
  (define-key god-local-mode-map (kbd "<") #'beginning-of-buffer)
  (define-key god-local-mode-map (kbd "[") #'backward-paragraph)
  (define-key god-local-mode-map (kbd "]") #'forward-paragraph)
  (define-key god-local-mode-map (kbd "{") #'backward-sexp)
  (define-key god-local-mode-map (kbd "}") #'forward-sexp)
  (add-to-list 'god-exempt-major-modes 'compilation-mode)
  (add-to-list 'god-exempt-major-modes 'org-capture-mode)
  (add-to-list 'god-exempt-major-modes 'org-agenda-mode)
  (add-to-list 'god-exempt-major-modes 'elfeed-search-mode)
  (add-to-list 'god-exempt-major-modes 'elfeed-show-mode)
  (god-mode))

which-key

(use-package which-key
  :config
  (which-key-mode))

Shared configurations

Here's I share my most used configuration files across systems by simply usiung a shared directory.

(if (file-exists-p "~/Dropbox/emacs/")
    (setq bookmark-file "~/Dropbox/emacs/bookmarks"
          eshell-aliases-file "~/Dropbox/emacs/eshell-aliases"
          custom-file "~/Dropbox/emacs/custom.el"
          org-agenda-files '("~/Dropbox/org/")
          org-roam-directory "~/Dropbox/org-roam/"))
(load custom-file 'noerror)

Modules

Autoload

Here we define a mechanism to easily extend your Emacs experience with some custom defined modules, a set of packages and configuration that can be grouped for any reason (they're the equivalent of the layers in Doom Emacs), but I'm not creating a whole mechanism to handle this: just place an .el file in the ~/.emacs.d/modules/ directory, and it will be autoloaded.

(let* ((modules-dir (concat user-emacs-directory "modules/"))
       (modules (if (file-exists-p modules-dir)
                    (directory-files modules-dir))))
  (if modules (mapcar (lambda (module)
                        (load (concat modules-dir module) 'noerror))
                      modules)))

Here's the list of modules I'm using. They consists in .org files tangling to specific .el file in the modules directory (~/.emacs.d/modules/).

Blorg

The Blorg publishing functions described in README.org will tangle its code in the blorg.el module.

TODO Hail Hydra

On hand documentation

Regular Expression Syntax (regexp)

You can use the wonderful tool regexp-builder.

Here is the syntax used by Emacs for regular expressions. Any character matches itself, except for the list below.

The following characters are special : . * + ? ^ $ \ [

Between brackets [], the following are special : ] - ^

Many characters are special when they follow a backslash – see below.

. any character (but newline)

  • previous character or group, repeated 0 or more time
  • previous character or group, repeated 1 or more time

? previous character or group, repeated 0 or 1 time ^ start of line $ end of line […] any character between brackets [^..] any character not in the brackets [a-z] any character between a and z \ prevents interpretation of following special char \| or \w word constituent \b word boundary \sc character with c syntax (e.g. \s- for whitespace char) \( \) start\end of group \< \> start\end of word \_< \_> start\end of symbol \` \' start\end of buffer\string \1 string matched by the first group \n string matched by the nth group \{3\} previous character or group, repeated 3 times \{3,\} previous character or group, repeated 3 or more times \{3,6\} previous character or group, repeated 3 to 6 times \= match succeeds if it is located at point *?, +?, and ?? are non-greedy versions of *, +, and ? – see NonGreedyRegexp. Also, \W, \B, and \Sc match any character that does not match \w, \b, and \sc.

Characters are organized by category. Use C-u C-x = to display the category of the character under the cursor.

\ca ascii character \Ca non-ascii character (newline included) \cl latin character \cg greek character Here are some syntax classes that can be used between brackets, e.g. [[:upper:]\|[:digit:]\.].

[:digit:] a digit, same as [0-9] [:alpha:] a letter (an alphabetic character) [:alnum:] a letter or adigit (an alphanumeric character () [:upper:] a letter in uppercase [:space:] a whitespace character, as defined by the syntax table [:xdigit:] an hexadecimal digit [:cntrl:] a control character [:ascii:] an ascii character Syntax classes:

\s- whitespace character \s/ character quote character \sw word constituent \s$ paired delimiter \s_ symbol constituent \s' expression prefix \s. punctuation character \s< comment starter \s( open delimiter character \s> comment ender \s) close delimiter character \s! generic comment delimiter \s" string quote character \s| generic string delimiter \s\ escape character

Vectors

Get an element from a vector

;; get a element from vector
(aref ["a" "b" "c"] 0) ; ⇒ "a"
;; get a element from vector
(elt ["a" "b" "c"] 0) ; ⇒ "a"

What's the difference between aref and elt? elt is more general. It works on vector and list. But if you know it's vector, you should use aref, because it's precise and faster.

Timers

You can run specified function at specified time and with a specific timeout! Check out the doc for more information.

The list-timers command lists all the currently active timers. There’s only one command available in the buffer displayed: c (timer-list-cancel) that will cancel the timer on the line under point.

(interactive) functions

Refs to this SO post try (completing-read "Prompt: " '(i1 i2 i3)) and this post; try (read-from-minibuffer "Prompt: " "initial"). Take a look at minemacs/demo-function, it can help if you want to write functions with bit more complex interactive prompts.

(defun minemacs/demo-function (url &optional handler)
  "Example function."
  (interactive (list
		(read-from-minibuffer "URL: ")
		(completing-read "handler: " '(browse-url-firefox browse-url-chrome))))
   (message (format "url: %s, handler: %s" url handler )))

Buffer management

Code stolen from stackoverflow.

(defun minemacs-clear-buffer ()
  "clear whole buffer add contents to the kill ring"
  (interactive)
  (kill-region (point-min) (point-max)))

(defun minemacs-clear-buffer-permenantly ()
  "clear whole buffer, contents is not added to the kill ring"
  (interactive)
  (delete-region (point-min) (point-max)))

Commands, functions and variables

Just press C-h o to get help on those symbols.

  • align-regexp
  • add-file-local-variable (append at bottom of the file) and add-file-local-variable-prop-line (prepend in the first line)
  • browse-url-of-buffer
  • completions-max-height
  • find-name-dired
  • json-pretty-print-buffer
  • org-archive-subtree-default
  • org-babel-load-file
  • org-agenda-include-diary
  • pp-eval-expression
  • proced
  • shr-inhibit-images

Libaries

Useful topics

Credits

I would like to thanks:

Date: 2023-07-15 Sat 00:00

Emacs 29.2 (Org mode 9.6.15)

Validate