'((:eval
(format
"[%s]" (number-to-string
- exwm-workspace-current-index)))))))))
+ exwm-workspace-current-index))))))))
+
+ ;; make some mode-line spaces smaller
+ (setq-default
+ mode-line-format
+ (mapcar
+ (lambda (x)
+ (if (and (stringp x) (or (string= x " ") (string= x " ")))
+ " "
+ x))
+ mode-line-format)
+ mode-line-buffer-identification
+ (propertized-buffer-identification "%10b")))
(add-hook 'after-init-hook #'b/post-init)
;; increase number of lines kept in *Messages* log
user-mail-address "bandali@gnu.org")
\f
-;;; Package management
+;;; csetq (`custom' setq)
-(progn ; `borg'
- (add-to-list 'load-path
- (expand-file-name "lib/borg" user-emacs-directory))
- (require 'borg)
- (borg-initialize)
- (setq borg-rewrite-urls-alist
- '(("git@github.com:" . "https://github.com/")
- ("git@gitlab.com:" . "https://gitlab.com/"))))
+(require 'cl-lib)
(defmacro csetq (&rest args)
"Set the value of user option VAR to VALUE.
',var ,value))))
\f
+;;; Package management
+
+;; variables of interest:
+;; package-archive-priorities
+;; package-load-list
+;; package-pinned-packages
+
+;; (let* ((b (find-file-noselect "refinery-theme.el"))
+;; (d (with-current-buffer b (package-buffer-info))))
+;; (package-generate-description-file d "refinery-theme-pkg.el"))
+(run-with-idle-timer 0.01 nil #'require 'package)
+(with-eval-after-load 'package
+ (when (= (length package-archives) 1)
+ (csetq
+ package-archives
+ `(,@package-archives
+ ;; ("bndl" . "https://p.bndl.org/elpa/")
+ ("org" . "https://orgmode.org/elpa/"))
+ package-load-list
+ '(;; GNU ELPA
+ (ivy "0.13.1")
+ (counsel "0.13.1")
+ (swiper "0.13.1")
+ (debbugs "0.26")
+ (delight "1.7")
+ (ebdb "0.6.19")
+ (orgalist "1.13")
+ (rt-liberation "1.31")
+ (yasnippet "0.14.0")
+ ;; bndl
+ (refinery-theme "0.1.1")
+ ;; Org ELPA
+ (org-plus-contrib "20201005"))))
+ (package-initialize))
+
+(csetq package-archive-upload-base "/ssh:caffeine:~/www/p/elpa")
+
+\f
;;; Initial setup
;; keep ~/.emacs.d clean
(expand-file-name
(convert-standard-filename "var/") user-emacs-directory)
"The directory where packages place their persistent data files.")
+(defvar b/lisp-dir
+ (expand-file-name
+ (convert-standard-filename "lisp/") user-emacs-directory)
+ "The directory where packages place their persistent data files.")
(defun b/etc (file)
"Expand filename FILE relative to `b/etc-dir'."
(expand-file-name (convert-standard-filename file) b/etc-dir))
(defun b/var (file)
"Expand filename FILE relative to `b/var-dir'."
(expand-file-name (convert-standard-filename file) b/var-dir))
+(defun b/lisp (file)
+ "Expand filename FILE relative to `b/lisp-dir'."
+ (expand-file-name (convert-standard-filename file) b/lisp-dir))
(csetq
auto-save-list-file-prefix (b/var "auto-save/sessions/")
nsm-settings-file (b/var "nsm-settings.el"))
-(require 'auto-compile)
-(auto-compile-on-load-mode)
-(auto-compile-on-save-mode)
-(setq auto-compile-display-buffer nil)
-(setq auto-compile-mode-line-counter t)
-(setq auto-compile-source-recreate-deletes-dest t)
-(setq auto-compile-toggle-deletes-nonlib-dest t)
-(setq auto-compile-update-autoloads t)
-
;; separate custom file (don't want it mixing with init.el)
(with-eval-after-load 'custom
(setq custom-file (b/etc "custom.el"))
(when (file-exists-p custom-file)
(load custom-file))
;; while at it, treat themes as safe
- (setf custom-safe-themes t)
+ ;; (setf custom-safe-themes t)
;; only one custom theme at a time
- (comment
- (defadvice load-theme (before clear-previous-themes activate)
- "Clear existing theme settings instead of layering them"
- (mapc #'disable-theme custom-enabled-themes))))
+ ;; (defadvice load-theme (before clear-previous-themes activate)
+ ;; "Clear existing theme settings instead of layering them"
+ ;; (mapc #'disable-theme custom-enabled-themes))
+ )
;; load the secrets file if it exists, otherwise show a warning
-(comment
- (with-demoted-errors
- (load (b/etc "secrets"))))
+;; (with-demoted-errors
+;; (load (b/etc "secrets")))
;; start up emacs server. see
;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html#Emacs-Server
(set-fontset-font t 'arabic "Vazir")
;; unicode support
-(comment
- (dolist (ft (fontset-list))
- (set-fontset-font
- ft
- 'unicode
- (font-spec :name "Source Code Pro" :size 14))
- (set-fontset-font
- ft
- 'unicode
- (font-spec :name "DejaVu Sans Mono")
- nil
- 'append)
- ;; (set-fontset-font
- ;; ft
- ;; 'unicode
- ;; (font-spec
- ;; :name "Symbola monospacified for DejaVu Sans Mono")
- ;; nil
- ;; 'append)
- ;; (set-fontset-font
- ;; ft
- ;; #x2115 ; ℕ
- ;; (font-spec :name "DejaVu Sans Mono")
- ;; nil
- ;; 'append)
- (set-fontset-font
- ft
- (cons ?Α ?ω)
- (font-spec :name "DejaVu Sans Mono" :size 14)
- nil
- 'prepend)))
+;; (dolist (ft (fontset-list))
+;; (set-fontset-font
+;; ft
+;; 'unicode
+;; (font-spec :name "Source Code Pro" :size 14))
+;; (set-fontset-font
+;; ft
+;; 'unicode
+;; (font-spec :name "DejaVu Sans Mono")
+;; nil
+;; 'append)
+;; ;; (set-fontset-font
+;; ;; ft
+;; ;; 'unicode
+;; ;; (font-spec
+;; ;; :name "Symbola monospacified for DejaVu Sans Mono")
+;; ;; nil
+;; ;; 'append)
+;; ;; (set-fontset-font
+;; ;; ft
+;; ;; #x2115 ; ℕ
+;; ;; (font-spec :name "DejaVu Sans Mono")
+;; ;; nil
+;; ;; 'append)
+;; (set-fontset-font
+;; ft
+;; (cons ?Α ?ω)
+;; (font-spec :name "DejaVu Sans Mono" :size 14)
+;; nil
+;; 'prepend))
;;;; Elisp-level customizations
;; lazy-person-friendly yes/no prompts
(defalias 'yes-or-no-p #'y-or-n-p)
-;; enable automatic reloading of changed buffers and files
-(progn ; autorevert
- (csetq auto-revert-verbose nil
- global-auto-revert-non-file-buffers nil)
- (require 'autorevert)
- (global-auto-revert-mode 1))
+;; autorevert: enable automatic reloading of changed buffers and files
+(csetq auto-revert-verbose nil
+ global-auto-revert-non-file-buffers nil)
+(require 'autorevert)
+(global-auto-revert-mode 1)
;; time and battery in mode-line
(csetq
(require 'time)
(display-time-mode)
-(csetq battery-mode-line-format "%p%% %t")
+(csetq battery-mode-line-format " %p%% %t")
(require 'battery)
(display-battery-mode)
(global-set-key (kbd "C-x v C-=") #'vc-ediff)
(with-eval-after-load 'vc-git
- (csetq vc-git-print-log-follow t))
+ (csetq vc-git-print-log-follow t
+ vc-git-show-stash 0))
(csetq ediff-window-setup-function 'ediff-setup-windows-plain
ediff-split-window-function 'split-window-horizontally)
authinfo-hidden (regexp-opt '("password" "client-secret" "token")))
\f
+;;; Useful utilities
+
+(defun b/add-elisp-section ()
+ (interactive)
+ (insert "\n")
+ (forward-line -1)
+ (insert "\n\f\n;;; "))
+
+(defun b/insert-asterism ()
+ "Insert a centred asterism."
+ (interactive)
+ (let ((asterism "* * *"))
+ (insert
+ (concat
+ "\n"
+ (make-string
+ (floor (/ (- fill-column (length asterism)) 2))
+ ?\s)
+ asterism
+ "\n"))))
+
+(defun b/start-process (program &rest args)
+ "Same as `start-process', but doesn't bother about name and buffer."
+ (let ((process-name (concat program "_process"))
+ (buffer-name (generate-new-buffer-name
+ (concat program "_output"))))
+ (apply #'start-process
+ process-name buffer-name program args)))
+
+(defun b/no-mouse-autoselect-window ()
+ "Conveniently disable `focus-follows-mouse'.
+For disabling the behaviour for certain buffers and/or modes."
+ (make-local-variable 'mouse-autoselect-window)
+ (setq mouse-autoselect-window nil))
+
+(defun b/kill-current-buffer ()
+ "Kill the current buffer."
+ ;; also see https://redd.it/64xb3q
+ (interactive)
+ (kill-buffer (current-buffer)))
+
+(defun b/move-indentation-or-beginning-of-line (arg)
+ "Move to the indentation or to the beginning of line."
+ (interactive "^p")
+ ;; (if (bolp)
+ ;; (back-to-indentation)
+ ;; (move-beginning-of-line arg))
+ (if (= (point)
+ (progn (back-to-indentation)
+ (point)))
+ (move-beginning-of-line arg)))
+
+(defun b/join-line-top ()
+ "Like `join-line', but join next line to the current line."
+ (interactive)
+ (join-line 1))
+
+(defun b/duplicate-line-or-region (&optional n)
+ "Duplicate the current line, or region (if active).
+Make N (default: 1) copies of the current line or region."
+ (interactive "*p")
+ (let ((u-r-p (use-region-p)) ; if region is active
+ (n1 (or n 1)))
+ (save-excursion
+ (let ((text
+ (if u-r-p
+ (buffer-substring (region-beginning) (region-end))
+ (prog1 (thing-at-point 'line)
+ (end-of-line)
+ (if (eobp)
+ (newline)
+ (forward-line 1))))))
+ (dotimes (_ (abs n1))
+ (insert text))))))
+
+\f
;;; General key bindings
(global-set-key (kbd "C-a") #'b/move-indentation-or-beginning-of-line)
\f
;;; Essential packages
+(add-to-list
+ 'load-path
+ (expand-file-name
+ (convert-standard-filename "lisp") user-emacs-directory))
+
;; (require 'bandali-exwm)
(require 'bandali-org)
(require 'bandali-theme)
-;; magit, *the* right way to do git
-(csetq transient-history-file (b/var "transient/history.el")
- transient-levels-file (b/etc "transient/levels.el")
- transient-values-file (b/etc "transient/values.el"))
-(with-eval-after-load 'magit
- (declare-function magit-add-section-hook "magit-section"
- (hook function &optional at append local))
- (magit-add-section-hook 'magit-status-sections-hook
- 'magit-insert-modules
- 'magit-insert-stashes
- 'append)
- ;; (magit-add-section-hook 'magit-status-sections-hook
- ;; 'magit-insert-ignored-files
- ;; 'magit-insert-untracked-files
- ;; 'append)
- (declare-function magit-display-buffer-fullframe-status-v1
- "magit-mode" (buffer))
- (csetq
- magit-diff-refine-hunk t
- magit-repository-directories '(("~/.emacs.d/" . 0)
- ("~/src/git/" . 2))
- ;; magit-completing-read-function 'magit-ido-completing-read
- magit-display-buffer-function
- #'magit-display-buffer-fullframe-status-v1)
- (nconc magit-section-initial-visibility-alist
- '(([unpulled status] . show)
- ([unpushed status] . show)))
- (custom-set-faces '(magit-diff-file-heading ((t (:weight normal)))))
-
- (with-eval-after-load 'magit-extras
- (csetq
- magit-pop-revision-stack-format
- (pcase-let ((`(,pt ,_eob ,index-regexp)
- (default-value 'magit-pop-revision-stack-format)))
- `(,pt "[%N: %h]: %ci\n %s
- https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=%H"
- ,index-regexp)))))
-;; global key bindings
-(global-set-key (kbd "C-x g") #'magit-status)
-(global-set-key (kbd "C-c g b") #'magit-blame-addition)
-(global-set-key (kbd "C-c g l") #'magit-log-buffer-file)
-(global-set-key (kbd "C-c g y") #'magit-pop-revision-stack)
+;; (require 'bandali-magit)
;; recently opened files
+(csetq recentf-max-saved-items 2000
+ recentf-save-file (b/var "recentf-save.el"))
(run-with-idle-timer 0.2 nil #'require 'recentf)
(with-eval-after-load 'recentf
- (csetq recentf-max-saved-items 2000
- recentf-save-file (b/var "recentf-save.el"))
- (add-to-list 'recentf-keep #'file-remote-p)
+ ;; (add-to-list 'recentf-keep #'file-remote-p)
(recentf-mode))
;; needed for history for counsel
(csetq amx-save-file (b/var "amx-save.el"))
+(add-to-list 'load-path (b/lisp "s"))
+(add-to-list 'load-path (b/lisp "amx"))
(run-with-idle-timer 0.3 nil #'require 'amx)
(with-eval-after-load 'amx
(amx-mode))
-;; (require 'bandali-ido)
(require 'bandali-ivy)
(require 'bandali-eshell)
-;; (require 'bandali-multi-term)
(require 'bandali-ibuffer)
(with-eval-after-load 'help
(temp-buffer-resize-mode)
- (csetq help-window-select t)
+ (csetq help-window-select t))
+(with-eval-after-load 'help-mode
;; local key bindings
(define-key help-mode-map (kbd "p") #'backward-button)
(define-key help-mode-map (kbd "n") #'forward-button))
(require 'bandali-message)
(require 'bandali-ebdb)
-;; IRC (with ERC and ZNC)
+;; IRC (with ERC)
(require 'bandali-erc)
+;; 'paste' service (aka scp + web server)
+(add-to-list 'load-path (b/lisp "scpaste"))
(with-eval-after-load 'scpaste
(csetq scpaste-http-destination "https://p.bndl.org"
scpaste-scp-destination "p:~"))
+(autoload 'scpaste "scpaste" nil t)
+(autoload 'scpaste-region "scpaste" nil t)
(global-set-key (kbd "C-c a p p") #'scpaste)
(global-set-key (kbd "C-c a p r") #'scpaste-region)
;; display Lisp objects at point in the echo area
(when (version< "25" emacs-version)
(with-eval-after-load 'eldoc
- (global-eldoc-mode)))
+ (csetq eldoc-minor-mode-string " eldoc")
+ (global-eldoc-mode)))
;; highlight matching parens
(require 'paren)
;; yanking (pasting) what I'd originally intended to.
save-interprogram-paste-before-kill t)
(with-eval-after-load 'simple
- (column-number-mode))
+ (column-number-mode 1))
;; save minibuffer history
(require 'savehist)
(global-prettify-symbols-mode))
(add-hook 'prog-mode-hook #'indicate-buffer-boundaries-left)
-(define-key text-mode-map (kbd "C-*") #'b/insert-asterism)
+(define-key text-mode-map (kbd "C-<return>") #'b/insert-asterism)
(add-hook 'text-mode-hook #'indicate-buffer-boundaries-left)
(add-hook 'text-mode-hook #'flyspell-mode)
(add-to-list 'auto-mode-alist '("\\.bashrc$" . sh-mode))
+(with-eval-after-load 'flyspell
+ (csetq flyspell-mode-line-string " fly"))
+
;; flycheck
;; (run-with-idle-timer 0.6 nil #'require 'flycheck)
;; (with-eval-after-load 'flycheck
;; #'endless/replace-quote))
;; abbrev
-(csetq abbrev-file-name (b/var "abbrev.el"))
+(csetq abbrev-file-name (b/etc "abbrev.el"))
(add-hook 'text-mode-hook #'abbrev-mode)
\f
(setq indent-tabs-mode nil))
(add-hook 'lisp-interaction-mode-hook #'indent-spaces-mode))
+;; alloy
+(add-to-list 'load-path (b/lisp "alloy-mode"))
+(autoload 'alloy-mode "alloy-mode" nil t)
(with-eval-after-load 'alloy-mode
(csetq alloy-basic-offset 2)
;; (defun b/alloy-simple-indent (start end)
(with-eval-after-load 'man
(csetq Man-width 80))
-(run-with-idle-timer 0.4 nil #'require 'which-key)
-(with-eval-after-load 'which-key
- (csetq
- which-key-add-column-padding 5
- which-key-idle-delay 10000
- which-key-idle-secondary-delay 0.05
- which-key-max-description-length 32
- which-key-show-early-on-C-h t)
- (which-key-add-key-based-replacements
- ;; prefixes for global prefixes and minor modes
- "C-c !" "flycheck"
- "C-x RET" "coding system"
- "C-x 8" "unicode"
- "C-x @" "event modifiers"
- "C-x a" "abbrev/expand"
- "C-x r" "rectangle/register/bookmark"
- "C-x t" "tabs"
- "C-x v" "version control"
- "C-x X" "edebug"
- "C-x C-a" "edebug"
- "C-x C-k" "kmacro"
- ;; prefixes for my personal bindings
- "C-c &" "yasnippet"
- "C-c a" "applications"
- "C-c a e" "erc"
- "C-c a o" "org"
- "C-c a s" "shells"
- "C-c b" "buffers"
- "C-c c" "compile-and-comments"
- "C-c e" "eval"
- "C-c f" "files"
- "C-c F" "frames"
- "C-c g" "magit"
- "C-S-h" "help(ful)"
- "C-c q" "boxquote"
- "C-c t" "themes")
- ;; prefixes for major modes
- (which-key-add-major-mode-key-based-replacements 'org-mode
- "C-c C-v" "org-babel")
- (which-key-mode))
-
-;; (require 'bandali-projectile)
-
-(run-with-idle-timer 0.6 nil #'require 'unkillable-scratch)
-(with-eval-after-load 'unkillable-scratch
- (csetq unkillable-buffers '("^\\*scratch\\*$" "^\\*Messages\\*$"))
- (unkillable-scratch 1))
+(defun b/*scratch* ()
+ "Switch to `*scratch*' buffer, creating it if it does not exist."
+ (interactive)
+ (switch-to-buffer
+ (or (get-buffer "*scratch*")
+ (with-current-buffer (get-buffer-create "*scratch*")
+ (set-buffer-major-mode (current-buffer))
+ (current-buffer)))))
+(global-set-key (kbd "C-c s") #'b/*scratch*)
;; ,----
;; | make pretty boxed quotes like this
;; `----
+(add-to-list 'load-path (b/lisp "boxquote"))
(run-with-idle-timer 0.6 nil #'require 'boxquote)
(with-eval-after-load 'boxquote
(defvar b/boxquote-prefix-map)
(define-key b/boxquote-prefix-map (kbd "M-q") #'boxquote-fill-paragraph)
(define-key b/boxquote-prefix-map (kbd "M-w") #'boxquote-kill-ring-save))
+(add-to-list 'load-path (b/lisp "hl-todo"))
(run-with-idle-timer 0.5 nil #'require 'hl-todo)
(with-eval-after-load 'hl-todo
;; highlight TODOs in buffers
(global-hl-todo-mode))
+(add-to-list 'load-path (b/lisp "page-break-lines"))
(run-with-idle-timer 0.5 nil #'require 'page-break-lines)
(with-eval-after-load 'page-break-lines
(csetq page-break-lines-max-width fill-column)
(getenv "XDG_DOWNLOAD_DIR")))
(global-set-key (kbd "C-c a e w") #'eww)
-(comment
-
-;; org-ref
-(csetq
- reftex-default-bibliography '("~/usr/org/references.bib")
- org-ref-default-bibliography '("~/usr/org/references.bib")
- org-ref-bibliography-notes "~/usr/org/notes.org"
- org-ref-pdf-directory "~/usr/org/bibtex-pdfs/")
+;; ;; org-ref
+;; (csetq
+;; reftex-default-bibliography '("~/usr/org/references.bib")
+;; org-ref-default-bibliography '("~/usr/org/references.bib")
+;; org-ref-bibliography-notes "~/usr/org/notes.org"
+;; org-ref-pdf-directory "~/usr/org/bibtex-pdfs/")
;; fill-column-indicator ?
(global-set-key (kbd "C-c w L") #'windmove-swap-states-right)
;; pass
-(global-set-key (kbd "C-c a p") #'pass)
-(add-hook 'pass-mode-hook #'View-exit)
+;; (global-set-key (kbd "C-c a p") #'pass)
+;; (add-hook 'pass-mode-hook #'View-exit)
;; reftex
;; uncomment to disable reftex-cite's default choice of previous word
(add-hook 'latex-mode-hook #'reftex-mode)
;; dmenu
-(csetq
- dmenu-prompt-string "run: "
- dmenu-save-file (b/var "dmenu-items"))
+;; (csetq
+;; dmenu-prompt-string "run: "
+;; dmenu-save-file (b/var "dmenu-items"))
;; eosd ?
+;; delight
+(run-with-idle-timer 0.5 nil #'require 'delight)
+(with-eval-after-load 'delight
+ (delight 'auto-fill-function " f" "simple")
+ (delight 'abbrev-mode "" "abbrev")
+ (delight 'page-break-lines-mode "" "page-break-lines")
+ (delight 'ivy-mode "" "ivy")
+ (delight 'counsel-mode "" "counsel")
+ (delight 'mml-mode " mml" "mml")
+ (delight 'yas-minor-mode "" "yasnippet"))
+
\f
;;; Post initialization
-)
(message "Loading %s...done (%.3fs)" user-init-file
(float-time (time-subtract (current-time)
b/before-user-init-time)))