diff options
-rw-r--r-- | init.el | 409 |
1 files changed, 342 insertions, 67 deletions
diff --git a/init.el b/init.el index c654c07..c6d361b 100644 --- a/init.el +++ b/init.el | |||
@@ -1,4 +1,4 @@ | |||
1 | ;;; Emacs init.el -*- lexical-binding: t; -*- | 1 | ;;; ~/.emacs -*- mode: emacs-lisp; lexical-binding: t; -*- |
2 | ;; by Case Duckworth <acdw@acdw.net> | 2 | ;; by Case Duckworth <acdw@acdw.net> |
3 | ;; Bankruptcy 10: "Annoyance" | 3 | ;; Bankruptcy 10: "Annoyance" |
4 | 4 | ||
@@ -11,11 +11,88 @@ | |||
11 | 11 | ||
12 | ;;; Code: | 12 | ;;; Code: |
13 | 13 | ||
14 | (load (locate-user-emacs-file "private")) | 14 | (add-hook 'after-init-hook |
15 | (lambda () | ||
16 | (load (locate-user-emacs-file "private")))) | ||
15 | 17 | ||
16 | |||
17 | ;;; Definitions: | 18 | ;;; Definitions: |
18 | 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. | ||
51 | When 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'. | ||
64 | Will not replace an existing template unless `:force' in ARGS is | ||
65 | non-nil. ARGS is a plist, which in addition to the additional | ||
66 | options `org-capture-templates' accepts (which see), also accepts | ||
67 | the 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 | |||
19 | (defun other-window-or-switch-buffer (&optional arg) | 96 | (defun other-window-or-switch-buffer (&optional arg) |
20 | "Switch to the other window. | 97 | "Switch to the other window. |
21 | If a window is the only buffer on a frame, switch buffer. When | 98 | If a window is the only buffer on a frame, switch buffer. When |
@@ -40,6 +117,9 @@ N spaces." | |||
40 | (face-spec-set 'default | 117 | (face-spec-set 'default |
41 | `((t :family "Recursive Mono Casual Static" | 118 | `((t :family "Recursive Mono Casual Static" |
42 | :height 110))) | 119 | :height 110))) |
120 | (face-spec-set 'variable-pitch | ||
121 | `((t :family "Recursive Sans Casual Static" | ||
122 | :height 1.0))) | ||
43 | ;; Emojis | 123 | ;; Emojis |
44 | (cl-loop with ffl = (font-family-list) | 124 | (cl-loop with ffl = (font-family-list) |
45 | for font in '("Noto Emoji" "Noto Color Emoji" | 125 | for font in '("Noto Emoji" "Noto Color Emoji" |
@@ -182,6 +262,23 @@ With prefix ARG, toggle the value of | |||
182 | (titlecase-region (progn (org-beginning-of-line) (point)) | 262 | (titlecase-region (progn (org-beginning-of-line) (point)) |
183 | (progn (org-end-of-line) (point))))))) | 263 | (progn (org-end-of-line) (point))))))) |
184 | 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 | |||
185 | 282 | ||
186 | ;;; Packages: | 283 | ;;; Packages: |
187 | 284 | ||
@@ -189,34 +286,49 @@ With prefix ARG, toggle the value of | |||
189 | (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) | 286 | (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) |
190 | (package-initialize) | 287 | (package-initialize) |
191 | 288 | ||
289 | (defun ensure-package (pkg &optional localp) | ||
290 | "Esnure PKG is installed from repositories. | ||
291 | If LOCALP is t, add ~/src/PKG.el to `load-path'. | ||
292 | If 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 | |||
192 | ;; Install packages here. Acutal configuration is done in the Configuration | 308 | ;; Install packages here. Acutal configuration is done in the Configuration |
193 | ;; section. | 309 | ;; section. |
194 | (dolist (pkg `(consult | 310 | (ensure-package 'consult) |
195 | marginalia | 311 | (ensure-package 'marginalia) |
196 | visual-fill-column | 312 | (ensure-package 'visual-fill-column) |
197 | adaptive-wrap | 313 | (ensure-package 'adaptive-wrap) |
198 | geiser | 314 | (ensure-package 'geiser) |
199 | ,(when (executable-find "csi") 'geiser-chicken) | 315 | (when (executable-find "csi") |
200 | avy | 316 | (ensure-package 'geiser-chicken)) |
201 | zzz-to-char | 317 | (ensure-package 'avy) |
202 | hungry-delete | 318 | (ensure-package 'zzz-to-char) |
203 | undohist | 319 | (ensure-package 'hungry-delete) |
204 | jinx)) | 320 | (ensure-package 'undohist) |
205 | (when (and pkg (not (package-installed-p pkg))) | 321 | (ensure-package 'jinx) |
206 | (unless (ignore-errors (package-install pkg)) | 322 | (ensure-package 'markdown-mode) |
207 | (package-refresh-contents) | 323 | (ensure-package 'anzu) |
208 | (package-install pkg)))) | 324 | |
209 | 325 | ;; Local packages | |
210 | (dolist (local-pkg `(scule | 326 | (ensure-package 'scule t) |
211 | frowny | 327 | (ensure-package 'frowny t) |
212 | hippie-completing-read | 328 | (ensure-package 'hippie-completing-read t) |
213 | mode-line-bell | 329 | (ensure-package 'mode-line-bell t) |
214 | titlecase | 330 | (ensure-package 'titlecase t) |
215 | jabber)) | 331 | (ensure-package 'jabber t) |
216 | (add-to-list 'load-path | ||
217 | (expand-file-name | ||
218 | (format "~/src/%s.el" | ||
219 | (symbol-name local-pkg))))) | ||
220 | 332 | ||
221 | ;;; Jabber | 333 | ;;; Jabber |
222 | 334 | ||
@@ -303,9 +415,7 @@ With prefix ARG, toggle the value of | |||
303 | ;;; General keybinding changes | 415 | ;;; General keybinding changes |
304 | 416 | ||
305 | (keymap-global-set "M-o" #'other-window-or-switch-buffer) | 417 | (keymap-global-set "M-o" #'other-window-or-switch-buffer) |
306 | |||
307 | (keymap-global-set "M-SPC" #'cycle-spacing@) | 418 | (keymap-global-set "M-SPC" #'cycle-spacing@) |
308 | |||
309 | (keymap-global-set "M-u" #'universal-argument) | 419 | (keymap-global-set "M-u" #'universal-argument) |
310 | (keymap-set universal-argument-map "M-u" #'universal-argument-more) | 420 | (keymap-set universal-argument-map "M-u" #'universal-argument-more) |
311 | 421 | ||
@@ -317,30 +427,46 @@ With prefix ARG, toggle the value of | |||
317 | 427 | ||
318 | (tool-bar-mode -1) | 428 | (tool-bar-mode -1) |
319 | 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 | |||
320 | (load-theme 'modus-vivendi :no-confirm :no-enable) | 436 | (load-theme 'modus-vivendi :no-confirm :no-enable) |
321 | (load-theme 'modus-operandi :no-confirm) | 437 | (load-theme 'modus-operandi :no-confirm) |
322 | 438 | ||
323 | (add-hook 'text-mode-hook #'visual-line-mode) | 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) | ||
324 | 442 | ||
325 | ;;; Mode line | 443 | ;;; Mode line |
326 | 444 | ||
327 | (defvar mode-line-position | 445 | (defvar mode-line-position |
328 | '("" | 446 | '("" |
329 | (:eval (if line-number-mode "%3l" "")) | 447 | (:propertize |
330 | (:eval (if column-number-mode | 448 | ("" |
331 | (if column-number-indicator-zero-based | 449 | (:eval (if line-number-mode "%3l" "")) |
332 | "/%2c" | 450 | (:eval (if column-number-mode |
333 | "/%2C") | 451 | (if column-number-indicator-zero-based |
334 | "")) | 452 | "/%2c" |
335 | " (" (-3 "%p") ") ")) | 453 | "/%2C") |
454 | ""))) | ||
455 | display (min-width (3.0))) | ||
456 | (:propertize (" [" (-3 "%p") "] ") | ||
457 | display (min-width (6.0))))) | ||
336 | 458 | ||
337 | (setopt mode-line-format | 459 | (setopt mode-line-format |
338 | '(("%e" mode-line-front-space | 460 | '(("%e" |
339 | mode-line-client | 461 | mode-line-front-space |
340 | mode-line-modified | 462 | (:propertize ("" |
341 | mode-line-remote " " | 463 | mode-line-client |
464 | mode-line-modified | ||
465 | mode-line-remote) | ||
466 | display (min-width (3.0))) | ||
467 | " " | ||
342 | mode-line-buffer-identification | 468 | mode-line-buffer-identification |
343 | (vc-mode vc-mode) | 469 | (vc-mode (" (" (:eval (string-trim vc-mode)) ")")) |
344 | " " | 470 | " " |
345 | (mode-line-position mode-line-position) | 471 | (mode-line-position mode-line-position) |
346 | mode-line-modes | 472 | mode-line-modes |
@@ -358,16 +484,15 @@ With prefix ARG, toggle the value of | |||
358 | 484 | ||
359 | ;;; Completion & minibuffer | 485 | ;;; Completion & minibuffer |
360 | 486 | ||
361 | (setopt icomplete-in-buffer t | ||
362 | icomplete-tidy-shadowed-file-names t) | ||
363 | (fido-vertical-mode) | 487 | (fido-vertical-mode) |
488 | (minibuffer-depth-indicate-mode) | ||
364 | 489 | ||
365 | (setopt completion-auto-help (not icomplete-mode) | 490 | (setopt completion-auto-help (not icomplete-mode) |
366 | completion-auto-select 'second-tab | 491 | completion-auto-select 'second-tab |
367 | completions-header-format nil | 492 | completions-header-format nil |
368 | completions-max-height 12 | 493 | completions-max-height 12 |
369 | completions-format 'one-column | 494 | completions-format 'one-column |
370 | completion-styles '(basic partial-completion flex) | 495 | completion-styles '(basic partial-completion emacs22 flex) |
371 | completion-ignore-case t | 496 | completion-ignore-case t |
372 | read-buffer-completion-ignore-case t | 497 | read-buffer-completion-ignore-case t |
373 | read-file-name-completion-ignore-case t | 498 | read-file-name-completion-ignore-case t |
@@ -385,12 +510,12 @@ With prefix ARG, toggle the value of | |||
385 | (add-hook 'minibuffer-setup-hook #'truncate-lines-mode) | 510 | (add-hook 'minibuffer-setup-hook #'truncate-lines-mode) |
386 | 511 | ||
387 | ;; Up/down when completing in the minibuffer | 512 | ;; Up/down when completing in the minibuffer |
388 | (define-key minibuffer-local-map (kbd "C-p") #'minibuffer-previous-completion) | 513 | ;; (define-key minibuffer-local-map (kbd "C-p") #'minibuffer-previous-completion) |
389 | (define-key minibuffer-local-map (kbd "C-n") #'minibuffer-next-completion) | 514 | ;; (define-key minibuffer-local-map (kbd "C-n") #'minibuffer-next-completion) |
390 | 515 | ||
391 | ;; Up/down when competing in a normal buffer | 516 | ;; Up/down when competing in a normal buffer |
392 | (define-key completion-in-region-mode-map (kbd "C-p") #'minibuffer-previous-completion) | 517 | ;; (define-key completion-in-region-mode-map (kbd "C-p") #'minibuffer-previous-completion) |
393 | (define-key completion-in-region-mode-map (kbd "C-n") #'minibuffer-next-completion) | 518 | ;; (define-key completion-in-region-mode-map (kbd "C-n") #'minibuffer-next-completion) |
394 | 519 | ||
395 | (setopt completions-sort #'renz/sort-multi-category) | 520 | (setopt completions-sort #'renz/sort-multi-category) |
396 | 521 | ||
@@ -428,9 +553,11 @@ With prefix ARG, toggle the value of | |||
428 | (keymap-set geiser-mode-map "C-c C-k" #'geiser-eval-buffer-and-go) | 553 | (keymap-set geiser-mode-map "C-c C-k" #'geiser-eval-buffer-and-go) |
429 | (keymap-unset geiser-mode-map "C-." t)) | 554 | (keymap-unset geiser-mode-map "C-." t)) |
430 | 555 | ||
431 | (setopt visual-fill-column-center-text t | 556 | |
432 | visual-fill-column-width (+ fill-column 2)) | 557 | (with-eval-after-load 'visual-fill-column |
433 | (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust) | 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)) | ||
434 | (add-hook 'visual-line-mode-hook #'visual-fill-column-mode) | 561 | (add-hook 'visual-line-mode-hook #'visual-fill-column-mode) |
435 | (add-hook 'visual-line-mode-hook #'adaptive-wrap-prefix-mode) | 562 | (add-hook 'visual-line-mode-hook #'adaptive-wrap-prefix-mode) |
436 | 563 | ||
@@ -617,7 +744,6 @@ With prefix ARG, toggle the value of | |||
617 | (defun tab-bar-end-space () | 744 | (defun tab-bar-end-space () |
618 | `((end menu-item " " ignore))) | 745 | `((end menu-item " " ignore))) |
619 | 746 | ||
620 | |||
621 | (add-to-list 'tab-bar-format 'tab-bar-format-align-right :append) | 747 | (add-to-list 'tab-bar-format 'tab-bar-format-align-right :append) |
622 | (add-to-list 'tab-bar-format 'tab-bar-format-global :append) | 748 | (add-to-list 'tab-bar-format 'tab-bar-format-global :append) |
623 | (add-to-list 'tab-bar-format 'tab-bar-end-space :append) | 749 | (add-to-list 'tab-bar-format 'tab-bar-end-space :append) |
@@ -627,9 +753,13 @@ With prefix ARG, toggle the value of | |||
627 | ;;; Org mode | 753 | ;;; Org mode |
628 | 754 | ||
629 | (keymap-global-set "C-c a" #'org-agenda) | 755 | (keymap-global-set "C-c a" #'org-agenda) |
756 | (keymap-global-set "C-c c" #'org-capture) | ||
630 | (setopt org-clock-clocked-in-display 'frame-title | 757 | (setopt org-clock-clocked-in-display 'frame-title |
631 | org-clock-frame-title-format | 758 | org-clock-frame-title-format |
632 | '("%b" " - " (t org-mode-line-string))) | 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) | ||
633 | 763 | ||
634 | ;;; Spelling | 764 | ;;; Spelling |
635 | 765 | ||
@@ -647,8 +777,118 @@ With prefix ARG, toggle the value of | |||
647 | (keymap-set jinx-mode-map "M-$" #'jinx-correct) | 777 | (keymap-set jinx-mode-map "M-$" #'jinx-correct) |
648 | (keymap-set jinx-mode-map "C-M-$" #'jinx-languages)) | 778 | (keymap-set jinx-mode-map "C-M-$" #'jinx-languages)) |
649 | 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'. | ||
785 | When called interactively with \\[universal-argument], call `org-return' | ||
786 | itself. 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 | |||
650 | ;;; Copy rich text to the keyboard | 879 | ;;; Copy rich text to the keyboard |
651 | 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. | ||
888 | Should be a list of strings---the command line. | ||
889 | Defaults to 'wl-copy' on wayland and 'xclip' on Xorg." | ||
890 | :type '(repeat string)) | ||
891 | |||
652 | ;; Thanks to Oleh Krehel: | 892 | ;; Thanks to Oleh Krehel: |
653 | ;; https://emacs.stackexchange.com/questions/54292/copy-results-of-org-export-directly-to-clipboard | 893 | ;; https://emacs.stackexchange.com/questions/54292/copy-results-of-org-export-directly-to-clipboard |
654 | ;; So. Emacs can't do this itself because it doesn't support sending clipboard | 894 | ;; So. Emacs can't do this itself because it doesn't support sending clipboard |
@@ -663,23 +903,40 @@ With prefix ARG, toggle the value of | |||
663 | ;; "-t" "text/html" "-selection" "clipboard") | 903 | ;; "-t" "text/html" "-selection" "clipboard") |
664 | ;; (message "HTML pasted to clipboard."))) | 904 | ;; (message "HTML pasted to clipboard."))) |
665 | 905 | ||
666 | ;; Wayland version.. TODO: make it work for both | 906 | (defun org-export-html-copy (&rest org-export-args) |
667 | (defun org-to-html-to-clipboard (&rest org-export-args) | 907 | "Export current org buffer to HTML and copy to clipboard as rich text. |
668 | "Export current org buffer to HTML, then copy it to the clipboard. | 908 | ORG-EXPORT-ARGS are passed to `org-export-to-buffer'." |
669 | ORG-EXPORT-ARGS are passed to `org-export-to-file'." | ||
670 | (let ((buf (generate-new-buffer "*org-html-clipboard*" t))) | 909 | (let ((buf (generate-new-buffer "*org-html-clipboard*" t))) |
671 | (apply #'org-export-to-buffer 'html buf org-export-args) | 910 | (apply #'org-export-to-buffer 'html buf org-export-args) |
672 | (with-current-buffer buf | 911 | (with-current-buffer buf |
673 | (call-process-region (point-min) (point-max) | 912 | (apply #'call-process-region |
674 | "wl-copy" nil nil nil | 913 | (point-min) |
675 | "-t" "text/html") | 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)) | ||
676 | (kill-buffer-and-window)) | 920 | (kill-buffer-and-window)) |
677 | (message "HTML copied to clipboard."))) | 921 | (message "HTML copied to clipboard."))) |
678 | 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 | |||
679 | (defun org-subtree-to-html-to-clipboard () | 936 | (defun org-subtree-to-html-to-clipboard () |
680 | "Export current subtree to HTML." | 937 | "Export current subtree to HTML." |
681 | (interactive) | 938 | (interactive) |
682 | (org-to-html-to-clipboard nil :subtree)) | 939 | (org-export-html-copy nil :subtree)) |
683 | 940 | ||
684 | (undohist-initialize) | 941 | (undohist-initialize) |
685 | 942 | ||
@@ -736,19 +993,37 @@ ORG-EXPORT-ARGS are passed to `org-export-to-file'." | |||
736 | (keymap-global-set "C-x C-b" #'ibuffer) | 993 | (keymap-global-set "C-x C-b" #'ibuffer) |
737 | (add-hook 'ibuffer-hook #'hl-line-mode) | 994 | (add-hook 'ibuffer-hook #'hl-line-mode) |
738 | 995 | ||
739 | (autoload 'scule-map "scule" nil nil 'keymap) | 996 | (require 'scule) |
740 | (keymap-global-set "M-c" 'scule-map) | 997 | (keymap-global-set "M-c" scule-map) |
741 | (with-eval-after-load 'scule | 998 | (autoload 'titlecase-dwim "titlecase" nil t) |
742 | (keymap-set scule-map "M-t" #'titlecase-dwim)) | 999 | (keymap-set scule-map "M-t" #'titlecase-dwim) |
743 | 1000 | ||
744 | ;; Use M-u for prefix keys | 1001 | ;; Use M-u for prefix keys |
745 | (keymap-global-set "M-u" #'universal-argument) | 1002 | (keymap-global-set "M-u" #'universal-argument) |
746 | (keymap-set universal-argument-map "M-u" #'universal-argument-more) | 1003 | (keymap-set universal-argument-map "M-u" #'universal-argument-more) |
747 | 1004 | ||
1005 | (autoload 'frowny-mode "frowny" nil t) | ||
748 | (add-hook 'jabber-chat-mode-hook #'frowny-mode) | 1006 | (add-hook 'jabber-chat-mode-hook #'frowny-mode) |
1007 | (add-hook 'jabber-chat-mode-hook #'electric-pair-local-mode-disable) | ||
749 | 1008 | ||
1009 | (autoload 'hippie-completing-read "hippie-completing-read" nil t) | ||
750 | (keymap-global-set "M-/" #'hippie-completing-read) | 1010 | (keymap-global-set "M-/" #'hippie-completing-read) |
751 | 1011 | ||
752 | (setopt mode-line-bell-flash-time 0.25) | 1012 | (setopt mode-line-bell-flash-time 0.25) |
753 | (autoload 'mode-line-bell-mode "mode-line-bell" nil t) | 1013 | (autoload 'mode-line-bell-mode "mode-line-bell" nil t) |
754 | (mode-line-bell-mode) | 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) | ||