💾 Archived View for minasmazar.srht.site › mm.org captured on 2022-04-28 at 18:35:33. Gemini links have been rewritten to link to archived content

View Raw

More Information

➡️ Next capture (2022-07-16)

-=-=-=-=-=-=-

+title: MineMacros = my brand new Emacs configuration file

+date: <2022-02-07>

+author: MinasMazar

+email: minasmazar@gmail.com

+property: header-args :comments yes

+begin_example emacs-lisp :tangle ~/.emacs.d/init.el

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

(require 'package)

(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)

(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)

(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)

; For important compatibility libraries like cl-lib

(when (< emacs-major-version 24)

(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))

(package-initialize)

(require 'use-package)

(use-package org

:config

(org-babel-load-file "~/.emacs.d/mm.org"))

+end_example

+begin_example emacs-lisp :tangle ~/.emacs.d/init.el

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

(require 'package)

(package-initialize)

(defvar bootstrap-version)

(let ((bootstrap-file

(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))

(bootstrap-version 5))

(unless (file-exists-p bootstrap-file)

(with-current-buffer

(url-retrieve-synchronously

"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"

'silent 'inhibit-cookies)

(goto-char (point-max))

(eval-print-last-sexp)))

(load bootstrap-file nil 'nomessage))

(setq package-enable-at-startup nil)

;(straight-use-package 'use-package)

(use-package org

:config

(org-babel-load-file "~/.emacs.d/emacs.org"))

+end_src

+begin_src emacs-lisp

(defmacro mm/package! (package &rest args)

"Wrapper around use-package"

`(use-package ,package ,@args :ensure t))

+end_src

Define the =mm/call= function, which define a fast way to perform some logic and execute a default callback with it.

The callback is defined as =mm.callback=.

+begin_src emacs-lisp

(defvar mm.callback nil "Main callback")

(defun mm/call (fun &rest options)

(let* ((callback (or (plist-get options :callback) mm.callback))

(result fun))

(if callback

(apply callback (list result)))

result))

+end_src

+begin_src emacs-lisp

(defun mm/conf/open ()

"Open configuration file."

(interactive)

(find-file "~/.emacs.d/mm.org"))

+end_src

+begin_src emacs-lisp

(defun mm/home-page/open ()

"Open sort of a homepage."

(interactive)

(find-file "~/Dropbox/emacs-homepage.org"))

+end_src

+begin_src emacs-lisp

(defun mm/straight/get-repo (&optional package)

"Bridge function to straight: return the local repo directory of straight"

(interactive "sPackage: ")

(mm/call (if package

(straight--repos-dir package)

(straight--repos-dir))

:callback mm/find-file))

+end_src

+begin_src emacs-lisp

(defun mm/utils/insert-date ()

""

(interactive)

(mm/call (shell-command-to-string "date") :callback #'insert))

+end_src

+begin_src emacs-lisp

(defun mm/get-current-hour ()

"Returns current hour of the day"

(nth 2 (decode-time (current-time))))

+end_src

If you want to toggle modus themes according to the daylight, you

can define call this function..

+begin_src emacs-lisp

(defun mm/toggle-modus-theme-by-current-hour ()

(interactive)

(let ((hour (mm/get-current-hour)))

(if (and (> hour 8) (< hour 20))

(modus-themes-load-operandi)

(modus-themes-load-vivendi))))

+end_src

..or schedule it to be automatically called evert hour.

+begin_example emacs-lisp

(run-at-time t 3600 'mm/toggle-modus-theme-by-current-hour)

+end_example

+begin_src emacs-lisp

(defun mm/other-backward ()

(interactive)

(other-window -1))

+end_src

+begin_src emacs-lisp

(menu-bar-mode -1)

(tool-bar-mode -1)

(scroll-bar-mode -1)

+end_src

I don't want Emacs to generate backup files.

#+begin_src emacs-lisp

(setq backup-inhibited t

auto-save-default nil

make-backup-files nil

use-dialog-box nil

global-auto-revert-non-file-bufffers t)

#+end_src

To append path like ~usr/local/bin~ or ~~/.asdf/shims/~ to the ~PATH~.

+begin_example emacs-lisp

(push "/usr/local/bin" exec-path)

(push "~/.asdf/shims" exec-path)

(setenv "PATH" (string-join exec-path ":"))

+end_example

For this reason I use.. [[https://github.com/purcell/exec-path-from-shell][exec-path-from-shell]] package.

+begin_src emacs-lisp

(mm/package! exec-path-from-shell

:straight t

:config

(exec-path-from-shell-initialize))

+end_src

Here's an example on how you can customize windows placement.

+begin_example emacs-lisp

(add-to-list 'display-buffer-alist '("\\*\\(Buffer List\\)\\*"

(display-buffer-in-side-window)

(window-height . 0.25)

(side . left)

(slot . -1)

(window-parameters . (

(mode-line-format . (" " "%b"))))))

(add-to-list 'display-buffer-alist '("\\*Embark Collect\\*"

(display-buffer-in-side-window)

(window-height . 0.25)

(side . bottom)

(slot . -1)

(window-parameters . (

(mode-line-format . (" " "%b"))))))

(add-to-list 'display-buffer-alist '("\\*Help\\*"

(display-buffer-in-side-window)

(window-height . 0.25)

(side . right)

(slot . -1)

(window-parameters . (

(mode-line-format . (" " "%b"))))))

+end_example

+begin_src emacs-lisp

(global-set-key (kbd "C-x C-f") 'find-file-at-point)

+end_src

Define a custom keymap for handling some useful shortcuts.

+begin_src emacs-lisp

(global-set-key (kbd "C-x 9 e") 'eshell)

(global-set-key (kbd "C-x 9 w g") 'elpher)

(global-set-key (kbd "C-x 9 w w") 'eww)

+end_src

Here I bind the kraken keymap to the super keybinding =s-o=.

+begin_src emacs-lisp

(define-key key-translation-map (kbd "s-o") (kbd "C-x 9"))

+end_src

Wants to take advantage of the meta key (i.e. ~CMD~ on MacOS, or ~Win~ on Windows) to set some useful shortcuts:

+begin_src emacs-lisp

(global-set-key (kbd "<S-s-return>") 'point-to-register)

(global-set-key (kbd "<s-return>") 'jump-to-register)

(global-set-key (kbd "s-h") 'mm/home-page/open)

(global-set-key (kbd "s-H") 'mm/conf/open)

(global-set-key (kbd "s-K") 'switch-to-buffer)

(global-set-key (kbd "s-N") 'dired-jump)

(global-set-key (kbd "s-i") 'imenu)

(global-set-key (kbd "s--") 'bookmark-jump)

(global-set-key (kbd "s-b") 'ibuffer)

(global-set-key (kbd "s-F") 'occur)

(global-set-key (kbd "s-r") 'query-replace)

(global-set-key (kbd "s-e") 'dabbrev-expand)

(global-set-key (kbd "s-1") 'delete-other-windows)

(global-set-key (kbd "s-3") 'split-window-horizontally)

(global-set-key (kbd "s-2") 'split-window-vertically)

(global-set-key (kbd "s-0") 'delete-window)

(global-set-key (kbd "s-w") 'other-window)

(global-set-key (kbd "s-W") 'maximize-window)

(global-set-key (kbd "s-R") 'query-replace-regexp)

(global-set-key (kbd "s-p") 'project-switch-to-buffer)

(global-set-key (kbd "s-P") 'project-find-file)

(global-set-key (kbd "s-t") 'rgrep)

(global-set-key (kbd "s-[") 'previous-buffer)

(global-set-key (kbd "s-]") 'next-buffer)

(global-set-key (kbd "s-)") 'kill-this-buffer)

(global-set-key (kbd "s-\\") 'other-frame)

(global-set-key (kbd "s-=") 'balance-windows)

(global-set-key (kbd "s-<backspace>") 'window-toggle-side-windows)

+end_src

Override ~isearch-mode-map~

+begin_src emacs-lisp

(define-key isearch-mode-map (kbd "C-p") 'isearch-repeat-backward)

(define-key isearch-mode-map (kbd "C-n") 'isearch-repeat-forward)

(define-key isearch-mode-map (kbd "<tab>") 'isearch-repeat-forward)

(define-key isearch-mode-map (kbd "<S-tab>") 'isearch-repeat-backward)

+end_src

Add shortcut in translation map which basically are fast access to ~C-x~ and ~C-c~.

+begin_src emacs-lisp

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

+end_src

For some reason you can't use the ~alt~ key on your keyboard? (It happens to me with Iterm + ssh + emacsclient session) and for some reason you don't want to solve this issue configuring Iterm or else? In this case you use this workaround, remapping some core keybinding like ~C-k~ and ~C-l~.

+begin_example emacs-lisp

(global-set-key (kbd "C-k") 'execute-extended-command)

(global-set-key (kbd "C-K") 'kill-visual-line)

(global-set-key (kbd "C-l") 'god-local-mode)

(global-set-key (kbd "C-L") 'recenter-top-bottom)

+end_example

+begin_src emacs-lisp

(setq indent-tabs-mode nil)

+end_src

A basic auto-completion package.

+begin_src emacs-lisp

(mm/package! company

:config

(global-company-mode))

+end_src

+begin_src emacs-lisp

(show-paren-mode t)

+end_src

+begin_src emacs-lisp

(mm/package! rainbow-mode)

+end_src

+begin_src emacs-lisp

(mm/package! mct

:config

(mct-mode 1)

:custom

(mct-completion-passlist '(imenu)))

+end_src

+begin_src emacs-lisp

(mm/package! embark

:bind*

("C-," . embark-act)

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

+end_src

+begin_quote

NOTE: Emacs 25.1 is required for this package to work well.

This is a global minor mode for entering Emacs commands without modifier keys. It's similar to Vim's separation of command mode and insert mode.

All existing key bindings will work in God mode. It's only there to reduce your usage of modifier keys.

+end_quote

[[https://github.com/emacsorphanage/god-mode][God-mode]] aims to ease keychord immision. You can easily switch it on/off via ~s-n~ shortcut. I use took inspiration from [[https://www.vim.org][vim]], so when in god-mode you can just hit ~i~ (to deactivate god-mode, something resembling the activation of /insert/ mode in vim) or ~u~ for /undo.

+begin_src emacs-lisp

(mm/package! god-mode

:config

(god-mode)

(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") 'keyboard-quit)

(define-key god-local-mode-map (kbd ".") 'repeat)

(define-key god-local-mode-map (kbd ">") 'end-of-buffer)

(define-key god-local-mode-map (kbd "<") 'beginning-of-buffer)

(defun mm/god-mode-enabled ()

(setq mm/god-mode-status 1)

(setq cursor-type 'box))

(defun mm/god-mode-disabled ()

(setq mm/god-mode-status nil)

(setq cursor-type 'bar))

(add-hook 'god-mode-enabled-hook 'mm/god-mode-enabled)

(add-hook 'god-mode-disabled-hook 'mm/god-mode-disabled)

(defun mm/mode-line-god-mode-indicator ()

(if mm/god-mode-status " *G* " "i "))

(add-to-list 'mode-line-format '(:eval (mm/mode-line-god-mode-indicator))))

+end_src

Avoid to have god-mode active on certain major modes.

+begin_example emacs-lisp

(setq god-exempt-major-modes (append god-exempt-major-modes '(

elfeed-search-mode

elfeed-show-mode

erc-mode

vterm-mode

)))

+end_example

+begin_src emacs-lisp

(mm/package! savehist

:init

(savehist-mode))

+end_src

+begin_src emacs-lisp

(mm/package! orderless

:custom

(completion-styles '(

orderless

;substring

;initials

;flex

partial-completion

)))

+end_src

+begin_src emacs-lisp

(setq dired-dwim-target t)

(add-hook 'dired-mode-hook 'dired-hide-details-mode)

+end_src

Main customizations for programming in ~elisp~.

+begin_src emacs-lisp :tangle no

(define-key emacs-lisp-mode-map (kbd "s-j") 'eval-print-last-sexp)

+end_src

+begin_src emacs-lisp

(setq browse-url-handlers '(("." . eww-browse-url)))

+end_src

+begin_src emacs-lisp

(use-package elpher)

+end_src

Configuring GNUS.

+begin_src emacs-lisp

(add-hook 'gnus-mode-hook 'gnus-topic-mode)

+end_src

From https://www.emacswiki.org/emacs/GnusGmail

+begin_example emacs-lisp

(setq user-mail-address "<EMAIL_ADDRESS>"

user-full-name "<FULL NAME>"

mml-secure-openpgp-signers '("YOUR KEY ID"))

(setq gnus-select-method

'(nnimap "gmail"

(nnimap-address "imap.example.com") ; it could also be imap.googlemail.com if that's your server.

(nnimap-server-port "imaps")

(nnimap-stream ssl)))

(setq message-send-mail-function 'smtpmail-send-it

smtpmail-smtp-server "smtp.example.com"

smtpmail-smtp-service 465

smtpmail-stream-type 'starttls

gnus-ignored-newsgroups "^to\\.\\|^[0-9. ]+\\( \\|$\\)\\|^[\"]\"[#'()]")

+end_example

From https://www.emacswiki.org/emacs/DefaultEncrypt

+begin_quote

Gnus supports GnuPG via the insertion of so-called MML secure tags,

which contain encryption instructions to be performed before a message

is sent.

+end_quote

+begin_src emacs-lisp

(add-hook 'message-setup-hook 'mml-secure-message-sign-pgpmime)

+end_src

+begin_src emacs-lisp

(mm/package! magit)

(mm/package! bongo)

(mm/package! restclient)

+end_src

This setting enables Emacs to ask pinentry via minibuffer.

+begin_src emacs-lisp

(setq epa-pinentry-mode 'loopback)

+end_src

Define macro to load modules.

+begin_src emacs-lisp

(defmacro mm/modules/load (module)

"Load module."

`(let ((module-file (format "~/.emacs.d/modules/%s.el" ,module)))

(message module-file)

(load module-file 'noerrors)))

+end_src

Define some external modules.

+begin_src emacs-lisp

(setq mm/modules '(

ide/ruby

ide/elixir

))

+end_src

Load external modules if present.

+begin_src emacs-lisp

(dolist (module mm/modules)

(mm/modules/load module))

+end_src

Set and load custom file.

+begin_src emacs-lisp

(setq custom-file "~/.emacs.d/custom.el")

(load custom-file 'noerrors 'nomessage)

+end_src

For each buffer you can define some custom variables, like the preferred major mode.

In this example you can disable =olivetti-mode= by simply adding this

comment at the beginning of the file.

+begin_example emacs-lisp

-*- olivetti-mode: nil; -*-

+end_example

You can also use the command =add-file-local-variable-prop-line=.

You can set variables for a particular project (directory) this way (for more information see "(emacs) Directory Variables").

+begin_example emacs-lisp

;;; Directory Local Variables

((sql-mode . ((sql-postgres-login-params . '((user :default "my_project_dir")

(database :default "my_project_dir_development")

(server :default "localhost")

+end_example

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.

+begin_quote

. 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

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

+end_quote

Get an element from a vector

+BEGIN_EXAMPLE emacs-lisp

;; get a element from vector

(aref ["a" "b" "c"] 0) ; ⇒ "a"

;; get a element from vector

(elt ["a" "b" "c"] 0) ; ⇒ "a"

+END_EXAMPLE

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.

You can run specified function at specified time and with a specific timeout! Check out [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Timers.html][the doc]] for more information.

+BEGIN_QUOTE

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.

+END_QUOTE

- =proced= (get UNIX processes list)

- =add-file-local-variable-prop-line=

- =org-startup-folded=

- =run-at-time= / =list-timers=

- =kmacro-to-register=

- =completion-at-point= (C-M-i or M-TAB)

- =initial-buffer-choice=

- =comint-scroll-to-bottom-on-output=

I would like to thanks:

- [[http://kelvinh.github.io/][Kelvin Hu]] for his [[https://github.com/kelvinh/.emacs.d][emacs configuration]] and the idea to write it in a *literate style*.

- [[http://www.howardism.org/][Howard Abrams]] for his [[https://github.com/howardabrams/dot-files][dotfiles]].

- [[https://github.com/aaronbieber][Aaron Bieber]] for his dotfiles and for the wonderful speech [[https://www.youtube.com/watch?v%3DJWD1Fpdd4Pc][Evil Mode: Or, How I Learned to Stop Worrying and Love Emacs]] that makes me *fall in love* with Emacs. ;-)

- [[https://protesilaos.com/][Protesilaos Stavrou]] for his [[https://protesilaos.com/dotemacs/][comprehensive "dotemacs" (.emacs) for GNU/Linux]] and [[https://protesilaos.com/codelog/][the huge amount of posts and videos about Emacs]].

- [[https://github.com/sponsors/daviwil][David Wilson]] for his fantastic [[https://www.youtube.com/channel/UCAiiOTio8Yu69c3XnR7nQBQ][System Crafters screencasts]]!

- [[http://staff.science.uva.nl/~dominik/][Carsten Dominik]], creator of the mighty [[http://orgmode.org][org-mode]]. <<org-mode>>

- [[http://ehneilsen.net][Eric H. Neilsen, Jr.]] for his wonderful [[http://ehneilsen.net/notebook/orgExamples/org-examples.html][org-mode examples and cookbook]].

- [[https://www.gnu.org/software/emacs/][The Emacs editor]] and his *guru* [[https://stallman.org/][Richard Stallman]].

- [[https://www.gnu.org/software/emacs/manual/pdf/emacs-lisp.pdf][The Elisp documentation]]