about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--bash/aliases.bash11
-rw-r--r--bash/bash_profile7
-rw-r--r--bash/functions.bash21
-rw-r--r--bash/prompt.bash2
-rw-r--r--bootstrap.manifest9
-rw-r--r--chicken/csirc2
-rw-r--r--emacs.el1029
-rwxr-xr-xnotmuch/default/hooks/post-new10
-rwxr-xr-xnotmuch/default/hooks/pre-new2
-rw-r--r--profile/00_functions.sh69
-rw-r--r--profile/01_path.sh19
-rw-r--r--profile/bc.sh2
-rw-r--r--profile/chicken.sh.disabled2
-rw-r--r--profile/gauche.sh2
-rw-r--r--profile/go.sh2
-rw-r--r--profile/less.sh2
-rw-r--r--profile/luarocks.sh6
-rw-r--r--profile/manpath.sh5
-rw-r--r--profile/nodejs.sh3
-rw-r--r--profile/npm.sh4
-rw-r--r--profile/python.sh5
-rw-r--r--profile/rust.sh9
-rw-r--r--profile/ssh-agent.sh7
-rw-r--r--profile/xdg.sh84
-rw-r--r--profile/xfce.sh4
-rw-r--r--profile/xorg.sh10
-rw-r--r--readline/inputrc10
-rw-r--r--systemd/user/emacs.service12
28 files changed, 1128 insertions, 222 deletions
diff --git a/bash/aliases.bash b/bash/aliases.bash index 6515873..18cd7d2 100644 --- a/bash/aliases.bash +++ b/bash/aliases.bash
@@ -10,14 +10,19 @@ sudo_cmds=(
10 visudo 10 visudo
11) 11)
12for cmd in "${sudo_cmds[@]}"; do 12for cmd in "${sudo_cmds[@]}"; do
13 alias $cmd="sudo $cmd" 13 if command -v sudo >/dev/null 2>&1; then
14 alias $cmd="sudo $cmd"
15 elif command -v doas >/dev/null 2>&1; then
16 alias $cmd="doas $cmd"
17 alias sudo=doas
18 fi
14done 19done
15 20
16# LS 21# LS
17alias ls='ls -F --color=never' 22alias ls='ls -F --color=never'
18alias ll='ls -l' 23alias ll='ls -l'
19# tree 24# tree
20alias tree='tree -F' 25#alias tree='tree -F'
21 26
22# make locally 27# make locally
23alias lake='make PREFIX=$LOCAL_PREFIX ' 28alias lake='make PREFIX=$LOCAL_PREFIX '
@@ -37,6 +42,8 @@ fi
37 42
38alias e="$EDITOR" 43alias e="$EDITOR"
39 44
45alias crontab='env EDITOR=ed VISUAL=vi crontab'
46
40## ffmpeg 47## ffmpeg
41# agafnd | i have ffmpeg and ffprobe aliased to ffwhatever -hide_banner 48# agafnd | i have ffmpeg and ffprobe aliased to ffwhatever -hide_banner
42# agafnd | because if you don't do this it spits out all of the options it was 49# agafnd | because if you don't do this it spits out all of the options it was
diff --git a/bash/bash_profile b/bash/bash_profile index 4439ca7..92ce061 100644 --- a/bash/bash_profile +++ b/bash/bash_profile
@@ -2,3 +2,10 @@
2 2
3[[ -f ~/.profile ]] && source ~/.profile 3[[ -f ~/.profile ]] && source ~/.profile
4[[ -f ~/.bashrc ]] && source ~/.bashrc 4[[ -f ~/.bashrc ]] && source ~/.bashrc
5
6# start sway on tty 1
7
8if test -z "$DISPLAY" && test /dev/tty1 = "$(tty)"
9then
10 swayrun
11fi
diff --git a/bash/functions.bash b/bash/functions.bash index debea2c..4241c8d 100644 --- a/bash/functions.bash +++ b/bash/functions.bash
@@ -139,3 +139,24 @@ up() {
139 UP_SPECIALARGS= 139 UP_SPECIALARGS=
140 return "$ret" 140 return "$ret"
141} 141}
142
143apk() { # wrapper for apk(1)
144 apk="$(which apk)"
145 test -z "$apk" && return 1
146 case "$1" in
147 add|del|fix|update|upgrade) doas "$apk" "$@" ;;
148 install) shift; apk add "$@" ;;
149 remove) shift; apk del "$@" ;;
150 *) "$apk" "$@" ;;
151 esac
152}
153
154sl() {
155 printf >&2 '%s\n' "CHOO CHOO!"
156 ls "$@"
157}
158
159mkssh() {
160 ssh-keygen -t ed25519 -f "$HOME/.ssh/$1"
161 cat "$HOME/.ssh/$1.pub" | tee /dev/stdout | wl-copy
162}
diff --git a/bash/prompt.bash b/bash/prompt.bash index bee5223..e51db96 100644 --- a/bash/prompt.bash +++ b/bash/prompt.bash
@@ -71,7 +71,7 @@ smiley_prompt() {
71 git_prompt_integration 71 git_prompt_integration
72 72
73 PS1+='\[$(__prompt_term_title "$USER@$(hostname): $PWD")\]' 73 PS1+='\[$(__prompt_term_title "$USER@$(hostname): $PWD")\]'
74 PS1+='\$ ' 74 PS1+=' \$ '
75} 75}
76 76
77eval "$MY_BASH_PROMPT" 77eval "$MY_BASH_PROMPT"
diff --git a/bootstrap.manifest b/bootstrap.manifest index 657095d..991a0d9 100644 --- a/bootstrap.manifest +++ b/bootstrap.manifest
@@ -17,10 +17,13 @@ profile/profile ~/.profile
17# Mail 17# Mail
18mail/mbsyncrc ~/.mbsyncrc 18mail/mbsyncrc ~/.mbsyncrc
19 19
20# Emacs
21emacs.el ~/.emacs
22
20# Xorg 23# Xorg
21xorg/xinitrc ~/.xinitrc 24#xorg/xinitrc ~/.xinitrc
22xorg/xsession ~/.xsession 25#xorg/xsession ~/.xsession
23xorg/xcompose ~/.Xcompose 26#xorg/xcompose ~/.Xcompose
24 27
25# SBCL 28# SBCL
26sbcl/sbclrc ~/.sbclrc \ No newline at end of file 29sbcl/sbclrc ~/.sbclrc \ No newline at end of file
diff --git a/chicken/csirc b/chicken/csirc index 9ff6c9d..ac2ef22 100644 --- a/chicken/csirc +++ b/chicken/csirc
@@ -4,6 +4,8 @@
4(import (chicken load)) 4(import (chicken load))
5(load-verbose #f) 5(load-verbose #f)
6(import (utf8)) 6(import (utf8))
7;; chicken-doc
8(require-library chicken-doc)
7;; set up breadline 9;; set up breadline
8(let () 10(let ()
9 (import (chicken format)) 11 (import (chicken format))
diff --git a/emacs.el b/emacs.el new file mode 100644 index 0000000..c6d361b --- /dev/null +++ b/emacs.el
@@ -0,0 +1,1029 @@
1;;; ~/.emacs -*- mode: emacs-lisp; lexical-binding: t; -*-
2;; by Case Duckworth <acdw@acdw.net>
3;; Bankruptcy 10: "Annoyance"
4
5;;; Commentary:
6
7;; This is my Emacs configuration. There are many like it but this
8;; one is mine.
9;;
10;; For the tenth time!
11
12;;; Code:
13
14(add-hook 'after-init-hook
15 (lambda ()
16 (load (locate-user-emacs-file "private"))))
17
18;;; Definitions:
19
20(defun reset-faces ()
21 (dolist (face '(font-lock-regexp-face
22 font-lock-builtin-face
23 font-lock-variable-name-face
24 font-lock-preprocessor-face
25 font-lock-remove-face
26 font-lock-delimiter-face
27 font-lock-label-face
28 font-lock-operator-face
29 font-lock-property-face
30 font-lock-builtin-face
31 font-lock-number-face
32 font-lock-keyword-face
33 font-lock-set-face
34 font-lock-warning-face
35 font-lock-punctuation-face
36 font-lock-constant-face
37 font-lock-type-face
38 font-lock-function-name-face
39 font-lock-reference-face
40 font-lock-misc-punctuation-face
41 font-lock-bracket-face))
42 (face-spec-set face '((t :foreground unspecified
43 :background unspecified)))))
44
45(defun electric-pair-local-mode-disable ()
46 "Disable `electric-pair-mode', locally."
47 (electric-pair-local-mode -1))
48
49(defun kill-this-buffer (&optional buffer-or-name)
50 "Kill this buffer, or BUFFER-OR-NAME.
51When called interactvely, the user will be prompted when passing
52\\[universal-argument]."
53 (interactive "P")
54 (cond
55 ((bufferp buffer-or-name)
56 (kill-buffer buffer-or-name))
57 ((null buffer-or-name)
58 (kill-current-buffer))
59 (:else
60 (kill-buffer (read-buffer "Kill: " nil :require-match)))))
61
62(defun define-org-capture-template (description &rest args)
63 "Define an template for `org-capture-templates'.
64Will not replace an existing template unless `:force' in ARGS is
65non-nil. ARGS is a plist, which in addition to the additional
66options `org-capture-templates' accepts (which see), also accepts
67the following: `:keys', `:description', `:type', `:target', and
68`:template'."
69 (declare (indent 1))
70 (let* ((keys (plist-get args :keys))
71 (type (plist-get args :type))
72 (target (plist-get args :target))
73 (template (plist-get args :template))
74 (force (plist-get args :force))
75 (template-value
76 (append
77 (list description)
78 (when (or type target template)
79 (list (or type 'entry) target template))
80 (cl-loop for i from 0 below (length args) by 2
81 unless (member (nth i args)
82 '( :keys :description :type
83 :target :template))
84 append (list (nth i args)
85 (plist-get args (nth i args)))))))
86 (if (seq-find (lambda (el) (equal (car el) keys))
87 org-capture-templates)
88 (and force
89 (setf (alist-get keys org-capture-templates nil nil #'equal)
90 template-value))
91 (setf org-capture-templates
92 (append org-capture-templates
93 (list (cons keys template-value)))))
94 org-capture-templates))
95
96(defun other-window-or-switch-buffer (&optional arg)
97 "Switch to the other window.
98If a window is the only buffer on a frame, switch buffer. When
99run with \\[universal-argument], unconditionally switch buffer."
100 (interactive "P")
101 (if (or arg (one-window-p))
102 (switch-to-buffer (other-buffer) nil t)
103 (other-window 1)))
104
105(defun cycle-spacing@ (&optional n)
106 ;; `cycle-spacing' is wildly different in 29.1 over 28.
107 "Negate N argument on `cycle-spacing'.
108That is, with a positive N, deletes newlines as well, leaving -N
109spaces. If N is negative, it will not delete newlines and leave
110N spaces."
111 (interactive "*p")
112 (cycle-spacing (- n)))
113
114(defun first-frame@set-fonts ()
115 (remove-hook 'server-after-make-frame-hook
116 #'first-frame@set-fonts)
117 (face-spec-set 'default
118 `((t :family "Recursive Mono Casual Static"
119 :height 110)))
120 (face-spec-set 'variable-pitch
121 `((t :family "Recursive Sans Casual Static"
122 :height 1.0)))
123 ;; Emojis
124 (cl-loop with ffl = (font-family-list)
125 for font in '("Noto Emoji" "Noto Color Emoji"
126 "Segoe UI Emoji" "Apple Color Emoji"
127 "FreeSans" "FreeMono" "FreeSerif"
128 "Unifont" "Symbola")
129 if (member font ffl)
130 do (set-fontset-font t 'symbol font))
131 ;; International fonts
132 (cl-loop with ffl = (font-family-list)
133 for (charset . font)
134 in '((latin . "Noto Sans")
135 (han . "Noto Sans CJK SC Regular")
136 (kana . "Noto Sans CJK JP Regular")
137 (hangul . "Noto Sans CJK KR Regular")
138 (cjk-misc . "Noto Sans CJK KR Regular")
139 (khmer . "Noto Sans Khmer")
140 (lao . "Noto Sans Lao")
141 (burmese . "Noto Sans Myanmar")
142 (thai . "Noto Sans Thai")
143 (ethiopic . "Noto Sans Ethiopic")
144 (hebrew . "Noto Sans Hebrew")
145 (arabic . "Noto Sans Arabic")
146 (gujarati . "Noto Sans Gujarati")
147 (devanagari . "Noto Sans Devanagari")
148 (kannada . "Noto Sans Kannada")
149 (malayalam . "Noto Sans Malayalam")
150 (oriya . "Noto Sans Oriya")
151 (sinhala . "Noto Sans Sinhala")
152 (tamil . "Noto Sans Tamil")
153 (telugu . "Noto Sans Telugu")
154 (tibetan . "Noto Sans Tibetan"))
155 if (member font ffl)
156 do (set-fontset-font t charset font))
157 ;; XXX: tab-bar does a weird thing, so i set it up here....
158 (setopt tab-bar-show t)
159 (tab-bar-mode))
160
161(defun renz/sort-by-alpha-length (elems)
162 "Sort ELEMS first alphabetically, then by length."
163 (sort elems (lambda (c1 c2)
164 (or (string-version-lessp c1 c2)
165 (< (length c1) (length c2))))))
166
167(defun renz/sort-by-history (elems)
168 "Sort ELEMS by minibuffer history.
169Use `mct-sort-sort-by-alpha-length' if no history is available."
170 (if-let ((hist (and (not (eq minibuffer-history-variable t))
171 (symbol-value minibuffer-history-variable))))
172 (minibuffer--sort-by-position hist elems)
173 (renz/sort-by-alpha-length elems)))
174
175(defun renz/completion-category ()
176 "Return completion category."
177 (when-let ((window (active-minibuffer-window)))
178 (with-current-buffer (window-buffer window)
179 (completion-metadata-get
180 (completion-metadata (buffer-substring-no-properties
181 (minibuffer-prompt-end)
182 (max (minibuffer-prompt-end) (point)))
183 minibuffer-completion-table
184 minibuffer-completion-predicate)
185 'category))))
186
187(defun renz/sort-multi-category (elems)
188 "Sort ELEMS per completion category."
189 (pcase (renz/completion-category)
190 ('nil elems) ; no sorting
191 ('kill-ring elems)
192 ('project-file (renz/sort-by-alpha-length elems))
193 (_ (renz/sort-by-history elems))))
194
195(defvar no-tabs-modes '(emacs-lisp-mode
196 lisp-mode
197 scheme-mode
198 python-mode
199 haskell-mode)
200 "Modes /not/ to indent with tabs.")
201
202(defun indent-tabs-mode-maybe ()
203 (if (apply #'derived-mode-p no-tabs-modes)
204 (indent-tabs-mode -1)
205 (indent-tabs-mode 1)))
206
207(define-minor-mode truncate-lines-mode
208 "Buffer-local mode to toggle `truncate-lines'."
209 :lighter ""
210 (setq-local truncate-lines truncate-lines-mode))
211
212;;; Region or buffer stuff
213
214(defun call-with-region-or-buffer (fn &rest _r)
215 "Call function FN with current region or buffer.
216Good to use for :around advice."
217 (if (region-active-p)
218 (funcall fn (region-beginning) (region-end))
219 (funcall fn (point-min) (point-max))))
220
221(defun delete-trailing-whitespace-except-current-line ()
222 (save-excursion
223 (delete-trailing-whitespace (point-min)
224 (line-beginning-position))
225 (delete-trailing-whitespace (line-end-position)
226 (point-max))))
227
228(defun create-missing-directories ()
229 "Automatically create missing directories."
230 (let ((target-dir (file-name-directory buffer-file-name)))
231 (unless (file-exists-p target-dir)
232 (make-directory target-dir :parents))))
233
234
235(defun vc-remote-off ()
236 "Turn VC off when remote."
237 (when (file-remote-p (buffer-file-name))
238 (setq-local vc-handled-backends nil)))
239
240(defun +titlecase-sentence-style-dwim (&optional arg)
241 "Titlecase a sentence.
242With prefix ARG, toggle the value of
243`titlecase-downcase-sentences' before sentence-casing."
244 (interactive "P")
245 (let ((titlecase-downcase-sentences (if arg (not titlecase-downcase-sentences)
246 titlecase-downcase-sentences)))
247 (titlecase-dwim 'sentence)))
248
249(defun +titlecase-org-headings ()
250 (interactive)
251 (require 'org)
252 (save-excursion
253 (goto-char (point-min))
254 ;; See also `org-map-tree'. I'm not using that function because I want to
255 ;; skip the first headline. A better solution would be to patch
256 ;; `titlecase-line' to ignore org-mode metadata (TODO cookies, tags, etc).
257 (let ((level (funcall outline-level))
258 (org-special-ctrl-a/e t))
259 (while (and (progn (outline-next-heading)
260 (> (funcall outline-level) level))
261 (not (eobp)))
262 (titlecase-region (progn (org-beginning-of-line) (point))
263 (progn (org-end-of-line) (point)))))))
264
265(defcustom browse-url-safe-browser-functions nil
266 "\"Safe\" browser functions."
267 :type '(repeat-function))
268
269(defun browse-url-browser-function-safe-p (fn)
270 "Return t if FN is a \"safe\" browser function."
271 (memq f (append browse-url-safe-browser-functions
272 (mapcar (lambda (i)
273 (plist-get (cdr i) :value))
274 (seq-filter (lambda (i)
275 (eq (car i) 'function-item))
276 (cdr (get 'browse-url-browser-function
277 'custom-type)))))))
278
279(put 'browse-url-browser-function 'safe-local-variable
280 'browse-url-browser-function-safe-p)
281
282
283;;; Packages:
284
285(require 'package)
286(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
287(package-initialize)
288
289(defun ensure-package (pkg &optional localp)
290 "Esnure PKG is installed from repositories.
291If LOCALP is t, add ~/src/PKG.el to `load-path'.
292If LOCALP is a string, add that directory to the `load-path'."
293 (cond
294 ((stringp localp)
295 (and (file-exists-p localp)
296 (add-to-list 'load-path localp)))
297 (localp
298 (ensure-package pkg
299 (expand-file-name
300 (format "~/src/%s.el"
301 (symbol-name pkg)))))
302 (:else
303 (unless (package-installed-p pkg)
304 (unless (ignore-errors (package-install pkg))
305 (package-refresh-contents)
306 (package-install pkg))))))
307
308;; Install packages here. Acutal configuration is done in the Configuration
309;; section.
310(ensure-package 'consult)
311(ensure-package 'marginalia)
312(ensure-package 'visual-fill-column)
313(ensure-package 'adaptive-wrap)
314(ensure-package 'geiser)
315(when (executable-find "csi")
316 (ensure-package 'geiser-chicken))
317(ensure-package 'avy)
318(ensure-package 'zzz-to-char)
319(ensure-package 'hungry-delete)
320(ensure-package 'undohist)
321(ensure-package 'jinx)
322(ensure-package 'markdown-mode)
323(ensure-package 'anzu)
324
325;; Local packages
326(ensure-package 'scule t)
327(ensure-package 'frowny t)
328(ensure-package 'hippie-completing-read t)
329(ensure-package 'mode-line-bell t)
330(ensure-package 'titlecase t)
331(ensure-package 'jabber t)
332
333;;; Jabber
334
335(use-package jabber
336 :load-path "~/src/jabber.el"
337 :defer t
338 :bind-keymap (("C-c j" . jabber-global-keymap))
339 :preface nil
340 (setq-default jabber-chat-buffer-format "*%n*"
341 jabber-browse-buffer-format "*%n*"
342 jabber-groupchat-buffer-format "*%n*"
343 jabber-muc-private-buffer-format "*%n*")
344 :custom-face
345 (jabber-activity-face ((t :inherit jabber-chat-prompt-foreign
346 :foreground unspecified
347 :weight normal)))
348 (jabber-activity-personal-face ((t :inherit jabber-chat-prompt-local
349 :foreground unspecified
350 :weight bold)))
351 (jabber-chat-prompt-local ((t :inherit minibuffer-prompt
352 :foreground unspecified
353 :weight normal
354 :slant italic)))
355 (jabber-chat-prompt-foreign ((t :inherit warning
356 :foreground unspecified
357 :weight normal)))
358 (jabber-chat-prompt-system ((t :inherit font-lock-doc-face
359 :foreground unspecified)))
360 (jabber-rare-time-face ((t :inherit font-lock-comment-face
361 :foreground unspecified
362 :underline nil)))
363 :config
364 (require 'jabber-httpupload nil t)
365 (setopt jabber-auto-reconnect t
366 jabber-last-read-marker "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~"
367 jabber-muc-decorate-presence-patterns
368 '(("\\( enters the room ([^)]+)\\| has left the chatroom\\)$" . nil)
369 ("Mode #.*" . jabber-muc-presence-dim)
370 ("." . jabber-muc-presence-dim))
371 jabber-activity-make-strings #'jabber-activity-make-strings-shorten
372 jabber-rare-time-format
373 (format " - - - - - %%H:%d %%F"
374 (let ((min (string-to-number (format-time-string "%M"))))
375 (* 5 (floor min 5))))
376 jabber-muc-header-line-format '(" " jabber-muc-topic))
377
378 (setopt jabber-groupchat-prompt-format "%n. "
379 jabber-chat-local-prompt-format "%n. "
380 jabber-chat-foreign-prompt-format "%n. "
381 jabber-muc-private-foreign-prompt-format "%g/%n. ")
382
383 (keymap-global-set "C-c C-SPC" #'jabber-activity-switch-to)
384 (map-keymap (lambda (key command)
385 (define-key jabber-global-keymap (vector (+ key #x60)) command))
386 jabber-global-keymap)
387 (keymap-global-set "C-x C-j" #'dired-jump)
388
389 (add-hook 'jabber-post-connect-hooks #'jabber-enable-carbons)
390 (remove-hook 'jabber-alert-muc-hooks 'jabber-muc-echo)
391 (remove-hook 'jabber-alert-presence-hooks 'jabber-presence-echo)
392 (add-hook 'jabber-chat-mode-hook 'visual-line-mode)
393 (add-hook 'jabber-chat-mode-hook (defun jabber-no-position ()
394 (setq-local mode-line-position nil)))
395
396 (add-hook 'jabber-alert-muc-hooks
397 (defun jabber@highlight-acdw (&optional _ _ buf _ _)
398 (when buf
399 (with-current-buffer buf
400 (let ((regexp (rx word-boundary
401 "acdw" ; maybe get from the config?
402 word-boundary)))
403 (hi-lock-unface-buffer regexp)
404 (highlight-regexp regexp 'jabber-chat-prompt-local))))))
405
406 (when (fboundp 'jabber-chat-update-focus)
407 (add-hook 'window-configuration-change-hook #'jabber-chat-update-focus)))
408
409
410;;; Configuration:
411
412(setopt custom-file (locate-user-emacs-file "custom.el"))
413(load custom-file :noerror)
414
415;;; General keybinding changes
416
417(keymap-global-set "M-o" #'other-window-or-switch-buffer)
418(keymap-global-set "M-SPC" #'cycle-spacing@)
419(keymap-global-set "M-u" #'universal-argument)
420(keymap-set universal-argument-map "M-u" #'universal-argument-more)
421
422;;; Theme
423
424(if (daemonp)
425 (add-hook 'server-after-make-frame-hook #'first-frame@set-fonts)
426 (run-with-idle-timer 1 nil #'first-frame@set-fonts))
427
428(tool-bar-mode -1)
429
430(setopt modus-themes2-bold-constructs nil
431 modus-themes-italic-constructs t
432 modus-themes-variable-pitch-ui t)
433
434(add-hook 'modus-themes-after-load-theme-hook #'reset-faces)
435
436(load-theme 'modus-vivendi :no-confirm :no-enable)
437(load-theme 'modus-operandi :no-confirm)
438
439(add-hook 'text-mode-hook #'visual-line-mode)
440(add-hook 'prog-mode-hook #'auto-fill-mode)
441(add-hook 'prog-mode-hook #'display-fill-column-indicator-mode)
442
443;;; Mode line
444
445(defvar mode-line-position
446 '(""
447 (:propertize
448 (""
449 (:eval (if line-number-mode "%3l" ""))
450 (:eval (if column-number-mode
451 (if column-number-indicator-zero-based
452 "/%2c"
453 "/%2C")
454 "")))
455 display (min-width (3.0)))
456 (:propertize (" [" (-3 "%p") "] ")
457 display (min-width (6.0)))))
458
459(setopt mode-line-format
460 '(("%e"
461 mode-line-front-space
462 (:propertize (""
463 mode-line-client
464 mode-line-modified
465 mode-line-remote)
466 display (min-width (3.0)))
467 " "
468 mode-line-buffer-identification
469 (vc-mode (" (" (:eval (string-trim vc-mode)) ")"))
470 " "
471 (mode-line-position mode-line-position)
472 mode-line-modes
473 mode-line-misc-info
474 mode-line-end-spaces)))
475
476;; Remove modes from mode-line
477(dolist (minor-mode '(frowny-mode
478 whitespace-mode
479 hungry-delete-mode))
480 (setf (alist-get minor-mode minor-mode-alist) (list ""))
481 (add-hook (intern (format "%s-hook" minor-mode))
482 (lambda ()
483 (setf (alist-get minor-mode minor-mode-alist) (list "")))))
484
485;;; Completion & minibuffer
486
487(fido-vertical-mode)
488(minibuffer-depth-indicate-mode)
489
490(setopt completion-auto-help (not icomplete-mode)
491 completion-auto-select 'second-tab
492 completions-header-format nil
493 completions-max-height 12
494 completions-format 'one-column
495 completion-styles '(basic partial-completion emacs22 flex)
496 completion-ignore-case t
497 read-buffer-completion-ignore-case t
498 read-file-name-completion-ignore-case t
499 completions-detailed t
500 enable-recursive-minibuffers t
501 file-name-shadow-properties '(invisible t intangible t)
502 minibuffer-eldef-shorten-default t
503 minibuffer-prompt-properties '( read-only t
504 cursor-intangible t
505 face minibuffer-prompt)
506 window-resize-pixelwise t
507 frame-resize-pixelwise t)
508
509(add-hook 'completion-list-mode-hook #'truncate-lines-mode)
510(add-hook 'minibuffer-setup-hook #'truncate-lines-mode)
511
512;; Up/down when completing in the minibuffer
513;; (define-key minibuffer-local-map (kbd "C-p") #'minibuffer-previous-completion)
514;; (define-key minibuffer-local-map (kbd "C-n") #'minibuffer-next-completion)
515
516;; Up/down when competing in a normal buffer
517;; (define-key completion-in-region-mode-map (kbd "C-p") #'minibuffer-previous-completion)
518;; (define-key completion-in-region-mode-map (kbd "C-n") #'minibuffer-next-completion)
519
520(setopt completions-sort #'renz/sort-multi-category)
521
522(setopt tab-always-indent 'complete)
523
524(file-name-shadow-mode)
525(minibuffer-electric-default-mode)
526
527(scroll-bar-mode -1)
528(menu-bar-mode -1)
529
530(add-hook 'prog-mode-hook #'indent-tabs-mode-maybe)
531
532(setopt electric-pair-skip-whitespace 'chomp)
533(electric-pair-mode)
534
535(setopt sh-basic-offset tab-width)
536
537(keymap-set emacs-lisp-mode-map "C-c C-c" #'eval-defun)
538(keymap-set emacs-lisp-mode-map "C-c C-k" #'eval-buffer)
539(keymap-set lisp-interaction-mode-map "C-c C-c" #'eval-defun)
540(keymap-set lisp-interaction-mode-map "C-c C-k" #'eval-buffer)
541
542(advice-add 'indent-region :around #'call-with-region-or-buffer)
543(advice-add 'tabify :around #'call-with-region-or-buffer)
544(advice-add 'untabify :around #'call-with-region-or-buffer)
545
546(with-eval-after-load 'scheme
547 (keymap-unset scheme-mode-map "M-o" t)
548 ;; Comparse "keywords" --- CHICKEN (http://wiki.call-cc.org/eggref/5/comparse)
549 (put 'sequence* 'scheme-indent-function 1)
550 (put 'satisfies 'scheme-indent-function 1)
551 (add-hook 'scheme-mode-hook #'geiser-mode))
552(with-eval-after-load 'geiser-mode
553 (keymap-set geiser-mode-map "C-c C-k" #'geiser-eval-buffer-and-go)
554 (keymap-unset geiser-mode-map "C-." t))
555
556
557(with-eval-after-load 'visual-fill-column
558 (setopt visual-fill-column-center-text t
559 visual-fill-column-width (+ fill-column 2))
560 (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust))
561(add-hook 'visual-line-mode-hook #'visual-fill-column-mode)
562(add-hook 'visual-line-mode-hook #'adaptive-wrap-prefix-mode)
563
564(setopt major-mode
565 (lambda () ; guess major mode from buffer name
566 (unless buffer-file-name
567 (let ((buffer-file-name (buffer-name)))
568 (set-auto-mode)))))
569
570;; Dialogs
571(unless (boundp 'use-short-answers)
572 (fset 'yes-or-no-p 'y-or-n-p))
573
574(setopt read-answer-short t
575 use-dialog-box nil
576 use-file-dialog nil
577 use-short-answers t)
578
579(require 'savehist)
580(setopt history-length 1024
581 history-delete-duplicates t
582 ;; savehist-file (etc/ "savehist.el")
583 savehist-save-minibuffer-history t
584 savehist-autosave-interval 30)
585(savehist-mode)
586
587;; Killing and yanking
588(setopt kill-do-not-save-duplicates t
589 kill-read-only-ok t
590 ;; XXX: This setting causes an error message the first time it's
591 ;; called: "Selection owner couldn't convert: TIMESTAMP". I have
592 ;; absolutely no idea why I get this error, but it's generated in
593 ;; `x_get_foreign_selection'. I also can't inhibit the message or
594 ;; do anything else with it, so for now, I'll just live with the
595 ;; message.
596 save-interprogram-paste-before-kill t
597 yank-pop-change-selection t)
598(delete-selection-mode)
599
600;; Notifying the user
601(setopt echo-keystrokes 0.01
602 ring-bell-function #'ignore)
603
604;; Point and mark
605(setopt set-mark-command-repeat-pop t)
606
607;; The system
608(setopt read-process-output-max (* 10 1024 1024))
609
610;; Startup
611(setopt inhibit-startup-screen t
612 initial-buffer-choice t
613 initial-scratch-message nil)
614
615(define-advice startup-echo-area-message (:override ())
616 (if (get-buffer "*Warnings*")
617 ";_;"
618 "^_^"))
619
620;; Text editing
621(setopt fill-column 80
622 sentence-end-double-space nil
623 tab-width 8
624 tab-always-indent 'complete)
625(global-so-long-mode)
626
627(setopt show-paren-delay 0.01
628 show-paren-style 'parenthesis
629 show-paren-when-point-in-periphery t
630 show-paren-when-point-inside-paren t)
631(show-paren-mode)
632
633
634;; Encodings
635(set-language-environment "UTF-8")
636(setopt buffer-file-coding-system 'utf-8-unix
637 coding-system-for-read 'utf-8-unix
638 coding-system-for-write 'utf-8-unix
639 default-process-coding-system '(utf-8-unix . utf-8-unix)
640 locale-coding-system 'utf-8-unix)
641(set-charset-priority 'unicode)
642(prefer-coding-system 'utf-8-unix)
643(set-default-coding-systems 'utf-8-unix)
644(set-terminal-coding-system 'utf-8-unix)
645(set-keyboard-coding-system 'utf-8-unix)
646(pcase system-type
647 ((or 'ms-dos 'windows-nt)
648 (set-clipboard-coding-system 'utf-16-le)
649 (set-selection-coding-system 'utf-16-le))
650 (_
651 (set-selection-coding-system 'utf-8)
652 (set-clipboard-coding-system 'utf-8)))
653
654
655;; Files
656(setopt auto-revert-verbose nil
657 global-auto-revert-non-file-buffers t
658 create-lockfiles nil
659 find-file-visit-truename t
660 mode-require-final-newline t
661 view-read-only t
662 save-silently t)
663(global-auto-revert-mode)
664
665(setopt auto-save-default nil
666 auto-save-interval 1
667 auto-save-no-message t
668 auto-save-timeout 1
669 auto-save-visited-interval 1
670 remote-file-name-inhibit-auto-save-visited t)
671(add-to-list 'auto-save-file-name-transforms
672 `(".*" ,(locate-user-emacs-file "auto-save/") t))
673(auto-save-visited-mode)
674
675(setopt backup-by-copying t
676 version-control t
677 kept-new-versions 8
678 kept-old-versions 8
679 delete-old-versions t)
680(setq-default backup-directory-alist
681 `(("^/dev/shm" . nil)
682 ("^/tmp" . nil)
683 (,(getenv "XDG_RUNTIME_DIR") . nil)
684 ("." . ,(locate-user-emacs-file "backup"))))
685
686(require 'recentf)
687(setopt
688 recentf-max-menu-items 500
689 recentf-max-saved-items nil ; Save the whole list
690 recentf-auto-cleanup 'mode
691 recentf-case-fold-search t)
692;; (add-to-list 'recentf-exclude etc/)
693(add-to-list 'recentf-exclude "-autoloads.el\\'")
694(add-hook 'buffer-list-update-hook #'recentf-track-opened-file)
695(add-hook 'after-save-hook #'recentf-save-list)
696(recentf-mode)
697
698(require 'saveplace)
699(setopt
700 save-place-forget-unreadable-files (eq system-type
701 'gnu/linux))
702(save-place-mode)
703
704(require 'uniquify)
705(setq uniquify-after-kill-buffer-p t
706 uniquify-buffer-name-style 'forward
707 uniquify-ignore-buffers-re "^\\*"
708 uniquify-separator path-separator)
709
710(setq-local vc-follow-symlinks t
711 vc-make-backup-files t)
712
713;; Whitespace
714(require 'whitespace)
715(setopt whitespace-style
716 '(face trailing tabs tab-mark))
717(global-whitespace-mode)
718(add-hook 'before-save-hook #'delete-trailing-whitespace-except-current-line)
719
720;; Native compilation
721(setopt native-comp-async-report-warnings-errors 'silent
722 native-comp-deferred-compilation t
723 native-compile-target-directory
724 (locate-user-emacs-file "eln"))
725(when (boundp 'native-comp-eln-load-path)
726 (add-to-list 'native-comp-eln-load-path native-compile-target-directory))
727(when (fboundp 'startup-redirect-eln-cache)
728 (startup-redirect-eln-cache native-compile-target-directory))
729
730(global-goto-address-mode)
731
732;; Winner
733(winner-mode)
734
735;;; Hooks
736(add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)
737(add-hook 'find-file-not-found-functions #'create-missing-directories)
738(add-hook 'find-file-hook #'vc-remote-off)
739(add-hook 'dired-mode-hook #'hl-line-mode)
740(add-hook 'org-agenda-mode-hook #'hl-line-mode)
741
742;;; Tab bar
743
744(defun tab-bar-end-space ()
745 `((end menu-item " " ignore)))
746
747(add-to-list 'tab-bar-format 'tab-bar-format-align-right :append)
748(add-to-list 'tab-bar-format 'tab-bar-format-global :append)
749(add-to-list 'tab-bar-format 'tab-bar-end-space :append)
750;;(setopt tab-bar-show t)
751;;(tab-bar-mode) ; done after setting fonts
752
753;;; Org mode
754
755(keymap-global-set "C-c a" #'org-agenda)
756(keymap-global-set "C-c c" #'org-capture)
757(setopt org-clock-clocked-in-display 'frame-title
758 org-clock-frame-title-format
759 '("%b" " - " (t org-mode-line-string))
760 org-tags-column (- (- fill-column 3))
761 org-log-into-drawer t
762 org-clock-into-drawer t)
763
764;;; Spelling
765
766(defun list-of-strings-p (x)
767 "Is X a list of strings?"
768 (and x
769 (listp x)
770 (cl-every #'stringp x)))
771
772(put 'ispell-local-words 'safe-local-variable
773 'list-of-strings-p)
774
775(add-hook 'text-mode-hook #'jinx-mode)
776(with-eval-after-load 'jinx
777 (keymap-set jinx-mode-map "M-$" #'jinx-correct)
778 (keymap-set jinx-mode-map "C-M-$" #'jinx-languages))
779
780;;; org-return-dwim
781;; https://github.com/alphapapa/unpackaged.el,
782;; http://kitchingroup.cheme.cmu.edu/blog/2017/04/09/A-better-return-in-org-mode/
783(defun org-return-dwim (&optional arg)
784 "A helpful replacement for `org-return'.
785When called interactively with \\[universal-argument], call `org-return'
786itself. Other values of ARG will call `newline' with that ARG."
787 (interactive "P")
788 ;; Auto-fill if enabled
789 (when auto-fill-function
790 (dolist (func (ensure-list auto-fill-function))
791 (funcall func)))
792 (cl-letf* ((el (org-element-at-point))
793 ((symbol-function 'el-child-of)
794 (lambda (&rest types)
795 (org-element-lineage el types t))))
796 (cond ; Figure out what we're going to do
797 (arg ; Handle prefix ARG
798 (pcase arg
799 ('(4) (org-return t nil t))
800 (_ (newline arg t))))
801 ((and org-return-follows-link ; Open a link
802 (el-child-of 'link))
803 (org-open-at-point-global))
804 ((org-at-heading-p) ; Open a paragraph after a heading
805 (let ((heading-start (org-entry-beginning-position)))
806 (goto-char (org-entry-end-position))
807 (cond ((and (org-at-heading-p) ; Entry is only a heading
808 (= heading-start (org-entry-beginning-position)))
809 (end-of-line)
810 (newline 2))
811 (:else ; Entry is more than a heading
812 (forward-line -1)
813 (end-of-line)
814 (when (org-at-heading-p)
815 ;; Open a paragraph
816 (forward-line)
817 (newline)
818 (forward-line -1))
819 (while (not (looking-back "\\(?:[[:blank:]]?\n\\)\\{3\\}" nil))
820 (newline))
821 (forward-line -1)))))
822 ((org-at-item-checkbox-p) ; Insert a new checkbox item
823 (end-of-line)
824 (org-insert-todo-heading nil))
825 ((org-in-item-p) ; Insert a new list item
826 (let* ((context (org-element-context el))
827 (first-item-p (eq 'plain-list (car context)))
828 (itemp (eq 'item (car context)))
829 (emptyp (or
830 ;; This (regular) list item is empty
831 (eq (org-element-property :contents-begin context)
832 (org-element-property :contents-end context))
833 ;; This (definition) list item is empty
834 (looking-at " *::")))
835 (item-child-p (el-child-of 'item)))
836 (cond ((and itemp emptyp)
837 ;; This test has to be here even though it's the same as the
838 ;; :else clause, because an item that's empty will also satisfy
839 ;; the next clause.
840 (delete-region (line-beginning-position) (line-end-position))
841 (newline))
842 ((or first-item-p
843 (and itemp (not emptyp))
844 item-child-p)
845 (org-end-of-item)
846 (org-insert-item))
847 (:else
848 (delete-region (line-beginning-position) (line-end-position))
849 (newline)))))
850 ((and (fboundp 'org-inlinetask-in-task-p) ; Just return for inline tasks
851 (org-inlinetask-in-task-p))
852 (org-return))
853 ((org-at-table-p) ; Insert a new table row
854 (cond ((save-excursion ; Empty row: end the table
855 (beginning-of-line)
856 (cl-loop with end = (line-end-position)
857 for cell = (org-element-table-cell-parser)
858 always (eq (org-element-property :contents-begin cell)
859 (org-element-property :contents-end cell))
860 while (re-search-forward "|" end t)))
861 (delete-region (line-beginning-position) (line-end-position))
862 (org-return))
863 (:else ; Non-empty row
864 (org-return))))
865 (:else ; Something else
866 (org-return)))))
867
868(defun org-table-copy-down|org-return-dwim (&optional n)
869 "Call `org-table-copy-down' or `+org-return' depending on context."
870 (interactive "P")
871 (if (org-table-check-inside-data-field 'noerror)
872 (org-table-copy-down (or n 1))
873 (org-return-dwim n)))
874
875(with-eval-after-load 'org
876 (keymap-set org-mode-map "RET" #'org-return-dwim)
877 (keymap-set org-mode-map "S-RET" #'org-table-copy-down|org-return-dwim))
878
879;;; Copy rich text to the keyboard
880
881(defcustom clipboard-html-copy-program
882 (if (or (equal "wayland"
883 (getenv "XDG_SESSION_TYPE"))
884 (getenv "WAYLAND_DISPLAY"))
885 '("wl-copy" "-t" "text/html")
886 '("xclip" "-t" "text/html" "-selection" "clipboard"))
887 "Program to use to copy HTML to the clipboard.
888Should be a list of strings---the command line.
889Defaults to 'wl-copy' on wayland and 'xclip' on Xorg."
890 :type '(repeat string))
891
892;; Thanks to Oleh Krehel:
893;; https://emacs.stackexchange.com/questions/54292/copy-results-of-org-export-directly-to-clipboard
894;; So. Emacs can't do this itself because it doesn't support sending clipboard
895;; or selection contents as text/html. We have to use xclip instead.
896;; (defun org-to-html-to-clipboard (&rest org-export-args)
897;; "Export current org buffer to HTML, then copy it to the clipboard.
898;; ORG-EXPORT-ARGS are passed to `org-export-to-file'."
899;; (let ((f (make-temp-file "org-html-export")))
900;; (apply #'org-export-to-file 'html f org-export-args)
901;; (start-process "xclip" " *xclip*"
902;; "xclip" "-verbose" "-i" f
903;; "-t" "text/html" "-selection" "clipboard")
904;; (message "HTML pasted to clipboard.")))
905
906(defun org-export-html-copy (&rest org-export-args)
907 "Export current org buffer to HTML and copy to clipboard as rich text.
908ORG-EXPORT-ARGS are passed to `org-export-to-buffer'."
909 (let ((buf (generate-new-buffer "*org-html-clipboard*" t)))
910 (apply #'org-export-to-buffer 'html buf org-export-args)
911 (with-current-buffer buf
912 (apply #'call-process-region
913 (point-min)
914 (point-max)
915 (car clipboard-html-copy-program)
916 nil ; don't delete text
917 nil ; discard the output
918 nil ; don't redisplay
919 (cdr clipboard-html-copy-program))
920 (kill-buffer-and-window))
921 (message "HTML copied to clipboard.")))
922
923;; Wayland version.. TODO: make it work for both
924;; (defun org-to-html-to-clipboard (&rest org-export-args)
925 ;; "Export current org buffer to HTML, then copy it to the clipboard.
926;; ORG-EXPORT-ARGS are passed to `org-export-to-file'."
927 ;; (let ((buf (generate-new-buffer "*org-html-clipboard*" t)))
928 ;; (apply #'org-export-to-buffer 'html buf org-export-args)
929 ;; (with-current-buffer buf
930 ;; (call-process-region (point-min) (point-max)
931 ;; "wl-copy" nil nil nil
932 ;; "-t" "text/html")
933 ;; (kill-buffer-and-window))
934 ;; (message "HTML copied to clipboard.")))
935
936(defun org-subtree-to-html-to-clipboard ()
937 "Export current subtree to HTML."
938 (interactive)
939 (org-export-html-copy nil :subtree))
940
941(undohist-initialize)
942
943(require 'hungry-delete)
944(setopt hungry-delete-chars-to-skip " \t"
945 hungry-delete-skip-regexp (format "[%s]" hungry-delete-chars-to-skip)
946 hungry-delete-join-reluctantly nil)
947(add-to-list 'hungry-delete-except-modes 'eshell-mode)
948(add-to-list 'hungry-delete-except-modes 'nim-mode)
949(add-to-list 'hungry-delete-except-modes 'python-mode)
950(global-hungry-delete-mode)
951
952(setopt avy-background t
953 avy-keys (string-to-list "asdfghjklqwertyuiopzxcvbnm"))
954(keymap-global-set "M-j" #'avy-goto-char-timer)
955(keymap-set isearch-mode-map "M-j" #'avy-isearch)
956(keymap-global-set "M-z" #'zzz-to-char)
957
958(marginalia-mode)
959
960(keymap-global-set "C-x b" #'consult-buffer)
961(keymap-global-set "C-x 4 b" #'consult-buffer-other-window)
962(keymap-global-set "C-x 5 b" #'consult-buffer-other-frame)
963(keymap-global-set "C-x r b" #'consult-bookmark)
964(keymap-global-set "M-y" #'consult-yank-pop)
965(keymap-global-set "M-g g" #'consult-goto-line)
966(keymap-global-set "M-g M-g" #'consult-goto-line)
967(keymap-global-set "M-g o" #'consult-outline)
968(keymap-global-set "M-g m" #'consult-mark)
969(keymap-global-set "M-g i" #'consult-imenu)
970(keymap-global-set "M-s d" #'consult-find)
971(keymap-global-set "M-s D" #'consult-locate)
972(keymap-global-set "M-s g" #'consult-grep)
973(keymap-global-set "M-s G" #'consult-git-grep)
974(keymap-global-set "M-s r" #'consult-ripgrep)
975(keymap-global-set "M-s l" #'consult-line)
976(keymap-global-set "M-s k" #'consult-keep-lines)
977(keymap-global-set "M-s u" #'consult-focus-lines)
978
979(keymap-global-set "M-s e" #'consult-isearch-history)
980(keymap-set isearch-mode-map "M-e" #'consult-isearch-history)
981(keymap-set isearch-mode-map "M-s e" #'consult-isearch-history)
982(keymap-set isearch-mode-map "M-s l" #'consult-line)
983
984(keymap-set minibuffer-local-map "M-n" #'consult-history)
985(keymap-set minibuffer-local-map "M-p" #'consult-history)
986
987(setopt completion-in-region-function #'consult-completion-in-region
988 xref-show-xrefs-function #'consult-xref
989 xref-show-definitions-function #'consult-xref)
990
991(setopt initial-scratch-message ";;; Emacs!\n\n")
992
993(keymap-global-set "C-x C-b" #'ibuffer)
994(add-hook 'ibuffer-hook #'hl-line-mode)
995
996(require 'scule)
997(keymap-global-set "M-c" scule-map)
998(autoload 'titlecase-dwim "titlecase" nil t)
999(keymap-set scule-map "M-t" #'titlecase-dwim)
1000
1001;; Use M-u for prefix keys
1002(keymap-global-set "M-u" #'universal-argument)
1003(keymap-set universal-argument-map "M-u" #'universal-argument-more)
1004
1005(autoload 'frowny-mode "frowny" nil t)
1006(add-hook 'jabber-chat-mode-hook #'frowny-mode)
1007(add-hook 'jabber-chat-mode-hook #'electric-pair-local-mode-disable)
1008
1009(autoload 'hippie-completing-read "hippie-completing-read" nil t)
1010(keymap-global-set "M-/" #'hippie-completing-read)
1011
1012(setopt mode-line-bell-flash-time 0.25)
1013(autoload 'mode-line-bell-mode "mode-line-bell" nil t)
1014(mode-line-bell-mode)
1015
1016(keymap-global-set "C-x C-k" #'kill-this-buffer)
1017
1018(require 'anzu)
1019(global-anzu-mode)
1020(setopt search-default-mode t
1021 anzu-mode-lighter ""
1022 anzu-deactivate-region t)
1023
1024(global-set-key [remap query-replace] #'anzu-query-replace-regexp)
1025(global-set-key [remap query-replace-regexp] #'anzu-query-replace)
1026(define-key isearch-mode-map [remap isearch-query-replace]
1027 #'anzu-isearch-query-replace-regexp)
1028(define-key isearch-mode-map [remap isearch-query-replace-regexp]
1029 #'anzu-isearch-query-replace)
diff --git a/notmuch/default/hooks/post-new b/notmuch/default/hooks/post-new index 744c334..b60ea78 100755 --- a/notmuch/default/hooks/post-new +++ b/notmuch/default/hooks/post-new
@@ -13,10 +13,10 @@
13# When I have that installed, I want to move this to ~/.config/notmuch. 13# When I have that installed, I want to move this to ~/.config/notmuch.
14 14
15# Update tags based on folders 15# Update tags based on folders
16for fdir in ~/var/mail/fastmail/* ; do 16# for fdir in ~/var/mail/fastmail/* ; do
17 if [[ $(basename "$fdir") != "INBOX" ]]; then 17# if [[ $(basename "$fdir") != "INBOX" ]]; then
18 notmuch tag +$(basename "$fdir") -inbox -- "folder:${fdir##$HOME/var/mail/}" 18# notmuch tag +$(basename "$fdir") -inbox -- "folder:${fdir##$HOME/var/mail/}"
19 fi 19# fi
20done 20# done
21 21
22notmuch tag --batch --input="${XDG_CONFIG_HOME:-$HOME/.config}/notmuch/post-new.tags" 22notmuch tag --batch --input="${XDG_CONFIG_HOME:-$HOME/.config}/notmuch/post-new.tags"
diff --git a/notmuch/default/hooks/pre-new b/notmuch/default/hooks/pre-new index 443e3f2..73df046 100755 --- a/notmuch/default/hooks/pre-new +++ b/notmuch/default/hooks/pre-new
@@ -12,4 +12,4 @@
12# TODO: In notmuch v0.35, the location of this hook becomes configurable. 12# TODO: In notmuch v0.35, the location of this hook becomes configurable.
13# When I have that installed, I want to move this to ~/.config/notmuch. 13# When I have that installed, I want to move this to ~/.config/notmuch.
14 14
15/home/case/usr/scripts/syncmail 15/home/acdw/usr/scripts/syncmail
diff --git a/profile/00_functions.sh b/profile/00_functions.sh deleted file mode 100644 index 4bf0c78..0000000 --- a/profile/00_functions.sh +++ /dev/null
@@ -1,69 +0,0 @@
1# utility functions for all shells
2# these should be POSIX-compatible.
3
4# add a path to PATH, but only if it's not already there
5path_add_to_PATH() { # path_add_to_PATH [-a] PATH...
6 # -a appends (default is prepend)
7 APPEND=false
8 if [ "x$1" = "x-a" ]; then
9 APPEND=true
10 shift
11 fi
12
13 for p; do
14 case ":$PATH:" in
15 *:"$p":*) ;;
16 *)
17 if $APPEND; then
18 PATH="$PATH:$p"
19 else
20 PATH="$p:$PATH"
21 fi
22 ;;
23 esac
24 done
25
26 unset APPEND
27}
28
29# Generalization of `path_add_to_PATH' for any variable.
30path_add_unsafe() { #path_add_unsafe [-a] [-d DELIM] VAR PATH...
31 ## Add PATH... to VAR, delimiting with DELIM (default :).
32 # By default, the VAR will be prepended to; passing -a will append the
33 # variable. -d DELIM defines the delimiter.
34 #
35 # This function has the _unsafe suffix because it uses `eval' to set
36 # variables.
37 APPEND=false
38 DELIM=:
39 while getopts ad: opt; do
40 case "$opt" in
41 a) APPEND=true ;;
42 d) DELIM="$OPTARG" ;;
43 *) return 1 ;;
44 esac
45 done
46 shift $(expr $OPTIND - 1)
47
48 var="$1"
49 shift
50
51 for path; do
52 case ":$(eval "echo \$$var"):" in
53 *:"$path":*) ;;
54 *)
55 if $APPEND; then
56 eval "$var=\$$var${var:+$DELIM}$path"
57 else
58 eval "$var=$path${var:+$DELIM}\$$var"
59 fi
60 ;;
61 esac
62 done
63 unset -v APPEND DELIM var
64}
65
66# Re-source ~/.profile
67reprofile() {
68 . $HOME/.profile
69}
diff --git a/profile/01_path.sh b/profile/01_path.sh deleted file mode 100644 index 8b18f5e..0000000 --- a/profile/01_path.sh +++ /dev/null
@@ -1,19 +0,0 @@
1# PATH and variables for $HOME-local installations
2
3LOCAL_PREFIX="$HOME/usr"
4export LOCAL_PREFIX
5
6# Pkg-config
7path_add_unsafe PKG_CONFIG_PATH "$LOCAL_PREFIX/lib/pkgconfig"
8export PKG_CONFIG_PATH
9
10# LD_LIBRARY_PATH
11path_add_unsafe LD_LIBRARY_PATH "$LOCAL_PREFIX/lib"
12export LD_LIBRARY_PATH
13
14# see 00_functions.sh for `path_add'
15path_add_to_PATH \
16 "$HOME/bin" \
17 "$LOCAL_PREFIX/bin" \
18 "$LOCAL_PREFIX/scripts" \
19 "$LOCAL_PREFIX/games/"
diff --git a/profile/bc.sh b/profile/bc.sh index f3b0f5e..c17f560 100644 --- a/profile/bc.sh +++ b/profile/bc.sh
@@ -1,5 +1,7 @@
1# GNU bc 1# GNU bc
2 2
3execp bc || return
4
3BC_ENV_ARGS="-l -q" 5BC_ENV_ARGS="-l -q"
4 6
5BC_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/bc/init" 7BC_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/bc/init"
diff --git a/profile/chicken.sh.disabled b/profile/chicken.sh.disabled index 975c830..8bfa21f 100644 --- a/profile/chicken.sh.disabled +++ b/profile/chicken.sh.disabled
@@ -1,6 +1,8 @@
1## chicken scheme -*- sh -*- 1## chicken scheme -*- sh -*-
2# Enable local installation (i.e., without root) 2# Enable local installation (i.e., without root)
3 3
4execp chicken || return
5
4## XXX: Disabled because I simply install chicken from source in $LOCAL_PREFIX, 6## XXX: Disabled because I simply install chicken from source in $LOCAL_PREFIX,
5## which automagically makes everything correct. 7## which automagically makes everything correct.
6 8
diff --git a/profile/gauche.sh b/profile/gauche.sh index ca5d35b..758d59f 100644 --- a/profile/gauche.sh +++ b/profile/gauche.sh
@@ -1,6 +1,8 @@
1# gauche scheme environment variables 1# gauche scheme environment variables
2# see also ~/.gaucherc 2# see also ~/.gaucherc
3 3
4execp gauche || return
5
4# Warn if ‘#<undef>’ is used in the test expression of branch. In boolean 6# Warn if ‘#<undef>’ is used in the test expression of branch. In boolean
5# context, ‘#<undef>’ counts true. It is also often the case that a procedure 7# context, ‘#<undef>’ counts true. It is also often the case that a procedure
6# returns ‘#<undef>’ when the return value doesn’t matter, and you shouldn’t 8# returns ‘#<undef>’ when the return value doesn’t matter, and you shouldn’t
diff --git a/profile/go.sh b/profile/go.sh index baa4187..34df159 100644 --- a/profile/go.sh +++ b/profile/go.sh
@@ -1,5 +1,7 @@
1# Go 1# Go
2 2
3execp go || return
4
3export GOPATH="$HOME/src/go" 5export GOPATH="$HOME/src/go"
4 6
5# https://drewdevault.com/2022/05/25/Google-has-been-DDoSing-sourcehut.html 7# https://drewdevault.com/2022/05/25/Google-has-been-DDoSing-sourcehut.html
diff --git a/profile/less.sh b/profile/less.sh index 19a73ce..e9e26a4 100644 --- a/profile/less.sh +++ b/profile/less.sh
@@ -1,3 +1,5 @@
1# less settings 1# less settings
2 2
3execp less || return
4
3export LESS="--mouse --RAW-CONTROL-CHARS" 5export LESS="--mouse --RAW-CONTROL-CHARS"
diff --git a/profile/luarocks.sh b/profile/luarocks.sh index e6e1d24..e084c1f 100644 --- a/profile/luarocks.sh +++ b/profile/luarocks.sh
@@ -1,5 +1,5 @@
1# add luarocks stuff to $PATH 1# add luarocks stuff to $PATH
2 2
3if command -v luarocks >/dev/null 2>&1; then 3execp luarocks || return
4 eval "$(luarocks path)" 4
5fi 5eval "$(luarocks path)"
diff --git a/profile/manpath.sh b/profile/manpath.sh index bda4fd2..7f17ea3 100644 --- a/profile/manpath.sh +++ b/profile/manpath.sh
@@ -4,7 +4,10 @@ path_add_unsafe MANPATH \
4 "${XDG_DATA_HOME:-$LOCAL_PREFIX/share}/man" \ 4 "${XDG_DATA_HOME:-$LOCAL_PREFIX/share}/man" \
5 "$LOCAL_PREFIX/local/man" \ 5 "$LOCAL_PREFIX/local/man" \
6 "$LOCAL_PREFIX/local/man" \ 6 "$LOCAL_PREFIX/local/man" \
7 "$LOCAL_PREFIX/man" 7 "$LOCAL_PREFIX/man" \
8 /usr/share/man \
9 /usr/X11R6/man \
10 /usr/local/man
8 11
9# $MANPATH ends with `:' so that manpath(1) will prepend it to its 12# $MANPATH ends with `:' so that manpath(1) will prepend it to its
10# special thing. 13# special thing.
diff --git a/profile/nodejs.sh b/profile/nodejs.sh index 224dbbe..3168930 100644 --- a/profile/nodejs.sh +++ b/profile/nodejs.sh
@@ -1,3 +1,6 @@
1# node.js environment 1# node.js environment
2 2
3execp npm || return
4
3export npm_config_prefix="$LOCAL_PREFIX" 5export npm_config_prefix="$LOCAL_PREFIX"
6path_add_to_PATH "$(npm config get prefix)/bin"
diff --git a/profile/npm.sh b/profile/npm.sh deleted file mode 100644 index 108a869..0000000 --- a/profile/npm.sh +++ /dev/null
@@ -1,4 +0,0 @@
1# Add npm path to $PATH
2
3command -v npm >/dev/null 2>&1 &&
4 path_add_to_PATH "$(npm config get prefix)/bin"
diff --git a/profile/python.sh b/profile/python.sh index 9353cfe..c5c11aa 100644 --- a/profile/python.sh +++ b/profile/python.sh
@@ -2,6 +2,11 @@
2# I try not to use python, because the tooling is just terrible. However, 2# I try not to use python, because the tooling is just terrible. However,
3# sometimes it's unavoidable. 3# sometimes it's unavoidable.
4 4
5if ! ( execp python || execp python3 )
6then
7 return
8fi
9
5# from grym on #emacs --- TODO: research what this actually does, lol 10# from grym on #emacs --- TODO: research what this actually does, lol
6# it's annoying ... (2023-02-08) 11# it's annoying ... (2023-02-08)
7#export PIP_REQUIRE_VIRTUALENV=1 12#export PIP_REQUIRE_VIRTUALENV=1
diff --git a/profile/rust.sh b/profile/rust.sh index dd85a65..fa23ae9 100644 --- a/profile/rust.sh +++ b/profile/rust.sh
@@ -1,3 +1,10 @@
1execp cargo || return
2
1export RUSTUP_HOME="${XDG_DATA_HOME:=$LOCAL_PREFIX/share}/rustup" 3export RUSTUP_HOME="${XDG_DATA_HOME:=$LOCAL_PREFIX/share}/rustup"
2export CARGO_HOME="${XDG_DATA_HOME:=$LOCAL_PREFIX/share}/cargo" 4export CARGO_HOME="${XDG_DATA_HOME:=$LOCAL_PREFIX/share}/cargo"
3. "$CARGO_HOME/env" # takes care of $PATH for us 5
6path_add_to_PATH "$CARGO_HOME/bin"
7
8if test -f "$CARGO_HOME/env"; then
9 . "$CARGO_HOME/env" # takes care of $PATH for us
10fi
diff --git a/profile/ssh-agent.sh b/profile/ssh-agent.sh index 95669d5..f940099 100644 --- a/profile/ssh-agent.sh +++ b/profile/ssh-agent.sh
@@ -1,10 +1,11 @@
1# start the ssh-agent 1# start the ssh-agent
2 2
3# use keychain(1), if available 3# use keychain(1), if available
4if type keychain >/dev/null 2>&1; then 4if execp keychain
5then
5 # Save directory name in a variable (for ease of maintenance) 6 # Save directory name in a variable (for ease of maintenance)
6 export KEYCHAIN_HOME="$XDG_RUNTIME_DIR/keychain" 7 export KEYCHAIN_HOME="$XDG_RUNTIME_DIR/"
7 eval $(keychain --eval --dir "$KEYCHAIN_HOME" --agents ssh 2>/dev/null) 8 eval $(keychain --quiet --eval --dir "$KEYCHAIN_HOME" --agents ssh)
8else 9else
9 eval $(ssh-agent -s) 10 eval $(ssh-agent -s)
10fi 11fi
diff --git a/profile/xdg.sh b/profile/xdg.sh deleted file mode 100644 index a4e395f..0000000 --- a/profile/xdg.sh +++ /dev/null
@@ -1,84 +0,0 @@
1# XDG compliance (miscellaneous)
2
3# If an XDG-complaint variable makes more sense somewhere else, it'll be
4# moved there (e.g., HISTFILE is in history.bash). So variables might
5# move /out/ of this directory, but they probably won't move /in/.
6
7# See also https://github.com/b3nj5m1n/xdg-ninja,
8# https://wiki.archlinux.org/title/XDG_Base_Directory#Support
9
10# Readline
11export INPUTRC="$XDG_CONFIG_HOME/readline/inputrc"
12export RLWRAP_HOME="$XDG_DATA_HOME/rlwrap"
13
14# Less
15export LESSKEY="$XDG_CONFIG_HOME/less/lesskey"
16export LESSHISTFILE="$XDG_CACHE_HOME/less/history"
17mkdir -p "$XDG_CACHE_HOME/less"
18
19# Vim
20export VIMINIT="source ${XDG_CONFIG_HOME:=$HOME/.config}/vim/vimrc"
21
22# Weechat
23export WEECHAT_HOME="$XDG_CONFIG_HOME/weechat"
24
25# Lynx
26export LYNX_CFG="$XDG_CONFIG_HOME/lynx/lynx.cfg"
27
28# Xorg
29export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-$HOME}"
30export XINITRC="$XDG_CONFIG_HOME/X11/xinitrc"
31export XSERVERRC="$XDG_CONFIG_HOME/X11/xserverrc"
32export USERXSESSION="$XDG_CACHE_HOME/X11/xsession"
33export ALTUSERXSESSION="$XDG_CACHE_HOME/X11/Xsession"
34export ERRFILE="$XDG_CACHE_HOME/X11/xsession-errors"
35
36
37
38# Notmuch -- https://notmuchmail.org/pipermail/notmuch/2011/007007.html
39export NOTMUCH_CONFIG="${XDG_CONFIG_HOME:=$HOME/.config}/notmuch/default/config"
40
41# GNUPG
42export GNUPGHOME="$XDG_DATA_HOME/gnupg"
43
44# ICEauthority
45export ICEAUTHORITY="$XDG_CACHE_HOME/ICEauthority"
46
47# mbsync (requires alias)
48export MBSYNC_CONFIG_HOME="$XDG_CONFIG_HOME/isync/mbsyncrc"
49alias mbsync='command mbsync -c "$MBSYNC_CONFIG_HOME"'
50
51# npm
52export NPM_CONFIG_USERCONFIG="$XDG_CONFIG_HOME/npm/npmrc"
53
54# bash-complete
55export BASH_COMPLETION_USER_FILE="$XDG_CONFIG_HOME/bash/completion"
56
57# aspell
58ASPELL_CONF="per-conf $XDG_CONFIG_HOME/aspell/aspell.conf"
59ASPELL_CONF="$ASPELL_CONF; personal $XDG_CONFIG_HOME/aspell/en.pws"
60ASPELL_CONF="$ASPELL_CONF; repl $XDG_CONFIG_HOME/aspell/en.prepl"
61mkdir -p "$XDG_CONFIG_HOME/aspell"
62export ASPELL_CONF
63
64# Xcompose
65export XCOMPOSEFILE="$XDG_CONFIG_HOME/xorg/xcompose"
66export XCOMPOSECACHE="$XDG_CACHE_HOME/xorg/xcompose"
67
68# sqlite
69export SQLITE_HISTORY="$XDG_DATA_HOME/sqlite_history"
70alias sqlite3='sqlite3 -init "$XDG_CONFIG_HOME/sqlite3/sqliterc"'
71
72# python
73export PYTHONSTARTUPFILE="$XDG_CONFIG_HOME/python/startup"
74export PYTHONPYCACHEPREFIX="$XDG_CACHE_HOME/python"
75export PYTHON_EGG_CACHE="$XDG_CACHE_HOME/python/eggs"
76export PYTHONUSERBASE="$XDG_DATA_HOME/python"
77
78# wget
79export WGETRC="$XDG_CONFIG_HOME/wget/config"
80mkdir -p "$XDG_CONFIG_HOME/wget"
81alias wget='wget --hsts-file="$XDG_CACHE_HOME/wget-hsts"'
82
83# dvdcss
84export DVDCSS_HOME="$XDG_CACHE_HOME/dvdcss"
diff --git a/profile/xfce.sh b/profile/xfce.sh deleted file mode 100644 index 85e90ce..0000000 --- a/profile/xfce.sh +++ /dev/null
@@ -1,4 +0,0 @@
1# enable global menus
2# NOTE: Firefox and Thunderbird require this variable to be 0!
3
4export UBUNTU_MENUPROXY=1
diff --git a/profile/xorg.sh b/profile/xorg.sh deleted file mode 100644 index 89a26ec..0000000 --- a/profile/xorg.sh +++ /dev/null
@@ -1,10 +0,0 @@
1# X.org environment variables
2# ~/.profile is sourced by LightDM
3
4# Xsession errors
5export ERRFILE="$XDG_CACHE_HOME/X11/xsession-errors"
6# Xsession RC
7export USERXSESSIONRC="$XDG_CONFIG_HOME/xorg/xsessionrc"
8# Xauthority --- though this doesn't work with LightDM (see
9# https://askubuntu.com/a/961459 for a workaround).
10export XAUTHORITY="$XDG_RUNTIME_DIR/Xauthority"
diff --git a/readline/inputrc b/readline/inputrc index bc113e6..824d03f 100644 --- a/readline/inputrc +++ b/readline/inputrc
@@ -48,4 +48,14 @@ $if Bash
48"\C-xq": "\C-a$(\C-e)" 48"\C-xq": "\C-a$(\C-e)"
49# C-M-o : dabbrev-expand 49# C-M-o : dabbrev-expand
50"\e\C-o": dabbrev-expand 50"\e\C-o": dabbrev-expand
51$endif
52
53### foot
54
55$if term=foot
56set show-mode-in-prompt on
57set emacs-mode-string "\1\e]133;A\e\\\2"
58# Uncomment and/or adjust if you're using the vi editing-mode.
59# set vi-cmd-mode-string "\1\e]133;A\e\\\2"
60# set vi-ins-mode-string "\1\e]133;A\e\\\2"
51$endif \ No newline at end of file 61$endif \ No newline at end of file
diff --git a/systemd/user/emacs.service b/systemd/user/emacs.service deleted file mode 100644 index 57a7e50..0000000 --- a/systemd/user/emacs.service +++ /dev/null
@@ -1,12 +0,0 @@
1[Unit]
2Description=Emacs text editor
3Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/
4
5[Service]
6Type=forking
7ExecStart=/home/case/.local/bin/emacs --daemon
8ExecStop=/home/case/.local/bin/emacsclient --eval "(kill-emacs)"
9Restart=on-always
10
11[Install]
12WantedBy=default.target