diff options
-rw-r--r-- | README.md | 305 |
1 files changed, 216 insertions, 89 deletions
diff --git a/README.md b/README.md index bb12961..63c5086 100644 --- a/README.md +++ b/README.md | |||
@@ -123,6 +123,23 @@ This comes in handy when I want to garbage collect, say, or save recent files. | |||
123 | (apply func args))) | 123 | (apply func args))) |
124 | 124 | ||
125 | 125 | ||
126 | ### Determine where I am | ||
127 | |||
128 | I use Emacs at home, with Linux, and at work, with Windows. | ||
129 | |||
130 | (defmacro at-work (&rest commands) | ||
131 | "Only do COMMANDS when at work." | ||
132 | (declare (indent defun)) | ||
133 | `(when (memq system-type '(ms-dos windows-nt)) | ||
134 | ,@commands)) | ||
135 | |||
136 | (defmacro at-home (&rest commands) | ||
137 | "Only do COMMANDS when at home." | ||
138 | (declare (indent defun)) | ||
139 | `(when (memq system-type '(gnu gnu/linux gnu/kfreebsd)) | ||
140 | ,@commands)) | ||
141 | |||
142 | |||
126 | ## Clean `.emacs.d` | 143 | ## Clean `.emacs.d` |
127 | 144 | ||
128 | (straight-use-package 'no-littering) | 145 | (straight-use-package 'no-littering) |
@@ -233,6 +250,12 @@ from [EmacsWiki](https://www.emacswiki.org/emacs/AlarmBell#h5o-3). | |||
233 | (global-set-key (kbd "M-o") #'other-window) | 250 | (global-set-key (kbd "M-o") #'other-window) |
234 | 251 | ||
235 | 252 | ||
253 | #### Pop-up windows | ||
254 | |||
255 | (straight-use-package 'popwin) | ||
256 | (popwin-mode +1) | ||
257 | |||
258 | |||
236 | ### Buffers | 259 | ### Buffers |
237 | 260 | ||
238 | 261 | ||
@@ -796,6 +819,11 @@ UNIX line endings, so I don't want to hear it. | |||
796 | "Update the X selection when rotating the kill ring.") | 819 | "Update the X selection when rotating the kill ring.") |
797 | 820 | ||
798 | 821 | ||
822 | #### Don’t append the same thing twice to the kill-ring | ||
823 | |||
824 | (cuss kill-do-not-save-duplicates t) | ||
825 | |||
826 | |||
799 | ### Searching & Replacing | 827 | ### Searching & Replacing |
800 | 828 | ||
801 | 829 | ||
@@ -850,98 +878,10 @@ UNIX line endings, so I don't want to hear it. | |||
850 | 878 | ||
851 | ## Prettify symbols | 879 | ## Prettify symbols |
852 | 880 | ||
853 | |||
854 | ### A bit from Rasmus | ||
855 | |||
856 | from [Rasmus Roulund](https://pank.eu/blog/pretty-babel-src-blocks.html#coderef-symbol), via [Musa Al-hassy](https://alhassy.github.io/emacs.d/index.html#Making-Block-Delimiters-Less-Intrusive). | ||
857 | |||
858 | (defvar-local rasmus/org-at-src-begin -1 | ||
859 | "Variable that holds whether last position was a ") | ||
860 | |||
861 | (defvar rasmus/ob-header-symbol ?☰ | ||
862 | "Symbol used for babel headers") | ||
863 | |||
864 | (defun rasmus/org-prettify-src--update () | ||
865 | (let ((case-fold-search t) | ||
866 | (re "^[ \t]*#\\+begin_src[ \t]+[^ \f\t\n\r\v]+[ \t]*") | ||
867 | found) | ||
868 | (save-excursion | ||
869 | (goto-char (point-min)) | ||
870 | (while (re-search-forward re nil t) | ||
871 | (goto-char (match-end 0)) | ||
872 | (let ((args (org-trim | ||
873 | (buffer-substring-no-properties (point) | ||
874 | (line-end-position))))) | ||
875 | (when (org-string-nw-p args) | ||
876 | (let ((new-cell (cons args rasmus/ob-header-symbol))) | ||
877 | (cl-pushnew new-cell prettify-symbols-alist :test #'equal) | ||
878 | (cl-pushnew new-cell found :test #'equal))))) | ||
879 | (setq prettify-symbols-alist | ||
880 | (cl-set-difference prettify-symbols-alist | ||
881 | (cl-set-difference | ||
882 | (cl-remove-if-not | ||
883 | (lambda (elm) | ||
884 | (eq (cdr elm) rasmus/ob-header-symbol)) | ||
885 | prettify-symbols-alist) | ||
886 | found :test #'equal))) | ||
887 | ;; Clean up old font-lock-keywords. | ||
888 | (font-lock-remove-keywords nil prettify-symbols--keywords) | ||
889 | (setq prettify-symbols--keywords (prettify-symbols--make-keywords)) | ||
890 | (font-lock-add-keywords nil prettify-symbols--keywords) | ||
891 | (while (re-search-forward re nil t) | ||
892 | (font-lock-flush (line-beginning-position) (line-end-position)))))) | ||
893 | |||
894 | (defun rasmus/org-prettify-src () | ||
895 | "Hide src options via `prettify-symbols-mode'. | ||
896 | |||
897 | `prettify-symbols-mode' is used because it has uncollpasing. It's | ||
898 | may not be efficient." | ||
899 | (let* ((case-fold-search t) | ||
900 | (at-src-block (save-excursion | ||
901 | (beginning-of-line) | ||
902 | (looking-at "^[ \t]*#\\+begin_src[ \t]+[^ \f\t\n\r\v]+[ \t]*")))) | ||
903 | ;; Test if we moved out of a block. | ||
904 | (when (or (and rasmus/org-at-src-begin | ||
905 | (not at-src-block)) | ||
906 | ;; File was just opened. | ||
907 | (eq rasmus/org-at-src-begin -1)) | ||
908 | (rasmus/org-prettify-src--update)) | ||
909 | ;; Remove composition if at line; doesn't work properly. | ||
910 | ;; (when at-src-block | ||
911 | ;; (with-silent-modifications | ||
912 | ;; (remove-text-properties (match-end 0) | ||
913 | ;; (1+ (line-end-position)) | ||
914 | ;; '(composition)))) | ||
915 | (setq rasmus/org-at-src-begin at-src-block))) | ||
916 | |||
917 | (defun rasmus/org-prettify-symbols () | ||
918 | (mapc (apply-partially 'add-to-list 'prettify-symbols-alist) | ||
919 | (cl-reduce 'append | ||
920 | (mapcar (lambda (x) (list x (cons (upcase (car x)) (cdr x)))) | ||
921 | `(("#+begin_src" . ?✎) ;; ➤ 🖝 ➟ ➤ ✎ | ||
922 | ("#+end_src" . ?⏹) ;; □ | ||
923 | ("#+header:" . ,rasmus/ob-header-symbol) | ||
924 | ("#+begin_quote" . ?») | ||
925 | ("#+end_quote" . ?«))))) | ||
926 | (turn-on-prettify-symbols-mode) | ||
927 | (add-hook 'post-command-hook 'rasmus/org-prettify-src t t)) | ||
928 | |||
929 | |||
930 | ### Regular prettify-symbols-mode | ||
931 | |||
932 | (cuss prettify-symbols-unprettify-at-point 'right-edge | 881 | (cuss prettify-symbols-unprettify-at-point 'right-edge |
933 | "Unprettify a symbol when inside it or next to it.") | 882 | "Unprettify a symbol when inside it or next to it.") |
934 | 883 | ||
935 | (defun acdw/org-mode-prettify () | 884 | (add-hook 'prog-mode-hook #'prettify-symbols-mode) |
936 | "Prettify `org-mode'." | ||
937 | (append '(("[ ]" . ?□) ("[X]" . ?☑) ("[-]" . ?◐) | ||
938 | ("#begin_src" . ?🖬) ("#BEGIN_SRC" . ?🖬) | ||
939 | ("#end_src" . ?■) ("#END_SRC" . ?■)) | ||
940 | prettify-symbols-alist)) | ||
941 | |||
942 | (add-hook 'org-mode-hook #'acdw/org-mode-prettify) | ||
943 | |||
944 | (global-prettify-symbols-mode +1) | ||
945 | 885 | ||
946 | 886 | ||
947 | ## Parentheses | 887 | ## Parentheses |
@@ -972,6 +912,39 @@ from [Rasmus Roulund](https://pank.eu/blog/pretty-babel-src-blocks.html#coderef- | |||
972 | (global-aggressive-indent-mode +1) | 912 | (global-aggressive-indent-mode +1) |
973 | 913 | ||
974 | 914 | ||
915 | ## Completion | ||
916 | |||
917 | (straight-use-package 'company) | ||
918 | |||
919 | (add-hook 'prog-mode-hook #'company-mode) | ||
920 | |||
921 | (cuss company-idle-delay 0.1 | ||
922 | "Show company sooner.") | ||
923 | (cuss company-minimum-prefix-length 3 | ||
924 | "Don't try to complete short words.") | ||
925 | |||
926 | (with-eval-after-load 'company | ||
927 | (define-key company-active-map (kbd "C-n") | ||
928 | (lambda () (interactive) (company-complete-common-or-cycle +1))) | ||
929 | (define-key company-active-map (kbd "C-p") | ||
930 | (lambda () (interactive) (company-complete-common-or-cycle -1)))) | ||
931 | |||
932 | |||
933 | ### Give it a frame and better help | ||
934 | |||
935 | (straight-use-package 'company-posframe) | ||
936 | |||
937 | (with-eval-after-load 'company | ||
938 | (company-posframe-mode +1)) | ||
939 | |||
940 | |||
941 | ### Prescient integration | ||
942 | |||
943 | (straight-use-package 'company-prescient) | ||
944 | |||
945 | (add-hook 'company-mode-hook #'company-prescient-mode) | ||
946 | |||
947 | |||
975 | ## Language-specific packages | 948 | ## Language-specific packages |
976 | 949 | ||
977 | 950 | ||
@@ -1047,6 +1020,12 @@ This has to be done *before* loading the package. It's included in `visual-fill | |||
1047 | #'org-in-src-block-p)) | 1020 | #'org-in-src-block-p)) |
1048 | 1021 | ||
1049 | 1022 | ||
1023 | ### Show `^L` as a horizontal line | ||
1024 | |||
1025 | (straight-use-package 'form-feed) | ||
1026 | (global-form-feed-mode +1) | ||
1027 | |||
1028 | |||
1050 | ## Word count | 1029 | ## Word count |
1051 | 1030 | ||
1052 | (straight-use-package 'wc-mode) | 1031 | (straight-use-package 'wc-mode) |
@@ -1062,6 +1041,12 @@ This has to be done *before* loading the package. It's included in `visual-fill | |||
1062 | ## Dired | 1041 | ## Dired |
1063 | 1042 | ||
1064 | 1043 | ||
1044 | ### Basic customization | ||
1045 | |||
1046 | ;; highlight the current line in dired. | ||
1047 | (add-hook 'dired-mode-hook #'hl-line-mode) | ||
1048 | |||
1049 | |||
1065 | ### Expand subtrees | 1050 | ### Expand subtrees |
1066 | 1051 | ||
1067 | (straight-use-package 'dired-subtree) | 1052 | (straight-use-package 'dired-subtree) |
@@ -1105,6 +1090,8 @@ I’ve put org mode under Applications, as opposed to Writing, because it’s m | |||
1105 | (cuss org-directory "~/Org") | 1090 | (cuss org-directory "~/Org") |
1106 | (cuss org-ellipsis "…") | 1091 | (cuss org-ellipsis "…") |
1107 | (cuss org-catch-invisible-edits 'show) | 1092 | (cuss org-catch-invisible-edits 'show) |
1093 | (cuss org-special-ctrl-a/e t) | ||
1094 | (cuss org-special-ctrl-k t) | ||
1108 | 1095 | ||
1109 | (cuss org-export-headline-levels 8 | 1096 | (cuss org-export-headline-levels 8 |
1110 | "Maximum level of headlines to export /as/ a headline.") | 1097 | "Maximum level of headlines to export /as/ a headline.") |
@@ -1123,6 +1110,19 @@ I’ve put org mode under Applications, as opposed to Writing, because it’s m | |||
1123 | (variable-pitch)))))) | 1110 | (variable-pitch)))))) |
1124 | 1111 | ||
1125 | 1112 | ||
1113 | #### Prettify | ||
1114 | |||
1115 | (defun acdw/org-mode-prettify () | ||
1116 | "Prettify `org-mode'." | ||
1117 | (dolist (cell '(("[ ]" . ?□) ("[X]" . ?☑) ("[-]" . ?◐) | ||
1118 | ("#+begin_src" . ?✎) ("#+BEGIN_SRC" . ?✎) | ||
1119 | ("#+end_src" . ?■) ("#+END_SRC" . ?■))) | ||
1120 | (add-to-list 'prettify-symbols-alist cell :append)) | ||
1121 | (prettify-symbols-mode +1)) | ||
1122 | |||
1123 | (add-hook 'org-mode-hook #'acdw/org-mode-prettify) | ||
1124 | |||
1125 | |||
1126 | ### General | 1126 | ### General |
1127 | 1127 | ||
1128 | 1128 | ||
@@ -1295,6 +1295,9 @@ from [unpackaged.el](https://github.com/alphapapa/unpackaged.el#ensure-blank-lin | |||
1295 | (cuss org-todo-keywords | 1295 | (cuss org-todo-keywords |
1296 | '((sequence "RECUR(r)" "TODO(t)" "|" "DONE(d)") | 1296 | '((sequence "RECUR(r)" "TODO(t)" "|" "DONE(d)") |
1297 | (sequence "|" "CANCELLED(c)"))) | 1297 | (sequence "|" "CANCELLED(c)"))) |
1298 | |||
1299 | (cuss org-agenda-skip-scheduled-if-done t) | ||
1300 | (cuss org-agenda-skip-deadline-if-done t) | ||
1298 | 1301 | ||
1299 | 1302 | ||
1300 | ### TODO Capture | 1303 | ### TODO Capture |
@@ -1317,6 +1320,15 @@ from [unpackaged.el](https://github.com/alphapapa/unpackaged.el#ensure-blank-lin | |||
1317 | (define-key acdw/map "g" #'magit-status) | 1320 | (define-key acdw/map "g" #'magit-status) |
1318 | 1321 | ||
1319 | 1322 | ||
1323 | ### Git file modes | ||
1324 | |||
1325 | (dolist (feat '(gitattributes-mode | ||
1326 | gitconfig-mode | ||
1327 | gitignore-mode)) | ||
1328 | (straight-use-package feat) | ||
1329 | (require feat)) | ||
1330 | |||
1331 | |||
1320 | ## Beancount mode | 1332 | ## Beancount mode |
1321 | 1333 | ||
1322 | (straight-use-package '(beancount-mode | 1334 | (straight-use-package '(beancount-mode |
@@ -1337,6 +1349,119 @@ from [unpackaged.el](https://github.com/alphapapa/unpackaged.el#ensure-blank-lin | |||
1337 | (define-key beancount-mode-map (kbd "M-p") #'outline-previous-visible-heading) | 1349 | (define-key beancount-mode-map (kbd "M-p") #'outline-previous-visible-heading) |
1338 | 1350 | ||
1339 | 1351 | ||
1352 | ### Company integration with company-ledger | ||
1353 | |||
1354 | (straight-use-package 'company-ledger) | ||
1355 | |||
1356 | (with-eval-after-load 'company | ||
1357 | (add-to-list 'company-backends 'company-ledger)) | ||
1358 | |||
1359 | |||
1360 | ## PDF Tools | ||
1361 | |||
1362 | I’m only enabling this at home for now, since it requires building stuff. | ||
1363 | |||
1364 | (defun acdw/disable-visual-fill-column-mode () | ||
1365 | "Disable `visual-fill-column-mode'." | ||
1366 | (visual-fill-column-mode -1)) | ||
1367 | |||
1368 | (at-home | ||
1369 | (straight-use-package 'pdf-tools) | ||
1370 | (pdf-loader-install) | ||
1371 | |||
1372 | (add-hook 'pdf-view-mode-hook #'acdw/disable-visual-fill-column-mode)) | ||
1373 | |||
1374 | |||
1375 | ## E-book tools | ||
1376 | |||
1377 | (straight-use-package 'nov) | ||
1378 | |||
1379 | (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode)) | ||
1380 | |||
1381 | (cuss nov-text-width t | ||
1382 | "Disable text filling -- `visual-fill-column-mode' takes care | ||
1383 | of that.") | ||
1384 | |||
1385 | (defun acdw/setup-nov-mode () | ||
1386 | (visual-fill-column-mode +1) | ||
1387 | (setq visual-fill-column-center-text t) | ||
1388 | (text-scale-increase +1)) | ||
1389 | |||
1390 | (add-hook 'nov-mode-hook #'acdw/setup-nov-mode) | ||
1391 | |||
1392 | |||
1393 | |||
1394 | |||
1395 | (when (executable-find "mu") | ||
1396 | |||
1397 | (add-to-list 'load-path | ||
1398 | "/usr/share/emacs/site-lisp/mu4e") | ||
1399 | (require 'mu4e) | ||
1400 | |||
1401 | (cuss mail-user-agent 'mu4e-user-agent) | ||
1402 | |||
1403 | (cuss mu4e-headers-skip-duplicates t) | ||
1404 | (cuss mu4e-view-show-images t) | ||
1405 | (cuss mu4e-view-show-addresses t) | ||
1406 | (cuss mu4e-compose-format-flowed t) | ||
1407 | (cuss mu4e-change-filenames-when-moving t) | ||
1408 | (cuss mu4e-attachments-dir "~/Downloads") | ||
1409 | |||
1410 | (cuss mu4e-maildir "~/.mail/fastmail") | ||
1411 | (cuss mu4e-refile-folder "/Archive") | ||
1412 | (cuss mu4e-sent-folder "/Sent") | ||
1413 | (cuss mu4e-drafts-folder "/Drafts") | ||
1414 | (cuss mu4e-trash-folder "/Trash") | ||
1415 | |||
1416 | (fset 'my-move-to-trash "mTrash") | ||
1417 | (define-key mu4e-headers-mode-map (kbd "d") 'my-move-to-trash) | ||
1418 | (define-key mu4e-view-mode-map (kbd "d") 'my-move-to-trash) | ||
1419 | |||
1420 | (cuss message-send-mail-function 'smtpmail-send-it) | ||
1421 | (cuss smtpmail-default-smtp-server "smtp.fastmail.com") | ||
1422 | (cuss smtpmail-smtp-server "smtp.fastmail.com") | ||
1423 | (cuss smtpmail-stream-type 'ssl) | ||
1424 | (cuss smtpmail-smtp-service 465) | ||
1425 | (cuss smtpmail-local-domain "acdw.net") | ||
1426 | (cuss mu4e-compose-signature | ||
1427 | "Best,\nCase\n") | ||
1428 | |||
1429 | ;; (cuss mu4e-get-mail-command "mbsync -a") | ||
1430 | ;; (cuss mu4e-update-interval 300) | ||
1431 | |||
1432 | (cuss mu4e-completing-read-function 'completing-read) | ||
1433 | (cuss message-kill-buffer-on-exit t) | ||
1434 | (cuss mu4e-confirm-quit nil) | ||
1435 | |||
1436 | (cuss mu4e-bookmarks | ||
1437 | '(( | ||
1438 | :name "Unread" | ||
1439 | :query | ||
1440 | "flag:unread AND NOT flag:trashed AND NOT maildir:/Spam" | ||
1441 | :key ?u) | ||
1442 | ( | ||
1443 | :name "Today" | ||
1444 | :query "date:today..now and not maildir:/Spam" | ||
1445 | :key ?t) | ||
1446 | ( | ||
1447 | :name "This week" | ||
1448 | :query "date:7d..now and not maildir:/Spam" | ||
1449 | :hide-unread t | ||
1450 | :key ?w))) | ||
1451 | |||
1452 | (cuss mu4e-headers-fields | ||
1453 | '((:human-date . 12) | ||
1454 | (:flags . 6) | ||
1455 | (:mailing-list . 10) | ||
1456 | (:from-or-to . 22) | ||
1457 | (:subject))) | ||
1458 | |||
1459 | (defun acdw/setup-mu4e-view-mode () | ||
1460 | (visual-fill-column-mode +1)) | ||
1461 | |||
1462 | (add-hook 'mu4e-view-mode-hook #'acdw/setup-mu4e-view-mode)) | ||
1463 | |||
1464 | |||
1340 | # Appendices | 1465 | # Appendices |
1341 | 1466 | ||
1342 | 1467 | ||
@@ -1375,6 +1500,8 @@ from [unpackaged.el](https://github.com/alphapapa/unpackaged.el#ensure-blank-lin | |||
1375 | 1500 | ||
1376 | ;; Don't resize the frame when loading fonts | 1501 | ;; Don't resize the frame when loading fonts |
1377 | (setq frame-inhibit-implied-resize t) | 1502 | (setq frame-inhibit-implied-resize t) |
1503 | ;; Resize frame by pixels | ||
1504 | (setq frame-resize-pixelwise t) | ||
1378 | 1505 | ||
1379 | 1506 | ||
1380 | ## Ease tangling and loading of Emacs' init | 1507 | ## Ease tangling and loading of Emacs' init |