summary refs log tree commit diff stats
path: root/init.el
blob: 3cbf3cc70363245b8222c862b5ccd4f82039c672 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
;;; emacs init --- an init for emacs  -*- lexical-binding: t; -*-
;; by C. Duckworth <acdw@acdw.net>
;; URL: https://git.acdw.net/emacs
;; Bankruptcy: 9
;;
;; Everyone is permitted to do whatever they like with this software
;; without limitation.  This software comes without any warranty
;; whatsoever, but with two pieces of advice:
;; - Be kind to yourself.
;; - Make good choices.

(yoke +emacs (locate-user-emacs-file "lisp/")
  (require '+emacs)
  ;; Settings
  (setq truncate-string-ellipsis "…"
	ring-bell-function #'ignore
	read-file-name-completion-ignore-case t)
  ;; Keys
  (define-keys (current-global-map)
    "C-x C-k" #'kill-current-buffer
    "C-/" #'undo-only
    "C-?" #'undo-redo
    "C-x C-c" #'+save-buffers-quit
    "M-SPC" #'+cycle-spacing
    "M-/" #'hippie-expand
    "M-=" #'count-words
    "C-x C-b" #'ibuffer
    "C-x 4 n" #'clone-buffer
    "S-<down-mouse-1>" #'mouse-set-mark
    "C-x 0" #'+delete-window-or-bury-buffer
    "M-j" nil
    "<Scroll_Lock>" nil)
  ;; Hooks
  (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)
  (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
  (add-hook 'find-file-not-found-functions #'+auto-create-missing-dirs)
  ;; Advice
  (add-function :after after-focus-change-function #'+save-some-buffers-debounce)
  (advice-add 'keyboard-escape-quit :around #'keyboard-escape-quit-keep-window-open)
  (define-advice keyboard-escape-quit (:around (fn &rest r))
    "Don't close quits on `keyboard-escape-quit'."
    (let ((buffer-quit-function #'ignore))
      (apply fn r)))
  ;; Themes
  (load-theme 'modus-operandi)
  (set-face-attribute 'default nil :family "Comic Code" :height 100)
  (set-face-attribute 'variable-pitch nil :family "Comic Code" :height 100))

(yoke isearch nil
  (define-keys (current-global-map)
    "C-s" #'isearch-forward-regexp
    "C-r" #'isearch-backward-regexp
    "C-M-s" #'isearch-forward
    "C-M-r" #'isearch-backward))

(yoke auth-source nil
  (setq auth-sources `(default "secrets:passwords"))
  (setq-local-hook authinfo-mode-hook
    truncate-lines t))

(yoke consult "https://github.com/minad/consult"
  (require 'consult)
  (setq register-preview-delay 0
        register-preview-function #'consult-register-format
        xref-show-xrefs-function #'consult-xref
        tab-always-indent 'complete
        completion-in-region-function #'consult-completion-in-region
        consult-narrow-key "<"
        consult--regexp-compiler #'consult--default-regexp-compiler)
  (advice-add #'register-preview :override #'consult-register-window)
  (define-keys (current-global-map)
    ;; C-c bindings (mode-specific-map)
    "C-c h" #'consult-history
    "C-c m" #'consult-mode-command
    "C-c b" #'consult-bookmark
    "C-c k" #'consult-kmacro
    ;; C-x bindings (ctl-x-map)
    "C-x M-:" #'consult-complex-command
    "C-x b" #'consult-buffer
    "C-x 4 b" #'consult-buffer-other-window
    "C-x 5 b" #'consult-buffer-other-frame
    ;; Custom M-# bindings for fast register access
    "M-#" #'consult-register-load
    "M-'" #'consult-register-store
    "C-M-#" #'consult-register
    ;; Other custom bindings
    "M-y" #'consult-yank-pop
    ;;("<f1> a" . consult-apropos)
    ;; M-g bindings (goto-map)
    "M-g e" #'consult-compile-error
    "M-g f" #'consult-flymake ; or consult-flycheck
    "M-g g" #'consult-goto-line
    "M-g M-g" #'consult-goto-line
    "M-g o" #'consult-outline ; or consult-org-heading
    "M-g m" #'consult-mark
    "M-g k" #'consult-global-mark
    "M-g i" #'consult-imenu
    "M-g M-i" #'consult-imenu
    "M-g I" #'consult-imenu-multi
    ;; M-s bindings (search-map)
    "M-s f" #'consult-find
    "M-s F" #'consult-locate
    "M-s g" #'consult-grep
    "M-s G" #'consult-git-grep
    "M-s r" #'consult-ripgrep
    "M-s l" #'consult-line
    "M-s L" #'consult-line-multi
    "M-s m" #'consult-multi-occur
    "M-s k" #'consult-keep-lines
    "M-s u" #'consult-focus-lines
    ;; Isearch integration
    "M-s e" #'consult-isearch-history)
  (eval-after isearch-mode
    (define-keys isearch-mode-map
      "M-e" #'consult-isearch-history
      "M-s e" #'consult-isearch-history
      "M-s l" #'consult-line
      "M-s L" #'consult-line-multi))
  (eval-after org
    (define-key org-mode-map (kbd "M-g o") #'consult-org-heading)))

(yoke orderless "https://github.com/oantolin/orderless"
  (require 'orderless)
  (setq completion-styles '(substring orderless basic)
        completion-category-defaults nil
        completion-category-overrides '((file (styles basic partial-completion)))
        orderless-component-separator #'orderless-escapable-split-on-space))

(yoke vertico "https://github.com/minad/vertico"
  (require 'vertico)
  (setq resize-mini-windows 'grow-only
        vertico-count-format nil
        vertico-cycle t)
  (vertico-mode))

(yoke marginalia "https://github.com/minad/marginalia/"
  (marginalia-mode))

(yoke slime "https://github.com/slime/slime"
  ;; r7rs-swank
  (let ((r7rsloc (yoke-git "https://github.com/ecraven/r7rs-swank")))
    (cond
     ((executable-find "chibi-scheme")
      (defun chibi-scheme-start-swank (file encoding)
	(format "%S\n\n" `(start-swank ,file)))
      (setq slime-lisp-implementations
	    (cons `(chibi-scheme
		    ("chibi-scheme" ,(format "-A%s" r7rsloc)
		     "-m" "(chibi-swank)")
		    :init chibi-scheme-start-swank)
		  (bound-and-true-p slime-lisp-implementations)))))))

(yoke puni "https://github.com/amaikinono/puni"
  (puni-global-mode)
  (electric-pair-mode)
  (define-keys puni-mode-map
    "C-)" #'puni-slurp-forward
    "C-(" #'puni-slurp-backward
    "C-}" #'puni-barf-forward
    "C-{" #'puni-barf-backward))

(yoke hungry-delete "https://github.com/nflath/hungry-delete"
  (setq hungry-delete-chars-to-skip " \t"
	hungry-delete-join-reluctantly nil)
  (eval-after hungry-delete
    (add-to-list* 'hungry-delete-except-modes
		  'eshell-mode
		  'nim-mode
		  'python-mode))
  (defun +hungry-delete-or (hd-fn fn arg)
    (funcall (if (looking-back (format "[%s]" hungry-delete-chars-to-skip) arg)
		 hd-fn
	       fn)
	     arg))
  (define-keys puni-mode-map
    [remap puni-backward-delete-char]
    (defun puni@hungry-delete-backward (arg)
      (interactive "p")
      (+hungry-delete-or #'hungry-delete-backward
			 #'puni-backward-delete-char
			 arg))
    [remap puni-forward-delete-char]
    (defun puni@hungry-delete-forward (arg)
      (interactive "p")
      (+hungry-delete-or #'hungry-delete-forward
			 #'puni-forward-delete-char
			 arg)))
  (global-hungry-delete-mode))

(yoke cape "https://github.com/minad/cape"
  (defun cape-insinuate ()
    (add-to-list* 'completion-at-point-functions
		  #'cape-dabbrev
		  #'cape-file))
  (add-hook* '(text-mode-hook prog-mode-hook)
	     #'cape-insinuate))

(yoke minions "https://github.com/tarsius/minions"
  (minions-mode))

(yoke magit "https://github.com/magit/magit"
  :load (locate-user-emacs-file "yoke/magit/lisp")
  :depends ((transient "https://github.com/magit/transient"
                       (locate-user-emacs-file "yoke/transient/lisp"))
            (dash "https://github.com/magnars/dash.el")
            (with-editor "https://github.com/magit/with-editor"
                         (locate-user-emacs-file "yoke/with-editor/lisp")))
  (autoload #'transient--with-suspended-override "transient")
  (autoload #'magit "magit" nil :interactive))

(yoke visual-fill-column "https://codeberg.org/joostkremers/visual-fill-column"
  (setq visual-fill-column-center-text t)
  (add-hook* 'visual-fill-column-mode-hook #'visual-line-mode)
  (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust))

(yoke org "https://git.savannah.gnu.org/git/emacs/org-mode.git"
  :load (locate-user-emacs-file "yoke/org/lisp/")
  :depends ((org-contrib "https://git.sr.ht/~bzg/org-contrib"
                         (locate-user-emacs-file "yoke/org-contrib/lisp")))
  ;; DON'T load system org
  (setq load-path
        (cl-remove-if (lambda (path) (string-match-p "lisp/org\\'" path)) load-path))
  (setq org-adapt-indentation nil
        org-auto-align-tags t
        org-archive-mark-done t
        org-fold-catch-invisible-edits 'show-and-error
        org-clock-clocked-in-display 'mode-line
        org-clock-frame-title-format (cons
                                      '(t org-mode-line-string)
                                      (cons " --- " frame-title-format))
        org-clock-string-limit 7     ; just the clock bit
        ;; org-clock-string-limit 25    ; gives enough information
        org-clock-persist nil
        org-confirm-babel-evaluate nil
        org-cycle-separator-lines 0
        org-directory (sync/ "org/" t)
        org-ellipsis (or truncate-string-ellipsis "…")
        org-fontify-done-headline t
        org-fontify-quote-and-verse-blocks t
        org-fontify-whole-heading-line t
        org-hide-emphasis-markers t
        org-html-coding-system 'utf-8-unix
        org-image-actual-width (list (* (window-font-width)
                                        (- fill-column 8)))
        org-imenu-depth 3
        org-indent-indentation-per-level 0
        org-indent-mode-turns-on-hiding-stars nil
        org-insert-heading-respect-content t
        org-list-demote-modify-bullet '(("-" . "+")
                                        ("+" . "-"))
        org-log-done 'time
        org-log-into-drawer t
        org-num-skip-commented t
        org-num-skip-unnumbered t
        org-num-skip-footnotes t
        org-outline-path-complete-in-steps nil
        org-pretty-entities t
        org-pretty-entities-include-sub-superscripts nil
        org-refile-targets '((nil . (:maxlevel . 2))
                             (org-agenda-files . (:maxlevel . 1)))
        org-refile-use-outline-path 'file
        org-special-ctrl-a/e t
        org-special-ctrl-k t
        org-src-fontify-natively t
        org-src-tab-acts-natively t
        org-src-window-setup 'current-window
        org-startup-truncated nil
        org-startup-with-inline-images t
        org-tags-column -77 ;; (- (- fill-column 1 (length org-ellipsis)))
        org-todo-keywords
        '((sequence "TODO(t)" "WAIT(w@/!)" "ONGOING(o@)"
                    "|" "DONE(d!)" "ASSIGNED(a@/!)")
          (sequence "|" "CANCELED(k@)")
          (sequence "MEETING(m)"))
        org-use-speed-commands t
        org-emphasis-alist '(("*" org-bold)
                             ("/" org-italic)
                             ("_" org-underline)
                             ("=" org-verbatim)
                             ("~" org-code)
                             ("+" org-strikethrough)))
  ;; (setq org-todo-keywords
  ;;       '((sequence
  ;;          "TODO(t)"
  ;;          "NEXT(n!)" ; next action
  ;;          "DONE(d)"  ; done)
  ;;          (sequence
  ;;           "WAIT(w@)"   ; waiting to be actionable again
  ;;           "HOLD(h@/!)" ; actinable, but will do later
  ;;           "IDEA(i)"    ; maybe someday
  ;;           "KILL(k@/!)" ;  cancelled, aborted or is no longer applicable
  ;;           ))))))
  (add-hook* 'org-mode-hook
             #'variable-pitch-mode
             #'visual-fill-column-mode
             #'turn-off-auto-fill
             #'org-indent-mode
             #'prettify-symbols-mode
             #'abbrev-mode)
  (eval-after org
    (require '+org)
    (define-keys org-mode-map
      "C-M-k" #'kill-paragraph
      "C-M-t" #'transpose-paragraphs)
    (org-clock-persistence-insinuate)))

(yoke org-agenda nil
  (setq org-agenda-skip-deadline-if-done t
        org-agenda-skip-scheduled-if-done t
        org-agenda-span 10
        org-agenda-block-separator ?─
        org-agenda-time-grid
        '((daily today require-timed)
          (800 1000 1200 1400 1600 1800 2000)
          " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")
        org-agenda-current-time-string
        "← now ─────────────────────────────────────────────────"
        org-agenda-include-diary nil ; I use the org-diary features
        org-agenda-todo-ignore-deadlines 'near
        org-agenda-todo-ignore-scheduled 'future
        org-agenda-include-deadlines t
        org-deadline-warning-days 0
        org-agenda-show-future-repeats 'next
        org-agenda-window-setup 'current-window)
  (setq-local-hook org-agenda-mode-hook
    truncate-lines t)
  (add-hook 'org-agenda-after-show-hook #'org-narrow-to-subtree))

(yoke ox nil                            ; org-export
  (eval-after org (require 'ox))
  (eval-after ox
    (require '+ox)
    (require 'ox-md nil :noerror)
    (+org-export-pre-hooks-insinuate))
  (setq org-export-coding-system 'utf-8-unix
        org-export-headline-levels 8
        org-export-with-drawers nil
        org-export-with-section-numbers nil
        org-export-with-smart-quotes t
        org-export-with-sub-superscripts t
        org-export-with-toc nil))

(yoke _work (sync/ "emacs/private")
  :depends ((+org-capture (locate-user-emacs-file "lisp"))
            (private (locate-user-emacs-file "lisp"))
            (bbdb "https://git.savannah.nongnu.org/git/bbdb.git"
                  (locate-user-emacs-file "yoke/bbdb/lisp"))
            (bbdb-vcard "https://github.com/tohojo/bbdb-vcard/"))
  (require 'bbdb)
  (require 'private)
  (require '_work) 
  (bbdb-initialize 'gnus 'message)
  (setq bbdb-complete-mail-allow-cycling t))

(yoke org-taskwise "https://codeberg.org/acdw/org-taskwise.el")

(yoke titlecase "https://codeberg.org/acdw/titlecase.el"
  (eval-after org (require 'titlecase))
  (eval-after titlecase
    (require '+titlecase)
    (add-to-list* 'titlecase-skip-words-regexps (rx word-boundary
                                                    (+ (any upper digit))
                                                    word-boundary))))

(yoke flyspell-correct "https://github.com/duckwork/flyspell-correct"
  (eval-after flyspell
    (require 'flyspell-correct)
    (require '+flyspell-correct)
    (define-keys flyspell-mode-map
      "C-;" #'flyspell-correct-wrapper
      "<f7>" #'+flyspell-correct-buffer))
  (add-hook 'org-mode-hook #'flyspell-mode)
  (setq flyspell-correct--cr-key ";"))