diff options
Diffstat (limited to 'init.el')
-rw-r--r-- | init.el | 1030 |
1 files changed, 9 insertions, 1021 deletions
diff --git a/init.el b/init.el index 94e2a0e..7f6da30 100644 --- a/init.el +++ b/init.el | |||
@@ -1,10 +1,10 @@ | |||
1 | ;;; init.el -*- lexical-binding: t; coding: utf-8 -*- | 1 | :;;; init.el -*- lexical-binding: t; coding: utf-8-unix -*- |
2 | ;; Copyright (C) 2020-2021 Case Duckworth | ||
3 | ;; | 2 | ;; |
4 | ;; Author: Case Duckworth <acdw@acdw.net> | 3 | ;; Author: Case Duckworth <acdw@acdw.net> |
5 | ;; Created: Sometime during Covid-19, 2020 | 4 | ;; Created: Sometime during Covid-19, 2020 |
6 | ;; Keywords: configuration | 5 | ;; Keywords: configuration |
7 | ;; URL https://tildegit.org/acdw/emacs | 6 | ;; URL: https://tildegit.org/acdw/emacs |
7 | ;; Bankruptcy: 5b | ||
8 | ;; | 8 | ;; |
9 | ;; This file is NOT part of GNU Emacs. | 9 | ;; This file is NOT part of GNU Emacs. |
10 | ;; | 10 | ;; |
@@ -16,1024 +16,12 @@ | |||
16 | ;; - Don't hurt yourself. | 16 | ;; - Don't hurt yourself. |
17 | ;; - Make good choices. | 17 | ;; - Make good choices. |
18 | ;; | 18 | ;; |
19 | ;;; Comentary: | ||
20 | ;; | ||
21 | ;;; Research: | ||
22 | ;; (map! :leader (:prefix "w" :desc "Toggle full screen buffer" "f" | ||
23 | ;; #'toggle-maximize-buffer)) | ||
24 | ;; | ||
25 | ;;; Code: | 19 | ;;; Code: |
26 | 20 | ||
27 | ;; User information | 21 | ;; Add `acdw.el' |
28 | (setq user-full-name "Case Duckworth" | 22 | (add-to-list 'load-path (expand-file-name "lisp/" |
29 | user-mail-address "acdw@acdw.net" | 23 | user-emacs-directory)) |
30 | calendar-location-name "Baton Rouge, LA" | 24 | (require 'acdw) |
31 | calendar-latitude 30.4 | ||
32 | calendar-longitude -91.1 | ||
33 | calendar-date-style 'iso | ||
34 | custom-file (expand-file-name "custom.el" acdw/etc-dir)) | ||
35 | |||
36 | ;; Load newer files first | ||
37 | (setq-default load-prefer-newer t) | ||
38 | |||
39 | ;; No littering | ||
40 | (use-package no-littering | ||
41 | :demand | ||
42 | :init (setq no-littering-etc-directory acdw/etc-dir | ||
43 | no-littering-var-directory acdw/var-dir)) | ||
44 | |||
45 | (defun when-unfocused (func &rest args) | ||
46 | "Run FUNC with ARGS iff all frames are out of focus." | ||
47 | (when (seq-every-p #'null (mapcar #'frame-focus-state (frame-list))) | ||
48 | (apply func args))) | ||
49 | |||
50 | (define-minor-mode acdw/reading-mode | ||
51 | "Make reading comfier." | ||
52 | :lighter " Read" | ||
53 | (if acdw/reading-mode | ||
54 | (progn ;; turn on | ||
55 | ;; (text-scale-increase +1) | ||
56 | (display-fill-column-indicator-mode -1) | ||
57 | (setq cursor-type 'hbar) | ||
58 | (dolist (func '(visual-fill-column-mode | ||
59 | iscroll-mode)) | ||
60 | (when (fboundp func) | ||
61 | (funcall func +1)))) | ||
62 | (progn ;; turn off | ||
63 | ;; (text-scale-increase 0) | ||
64 | (setq cursor-type 'bar) | ||
65 | (display-fill-column-indicator-mode +1) | ||
66 | (dolist (func '(visual-fill-column-mode | ||
67 | iscroll-mode)) | ||
68 | (when (fboundp func) | ||
69 | (funcall func -1)))))) | ||
70 | |||
71 | (defun hook--read-only-cursor () | ||
72 | (setq cursor-type (if buffer-read-only 'hbar 'bar))) | ||
73 | (add-hook 'read-only-mode-hook #'hook--read-only-cursor) | ||
74 | |||
75 | ;; Dialogs & alerts | ||
76 | (setq-default use-dialog-box nil) ; Don't use a dialog box | ||
77 | (fset 'yes-or-no-p #'y-or-n-p) | ||
78 | |||
79 | (defun flash-mode-line () | ||
80 | (ding) | ||
81 | (invert-face 'mode-line) | ||
82 | (run-with-timer 0.2 nil #'invert-face 'mode-line)) | ||
83 | |||
84 | (setq-default visible-bell nil ; Don't use a visible bell | ||
85 | ring-bell-function #'flash-mode-line) | ||
86 | |||
87 | (defun hook--gc-when-unfocused () | ||
88 | (when-unfocused #'garbage-collect)) | ||
89 | |||
90 | (add-function :after after-focus-change-function | ||
91 | #'hook--gc-when-unfocused) | ||
92 | |||
93 | ;; Minibuffer | ||
94 | (setq-default | ||
95 | minibuffer-prompt-properties '(read-only t | ||
96 | cursor-intangible t | ||
97 | face minibuffer-prompt) | ||
98 | enable-recursive-minibuffers t | ||
99 | file-name-shadow-properties '(invisible t)) | ||
100 | (file-name-shadow-mode +1) | ||
101 | (minibuffer-depth-indicate-mode +1) | ||
102 | |||
103 | (use-package savehist | ||
104 | :straight nil | ||
105 | :init | ||
106 | (setq-default | ||
107 | savehist-file (expand-file-name "history" acdw/var-dir) | ||
108 | savehist-additional-variables '(kill-ring search-ring regexp-search-ring) | ||
109 | history-length t | ||
110 | history-delete-duplicates t | ||
111 | savehist-autosave-interval 60) | ||
112 | :config (savehist-mode +1)) | ||
113 | |||
114 | ;; Backups | ||
115 | (setq-default backup-by-copying t | ||
116 | delete-old-versions -1 ; Don't delete old versions | ||
117 | version-control t ; Make numeric backups | ||
118 | vc-make-backup-files t ; Backup version-controlled files | ||
119 | ) | ||
120 | |||
121 | (let ((dir (expand-file-name "backup" acdw/var-dir))) | ||
122 | (make-directory dir 'parents) | ||
123 | (setq-default backup-directory-alist | ||
124 | `((".*" . ,dir)))) | ||
125 | |||
126 | ;; Lockfiles | ||
127 | (setq-default create-lockfiles nil) ; Are these necessary? | ||
128 | |||
129 | ;; Autosaves | ||
130 | (setq auto-save-default nil ; Don't use `auto-save' system | ||
131 | ) | ||
132 | (use-package super-save | ||
133 | :defer 5 ; This package can wait | ||
134 | :init | ||
135 | (setq-default | ||
136 | super-save-remote-files nil ; Don't save remote files | ||
137 | super-save-exclude '(".gpg") ; Wouldn't work anyway | ||
138 | super-save-auto-save-when-idle t) | ||
139 | :config | ||
140 | (super-save-mode +1)) | ||
141 | |||
142 | ;; Auto-revert | ||
143 | (global-auto-revert-mode +1) ; Automatically revert a file | ||
144 | ; to its on-disk contents | ||
145 | |||
146 | (use-package saveplace | ||
147 | :straight nil | ||
148 | :init | ||
149 | (setq-default | ||
150 | save-place-file (expand-file-name "places" acdw/var-dir) | ||
151 | save-place-forget-unreadable-files (eq acdw/system :home)) | ||
152 | :config (save-place-mode +1)) | ||
153 | |||
154 | (use-package recentf | ||
155 | :straight nil | ||
156 | :init | ||
157 | (setq recentf-save-file (expand-file-name "recentf" acdw/var-dir) | ||
158 | recentf-max-menu-items 100 | ||
159 | recentf-max-saved-items nil | ||
160 | recentf-auto-cleanup 'never) | ||
161 | (defun maybe-save-recentf () | ||
162 | "Save `recentf-file' every five minutes, but only when out of focus." | ||
163 | (defvar recentf--last-save (time-convert nil 'integer) | ||
164 | "When we last saved the `recentf-save-list'.") | ||
165 | |||
166 | (when (> (time-convert (time-since recentf--last-save) 'integer) | ||
167 | (* 60 5)) | ||
168 | (setq-default recentf--last-save (time-convert nil 'integer)) | ||
169 | (when-unfocused #'recentf-save-list))) | ||
170 | :config | ||
171 | (recentf-mode +1) | ||
172 | (add-to-list 'recentf-exclude acdw/var-dir) | ||
173 | (add-to-list 'recentf-exclude acdw/etc-dir) | ||
174 | (add-function :after after-focus-change-function | ||
175 | #'maybe-save-recentf)) | ||
176 | |||
177 | |||
178 | ;; Uniquify | ||
179 | (use-package uniquify | ||
180 | :straight nil | ||
181 | :init | ||
182 | (setq-default | ||
183 | uniquify-buffer-name-style 'forward ; bubble 'up' the directory tree | ||
184 | uniquify-separator "/" ; separate path elements | ||
185 | uniquify-after-kill-buffer-p t ; hook into buffer kills | ||
186 | uniquify-ignore-buffers-re "^\\*" ; don't worry about special buffers | ||
187 | )) | ||
188 | |||
189 | ;; Scratch | ||
190 | (setq-default | ||
191 | inhibit-startup-screen t ; Don't show the splash screen | ||
192 | initial-buffer-choice t ; Start on *scratch* | ||
193 | initial-scratch-message | ||
194 | (concat ";; Howdy, " | ||
195 | (nth 0 (split-string user-full-name)) "!" | ||
196 | " Welcome to GNU Emacs.\n\n")) | ||
197 | |||
198 | (defun immortal-scratch () | ||
199 | "Don't kill *scratch* when asked to by `kill-buffer'." | ||
200 | (if (not (eq (current-buffer) (get-buffer "*scratch*"))) | ||
201 | t | ||
202 | (bury-buffer) | ||
203 | nil)) | ||
204 | (add-hook 'kill-buffer-query-functions #'immortal-scratch) | ||
205 | |||
206 | ;; Easier buffer-killing | ||
207 | (defun kill-a-buffer (&optional prefix) | ||
208 | "Kill a buffer and its window, prompting only on unsaved changes. | ||
209 | |||
210 | `kill-a-buffer' uses the PREFIX argument to determine which buffer(s) to kill: | ||
211 | 0 => Kill THIS buffer & window | ||
212 | 4 (C-u) => Kill OTHER buffer & window | ||
213 | 16 (C-u C-u) => Run the default `kill-buffer'." | ||
214 | (interactive "P") | ||
215 | (pcase (or (car prefix) 0) | ||
216 | (0 (kill-current-buffer) | ||
217 | (unless (one-window-p) (delete-window))) | ||
218 | (4 (other-window 1) | ||
219 | (kill-current-buffer) | ||
220 | (unless (one-window-p) (delete-window))) | ||
221 | (16 (let ((current-prefix-arg nil)) | ||
222 | (kill-buffer))))) | ||
223 | |||
224 | (bind-key "C-x k" #'kill-a-buffer) | ||
225 | |||
226 | ;; UTF-8 with LF line endings | ||
227 | (set-charset-priority 'unicode) | ||
228 | (set-language-environment "UTF-8") | ||
229 | |||
230 | (prefer-coding-system 'utf-8-unix) | ||
231 | (set-default-coding-systems 'utf-8-unix) | ||
232 | (set-terminal-coding-system 'utf-8-unix) | ||
233 | (set-keyboard-coding-system 'utf-8-unix) | ||
234 | (set-selection-coding-system 'utf-8-unix) | ||
235 | |||
236 | (setq-default | ||
237 | locale-coding-system 'utf-8-unix | ||
238 | coding-system-for-read 'utf-8-unix | ||
239 | coding-system-for-write 'utf-8-unix | ||
240 | buffer-file-coding-system 'utf-8-unix | ||
241 | |||
242 | org-export-coding-system 'utf-8-unix | ||
243 | org-html-coding-system 'utf-8-unix ; doesn't take from above | ||
244 | |||
245 | default-process-coding-system '(utf-8-unix . utf-8-unix) | ||
246 | x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)) | ||
247 | |||
248 | (defun ewiki/no-junk-please-were-unixish () | ||
249 | "Convert line endings to UNIX, dammit." | ||
250 | (let ((coding-str (symbol-name buffer-file-coding-system))) | ||
251 | (when (string-match "-\\(?:dos\\|mac\\)$" coding-str) | ||
252 | (set-buffer-file-coding-system 'unix)))) | ||
253 | |||
254 | (add-hook 'find-file-hook #'ewiki/no-junk-please-were-unixish) | ||
255 | (add-hook 'before-save-hook #'ewiki/no-junk-please-were-unixish) | ||
256 | |||
257 | ;; Cursor | ||
258 | (setq-default cursor-type 'bar | ||
259 | cursor-in-non-selected-windows nil) | ||
260 | (blink-cursor-mode 0) | ||
261 | |||
262 | ;; Filling text | ||
263 | (setq-default fill-column 80) | ||
264 | (global-display-fill-column-indicator-mode +1) | ||
265 | |||
266 | (bind-key "C-x f" #'find-file) ; I don't set `fill-column', ever | ||
267 | |||
268 | (setq-default comment-auto-fill-only-comments t) | ||
269 | ;; Enable `auto-fill-mode' everywhere | ||
270 | (add-hook 'text-mode-hook #'auto-fill-mode) | ||
271 | (add-hook 'prog-mode-hook #'auto-fill-mode) | ||
272 | ;; Also enable `visual-line-mode' everywhere | ||
273 | (global-visual-line-mode +1) | ||
274 | ;; "Fix" `visual-line-mode' in `org-mode' | ||
275 | (defun hook--visual-line-fix-org-keys () | ||
276 | (when (derived-mode-p 'org-mode) | ||
277 | (local-set-key (kbd "C-a") #'org-beginning-of-line) | ||
278 | (local-set-key (kbd "C-e") #'org-end-of-line) | ||
279 | (local-set-key (kbd "C-k") #'org-kill-line))) | ||
280 | (add-hook 'visual-line-mode-hook #'hook--visual-line-fix-org-keys) | ||
281 | |||
282 | (dolist (margin '(right-margin left-margin)) | ||
283 | (dolist (button '(mouse-1 mouse-2 mouse-3)) | ||
284 | (global-set-key (vector margin button) | ||
285 | (global-key-binding (vector button))))) | ||
286 | |||
287 | (mouse-wheel-mode +1) | ||
288 | |||
289 | (when (bound-and-true-p mouse-wheel-mode) | ||
290 | (dolist (margin '(right-margin left-margin)) | ||
291 | (dolist (event '(mouse-wheel-down-event | ||
292 | mouse-wheel-up-event | ||
293 | wheel-down | ||
294 | wheel-up | ||
295 | mouse-4 | ||
296 | mouse-5)) | ||
297 | (global-set-key (vector margin event) #'mwheel-scroll)))) | ||
298 | |||
299 | (use-package visual-fill-column | ||
300 | :init (setq-default visual-fill-column-center-text t) | ||
301 | (add-hook 'visual-fill-column-mode-hook #'visual-line-mode) | ||
302 | :config | ||
303 | (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust)) | ||
304 | |||
305 | (when (fboundp 'global-so-long-mode) | ||
306 | (global-so-long-mode +1)) | ||
307 | |||
308 | ;; Whitespace | ||
309 | (setq-default whitespace-style '(empty ; remove blank lines at buffer edges | ||
310 | indentation ; clean up indentation | ||
311 | ;; mixed tabs & spaces | ||
312 | space-before-tab | ||
313 | space-after-tab)) | ||
314 | (add-hook 'before-save-hook #'whitespace-cleanup) | ||
315 | |||
316 | (setq-default indent-tabs-mode t | ||
317 | tab-width 8) | ||
318 | |||
319 | (use-package smart-tabs-mode | ||
320 | :config | ||
321 | (smart-tabs-insinuate 'c 'c++ 'java 'javascript 'cperl 'python 'ruby 'nxml)) | ||
322 | |||
323 | ;; Window layouts | ||
324 | (setq-default | ||
325 | split-width-threshold 100 ; minimum width for window splits | ||
326 | split-height-threshold 50 ; minimum height for window splits | ||
327 | display-buffer-alist ; how to display buffers | ||
328 | '((".*" . (display-buffer-reuse-window display-buffer-same-window))) | ||
329 | display-buffer-reuse-frames t ; allow reuse of frames | ||
330 | even-window-sizes nil ; avoid resizing windows to even them | ||
331 | help-window-select t ; select *Help* window when opened | ||
332 | ) | ||
333 | |||
334 | (defun vsplit-other-window () | ||
335 | "Split the window vertically and switch to the new window." | ||
336 | (interactive) | ||
337 | (split-window-vertically) | ||
338 | (other-window 1 nil)) | ||
339 | |||
340 | (defun hsplit-other-window () | ||
341 | "Split the window horizontally and switch to the new window." | ||
342 | (interactive) | ||
343 | (split-window-horizontally) | ||
344 | (other-window 1 nil)) | ||
345 | |||
346 | (bind-key "C-x 2" #'vsplit-other-window) | ||
347 | (bind-key "C-x 3" #'hsplit-other-window) | ||
348 | |||
349 | ;; Theming | ||
350 | |||
351 | (use-package form-feed | ||
352 | :demand | ||
353 | :config (global-form-feed-mode +1)) | ||
354 | |||
355 | (use-package modus-themes | ||
356 | :straight (:host gitlab :repo "protesilaos/modus-themes") | ||
357 | :demand | ||
358 | :init | ||
359 | (setq-default modus-themes-slanted-constructs t | ||
360 | modus-themes-bold-constructs t | ||
361 | modus-themes-region 'bg-only | ||
362 | modus-themes-org-blocks 'grayscale | ||
363 | modus-themes-headings '((1 . section) | ||
364 | (t . no-color)) | ||
365 | modus-themes-scale-headings nil | ||
366 | modus-themes-mode-line nil) | ||
367 | :custom-face | ||
368 | (modus-theme-heading-1 | ||
369 | ((t (:inherit (modus-theme-heading-1 fixed-pitch bold))))) | ||
370 | (modus-theme-heading-2 | ||
371 | ((t (:inherit (modus-theme-heading-2 fixed-pitch bold))))) | ||
372 | (modus-theme-heading-3 | ||
373 | ((t (:inherit (modus-theme-heading-3 fixed-pitch bold))))) | ||
374 | (modus-theme-heading-4 | ||
375 | ((t (:inherit (modus-theme-heading-4 fixed-pitch bold))))) | ||
376 | (modus-theme-heading-5 | ||
377 | ((t (:inherit (modus-theme-heading-5 fixed-pitch bold))))) | ||
378 | (modus-theme-heading-6 | ||
379 | ((t (:inherit (modus-theme-heading-6 fixed-pitch bold))))) | ||
380 | (modus-theme-heading-7 | ||
381 | ((t (:inherit (modus-theme-heading-7 fixed-pitch bold))))) | ||
382 | (modus-theme-heading-8 | ||
383 | ((t (:inherit (modus-theme-heading-8 fixed-pitch bold)))))) | ||
384 | |||
385 | ;; Change themes based on time of day | ||
386 | |||
387 | (defun acdw/run-with-sun (sunrise-command sunset-command) | ||
388 | "Run commands at sunrise and sunset." | ||
389 | (let* ((times-regex (rx (* nonl) | ||
390 | (: (any ?s ?S) "unrise") " " | ||
391 | (group (repeat 1 2 digit) ":" | ||
392 | (repeat 1 2 digit) | ||
393 | (: (any ?a ?A ?p ?P) (any ?m ?M))) | ||
394 | (* nonl) | ||
395 | (: (any ?s ?S) "unset") " " | ||
396 | (group (repeat 1 2 digit) ":" | ||
397 | (repeat 1 2 digit) | ||
398 | (: (any ?a ?A ?p ?P) (any ?m ?M))) | ||
399 | (* nonl))) | ||
400 | (ss (sunrise-sunset)) | ||
401 | (_m (string-match times-regex ss)) | ||
402 | (sunrise-time (match-string 1 ss)) | ||
403 | (sunset-time (match-string 2 ss))) | ||
404 | (run-at-time sunrise-time (* 60 60 24) sunrise-command) | ||
405 | (run-at-time sunset-time (* 60 60 24) sunset-command) | ||
406 | (run-at-time "0:00" (* 60 60 24) sunset-command))) | ||
407 | |||
408 | (acdw/run-with-sun #'modus-themes-load-operandi | ||
409 | #'modus-themes-load-vivendi) | ||
410 | |||
411 | (use-package minions | ||
412 | :config (minions-mode +1)) | ||
413 | |||
414 | (use-package which-key | ||
415 | :config (which-key-mode +1)) | ||
416 | |||
417 | (delete-selection-mode +1) | ||
418 | |||
419 | (setq-default | ||
420 | save-interprogram-paste-before-kill t ; save existing text before replacing | ||
421 | yank-pop-change-selection t ; update X selection when rotating ring | ||
422 | x-select-enable-clipboard t ; Enable X clipboards | ||
423 | x-select-enable-primary t | ||
424 | mouse-drag-copy-region t ; Copy a region when mouse-selected | ||
425 | kill-do-not-save-duplicates t ; Don't append the same thing twice | ||
426 | ) | ||
427 | |||
428 | (use-package smartscan | ||
429 | :config (global-smartscan-mode +1)) | ||
430 | |||
431 | (when (fboundp 'global-goto-address-mode) | ||
432 | (global-goto-address-mode +1)) | ||
433 | |||
434 | (use-package flyspell | ||
435 | :init | ||
436 | (setenv "LANG" "en_US") | ||
437 | (setq-default ispell-program-name "hunspell" | ||
438 | ispell-dictionary "en_US" | ||
439 | ispell-personal-dictionary "~/.hunspell_personal") | ||
440 | :hook | ||
441 | (text-mode . flyspell-mode) | ||
442 | (prog-mode . flyspell-prog-mode) | ||
443 | :config | ||
444 | (ispell-set-spellchecker-params) | ||
445 | (unless (file-exists-p ispell-personal-dictionary) | ||
446 | (write-region "" nil ispell-personal-dictionary nil 0))) | ||
447 | |||
448 | (use-package flyspell-correct | ||
449 | :after flyspell | ||
450 | :bind (:map flyspell-mode-map | ||
451 | ("C-;" . flyspell-correct-wrapper))) | ||
452 | |||
453 | (setq-default show-paren-delay 0 | ||
454 | show-paren-style 'mixed | ||
455 | show-paren-when-point-inside-paren t | ||
456 | show-paren-when-point-in-periphery t) | ||
457 | (show-paren-mode +1) | ||
458 | |||
459 | (add-hook 'prog-mode-hook #'electric-pair-local-mode) | ||
460 | |||
461 | (setq-default prettify-symbols-unprettify-at-point 'right-edge) | ||
462 | (add-hook 'prog-mode-hook #'prettify-symbols-mode) | ||
463 | |||
464 | (add-hook 'after-save-hook | ||
465 | #'executable-make-buffer-file-executable-if-script-p) | ||
466 | |||
467 | (setq-default compilation-ask-about-save nil ; just save the buffer | ||
468 | compilation-always-kill t ; kill the processes without asking | ||
469 | compilation-scroll-output 'first-error) | ||
470 | |||
471 | (use-package reformatter | ||
472 | :demand) | ||
473 | |||
474 | (setq-default smie-indent-basic 8) | ||
475 | |||
476 | ;; Shell scripts | ||
477 | (setq-default sh-basic-offset 8 | ||
478 | ;; try to indent like shfmt | ||
479 | sh-indent-after-case 0 | ||
480 | sh-indent-for-case-alt '+ | ||
481 | sh-indent-for-case-label 0) | ||
482 | |||
483 | (use-package flymake-shellcheck | ||
484 | :when (executable-find "shellcheck") | ||
485 | :hook (sh-mode . flymake-shellcheck-load)) | ||
486 | |||
487 | (when (executable-find "shfmt") | ||
488 | (reformatter-define sh-format | ||
489 | :program "shfmt" | ||
490 | :lighter "Shfmt") | ||
491 | (add-hook 'sh-mode-hook #'sh-format-on-save-mode)) | ||
492 | |||
493 | (bind-key "M-/" #'hippie-expand) | ||
494 | |||
495 | ;; Tabs | ||
496 | (setq-default | ||
497 | tab-bar-show 1 ; show the tab bar when more than one | ||
498 | tab-bar-new-tab-choice "*scratch*" ; what to show on a new tab | ||
499 | tab-bar-tab-name-function ; how to name a new tab | ||
500 | #'tab-bar-tab-name-current-with-count | ||
501 | tab-bar-history-limit 25 ; how many tabs to save in history | ||
502 | ) | ||
503 | |||
504 | (tab-bar-history-mode +1) | ||
505 | |||
506 | ;; Smart hungry delete | ||
507 | (use-package smart-hungry-delete | ||
508 | :defer nil | ||
509 | :bind (("<backspace>" . smart-hungry-delete-backward-char) | ||
510 | ("C-d" . smart-hungry-delete-forward-char)) | ||
511 | :config (smart-hungry-delete-add-default-hooks)) | ||
512 | |||
513 | ;; Enable all commands | ||
514 | (setq-default disabled-command-function nil) | ||
515 | |||
516 | ;; Magit | ||
517 | (use-package magit | ||
518 | :bind ("C-x g" . magit-status) | ||
519 | :init (when (eq acdw/system :work) | ||
520 | (setenv "GIT_ASKPASS" "git-gui--askpass")) | ||
521 | (defun magit-display-buffer-same-window (buffer) | ||
522 | "Show `magit' in the same buffer, like god intended." | ||
523 | (display-buffer buffer '(display-buffer-same-window))) | ||
524 | (setq magit-display-buffer-function 'magit-display-buffer-same-window | ||
525 | magit-popup-display-buffer-action '((display-buffer-same-window)))) | ||
526 | (use-package forge | ||
527 | :after magit) | ||
528 | (use-package gitattributes-mode | ||
529 | :mode "\\.gitattributes\\'") | ||
530 | (use-package gitconfig-mode | ||
531 | :mode "\\.gitconfig\\'") | ||
532 | (use-package gitignore-mode | ||
533 | :mode "\\.gitignore\\'") | ||
534 | |||
535 | ;; crux | ||
536 | (use-package crux | ||
537 | :straight (:host github :repo "bbatsov/crux") | ||
538 | :bind | ||
539 | ("M-o" . crux-other-window-or-switch-buffer) | ||
540 | :config | ||
541 | (crux-with-region-or-line kill-ring-save) | ||
542 | (crux-with-region-or-line kill-region) | ||
543 | (crux-with-region-or-line comment-or-uncomment-region)) | ||
544 | |||
545 | ;; Completion and... stuff | ||
546 | (setq-default | ||
547 | completion-ignore-case t | ||
548 | read-buffer-completion-ignore-case t | ||
549 | read-file-name-completion-ignore-case t | ||
550 | minibuffer-eldef-shorten-default t) | ||
551 | |||
552 | (minibuffer-electric-default-mode +1) | ||
553 | |||
554 | (use-package icomplete-vertical | ||
555 | :demand | ||
556 | :init | ||
557 | (setq-default | ||
558 | icomplete-delay-completions-threshold 0 | ||
559 | icomplete-max-delay-chars 0 | ||
560 | icomplete-compute-delay 0 | ||
561 | icomplete-show-matches-on-no-input t | ||
562 | icomplete-hide-common-prefix nil | ||
563 | icomplete-with-completion-tables t | ||
564 | icomplete-in-buffer t) | ||
565 | :bind (:map icomplete-minibuffer-map | ||
566 | ("<down>" . icomplete-forward-completions) | ||
567 | ("C-n" . icomplete-forward-completions) | ||
568 | ("<up>" . icomplete-backward-completions) | ||
569 | ("C-p" . icomplete-backward-completions) | ||
570 | ("C-v" . icomplete-vertical-toggle)) | ||
571 | :config | ||
572 | (fido-mode -1) | ||
573 | (icomplete-mode +1) | ||
574 | (icomplete-vertical-mode +1)) | ||
575 | |||
576 | (use-package orderless | ||
577 | :after icomplete | ||
578 | :init (setq-default completion-styles '(orderless))) | ||
579 | |||
580 | (use-package marginalia | ||
581 | :after icomplete | ||
582 | :init (setq-default marginalia-annotators | ||
583 | '(marginalia-annotators-heavy | ||
584 | marginalia-annotators-light)) | ||
585 | :config (marginalia-mode +1)) | ||
586 | |||
587 | (use-package consult | ||
588 | :after icomplete | ||
589 | :bind (;; C-c bindings (mode-specific-map) | ||
590 | ("C-c h" . consult-history) | ||
591 | ("C-c m" . consult-mode-command) | ||
592 | ("C-c b" . consult-bookmark) | ||
593 | ("C-c k" . consult-kmacro) | ||
594 | ;; C-x bindings (ctl-x-map) | ||
595 | ("C-x M-:" . consult-complex-command) | ||
596 | ("C-x b" . consult-buffer) | ||
597 | ("C-x 4 b" . consult-buffer-other-window) | ||
598 | ("C-x 5 b" . consult-buffer-other-frame) | ||
599 | ;; Custom M-# bindings for fast register access | ||
600 | ("M-#" . consult-register-load) | ||
601 | ("M-'" . consult-register-store) | ||
602 | ("C-M-#" . consult-register) | ||
603 | ;; Other custom bindings | ||
604 | ("M-y" . consult-yank-pop) | ||
605 | ("<help> a" . consult-apropos) | ||
606 | ;; M-g bindings (goto-map) | ||
607 | ("M-g e" . consult-compile-error) | ||
608 | ("M-g g" . consult-goto-line) | ||
609 | ("M-g M-g" . consult-goto-line) | ||
610 | ("M-g o" . consult-outline) | ||
611 | ("M-g m" . consult-mark) | ||
612 | ("M-g k" . consult-global-mark) | ||
613 | ("M-g i" . consult-imenu) | ||
614 | ("M-g I" . consult-project-imenu) | ||
615 | ;; M-s bindings (search-map) | ||
616 | ("M-s f" . consult-find) | ||
617 | ("M-s L" . consult-locate) | ||
618 | ("M-s g" . consult-grep) | ||
619 | ("M-s G" . consult-git-grep) | ||
620 | ("M-s r" . consult-ripgrep) | ||
621 | ("M-s l" . consult-line) | ||
622 | ("M-s m" . consult-multi-occur) | ||
623 | ("M-s k" . consult-keep-lines) | ||
624 | ("M-s u" . consult-focus-lines) | ||
625 | ;; Isearch integration | ||
626 | ("M-s e" . consult-isearch) | ||
627 | :map isearch-mode-map | ||
628 | ("M-e" . consult-isearch) | ||
629 | ("M-s e" . consult-isearch) | ||
630 | ("M-s l" . consult-line)) | ||
631 | :init | ||
632 | (setq register-preview-delay 0 | ||
633 | register-preview-function #'consult-register-format) | ||
634 | (advice-add #'register-preview :override #'consult-register-window) | ||
635 | (setq xref-show-xrefs-function #'consult-xref | ||
636 | xref-show-definitions-function #'consult-xref) | ||
637 | :config | ||
638 | ;; (setq consult-preview-key 'any) | ||
639 | ;; (setq consult-preview-key (kbd "M-p")) | ||
640 | (setq consult-narrow-key "<")) | ||
641 | |||
642 | ;; Language: Emacs-Lisp | ||
643 | (setq-default eval-expression-print-length nil ; don't limit print length | ||
644 | eval-expression-print-level nil | ||
645 | ) | ||
646 | ;; indent like common lisp | ||
647 | (require 'cl-lib) | ||
648 | (setq-default lisp-indent-function #'common-lisp-indent-function) | ||
649 | (put 'cl-flet 'common-lisp-indent-function | ||
650 | (get 'flet 'common-lisp-indent-function)) | ||
651 | (put 'cl-labels 'common-lisp-indent-function | ||
652 | (get 'labels 'common-lisp-indent-function)) | ||
653 | (put 'if 'common-lisp-indent-function 2) | ||
654 | (put 'dotimes-protect 'common-lisp-indent-function | ||
655 | (get 'when 'common-lisp-indent-function)) | ||
656 | ;; eldoc mode | ||
657 | (use-package eldoc | ||
658 | :straight nil | ||
659 | :init (setq-default eldoc-echo-area-display-truncation-message nil | ||
660 | eldoc-idle-delay 0)) | ||
661 | |||
662 | ;; Dired | ||
663 | (use-package dired | ||
664 | :straight nil | ||
665 | :init | ||
666 | (setq-default dired-recursive-copies 'always | ||
667 | dired-recursive-deletes 'always | ||
668 | delete-by-moving-to-trash t | ||
669 | dired-listing-switches "-AFgho --group-directories-first" | ||
670 | dired-auto-revert-buffer t | ||
671 | dired-dwim-target t) | ||
672 | :bind ("C-x C-j" . dired-jump)) | ||
673 | (defun hook--dired-mode () | ||
674 | (hl-line-mode +1) | ||
675 | (dired-hide-details-mode +1)) | ||
676 | (add-hook 'dired-mode-hook #'hook--dired-mode) | ||
677 | |||
678 | (use-package dired-subtree | ||
679 | :bind (:map dired-mode-map | ||
680 | ("i" . dired-subtree-toggle))) | ||
681 | |||
682 | (use-package dired-collapse | ||
683 | :hook dired-mode) | ||
684 | |||
685 | (use-package 0x0 | ||
686 | :straight (:repo "https://git.sr.ht/~zge/nullpointer-emacs") | ||
687 | :init (setq 0x0-default-service 'ttm) | ||
688 | :commands (0x0-upload | ||
689 | 0x0-upload-file | ||
690 | 0x0-upload-string | ||
691 | 0x0-upload-kill-ring | ||
692 | 0x0-popup)) | ||
693 | |||
694 | (use-package elpher | ||
695 | :straight (:repo "git://thelambdalab.xyz/elpher.git") | ||
696 | :commands (elpher elpher-bookmarks) | ||
697 | :init (setq elpher-ipv4-always t | ||
698 | elpher-certificate-directory | ||
699 | (expand-file-name "elpher-certificates/" | ||
700 | acdw/var-dir)) | ||
701 | (add-hook 'elpher-mode-hook #'acdw/reading-mode) | ||
702 | :custom-face | ||
703 | (elpher-gemini-heading1 | ||
704 | ((t (:inherit (modus-theme-heading-1) | ||
705 | :height 1.0)))) | ||
706 | (elpher-gemini-heading2 | ||
707 | ((t (:inherit (modus-theme-heading-2) | ||
708 | :height 1.0)))) | ||
709 | (elpher-gemini-heading3 | ||
710 | ((t (:inherit (modus-theme-heading-3) | ||
711 | :height 1.0)))) | ||
712 | :bind (:map elpher-mode-map | ||
713 | ("n" . elpher-next-link) | ||
714 | ("p" . elpher-prev-link) | ||
715 | ("o" . elpher-follow-current-link) | ||
716 | ("G" . elpher-go-current))) | ||
717 | |||
718 | (use-package gemini-write | ||
719 | :straight (:repo | ||
720 | "https://alexschroeder.ch/cgit/gemini-write" | ||
721 | :fork (:repo "https://tildegit.org/acdw/gemini-write" | ||
722 | :branch "main")) | ||
723 | :after elpher) | ||
724 | |||
725 | (use-package gemini-mode | ||
726 | :straight (:repo "https://git.carcosa.net/jmcbray/gemini.el.git") | ||
727 | :mode "\\.\\(gemini\\|gmi\\)\\'" | ||
728 | :custom-face | ||
729 | (gemini-heading-face-1 | ||
730 | ((t (:inherit (elpher-gemini-heading1))))) | ||
731 | (gemini-heading-face2 | ||
732 | ((t (:inherit (elpher-gemini-heading2))))) | ||
733 | (gemini-heading-face3 | ||
734 | ((t (:inherit (elpher-gemini-heading3)))))) | ||
735 | |||
736 | (use-package nov | ||
737 | :init (setq nov-text-width fill-column) | ||
738 | (add-hook 'nov-mode-hook #'acdw/reading-mode) | ||
739 | :mode ("\\.epub\\'" . nov-mode)) | ||
740 | |||
741 | (use-package undo-fu | ||
742 | :bind (("C-/" . undo-fu-only-undo) | ||
743 | ("C-?" . undo-fu-only-redo))) | ||
744 | (use-package undo-fu-session | ||
745 | :init (setq undo-fu-session-directory (expand-file-name "undo/" | ||
746 | acdw/var-dir) | ||
747 | undo-fu-session-incompatible-files | ||
748 | '("/COMMIT_EDITMSG\\'" "/git-rebase-todo\\'")) | ||
749 | :config (global-undo-fu-session-mode)) | ||
750 | |||
751 | (setq-default set-mark-repeat-command-pop t) ; repeat mark pops w/o prefix | ||
752 | |||
753 | (use-package expand-region | ||
754 | :bind ("C-=" . er/expand-region)) | ||
755 | |||
756 | (use-package goggles | ||
757 | :hook ((text-mode prog-mode) . goggles-mode)) | ||
758 | |||
759 | (use-package isearch | ||
760 | :straight nil) | ||
761 | |||
762 | (use-package anzu | ||
763 | :init (setq search-default-mode t) | ||
764 | :bind (([remap query-replace] . anzu-query-replace-regexp) | ||
765 | ([remap query-replace-regexp] . anzu-query-replace) | ||
766 | :map isearch-mode-map | ||
767 | ([remap isearch-query-replace] . anzu-isearch-query-replace) | ||
768 | ([remap isearch-query-replace-regexp] . | ||
769 | anzu-isearch-query-replace-regexp))) | ||
770 | |||
771 | (use-package iscroll | ||
772 | :hook (text-mode . iscroll-mode)) | ||
773 | |||
774 | (use-package ibuffer | ||
775 | :straight nil | ||
776 | :bind ([remap list-buffers] . #'ibuffer) | ||
777 | ;; from http://martinowen.net/blog/2010/02/03/tips-for-emacs-ibuffer.html | ||
778 | :init | ||
779 | (setq ibuffer-saved-filter-groups ; this could still be improved | ||
780 | '(("home" | ||
781 | ("emacs-config" (or (filename . ".emacs.d") | ||
782 | (filename . "etc/emacs"))) | ||
783 | ("Org" (or (mode . org-mode) | ||
784 | (filename . "OrgMode"))) | ||
785 | ("Dired" (mode . dired-mode)) | ||
786 | ("Magit" (name . "magit")) | ||
787 | ("Help" (or (name . "\*Help\*") | ||
788 | (name . "\*Apropos\*") | ||
789 | (name . "\*info\*"))))) | ||
790 | ibuffer-expert t ; don't ask if i wanna kill unmodifieds | ||
791 | ibuffer-show-empty-filter-groups nil | ||
792 | ) | ||
793 | (defun hook--ibuffer-setup () | ||
794 | (ibuffer-auto-mode +1) | ||
795 | (ibuffer-switch-to-saved-filter-groups "home")) | ||
796 | (add-hook 'ibuffer-mode-hook #'hook--ibuffer-setup)) | ||
797 | |||
798 | (setq-default | ||
799 | browse-url-browser-function 'browse-url-firefox | ||
800 | browse-url-new-window-flag t | ||
801 | browse-url-firefox-new-window-is-tab t | ||
802 | shr-max-width fill-column | ||
803 | shr-width fill-column) | ||
804 | |||
805 | (when (eq acdw/system :work) | ||
806 | (add-to-list 'exec-path "C:/Program Files/Mozilla Firefox")) | ||
807 | |||
808 | (bind-key [remap just-one-space] #'cycle-spacing) | ||
809 | |||
810 | ;; Org mode | ||
811 | ;; org-return-dwim (unpacakged) | ||
812 | (defun unpackaged/org-element-descendant-of (type element) | ||
813 | "Return non-nil if ELEMENT is a descendant of TYPE. | ||
814 | TYPE should be an element type, like `item' or `paragraph'. | ||
815 | ELEMENT should be a list like that returned by `org-element-context'." | ||
816 | ;; MAYBE: Use `org-element-lineage'. | ||
817 | (when-let* ((parent (org-element-property :parent element))) | ||
818 | (or (eq type (car parent)) | ||
819 | (unpackaged/org-element-descendant-of type parent)))) | ||
820 | |||
821 | (defun unpackaged/org-return-dwim (&optional default) | ||
822 | "A helpful replacement for `org-return'. With prefix, call `org-return'. | ||
823 | |||
824 | On headings, move point to position after entry content. In | ||
825 | lists, insert a new item or end the list, with checkbox if | ||
826 | appropriate. In tables, insert a new row or end the table." | ||
827 | ;; Inspired by John Kitchin: | ||
828 | ;; http://kitchingroup.cheme.cmu.edu/blog/2017/04/09/A-better-return-in-org-mode/ | ||
829 | (interactive "P") | ||
830 | (if default | ||
831 | (org-return) | ||
832 | (cond | ||
833 | ;; Act depending on context around point. | ||
834 | |||
835 | ;; NOTE: I prefer RET to not follow links, but by uncommenting | ||
836 | ;; this block, links will be followed. | ||
837 | ;; FURTHER NOTE: Ideally, I would follow links unless point | ||
838 | ;; /appeared/ to be at the end of the line (even if it's still | ||
839 | ;; inside the link) -- when it would do `org-return'. That | ||
840 | ;; would take some /doing/, however. | ||
841 | |||
842 | ;; ((eq 'link (car (org-element-context))) | ||
843 | ;; ;; Link: Open it. | ||
844 | ;; (org-open-at-point-global)) | ||
845 | |||
846 | ((org-at-heading-p) | ||
847 | ;; Heading: Move to position after entry content. | ||
848 | ;; NOTE: This is probably the most interesting feature of this function. | ||
849 | (let ((heading-start (org-entry-beginning-position))) | ||
850 | (goto-char (org-entry-end-position)) | ||
851 | (cond ((and (org-at-heading-p) | ||
852 | (= heading-start (org-entry-beginning-position))) | ||
853 | ;; Entry ends on its heading; add newline after | ||
854 | (end-of-line) | ||
855 | (insert "\n\n")) | ||
856 | (t | ||
857 | ;; Entry ends after its heading; back up | ||
858 | (forward-line -1) | ||
859 | (end-of-line) | ||
860 | (when (org-at-heading-p) | ||
861 | ;; At the same heading | ||
862 | (forward-line) | ||
863 | (insert "\n") | ||
864 | (forward-line -1)) | ||
865 | ;; FIXME: looking-back is supposed to be called with | ||
866 | ;; more arguments. | ||
867 | (while (not (looking-back (rx | ||
868 | (repeat 3 | ||
869 | (seq (optional blank) | ||
870 | "\n"))) | ||
871 | nil)) | ||
872 | (insert "\n")) | ||
873 | (forward-line -1))))) | ||
874 | |||
875 | ((org-at-item-checkbox-p) | ||
876 | ;; Checkbox: Insert new item with checkbox. | ||
877 | (org-insert-todo-heading nil)) | ||
878 | |||
879 | ((org-in-item-p) | ||
880 | ;; Plain list. Yes, this gets a little complicated... | ||
881 | (let ((context (org-element-context))) | ||
882 | (if (or (eq 'plain-list (car context)) ; First item in list | ||
883 | (and (eq 'item (car context)) | ||
884 | (not (eq (org-element-property :contents-begin context) | ||
885 | (org-element-property :contents-end context)))) | ||
886 | ;; Element in list item, e.g. a link | ||
887 | (unpackaged/org-element-descendant-of 'item context)) | ||
888 | ;; Non-empty item: Add new item. | ||
889 | (org-insert-item) | ||
890 | ;; Empty item: Close the list. | ||
891 | ;; TODO: Do this with org functions rather than operating | ||
892 | ;; on the text. Can't seem to find the right function. | ||
893 | (delete-region (line-beginning-position) (line-end-position)) | ||
894 | (insert "\n")))) | ||
895 | |||
896 | ((when (fboundp 'org-inlinetask-in-task-p) | ||
897 | (org-inlinetask-in-task-p)) | ||
898 | ;; Inline task: Don't insert a new heading. | ||
899 | (org-return)) | ||
900 | |||
901 | ((org-at-table-p) | ||
902 | (cond ((save-excursion | ||
903 | (beginning-of-line) | ||
904 | ;; See `org-table-next-field'. | ||
905 | (cl-loop with end = (line-end-position) | ||
906 | for cell = (org-element-table-cell-parser) | ||
907 | always (equal (org-element-property :contents-begin cell) | ||
908 | (org-element-property :contents-end cell)) | ||
909 | while (re-search-forward "|" end t))) | ||
910 | ;; Empty row: end the table. | ||
911 | (delete-region (line-beginning-position) (line-end-position)) | ||
912 | (org-return)) | ||
913 | (t | ||
914 | ;; Non-empty row: call `org-return'. | ||
915 | (org-return)))) | ||
916 | (t | ||
917 | ;; All other cases: call `org-return'. | ||
918 | (org-return))))) | ||
919 | |||
920 | ;; org-fix-blank-lines (unpackaged) | ||
921 | (defun unpackaged/org-fix-blank-lines (&optional prefix) | ||
922 | "Ensure that blank lines exist between headings and between headings and their contents. | ||
923 | With prefix, operate on whole buffer. Ensures that blank lines | ||
924 | exist after each headings's drawers." | ||
925 | (interactive "P") | ||
926 | (org-map-entries (lambda () | ||
927 | (org-with-wide-buffer | ||
928 | ;; `org-map-entries' narrows the buffer, which prevents us | ||
929 | ;; from seeing newlines before the current heading, so we | ||
930 | ;; do this part widened. | ||
931 | (while (not (looking-back "\n\n" nil)) | ||
932 | ;; Insert blank lines before heading. | ||
933 | (insert "\n"))) | ||
934 | (let ((end (org-entry-end-position))) | ||
935 | ;; Insert blank lines before entry content | ||
936 | (forward-line) | ||
937 | (while (and (org-at-planning-p) | ||
938 | (< (point) (point-max))) | ||
939 | ;; Skip planning lines | ||
940 | (forward-line)) | ||
941 | (while (re-search-forward org-drawer-regexp end t) | ||
942 | ;; Skip drawers. You might think that `org-at-drawer-p' | ||
943 | ;; would suffice, but for some reason it doesn't work | ||
944 | ;; correctly when operating on hidden text. This | ||
945 | ;; works, taken from `org-agenda-get-some-entry-text'. | ||
946 | (re-search-forward "^[ \t]*:END:.*\n?" end t) | ||
947 | (goto-char (match-end 0))) | ||
948 | (unless (or (= (point) (point-max)) | ||
949 | (org-at-heading-p) | ||
950 | (looking-at-p "\n")) | ||
951 | (insert "\n")))) | ||
952 | t (if prefix | ||
953 | nil | ||
954 | 'tree))) | ||
955 | |||
956 | (defun hook--org-mode-fix-blank-lines () | ||
957 | (when (eq major-mode 'org-mode) | ||
958 | (let ((current-prefix-arg 4)) ; Emulate C-u | ||
959 | (call-interactively 'unpackaged/org-fix-blank-lines)))) | ||
960 | (add-hook 'before-save-hook #'hook--org-mode-fix-blank-lines) | ||
961 | |||
962 | (use-package org | ||
963 | :straight (:repo "https://code.orgmode.org/bzg/org-mode.git") | ||
964 | :init | ||
965 | (setq-default | ||
966 | org-directory "~/org" ; where to search for org files | ||
967 | ;; typesetting | ||
968 | org-hide-emphasis-markers t | ||
969 | org-fontify-whole-heading-line t | ||
970 | org-fontify-done-headline t | ||
971 | org-fontify-quote-and-verse-blocks t | ||
972 | org-src-fontify-natively t | ||
973 | org-ellipsis " ≡" | ||
974 | org-pretty-entities t | ||
975 | org-tags-column (- 0 fill-column (- (length org-ellipsis))) | ||
976 | ;; Source blocks | ||
977 | org-src-tab-acts-natively t | ||
978 | org-src-window-setup 'current-window | ||
979 | org-confirm-babel-evaluate nil | ||
980 | ;; Behavior | ||
981 | org-adapt-indentation t ; indent text after a header | ||
982 | org-catch-invisible-edits 'smart | ||
983 | org-special-ctrl-a/e t | ||
984 | org-special-ctrl-k t | ||
985 | org-imenu-depth 8 ; catch all headings | ||
986 | ;; Exporting | ||
987 | org-export-headline-levels 8 ; export all headings | ||
988 | org-export-with-smart-quotes t | ||
989 | org-export-with-sub-superscripts t | ||
990 | ;; Modules | ||
991 | org-modules '(;; default (commented if unused) | ||
992 | ;; bbdb | ||
993 | ;; bibtex | ||
994 | ;; docview | ||
995 | eww | ||
996 | ;; gnus | ||
997 | info | ||
998 | ;; irc | ||
999 | ;; mhe | ||
1000 | ;; rmail | ||
1001 | ;; w3m | ||
1002 | ;; extra stuff for me | ||
1003 | ;; habit ; track your consistency with habits | ||
1004 | ;; inlinetask ; tasks independent of outline hierarchy | ||
1005 | mouse ; additional mouse support | ||
1006 | ;; protocol ; intercept calls from emacsclient | ||
1007 | ;; man | ||
1008 | tempo ; templates | ||
1009 | ) | ||
1010 | org-export-backends '(;; defaults | ||
1011 | ascii | ||
1012 | html | ||
1013 | latex | ||
1014 | odt | ||
1015 | ;; added by me | ||
1016 | man | ||
1017 | md | ||
1018 | ) | ||
1019 | ) | ||
1020 | :config | ||
1021 | (require 'org-tempo) | ||
1022 | (require 'ox-md) | ||
1023 | :bind (:map org-mode-map | ||
1024 | ("RET" . unpackaged/org-return-dwim))) | ||
1025 | |||
1026 | (use-package goto-addr | ||
1027 | :straight nil | ||
1028 | :config | ||
1029 | (goto-address-mode +1)) | ||
1030 | 25 | ||
1031 | (use-package web-mode | 26 | (autoload 'ehelp-command "ehelp") |
1032 | :mode (("\\.phtml\\'" . web-mode) | 27 | (define-key acdw/map (kbd "C-h") #'ehelp-command) |
1033 | ("\\.tpl\\.php\\'" . web-mode) | ||
1034 | ("\\.[agj]sp\\'" . web-mode) | ||
1035 | ("\\as[cp]x\\'" . web-mode) | ||
1036 | ("\\.erb\\'" . web-mode) | ||
1037 | ("\\.mustache\\'" . web-mode) | ||
1038 | ("\\.djhtml\\'" . web-mode) | ||
1039 | ("\\.html?\\'" . web-mode))) | ||