1 ;;; init.el --- bandali's emacs configuration -*- lexical-binding: t -*-
3 ;; Copyright (C) 2018-2020 Amin Bandali <bandali@gnu.org>
5 ;; This program is free software: you can redistribute it and/or modify
6 ;; it under the terms of the GNU General Public License as published by
7 ;; the Free Software Foundation, either version 3 of the License, or
8 ;; (at your option) any later version.
10 ;; This program is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ;; GNU General Public License for more details.
15 ;; You should have received a copy of the GNU General Public License
16 ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
20 ;; GNU Emacs configuration of Amin Bandali, computer scientist,
21 ;; Free Software activist, and GNU maintainer & webmaster. Packages
22 ;; are installed through using Borg for a fully reproducible setup.
24 ;; Over the years, I've taken inspiration from configurations of many
25 ;; great people. Some that I can remember off the top of my head are:
27 ;; - https://github.com/dieggsy/dotfiles
28 ;; - https://github.com/dakra/dmacs
29 ;; - http://pages.sachachua.com/.emacs.d/Sacha.html
30 ;; - https://github.com/dakrone/eos
31 ;; - http://doc.rix.si/cce/cce.html
32 ;; - https://github.com/jwiegley/dot-emacs
33 ;; - https://github.com/wasamasa/dotemacs
34 ;; - https://github.com/hlissner/doom-emacs
38 ;;; Emacs initialization
40 (defvar b
/before-user-init-time
(current-time)
41 "Value of `current-time' when Emacs begins loading `user-init-file'.")
42 (defvar b
/emacs-initialized nil
43 "Whether Emacs has been initialized.")
45 (when (not (bound-and-true-p b
/emacs-initialized
))
46 (message "Loading Emacs...done (%.3fs)"
47 (float-time (time-subtract b
/before-user-init-time
50 ;; temporarily increase `gc-cons-threshhold' and `gc-cons-percentage'
51 ;; during startup to reduce garbage collection frequency. clearing
52 ;; `file-name-handler-alist' seems to help reduce startup time too.
53 (defvar b
/gc-cons-threshold gc-cons-threshold
)
54 (defvar b
/gc-cons-percentage gc-cons-percentage
)
55 (defvar b
/file-name-handler-alist file-name-handler-alist
)
56 (setq gc-cons-threshold
(* 30 1024 1024) ; 30 MiB
57 gc-cons-percentage
0.6
58 file-name-handler-alist nil
59 ;; sidesteps a bug when profiling with esup
60 esup-child-profile-require-level
0)
62 ;; set them back to their defaults once we're done initializing
64 "My post-initialize function, run after loading `user-init-file'."
65 (setq b
/emacs-initialized t
66 gc-cons-threshold b
/gc-cons-threshold
67 gc-cons-percentage b
/gc-cons-percentage
68 file-name-handler-alist b
/file-name-handler-alist
)
69 (when (featurep 'exwm-workspace
)
70 (with-eval-after-load 'exwm-workspace
77 "[%s]" (number-to-string
78 exwm-workspace-current-index
)))))))))
79 (add-hook 'after-init-hook
#'b
/post-init
)
81 ;; increase number of lines kept in *Messages* log
82 (setq message-log-max
20000)
84 ;; optionally, uncomment to supress some byte-compiler warnings
85 ;; (see C-h v byte-compile-warnings RET for more info)
86 ;; (setq byte-compile-warnings
87 ;; '(not free-vars unresolved noruntime lexical make-local))
92 (setq user-full-name
"Amin Bandali"
93 user-mail-address
"bandali@gnu.org")
96 ;;; Package management
99 (add-to-list 'load-path
100 (expand-file-name "lib/borg" user-emacs-directory
))
103 (setq borg-rewrite-urls-alist
104 '(("git@github.com:" .
"https://github.com/")
105 ("git@gitlab.com:" .
"https://gitlab.com/"))))
107 (defmacro csetq
(&rest args
)
108 "Set the value of user option VAR to VALUE.
110 More generally, you can use multiple variables and values, as in
111 (csetq VAR VALUE VAR VALUE...)
112 This sets each user option VAR's value to the corresponding VALUE.
114 \(fn [VAR VALUE]...)"
115 (declare (debug setq
))
117 ,@(cl-loop for
(var value
) on args by
'cddr
119 `(funcall (or (get ',var
'custom-set
) #'set-default
)
125 ;; keep ~/.emacs.d clean
126 (require 'no-littering
)
127 (defalias 'b
/etc
'no-littering-expand-etc-file-name
)
128 (defalias 'b
/var
'no-littering-expand-var-file-name
)
130 (require 'auto-compile
)
131 (auto-compile-on-load-mode)
132 (auto-compile-on-save-mode)
133 (setq auto-compile-display-buffer nil
)
134 (setq auto-compile-mode-line-counter t
)
135 (setq auto-compile-source-recreate-deletes-dest t
)
136 (setq auto-compile-toggle-deletes-nonlib-dest t
)
137 (setq auto-compile-update-autoloads t
)
139 ;; separate custom file (don't want it mixing with init.el)
140 (with-eval-after-load 'custom
141 (setq custom-file
(b/etc
"custom.el"))
142 (when (file-exists-p custom-file
)
144 ;; while at it, treat themes as safe
145 (setf custom-safe-themes t
)
146 ;; only one custom theme at a time
148 (defadvice load-theme
(before clear-previous-themes activate
)
149 "Clear existing theme settings instead of layering them"
150 (mapc #'disable-theme custom-enabled-themes
))))
152 ;; load the secrets file if it exists, otherwise show a warning
155 (load (b/etc
"secrets"))))
157 ;; start up emacs server. see
158 ;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html#Emacs-Server
159 (run-with-idle-timer 0.5 nil
#'require
'server
)
160 (with-eval-after-load 'server
161 (declare-function server-edit
"server")
162 (bind-key "C-c F D" 'server-edit
)
163 (declare-function server-running-p
"server")
164 (or (server-running-p) (server-mode)))
169 ;;;; C-level customizations
173 enable-recursive-minibuffers t
174 resize-mini-windows t
175 ;; more useful frame titles
176 ;; frame-title-format '("" invocation-name " - "
178 ;; (if (buffer-file-name)
179 ;; (abbreviate-file-name (buffer-file-name))
181 ;; i don't feel like jumping out of my chair every now and again; so
182 ;; don't BEEP! at me, emacs
183 ring-bell-function
'ignore
186 ;; scroll-conservatively 10000
188 scroll-conservatively
101
189 scroll-preserve-screen-position
1
190 ;; focus follows mouse
191 mouse-autoselect-window t
)
194 ;; always use space for indentation
197 ;; case-sensitive search (and `dabbrev-expand')
198 ;; case-fold-search nil
202 (set-fontset-font t
'arabic
"Vazir")
206 (dolist (ft (fontset-list))
210 (font-spec :name
"Source Code Pro" :size
14))
214 (font-spec :name
"DejaVu Sans Mono")
221 ;; :name "Symbola monospacified for DejaVu Sans Mono")
227 ;; (font-spec :name "DejaVu Sans Mono")
233 (font-spec :name
"DejaVu Sans Mono" :size
14)
237 ;;;; Elisp-level customizations
240 ;; don't need to see the startup echo area message
241 (advice-add #'display-startup-echo-area-message
:override
#'ignore
)
243 ;; i want *scratch* as my startup buffer
244 initial-buffer-choice t
245 ;; i don't need the default hint
246 initial-scratch-message nil
247 ;; use customizable text-mode as major mode for *scratch*
248 ;; (initial-major-mode 'text-mode)
249 ;; inhibit buffer list when more than 2 files are loaded
250 inhibit-startup-buffer-menu t
251 ;; don't need to see the startup screen or echo area message
252 inhibit-startup-screen t
253 inhibit-startup-echo-area-message user-login-name
)
257 ;; backups (C-h v make-backup-files RET)
260 delete-old-versions t
262 auto-save-file-name-transforms
`((".*" ,(b/var
"auto-save/") t
))
263 ;; insert newline at the end of files
264 require-final-newline t
265 ;; open read-only file buffers in view-mode
266 ;; (enables niceties like `q' for quit)
270 ;; disable disabled commands
271 (csetq disabled-command-function nil
)
273 ;; lazy-person-friendly yes/no prompts
274 (defalias 'yes-or-no-p
#'y-or-n-p
)
276 ;; enable automatic reloading of changed buffers and files
278 (csetq auto-revert-verbose nil
279 global-auto-revert-non-file-buffers nil
)
280 (require 'autorevert
)
281 (global-auto-revert-mode 1))
283 ;; time and battery in mode-line
285 display-time-default-load-average nil
286 display-time-format
" %a %b %-e %-l:%M%P"
287 display-time-mail-icon
'(image :type xpm
288 :file
"gnus/gnus-pointer.xpm"
290 display-time-use-mail-icon t
)
294 (csetq battery-mode-line-format
"%p%% %t")
296 (display-battery-mode)
300 ;; (fringe-mode '(3 . 1))
304 ;; enable winner-mode (C-h f winner-mode RET)
307 (with-eval-after-load 'compile
308 ;; don't display *compilation* buffer on success. based on
309 ;; https://stackoverflow.com/a/17788551, with changes to use `cl-letf'
310 ;; instead of the now obsolete `flet'.
311 (defun b/compilation-finish-function
(buffer outstr
)
312 (unless (string-match "finished" outstr
)
313 (switch-to-buffer-other-window buffer
))
316 (setq compilation-finish-functions
#'b
/compilation-finish-function
)
320 (defadvice compilation-start
321 (around inhibit-display
322 (command &optional mode name-function highlight-regexp
))
323 (if (not (string-match "^\\(find\\|grep\\)" command
))
324 (cl-letf (((symbol-function 'display-buffer
) #'ignore
))
325 (save-window-excursion ad-do-it
))
327 (ad-activate 'compilation-start
))
331 ;; allow scrolling in Isearch
332 isearch-allow-scroll t
333 ;; search for non-ASCII characters: i’d like non-ASCII characters such
334 ;; as ‘’“”«»‹›áⓐ𝒶 to be selected when i search for their ASCII
335 ;; counterpart. shoutout to
336 ;; http://endlessparentheses.com/new-in-emacs-25-1-easily-search-non-ascii-characters.html
337 search-default-mode
#'char-fold-to-regexp
)
340 ;; uncomment to extend the above behaviour to query-replace
341 ;; (csetq replace-char-fold t)
344 (global-set-key (kbd "C-x v C-=") #'vc-ediff
)
346 (with-eval-after-load 'vc-git
347 (csetq vc-git-print-log-follow t
))
349 (csetq ediff-window-setup-function
'ediff-setup-windows-plain
350 ediff-split-window-function
'split-window-horizontally
)
351 (with-eval-after-load 'ediff
352 (add-hook 'ediff-after-quit-hook-internal
#'winner-undo
))
356 ;; gentler font resizing
357 text-scale-mode-step
1.05)
359 (run-with-idle-timer 0.4 nil
#'require
'mwheel
)
360 (csetq mouse-wheel-scroll-amount
'(1 ((shift) .
1)) ; one line at a time
361 mouse-wheel-progressive-speed nil
; don't accelerate scrolling
362 mouse-wheel-follow-mouse t
) ; scroll window under mouse
364 (run-with-idle-timer 0.4 nil
#'require
'pixel-scroll
)
365 (with-eval-after-load 'pixel-scroll
366 (pixel-scroll-mode 1))
370 epg-gpg-program
(executable-find "gpg")
371 ;; ask for GPG passphrase in minibuffer
372 ;; this will fail if gpg>=2.1 is not available
373 epg-pinentry-mode
'loopback
)
375 ;; (require 'pinentry)
376 ;; workaround for systemd-based distros:
377 ;; (setq pinentry--socket-dir server-socket-dir)
382 auth-sources
'("~/.authinfo.gpg")
383 authinfo-hidden
(regexp-opt '("password" "client-secret" "token")))
386 ;;; General key bindings
388 (global-set-key (kbd "C-a") #'b
/move-indentation-or-beginning-of-line
)
389 (global-set-key (kbd "C-c a i") #'ielm
)
390 (global-set-key (kbd "C-c d") #'b
/duplicate-line-or-region
)
391 (global-set-key (kbd "C-S-j") #'b
/join-line-top
)
392 (global-set-key (kbd "C-c x") #'execute-extended-command
)
394 ;; evaling and macro-expanding
395 (global-set-key (kbd "C-c e b") #'eval-buffer
)
396 (global-set-key (kbd "C-c e e") #'eval-last-sexp
)
397 (global-set-key (kbd "C-c e p") #'pp-macroexpand-last-sexp
)
398 (global-set-key (kbd "C-c e r") #'eval-region
)
401 (global-set-key (kbd "C-c e i") #'emacs-init-time
)
402 (global-set-key (kbd "C-c e u") #'emacs-uptime
)
403 (global-set-key (kbd "C-c e v") #'emacs-version
)
406 (global-set-key (kbd "C-c f .") #'find-file
)
407 (global-set-key (kbd "C-c f d") #'find-name-dired
)
408 (global-set-key (kbd "C-c f l") #'find-library
)
411 (global-set-key (kbd "C-c F m") #'make-frame-command
)
412 (global-set-key (kbd "C-c F d") #'delete-frame
)
415 (global-set-key (kbd "C-S-h C") #'describe-char
)
416 (global-set-key (kbd "C-S-h F") #'describe-face
)
418 ;; (global-set-key (kbd "C-x k") #'b/kill-current-buffer)
419 ;; (global-set-key (kbd "C-x K") #'kill-buffer)
420 ;; (global-set-key (kbd "C-x s") #'save-buffer)
421 ;; (global-set-key (kbd "C-x S") #'save-some-buffers)
423 (define-key emacs-lisp-mode-map
(kbd "<C-return>") #'b
/add-elisp-section
)
425 (when (display-graphic-p)
426 (global-unset-key (kbd "C-z")))
429 ;;; Essential packages
431 ;; (require 'bandali-exwm)
433 (require 'bandali-org
)
435 (require 'bandali-theme
)
437 ;; *the* right way to do git
438 (with-eval-after-load 'magit
439 (declare-function magit-add-section-hook
"magit-section"
440 (hook function
&optional at append local
))
441 (magit-add-section-hook 'magit-status-sections-hook
442 'magit-insert-modules
443 'magit-insert-stashes
445 ;; (magit-add-section-hook 'magit-status-sections-hook
446 ;; 'magit-insert-ignored-files
447 ;; 'magit-insert-untracked-files
449 (declare-function magit-display-buffer-fullframe-status-v1
450 "magit-mode" (buffer))
452 magit-diff-refine-hunk t
453 magit-repository-directories
'(("~/.emacs.d/" .
0)
455 ;; magit-completing-read-function 'magit-ido-completing-read
456 magit-display-buffer-function
457 #'magit-display-buffer-fullframe-status-v1
)
458 (nconc magit-section-initial-visibility-alist
459 '(([unpulled status
] . show
)
460 ([unpushed status
] . show
)))
461 (custom-set-faces '(magit-diff-file-heading ((t (:weight normal
)))))
463 (with-eval-after-load 'magit-extras
465 magit-pop-revision-stack-format
466 (pcase-let ((`(,pt
,_eob
,index-regexp
)
467 (default-value 'magit-pop-revision-stack-format
)))
468 `(,pt
"[%N: %h]: %ci\n %s
469 https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=%H"
471 ;; global key bindings
472 (global-set-key (kbd "C-x g") #'magit-status
)
473 (global-set-key (kbd "C-c g b") #'magit-blame-addition
)
474 (global-set-key (kbd "C-c g l") #'magit-log-buffer-file
)
475 (global-set-key (kbd "C-c g y") #'magit-pop-revision-stack
)
477 ;; recently opened files
478 (run-with-idle-timer 0.2 nil
#'require
'recentf
)
479 (with-eval-after-load 'recentf
480 (csetq recentf-max-saved-items
2000)
481 (add-to-list 'recentf-keep
#'file-remote-p
)
484 ;; needed for history for counsel
485 (run-with-idle-timer 0.3 nil
#'require
'amx
)
486 (with-eval-after-load 'amx
489 ;; (require 'bandali-ido)
490 (require 'bandali-ivy
)
492 (require 'bandali-eshell
)
493 ;; (require 'bandali-multi-term)
495 (require 'bandali-ibuffer
)
498 ;; (with-eval-after-load 'outline
499 ;; (when (featurep 'which-key)
500 ;; (which-key-add-key-based-replacements
503 ;; (define-key outline-minor-mode-map (kbd "<s-tab>")
504 ;; #'outline-toggle-children)
505 ;; (define-key outline-minor-mode-map (kbd "M-p")
506 ;; #'outline-previous-visible-heading)
507 ;; (define-key outline-minor-mode-map (kbd "M-n")
508 ;; #'outline-next-visible-heading)
509 ;; (defvar b/outline-prefix-map)
510 ;; (define-prefix-command 'b/outline-prefix-map)
511 ;; (define-key outline-minor-mode-map (kbd "s-O")
512 ;; 'b/outline-prefix-map)
513 ;; (define-key b/outline-prefix-map (kbd "TAB")
514 ;; #'outline-toggle-children)
515 ;; (define-key b/outline-prefix-map (kbd "a")
516 ;; #'outline-hide-body)
517 ;; (define-key b/outline-prefix-map (kbd "H")
518 ;; #'outline-hide-body)
519 ;; (define-key b/outline-prefix-map (kbd "S")
520 ;; #'outline-show-all)
521 ;; (define-key b/outline-prefix-map (kbd "h")
522 ;; #'outline-hide-subtree)
523 ;; (define-key b/outline-prefix-map (kbd "s")
524 ;; #'outline-show-subtree))
525 ;; (add-hook 'prog-mode-hook #'outline-minor-mode)
527 (require 'bandali-dired
)
529 (with-eval-after-load 'help
530 (temp-buffer-resize-mode)
531 (csetq help-window-select t
)
533 ;; local key bindings
534 (define-key help-mode-map
(kbd "p") #'backward-button
)
535 (define-key help-mode-map
(kbd "n") #'forward-button
))
537 (with-eval-after-load 'tramp
538 (add-to-list 'tramp-default-proxies-alist
'(nil "\\`root\\'" "/ssh:%h:"))
539 (add-to-list 'tramp-default-proxies-alist
'("localhost" nil nil
))
540 (add-to-list 'tramp-default-proxies-alist
541 (list (regexp-quote (system-name)) nil nil
)))
543 (with-eval-after-load 'doc-view
544 (define-key doc-view-mode-map
(kbd "M-RET") #'image-previous-line
))
546 (csetq shr-max-width
80)
548 ;; Email (with Gnus, message, and EBDB)
549 (require 'bandali-gnus
)
550 (with-eval-after-load 'sendmail
551 (csetq sendmail-program
(executable-find "msmtp")
552 ;; message-sendmail-extra-arguments '("-v" "-d")
553 mail-specify-envelope-from t
554 mail-envelope-from
'header
))
555 (require 'bandali-message
)
556 (require 'bandali-ebdb
)
558 ;; IRC (with ERC and ZNC)
559 (require 'bandali-erc
)
561 (with-eval-after-load 'scpaste
562 (csetq scpaste-http-destination
"https://p.bndl.org"
563 scpaste-scp-destination
"p:~"))
568 ;; display Lisp objects at point in the echo area
569 (when (version< "25" emacs-version
)
570 (with-eval-after-load 'eldoc
571 (global-eldoc-mode)))
573 ;; highlight matching parens
577 ;; (require 'elec-pair)
578 ;; (electric-pair-mode)
581 ;; Save what I copy into clipboard from other applications into Emacs'
582 ;; kill-ring, which would allow me to still be able to easily access
583 ;; it in case I kill (cut or copy) something else inside Emacs before
584 ;; yanking (pasting) what I'd originally intended to.
585 save-interprogram-paste-before-kill t
)
586 (with-eval-after-load 'simple
587 (column-number-mode))
589 ;; save minibuffer history
592 (add-to-list 'savehist-additional-variables
'kill-ring
)
594 ;; automatically save place in files
595 (when (version< "25" emacs-version
)
598 (defun indicate-buffer-boundaries-left ()
599 (csetq indicate-buffer-boundaries
'left
))
600 (with-eval-after-load 'prog-mode
601 (global-prettify-symbols-mode))
602 (add-hook 'prog-mode-hook
#'indicate-buffer-boundaries-left
)
604 (define-key text-mode-map
(kbd "C-*") #'b
/insert-asterism
)
605 (add-hook 'text-mode-hook
#'indicate-buffer-boundaries-left
)
606 (add-hook 'text-mode-hook
#'flyspell-mode
)
608 (add-to-list 'auto-mode-alist
'("\\.*rc$" . conf-mode
))
610 (add-to-list 'auto-mode-alist
'("\\.bashrc$" . sh-mode
))
613 ;; (run-with-idle-timer 0.6 nil #'require 'flycheck)
614 ;; (with-eval-after-load 'flycheck
616 ;; ;; Use the load-path from running Emacs when checking elisp files
617 ;; flycheck-emacs-lisp-load-path 'inherit
618 ;; ;; Only flycheck when I actually save the buffer
619 ;; flycheck-check-syntax-automatically '(mode-enabled save)
620 ;; flycheck-mode-line-prefix "flyc"))
621 ;; (define-key flycheck-mode-map (kbd "M-P") #'flycheck-previous-error)
622 ;; (define-key flycheck-mode-map (kbd "M-N") #'flycheck-next-error)
623 ;; (add-hook 'prog-mode-hook #'flycheck-mode)
626 ;; http://endlessparentheses.com/ispell-and-apostrophes.html
627 ;; (run-with-idle-timer 0.6 nil #'require 'ispell)
628 ;; (with-eval-after-load 'ispell
629 ;; ;; ’ can be part of a word
630 ;; (csetq ispell-local-dictionary-alist
631 ;; `((nil "[[:alpha:]]" "[^[:alpha:]]"
632 ;; "['\x2019]" nil ("-B") nil utf-8))
633 ;; ispell-program-name (executable-find "hunspell"))
634 ;; ;; don't send ’ to the subprocess
635 ;; (defun endless/replace-apostrophe (args)
636 ;; (cons (replace-regexp-in-string
637 ;; "’" "'" (car args))
639 ;; (advice-add #'ispell-send-string :filter-args
640 ;; #'endless/replace-apostrophe)
641 ;; ;; convert ' back to ’ from the subprocess
642 ;; (defun endless/replace-quote (args)
643 ;; (if (not (derived-mode-p 'org-mode))
645 ;; (cons (replace-regexp-in-string
646 ;; "'" "’" (car args))
648 ;; (advice-add #'ispell-parse-output :filter-args
649 ;; #'endless/replace-quote))
651 (add-hook 'text-mode-hook
#'abbrev-mode
)
654 ;;; Programming modes
656 (with-eval-after-load 'lisp-mode
657 (defun indent-spaces-mode ()
658 (setq indent-tabs-mode nil
))
659 (add-hook 'lisp-interaction-mode-hook
#'indent-spaces-mode
))
661 (with-eval-after-load 'alloy-mode
662 (csetq alloy-basic-offset
2)
663 ;; (defun b/alloy-simple-indent (start end)
665 ;; ;; (if (region-active-p)
666 ;; ;; (indent-rigidly start end alloy-basic-offset)
668 ;; ;; (indent-rigidly (line-beginning-position)
669 ;; ;; (line-end-position)
670 ;; ;; alloy-basic-offset)))
671 ;; (indent-to (+ (current-column) alloy-basic-offset)))
672 ;; local key bindings
673 (define-key alloy-mode-map
(kbd "RET") #'electric-newline-and-maybe-indent
)
674 ;; (define-key alloy-mode-map (kbd "TAB") #'b/alloy-simple-indent)
675 (define-key alloy-mode-map
(kbd "TAB") #'indent-for-tab-command
))
676 (add-to-list 'auto-mode-alist
'("\\.\\(als\\|dsh\\)\\'" . alloy-mode
))
677 (add-hook 'alloy-mode-hook
(lambda nil
(setq-local indent-tabs-mode nil
)))
680 ;; (eval-when-compile (defvar lean-mode-map))
681 ;; (run-with-idle-timer 0.4 nil #'require 'lean-mode)
682 ;; (with-eval-after-load 'lean-mode
683 ;; (require 'lean-input)
684 ;; (csetq default-input-method "Lean"
685 ;; lean-input-tweak-all '(lean-input-compose
686 ;; (lean-input-prepend "/")
687 ;; (lean-input-nonempty))
688 ;; lean-input-user-translations '(("/" "/")))
689 ;; (lean-input-setup)
690 ;; ;; local key bindings
691 ;; (define-key lean-mode-map (kbd "S-SPC") #'company-complete))
693 (with-eval-after-load 'sgml-mode
694 (csetq sgml-basic-offset
0))
696 (with-eval-after-load 'css-mode
697 (csetq css-indent-offset
2))
700 ;; (add-hook 'po-mode-hook (lambda nil (run-with-timer 0.1 nil 'View-exit)))
703 ;; (csetq font-latex-fontify-sectioning 'color)
705 (with-eval-after-load 'tex-mode
707 (lambda (p) (string-match "^---?" (car p
)))
708 tex--prettify-symbols-alist
))
709 (add-hook 'tex-mode-hook
#'auto-fill-mode
)
710 (add-hook 'tex-mode-hook
#'flyspell-mode
)
713 ;;; Emacs enhancements & auxiliary packages
715 (with-eval-after-load 'man
716 (csetq Man-width
80))
718 (run-with-idle-timer 0.4 nil
#'require
'which-key
)
719 (with-eval-after-load 'which-key
721 which-key-add-column-padding
5
722 which-key-idle-delay
10000
723 which-key-idle-secondary-delay
0.05
724 which-key-max-description-length
32
725 which-key-show-early-on-C-h t
)
726 (which-key-add-key-based-replacements
727 ;; prefixes for global prefixes and minor modes
729 "C-x RET" "coding system"
731 "C-x @" "event modifiers"
732 "C-x a" "abbrev/expand"
733 "C-x r" "rectangle/register/bookmark"
735 "C-x v" "version control"
739 ;; prefixes for my personal bindings
741 "C-c a" "applications"
746 "C-c c" "compile-and-comments"
754 ;; prefixes for major modes
755 (which-key-add-major-mode-key-based-replacements 'org-mode
756 "C-c C-v" "org-babel")
759 ;; (require 'bandali-projectile)
761 (run-with-idle-timer 0.6 nil
#'require
'unkillable-scratch
)
762 (with-eval-after-load 'unkillable-scratch
763 (csetq unkillable-buffers
'("^\\*scratch\\*$" "^\\*Messages\\*$"))
764 (unkillable-scratch 1))
767 ;; | make pretty boxed quotes like this
769 (run-with-idle-timer 0.6 nil
#'require
'boxquote
)
770 (with-eval-after-load 'boxquote
771 (defvar b
/boxquote-prefix-map
)
772 (define-prefix-command 'b
/boxquote-prefix-map
)
773 (global-set-key (kbd "C-c q") 'b
/boxquote-prefix-map
)
774 (define-key b
/boxquote-prefix-map
(kbd "b") #'boxquote-buffer
)
775 (define-key b
/boxquote-prefix-map
(kbd "B") #'boxquote-insert-buffer
)
776 (define-key b
/boxquote-prefix-map
(kbd "d") #'boxquote-defun
)
777 (define-key b
/boxquote-prefix-map
(kbd "F") #'boxquote-insert-file
)
778 (define-key b
/boxquote-prefix-map
(kbd "hf") #'boxquote-describe-function
)
779 (define-key b
/boxquote-prefix-map
(kbd "hk") #'boxquote-describe-key
)
780 (define-key b
/boxquote-prefix-map
(kbd "hv") #'boxquote-describe-variable
)
781 (define-key b
/boxquote-prefix-map
(kbd "hw") #'boxquote-where-is
)
782 (define-key b
/boxquote-prefix-map
(kbd "k") #'boxquote-kill
)
783 (define-key b
/boxquote-prefix-map
(kbd "p") #'boxquote-paragraph
)
784 (define-key b
/boxquote-prefix-map
(kbd "q") #'boxquote-boxquote
)
785 (define-key b
/boxquote-prefix-map
(kbd "r") #'boxquote-region
)
786 (define-key b
/boxquote-prefix-map
(kbd "s") #'boxquote-shell-command
)
787 (define-key b
/boxquote-prefix-map
(kbd "t") #'boxquote-text
)
788 (define-key b
/boxquote-prefix-map
(kbd "T") #'boxquote-title
)
789 (define-key b
/boxquote-prefix-map
(kbd "u") #'boxquote-unbox
)
790 (define-key b
/boxquote-prefix-map
(kbd "U") #'boxquote-unbox-region
)
791 (define-key b
/boxquote-prefix-map
(kbd "y") #'boxquote-yank
)
792 (define-key b
/boxquote-prefix-map
(kbd "M-q") #'boxquote-fill-paragraph
)
793 (define-key b
/boxquote-prefix-map
(kbd "M-w") #'boxquote-kill-ring-save
))
795 (run-with-idle-timer 0.5 nil
#'require
'hl-todo
)
796 (with-eval-after-load 'hl-todo
797 ;; highlight TODOs in buffers
798 (global-hl-todo-mode))
800 (run-with-idle-timer 0.5 nil
#'require
'page-break-lines
)
801 (with-eval-after-load 'page-break-lines
802 (csetq page-break-lines-max-width fill-column
)
803 (global-page-break-lines-mode))
806 (global-set-key (kbd "C-=") #'er
/expand-region
)
808 (run-with-idle-timer 0.6 nil
#'require
'yasnippet
)
809 (with-eval-after-load 'yasnippet
810 (declare-function yas-reload-all
811 "yasnippet" (&optional no-jit interactive
))
812 (declare-function yas-maybe-expand-abbrev-key-filter
815 (defconst yas-verbosity-cur yas-verbosity
)
816 (setq yas-verbosity
2)
817 (add-to-list 'yas-snippet-dirs
"~/src/git/guix/etc/snippets" t
)
819 (setq yas-verbosity yas-verbosity-cur
)
821 (defun b/yas-maybe-expand-abbrev-key-filter
(cmd)
822 (when (and (yas-maybe-expand-abbrev-key-filter cmd
)
823 (not (bound-and-true-p git-commit-mode
)))
825 (defconst b
/yas-maybe-expand
826 '(menu-item "" yas-expand
827 :filter b
/yas-maybe-expand-abbrev-key-filter
))
828 (define-key yas-minor-mode-map
(kbd "SPC") b
/yas-maybe-expand
)
833 (global-set-key (kbd "C-c D d") #'debbugs-gnu
)
834 (global-set-key (kbd "C-c D b") #'debbugs-gnu-bugs
)
835 (global-set-key (kbd "C-c D e") ; bug-gnu-emacs
838 (setq debbugs-gnu-current-suppress t
)
839 (debbugs-gnu debbugs-gnu-default-severities
841 (global-set-key (kbd "C-c D g") ; bug-gnuzilla
844 (setq debbugs-gnu-current-suppress t
)
845 (debbugs-gnu debbugs-gnu-default-severities
847 (global-set-key (kbd "C-c D G b") ; bug-guix
850 (setq debbugs-gnu-current-suppress t
)
851 (debbugs-gnu debbugs-gnu-default-severities
853 (global-set-key (kbd "C-c D G p") ; guix-patches
856 (setq debbugs-gnu-current-suppress t
)
857 (debbugs-gnu debbugs-gnu-default-severities
861 (csetq eww-download-directory
(file-name-as-directory
862 (getenv "XDG_DOWNLOAD_DIR")))
863 (global-set-key (kbd "C-c a e w") #'eww
)
869 reftex-default-bibliography
'("~/usr/org/references.bib")
870 org-ref-default-bibliography
'("~/usr/org/references.bib")
871 org-ref-bibliography-notes
"~/usr/org/notes.org"
872 org-ref-pdf-directory
"~/usr/org/bibtex-pdfs/")
874 ;; fill-column-indicator ?
877 (csetq split-width-threshold
150)
878 (global-set-key (kbd "C-c w s l")
883 (global-set-key (kbd "C-c w s j")
888 (global-set-key (kbd "C-c w q") #'quit-window
)
890 (run-with-idle-timer 0.6 nil
#'require
'windmove
)
891 (global-set-key (kbd "C-c w h") #'windmove-left
)
892 (global-set-key (kbd "C-c w j") #'windmove-down
)
893 (global-set-key (kbd "C-c w k") #'windmove-up
)
894 (global-set-key (kbd "C-c w l") #'windmove-right
)
895 (global-set-key (kbd "C-c w H") #'windmove-swap-states-left
)
896 (global-set-key (kbd "C-c w J") #'windmove-swap-states-down
)
897 (global-set-key (kbd "C-c w K") #'windmove-swap-states-up
)
898 (global-set-key (kbd "C-c w L") #'windmove-swap-states-right
)
901 (global-set-key (kbd "C-c a p") #'pass
)
902 (add-hook 'pass-mode-hook
#'View-exit
)
905 ;; uncomment to disable reftex-cite's default choice of previous word
906 ;; (with-eval-after-load 'reftex
907 ;; (require 'reftex-cite)
908 ;; (defun reftex-get-bibkey-default ()
909 ;; "If the cursor is in a citation macro, return the word before the macro."
910 ;; (let* ((macro (reftex-what-macro 1)))
912 ;; (when (and macro (string-match "cite" (car macro)))
913 ;; (goto-char (cdr macro)))
914 ;; (reftex-this-word)))))
915 (add-hook 'latex-mode-hook
#'reftex-mode
)
919 dmenu-prompt-string
"run: "
920 dmenu-save-file
(b/var
"dmenu-items"))
925 ;;; Post initialization
928 (message "Loading %s...done (%.3fs)" user-init-file
929 (float-time (time-subtract (current-time)
930 b
/before-user-init-time
)))
932 ;;; init.el ends here