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
128 (convert-standard-filename "etc/") user-emacs-directory
)
129 "The directory where packages place their configuration files.")
132 (convert-standard-filename "var/") user-emacs-directory
)
133 "The directory where packages place their persistent data files.")
135 "Expand filename FILE relative to `b/etc-dir'."
136 (expand-file-name (convert-standard-filename file
) b
/etc-dir
))
138 "Expand filename FILE relative to `b/var-dir'."
139 (expand-file-name (convert-standard-filename file
) b
/var-dir
))
142 auto-save-list-file-prefix
(b/var
"auto-save/sessions/")
143 nsm-settings-file
(b/var
"nsm-settings.el"))
145 (require 'auto-compile
)
146 (auto-compile-on-load-mode)
147 (auto-compile-on-save-mode)
148 (setq auto-compile-display-buffer nil
)
149 (setq auto-compile-mode-line-counter t
)
150 (setq auto-compile-source-recreate-deletes-dest t
)
151 (setq auto-compile-toggle-deletes-nonlib-dest t
)
152 (setq auto-compile-update-autoloads t
)
154 ;; separate custom file (don't want it mixing with init.el)
155 (with-eval-after-load 'custom
156 (setq custom-file
(b/etc
"custom.el"))
157 (when (file-exists-p custom-file
)
159 ;; while at it, treat themes as safe
160 (setf custom-safe-themes t
)
161 ;; only one custom theme at a time
163 (defadvice load-theme
(before clear-previous-themes activate
)
164 "Clear existing theme settings instead of layering them"
165 (mapc #'disable-theme custom-enabled-themes
))))
167 ;; load the secrets file if it exists, otherwise show a warning
170 (load (b/etc
"secrets"))))
172 ;; start up emacs server. see
173 ;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html#Emacs-Server
174 (run-with-idle-timer 0.5 nil
#'require
'server
)
175 (with-eval-after-load 'server
176 (declare-function server-edit
"server")
177 (global-set-key (kbd "C-c F D") #'server-edit
)
178 (declare-function server-running-p
"server")
179 (or (server-running-p) (server-mode)))
184 ;;;; C-level customizations
188 enable-recursive-minibuffers t
189 resize-mini-windows t
190 ;; more useful frame titles
191 ;; frame-title-format '("" invocation-name " - "
193 ;; (if (buffer-file-name)
194 ;; (abbreviate-file-name (buffer-file-name))
196 ;; i don't feel like jumping out of my chair every now and again; so
197 ;; don't BEEP! at me, emacs
198 ring-bell-function
'ignore
201 ;; scroll-conservatively 10000
203 scroll-conservatively
101
204 scroll-preserve-screen-position
1
205 ;; focus follows mouse
206 mouse-autoselect-window t
)
209 ;; always use space for indentation
212 ;; case-sensitive search (and `dabbrev-expand')
213 ;; case-fold-search nil
217 (set-fontset-font t
'arabic
"Vazir")
221 (dolist (ft (fontset-list))
225 (font-spec :name
"Source Code Pro" :size
14))
229 (font-spec :name
"DejaVu Sans Mono")
236 ;; :name "Symbola monospacified for DejaVu Sans Mono")
242 ;; (font-spec :name "DejaVu Sans Mono")
248 (font-spec :name
"DejaVu Sans Mono" :size
14)
252 ;;;; Elisp-level customizations
255 ;; don't need to see the startup echo area message
256 (advice-add #'display-startup-echo-area-message
:override
#'ignore
)
258 ;; i want *scratch* as my startup buffer
259 initial-buffer-choice t
260 ;; i don't need the default hint
261 initial-scratch-message nil
262 ;; use customizable text-mode as major mode for *scratch*
263 ;; (initial-major-mode 'text-mode)
264 ;; inhibit buffer list when more than 2 files are loaded
265 inhibit-startup-buffer-menu t
266 ;; don't need to see the startup screen or echo area message
267 inhibit-startup-screen t
268 inhibit-startup-echo-area-message user-login-name
)
272 ;; backups (C-h v make-backup-files RET)
274 backup-directory-alist
(list (cons "." (b/var
"backup/")))
276 delete-old-versions t
278 auto-save-file-name-transforms
`((".*" ,(b/var
"auto-save/") t
))
279 ;; insert newline at the end of files
280 require-final-newline t
281 ;; open read-only file buffers in view-mode
282 ;; (enables niceties like `q' for quit)
286 ;; disable disabled commands
287 (csetq disabled-command-function nil
)
289 ;; lazy-person-friendly yes/no prompts
290 (defalias 'yes-or-no-p
#'y-or-n-p
)
292 ;; enable automatic reloading of changed buffers and files
294 (csetq auto-revert-verbose nil
295 global-auto-revert-non-file-buffers nil
)
296 (require 'autorevert
)
297 (global-auto-revert-mode 1))
299 ;; time and battery in mode-line
301 display-time-default-load-average nil
302 display-time-format
" %a %b %-e %-l:%M%P"
303 display-time-mail-icon
'(image :type xpm
304 :file
"gnus/gnus-pointer.xpm"
306 display-time-use-mail-icon t
)
310 (csetq battery-mode-line-format
"%p%% %t")
312 (display-battery-mode)
316 ;; (fringe-mode '(3 . 1))
320 ;; enable winner-mode (C-h f winner-mode RET)
323 (with-eval-after-load 'compile
324 ;; don't display *compilation* buffer on success. based on
325 ;; https://stackoverflow.com/a/17788551, with changes to use `cl-letf'
326 ;; instead of the now obsolete `flet'.
327 (defun b/compilation-finish-function
(buffer outstr
)
328 (unless (string-match "finished" outstr
)
329 (switch-to-buffer-other-window buffer
))
332 (setq compilation-finish-functions
#'b
/compilation-finish-function
)
336 (defadvice compilation-start
337 (around inhibit-display
338 (command &optional mode name-function highlight-regexp
))
339 (if (not (string-match "^\\(find\\|grep\\)" command
))
340 (cl-letf (((symbol-function 'display-buffer
) #'ignore
))
341 (save-window-excursion ad-do-it
))
343 (ad-activate 'compilation-start
))
347 ;; allow scrolling in Isearch
348 isearch-allow-scroll t
349 ;; search for non-ASCII characters: i’d like non-ASCII characters such
350 ;; as ‘’“”«»‹›áⓐ𝒶 to be selected when i search for their ASCII
351 ;; counterpart. shoutout to
352 ;; http://endlessparentheses.com/new-in-emacs-25-1-easily-search-non-ascii-characters.html
353 search-default-mode
#'char-fold-to-regexp
)
356 ;; uncomment to extend the above behaviour to query-replace
357 ;; (csetq replace-char-fold t)
360 (global-set-key (kbd "C-x v C-=") #'vc-ediff
)
362 (with-eval-after-load 'vc-git
363 (csetq vc-git-print-log-follow t
))
365 (csetq ediff-window-setup-function
'ediff-setup-windows-plain
366 ediff-split-window-function
'split-window-horizontally
)
367 (with-eval-after-load 'ediff
368 (add-hook 'ediff-after-quit-hook-internal
#'winner-undo
))
372 ;; gentler font resizing
373 text-scale-mode-step
1.05)
375 (run-with-idle-timer 0.4 nil
#'require
'mwheel
)
376 (csetq mouse-wheel-scroll-amount
'(1 ((shift) .
1)) ; one line at a time
377 mouse-wheel-progressive-speed nil
; don't accelerate scrolling
378 mouse-wheel-follow-mouse t
) ; scroll window under mouse
380 (run-with-idle-timer 0.4 nil
#'require
'pixel-scroll
)
381 (with-eval-after-load 'pixel-scroll
382 (pixel-scroll-mode 1))
386 epg-gpg-program
(executable-find "gpg")
387 ;; ask for GPG passphrase in minibuffer
388 ;; this will fail if gpg>=2.1 is not available
389 epg-pinentry-mode
'loopback
)
391 ;; (require 'pinentry)
392 ;; workaround for systemd-based distros:
393 ;; (setq pinentry--socket-dir server-socket-dir)
398 auth-sources
'("~/.authinfo.gpg")
399 authinfo-hidden
(regexp-opt '("password" "client-secret" "token")))
402 ;;; General key bindings
404 (global-set-key (kbd "C-a") #'b
/move-indentation-or-beginning-of-line
)
405 (global-set-key (kbd "C-c a i") #'ielm
)
406 (global-set-key (kbd "C-c d") #'b
/duplicate-line-or-region
)
407 (global-set-key (kbd "C-S-j") #'b
/join-line-top
)
408 (global-set-key (kbd "C-c x") #'execute-extended-command
)
410 ;; evaling and macro-expanding
411 (global-set-key (kbd "C-c e b") #'eval-buffer
)
412 (global-set-key (kbd "C-c e e") #'eval-last-sexp
)
413 (global-set-key (kbd "C-c e p") #'pp-macroexpand-last-sexp
)
414 (global-set-key (kbd "C-c e r") #'eval-region
)
417 (global-set-key (kbd "C-c e i") #'emacs-init-time
)
418 (global-set-key (kbd "C-c e u") #'emacs-uptime
)
419 (global-set-key (kbd "C-c e v") #'emacs-version
)
422 (global-set-key (kbd "C-c f .") #'find-file
)
423 (global-set-key (kbd "C-c f d") #'find-name-dired
)
424 (global-set-key (kbd "C-c f l") #'find-library
)
427 (global-set-key (kbd "C-c F m") #'make-frame-command
)
428 (global-set-key (kbd "C-c F d") #'delete-frame
)
431 (global-set-key (kbd "C-S-h C") #'describe-char
)
432 (global-set-key (kbd "C-S-h F") #'describe-face
)
434 ;; (global-set-key (kbd "C-x k") #'b/kill-current-buffer)
435 ;; (global-set-key (kbd "C-x K") #'kill-buffer)
436 ;; (global-set-key (kbd "C-x s") #'save-buffer)
437 ;; (global-set-key (kbd "C-x S") #'save-some-buffers)
439 (define-key emacs-lisp-mode-map
(kbd "<C-return>") #'b
/add-elisp-section
)
441 (when (display-graphic-p)
442 (global-unset-key (kbd "C-z")))
445 ;;; Essential packages
447 ;; (require 'bandali-exwm)
449 (require 'bandali-org
)
451 (require 'bandali-theme
)
453 ;; magit, *the* right way to do git
454 (csetq transient-history-file
(b/var
"transient/history.el")
455 transient-levels-file
(b/etc
"transient/levels.el")
456 transient-values-file
(b/etc
"transient/values.el"))
457 (with-eval-after-load 'magit
458 (declare-function magit-add-section-hook
"magit-section"
459 (hook function
&optional at append local
))
460 (magit-add-section-hook 'magit-status-sections-hook
461 'magit-insert-modules
462 'magit-insert-stashes
464 ;; (magit-add-section-hook 'magit-status-sections-hook
465 ;; 'magit-insert-ignored-files
466 ;; 'magit-insert-untracked-files
468 (declare-function magit-display-buffer-fullframe-status-v1
469 "magit-mode" (buffer))
471 magit-diff-refine-hunk t
472 magit-repository-directories
'(("~/.emacs.d/" .
0)
474 ;; magit-completing-read-function 'magit-ido-completing-read
475 magit-display-buffer-function
476 #'magit-display-buffer-fullframe-status-v1
)
477 (nconc magit-section-initial-visibility-alist
478 '(([unpulled status
] . show
)
479 ([unpushed status
] . show
)))
480 (custom-set-faces '(magit-diff-file-heading ((t (:weight normal
)))))
482 (with-eval-after-load 'magit-extras
484 magit-pop-revision-stack-format
485 (pcase-let ((`(,pt
,_eob
,index-regexp
)
486 (default-value 'magit-pop-revision-stack-format
)))
487 `(,pt
"[%N: %h]: %ci\n %s
488 https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=%H"
490 ;; global key bindings
491 (global-set-key (kbd "C-x g") #'magit-status
)
492 (global-set-key (kbd "C-c g b") #'magit-blame-addition
)
493 (global-set-key (kbd "C-c g l") #'magit-log-buffer-file
)
494 (global-set-key (kbd "C-c g y") #'magit-pop-revision-stack
)
496 ;; recently opened files
497 (run-with-idle-timer 0.2 nil
#'require
'recentf
)
498 (with-eval-after-load 'recentf
499 (csetq recentf-max-saved-items
2000
500 recentf-save-file
(b/var
"recentf-save.el"))
501 (add-to-list 'recentf-keep
#'file-remote-p
)
504 ;; needed for history for counsel
505 (csetq amx-save-file
(b/var
"amx-save.el"))
506 (run-with-idle-timer 0.3 nil
#'require
'amx
)
507 (with-eval-after-load 'amx
510 ;; (require 'bandali-ido)
511 (require 'bandali-ivy
)
513 (require 'bandali-eshell
)
514 ;; (require 'bandali-multi-term)
516 (require 'bandali-ibuffer
)
519 ;; (with-eval-after-load 'outline
520 ;; (when (featurep 'which-key)
521 ;; (which-key-add-key-based-replacements
524 ;; (define-key outline-minor-mode-map (kbd "<s-tab>")
525 ;; #'outline-toggle-children)
526 ;; (define-key outline-minor-mode-map (kbd "M-p")
527 ;; #'outline-previous-visible-heading)
528 ;; (define-key outline-minor-mode-map (kbd "M-n")
529 ;; #'outline-next-visible-heading)
530 ;; (defvar b/outline-prefix-map)
531 ;; (define-prefix-command 'b/outline-prefix-map)
532 ;; (define-key outline-minor-mode-map (kbd "s-O")
533 ;; 'b/outline-prefix-map)
534 ;; (define-key b/outline-prefix-map (kbd "TAB")
535 ;; #'outline-toggle-children)
536 ;; (define-key b/outline-prefix-map (kbd "a")
537 ;; #'outline-hide-body)
538 ;; (define-key b/outline-prefix-map (kbd "H")
539 ;; #'outline-hide-body)
540 ;; (define-key b/outline-prefix-map (kbd "S")
541 ;; #'outline-show-all)
542 ;; (define-key b/outline-prefix-map (kbd "h")
543 ;; #'outline-hide-subtree)
544 ;; (define-key b/outline-prefix-map (kbd "s")
545 ;; #'outline-show-subtree))
546 ;; (add-hook 'prog-mode-hook #'outline-minor-mode)
548 (require 'bandali-dired
)
550 (with-eval-after-load 'help
551 (temp-buffer-resize-mode)
552 (csetq help-window-select t
)
554 ;; local key bindings
555 (define-key help-mode-map
(kbd "p") #'backward-button
)
556 (define-key help-mode-map
(kbd "n") #'forward-button
))
558 (with-eval-after-load 'tramp
559 (csetq tramp-auto-save-directory
(b/var
"tramp/auto-save/")
560 tramp-persistency-file-name
(b/var
"tramp/persistency.el"))
561 (add-to-list 'tramp-default-proxies-alist
'(nil "\\`root\\'" "/ssh:%h:"))
562 (add-to-list 'tramp-default-proxies-alist
'("localhost" nil nil
))
563 (add-to-list 'tramp-default-proxies-alist
564 (list (regexp-quote (system-name)) nil nil
)))
566 (with-eval-after-load 'doc-view
567 (define-key doc-view-mode-map
(kbd "M-RET") #'image-previous-line
))
569 (csetq shr-max-width
80)
571 ;; Email (with Gnus, message, and EBDB)
572 (require 'bandali-gnus
)
573 (with-eval-after-load 'sendmail
574 (csetq sendmail-program
(executable-find "msmtp")
575 ;; message-sendmail-extra-arguments '("-v" "-d")
576 mail-specify-envelope-from t
577 mail-envelope-from
'header
))
578 (require 'bandali-message
)
579 (require 'bandali-ebdb
)
581 ;; IRC (with ERC and ZNC)
582 (require 'bandali-erc
)
584 (with-eval-after-load 'scpaste
585 (csetq scpaste-http-destination
"https://p.bndl.org"
586 scpaste-scp-destination
"p:~"))
587 (global-set-key (kbd "C-c a p p") #'scpaste
)
588 (global-set-key (kbd "C-c a p r") #'scpaste-region
)
593 ;; display Lisp objects at point in the echo area
594 (when (version< "25" emacs-version
)
595 (with-eval-after-load 'eldoc
596 (global-eldoc-mode)))
598 ;; highlight matching parens
602 ;; (require 'elec-pair)
603 ;; (electric-pair-mode)
606 ;; Save what I copy into clipboard from other applications into Emacs'
607 ;; kill-ring, which would allow me to still be able to easily access
608 ;; it in case I kill (cut or copy) something else inside Emacs before
609 ;; yanking (pasting) what I'd originally intended to.
610 save-interprogram-paste-before-kill t
)
611 (with-eval-after-load 'simple
612 (column-number-mode))
614 ;; save minibuffer history
616 (csetq savehist-file
(b/var
"savehist.el"))
618 (add-to-list 'savehist-additional-variables
'kill-ring
)
620 ;; automatically save place in files
621 (when (version< "25" emacs-version
)
622 (csetq save-place-file
(b/var
"save-place.el"))
625 (defun indicate-buffer-boundaries-left ()
626 (csetq indicate-buffer-boundaries
'left
))
627 (with-eval-after-load 'prog-mode
628 (global-prettify-symbols-mode))
629 (add-hook 'prog-mode-hook
#'indicate-buffer-boundaries-left
)
631 (define-key text-mode-map
(kbd "C-*") #'b
/insert-asterism
)
632 (add-hook 'text-mode-hook
#'indicate-buffer-boundaries-left
)
633 (add-hook 'text-mode-hook
#'flyspell-mode
)
635 (add-to-list 'auto-mode-alist
'("\\.*rc$" . conf-mode
))
637 (add-to-list 'auto-mode-alist
'("\\.bashrc$" . sh-mode
))
640 ;; (run-with-idle-timer 0.6 nil #'require 'flycheck)
641 ;; (with-eval-after-load 'flycheck
643 ;; ;; Use the load-path from running Emacs when checking elisp files
644 ;; flycheck-emacs-lisp-load-path 'inherit
645 ;; ;; Only flycheck when I actually save the buffer
646 ;; flycheck-check-syntax-automatically '(mode-enabled save)
647 ;; flycheck-mode-line-prefix "flyc"))
648 ;; (define-key flycheck-mode-map (kbd "M-P") #'flycheck-previous-error)
649 ;; (define-key flycheck-mode-map (kbd "M-N") #'flycheck-next-error)
650 ;; (add-hook 'prog-mode-hook #'flycheck-mode)
653 ;; http://endlessparentheses.com/ispell-and-apostrophes.html
654 ;; (run-with-idle-timer 0.6 nil #'require 'ispell)
655 ;; (with-eval-after-load 'ispell
656 ;; ;; ’ can be part of a word
657 ;; (csetq ispell-local-dictionary-alist
658 ;; `((nil "[[:alpha:]]" "[^[:alpha:]]"
659 ;; "['\x2019]" nil ("-B") nil utf-8))
660 ;; ispell-program-name (executable-find "hunspell"))
661 ;; ;; don't send ’ to the subprocess
662 ;; (defun endless/replace-apostrophe (args)
663 ;; (cons (replace-regexp-in-string
664 ;; "’" "'" (car args))
666 ;; (advice-add #'ispell-send-string :filter-args
667 ;; #'endless/replace-apostrophe)
668 ;; ;; convert ' back to ’ from the subprocess
669 ;; (defun endless/replace-quote (args)
670 ;; (if (not (derived-mode-p 'org-mode))
672 ;; (cons (replace-regexp-in-string
673 ;; "'" "’" (car args))
675 ;; (advice-add #'ispell-parse-output :filter-args
676 ;; #'endless/replace-quote))
679 (csetq abbrev-file-name
(b/var
"abbrev.el"))
680 (add-hook 'text-mode-hook
#'abbrev-mode
)
683 ;;; Programming modes
685 (with-eval-after-load 'lisp-mode
686 (defun indent-spaces-mode ()
687 (setq indent-tabs-mode nil
))
688 (add-hook 'lisp-interaction-mode-hook
#'indent-spaces-mode
))
690 (with-eval-after-load 'alloy-mode
691 (csetq alloy-basic-offset
2)
692 ;; (defun b/alloy-simple-indent (start end)
694 ;; ;; (if (region-active-p)
695 ;; ;; (indent-rigidly start end alloy-basic-offset)
697 ;; ;; (indent-rigidly (line-beginning-position)
698 ;; ;; (line-end-position)
699 ;; ;; alloy-basic-offset)))
700 ;; (indent-to (+ (current-column) alloy-basic-offset)))
701 ;; local key bindings
702 (define-key alloy-mode-map
(kbd "RET") #'electric-newline-and-maybe-indent
)
703 ;; (define-key alloy-mode-map (kbd "TAB") #'b/alloy-simple-indent)
704 (define-key alloy-mode-map
(kbd "TAB") #'indent-for-tab-command
))
705 (add-to-list 'auto-mode-alist
'("\\.\\(als\\|dsh\\)\\'" . alloy-mode
))
706 (add-hook 'alloy-mode-hook
(lambda nil
(setq-local indent-tabs-mode nil
)))
709 ;; (eval-when-compile (defvar lean-mode-map))
710 ;; (run-with-idle-timer 0.4 nil #'require 'lean-mode)
711 ;; (with-eval-after-load 'lean-mode
712 ;; (require 'lean-input)
713 ;; (csetq default-input-method "Lean"
714 ;; lean-input-tweak-all '(lean-input-compose
715 ;; (lean-input-prepend "/")
716 ;; (lean-input-nonempty))
717 ;; lean-input-user-translations '(("/" "/")))
718 ;; (lean-input-setup)
719 ;; ;; local key bindings
720 ;; (define-key lean-mode-map (kbd "S-SPC") #'company-complete))
722 (with-eval-after-load 'sgml-mode
723 (csetq sgml-basic-offset
0))
725 (with-eval-after-load 'css-mode
726 (csetq css-indent-offset
2))
729 ;; (add-hook 'po-mode-hook (lambda nil (run-with-timer 0.1 nil 'View-exit)))
732 ;; (csetq font-latex-fontify-sectioning 'color)
734 (with-eval-after-load 'tex-mode
736 (lambda (p) (string-match "^---?" (car p
)))
737 tex--prettify-symbols-alist
))
738 (add-hook 'tex-mode-hook
#'auto-fill-mode
)
739 (add-hook 'tex-mode-hook
#'flyspell-mode
)
742 ;;; Emacs enhancements & auxiliary packages
744 (with-eval-after-load 'man
745 (csetq Man-width
80))
747 (run-with-idle-timer 0.4 nil
#'require
'which-key
)
748 (with-eval-after-load 'which-key
750 which-key-add-column-padding
5
751 which-key-idle-delay
10000
752 which-key-idle-secondary-delay
0.05
753 which-key-max-description-length
32
754 which-key-show-early-on-C-h t
)
755 (which-key-add-key-based-replacements
756 ;; prefixes for global prefixes and minor modes
758 "C-x RET" "coding system"
760 "C-x @" "event modifiers"
761 "C-x a" "abbrev/expand"
762 "C-x r" "rectangle/register/bookmark"
764 "C-x v" "version control"
768 ;; prefixes for my personal bindings
770 "C-c a" "applications"
775 "C-c c" "compile-and-comments"
783 ;; prefixes for major modes
784 (which-key-add-major-mode-key-based-replacements 'org-mode
785 "C-c C-v" "org-babel")
788 ;; (require 'bandali-projectile)
790 (run-with-idle-timer 0.6 nil
#'require
'unkillable-scratch
)
791 (with-eval-after-load 'unkillable-scratch
792 (csetq unkillable-buffers
'("^\\*scratch\\*$" "^\\*Messages\\*$"))
793 (unkillable-scratch 1))
796 ;; | make pretty boxed quotes like this
798 (run-with-idle-timer 0.6 nil
#'require
'boxquote
)
799 (with-eval-after-load 'boxquote
800 (defvar b
/boxquote-prefix-map
)
801 (define-prefix-command 'b
/boxquote-prefix-map
)
802 (global-set-key (kbd "C-c q") 'b
/boxquote-prefix-map
)
803 (define-key b
/boxquote-prefix-map
(kbd "b") #'boxquote-buffer
)
804 (define-key b
/boxquote-prefix-map
(kbd "B") #'boxquote-insert-buffer
)
805 (define-key b
/boxquote-prefix-map
(kbd "d") #'boxquote-defun
)
806 (define-key b
/boxquote-prefix-map
(kbd "F") #'boxquote-insert-file
)
807 (define-key b
/boxquote-prefix-map
(kbd "hf") #'boxquote-describe-function
)
808 (define-key b
/boxquote-prefix-map
(kbd "hk") #'boxquote-describe-key
)
809 (define-key b
/boxquote-prefix-map
(kbd "hv") #'boxquote-describe-variable
)
810 (define-key b
/boxquote-prefix-map
(kbd "hw") #'boxquote-where-is
)
811 (define-key b
/boxquote-prefix-map
(kbd "k") #'boxquote-kill
)
812 (define-key b
/boxquote-prefix-map
(kbd "p") #'boxquote-paragraph
)
813 (define-key b
/boxquote-prefix-map
(kbd "q") #'boxquote-boxquote
)
814 (define-key b
/boxquote-prefix-map
(kbd "r") #'boxquote-region
)
815 (define-key b
/boxquote-prefix-map
(kbd "s") #'boxquote-shell-command
)
816 (define-key b
/boxquote-prefix-map
(kbd "t") #'boxquote-text
)
817 (define-key b
/boxquote-prefix-map
(kbd "T") #'boxquote-title
)
818 (define-key b
/boxquote-prefix-map
(kbd "u") #'boxquote-unbox
)
819 (define-key b
/boxquote-prefix-map
(kbd "U") #'boxquote-unbox-region
)
820 (define-key b
/boxquote-prefix-map
(kbd "y") #'boxquote-yank
)
821 (define-key b
/boxquote-prefix-map
(kbd "M-q") #'boxquote-fill-paragraph
)
822 (define-key b
/boxquote-prefix-map
(kbd "M-w") #'boxquote-kill-ring-save
))
824 (run-with-idle-timer 0.5 nil
#'require
'hl-todo
)
825 (with-eval-after-load 'hl-todo
826 ;; highlight TODOs in buffers
827 (global-hl-todo-mode))
829 (run-with-idle-timer 0.5 nil
#'require
'page-break-lines
)
830 (with-eval-after-load 'page-break-lines
831 (csetq page-break-lines-max-width fill-column
)
832 (global-page-break-lines-mode))
835 (global-set-key (kbd "C-=") #'er
/expand-region
)
837 (run-with-idle-timer 0.6 nil
#'require
'yasnippet
)
838 (with-eval-after-load 'yasnippet
839 (declare-function yas-reload-all
840 "yasnippet" (&optional no-jit interactive
))
841 (declare-function yas-maybe-expand-abbrev-key-filter
844 (defconst yas-verbosity-cur yas-verbosity
)
845 (setq yas-verbosity
2)
846 (csetq yas-snippet-dirs
`(,(b/etc
"yasnippet/snippets")))
847 (add-to-list 'yas-snippet-dirs
"~/src/git/guix/etc/snippets" t
)
849 (setq yas-verbosity yas-verbosity-cur
)
851 (defun b/yas-maybe-expand-abbrev-key-filter
(cmd)
852 (when (and (yas-maybe-expand-abbrev-key-filter cmd
)
853 (not (bound-and-true-p git-commit-mode
)))
855 (defconst b
/yas-maybe-expand
856 '(menu-item "" yas-expand
857 :filter b
/yas-maybe-expand-abbrev-key-filter
))
858 (define-key yas-minor-mode-map
(kbd "SPC") b
/yas-maybe-expand
)
863 (global-set-key (kbd "C-c D d") #'debbugs-gnu
)
864 (global-set-key (kbd "C-c D b") #'debbugs-gnu-bugs
)
865 (global-set-key (kbd "C-c D e") ; bug-gnu-emacs
868 (setq debbugs-gnu-current-suppress t
)
869 (debbugs-gnu debbugs-gnu-default-severities
871 (global-set-key (kbd "C-c D g") ; bug-gnuzilla
874 (setq debbugs-gnu-current-suppress t
)
875 (debbugs-gnu debbugs-gnu-default-severities
877 (global-set-key (kbd "C-c D G b") ; bug-guix
880 (setq debbugs-gnu-current-suppress t
)
881 (debbugs-gnu debbugs-gnu-default-severities
883 (global-set-key (kbd "C-c D G p") ; guix-patches
886 (setq debbugs-gnu-current-suppress t
)
887 (debbugs-gnu debbugs-gnu-default-severities
892 url-configuration-directory
(b/var
"url/configuration/")
893 url-cache-directory
(b/var
"url/cache/"))
896 (csetq eww-download-directory
(file-name-as-directory
897 (getenv "XDG_DOWNLOAD_DIR")))
898 (global-set-key (kbd "C-c a e w") #'eww
)
904 reftex-default-bibliography
'("~/usr/org/references.bib")
905 org-ref-default-bibliography
'("~/usr/org/references.bib")
906 org-ref-bibliography-notes
"~/usr/org/notes.org"
907 org-ref-pdf-directory
"~/usr/org/bibtex-pdfs/")
909 ;; fill-column-indicator ?
912 (csetq split-width-threshold
150)
913 (global-set-key (kbd "C-c w s l")
918 (global-set-key (kbd "C-c w s j")
923 (global-set-key (kbd "C-c w q") #'quit-window
)
925 (run-with-idle-timer 0.6 nil
#'require
'windmove
)
926 (global-set-key (kbd "C-c w h") #'windmove-left
)
927 (global-set-key (kbd "C-c w j") #'windmove-down
)
928 (global-set-key (kbd "C-c w k") #'windmove-up
)
929 (global-set-key (kbd "C-c w l") #'windmove-right
)
930 (global-set-key (kbd "C-c w H") #'windmove-swap-states-left
)
931 (global-set-key (kbd "C-c w J") #'windmove-swap-states-down
)
932 (global-set-key (kbd "C-c w K") #'windmove-swap-states-up
)
933 (global-set-key (kbd "C-c w L") #'windmove-swap-states-right
)
936 (global-set-key (kbd "C-c a p") #'pass
)
937 (add-hook 'pass-mode-hook
#'View-exit
)
940 ;; uncomment to disable reftex-cite's default choice of previous word
941 ;; (with-eval-after-load 'reftex
942 ;; (require 'reftex-cite)
943 ;; (defun reftex-get-bibkey-default ()
944 ;; "If the cursor is in a citation macro, return the word before the macro."
945 ;; (let* ((macro (reftex-what-macro 1)))
947 ;; (when (and macro (string-match "cite" (car macro)))
948 ;; (goto-char (cdr macro)))
949 ;; (reftex-this-word)))))
950 (add-hook 'latex-mode-hook
#'reftex-mode
)
954 dmenu-prompt-string
"run: "
955 dmenu-save-file
(b/var
"dmenu-items"))
960 ;;; Post initialization
963 (message "Loading %s...done (%.3fs)" user-init-file
964 (float-time (time-subtract (current-time)
965 b
/before-user-init-time
)))
967 ;;; init.el ends here