diff options
author | Case Duckworth | 2020-12-30 23:34:39 -0600 |
---|---|---|
committer | Case Duckworth | 2020-12-30 23:34:39 -0600 |
commit | 2f7a11caf34757bb66376daf6320c3dd36338dd3 (patch) | |
tree | d55ea10a20f71fbbf0089cccb7a8e34f9edb99c8 | |
parent | Fold init.el and early-init.el together (diff) | |
download | emacs-2f7a11caf34757bb66376daf6320c3dd36338dd3.tar.gz emacs-2f7a11caf34757bb66376daf6320c3dd36338dd3.zip |
Fuck with fonts
-rw-r--r-- | config.org | 1325 |
1 files changed, 553 insertions, 772 deletions
diff --git a/config.org b/config.org index c622e62..4596ef6 100644 --- a/config.org +++ b/config.org | |||
@@ -448,9 +448,7 @@ Since this /comes/ with smart mode line, I’m just going to use it, instead of | |||
448 | :height 100))) | 448 | :height 100))) |
449 | 449 | ||
450 | (set-face-from-alternatives 'fixed-pitch | 450 | (set-face-from-alternatives 'fixed-pitch |
451 | '(("Libertinus Mono" | 451 | '(("Linux Libertine Mono O" |
452 | :height 110) | ||
453 | ("Linux Libertine Mono O" | ||
454 | :height 110) | 452 | :height 110) |
455 | ("Go Mono" | 453 | ("Go Mono" |
456 | :height 100) | 454 | :height 100) |
@@ -459,7 +457,7 @@ Since this /comes/ with smart mode line, I’m just going to use it, instead of | |||
459 | 457 | ||
460 | (set-face-from-alternatives 'variable-pitch | 458 | (set-face-from-alternatives 'variable-pitch |
461 | '(("Libertinus Serif" | 459 | '(("Libertinus Serif" |
462 | :height 120) | 460 | :height 110) |
463 | ("Linux Libertine O" | 461 | ("Linux Libertine O" |
464 | :height 120) | 462 | :height 120) |
465 | ("Georgia" | 463 | ("Georgia" |
@@ -468,948 +466,731 @@ Since this /comes/ with smart mode line, I’m just going to use it, instead of | |||
468 | (remove-function after-focus-change-function #'acdw/setup-fonts))) | 466 | (remove-function after-focus-change-function #'acdw/setup-fonts))) |
469 | 467 | ||
470 | (add-function :before after-focus-change-function #'acdw/setup-fonts) | 468 | (add-function :before after-focus-change-function #'acdw/setup-fonts) |
471 | #+end_src | 469 | #+END_SRC |
472 | 470 | ||
473 | **** Variable-pitch in text modes | 471 | **** Custom faces |
474 | 472 | ||
475 | #+begin_src emacs-lisp | 473 | #+begin_src emacs-lisp |
476 | (add-hook 'text-mode-hook #'variable-pitch-mode) | 474 | (custom-set-faces `(font-lock-comment-face |
475 | ((t (:inherit (custom-comment italic variable-pitch)))))) | ||
477 | #+end_src | 476 | #+end_src |
478 | 477 | ||
479 | **** Line spacing | 478 | **** Line spacing |
480 | 479 | ||
481 | #+begin_src emacs-lisp | 480 | #+BEGIN_SRC emacs-lisp |
482 | (cuss line-spacing 0.1) | 481 | (cuss line-spacing 0.1 |
483 | #+end_src | 482 | "Add 10% extra space below each line.") |
483 | #+END_SRC | ||
484 | 484 | ||
485 | **** Unicode fonts | 485 | **** Unicode Fonts |
486 | 486 | ||
487 | #+begin_src emacs-lisp | 487 | #+BEGIN_SRC emacs-lisp |
488 | (straight-use-package 'unicode-fonts) | 488 | (straight-use-package 'unicode-fonts) |
489 | (with-eval-after-load 'unicode-fonts | 489 | (require 'unicode-fonts) |
490 | (unicode-fonts-setup)) | 490 | (unicode-fonts-setup) |
491 | #+end_src | 491 | #+END_SRC |
492 | |||
493 | * Interactivity | ||
494 | |||
495 | ** Async | ||
496 | 492 | ||
497 | #+begin_src emacs-lisp | 493 | ** Interactivity |
498 | (straight-use-package 'async) | ||
499 | (autoload 'dired-async-mode "dired-async.el" nil t) | ||
500 | (dired-async-mode +1) | ||
501 | 494 | ||
502 | (async-bytecomp-package-mode +1) | 495 | *** Completing read |
503 | #+end_src | ||
504 | 496 | ||
505 | ** Completing-read | 497 | **** Shadow file names in =completing-read=. |
506 | 498 | ||
507 | *** Shadow file names | 499 | #+BEGIN_SRC emacs-lisp |
508 | 500 | (cuss file-name-shadow-properties '(invisible t)) | |
509 | #+begin_src emacs-lisp | ||
510 | (cuss file-name-shadow-properties '(invisible t)) | ||
511 | 501 | ||
512 | (file-name-shadow-mode +1) | 502 | (file-name-shadow-mode +1) |
513 | #+end_src | 503 | #+END_SRC |
514 | 504 | ||
515 | *** Selectrum | 505 | **** Ignore case in =completing-read= |
516 | 506 | ||
517 | #+begin_src emacs-lisp | 507 | #+BEGIN_SRC emacs-lisp |
518 | (straight-use-package 'selectrum) | 508 | (cuss completion-ignore-case t) |
519 | (require 'selectrum) | 509 | (cuss read-buffer-completion-ignore-case t) |
520 | (selectrum-mode +1) | 510 | (cuss read-file-name-completion-ignore-case t) |
521 | #+end_src | 511 | #+END_SRC |
522 | 512 | ||
523 | *** Prescient | 513 | **** Selectrum |
524 | 514 | ||
525 | #+begin_src emacs-lisp | 515 | #+BEGIN_SRC emacs-lisp |
526 | (straight-use-package 'prescient) | 516 | (straight-use-package 'selectrum) |
527 | (require 'prescient) | 517 | (require 'selectrum) |
518 | (selectrum-mode +1) | ||
519 | #+END_SRC | ||
528 | 520 | ||
529 | (prescient-persist-mode +1) | 521 | **** Prescient |
530 | 522 | ||
531 | (straight-use-package 'selectrum-prescient) | 523 | #+BEGIN_SRC emacs-lisp |
524 | (straight-use-package 'prescient) | ||
525 | (require 'prescient) | ||
526 | (prescient-persist-mode +1) | ||
532 | 527 | ||
533 | (with-eval-after-load 'prescient | 528 | (straight-use-package 'selectrum-prescient) |
534 | (with-eval-after-load 'selectrum | 529 | (require 'selectrum-prescient) |
535 | (selectrum-prescient-mode +1))) | 530 | (selectrum-prescient-mode +1) |
536 | #+end_src | 531 | #+END_SRC |
537 | 532 | ||
538 | *** Consult | 533 | **** Consult |
539 | 534 | ||
540 | #+begin_src emacs-lisp | 535 | #+BEGIN_SRC emacs-lisp |
541 | (straight-use-package '(consult | 536 | (straight-use-package '(consult |
542 | :host github | 537 | :host github |
543 | :repo "minad/consult")) | 538 | :repo "minad/consult")) |
544 | (require 'consult) | 539 | (require 'consult) |
545 | 540 | ||
541 | (straight-use-package '(consult-selectrum | ||
542 | :host github | ||
543 | :repo "minad/consult")) | ||
544 | (require 'consult-selectrum) | ||
545 | |||
546 | (define-key ctl-x-map "b" #'consult-buffer) | 546 | (define-key ctl-x-map "b" #'consult-buffer) |
547 | (define-key ctl-x-map (kbd "C-r") #'consult-buffer) | ||
547 | (define-key ctl-x-map "4b" #'consult-buffer-other-window) | 548 | (define-key ctl-x-map "4b" #'consult-buffer-other-window) |
548 | (define-key ctl-x-map "5b" #'consult-buffer-other-frame) | 549 | (define-key ctl-x-map "5b" #'consult-buffer-other-frame) |
550 | |||
549 | (define-key goto-map "o" #'consult-outline) | 551 | (define-key goto-map "o" #'consult-outline) |
552 | (define-key goto-map "g" #'consult-line) | ||
553 | (define-key goto-map (kbd "M-g") #'consult-line) | ||
550 | (define-key goto-map "l" #'consult-line) | 554 | (define-key goto-map "l" #'consult-line) |
555 | (define-key goto-map "m" #'consult-mark) | ||
556 | (define-key goto-map "k" #'consult-global-mark) | ||
557 | (define-key goto-map "i" #'consult-imenu) | ||
558 | (define-key goto-map "e" #'consult-error) | ||
559 | |||
551 | (global-set-key (kbd "M-y") #'consult-yank-pop) | 560 | (global-set-key (kbd "M-y") #'consult-yank-pop) |
561 | |||
552 | (define-key help-map "a" #'consult-apropos) | 562 | (define-key help-map "a" #'consult-apropos) |
553 | 563 | ||
554 | (fset 'multi-occur #'consult-multi-occur) | 564 | (fset 'multi-occur #'consult-multi-occur) |
565 | #+END_SRC | ||
555 | 566 | ||
556 | (straight-use-package '(consult-selectrum | 567 | **** Marginalia |
557 | :host github | ||
558 | :repo "minad/consult")) | ||
559 | #+end_src | ||
560 | |||
561 | *** Marginalia | ||
562 | |||
563 | #+begin_src emacs-lisp | ||
564 | (straight-use-package '(marginalia | ||
565 | :host github | ||
566 | :repo "minad/marginalia" | ||
567 | :branch "main")) | ||
568 | |||
569 | (cuss marginalia-annotators | ||
570 | (if (eq system-type 'windows-nt) | ||
571 | '(marginalia-annotators-light | ||
572 | marginalia-annotators-heavy) | ||
573 | '(marginalia-annotators-heavy | ||
574 | marginalia-annotators-light))) | ||
575 | |||
576 | (marginalia-mode +1) | ||
577 | #+end_src | ||
578 | 568 | ||
579 | ** Ignore case | 569 | #+BEGIN_SRC emacs-lisp |
580 | 570 | (straight-use-package '(marginalia | |
581 | #+begin_src emacs-lisp | 571 | :host github |
582 | (cuss completion-ignore-case t) | 572 | :repo "minad/marginalia" |
583 | (cuss read-buffer-completion-ignore-case t) | 573 | :branch "main")) |
584 | (cuss read-file-name-completion-ignore-case t) | ||
585 | #+end_src | ||
586 | 574 | ||
587 | ** Search | 575 | (cuss marginalia-annotators |
576 | '(marginalia-annotators-heavy | ||
577 | marginalia-annotators-light)) | ||
588 | 578 | ||
589 | #+begin_src emacs-lisp | 579 | (marginalia-mode +1) |
590 | (straight-use-package 'ctrlf) | 580 | #+END_SRC |
591 | (require 'ctrlf) | ||
592 | 581 | ||
593 | (cuss ctrlf-show-match-count-at-eol nil) | 582 | **** COMMENT Ido |
594 | 583 | ||
595 | (cuss ctrlf-mode-bindings | 584 | [[https://wandersoncferreira.github.io/blog/ido/][Let’s try this out]]. |
596 | '(("C-s" . ctrlf-forward-regexp) | ||
597 | ("C-r" . ctrlf-backward-regexp) | ||
598 | ("C-M-s" . ctrlf-forward-literal) | ||
599 | ("C-M-r" . ctrlf-backward-literal) | ||
600 | ("M-s _" . ctrlf-forward-symbol) | ||
601 | ("M-s ." . ctrlf-forward-symbol-at-point))) | ||
602 | |||
603 | (ctrlf-mode +1) | ||
604 | #+end_src | ||
605 | |||
606 | ** Replace | ||
607 | 585 | ||
608 | #+begin_src emacs-lisp | 586 | #+begin_src emacs-lisp |
609 | (straight-use-package 'anzu) | 587 | (defun ido-choose-from-recentf () |
610 | (global-anzu-mode +1) | 588 | "Use ido to select recently visited files." |
611 | 589 | (interactive) | |
612 | (cuss anzu-replace-to-string-separator " → ") | 590 | (find-file (ido-completing-read "Open file: " recentf-list nil t))) |
613 | (global-set-key (kbd "M-%") #'anzu-query-replace-regexp) | ||
614 | (global-set-key (kbd "M-C-%") #'anzu-query-replace) | ||
615 | #+end_src | ||
616 | |||
617 | ** Mouse | ||
618 | |||
619 | *** Fix scrolling in margins | ||
620 | |||
621 | This is not /quite/ correct yet. For example, scrolling in the margins with a trackpad isn’t picked up (a trackpad sends different mouse events). | ||
622 | 591 | ||
623 | #+begin_src emacs-lisp | 592 | (defun bk/go-straight-home () |
624 | (dolist (vec '([left-margin wheel-down] | 593 | (interactive) |
625 | [right-margin wheel-down] | 594 | (cond |
626 | [left-margin wheel-up] | 595 | ((looking-back "~/") (insert "projects/")) |
627 | [right-margin wheel-up])) | 596 | ((looking-back "/") (insert "~/")) |
628 | (global-set-key vec #'mwheel-scroll)) | 597 | (:else (call-interactively 'self-insert-command)))) |
598 | |||
599 | (defun ido-disable-line-truncation () | ||
600 | (set (make-local-variable 'truncate-lines) nil)) | ||
601 | |||
602 | (defun ido-define-keys () | ||
603 | (define-key ido-completion-map (kbd "C-n") 'ido-next-match) | ||
604 | (define-key ido-completion-map (kbd "C-p") 'ido-prev-match)) | ||
605 | |||
606 | (setq ido-enable-flex-matching t | ||
607 | ido-use-filename-at-point nil | ||
608 | ido-create-new-buffer 'always | ||
609 | confirm-nonexistent-file-or-buffer nil | ||
610 | completion-ignored-extensions (cons "*.aux" completion-ignored-extensions) | ||
611 | max-mini-window-height 0.5 | ||
612 | ido-enable-tramp-completion t | ||
613 | ido-auto-merge-work-directories-length -1 | ||
614 | ido-confirm-unique-completion t | ||
615 | ido-default-file-method 'selected-window | ||
616 | ido-case-fold t | ||
617 | ido-show-dot-for-dired t | ||
618 | ido-everywhere t | ||
619 | ido-ignore-buffers (list (rx (or (and bos " ") | ||
620 | (and bos | ||
621 | (or "*Completions*" | ||
622 | "*Compile-Log*" | ||
623 | "*Ido Completions*" | ||
624 | "*Shell Command Output*" | ||
625 | "*vc-diff*") | ||
626 | eos)))) | ||
627 | ido-decorations (quote ("\n-> " "" "\n " "\n ..." "[" "]" " | ||
628 | [No match]" " [Matched]" " [Not readable]" " [Too big]" " | ||
629 | [Confirm]"))) | ||
630 | |||
631 | (with-eval-after-load 'ido | ||
632 | (define-key ido-common-completion-map (kbd "M-SPC") 'just-one-space) | ||
633 | (define-key ido-common-completion-map (kbd "SPC") 'self-insert-command) | ||
634 | (define-key ido-file-completion-map (kbd "~") 'bk/go-straight-home) | ||
635 | |||
636 | (add-hook 'ido-setup-hook 'ido-define-keys) | ||
637 | |||
638 | (add-hook 'ido-minibuffer-setup-hook 'ido-disable-line-truncation) | ||
639 | |||
640 | (set-default 'imenu-auto-rescan t) | ||
641 | |||
642 | (add-to-list 'ido-ignore-directories "target") | ||
643 | (add-to-list 'ido-ignore-directories "node_modules") | ||
644 | ) | ||
645 | |||
646 | (defun setup-ido-mode () | ||
647 | (require 'ido) | ||
648 | (ido-mode +1) | ||
649 | (ido-everywhere +1)) | ||
650 | |||
651 | (add-hook 'after-init-hook #'setup-ido-mode) | ||
629 | #+end_src | 652 | #+end_src |
630 | 653 | ||
631 | ** Keyboard | 654 | ** Keyboard |
632 | 655 | ||
633 | *** Use =ESC= as a cancel key | 656 | *** =ESC= cancels all |
634 | 657 | ||
635 | From [[https://github.com/link0ff/emacs-init][link0ff]]. I thought they made a great point that =ESC= isn’t necessary to copy the =META= key on window-systems, which is where I use Emacs, anyway. | 658 | #+BEGIN_SRC emacs-lisp |
659 | (global-set-key (kbd "<escape>") #'keyboard-escape-quit) | ||
660 | #+END_SRC | ||
636 | 661 | ||
637 | #+begin_src emacs-lisp | 662 | *** Personal prefix key: =C-z= |
638 | (when window-system | ||
639 | (global-set-key [escape] 'keyboard-escape-quit) | ||
640 | (define-key isearch-mode-map [escape] 'isearch-cancel)) | ||
641 | #+end_src | ||
642 | 663 | ||
643 | *** Make =C-z= more useful as a prefix key | 664 | #+BEGIN_SRC emacs-lisp |
665 | (defvar acdw/map | ||
666 | (let ((map (make-sparse-keymap)) | ||
667 | (c-z (global-key-binding "\C-z"))) | ||
668 | (global-unset-key "\C-z") | ||
669 | (define-key global-map "\C-z" map) | ||
670 | (define-key map "\C-z" c-z) | ||
671 | map)) | ||
644 | 672 | ||
645 | Also from link0ff. See the above for a link. | 673 | (run-hooks 'acdw/map-defined-hook) |
646 | 674 | #+END_SRC | |
647 | #+begin_src emacs-lisp | ||
648 | (defvar acdw/map | ||
649 | (let ((map (make-sparse-keymap)) | ||
650 | (c-z (global-key-binding "\C-z"))) | ||
651 | (global-unset-key "\C-z") | ||
652 | (define-key global-map "\C-z" map) | ||
653 | (define-key map "\C-z" c-z) | ||
654 | map)) | ||
655 | (run-hooks 'acdw/map-defined-hook) | ||
656 | #+end_src | ||
657 | 675 | ||
658 | *** Which-key | 676 | ** Persistence |
659 | 677 | ||
660 | #+begin_src emacs-lisp | 678 | *** Minibuffer history |
661 | (straight-use-package 'which-key) | ||
662 | 679 | ||
663 | (which-key-mode +1) | 680 | #+BEGIN_SRC emacs-lisp |
664 | #+end_src | 681 | (require 'savehist) |
665 | 682 | ||
666 | *** Bindings | 683 | (cuss savehist-additional-variables |
684 | '(kill-ring | ||
685 | search-ring | ||
686 | regexp-search-ring) | ||
687 | "Other variables to save alongside the minibuffer history.") | ||
667 | 688 | ||
668 | **** Switch to another window | 689 | (cuss history-length t |
690 | "Don't truncate history.") | ||
669 | 691 | ||
670 | #+begin_src emacs-lisp | 692 | (cuss history-delete-duplicates t |
671 | (global-set-key (kbd "M-o") #'other-window) | 693 | "Delete history duplicates.") |
672 | #+end_src | ||
673 | 694 | ||
674 | * Persistence | 695 | (savehist-mode +1) |
696 | #+END_SRC | ||
675 | 697 | ||
676 | ** Save history | 698 | *** File places |
677 | 699 | ||
678 | #+begin_src emacs-lisp | 700 | #+BEGIN_SRC emacs-lisp |
679 | (require 'savehist) | 701 | (require 'saveplace) ; this isn't required, but ... I like having it here |
680 | 702 | ||
681 | (cuss savehist-additional-variables | 703 | (cuss save-place-forget-unreadable-files t |
682 | '(kill-ring | 704 | "Don't check if files are readable or not.") |
683 | search-ring | ||
684 | regexp-search-ring)) | ||
685 | 705 | ||
686 | (cuss savehist-save-minibuffer-history t) | 706 | (save-place-mode +1) |
707 | #+END_SRC | ||
687 | 708 | ||
688 | (cuss history-length t) | 709 | *** Recent files |
689 | 710 | ||
690 | (cuss history-delete-duplicates t) | 711 | #+BEGIN_SRC emacs-lisp |
712 | (require 'recentf) | ||
691 | 713 | ||
692 | (savehist-mode +1) | 714 | (cuss recentf-max-menu-items 100 |
693 | #+end_src | 715 | "The maximum number of items in the recentf menu.") |
716 | (cuss recentf-max-saved-items nil | ||
717 | "Don't limit the number of recent files.") | ||
694 | 718 | ||
695 | ** Save places in files | 719 | (with-eval-after-load 'no-littering |
720 | (add-to-list 'recentf-exclude no-littering-var-directory) | ||
721 | (add-to-list 'recentf-exclude no-littering-etc-directory)) | ||
696 | 722 | ||
697 | #+begin_src emacs-lisp | 723 | (recentf-mode +1) |
698 | (require 'saveplace) | ||
699 | 724 | ||
700 | (cuss save-place-forget-unreadable-files | 725 | ;; save the recentf-list every 5 minutes |
701 | (not (eq system-type 'windows-nt))) | 726 | (run-at-time nil (* 5 60) 'recentf-save-list) |
702 | 727 | #+END_SRC | |
703 | (save-place-mode 1) | ||
704 | #+end_src | ||
705 | |||
706 | ** Recent files | ||
707 | |||
708 | #+begin_src emacs-lisp | ||
709 | (require 'recentf) | ||
710 | |||
711 | (cuss recentf-max-menu-items 100) | ||
712 | (cuss recentf-max-saved-items 100) | ||
713 | |||
714 | (with-eval-after-load 'no-littering | ||
715 | (add-to-list 'recentf-exclude no-littering-var-directory) | ||
716 | (add-to-list 'recentf-exclude no-littering-etc-directory)) | ||
717 | |||
718 | (recentf-mode 1) | ||
719 | #+end_src | ||
720 | |||
721 | *** Easily navigate recent files | ||
722 | |||
723 | #+begin_src emacs-lisp | ||
724 | (defun recentf-find-file () | ||
725 | "Find a recent file using `completing-read'." | ||
726 | (interactive) | ||
727 | (let ((file (completing-read "Recent file: " recentf-list nil t))) | ||
728 | (when file | ||
729 | (find-file file)))) | ||
730 | |||
731 | (global-set-key (kbd "C-x C-r") #'recentf-find-file) | ||
732 | #+end_src | ||
733 | 728 | ||
734 | ** Undo | 729 | ** Undo |
735 | 730 | ||
736 | #+begin_src emacs-lisp | 731 | #+BEGIN_SRC emacs-lisp |
737 | (straight-use-package 'undo-fu) | 732 | (straight-use-package 'undo-fu) |
738 | (require 'undo-fu) | 733 | (require 'undo-fu) |
739 | 734 | ||
740 | (global-set-key (kbd "C-/") #'undo-fu-only-undo) | 735 | (global-set-key (kbd "C-/") #'undo-fu-only-undo) |
741 | (global-set-key (kbd "C-?") #'undo-fu-only-redo) | 736 | (global-set-key (kbd "C-?") #'undo-fu-only-redo) |
742 | 737 | ||
743 | (straight-use-package 'undo-fu-session) | 738 | (straight-use-package 'undo-fu-session) |
744 | (require 'undo-fu-session) | 739 | (require 'undo-fu-session) |
745 | 740 | ||
746 | (cuss undo-fu-session-incompatible-files | 741 | (cuss undo-fu-session-incompatible-files |
747 | '("/COMMIT_EDITMSG\\'" | 742 | '("/COMMIT_EDITMSG\\'" |
748 | "/git-rebase-todo\\'")) | 743 | "/git-rebase-todo\\'") |
744 | "A list of files that are incompatible with the concept of undo sessions.") | ||
749 | 745 | ||
750 | (global-undo-fu-session-mode +1) | 746 | (with-eval-after-load 'no-littering |
747 | (let ((dir (no-littering-expand-var-file-name "undos"))) | ||
748 | (make-directory dir 'parents) | ||
749 | (cuss undo-fu-session-directory dir))) | ||
751 | 750 | ||
752 | #+end_src | 751 | (global-undo-fu-session-mode +1) |
752 | #+END_SRC | ||
753 | 753 | ||
754 | * Editing | 754 | ** Files |
755 | 755 | ||
756 | ** Operate visually on lines | 756 | *** Encoding |
757 | 757 | ||
758 | #+begin_src emacs-lisp | 758 | **** UTF-8 |
759 | (global-visual-line-mode +1) | ||
760 | #+end_src | ||
761 | 759 | ||
762 | ** Require a final newline | 760 | #+BEGIN_SRC emacs-lisp |
761 | (set-language-environment "UTF-8") | ||
762 | (set-terminal-coding-system 'utf-8) | ||
763 | (cuss locale-coding-system 'utf-8) | ||
764 | (set-default-coding-systems 'utf-8) | ||
765 | (set-selection-coding-system 'utf-8) | ||
766 | (prefer-coding-system 'utf-8) | ||
767 | #+END_SRC | ||
763 | 768 | ||
764 | #+begin_src emacs-lisp | 769 | **** Convert all files to UNIX-style line endings |
765 | (cuss require-final-newline t) | ||
766 | #+end_src | ||
767 | 770 | ||
768 | ** Killing & Yanking | 771 | from [[https://www.emacswiki.org/emacs/EndOfLineTips][Emacs Wiki]]. |
769 | 772 | ||
770 | *** Replace selection when typing | 773 | #+BEGIN_SRC emacs-lisp |
774 | (defun ewiki/no-junk-please-were-unixish () | ||
775 | "Convert line endings to UNIX, dammit." | ||
776 | (let ((coding-str (symbol-name buffer-file-coding-system))) | ||
777 | (when (string-match "-\\(?:dos\\|mac\\)$" coding-str) | ||
778 | (set-buffer-file-coding-system 'unix)))) | ||
779 | #+END_SRC | ||
780 | |||
781 | I add it to the ~find-file-hook~ /and/ ~before-save-hook~ because I | ||
782 | don't want to ever work with anything other than UNIX line endings | ||
783 | ever again. I just don't care. Even Microsoft Notepad can handle | ||
784 | UNIX line endings, so I don't want to hear it. | ||
771 | 785 | ||
772 | #+begin_src emacs-lisp | 786 | #+BEGIN_SRC emacs-lisp |
773 | (delete-selection-mode +1) | 787 | (add-hook 'find-file-hook #'ewiki/no-junk-please-were-unixish) |
774 | #+end_src | 788 | (add-hook 'before-save-hook #'ewiki/no-junk-please-were-unixish) |
789 | #+END_SRC | ||
775 | 790 | ||
776 | *** Save existing clipboard text into kill ring before replacing it | 791 | *** Backups |
777 | 792 | ||
778 | #+begin_src emacs-lisp | 793 | #+BEGIN_SRC emacs-lisp |
779 | (cuss save-interprogram-paste-before-kill t) | 794 | (cuss backup-by-copying 1) |
780 | #+end_src | 795 | (cuss delete-old-versions -1) |
796 | (cuss version-control t) | ||
797 | (cuss vc-make-backup-files t) | ||
781 | 798 | ||
782 | *** Sync the system clipboard and the kill ring | 799 | (with-eval-after-load 'no-littering |
800 | (let ((dir (no-littering-expand-var-file-name "backup"))) | ||
801 | (make-directory dir 'parents) | ||
802 | (cuss backup-directory-alist | ||
803 | `((".*" . ,dir))))) | ||
804 | #+END_SRC | ||
783 | 805 | ||
784 | #+begin_src emacs-lisp | 806 | *** Auto-saves |
785 | (cuss yank-pop-change-selection t) | ||
786 | #+end_src | ||
787 | 807 | ||
788 | ** So long mode | 808 | #+BEGIN_SRC emacs-lisp |
809 | (with-eval-after-load 'no-littering | ||
810 | (let ((dir (no-littering-expand-var-file-name "autosaves"))) | ||
811 | (make-directory dir 'parents) | ||
812 | (cuss auto-save-file-name-transforms | ||
813 | `((".*" ,dir t)))) | ||
789 | 814 | ||
790 | #+begin_src emacs-lisp | 815 | (auto-save-visited-mode +1)) |
791 | (when (fboundp 'global-so-long-mode) | 816 | #+END_SRC |
792 | (global-so-long-mode)) | ||
793 | #+end_src | ||
794 | 817 | ||
795 | ** Multiple cursors | 818 | *** Auto-revert buffers to files on disk |
796 | 819 | ||
797 | #+begin_src emacs-lisp | 820 | #+BEGIN_SRC emacs-lisp |
798 | (straight-use-package 'multiple-cursors) | 821 | (global-auto-revert-mode +1) |
822 | #+END_SRC | ||
799 | 823 | ||
800 | (global-set-key (kbd "C->") #'mc/mark-next-like-this) | 824 | *** Add a timestamp to files |
801 | (global-set-key (kbd "C-<") #'mc/mark-previous-like-this) | ||
802 | (global-set-key (kbd "C-c C-<") #'mc/mark-all-like-this) | ||
803 | #+end_src | ||
804 | 825 | ||
805 | ** Expand region | 826 | #+BEGIN_SRC emacs-lisp |
827 | (add-hook 'before-save-hook #'time-stamp) | ||
828 | #+END_SRC | ||
806 | 829 | ||
807 | #+begin_src emacs-lisp | 830 | *** Require a final new line |
808 | (straight-use-package 'expand-region) | ||
809 | 831 | ||
810 | (global-set-key (kbd "C-=") #'er/expand-region) | 832 | #+BEGIN_SRC emacs-lisp |
811 | (global-set-key (kbd "C-+") #'er/contract-region) | 833 | (cuss require-final-newline t) |
812 | #+end_src | 834 | #+END_SRC |
813 | 835 | ||
814 | ** Highlight modified regions | 836 | ** Text editing |
815 | 837 | ||
816 | #+begin_src emacs-lisp | 838 | *** Operate visually on lines |
817 | (straight-use-package 'goggles) | ||
818 | 839 | ||
819 | (cuss goggles-pulse nil) | 840 | #+BEGIN_SRC emacs-lisp |
841 | (global-visual-line-mode +1) | ||
842 | #+END_SRC | ||
820 | 843 | ||
821 | (goggles-mode +1) | 844 | *** Stay snappy with long-lined files |
822 | #+end_src | ||
823 | 845 | ||
824 | * Files | 846 | #+BEGIN_SRC emacs-lisp |
847 | (when (fboundp 'global-so-long-mode) | ||
848 | (global-so-long-mode +1)) | ||
849 | #+END_SRC | ||
825 | 850 | ||
826 | ** Encoding | 851 | *** Killing & Yanking |
827 | 852 | ||
828 | *** UTF-8 | 853 | **** Replace selection when typing |
829 | 854 | ||
830 | #+begin_src emacs-lisp | 855 | #+BEGIN_SRC emacs-lisp |
831 | (set-language-environment "UTF-8") | 856 | (delete-selection-mode +1) |
832 | (set-terminal-coding-system 'utf-8) | 857 | #+END_SRC |
833 | (cuss locale-coding-system 'utf-8) | ||
834 | (set-default-coding-systems 'utf-8) | ||
835 | (set-selection-coding-system 'utf-8) | ||
836 | (prefer-coding-system 'utf-8) | ||
837 | #+end_src | ||
838 | 858 | ||
839 | *** Convert all files to UNIX-style line endings | 859 | **** Work better with the system clipboard |
840 | 860 | ||
841 | from [[https://www.emacswiki.org/emacs/EndOfLineTips][Emacs Wiki]]. | 861 | #+BEGIN_SRC emacs-lisp |
862 | (cuss save-interprogram-paste-before-kill t | ||
863 | "Save existing clipboard text into the kill ring before | ||
864 | replacing it.") | ||
842 | 865 | ||
843 | #+begin_src emacs-lisp | 866 | (cuss yank-pop-change-selection t |
844 | (defun ewiki/no-junk-please-were-unixish () | 867 | "Update the X selection when rotating the kill ring.") |
845 | "Convert line endings to UNIX, dammit." | 868 | #+END_SRC |
846 | (let ((coding-str (symbol-name buffer-file-coding-system))) | ||
847 | (when (string-match "-\\(?:dos\\|mac\\)$" coding-str) | ||
848 | (set-buffer-file-coding-system 'unix)))) | ||
849 | #+end_src | ||
850 | 869 | ||
851 | I add it to the ~find-file-hook~ /and/ ~before-save-hook~ because I don't want to ever work with anything other than UNIX line endings ever again. I just don't care. Even Microsoft Notepad can handle UNIX line endings, so I don't want to hear it. | 870 | *** Searching & Replacing |
852 | 871 | ||
853 | #+begin_src emacs-lisp | 872 | **** COMMENT Search with CtrlF |
854 | (add-hook 'find-file-hook #'ewiki/no-junk-please-were-unixish) | ||
855 | (add-hook 'before-save-hook #'ewiki/no-junk-please-were-unixish) | ||
856 | #+end_src | ||
857 | 873 | ||
858 | ** Backups | 874 | For right now, I’m /just/ using Anzu – I don’t like parts of =isearch= but … CtrlF doesn’t match with that sweet replace flow. |
859 | 875 | ||
860 | #+begin_src emacs-lisp | 876 | #+begin_src emacs-lisp |
861 | (cuss backup-by-copying 1) | 877 | (straight-use-package 'ctrlf) |
862 | (cuss delete-old-versions -1) | 878 | (ctrlf-mode +1) |
863 | (cuss version-control t) | ||
864 | (cuss vc-make-backup-files t) | ||
865 | #+end_src | 879 | #+end_src |
866 | 880 | ||
867 | ** Auto-saves | 881 | **** Replace with Anzu |
868 | 882 | ||
869 | #+begin_src emacs-lisp | 883 | #+begin_src emacs-lisp |
870 | (auto-save-visited-mode 1) | 884 | (straight-use-package 'anzu) |
871 | #+end_src | 885 | (require 'anzu) |
872 | 886 | ||
873 | ** Revert files | 887 | ;; show search count in the modeline |
888 | (global-anzu-mode +1) | ||
874 | 889 | ||
875 | #+begin_src emacs-lisp | 890 | (cuss anzu-replace-to-string-separator " → " |
876 | (cuss auto-revert-verbose nil) | 891 | "What to separate the search from the replacement.") |
877 | (global-auto-revert-mode +1) | ||
878 | #+end_src | ||
879 | 892 | ||
880 | ** Add a timestamp to files | 893 | (global-set-key [remap query-replace] #'anzu-query-replace) |
881 | 894 | (global-set-key [remap query-replace-regexp] #'anzu-query-replace-regexp) | |
882 | #+begin_src emacs-lisp | ||
883 | (add-hook 'before-save-hook #'time-stamp) | ||
884 | #+end_src | ||
885 | 895 | ||
886 | * Programming | 896 | (define-key isearch-mode-map [remap isearch-query-replace] #'anzu-isearch-query-replace) |
897 | (define-key isearch-mode-map [remap isearch-query-replace-regexp] #'anzu-isearch-query-replace-regexp) | ||
887 | 898 | ||
888 | ** Which function are we in? | ||
889 | 899 | ||
890 | #+begin_src emacs-lisp | ||
891 | (which-function-mode +1) | ||
892 | #+end_src | 900 | #+end_src |
893 | 901 | ||
894 | ** Parentheses | 902 | * Programming |
895 | |||
896 | *** Show parentheses | ||
897 | 903 | ||
898 | #+begin_src emacs-lisp | 904 | ** Parentheses |
899 | (cuss show-paren-delay 0 "Show matching parens immediately.") | ||
900 | (cuss show-paren-style 'mixed | ||
901 | "Show parenthesis, or whole expression, depending on visibility.") | ||
902 | (cuss show-paren-when-point-in-periphery t | ||
903 | "Show paren when point is near-to paren.") | ||
904 | (cuss show-paren-when-point-inside-paren t | ||
905 | "Show surrounding parens.") | ||
906 | |||
907 | (add-hook 'prog-mode-hook #'show-paren-mode) | ||
908 | #+end_src | ||
909 | 905 | ||
910 | *** Smart parentheses | 906 | *** Smart parentheses |
911 | 907 | ||
912 | #+begin_src emacs-lisp | 908 | #+BEGIN_SRC emacs-lisp |
913 | (straight-use-package 'smartparens) | 909 | (straight-use-package 'smartparens) |
914 | (require 'smartparens-config) | 910 | (require 'smartparens-config) |
915 | |||
916 | (show-smartparens-global-mode +1) | ||
917 | (add-to-list 'sp-ignore-modes-list 'org-mode) | ||
918 | 911 | ||
919 | (add-hook 'prog-mode-hook #'smartparens-strict-mode) | 912 | ;; replace show-paren |
920 | #+end_src | ||
921 | 913 | ||
922 | ** COMMENT Line numbers | 914 | (cuss sp-show-pair-delay 0 |
915 | "Don't delay before showing the pairs.") | ||
916 | (cuss sp-show-pair-from-inside t | ||
917 | "Highlight the enclosing pair when immediately inside.") | ||
923 | 918 | ||
924 | #+begin_src emacs-lisp | 919 | (add-hook 'prog-mode-hook #'show-smartparens-mode +1) |
925 | (defun acdw/enable-line-numbers () | ||
926 | "Enable line numbers, through either | ||
927 | `display-line-numbers-mode' or through `linum-mode'." | ||
928 | (if (and (fboundp 'display-line-numbers-mode) | ||
929 | (display-graphic-p)) | ||
930 | (display-line-numbers-mode +1) | ||
931 | (linum-mode +1))) | ||
932 | |||
933 | (cuss display-line-numbers-width 2 | ||
934 | "Always have at least 2 digits for line numbers.") | ||
935 | |||
936 | (add-hook 'prog-mode-hook #'acdw/enable-line-numbers) | ||
937 | #+end_src | ||
938 | 920 | ||
939 | ** Indenting | 921 | ;; enable strict smartparens in prog mode |
922 | (add-hook 'prog-mode-hook #'smartparens-strict-mode) | ||
923 | #+END_SRC | ||
940 | 924 | ||
941 | #+begin_src emacs-lisp | 925 | ** Indent aggressively |
942 | (straight-use-package 'aggressive-indent) | ||
943 | 926 | ||
944 | (global-aggressive-indent-mode +1) | 927 | #+BEGIN_SRC emacs-lisp |
945 | #+end_src | 928 | (straight-use-package 'aggressive-indent) |
946 | 929 | ||
947 | ** Completion | 930 | (global-aggressive-indent-mode +1) |
931 | #+END_SRC | ||
948 | 932 | ||
949 | #+begin_src emacs-lisp | 933 | ** Language-specific packages |
950 | (unless (eq system-type 'windows-nt) | ||
951 | (straight-use-package 'company) | ||
952 | (cuss company-idle-delay 0.1) | ||
953 | (cuss company-minimum-prefix-length 2) | ||
954 | |||
955 | (add-hook 'prog-mode-hook #'company-mode) | ||
956 | |||
957 | (straight-use-package 'company-prescient) | ||
958 | (add-hook 'company-mode-hook #'company-prescient-mode) | ||
959 | |||
960 | (straight-use-package 'company-posframe) | ||
961 | |||
962 | (with-eval-after-load 'company | ||
963 | (company-posframe-mode +1) | ||
964 | (define-key company-active-map (kbd "C-n") | ||
965 | (lambda () | ||
966 | (interactive) | ||
967 | (company-complete-common-or-cycle +1))) | ||
968 | (define-key company-active-map (kbd "C-p") | ||
969 | (lambda () | ||
970 | (interactive) | ||
971 | (company-complete-common-or-cycle -1))))) | ||
972 | #+end_src | ||
973 | |||
974 | ** Languages | ||
975 | |||
976 | *** Lua | ||
977 | |||
978 | #+begin_src emacs-lisp | ||
979 | (straight-use-package 'lua-mode) | ||
980 | (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-mode)) | ||
981 | (add-to-list 'interpreter-mode-alist '("lua" . lua-mode)) | ||
982 | #+end_src | ||
983 | |||
984 | *** Fennel | ||
985 | |||
986 | #+begin_src emacs-lisp | ||
987 | (straight-use-package 'fennel-mode) | ||
988 | (add-to-list 'auto-mode-alist '("\\.fnl\\'" . fennel-mode)) | ||
989 | #+end_src | ||
990 | 934 | ||
991 | *** Emacs lisp | 935 | *** Emacs lisp |
992 | 936 | ||
993 | #+begin_src emacs-lisp | 937 | #+BEGIN_SRC emacs-lisp |
994 | (cuss eval-expression-print-length nil | 938 | (cuss eval-expression-print-length nil |
995 | "Don't truncate printed expressions by length.") | 939 | "Don't truncate printed expressions by length.") |
996 | (cuss eval-expression-print-level nil | 940 | (cuss eval-expression-print-level nil |
997 | "Don't truncate printed expressions by level.") | 941 | "Don't truncate printed expressions by level.") |
998 | #+end_src | 942 | #+END_SRC |
999 | 943 | ||
1000 | * Writing | 944 | * Writing |
1001 | 945 | ||
1002 | ** Visual Fill Column | 946 | ** Visual fill column |
1003 | |||
1004 | #+begin_src emacs-lisp | ||
1005 | (straight-use-package 'visual-fill-column) | ||
1006 | |||
1007 | (cuss split-window-preferred-function | ||
1008 | 'visual-fill-column-split-window-sensibly) | ||
1009 | (cuss visual-fill-column-center-text t) | ||
1010 | (cuss fill-column 80) | ||
1011 | |||
1012 | (advice-add 'text-scale-adjust | ||
1013 | :after #'visual-fill-column-adjust) | ||
1014 | |||
1015 | (add-hook 'text-mode-hook #'visual-fill-column-mode) | ||
1016 | #+end_src | ||
1017 | |||
1018 | *** COMMENT Split windows /more/ sensibly | ||
1019 | |||
1020 | from [[https://stackoverflow.com/questions/23659909/reverse-evaluation-order-of-split-height-threshold-and-split-width-threshold-in][Stack Overflow]]. | ||
1021 | |||
1022 | #+begin_src emacs-lisp | ||
1023 | (defun my-split-window-sensibly (&optional window) | ||
1024 | (let ((window (or window (selected-window)))) | ||
1025 | (or (and (window-splittable-p window t) | ||
1026 | ;; Split window horizontally. | ||
1027 | (with-selected-window window | ||
1028 | (split-window-right))) | ||
1029 | (and (window-splittable-p window) | ||
1030 | ;; Split window vertically. | ||
1031 | (with-selected-window window | ||
1032 | (split-window-below))) | ||
1033 | (and (eq window (frame-root-window (window-frame window))) | ||
1034 | (not (window-minibuffer-p window)) | ||
1035 | ;; If WINDOW is the only window on its frame and is not the | ||
1036 | ;; minibuffer window, try to split it horizontally disregarding | ||
1037 | ;; the value of `split-width-threshold'. | ||
1038 | (let ((split-width-threshold 0)) | ||
1039 | (when (window-splittable-p window t) | ||
1040 | (with-selected-window window | ||
1041 | (split-window-right)))))))) | ||
1042 | |||
1043 | (setq split-window-preferred-function #'my-split-window-sensibly) | ||
1044 | #+end_src | ||
1045 | 947 | ||
1046 | ** Type nice-looking quote-type marks | 948 | *** Fix scrolling in margins |
1047 | |||
1048 | #+begin_src emacs-lisp | ||
1049 | (straight-use-package 'typo) | ||
1050 | (add-hook 'text-mode-hook #'typo-mode) | ||
1051 | #+end_src | ||
1052 | 949 | ||
1053 | ** Insert /kaomoji/ | 950 | This has to be done /before/ loading the package. It's included in =visual-fill-column=, too, but for some reason isn't loaded there. |
1054 | 951 | ||
1055 | #+begin_src emacs-lisp | 952 | #+BEGIN_SRC emacs-lisp |
1056 | (straight-use-package 'insert-kaomoji) | 953 | (global-set-key [right-margin mouse-1] (global-key-binding [mouse-1])) ; #'mouse-set-point |
1057 | (global-set-key (kbd "C-x 8 k") #'insert-kaomoji) | 954 | (global-set-key [right-margin mouse-2] (global-key-binding [mouse-2])) ; #'mouse-yank-primary |
1058 | #+end_src | 955 | (global-set-key [right-margin mouse-3] (global-key-binding [mouse-3])) ; #'mouse-save-then-kill |
956 | (global-set-key [right-margin drag-mouse-1] #'ignore) | ||
957 | (global-set-key [right-margin drag-mouse-2] #'ignore) | ||
958 | (global-set-key [right-margin drag-mouse-3] #'ignore) | ||
959 | (global-set-key [right-margin double-mouse-1] #'ignore) | ||
960 | (global-set-key [right-margin double-mouse-2] #'ignore) | ||
961 | (global-set-key [right-margin double-mouse-3] #'ignore) | ||
962 | (global-set-key [right-margin triple-mouse-1] #'ignore) | ||
963 | (global-set-key [right-margin triple-mouse-2] #'ignore) | ||
964 | (global-set-key [right-margin triple-mouse-3] #'ignore) | ||
965 | (global-set-key [left-margin mouse-1] (global-key-binding [mouse-1])) ; #'mouse-set-point | ||
966 | (global-set-key [left-margin mouse-2] (global-key-binding [mouse-2])) ; #'mouse-yank-primary | ||
967 | (global-set-key [left-margin mouse-3] (global-key-binding [mouse-3])) ; #'mouse-save-then-kill | ||
968 | (global-set-key [left-margin drag-mouse-1] #'ignore) | ||
969 | (global-set-key [left-margin drag-mouse-2] #'ignore) | ||
970 | (global-set-key [left-margin drag-mouse-3] #'ignore) | ||
971 | (global-set-key [left-margin double-mouse-1] #'ignore) | ||
972 | (global-set-key [left-margin double-mouse-2] #'ignore) | ||
973 | (global-set-key [left-margin double-mouse-3] #'ignore) | ||
974 | (global-set-key [left-margin triple-mouse-1] #'ignore) | ||
975 | (global-set-key [left-margin triple-mouse-2] #'ignore) | ||
976 | (global-set-key [left-margin triple-mouse-3] #'ignore) | ||
977 | |||
978 | (mouse-wheel-mode +1) | ||
979 | |||
980 | (when (bound-and-true-p mouse-wheel-mode) | ||
981 | (global-set-key [right-margin mouse-wheel-down-event] #'mwheel-scroll) | ||
982 | (global-set-key [right-margin mouse-wheel-up-event] #'mwheel-scroll) | ||
983 | (global-set-key [right-margin wheel-down] #'mwheel-scroll) | ||
984 | (global-set-key [right-margin wheel-up] #'mwheel-scroll) | ||
985 | (global-set-key [left-margin mouse-wheel-down-event] #'mwheel-scroll) | ||
986 | (global-set-key [left-margin mouse-wheel-up-event] #'mwheel-scroll) | ||
987 | (global-set-key [left-margin wheel-down] #'mwheel-scroll) | ||
988 | (global-set-key [left-margin wheel-up] #'mwheel-scroll)) | ||
989 | #+END_SRC | ||
990 | |||
991 | *** Load the package | ||
992 | |||
993 | #+BEGIN_SRC emacs-lisp | ||
994 | (straight-use-package 'visual-fill-column) | ||
995 | |||
996 | (cuss visual-fill-column-center-text nil | ||
997 | "Whether to center the text in the frame.") | ||
998 | |||
999 | (cuss fill-column 84 | ||
1000 | "Width of fill-column, and thus, visual-fill-column.") | ||
1001 | |||
1002 | (advice-add 'text-scale-adjust | ||
1003 | :after #'visual-fill-column-adjust) | ||
1004 | |||
1005 | (global-visual-fill-column-mode +1) | ||
1006 | #+END_SRC | ||
1007 | |||
1008 | ** Typographical niceties | ||
1009 | |||
1010 | *** Typo mode | ||
1011 | |||
1012 | #+BEGIN_SRC emacs-lisp | ||
1013 | (straight-use-package 'typo) | ||
1014 | |||
1015 | (add-hook 'text-mode-hook #'typo-mode) | ||
1016 | #+END_SRC | ||
1059 | 1017 | ||
1060 | * Applications | 1018 | * Applications |
1061 | 1019 | ||
1062 | ** Magit | ||
1063 | |||
1064 | #+begin_src emacs-lisp | ||
1065 | (straight-use-package 'magit) | ||
1066 | |||
1067 | (define-key acdw/map "g" #'magit-status) | ||
1068 | #+end_src | ||
1069 | |||
1070 | ** Org mode | 1020 | ** Org mode |
1071 | 1021 | ||
1072 | I’ve put org mode under Applications, as opposed to Writing, because it’s more generally-applicable than that. | 1022 | I’ve put org mode under Applications, as opposed to Writing, because it’s more generally-applicable than that. |
1073 | 1023 | ||
1074 | #+begin_src emacs-lisp | 1024 | *** Basics |
1075 | (straight-use-package 'org) | 1025 | |
1076 | 1026 | #+BEGIN_SRC emacs-lisp | |
1077 | (with-eval-after-load 'org | 1027 | (straight-use-package 'org) |
1078 | (require 'org-tempo) | 1028 | |
1079 | (require 'ox-md) | 1029 | (with-eval-after-load 'org |
1080 | (define-key org-mode-map (kbd "M-n") #'outline-next-visible-heading) | 1030 | (require 'org-tempo) |
1081 | (define-key org-mode-map (kbd "M-p") #'outline-previous-visible-heading)) | 1031 | (require 'ox-md) |
1082 | 1032 | (define-key org-mode-map (kbd "M-n") #'outline-next-visible-heading) | |
1083 | (cuss org-hide-emphasis-markers t) | 1033 | (define-key org-mode-map (kbd "M-p") #'outline-previous-visible-heading)) |
1084 | (cuss org-fontify-done-headline t) | 1034 | |
1085 | (cuss org-fontify-whole-heading-line t) | 1035 | (cuss org-hide-emphasis-markers t) |
1086 | (cuss org-fontify-quote-and-verse-blocks t) | 1036 | (cuss org-fontify-done-headline t) |
1087 | (cuss org-pretty-entities t) | 1037 | (cuss org-fontify-whole-heading-line t) |
1088 | (cuss org-num-mode +1) | 1038 | (cuss org-fontify-quote-and-verse-blocks t) |
1089 | (cuss org-src-tab-acts-natively t) | 1039 | (cuss org-pretty-entities t) |
1090 | (cuss org-src-fontify-natively t) | 1040 | (cuss org-num-mode +1) |
1091 | (cuss org-src-window-setup 'current-window) | 1041 | (cuss org-src-tab-acts-natively t) |
1092 | (cuss org-confirm-babel-evaluate nil) | 1042 | (cuss org-src-fontify-natively t) |
1093 | (cuss org-directory "~/Org") | 1043 | (cuss org-src-window-setup 'current-window) |
1094 | #+end_src | 1044 | (cuss org-confirm-babel-evaluate nil) |
1045 | (cuss org-directory "~/Org") | ||
1046 | #+END_SRC | ||
1095 | 1047 | ||
1096 | *** Org Agenda | 1048 | *** Org Agenda |
1097 | 1049 | ||
1098 | #+begin_src emacs-lisp | 1050 | #+BEGIN_SRC emacs-lisp |
1099 | (cuss org-agenda-files (no-littering-expand-etc-file-name "agenda-files")) | 1051 | (cuss org-agenda-files (no-littering-expand-etc-file-name "agenda-files")) |
1100 | |||
1101 | (if (and (stringp org-agenda-files) | ||
1102 | (not (file-exists-p org-agenda-files))) | ||
1103 | (with-temp-buffer (write-file org-agenda-files))) | ||
1104 | |||
1105 | (define-key acdw/map (kbd "C-a") #'org-agenda) | ||
1106 | #+end_src | ||
1107 | 1052 | ||
1108 | *** COMMENT Make bullets look like bullets | 1053 | (if (and (stringp org-agenda-files) |
1054 | (not (file-exists-p org-agenda-files))) | ||
1055 | (with-temp-buffer (write-file org-agenda-files))) | ||
1109 | 1056 | ||
1110 | #+begin_src emacs-lisp | 1057 | (define-key acdw/map (kbd "C-a") #'org-agenda) |
1111 | (font-lock-add-keywords | 1058 | #+END_SRC |
1112 | 'org-mode | ||
1113 | '(("^ *\\([-+]\\) " | ||
1114 | (0 (prog1 () | ||
1115 | (compose-region (match-beginning 1) | ||
1116 | (match-end 1) | ||
1117 | "•")))))) | ||
1118 | #+end_src | ||
1119 | 1059 | ||
1120 | *** [[http://kitchingroup.cheme.cmu.edu/blog/2017/04/09/A-better-return-in-org-mode/][A better return in Org mode]] | 1060 | *** [[http://kitchingroup.cheme.cmu.edu/blog/2017/04/09/A-better-return-in-org-mode/][A better return in Org mode]] |
1121 | 1061 | ||
1122 | #+begin_src emacs-lisp | 1062 | #+BEGIN_SRC emacs-lisp |
1123 | (require 'org-inlinetask) | 1063 | (require 'org-inlinetask) |
1124 | 1064 | ||
1125 | (defun scimax/org-return (&optional ignore) | 1065 | (defun scimax/org-return (&optional ignore) |
1126 | "Add new list item, heading or table row with RET. | 1066 | "Add new list item, heading or table row with RET. |
1127 | A double return on an empty element deletes it. | 1067 | A double return on an empty element deletes it. |
1128 | Use a prefix arg to get regular RET." | 1068 | Use a prefix arg to get regular RET." |
1129 | (interactive "P") | 1069 | (interactive "P") |
1130 | (if ignore | 1070 | (if ignore |
1131 | (org-return) | 1071 | (org-return) |
1132 | (cond | 1072 | (cond |
1133 | 1073 | ||
1134 | ((eq 'line-break (car (org-element-context))) | 1074 | ((eq 'line-break (car (org-element-context))) |
1135 | (org-return t)) | 1075 | (org-return t)) |
1136 | 1076 | ||
1137 | ;; Open links like usual, unless point is at the end of a line. | 1077 | ;; Open links like usual, unless point is at the end of a line. |
1138 | ;; and if at beginning of line, just press enter. | 1078 | ;; and if at beginning of line, just press enter. |
1139 | ((or (and (eq 'link (car (org-element-context))) (not (eolp))) | 1079 | ((or (and (eq 'link (car (org-element-context))) (not (eolp))) |
1140 | (bolp)) | 1080 | (bolp)) |
1141 | (org-return)) | 1081 | (org-return)) |
1142 | 1082 | ||
1143 | ;; It doesn't make sense to add headings in inline tasks. Thanks Anders | 1083 | ;; It doesn't make sense to add headings in inline tasks. Thanks Anders |
1144 | ;; Johansson! | 1084 | ;; Johansson! |
1145 | ((org-inlinetask-in-task-p) | 1085 | ((org-inlinetask-in-task-p) |
1146 | (org-return)) | 1086 | (org-return)) |
1147 | 1087 | ||
1148 | ;; checkboxes too | 1088 | ;; checkboxes too |
1149 | ((org-at-item-checkbox-p) | 1089 | ((org-at-item-checkbox-p) |
1150 | (org-insert-todo-heading nil)) | 1090 | (org-insert-todo-heading nil)) |
1151 | 1091 | ||
1152 | ;; lists end with two blank lines, so we need to make sure we are also not | 1092 | ;; lists end with two blank lines, so we need to make sure we are also not |
1153 | ;; at the beginning of a line to avoid a loop where a new entry gets | 1093 | ;; at the beginning of a line to avoid a loop where a new entry gets |
1154 | ;; created with only one blank line. | 1094 | ;; created with only one blank line. |
1155 | ((org-in-item-p) | 1095 | ((org-in-item-p) |
1156 | (if (save-excursion (beginning-of-line) (org-element-property :contents-begin (org-element-context))) | 1096 | (if (save-excursion (beginning-of-line) (org-element-property :contents-begin (org-element-context))) |
1157 | (org-insert-heading) | 1097 | (org-insert-heading) |
1158 | (beginning-of-line) | 1098 | (beginning-of-line) |
1159 | (delete-region (line-beginning-position) (line-end-position)) | 1099 | (delete-region (line-beginning-position) (line-end-position)) |
1160 | (org-return))) | 1100 | (org-return))) |
1161 | 1101 | ||
1162 | ;; org-heading | 1102 | ;; org-heading |
1163 | ((org-at-heading-p) | 1103 | ((org-at-heading-p) |
1164 | (if (not (string= "" (org-element-property :title (org-element-context)))) | 1104 | (if (not (string= "" (org-element-property :title (org-element-context)))) |
1165 | (progn (org-end-of-meta-data) | 1105 | (progn (org-end-of-meta-data) |
1166 | (org-insert-heading-respect-content) | 1106 | (org-insert-heading-respect-content) |
1167 | (outline-show-entry)) | 1107 | (outline-show-entry)) |
1168 | (beginning-of-line) | 1108 | (beginning-of-line) |
1169 | (setf (buffer-substring | 1109 | (setf (buffer-substring |
1170 | (line-beginning-position) (line-end-position)) ""))) | 1110 | (line-beginning-position) (line-end-position)) ""))) |
1171 | 1111 | ||
1172 | ;; tables | 1112 | ;; tables |
1173 | ((org-at-table-p) | 1113 | ((org-at-table-p) |
1174 | (if (-any? | 1114 | (if (-any? |
1175 | (lambda (x) (not (string= "" x))) | 1115 | (lambda (x) (not (string= "" x))) |
1176 | (nth | 1116 | (nth |
1177 | (- (org-table-current-dline) 1) | 1117 | (- (org-table-current-dline) 1) |
1178 | (org-table-to-lisp))) | 1118 | (org-table-to-lisp))) |
1179 | (org-return) | 1119 | (org-return) |
1180 | ;; empty row | 1120 | ;; empty row |
1181 | (beginning-of-line) | 1121 | (beginning-of-line) |
1182 | (setf (buffer-substring | 1122 | (setf (buffer-substring |
1183 | (line-beginning-position) (line-end-position)) "") | 1123 | (line-beginning-position) (line-end-position)) "") |
1184 | (org-return))) | 1124 | (org-return))) |
1185 | 1125 | ||
1186 | ;; fall-through case | 1126 | ;; fall-through case |
1187 | (t | 1127 | (t |
1188 | (org-return))))) | 1128 | (org-return))))) |
1189 | 1129 | ||
1190 | 1130 | ||
1191 | (define-key org-mode-map (kbd "RET") | 1131 | (define-key org-mode-map (kbd "RET") |
1192 | 'scimax/org-return) | 1132 | 'scimax/org-return) |
1193 | #+end_src | 1133 | #+END_SRC |
1194 | 1134 | ||
1195 | *** Insert blank lines | 1135 | *** Insert blank lines around headers |
1196 | 1136 | ||
1197 | from [[https://github.com/alphapapa/unpackaged.el#ensure-blank-lines-between-headings-and-before-contents][unpackaged.el]]. | 1137 | from [[https://github.com/alphapapa/unpackaged.el#ensure-blank-lines-between-headings-and-before-contents][unpackaged.el]]. |
1198 | 1138 | ||
1199 | #+begin_src emacs-lisp | 1139 | #+BEGIN_SRC emacs-lisp |
1200 | ;;;###autoload | 1140 | ;;;###autoload |
1201 | (defun unpackaged/org-fix-blank-lines (&optional prefix) | 1141 | (defun unpackaged/org-fix-blank-lines (&optional prefix) |
1202 | "Ensure that blank lines exist between headings and between headings and their contents. | 1142 | "Ensure that blank lines exist between headings and between headings and their contents. |
1203 | With prefix, operate on whole buffer. Ensures that blank lines | 1143 | With prefix, operate on whole buffer. Ensures that blank lines |
1204 | exist after each headings's drawers." | 1144 | exist after each headings's drawers." |
1205 | (interactive "P") | 1145 | (interactive "P") |
1206 | (org-map-entries (lambda () | 1146 | (org-map-entries (lambda () |
1207 | (org-with-wide-buffer | 1147 | (org-with-wide-buffer |
1208 | ;; `org-map-entries' narrows the buffer, which prevents us | 1148 | ;; `org-map-entries' narrows the buffer, which prevents us |
1209 | ;; from seeing newlines before the current heading, so we | 1149 | ;; from seeing newlines before the current heading, so we |
1210 | ;; do this part widened. | 1150 | ;; do this part widened. |
1211 | (while (not (looking-back "\n\n" nil)) | 1151 | (while (not (looking-back "\n\n" nil)) |
1212 | ;; Insert blank lines before heading. | 1152 | ;; Insert blank lines before heading. |
1213 | (insert "\n"))) | 1153 | (insert "\n"))) |
1214 | (let ((end (org-entry-end-position))) | 1154 | (let ((end (org-entry-end-position))) |
1215 | ;; Insert blank lines before entry content | 1155 | ;; Insert blank lines before entry content |
1216 | (forward-line) | 1156 | (forward-line) |
1217 | (while (and (org-at-planning-p) | 1157 | (while (and (org-at-planning-p) |
1218 | (< (point) (point-max))) | 1158 | (< (point) (point-max))) |
1219 | ;; Skip planning lines | 1159 | ;; Skip planning lines |
1220 | (forward-line)) | 1160 | (forward-line)) |
1221 | (while (re-search-forward org-drawer-regexp end t) | 1161 | (while (re-search-forward org-drawer-regexp end t) |
1222 | ;; Skip drawers. You might think that `org-at-drawer-p' | 1162 | ;; Skip drawers. You might think that `org-at-drawer-p' |
1223 | ;; would suffice, but for some reason it doesn't work | 1163 | ;; would suffice, but for some reason it doesn't work |
1224 | ;; correctly when operating on hidden text. This | 1164 | ;; correctly when operating on hidden text. This |
1225 | ;; works, taken from `org-agenda-get-some-entry-text'. | 1165 | ;; works, taken from `org-agenda-get-some-entry-text'. |
1226 | (re-search-forward "^[ \t]*:END:.*\n?" end t) | 1166 | (re-search-forward "^[ \t]*:END:.*\n?" end t) |
1227 | (goto-char (match-end 0))) | 1167 | (goto-char (match-end 0))) |
1228 | (unless (or (= (point) (point-max)) | 1168 | (unless (or (= (point) (point-max)) |
1229 | (org-at-heading-p) | 1169 | (org-at-heading-p) |
1230 | (looking-at-p "\n")) | 1170 | (looking-at-p "\n")) |
1231 | (insert "\n")))) | 1171 | (insert "\n")))) |
1232 | t (if prefix | 1172 | t (if prefix |
1233 | nil | 1173 | nil |
1234 | 'tree))) | 1174 | 'tree))) |
1235 | #+end_src | 1175 | #+END_SRC |
1236 | 1176 | ||
1237 | **** Add a before-save-hook | 1177 | **** Add a before-save-hook |
1238 | 1178 | ||
1239 | #+begin_src emacs-lisp | 1179 | #+BEGIN_SRC emacs-lisp |
1240 | (defun cribbed/org-mode-fix-blank-lines () | 1180 | (defun cribbed/org-mode-fix-blank-lines () |
1241 | (when (eq major-mode 'org-mode) | 1181 | (when (eq major-mode 'org-mode) |
1242 | (let ((current-prefix-arg 4)) ; Emulate C-u | 1182 | (let ((current-prefix-arg 4)) ; Emulate C-u |
1243 | (call-interactively 'unpackaged/org-fix-blank-lines)))) | 1183 | (call-interactively 'unpackaged/org-fix-blank-lines)))) |
1244 | 1184 | ||
1245 | (add-hook 'before-save-hook #'cribbed/org-mode-fix-blank-lines) | 1185 | (add-hook 'before-save-hook #'cribbed/org-mode-fix-blank-lines) |
1246 | #+end_src | 1186 | #+END_SRC |
1247 | |||
1248 | ** Elpher | ||
1249 | |||
1250 | #+begin_src emacs-lisp | ||
1251 | (straight-use-package '(elpher | ||
1252 | :repo "git://thelambdalab.xyz/elpher.git" | ||
1253 | :branch "patch_multiple_buffers")) | ||
1254 | |||
1255 | (cuss elpher-ipv4-always t) | ||
1256 | |||
1257 | (custom-set-faces | ||
1258 | `(elpher-gemini-heading1 | ||
1259 | ((t (:inherit (modus-theme-heading1))))) | ||
1260 | `(elpher-gemini-heading2 | ||
1261 | ((t (:inherit (modus-theme-heading2))))) | ||
1262 | `(elpher-gemini-heading3 | ||
1263 | ((t (:inherit (modus-theme-heading3)))))) | ||
1264 | |||
1265 | (defun elpher:eww-browse-url (original url &optional new-window) | ||
1266 | "Handle gemini/gopher links with eww." | ||
1267 | (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url) | ||
1268 | (require 'elpher) | ||
1269 | (elpher-go url)) | ||
1270 | (t (funcall original url new-window)))) | ||
1271 | |||
1272 | (advice-add 'eww-browse-url :around 'elpher:eww-browse-url) | ||
1273 | |||
1274 | (unless (fboundp 'elpher-bookmarks) | ||
1275 | (autoload #'elpher-bookmarks "elpher" nil t)) | ||
1276 | |||
1277 | (define-key acdw/map "e" #'elpher-bookmarks) | ||
1278 | |||
1279 | (with-eval-after-load 'elpher | ||
1280 | (dolist (key '(("n" . elpher-next-link) | ||
1281 | ("p" . elpher-prev-link) | ||
1282 | ("o" . elpher-follow-current-link) | ||
1283 | ("G" . elpher-go-current))) | ||
1284 | (define-key elpher-mode-map (car key) (cdr key)))) | ||
1285 | |||
1286 | (add-hook 'elpher-mode-hook #'visual-fill-column-mode) | ||
1287 | #+end_src | ||
1288 | |||
1289 | *** Gemini mode | ||
1290 | |||
1291 | #+begin_src emacs-lisp | ||
1292 | (straight-use-package | ||
1293 | '(gemini-mode | ||
1294 | :repo "https://git.carcosa.net/jmcbray/gemini.el.git")) | ||
1295 | |||
1296 | (add-to-list 'auto-mode-alist | ||
1297 | '("\\.\\(gemini\\|gmi\\)\\'" . gemini-mode)) | ||
1298 | |||
1299 | (defun acdw/setup-gemini-mode () | ||
1300 | (visual-fill-column-mode +1) | ||
1301 | (variable-pitch-mode -1)) | ||
1302 | |||
1303 | (add-hook 'gemini-mode-hook #'acdw/setup-gemini-mode) | ||
1304 | #+end_src | ||
1305 | |||
1306 | *** Gemini write | ||
1307 | |||
1308 | #+begin_src emacs-lisp | ||
1309 | (straight-use-package | ||
1310 | '(gemini-write | ||
1311 | :repo "https://alexschroeder.ch/cgit/gemini-write")) | ||
1312 | #+end_src | ||
1313 | 1187 | ||
1314 | *** Ox-gemini | 1188 | ** Git |
1315 | 1189 | ||
1316 | #+begin_src emacs-lisp | 1190 | #+begin_src emacs-lisp |
1317 | (straight-use-package | 1191 | (straight-use-package 'magit) |
1318 | '(ox-gemini | ||
1319 | :repo "https://git.sr.ht/~abrahms/ox-gemini" | ||
1320 | :branch "main")) | ||
1321 | #+end_src | ||
1322 | |||
1323 | ** Pastebin | ||
1324 | |||
1325 | #+begin_src emacs-lisp | ||
1326 | (straight-use-package '0x0) | ||
1327 | |||
1328 | (cuss 0x0-default-service 'ttm) | ||
1329 | #+end_src | ||
1330 | |||
1331 | ** RSS | ||
1332 | |||
1333 | #+begin_src emacs-lisp | ||
1334 | (cuss newsticker-url-list | ||
1335 | ;; LABEL URL [START-TIME] [INERVAL] [WGET-ARGUMENTS] | ||
1336 | '(("wsinatra" "http://lambdacreate.com/static/feed.rss") | ||
1337 | ("elioat" "https://eli.li/feed.rss") | ||
1338 | ("ACDW" "https://www.acdw.net/atom.xml") | ||
1339 | ("june" "https://text.causal.agency/feed.atom") | ||
1340 | ("kylie - notes" "https://www.somas.is/notes.atom") | ||
1341 | ("kylie - rhizome" "https://www.somas.is/rhizome.atom") | ||
1342 | ("brennan" "https://p1k3.com/all.xml") | ||
1343 | ("Planet Emacs" "https://planet.emacslife.com/atom.xml") | ||
1344 | ("nullprogram, Chris Wellons" "https://nullprogram.com/feed/") | ||
1345 | ("Malleable Systems" "https://malleable.systems/blog/index.xml")) | ||
1346 | ) | ||
1347 | |||
1348 | (add-hook 'newsticker-treeview-item-mode-hook #'visual-fill-column-mode) | ||
1349 | #+end_src | ||
1350 | |||
1351 | ** Web browsing | ||
1352 | |||
1353 | *** Open youtube links in mpv | ||
1354 | |||
1355 | from [[https://karthinks.com/software/more-batteries-included-with-emacs/#regexp-builder--m-x-re-builder][karthinks]]. | ||
1356 | |||
1357 | #+begin_src emacs-lisp | ||
1358 | (require 'browse-url) | ||
1359 | |||
1360 | (when (executable-find "mpv") | ||
1361 | (defun browse-url-mpv (url &optional single) | ||
1362 | (start-process "mpv" nil (if single "mpv" "umpv") | ||
1363 | (shell-quote-wildcard-pattern url))) | ||
1364 | |||
1365 | (defun browse-url-at-point-mpv (&optional single) | ||
1366 | "Open a link in mpv." | ||
1367 | (interactive "P") | ||
1368 | (let ((browse-url-browser-function | ||
1369 | (if single | ||
1370 | (lambda | ||
1371 | (url &optional _new-window) | ||
1372 | (browse-url-mpv url t)) | ||
1373 | #'browse-url-mpv))) | ||
1374 | (browse-url-at-point))) | ||
1375 | |||
1376 | (cuss browse-url-browser-function | ||
1377 | '(("https?:\\/\\/www\\.youtu\\.*be." . browse-url-mpv) | ||
1378 | ("." . browse-url-generic)))) | ||
1379 | #+end_src | ||
1380 | |||
1381 | ** Reading e-books | ||
1382 | |||
1383 | #+begin_src emacs-lisp | ||
1384 | (straight-use-package 'nov) | ||
1385 | |||
1386 | (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode)) | ||
1387 | |||
1388 | (defun acdw/setup-nov-mode () | ||
1389 | (visual-line-mode +1) | ||
1390 | (visual-fill-column-mode +1) | ||
1391 | (variable-pitch-mode +1) | ||
1392 | (setq cursor-type nil)) | ||
1393 | |||
1394 | (cuss nov-text-width t) | ||
1395 | |||
1396 | (add-hook 'nov-mode-hook #'acdw/setup-nov-mode) | ||
1397 | #+end_src | ||
1398 | |||
1399 | ** Eshell | ||
1400 | |||
1401 | #+begin_src emacs-lisp | ||
1402 | (when (executable-find "bash") | ||
1403 | (straight-use-package 'bash-completion)) | ||
1404 | |||
1405 | (when (executable-find "fish") | ||
1406 | (straight-use-package 'fish-completion) | ||
1407 | (require 'fish-completion) | ||
1408 | (cuss fish-completion-fallback-on-bash-p (executable-find "bash")) | ||
1409 | (global-fish-completion-mode +1) | ||
1410 | 1192 | ||
1411 | (straight-use-package 'fish-mode) | 1193 | (define-key acdw/map "g" #'magit-status) |
1412 | (add-to-list 'auto-mode-alist '("\\.fish\\'" . fish-mode))) | ||
1413 | #+end_src | 1194 | #+end_src |
1414 | 1195 | ||
1415 | * Appendices | 1196 | * Appendices |