(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"))
(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"))
(defmacro mm/package! (package &rest args)
"Wrapper around use-package"
`(use-package ,package ,@args :ensure t))
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=.
(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))
(defun mm/conf/open ()
"Open configuration file."
(interactive)
(find-file "~/.emacs.d/mm.org"))
(defun mm/home-page/open ()
"Open sort of a homepage."
(interactive)
(find-file "~/Dropbox/emacs-homepage.org"))
(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))
(defun mm/utils/insert-date ()
""
(interactive)
(mm/call (shell-command-to-string "date") :callback #'insert))
(defun mm/get-current-hour ()
"Returns current hour of the day"
(nth 2 (decode-time (current-time))))
If you want to toggle modus themes according to the daylight, you
can define call this function..
(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))))
..or schedule it to be automatically called evert hour.
(run-at-time t 3600 'mm/toggle-modus-theme-by-current-hour)
(defun mm/other-backward ()
(interactive)
(other-window -1))
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
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~.
(push "/usr/local/bin" exec-path)
(push "~/.asdf/shims" exec-path)
(setenv "PATH" (string-join exec-path ":"))
For this reason I use.. [[https://github.com/purcell/exec-path-from-shell][exec-path-from-shell]] package.
(mm/package! exec-path-from-shell
:straight t
:config
(exec-path-from-shell-initialize))
Here's an example on how you can customize windows placement.
(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"))))))
(global-set-key (kbd "C-x C-f") 'find-file-at-point)
Define a custom keymap for handling some useful shortcuts.
(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)
Here I bind the kraken keymap to the super keybinding =s-o=.
(define-key key-translation-map (kbd "s-o") (kbd "C-x 9"))
Wants to take advantage of the meta key (i.e. ~CMD~ on MacOS, or ~Win~ on Windows) to set some useful shortcuts:
(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)
Override ~isearch-mode-map~
(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)
Add shortcut in translation map which basically are fast access to ~C-x~ and ~C-c~.
(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"))
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~.
(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)
(setq indent-tabs-mode nil)
A basic auto-completion package.
(mm/package! company
:config
(global-company-mode))
(show-paren-mode t)
(mm/package! rainbow-mode)
(mm/package! mct
:config
(mct-mode 1)
:custom
(mct-completion-passlist '(imenu)))
(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)))
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.
[[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.
(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))))
Avoid to have god-mode active on certain major modes.
(setq god-exempt-major-modes (append god-exempt-major-modes '(
elfeed-search-mode
elfeed-show-mode
erc-mode
vterm-mode
)))
(mm/package! savehist
:init
(savehist-mode))
(mm/package! orderless
:custom
(completion-styles '(
orderless
;substring
;initials
;flex
partial-completion
)))
(setq dired-dwim-target t)
(add-hook 'dired-mode-hook 'dired-hide-details-mode)
Main customizations for programming in ~elisp~.
(define-key emacs-lisp-mode-map (kbd "s-j") 'eval-print-last-sexp)
(setq browse-url-handlers '(("." . eww-browse-url)))
(use-package elpher)
Configuring GNUS.
(add-hook 'gnus-mode-hook 'gnus-topic-mode)
From https://www.emacswiki.org/emacs/GnusGmail
(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. ]+\\( \\|$\\)\\|^[\"]\"[#'()]")
From https://www.emacswiki.org/emacs/DefaultEncrypt
Gnus supports GnuPG via the insertion of so-called MML secure tags,
which contain encryption instructions to be performed before a message
is sent.
(add-hook 'message-setup-hook 'mml-secure-message-sign-pgpmime)
(mm/package! magit)
(mm/package! bongo)
(mm/package! restclient)
This setting enables Emacs to ask pinentry via minibuffer.
(setq epa-pinentry-mode 'loopback)
Define macro to load modules.
(defmacro mm/modules/load (module)
"Load module."
`(let ((module-file (format "~/.emacs.d/modules/%s.el" ,module)))
(message module-file)
(load module-file 'noerrors)))
Define some external modules.
(setq mm/modules '(
ide/ruby
ide/elixir
))
Load external modules if present.
(dolist (module mm/modules)
(mm/modules/load module))
Set and load custom file.
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file 'noerrors 'nomessage)
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.
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").
;;; Directory Local Variables
((sql-mode . ((sql-postgres-login-params . '((user :default "my_project_dir")
(database :default "my_project_dir_development")
(server :default "localhost")
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
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
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.
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.
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.
- =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]]