2020-10-07 19:41:29 +00:00
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
2022-06-27 09:55:43 +00:00
( defun load-theme-string ( theme )
( if ( -contains? ( custom-available-themes ) ( intern theme ) ) ( load-theme ( intern theme ) ) ) )
( defun toggle-theme ( &optional suffix )
" Heuristically toggle between light and dark themes. "
( interactive )
( let* ( ( theme ( s-replace-all ' ( ( " light " . " dark " ) ( " dark " . " light " )
( " black " . " white " ) ( " white " . " black " )
( " day " . " night " ) ( " night " . " day " ) )
( symbol-name doom-theme ) ) )
( theme-base ( s-replace-regexp " -[^-]*$ " " " theme ) ) )
( or ( if suffix ( or ( load-theme-string ( concat theme " - " suffix ) ) ( load-theme-string ( concat theme-base " - " suffix ) ) ) ) ( load-theme-string ( if ( and ( not suffix ) ( equal theme ( symbol-name doom-theme ) ) ) ( concat theme " -light " ) theme ) ) ( load-theme-string theme-base ) )
)
)
2022-06-22 16:29:30 +00:00
2021-06-03 10:16:09 +00:00
( setq display-line-numbers-type 'relative
2022-02-11 07:57:32 +00:00
scroll-margin 6
2021-06-03 10:16:09 +00:00
hscroll-margin 20
)
2021-03-26 18:02:37 +00:00
;;;; BINDINGS
2022-08-21 09:55:09 +00:00
( defun xah/open-in-external-app ( &optional @fname )
2021-05-07 10:32:04 +00:00
" Open the current file or dired marked files in external app.
When called in emacs lisp, if @fname is given, open that.
URL ` http://ergoemacs.org/emacs/emacs_dired_open_file_in_ext_apps.html '
Version 2019-11-04 2021-02-16 "
( interactive )
( let* (
( $file-list
( if @fname
( progn ( list @fname ) )
( if ( string-equal major-mode " dired-mode " )
( dired-get-marked-files )
( list ( buffer-file-name ) ) ) ) )
( $do-it-p ( if ( <= ( length $file-list ) 5 )
t
( y-or-n-p " Open more than 5 files? " ) ) ) )
( when $do-it-p
( cond
( ( string-equal system-type " windows-nt " )
( mapc
( lambda ( $fpath )
( shell-command ( concat " PowerShell -Command \" Invoke-Item -LiteralPath \" " " ' " ( shell-quote-argument ( expand-file-name $fpath ) ) " ' " ) ) )
$file-list ) )
( ( string-equal system-type " darwin " )
( mapc
( lambda ( $fpath )
( shell-command
( concat " open " ( shell-quote-argument $fpath ) ) ) ) $file-list ) )
( ( string-equal system-type " gnu/linux " )
( mapc
( lambda ( $fpath ) ( let ( ( process-connection-type nil ) )
( start-process " " nil " xdg-open " $fpath ) ) ) $file-list ) ) ) ) ) )
2021-07-03 18:59:33 +00:00
2022-11-06 21:39:45 +00:00
( defun xf/dragon ( )
2022-01-10 20:39:57 +00:00
" Share file from current buffer via dragon. "
2021-07-03 18:59:33 +00:00
( interactive )
2022-11-06 21:49:43 +00:00
( apply 'start-process
` ( " dragon " nil
" dragon-drop " " -a " " -x "
,@ ( dired-get-marked-files )
2022-11-09 17:51:00 +00:00
,@ ( unless ( dired-get-marked-files )
( list ( or ( buffer-file-name )
2022-11-06 21:49:43 +00:00
( image-dired-original-file-name )
2022-11-09 17:51:00 +00:00
default-directory ) )
) )
)
2021-07-03 18:59:33 +00:00
)
2022-08-21 09:55:09 +00:00
( defun xf/org-journal-current ( )
( interactive )
( org-journal-open-current-journal-file )
2023-05-09 12:03:21 +00:00
;(goto-char (point-max))
2022-08-21 09:55:09 +00:00
)
2021-07-03 18:59:33 +00:00
;; rebing C-u - https://emacs.stackexchange.com/a/58320
( global-set-key ( kbd " C-# " ) 'universal-argument )
( define-key universal-argument-map ( kbd " C-# " ) 'universal-argument-more )
( global-set-key ( kbd " C-* " ) 'universal-argument )
( define-key universal-argument-map ( kbd " C-* " ) 'universal-argument-more )
2022-09-22 07:57:37 +00:00
; TODO map C-c C-c to save and quit if unmapped
2022-08-21 09:55:09 +00:00
;; https://emacs.stackexchange.com/questions/21335/prevent-folding-org-files-opened-by-ediff
( with-eval-after-load 'outline
( add-hook 'ediff-prepare-buffer-hook 'outline-show-all ) )
2023-03-13 14:34:44 +00:00
2022-09-09 19:58:38 +00:00
( map! :n
2022-08-29 22:06:26 +00:00
;; Buffer-local font resizing
2021-07-04 16:20:36 +00:00
" M-C-+ " 'text-scale-increase
2021-05-07 10:32:04 +00:00
" M-C-- " 'text-scale-decrease
2021-03-30 16:15:44 +00:00
;; Frame-local font resizing
2021-07-04 16:20:36 +00:00
" C-= " 'doom/reset-font-size
" C-+ " 'doom/increase-font-size
2021-05-07 10:32:04 +00:00
" C-- " 'doom/decrease-font-size
2022-09-22 07:57:37 +00:00
" C-u " 'evil-scroll-up
2021-10-15 12:28:52 +00:00
:leader
2023-11-04 18:04:03 +00:00
" l " 'link-hint-open-link-at-point
2021-12-02 22:27:35 +00:00
" u " 'evil-prev-buffer
" i " 'evil-next-buffer
2022-09-16 12:33:17 +00:00
" q " 'doom/save-and-kill-buffer
2021-12-02 22:27:35 +00:00
" bq " 'doom/save-and-kill-buffer
2022-08-21 09:55:09 +00:00
" # " 'xah/open-in-external-app
" - " 'evil-quick-diff
" _ " 'ediff
2022-09-22 07:57:37 +00:00
" wO " 'delete-other-windows
2022-08-21 09:55:09 +00:00
" os " 'eshell
" oj " 'xf/org-journal-current
" njo " 'xf/org-journal-current
" nrb " ( lambda ( ) ( interactive ) ( setq +org-roam-auto-backlinks-buffer ( not +org-roam-auto-backlinks-buffer ) ) ( org-roam-buffer-toggle ) )
2022-12-07 17:40:50 +00:00
" sa " 'projectile-find-file-in-known-projects
2021-10-15 12:28:52 +00:00
" Se " '+snippets/edit
2022-02-11 07:57:32 +00:00
" SN " '+snippets/new
2021-10-15 12:28:52 +00:00
" Sm " 'smerge-mode
2022-01-15 21:04:04 +00:00
" m; " 'comment-line
2022-09-16 12:33:17 +00:00
" Q " 'save-buffers-kill-terminal ; or evil-quit-all?
2022-08-21 09:55:09 +00:00
:desc " Dragon current buffer " " d " 'xf/dragon
2022-11-06 20:33:00 +00:00
:desc " Update DB & Quit " " wU " ( lambda ( ) ( interactive ) ( xf/org-roam-update ) ( save-buffers-kill-terminal ) )
2022-09-09 19:58:38 +00:00
:map ctl-x-map
" 8 SPC " ( lambda ( ) ( insert-char " 200B " ) )
2021-12-21 12:41:37 +00:00
:map text-mode-map
2023-01-20 07:41:07 +00:00
:desc " Markdown to Zulip " " mam " " gg4dip
2022-08-04 08:36:37 +00:00
:%s/<\\/?span ?[ ^ > ] *>//g
:%s/\\n\\n<a id=.*<\\/a>\\n\\n//g
2023-01-31 18:10:27 +00:00
:%s/<\\ ( http [ ^ \\n ] +\\ ) >/\\1/g
"
;:%s/\\\\<\\([^ \\n]+\\)\\\\>/<\\1>/g
"
2022-08-04 08:36:37 +00:00
;:%s/\\n *\\n /\\n /
;:%s/ / /g
"
)
2022-02-11 07:57:32 +00:00
; TODO use smerge-basic-map
( map! :map smerge-mode-map
2021-10-15 12:28:52 +00:00
:leader
" Ss " 'smerge-next
2022-02-11 07:57:32 +00:00
" Sj " 'smerge-next
2021-10-15 12:28:52 +00:00
" Sn " 'smerge-next
2022-02-11 07:57:32 +00:00
" Sk " 'smerge-prev
2021-10-15 12:28:52 +00:00
" Sp " 'smerge-prev
" Sr " 'smerge-resolve
" SR " 'smerge-refine
" Su " 'smerge-keep-upper
" Si " 'smerge-keep-current
" So " 'smerge-keep-lower
2021-02-25 17:36:51 +00:00
)
2020-11-23 23:15:00 +00:00
2021-03-26 18:02:37 +00:00
;;;; GLOBAL SETUP
2021-10-19 09:34:44 +00:00
( setq confirm-kill-emacs nil
lazy-highlight-cleanup nil
large-file-warning-threshold 40000000 )
2020-11-12 09:01:12 +00:00
2023-06-21 10:33:33 +00:00
; TODO auto-trim whitespace unless markdown
2020-12-07 20:55:59 +00:00
( whitespace-mode 0 )
2021-10-19 09:34:44 +00:00
( auto-correct-mode )
2021-03-20 10:12:10 +00:00
2021-10-04 08:45:24 +00:00
;;; UTF-8 encoding - https://zhangda.wordpress.com/2016/02/15/configurations-for-beautifying-emacs-org-mode/
;; disable CJK coding/encoding (Chinese/Japanese/Korean characters)
( setq utf-translate-cjk-mode nil )
( set-language-environment 'utf-8 )
( setq locale-coding-system 'utf-8 )
;; set the default encoding system
( prefer-coding-system 'utf-8 )
( setq default-file-name-coding-system 'utf-8 )
( set-default-coding-systems 'utf-8 )
( set-terminal-coding-system 'utf-8 )
( set-keyboard-coding-system 'utf-8 )
;; backwards compatibility as default-buffer-file-coding-system
;; is deprecated in 23.2.
( if ( boundp buffer-file-coding-system )
( setq buffer-file-coding-system 'utf-8 )
( setq default-buffer-file-coding-system 'utf-8 ) )
2023-03-13 14:34:44 +00:00
;;; Clipboard
;; Checks if the session type is in fact for Wayland.
( if ( string= ( getenv " XDG_SESSION_TYPE " ) " wayland " )
( progn
;; Clipboard from Terminal in Wayland: https://vernon-grant.com/emacs/tmux-emacs-and-the-system-clipboard-on-wayland/
( setq wl-copy-process nil )
( defun wl-copy ( text )
( setq wl-copy-process ( make-process :name " wl-copy "
:buffer nil
:command ' ( " wl-copy " " -f " " -n " )
:connection-type 'pipe
:noquery t ) )
( process-send-string wl-copy-process text )
( process-send-eof wl-copy-process ) )
( defun wl-paste ( )
( if ( and wl-copy-process ( process-live-p wl-copy-process ) )
nil ; should return nil if we're the current paste owner
( shell-command-to-string " wl-paste -n | tr -d \r " ) ) )
( setq interprogram-cut-function 'wl-copy )
( setq interprogram-paste-function 'wl-paste )
)
;; Treat clipboard input as UTF-8 string first; compound text next, etc.
( setq x-select-request-type ' ( UTF8_STRING COMPOUND_TEXT TEXT STRING ) )
( add-hook 'window-setup-hook #' xclip-mode )
)
2021-10-04 08:45:24 +00:00
2021-11-04 11:21:35 +00:00
;;; Data Preservation
2022-07-05 09:40:11 +00:00
;; Undo
2021-06-03 10:16:09 +00:00
( setq evil-want-fine-undo t )
( setq amalgamating-undo-limit 5 )
2021-04-12 08:38:08 +00:00
;; Doom defaults: /home/janek/.config/emacs/core/core-editor.el::89
2021-02-24 11:19:09 +00:00
( setq auto-save-default t
auto-save-interval 40 )
( setq make-backup-files t
delete-old-versions t
version-control t
vc-make-backup-files t
kept-new-versions 5
kept-old-versions 3
)
2020-10-07 19:41:29 +00:00
2021-11-04 11:21:35 +00:00
;;;; Directory configuration
2020-10-07 19:41:29 +00:00
2022-01-09 22:22:03 +00:00
( defvar user-data-dir ( if ( file-exists-p " ~/data/ " ) " ~/data " " /home/data " ) " Location of the main user data " )
2020-10-07 19:41:29 +00:00
2022-01-11 01:54:46 +00:00
( load! " ./user.el " nil t )
2020-10-12 20:13:22 +00:00
( load! " ./local.el " nil t )
2022-11-29 22:20:54 +00:00
( load! " ./theme.el " nil t )
2020-10-12 20:13:22 +00:00
2021-12-10 12:29:31 +00:00
( setq backup-directory-alist ( list ( cons " . " ( concat doom-cache-dir " backup/ " ) ) )
2021-11-04 11:21:35 +00:00
custom-emacs-data-dir ( expand-file-name " data " doom-private-dir ) )
2021-03-26 18:02:37 +00:00
2021-10-31 18:32:04 +00:00
( use-package! projectile
2021-11-23 21:22:06 +00:00
:init
2022-09-30 18:01:23 +00:00
( projectile-add-known-project ( expand-file-name " 4-media/ " user-data-dir ) )
2022-01-09 17:20:19 +00:00
( after! org
( projectile-add-known-project org-directory )
( projectile-register-project-type 'org ' ( " .orgids " ) )
2022-01-30 11:32:06 +00:00
;(setq projectile-project-search-path '((org-directory . 0) ((expand-file-name "1-projects" user-data-dir) . 3)))
)
2022-12-07 17:40:50 +00:00
:config
( add-to-list 'projectile-project-root-files " README.org " )
( add-to-list 'projectile-project-root-files " .orgids " )
2021-06-30 16:25:43 +00:00
)
2021-10-11 08:01:22 +00:00
2022-04-22 11:11:07 +00:00
( setq time-stamp-bare " %Y-%m-%d "
time-stamp-format ( concat " [ " time-stamp-bare " ] " ) )
2022-02-11 07:57:32 +00:00
;; Automatically add modified stamp - https://github.com/org-roam/org-roam/issues/1935#issuecomment-968047007
( use-package! time-stamp
2023-03-13 14:34:44 +00:00
:init ( setq time-stamp-start " modified:[ ]+ \\ \\ ? "
2022-02-11 07:57:32 +00:00
time-stamp-end " $ " )
:hook before-save )
2022-09-10 17:03:58 +00:00
( use-package! image
:custom
;; Enable converting external formats (ie. webp) to internal ones.
( image-use-external-converter t ) )
2022-08-09 20:53:56 +00:00
;(setq image-file-name-regexps "/preview/")
2022-08-04 08:36:37 +00:00
;(add-to-list 'image-file-name-regexps "/preview/")
2021-03-26 18:02:37 +00:00
;;;; ORG
2021-11-04 11:21:35 +00:00
( use-package! org
:bind ( :map org-mode-map
2021-11-19 11:01:04 +00:00
( " C-c b " . org-cycle-list-bullet )
2021-11-04 11:21:35 +00:00
( " C-c . " . org-time-stamp-inactive )
( " C-c C-. " . org-time-stamp )
2023-11-04 18:04:03 +00:00
( " C-c C-; " . ( lambda ( ) ( interactive ) ( let ( ( time-stamp-format ( concat " [ " time-stamp-bare " %a %H:%M] " ) ) ) ( call-interactively 'org-time-stamp ) ) ) )
2021-11-04 11:21:35 +00:00
( " M-C-+ " . org-timestamp-up )
( " M-C-- " . org-timestamp-down )
)
2022-05-19 07:45:55 +00:00
:init
;; Behavior
( setq org-read-date-prefer-future nil
2022-08-04 08:36:37 +00:00
org-extend-today-until 5
)
2022-05-19 07:45:55 +00:00
( setq org-id-method 'org
2022-08-04 08:36:37 +00:00
org-id-ts-format " %Y%m%dT%H%M%S "
)
2022-05-19 07:45:55 +00:00
;; Visuals
; https?[0-z.\/-]*\.(png|jpg)\?[^?]*
2022-08-04 08:36:37 +00:00
( setq org-fold-core-style 'overlays )
2022-05-19 07:45:55 +00:00
( setq org-image-actual-width nil )
( setq org-ellipsis " ◀ " )
2021-11-04 11:21:35 +00:00
:config
2021-12-21 12:41:37 +00:00
2023-03-13 14:34:44 +00:00
( defun xf/slugify ( string )
( downcase ( s-replace-regexp " [^[:alnum:][:digit:]] \+ " " - "
( s-replace-regexp " .*:// \\ ([^.]+ \\ ) \\ ..* " " \\ 1 " ( substring-no-properties ( org-sort-remove-invisible string ) ) ) ) ) )
2022-09-18 11:47:49 +00:00
2022-05-16 21:53:27 +00:00
; the value does not matter, see https://emacs.stackexchange.com/questions/71774/pass-default-value-to-org-set-property/71777#71777
2022-06-01 13:01:07 +00:00
;(add-to-list 'org-global-properties-fixed '("ID_ALL" . "id"))
2021-11-04 11:21:35 +00:00
( map! :map org-mode-map
:leader
2022-09-16 12:33:17 +00:00
" \\ " 'org-ctrl-c-ctrl-c
2023-12-01 16:41:05 +00:00
:desc " Agenda " " oa " 'org-agenda
2024-01-12 16:55:25 +00:00
:desc " My Agenda " " oA " ( lambda ( ) ( interactive ) ( let ( ( org-agenda-tag-filter-preset ' ( " -phys " " -erlangen " ) ) ) ( org-agenda nil " d " ) ) )
2021-11-04 11:21:35 +00:00
:localleader
2021-12-02 22:27:35 +00:00
" C " 'org-clock-in
2022-04-11 06:31:13 +00:00
" v " 'org-insert-heading
" jj " 'org-insert-heading
2021-11-04 11:21:35 +00:00
" k " 'org-latex-export-to-pdf
" t " 'org-todo-or-insert
" n " 'org-add-note
" y " 'org-yank-visible
2021-11-09 04:37:29 +00:00
" Y " 'org-copy-visible
2021-11-04 11:21:35 +00:00
" d= " 'org-timestamp-up-week
" rt " 'org-change-todo-in-region
" ra " 'org-change-tag-in-region
" lk " 'counsel-org-link
2021-11-23 10:53:58 +00:00
" gR " 'org-mode-restart
2022-09-16 12:33:17 +00:00
:desc " Low Priority " " pc " ( lambda ( ) ( interactive ) ( org-priority " C " ) )
:desc " Medium Priority " " pb " ( lambda ( ) ( interactive ) ( org-priority " B " ) )
:desc " High Priority " " pa " ( lambda ( ) ( interactive ) ( org-priority " A " ) )
2022-09-18 11:47:49 +00:00
:desc " Set ID property " " lI " ( lambda ( ) ( interactive )
2022-11-19 18:57:52 +00:00
;; Check out https://github.com/novoid/dot-emacs/blob/master/config.org#my-id-get-or-generate
2023-06-21 10:33:33 +00:00
; TODO trim trailing dash
2022-09-18 11:47:49 +00:00
( org-set-property " ID "
2022-06-01 13:01:07 +00:00
( let ( ( heading ( org-get-heading t t t t ) ) )
2022-09-18 11:47:49 +00:00
( if heading ( org-read-property-value " ID " nil ( xf/slugify heading ) ) ( file-name-sans-extension ( file-name-nondirectory buffer-file-name ) ) )
2023-06-21 10:33:33 +00:00
) )
; TODO insert current date timestamp
;(or (org-entry-get nil "CREATED") (org-set-property "CREATED" (org-read-date)))
;(or (org-entry-get nil "MODIFIED") (org-set-property "MODIFIED" (org-read-date)))
)
2022-05-16 20:32:03 +00:00
:desc " Set Roam Aliases " " la " ( lambda ( ) ( interactive ) ( org-set-property " ROAM_ALIASES " nil ) )
2021-11-23 10:53:58 +00:00
:desc " Add tag " " mt " 'org-roam-tag-add
:desc " Remove tag " " mT " 'org-roam-tag-remove
:desc " Extract node to file " " me " 'org-roam-extract-subtree
2021-11-04 11:21:35 +00:00
)
2021-11-09 04:37:29 +00:00
2022-05-19 07:45:55 +00:00
;; Fix xdg-open & pdfs - https://depp.brause.cc/dotemacs/#orgd97f08c
( setq org-file-apps ' ( ( remote . emacs )
( " \\ .pdf \\ ' " . default )
( auto-mode . emacs )
( directory . emacs )
( system . " setsid -w xdg-open %s " )
( t . system ) ) )
2021-10-11 08:21:29 +00:00
2022-03-24 10:32:12 +00:00
( setq org-priority-default 67
org-priority-lowest 68
2022-05-19 07:45:55 +00:00
org-priority-start-cycle-with-default nil )
( setq org-priority-faces ' ( ( 65 . error ) ( 66 . " DarkGoldenRod " ) ( 67 . warning ) ( 68 . " bisque " ) ( 69 . " grey " ) ) )
2022-03-24 10:32:12 +00:00
2023-04-27 12:28:04 +00:00
; highlight review keyword
2024-01-12 16:55:25 +00:00
( setq org-todo-keywords
' (
( sequence
" TODO(t) " ; A task that needs doing & is ready to do
" PROJ(p) " ; A project, which usually contains other tasks
" STRT(s) " ; A task that is in progress
" WAIT(w) " ; Something external is holding up this task
" HOLD(h) " ; This task is paused/on hold because of me
" IDEA(i) " ; An unconfirmed and unapproved task or notion
" | "
" DONE(d) " ; Task successfully completed
" KILL(k) " ) ; Task was cancelled, aborted, or is no longer applicable
( sequence " IDEA(i!) " " OUTLINE(o!) " " DRAFT(f!) " " | " " REVIEW(v!) " " DONE(d!) " " ABANDON(a!) " ) ; For Writings
( sequence
" LOOP(l) "
" PERM(e) " ; A task that can always be worked on
" | "
" RELOOP(d) " )
( sequence
" [ ](T) " ; A task that needs doing
" [-](S) " ; Task is in progress
" [?](W) " ; Task is being held up or paused
" | "
" [X](D) " ) ; Task was completed
( sequence
" | "
" OKAY(o) "
" YES(y) "
" NO(n) " ) )
org-todo-keyword-faces
' ( ( " [-] " . +org-todo-active )
( " STRT " . +org-todo-active )
( " [?] " . +org-todo-onhold )
( " WAIT " . +org-todo-onhold )
;("REVIEW" . +org-todo-onhold)
( " HOLD " . +org-todo-onhold )
( " PROJ " . +org-todo-project )
( " NO " . +org-todo-cancel )
( " ABANDON " . +org-todo-cancel )
( " KILL " . +org-todo-cancel ) ) )
2022-09-16 12:33:17 +00:00
2021-10-11 08:21:29 +00:00
;; Org startup - https://orgmode.org/manual/In_002dbuffer-Settings.html
( setq org-startup-folded 'show2levels
2022-09-18 11:47:49 +00:00
org-display-remote-inline-images 'cache )
2022-05-19 07:45:55 +00:00
; TODO customize org-log-note-headings
2021-10-11 08:21:29 +00:00
;; Automated logging for todos - https://stackoverflow.com/questions/12262220/add-created-date-property-to-todos-in-org-mode/52815573#52815573
( setq org-log-done 'time
org-log-into-drawer t
org-treat-insert-todo-heading-as-state-change t )
2021-10-04 08:45:24 +00:00
2022-05-19 07:45:55 +00:00
( defun xf/org-attach-id-folder-format ( id )
" Translate any ID into a folder-path. "
( format " %s/%s "
( substring id 0 2 )
( if ( > ( seq-length id ) 2 ) ( substring id 2 ) id ) )
)
2022-06-22 16:29:30 +00:00
( unless ( file-exists-p org-attach-id-dir )
( setq org-attach-id-dir ( expand-file-name " attach " ( xdg-user-dir " DOCUMENTS " ) ) ) )
( setq org-attach-method 'mv
2022-05-19 07:45:55 +00:00
org-attach-preferred-new-method nil
org-attach-id-to-path-function-list ' ( xf/org-attach-id-folder-format )
)
2021-10-04 08:45:24 +00:00
;; https://stackoverflow.com/a/32353255/6723250
( defun org-convert-csv-table ( beg end )
2022-01-10 20:39:57 +00:00
" convert csv to org-table considering '12,12' "
2021-10-04 08:45:24 +00:00
( interactive ( list ( point ) ( mark ) ) )
( replace-regexp " \\ (^ \\ ) \\ | \\ ( \" .*? \" \\ ) \\ |, " ( quote ( replace-eval-replacement
replace-quote ( cond ( ( equal " ^ " ( match-string 1 ) ) " | " )
( ( equal " , " ( match-string 0 ) ) " | " )
( ( match-string 2 ) ) ) ) ) nil beg end ) )
2021-03-30 18:29:08 +00:00
( defun org-todo-or-insert ( &optional arg )
( interactive " P " )
( if ( org-at-heading-p ) ( org-todo arg ) ( org-insert-todo-heading arg t ) ) )
2021-03-30 16:15:44 +00:00
( defun org-timestamp-up-week ( )
( interactive )
2021-04-02 19:01:26 +00:00
( let ( ( current-prefix-arg ' ( 7 ) ) ) ( call-interactively 'org-timestamp-up-day ) )
2021-03-30 18:29:08 +00:00
)
2021-03-30 16:15:44 +00:00
2021-04-11 20:47:16 +00:00
( defun org-change-todo-in-region ( )
2022-01-10 20:39:57 +00:00
" https://emacs.stackexchange.com/questions/38529/make-multiple-lines-todos-at-once-in-org-mode "
2021-04-11 20:47:16 +00:00
( interactive )
( let ( ( scope ( if mark-active 'region 'tree ) )
( state ( org-fast-todo-selection ) )
( org-enforce-todo-dependencies nil ) )
( org-map-entries ( lambda ( ) ( org-todo state ) ) nil scope ) ) )
2021-09-20 19:29:19 +00:00
( defun org-yank-visible ( )
( interactive )
2021-11-08 23:31:44 +00:00
( if mark-active ( call-interactively 'org-copy-visible ) ( org-copy-visible ( point ) ( progn ( end-of-line ) ( point ) ) ) ) )
2021-09-20 19:29:19 +00:00
2021-03-26 18:02:37 +00:00
;; Toggle source blocks with C-c t
( defvar org-blocks-hidden nil )
( defun org-toggle-blocks ( )
2021-04-11 20:47:16 +00:00
" Toggle all org blocks. "
2021-03-26 18:02:37 +00:00
( interactive )
( if org-blocks-hidden
( org-show-block-all )
( org-hide-block-all ) )
( setq-local org-blocks-hidden ( not org-blocks-hidden ) ) )
( define-key org-mode-map ( kbd " C-c t " ) 'org-toggle-blocks )
;; https://christiantietze.de/posts/2019/06/org-fold-heading/
( defun ct/org-foldup ( )
" Hide the entire subtree from root headline at point. "
( interactive )
( while ( ignore-errors ( outline-up-heading 1 ) ) )
( org-flag-subtree t ) )
( defun ct/org-shifttab ( &optional arg )
( interactive " P " )
( if ( or ( null ( org-current-level ) ) ; point is before 1st heading, or
( and ( = 1 ( org-current-level ) ) ; at level-1 heading, or
( org-at-heading-p ) )
( org-at-table-p ) ) ; in a table (to preserve cell movement)
; perform org-shifttab at root level elements and inside tables
( org-shifttab arg )
; try to fold up elsewhere
( ct/org-foldup ) ) )
( define-key org-mode-map ( kbd " S-<tab> " ) 'ct/org-shifttab )
2022-03-24 10:32:12 +00:00
;; https://blog.aaronbieber.com/2016/09/24/an-agenda-for-life-with-org-mode.html
( defun air-org-skip-subtree-if-habit ( )
" Skip an agenda entry if it has a STYLE property equal to \" habit \" . "
( let ( ( subtree-end ( save-excursion ( org-end-of-subtree t ) ) ) )
( if ( string= ( org-entry-get nil " STYLE " ) " habit " )
subtree-end
nil ) ) )
( defun air-org-skip-subtree-if-priority ( priority )
" Skip an agenda subtree if it has a priority of PRIORITY.
PRIORITY may be one of the characters ?A , ?B , or ?C . "
( let ( ( subtree-end ( save-excursion ( org-end-of-subtree t ) ) )
( pri-value ( * 1000 ( - org-lowest-priority priority ) ) )
( pri-current ( org-get-priority ( thing-at-point 'line t ) ) ) )
( if ( = pri-value pri-current )
subtree-end
nil ) ) )
2024-01-12 16:55:25 +00:00
2022-03-24 10:32:12 +00:00
( setq org-agenda-custom-commands
2024-01-12 16:55:25 +00:00
' ( ( " d " " Daily agenda and all TODOs " (
( tags " PRIORITY= \" A \" "
( ( org-agenda-skip-function ' ( org-agenda-skip-entry-if 'todo 'done ) )
( org-agenda-overriding-header " DO NOW: " ) ) )
( agenda " " ( ( org-agenda-start-day nil ) ( org-agenda-span 4 ) ) )
( tags " PRIORITY= \" B \" "
2022-03-24 10:32:12 +00:00
( ( org-agenda-skip-function ' ( org-agenda-skip-entry-if 'todo 'done ) )
2024-01-12 16:55:25 +00:00
( org-agenda-overriding-header " Important: " ) ) )
2022-03-24 10:32:12 +00:00
( alltodo " "
( ( org-agenda-skip-function ' ( or ( air-org-skip-subtree-if-habit )
( air-org-skip-subtree-if-priority ?A )
( org-agenda-skip-if nil ' ( scheduled deadline ) ) ) )
( org-agenda-overriding-header " ALL normal priority tasks: " ) ) ) )
( ( org-agenda-compact-blocks t ) ) ) ) )
2022-09-22 07:57:37 +00:00
( use-package! dash
:defer t
:config
( add-variable-watcher 'org-display-custom-times ( lambda ( symbol val op wh ) ( cl-flet ( ( wrapper ( if val ( -cut concat " < " <> " > " ) 'identity ) ) ) ( setq org-time-stamp-custom-formats ` ( , ( wrapper " %d.%m.%Y %a " ) . , ( wrapper " %d.%m.%Y %a %H:%M " ) ) ) ) ) )
( setq org-display-custom-times 't )
)
2021-04-11 20:47:16 +00:00
)
2021-03-30 18:29:08 +00:00
2022-05-19 07:45:55 +00:00
( after! org-fancy-priorities
;; https://unicode-table.com/en/blocks/miscellaneous-symbols-and-arrows https://www.w3schools.com/colors/colors_names.asp
; (custom-reevaluate-setting 'org-fancy-priorities-list) (add-to-list 'org-fancy-priorities-list "☠" t)
( setq org-fancy-priorities-list ' ( " ❗ " " ✯ " " ❖ " " ⬢ " " ■ " ) )
)
2021-11-23 21:22:06 +00:00
( use-package! org-journal
;; Prompt after idleness - Focused? ETC? (Pragmatic Programmer)
:init
2023-12-01 16:41:05 +00:00
2022-04-04 09:59:49 +00:00
( setq org-journal-file-type 'monthly
2022-04-22 11:11:07 +00:00
org-journal-file-format " %Y%m.org "
2022-04-04 09:59:49 +00:00
org-journal-created-property-timestamp-format time-stamp-format
2021-11-23 21:22:06 +00:00
org-journal-carryover-delete-empty-journal 'always
2022-04-22 11:11:07 +00:00
org-journal-date-format ( concat " [ " time-stamp-bare " %3a] " )
2024-01-12 16:55:25 +00:00
org-journal-time-format " %02H "
2021-11-23 21:22:06 +00:00
)
2023-12-01 16:41:05 +00:00
2021-11-23 21:22:06 +00:00
:config
2022-08-21 09:55:09 +00:00
; TODO map njj to open-or-create-entry
2022-05-03 09:30:17 +00:00
2022-04-27 23:48:22 +00:00
;; https://emacs.stackexchange.com/questions/17897/create-an-org-journal-template-for-daily-journal-entry/32655#32655
( defun pc/new-buffer-p ( )
( not ( file-exists-p ( buffer-file-name ) ) ) )
( defun pc/insert-journal-template ( )
( when ( pc/new-buffer-p )
( save-excursion
( goto-char ( point-min ) )
2022-05-03 09:30:17 +00:00
( insert ( concat " :properties: \n :id: " ( file-name-base buffer-file-name ) " \n :end: \n #+startup: overview noinlineimages \n #+options: \\ n:t \n " ) ) ) ) )
2022-04-27 23:48:22 +00:00
( add-hook 'org-journal-after-entry-create-hook #' pc/insert-journal-template )
2022-05-16 20:32:03 +00:00
( defvar xf/survey-mode-journal--timer nil )
( defvar xf/survey-mode-journal--timer-interval 300 )
2022-01-07 12:28:07 +00:00
2022-05-16 20:32:03 +00:00
( define-minor-mode xf/survey-mode
2022-01-07 12:28:07 +00:00
" New org-journal entry after long idleness "
2021-11-23 21:22:06 +00:00
:group 'org-roam
:global t
2022-05-16 20:32:03 +00:00
( when xf/survey-mode-journal--timer ( cancel-timer xf/survey-mode-journal--timer ) )
( setq xf/survey-mode-journal--timer
( when xf/survey-mode
2021-11-23 21:22:06 +00:00
( run-with-idle-timer
2022-05-16 20:32:03 +00:00
xf/survey-mode-journal--timer-interval :repeat
#' xf/journal-survey ) ) ) )
2021-11-23 21:22:06 +00:00
2022-05-16 20:32:03 +00:00
( defun xf/journal-survey ( )
2022-01-07 12:28:07 +00:00
" Open a new journal entry "
2021-11-23 21:22:06 +00:00
( interactive )
( unless ( equal major-mode 'org-journal-mode ) ( call-interactively 'org-journal-new-entry ) ) )
2022-07-06 06:59:22 +00:00
;(if (file-exists-p org-journal-dir) (xf/survey-mode))
2021-11-23 21:22:06 +00:00
; TODO journal at start (call-interactively 'org-journal-new-entry)
)
2022-01-21 09:32:52 +00:00
;; FIXME can I combine defer and after?
2021-11-04 11:21:35 +00:00
( use-package! org-roam
2022-01-21 09:32:52 +00:00
;:after org-mode
:defer 3
2022-11-06 21:39:45 +00:00
:init
( setq company-minimum-prefix-length 1
company-dabbrev-ignore-case 't
completion-ignore-case 't )
2021-11-04 11:21:35 +00:00
:config
( require 'org-roam-protocol )
2022-06-13 13:50:42 +00:00
;; https://github.com/org-roam/org-roam/pull/833
2022-05-16 20:32:03 +00:00
( defun xf/dashify-slug ( slug )
( s-replace " _ " " - " slug ) )
( advice-add 'org-roam-node-slug :filter-return #' xf/dashify-slug )
2021-11-09 04:37:29 +00:00
( setq org-roam-db-update-on-save nil
2022-05-10 13:23:01 +00:00
org-roam-extract-new-file-path " ${slug}.org "
+org-roam-auto-backlinks-buffer t )
2022-01-13 19:52:25 +00:00
( add-hook 'org-capture-after-finalize-hook ( lambda ( ) ( if ( org-roam-file-p ) ( org-roam-db-sync ) ) ) )
2021-11-09 04:37:29 +00:00
2022-05-16 20:32:03 +00:00
( setq xf/org-roam-capture-props ( concat " :properties: \n :id: ${slug} \n :created: %< " time-stamp-format " > \n :modified: <> \n :end: \n " ) )
( setq xf/org-roam-capture-title " \n #+title: ${title} " )
2021-11-09 04:37:29 +00:00
( setq org-roam-capture-templates
2021-11-13 10:16:17 +00:00
` ( ( " d " " default " plain " %? " :target
2022-05-16 20:32:03 +00:00
( file+head , org-roam-extract-new-file-path , ( concat xf/org-roam-capture-props " #+filetags: : " xf/org-roam-capture-title ) )
2021-11-13 10:16:17 +00:00
:unnarrowed t )
2021-11-18 10:14:28 +00:00
)
)
2022-12-16 18:49:07 +00:00
( cl-loop for item in ' ( " health " " own " " list " " notes " " project " " entity:person " " tech:software:list " " faith " " inspiration " " writing:blog " )
2021-11-18 10:14:28 +00:00
do ( add-to-list 'org-roam-capture-templates
` ( , ( substring item 0 1 ) , ( car ( split-string item " : " ) ) plain " %? " :target
2022-05-16 20:32:03 +00:00
( file+head , ( concat ( car ( split-string item " : " ) ) " / " org-roam-extract-new-file-path ) , ( concat xf/org-roam-capture-props " #+filetags: : " item " : " xf/org-roam-capture-title ) )
2021-11-13 10:16:17 +00:00
:unnarrowed t )
)
2021-11-18 10:14:28 +00:00
)
2021-11-09 04:37:29 +00:00
2022-05-16 20:32:03 +00:00
( defvar xf/auto-org-roam-db-sync--timer nil )
2023-03-13 14:34:44 +00:00
( defvar xf/auto-org-roam-db-sync--timer-interval 40 )
2022-05-16 20:32:03 +00:00
( define-minor-mode xf/auto-org-roam-db-sync-mode
2021-11-04 11:21:35 +00:00
" Toggle automatic `org-roam-db-sync' when Emacs is idle.
2022-01-07 12:28:07 +00:00
Reference: ` auto-save-visited-mode ' "
2021-11-04 11:21:35 +00:00
:group 'org-roam
:global t
2022-05-16 20:32:03 +00:00
( when xf/auto-org-roam-db-sync--timer ( cancel-timer xf/auto-org-roam-db-sync--timer ) )
( setq xf/auto-org-roam-db-sync--timer
( when xf/auto-org-roam-db-sync-mode
2021-11-04 11:21:35 +00:00
( run-with-idle-timer
2022-05-16 20:32:03 +00:00
xf/auto-org-roam-db-sync--timer-interval :repeat
2022-01-13 19:52:25 +00:00
#' org-roam-db-sync ) ) ) )
2021-11-23 11:54:33 +00:00
2022-01-21 09:32:52 +00:00
;; TODO kill opened buffers
2022-05-16 20:32:03 +00:00
( defun xf/org-roam-update ( )
2022-01-21 09:32:52 +00:00
" Update org-roam database and sync ids to orgids. "
2021-11-23 11:54:33 +00:00
( interactive )
2022-01-21 09:32:52 +00:00
( org-roam-db-sync )
( let ( ( org-display-remote-inline-images 'skip ) ) ( org-roam-update-org-id-locations ) )
( when ( equal major-mode 'org-mode ) ( org-mode-restart ) ) )
2021-11-23 11:54:33 +00:00
2023-06-21 10:33:33 +00:00
; FIXME test if still needed (if (file-exists-p org-roam-directory) (xf/auto-org-roam-db-sync-mode))
2022-12-22 16:25:29 +00:00
;; Node Search
( setq org-roam-node-display-template
#( " ${doom-hierarchy:*} ${doom-type:7} ${doom-tags:30} " 20 35
( face font-lock-keyword-face )
28 40
( face org-tag )
) )
;; REVIEW Remove when addressed upstream. See org-roam/org-roam#2066.
( defun my/org-roam-node-read--to-candidate ( node template )
" Return a minibuffer completion candidate given NODE.
TEMPLATE is the processed template used to format the entry. "
( let ( ( candidate-main ( org-roam-node--format-entry
template
node
( 1- ( frame-width ) ) ) ) )
( cons ( propertize candidate-main 'node node ) node ) ) )
( advice-add 'org-roam-node-read--to-candidate :override #' my/org-roam-node-read--to-candidate )
2021-11-04 11:21:35 +00:00
)
2022-01-21 09:32:52 +00:00
( use-package! ox
:config
( map! :map org-mode-map
:leader
2022-09-18 11:47:49 +00:00
" e " 'org-export-dispatch-without-time
2022-01-21 09:32:52 +00:00
" E " 'org-export-repeat
2022-05-16 20:32:03 +00:00
:desc " Save and Export " " be " ( lambda ( ) ( interactive ) ( basic-save-buffer ) ( org-export-repeat ) )
2022-01-21 09:32:52 +00:00
:localleader
" E " 'org-export-repeat
)
2023-04-21 07:27:47 +00:00
( defun org-export-disable-id ( )
( interactive )
( defun my-link-remover ( link contents info ) contents )
( org-link-set-parameters " id " :export 'my-link-remover )
)
2022-09-16 12:55:11 +00:00
( setq org-html-style " <link rel= \" stylesheet \" type= \" text/css \" href= \" https://gongzhitaao.org/orgcss/org.css \" /> "
org-html-head-include-default-style nil
org-html-htmlize-output-type 'css )
2022-01-21 09:32:52 +00:00
( defun org-export-repeat ( )
( interactive )
( let ( ( current-prefix-arg ' ( 4 ) ) ) ( call-interactively 'org-export-dispatch ) )
)
;; TODO name file according to subtree headline
2022-09-18 11:47:49 +00:00
( defun org-export-dispatch-without-time ( )
2022-01-21 09:32:52 +00:00
( interactive )
( let ( ( org-time-stamp-custom-formats
2022-09-18 11:47:49 +00:00
' ( " %d.%m.%Y " . " %d.%m.%Y " ) )
2022-01-21 09:32:52 +00:00
( org-display-custom-times 't ) )
2022-09-18 11:47:49 +00:00
( org-set-property " EXPORT_FILE_NAME " ( xf/slugify ( org-get-heading t t t t ) ) )
2022-01-21 09:32:52 +00:00
( org-export-dispatch ) )
)
2022-05-16 20:32:03 +00:00
( setq org-latex-to-pdf-process ' ( " xelatex -interaction -shell-escape nonstopmode %f " " xelatex -interaction nonstopmode -shell-escape %f " ) )
2022-01-21 09:32:52 +00:00
;; Exporting - https://orgmode.org/manual/Export-Settings.html
( setq org-export-with-tags nil
org-export-with-tasks 'done
org-export-with-todo-keywords nil
2022-08-04 08:36:37 +00:00
;org-export-with-toc nil
2022-01-21 09:32:52 +00:00
org-export-with-section-numbers nil
2022-08-04 08:36:37 +00:00
org-export-with-broken-links 't
2022-01-21 09:32:52 +00:00
org-ascii-text-width 999
org-export-headline-levels 4
org-export-with-sub-superscripts '{}
org-use-sub-superscripts '{}
)
)
2022-01-21 12:43:53 +00:00
( use-package! ox-context
:after ox )
2022-02-01 10:35:00 +00:00
( use-package! ox-bb
:after ox )
2022-01-21 09:32:52 +00:00
( use-package! ox-extra
:after ox
:config ( ox-extras-activate ' ( ignore-headlines ) ) ;; use tag :ignore: to export content without headline
)
( use-package! ox-latex
:after ox
:config
;; Insert linebreak after headings tagged with "newpage" when exporting through latex - https://emacs.stackexchange.com/a/30892
( defun org/get-headline-string-element ( headline backend info )
( let ( ( prop-point ( next-property-change 0 headline ) ) )
( if prop-point ( plist-get ( text-properties-at prop-point headline ) :parent ) ) ) )
( defun org/ensure-latex-clearpage ( headline backend info )
( when ( org-export-derived-backend-p backend 'latex )
( let ( ( elmnt ( org/get-headline-string-element headline backend info ) ) )
( when ( member " newpage " ( org-element-property :tags elmnt ) )
( concat " \\ clearpage \n " headline ) ) ) ) )
( add-to-list 'org-export-filter-headline-functions
'org/ensure-latex-clearpage )
;;(setq org-latex-toc-command "\\tableofcontents*\n\n")
( setq org-latex-pdf-process ' ( " latexmk -shell-escape -pdfxe -pdfxelatex= \" xelatex --shell-escape \" -outdir=/tmp/latexmk -f -pdf %F && mv %f /tmp/latexmk && mv /tmp/latexmk/%b.pdf %o " ) ; https://emacs.stackexchange.com/a/48351
org-latex-packages-alist ' ( ( " " " fullpage " ) ( " avoid-all " " widows-and-orphans " ) ( " " " svg " ) )
2022-08-21 10:29:15 +00:00
org-latex-src-block-backend 'minted
2022-01-21 09:32:52 +00:00
org-latex-default-class " article4 " )
( add-to-list 'org-latex-classes
' ( " article4 " " \\ documentclass{article} \\ usepackage{titlesec} \\ titleformat{ \\ paragraph}{ \\ normalfont \\ normalsize \\ itshape}{ \\ theparagraph}{1em}{} \\ titlespacing*{ \\ paragraph}{0pt}{2ex plus 1ex minus .2ex}{.5ex plus .2ex} "
( " \\ section{%s} " . " \\ section*{%s} " )
( " \\ subsection{%s} " . " \\ subsection*{%s} " )
( " \\ subsubsection{%s} " . " \\ subsubsection*{%s} " )
( " \\ paragraph{%s} " . " \\ paragraph*{%s} " )
( " \\ subparagraph{%s} " . " \\ subparagraph*{%s} " ) ) )
( add-to-list 'org-latex-classes
' ( " shortreport " " \\ documentclass[oneside]{memoir} \\ chapterstyle{article} "
( " \\ chapter{%s} " . " \\ chapter*{%s} " )
( " \\ section{%s} " . " \\ section*{%s} " )
( " \\ subsection{%s} " . " \\ subsection*{%s} " )
( " \\ subsubsection{%s} " . " \\ subsubsection*{%s} " )
( " \\ paragraph{%s} " . " \\ paragraph*{%s} " )
( " \\ subparagraph{%s} " . " \\ subparagraph*{%s} " ) ) )
)
2021-07-05 17:59:47 +00:00
2021-02-25 11:24:50 +00:00
;; https://discord.com/channels/406534637242810369/406554085794381833/814175445004189706
2021-10-11 08:21:29 +00:00
;; Fix xdg-open after setting process-connection-type
;(setq process-connection-type nil)
2021-02-25 11:24:50 +00:00
;(after! org
; (add-to-list 'org-file-apps '(system . "setsid -w xdg-open %s"))
2021-02-24 11:19:09 +00:00
2021-03-26 18:02:37 +00:00
;;;; PACKAGES
2021-03-23 20:57:07 +00:00
2022-10-13 19:57:44 +00:00
;;; Colors
; https://www.emacswiki.org/emacs/HexColour
2023-09-27 13:37:44 +00:00
( require 'cl )
( defun hexcolor-luminance ( color )
" Calculate the luminance of a color string (e.g. \" #ffaa00 \" , \" blue \" ).
This is 0.3 red + 0.59 green + 0.11 blue and always between 0 and 255. "
( let* ( ( values ( x-color-values color ) )
( r ( car values ) )
( g ( cadr values ) )
( b ( caddr values ) ) )
( floor ( + ( * .3 r ) ( * .59 g ) ( * .11 b ) ) 256 ) ) )
( defun hexcolor-add-to-font-lock ( )
( interactive )
( font-lock-add-keywords nil
` ( ( , ( concat " #[0-9a-fA-F] \\ {3 \\ }[0-9a-fA-F] \\ {3 \\ }? \\ | "
( regexp-opt ( x-defined-colors ) 'words ) )
( 0 ( let ( ( color ( match-string-no-properties 0 ) ) )
( put-text-property
( match-beginning 0 ) ( match-end 0 )
'face ` ( ( :foreground , ( if ( > 128.0 ( hexcolor-luminance color ) )
" white " " black " ) )
( :background , color ) ) ) ) ) ) ) ) )
( defvar hexcolor-keywords
' ( ( " #[abcdef[:digit:]] \\ {6 \\ } "
( 0 ( put-text-property ( match-beginning 0 )
( match-end 0 )
'face ( list :background
( match-string-no-properties 0 ) ) ) ) ) ) )
( defun hexcolor-add-to-font-lock ( )
( font-lock-add-keywords nil hexcolor-keywords ) )
( add-hook 'web-mode-hook 'hexcolor-add-to-font-lock )
2022-10-13 19:57:44 +00:00
( after! eshell
; https://stackoverflow.com/questions/63469203/eshell-and-color-output
( require 'xterm-color )
( add-hook 'eshell-before-prompt-hook
( lambda ( )
( setq xterm-color-preserve-properties t ) ) )
( add-to-list 'eshell-preoutput-filter-functions 'xterm-color-filter )
2022-11-06 20:33:00 +00:00
( setq eshell-output-filter-functions ( remove 'eshell-handle-ansi-color eshell-output-filter-functions )
eshell-scroll-to-bottom-on-output 'others
)
2022-10-13 19:57:44 +00:00
( setenv " TERM " " xterm-256color " )
)
2021-11-04 11:21:35 +00:00
;;; Mappings
2021-06-14 18:37:10 +00:00
( map! :map special-mode-map
2021-10-08 10:26:35 +00:00
" <tab> " 'other-window
" q " 'kill-this-buffer
:map nov-mode-map
2021-06-14 18:37:10 +00:00
" <tab> " 'other-window
" q " 'kill-this-buffer
2022-01-21 09:32:52 +00:00
:n " q " 'kill-this-buffer
2021-06-14 18:37:10 +00:00
:map image-mode-map
" <tab> " 'other-window
2023-12-01 16:41:05 +00:00
:n " D " 'doom/delete-this-file ; Follow by dired-find-file to select next?
2022-01-21 09:32:52 +00:00
:n " q " 'kill-this-buffer
2021-06-14 18:37:10 +00:00
:n " + " 'image-increase-size
2022-01-21 09:32:52 +00:00
:n " - " 'image-decrease-size
2022-09-19 22:04:59 +00:00
:map Info-mode-map
:desc " Go Home " :n " gu " 'Info-directory
:desc " Go Home " :n " gU " 'Info-directory
2023-04-27 12:28:04 +00:00
:desc " Search next " :n " , " 'Info-search-next
2022-01-21 09:32:52 +00:00
:map thumbs-mode-map
:n " q " 'thumbs-kill-buffer
)
2021-06-14 18:37:10 +00:00
2021-10-11 08:01:22 +00:00
( after! ivy
( ivy-define-key ivy-minibuffer-map ( kbd " <S-return> " ) 'ivy-immediate-done )
2022-03-24 10:32:12 +00:00
( ivy-define-key ivy-minibuffer-map ( kbd " C-h " ) 'ivy-backward-kill-word )
( ivy-define-key ivy-minibuffer-map ( kbd " C-l " ) 'ivy-partial-or-done )
2021-10-11 08:01:22 +00:00
)
2021-11-04 11:21:35 +00:00
;;; Dired
( use-package! dired
:config
2022-10-13 19:57:44 +00:00
; Make dired open certain file types externally when pressing RET on a file https://pastebin.com/8QWYpCA2
; Alternative: https://www.emacswiki.org/emacs/OpenWith
2021-06-14 18:37:10 +00:00
( defvar unsupported-mime-types
2021-09-16 12:25:30 +00:00
' ( " image/x-xcf " ) ) ; "application/zip"))
2021-06-14 18:37:10 +00:00
( load " subr-x " )
( defun get-mimetype ( filepath )
( string-trim
2021-11-04 11:21:35 +00:00
( shell-command-to-string ( concat " file -b --mime-type \" " filepath " \" " ) ) ) )
2021-06-14 18:37:10 +00:00
2021-07-29 10:03:31 +00:00
;;(let ((mime "image/x-xcf")) (msg mime))
2021-06-14 18:37:10 +00:00
( defun dired-find-file-dwim ( )
( interactive )
( let* ( ( file ( dired-get-filename nil t ) )
( mime ( get-mimetype file ) ) )
2022-06-27 20:21:33 +00:00
( if ( or ( string-suffix-p " .desktop " file ) ( string-prefix-p " audio " mime ) ( string-prefix-p " video " mime ) ( member mime unsupported-mime-types ) )
2021-06-14 18:37:10 +00:00
( call-process " xdg-open " nil 0 nil file )
( find-file file ) ) ) )
2023-12-01 16:41:05 +00:00
; maybe add +org/close-fold
2024-01-12 16:55:25 +00:00
( map! ; what about closing popup buffers first, like debugger-mode :n "<escape>" (lambda () (interactive) (if (eq major-mode 'org-mode) (condition-case nil (org-up-element) (error (dired-jump))) (dired-jump)))
2023-12-01 16:41:05 +00:00
:leader
" . " 'dired-jump )
2021-06-05 18:25:46 +00:00
( map! :map dired-mode-map
2021-06-14 18:37:10 +00:00
:n " RET " 'dired-find-file-dwim
2023-12-01 16:41:05 +00:00
:n " l " 'dired-find-file-dwim
:n " h " 'dired-up-directory
:n " ö " 'evil-ex-search-forward
2022-05-16 20:32:03 +00:00
:localleader
2021-10-11 08:01:22 +00:00
:desc " Compress/Extract " " c " 'dired-do-compress
2021-10-13 17:13:07 +00:00
:desc " Size information " " s "
2021-10-31 18:32:04 +00:00
( lambda ( ) ( interactive ) ( dired-do-shell-command " s " ) )
:desc " Lowercase files " " L "
( lambda ( ) ( interactive ) ( dired-do-shell-command " lowercase " ) )
2022-01-11 00:51:12 +00:00
:desc " Symlink to this " " l " 'dired-do-symlink
2021-10-13 17:13:07 +00:00
:desc " Open image-dired " " i "
( lambda ( ) ( interactive ) ( image-dired buffer-file-name ) )
2021-10-11 08:01:22 +00:00
:desc " Open image externally " " I " 'image-dired-dired-display-external
2021-11-02 13:55:24 +00:00
:desc " Org attach subtree " " a " 'org-attach-dired-to-subtree
2021-10-14 13:53:28 +00:00
:map wdired-mode-map
2022-01-23 16:43:56 +00:00
:n " RET " ( lambda ( ) ( interactive ) ( wdired-exit ) ( dired-find-file-dwim ) )
2021-06-14 18:37:10 +00:00
)
2022-08-04 08:36:37 +00:00
2021-11-23 21:22:06 +00:00
)
2022-01-21 09:32:52 +00:00
( use-package! dired-ranger
:disabled
2022-01-23 16:43:56 +00:00
:config
( ranger-override-dired-mode 0 )
( map! :map dired-mode-map
:n " r " 'ranger
:localleader
:desc " Start ranger " " r " 'ranger
:map ranger-mode-map
" i " 'dired-toggle-read-only
:n " r " 'ranger )
)
2022-01-21 09:32:52 +00:00
( use-package! image-dired
2022-08-28 20:34:08 +00:00
:init
2022-01-21 09:32:52 +00:00
( setq image-dired-external-viewer " gimp "
2022-08-28 20:34:08 +00:00
image-dired-thumb-size 400
2022-01-21 09:32:52 +00:00
image-dired-show-all-from-dir-max-files 300 )
2022-08-28 20:34:08 +00:00
:config
; TODO map image-dired-delete-marked
2022-01-21 09:32:52 +00:00
( add-to-list 'image-dired-cmd-create-thumbnail-options " -auto-orient " )
( add-to-list 'image-dired-cmd-create-temp-image-options " -auto-orient " )
( add-to-list 'image-dired-cmd-create-standard-thumbnail-options " -auto-orient " )
)
2021-11-23 21:22:06 +00:00
( use-package! diredfl
:config ( add-to-list 'diredfl-compressed-extensions " .nupkg " )
2021-10-31 18:32:04 +00:00
)
( after! dired-aux
( add-to-list 'dired-compress-file-suffixes ' ( " \\ .nupkg \\ ' " " " " unzip -o -d %o %i " ) )
2021-11-16 09:22:56 +00:00
( add-to-list 'dired-compress-file-suffixes ' ( " \\ .tar \\ ' " " " " tar xf %i " ) )
2021-10-31 18:32:04 +00:00
)
( after! all-the-icons
( add-to-list 'all-the-icons-extension-icon-alist ' ( " nupkg " all-the-icons-octicon " file-zip " :v-adjust 0.0 :face all-the-icons-lmaroon ) )
2021-06-05 18:25:46 +00:00
)
2021-11-04 11:21:35 +00:00
;;; evil
( add-hook 'visual-line-mode-hook ( lambda ( ) ( setq line-move-visual nil ) ) )
2022-02-11 07:57:32 +00:00
( use-package! evil
:ensure t
:init ( setq evil-respect-visual-line-mode nil )
2022-08-09 20:53:56 +00:00
:config
( evil-set-register ?i " yiwjgriw " ) ; copy current word and replace down
( after! evil-surround
( setq-default evil-embrace-evil-surround-keys ( -union evil-embrace-evil-surround-keys ' ( ?` ?~ ?\~ ) ) )
;; TILDE https://github.com/emacs-evil/evil-surround/issues/20#issuecomment-471516289
( defmacro define-and-bind-quoted-text-object ( name key start-regex end-regex )
( let ( ( inner-name ( make-symbol ( concat " evil-inner- " name ) ) )
( outer-name ( make-symbol ( concat " evil-a- " name ) ) ) )
` ( progn
( evil-define-text-object , inner-name ( count &optional beg end type )
( evil-select-paren , start-regex , end-regex beg end type count nil ) )
( evil-define-text-object , outer-name ( count &optional beg end type )
( evil-select-paren , start-regex , end-regex beg end type count t ) )
( define-key evil-inner-text-objects-map , key #' , inner-name )
( define-key evil-outer-text-objects-map , key #' , outer-name ) ) ) )
( define-and-bind-quoted-text-object " tilde " " ~ " " ~ " " ~ " )
)
2022-02-11 07:57:32 +00:00
)
2020-11-26 19:34:08 +00:00
2021-02-23 19:15:42 +00:00
( use-package! evil-replace-with-register ; gr
2022-01-23 16:43:56 +00:00
:ensure t
2021-02-23 19:15:42 +00:00
:init
( setq evil-replace-with-register-key ( kbd " gr " ) )
:config
2022-02-11 07:57:32 +00:00
( evil-replace-with-register-install )
2021-04-07 18:27:22 +00:00
( defun eval-paragraph ( )
( interactive )
( er/mark-paragraph )
( call-interactively '+eval:region )
)
( map! :n " gR " 'eval-paragraph
2022-11-06 21:39:45 +00:00
:n " g% " 'eval-defun
2021-04-07 18:27:22 +00:00
:v " gR " '+eval/region )
2021-02-23 19:15:42 +00:00
)
2021-04-07 18:27:22 +00:00
2021-02-25 11:24:50 +00:00
( use-package! evil-args ; https://github.com/wcsmith/evil-args
:config
;; bind evil-args text objects
( define-key evil-inner-text-objects-map " a " 'evil-inner-arg )
( define-key evil-outer-text-objects-map " a " 'evil-outer-arg )
;; bind evil-forward/backward-args
( define-key evil-normal-state-map " L " 'evil-forward-arg )
( define-key evil-normal-state-map " H " 'evil-backward-arg )
( define-key evil-motion-state-map " L " 'evil-forward-arg )
( define-key evil-motion-state-map " H " 'evil-backward-arg )
;; bind evil-jump-out-args
( define-key evil-normal-state-map " K " 'evil-jump-out-args )
)
2021-05-19 19:47:57 +00:00
2022-09-19 22:04:59 +00:00
;;; File Editing Modes
2023-11-04 18:04:03 +00:00
( setq initial-major-mode 'org-mode )
2024-01-12 16:55:25 +00:00
( add-to-list 'auto-mode-alist ' ( " /journal/ " . org-mode ) )
( add-to-list 'auto-mode-alist ' ( " \\ .jrnl \\ ' " . org-mode ) )
( add-to-list 'auto-mode-alist ' ( " \\ .el## " . emacs-lisp-mode ) )
( add-to-list 'auto-mode-alist ` ( , ( or ( getenv " CONFIG_SHELLS " ) " ~/.config/shell " ) . sh-mode ) )
( add-to-list 'auto-mode-alist ` ( , ( or ( getenv " CONFIG_ZSH " ) " ~/.config/zsh " ) . sh-mode ) )
( add-to-list 'auto-mode-alist ` ( " \\ .local/bin " . sh-mode ) )
;(add-to-list 'auto-mode-alist '("\\.twee\\'" . twee-chapbook-mode))
;(add-hook 'twee-chapbook-mode-hook 'twee-mode)
( add-to-list 'auto-mode-alist ` ( " \\ .scss.erb \\ ' " . scss-mode ) )
( add-to-list 'auto-mode-alist ' ( " \\ .html \\ ' " . web-mode ) )
( add-hook 'pdf-view-mode-hook 'auto-revert-mode )
2022-09-19 22:04:59 +00:00
( use-package! web-mode
2022-10-09 20:15:34 +00:00
:mode " \\ .html \\ ' "
2022-09-19 22:04:59 +00:00
:mode " \\ .phtml \\ ' "
:mode " \\ .tpl \\ .php \\ ' "
:mode " \\ .[agj]sp \\ ' "
:mode " \\ .as[cp]x \\ ' "
:mode " \\ .erb \\ ' "
:mode " \\ .mustache \\ ' "
:mode " \\ .djhtml \\ ' "
2022-10-13 19:57:44 +00:00
:config ( add-hook 'web-mode-hook 'rainbow-mode )
2022-09-19 22:04:59 +00:00
)
2021-06-19 19:26:23 +00:00
2023-03-14 22:33:06 +00:00
; https://discourse.doomemacs.org/t/disabling-ruby-typeprof/3197/3
2022-10-08 14:54:10 +00:00
( after! lsp-mode
( setq lsp-disabled-clients ' ( typeprof-ls ) ) )
2023-09-27 13:37:44 +00:00
( use-package eglot
:config
( add-hook 'haskell-mode-hook #' eglot-ensure )
;; Optionally add keybindings to some common functions:
:bind ( ( :map eglot-mode-map
( " C-c C-e r " . eglot-rename )
( " C-c C-e l " . flymake-show-buffer-diagnostics )
( " C-c C-e p " . flymake-show-project-diagnostics )
( " C-c C-e C " . eglot-show-workspace-configuration )
( " C-c C-e R " . eglot-reconnect )
( " C-c C-e S " . eglot-shutdown )
( " C-c C-e A " . eglot-shutdown-all )
( " C-c C-e a " . eglot-code-actions )
( " C-c C-e f " . eglot-format ) ) ) )
;; Optional: Show/pick completions on tab, sane max height:
( setq tab-always-indent 'complete
completions-max-height 20
completion-auto-select 'second-tab )
2022-09-18 11:47:49 +00:00
( use-package! adoc-mode ; Asciidoc, a md alternative
:mode " \\ .adoc \\ ' "
)
2021-02-23 19:15:42 +00:00
( use-package! plantuml-mode ; Diagrams
2022-05-31 23:01:20 +00:00
:mode " \\ .puml \\ ' "
2021-02-23 19:15:42 +00:00
:config
2022-02-11 07:57:32 +00:00
( set-file-template! 'plantuml-mode :mode 'plantuml-mode )
2021-03-26 18:02:37 +00:00
( setq plantuml-executable-path " nostderr "
plantuml-executable-args ' ( " plantuml " " -headless " )
2021-05-02 17:38:09 +00:00
plantuml-default-exec-mode 'jar
2021-03-26 18:02:37 +00:00
plantuml-jar-path " /usr/share/java/plantuml/plantuml.jar "
org-plantuml-jar-path plantuml-jar-path
plantuml-java-args ' ( " -Djava.awt.headless=true " " -jar " )
2022-04-27 23:48:22 +00:00
plantuml-indent-level 4
2021-03-26 18:02:37 +00:00
)
( after! org
2022-11-29 22:20:54 +00:00
( org-babel-do-load-languages 'org-babel-load-languages
' ( ( plantuml . t ) ) )
2021-02-24 11:19:09 +00:00
)
2022-11-29 22:20:54 +00:00
( add-hook 'plantuml-mode-hook
( lambda ( ) ( setq-local compile-command ( format " plantuml %s " ( shell-quote-argument buffer-file-name ) ) ) ) )
2021-02-23 19:15:42 +00:00
)
2021-09-16 12:25:30 +00:00
2022-09-22 07:57:37 +00:00
( use-package vc-fossil
;; Keep from loading unnecessarily at startup.
:defer t
;; This allows VC to load vc-fossil when needed.
:init ( add-to-list 'vc-handled-backends 'Fossil ) )
2021-08-09 22:34:14 +00:00
( use-package! chordpro-mode
2023-03-13 14:34:44 +00:00
:mode ( " \\ .cho \\ ' " . chordpro-mode )
2021-09-16 12:25:30 +00:00
:config
2022-09-18 11:47:49 +00:00
( set-file-template! 'chordpro-mode :mode 'chordpro-mode ) ; TODO broken
2021-09-16 12:25:30 +00:00
( define-key chordpro-mode-map ( kbd " C-c C-c " ) 'chordpro-insert-chord )
2021-08-09 22:34:14 +00:00
)
2023-03-13 14:34:44 +00:00
2021-05-19 19:47:57 +00:00
( use-package! lilypond-mode
2021-06-03 10:08:43 +00:00
:mode ( " \\ .ly \\ ' " . LilyPond-mode )
2021-05-19 19:47:57 +00:00
:config
2023-04-27 12:28:04 +00:00
( map! :map rdictcc-buffer-mode-map
:leader
" hi " 'LilyPond-info )
2022-05-31 23:01:20 +00:00
( set-file-template! 'LilyPond-mode :mode 'LilyPond-mode )
2021-05-19 19:47:57 +00:00
( setq LilyPond-pdf-command " xdg-open " )
( add-hook 'LilyPond-mode-hook 'turn-on-font-lock )
2022-09-27 20:09:19 +00:00
( defun xf/live-preview ( )
( interactive )
( setq-local compile-command ( format " lilypond %s " ( shell-quote-argument buffer-file-name ) ) )
; TODO this does not quite work
( message mode-name )
( message buffer-file-name )
( message " %s " ( length ( window-list ) ) )
( unless ( > ( length ( window-list ) ) 1 )
( split-window-horizontally )
( find-file ( concat ( file-name-sans-extension buffer-file-name ) " .pdf " ) )
( find-file-other-window ( concat ( file-name-sans-extension buffer-file-name ) " .ly " ) )
)
)
( add-hook 'LilyPond-mode-hook 'xf/live-preview )
2022-05-31 23:01:20 +00:00
; TODO (require 'lyqi nil t)
2021-02-23 19:15:42 +00:00
)
2021-03-26 18:02:37 +00:00
2022-05-12 09:33:11 +00:00
( setq js-indent-level 2 )
2021-11-04 11:21:35 +00:00
( after! json-mode
( defconst json-mode-comments-re ( rx ( group " // " ( zero-or-more nonl ) line-end ) ) )
( push ' ( json-mode-comments-re 1 font-lock-comment-face ) json-font-lock-keywords-1 )
)
;;; Misc package config
2021-09-27 09:18:37 +00:00
2021-12-10 12:29:31 +00:00
( setq pdf-misc-print-programm " /usr/bin/lpr " )
2022-08-29 22:06:26 +00:00
( add-hook 'pdf-view-mode-hook 'auto-revert-mode )
( setq auto-revert-interval 2 )
2021-11-04 11:21:35 +00:00
( setq eww-search-prefix " https://safe.duckduckgo.com/html/?q= " )
2023-09-27 13:37:44 +00:00
;; Customize word-wrap to break at commas
;; https://emacs.stackexchange.com/questions/19027/how-to-wrap-line-at-some-characters-other-than-space/71342#71342
( setq-default word-wrap t )
( setq-default word-wrap-by-category t )
( modify-category-entry ?, ?| )
2022-01-11 12:22:00 +00:00
( use-package! activity-watch-mode
:config
( activity-watch--send-heartbeat ( activity-watch--create-heartbeat ( current-time ) )
:on-success ( lambda ( &rest _ ) ( global-activity-watch-mode ) )
:on-error ( lambda ( &rest _ ) ( message " " ) ) )
)
2021-11-04 11:21:35 +00:00
2022-09-08 11:29:21 +00:00
( use-package! rdictcc
:if ( locate-library " rdictcc " )
:bind ( ( " C-c t " . 'rdictcc-translate-word-at-point )
( " C-c T " . 'rdictcc-translate-word ) )
:config
2022-09-09 19:58:38 +00:00
;; TODO what happened to q?
2022-09-08 11:29:21 +00:00
( map! :leader " T " 'rdictcc-translate-word
:map rdictcc-buffer-mode-map
2022-09-09 19:58:38 +00:00
:n " q " 'kill-this-buffer
2022-09-08 11:29:21 +00:00
" q " 'kill-this-buffer
2022-09-09 19:58:38 +00:00
)
2022-09-08 11:29:21 +00:00
( setq rdictcc-program-args " --directory $XDG_DATA_HOME/dictcc " )
)
2021-11-04 11:21:35 +00:00
( after! tramp
( setq tramp-default-method " scpx " )
( add-to-list 'tramp-methods
' ( " yadm "
( tramp-login-program " yadm " )
( tramp-login-args ( ( " enter " ) ) )
( tramp-login-env ( ( " SHELL " ) ( " /bin/sh " ) ) )
( tramp-remote-shell " /bin/sh " )
( tramp-remote-shell-args ( " -c " ) ) ) )
( map! :leader
:desc " Yadm status " " gT " ( lambda ( ) ( interactive ) ( magit-status " /yadm:: " ) ) )
)
2022-01-05 17:38:17 +00:00
( use-package! magit
:defer t
2022-09-16 12:55:11 +00:00
:config
2023-03-14 22:33:06 +00:00
( setq git-commit-summary-max-length 60
magit-clone-set-remote.pushDefault 't
2022-09-16 12:55:11 +00:00
magit-clone-default-directory ( expand-file-name " 1-projects " user-data-dir )
magit-blame--style ( car magit-blame-styles ) )
2022-01-05 17:38:17 +00:00
( setq magit-clone-name-alist
' ( ( " \\ ` \\ (?:github: \\ |gh: \\ )? \\ ([^:]+ \\ ) \\ ' " " github.com " " user.name " )
( " \\ ` \\ (?:gitlab: \\ |gl: \\ ) \\ ([^:]+ \\ ) \\ ' " " gitlab.com " " user.name " )
( " \\ ` \\ (?:gitea: \\ |x: \\ ) \\ ([^:]+ \\ ) \\ ' " " git.jfischer.org " " user.name " ) ) )
)
2021-11-04 11:21:35 +00:00
( use-package! direnv ; nix-shell stuffs
:defer t
:config
( setq direnv-always-show-summary nil )
( direnv-mode )
)
2022-09-19 22:04:59 +00:00
( use-package! nov
:mode ( " \\ .epub \\ ' " . nov-mode )
)
2022-05-31 23:01:20 +00:00
( use-package! recompile-on-save )
2021-11-04 11:21:35 +00:00
;; https://emacs.stackexchange.com/questions/64532/emms-and-mpd-configuration
2022-01-21 09:32:52 +00:00
( use-package! emms
2021-11-04 11:21:35 +00:00
:disabled
:config
( require 'emms-setup )
( require 'emms-player-mpd )
( emms-all ) ; don't change this to values you see on stackoverflow questions if you expect emms to work
( setq emms-player-list ' ( emms-player-mpd ) )
( add-to-list 'emms-info-functions 'emms-info-mpd )
( add-to-list 'emms-player-list 'emms-player-mpd )
( setq emms-source-file-default-directory ( getenv " MUSIC " ) )
;; Socket is not supported
( setq emms-player-mpd-server-name " localhost " )
( setq emms-player-mpd-server-port " 6600 " )
2022-01-05 17:38:17 +00:00
( setq emms-player-mpd-music-directory ( expand-file-name " music " user-data-dir ) )
2021-11-04 11:21:35 +00:00
)
2022-08-04 08:36:37 +00:00
( use-package! mu4e
:defer 3
:config
( setq mu4e-change-filenames-when-moving t ; avoid sync conflicts
mu4e-update-interval ( * 10 60 ) ; check mail 10 minutes
mu4e-compose-format-flowed t ; re-flow mail so it's not hard wrapped
mu4e-get-mail-command " offlineimap -o "
mu4e-maildir " ~/.local/share/mail " )
( setq mu4e-drafts-folder " /mail/Drafts "
mu4e-sent-folder " /mail/Sent "
mu4e-refile-folder " /mail/All Mail "
mu4e-trash-folder " /mail/Trash " )
( setq mu4e-maildir-shortcuts
' ( ( " /mail/inbox " . ?i )
( " /mail/Sent " . ?s )
( " /mail/Trash " . ?t )
( " /mail/Drafts " . ?d )
( " /mail/All Mail " . ?a ) ) )
( setq message-send-mail-function 'smtpmail-send-it
auth-sources ' ( " ~/.authinfo " ) ;need to use gpg version but only local smtp stored for now
smtpmail-smtp-server " 127.0.0.1 "
smtpmail-smtp-service 1025
smtpmail-stream-type 'ssl ) )
2023-11-04 18:04:03 +00:00
( after! spell-fu
( remove-hook 'text-mode-hook #' spell-fu-mode )
)
( setq ispell-personal-dictionary ( expand-file-name " personal-dictionary " custom-emacs-data-dir ) )
( with-eval-after-load " ispell "
( setq ispell-program-name " hunspell " )
( setq hunspell-default-dict " en_US " )
( setq ispell-dictionary " en_US,de_DE " )
;; ispell-set-spellchecker-params has to be called
;; before ispell-hunspell-add-multi-dic will work
( ispell-set-spellchecker-params )
( ispell-hunspell-add-multi-dic ispell-dictionary )
)
2021-05-19 19:47:57 +00:00
2020-10-07 19:41:29 +00:00
;; Here are some additional functions/macros that could help you configure Doom:
;;
;; - `load!' for loading external *.el files relative to this one
;; - `use-package!' for configuring packages
;; - `after!' for running code after a package has loaded
;; - `add-load-path!' for adding directories to the `load-path', relative to
;; this file. Emacs searches the `load-path' when you load packages with
;; `require' or `use-package'.
;; - `map!' for binding new keys
;;
;; To get information about any of these functions/macros, move the cursor over
;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
;; This will open documentation for it, including demos of how they are used.
;;
;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
;; they are implemented.