From df207947bae8f29dce49815587436cde9f49ebed Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Thu, 23 Sep 2021 17:11:30 -0500 Subject: blehhaheoi --- init.el | 540 ++++++++++++++++++++++++----------------------------------- lisp/acdw.el | 132 ++++++++++++++- 2 files changed, 348 insertions(+), 324 deletions(-) diff --git a/init.el b/init.el index 48f3d39..d8e9bf0 100644 --- a/init.el +++ b/init.el @@ -21,7 +21,10 @@ ;; NOTE that some of the names in `setup' forms are arbitrary. (setup (:require auth-source) - (:option auth-sources '("~/.authinfo" "~/.authinfo.gpg"))) + (:option auth-sources (list (acdw/sync-dir "authinfo") + (acdw/sync-dir "authinfo.gpg") + "~/.authinfo" + "~/.authinfo.gpg"))) (setup (:require goto-addr) (if (fboundp #'global-goto-address-mode) @@ -181,7 +184,25 @@ In short, DO NOT USE THIS FUNCTION!!!" (acdw/add-button-url-regexp-protocol "gemini")) (setup buffers - (:global "C-x k" #'acdw/kill-a-buffer)) + (:global "C-x k" #'acdw/kill-a-buffer) + (defun buffer-list-update@set-major-mode () + "Set `major-mode' from buffer name, even when not visiting a file." + (let ((name (buffer-name))) + (unless (or (active-minibuffer-window) + (string-prefix-p "*" name) + (not (eq major-mode 'fundamental-mode))) + (catch 'done + (dolist (cell auto-mode-alist) + (let ((regexp (car cell)) + (mode (cdr cell))) + (when (string-match regexp name) + (let ((major-mode mode)) + (funcall mode)) + (throw 'done mode)))))))) + + ;; TODO: more testing, just in case. + ;;(add-hook 'buffer-list-update-hook #'buffer-list-update@set-major-mode) + ) (setup calendar (:option calendar-week-start-day 1)) @@ -189,35 +210,24 @@ In short, DO NOT USE THIS FUNCTION!!!" (setup (:straight circe) (require 'circe) (require 'acdw-irc) - - (:option acdw-irc/left-margin 12 + + (:option acdw-irc/left-margin 20 acdw-irc/post-my-nick "-> " circe-channel-killed-confirmation nil circe-color-nicks-everywhere t circe-default-nick "acdw" circe-default-part-message "See You, Space Cowpokes . . ." circe-default-user "acdw" - circe-format-action - (lambda (&rest plist) - (concat - (acdw-irc/margin-format "" "*" "*" t) - " " (plist-get plist :nick) " " (plist-get plist :body))) - circe-format-say - (lambda (&rest plist) - (concat - (acdw-irc/margin-format (plist-get plist :nick) "" " |" t) - " " (plist-get plist :body))) - circe-format-self-action - (lambda (&rest plist) - (concat - (acdw-irc/margin-format "" "-*" " *" t) - " " (plist-get plist :nick) " " (plist-get plist :body))) - circe-format-self-say - (lambda (&rest plist) - (concat - (acdw-irc/margin-format (plist-get plist :nick) "-" " >" t) - " " (plist-get plist :body))) - ;; circe-highlight-nick-type 'message + circe-format-action (format + (format "%%%ds* {nick} {body}" + (- acdw-irc/left-margin 2)) " ") + circe-format-say (format + "{nick:%1$d.%1$ds} | {body}" + (- acdw-irc/left-margin 3)) + circe-format-self-action circe-format-action + circe-format-self-say (format + "{nick:%1$d.%1$ds} > {body}" + (- acdw-irc/left-margin 3)) circe-network-options `(("Libera Chat" :channels ("#emacs" "#systemcrafters" "##webpals") @@ -226,7 +236,7 @@ In short, DO NOT USE THIS FUNCTION!!!" :host "libera.chat")) ("Tilde Chat" :host "irc.tilde.chat" :port 6697 :use-tls t :channels ("#meta" "#bread" "#dadjokes" "#team" - "#emacs") + "#emacs" "#nsfw") :sasl-username ,circe-default-nick :sasl-password ,(acdw/make-password-fetcher :host "tilde.chat")) @@ -247,9 +257,12 @@ In short, DO NOT USE THIS FUNCTION!!!" circe-server-buffer-action (lambda (buf) (message "Connected to %s" buf))) - ;; (:face circe-nick-highlight-face - ;; ((t (:inherit (modus-themes-hl-line))))) - + (with-eval-after-load 'circe + (:face circe-nick-highlight-face + ((t (:inherit (modus-themes-hl-line modus-themes-bold)))) + circe-my-message-face + ((t (:inherit (modus-themes-slant)))))) + (:bind "C-c C-p" #'circe-command-PART "C-l" #'lui-track-jump-to-indicator) @@ -280,7 +293,8 @@ In short, DO NOT USE THIS FUNCTION!!!" (with-current-buffer buf (dolist (buf (circe-server-chat-buffers)) (let ((circe-channel-killed-confirmation nil)) - (kill-buffer buf))) + (kill-buffer buf)) + (cancel-timer 'irc-send--queue)) (message "%s: %s" buf circe-server-killed-confirmation) (kill-buffer)))))) @@ -312,12 +326,13 @@ In short, DO NOT USE THIS FUNCTION!!!" #'circe-nick-color-reset) (:with-mode lui-mode - (:option lui-fill-column fill-column + (:option lui-fill-column (+ fill-column acdw-irc/left-margin) lui-fill-type (repeat-string acdw-irc/left-margin " ") lui-time-stamp-position 'right-margin lui-time-stamp-format "%H:%M" lui-track-behavior 'before-switch-to-buffer - lui-track-indicator 'fringe) + lui-track-indicator 'fringe + lui-fill-remove-face-from-newline nil) (:local-set fringes-outside-margins t right-margin-width 5 @@ -374,8 +389,9 @@ In short, DO NOT USE THIS FUNCTION!!!" dired-collapse dired-git-info) - (:option dired-recursive-copies 'always - dired-recursive-deletes 'always + (:option dired-recursive-copies 'top + dired-recursive-deletes 'top + dired-create-destination-dirs 'ask delete-by-moving-to-trash t dired-listing-switches "-Al" ls-lisp-dirs-first t @@ -433,24 +449,7 @@ In short, DO NOT USE THIS FUNCTION!!!" ;; And set the disabled function to something better than the default. ;; Now, I can run any disabled command, but I have to use M-x to do it. - (setq disabled-command-function - (defun acdw/disabled-command-function (&optional cmd keys) - (let ((cmd (or cmd this-command)) - (keys (or keys (this-command-keys)))) - ;; this logic stolen from original `disabled-command-function' - (if (or (eq (aref keys 0) (if (stringp keys) - (aref "\M-x" 0) - ?\M-x)) - (and (>= (length keys) 2) - (eq (aref keys 0) meta-prefix-char) - (eq (aref keys 1) ?x))) - ;; it's been run as an M-x command, we want to do it - (call-interactively cmd) - ;; else, tell the user it's disabled. - (message (substitute-command-keys - (concat "Command `%s' has been disabled. " - "Run with \\[execute-extended-command].")) - cmd)))))) + (:option disabled-command-function #'acdw/disabled-command-function)) (setup ediff (:option ediff-diff-options "-w" ; ignore whitespace @@ -459,8 +458,6 @@ In short, DO NOT USE THIS FUNCTION!!!" ;; https://oremacs.com/2015/01/17/setting-up-ediff/ (add-hook 'ediff-after-quit-hook-internal #'winner-undo)) -(setup (:straight edit-indirect)) - ;; requires extension: ;; https://addons.mozilla.org/en-US/firefox/addon/edit-with-emacs1/ (setup (:straight edit-server) @@ -487,6 +484,8 @@ In short, DO NOT USE THIS FUNCTION!!!" (:with-mode emacs-lisp-mode ;; -_- (:option eval-expression-print-length nil eval-expression-print-level nil + print-length nil + print-level nil lisp-indent-function #'lisp-indent-function) (:local-set (append imenu-generic-expression) @@ -494,7 +493,7 @@ In short, DO NOT USE THIS FUNCTION!!!" ,(rx (seq (group bol (* space) "(setup" (+ space)) (? (group "(:" (+ graph) (* space) (? "("))) - (group (+ (any word ?-))))) + (group (+ (any word ?+ ?-))))) 3)) (:hook #'checkdoc-minor-mode @@ -522,6 +521,7 @@ In short, DO NOT USE THIS FUNCTION!!!" ;; else /should/ go there. (:option attempt-orderly-shutdown-on-fatal-signal nil + auto-hscroll-mode 'current-line attempt-stack-overflow-recovery nil echo-keystrokes 0.01 find-function-C-source-directory (acdw/find-emacs-source) @@ -544,10 +544,6 @@ In short, DO NOT USE THIS FUNCTION!!!" "A keymap for looking up things.") (global-set-key (kbd "C-c l") lookup-map) - (defvar toggle-map (make-sparse-keymap) - "A keymap for toggling!") - (global-set-key (kbd "C-c t") toggle-map) - (:global "M-=" #'count-words "C-w" #'kill-region-or-backward-word "C-c d" #'acdw/insert-iso-date @@ -557,11 +553,26 @@ In short, DO NOT USE THIS FUNCTION!!!" "C-c _" #'add-file-local-variable "C-x C-c" #'acdw/fat-finger-exit) + ;; inspo: https://github.com/zaeph/.emacs.d/blob/master/init.el#L479 + (defvar toggle-map (make-sparse-keymap) + "A keymap for toggling!") + (global-set-key (kbd "C-c t") toggle-map) + (:with-map toggle-map (:bind "c" #'column-number-mode "l" #'display-line-numbers-mode - "d" #'toggle-debug-on-error)) + "d" #'toggle-debug-on-error + "s" #'so-long-mode + "S" #'scroll-bar-mode)) + + ;; Toggle + (:with-map toggle-map + (:bind "b" (defun acdw/toggle-lexical-binding () + "Toggle `lexical-binding' in the current buffer." + (interactive) + (setq lexical-binding (not lexical-binding))))) + (:with-map case-map (require 'titlecase) (:bind "c" #'capitalize-dwim @@ -796,7 +807,7 @@ specific to most general, they are these: word-wrap t truncate-lines nil) - (global-display-fill-column-indicator-mode +1) + (global-display-fill-column-indicator-mode -1) (global-so-long-mode +1) (add-hook 'visual-line-mode-hook @@ -837,6 +848,17 @@ specific to most general, they are these: (fset 'yes-or-no-p #'y-or-n-p) (setq use-short-answers t))) +(setup mouse + ;; Unconditionally follow links when clicked. + ;; This is because mouse-1 usually sets point. + ;; Other options: + ;; +[ms] -> perform mouse-2 until held for [ms], then mouse-1 + ;; -[ms] -> perform mouse-1 until held for [ms], then mouse-2 + ;; 'double -> mouse-2 on double click + ;; nil -> mouse-1 never follows link + ;; -> mouse-1 /always/ follows link + (:option mouse-1-click-follows-link t)) + (setup mouse-avoidance (mouse-avoidance-mode 'exile)) @@ -869,24 +891,6 @@ specific to most general, they are these: ;; (put 'backward-page 'repeat-map 'page-navigation-repeat-map) ) -(setup prog - (:option show-paren-delay 0 - show-paren-style 'mixed - show-paren-when-point-inside-paren t - show-paren-when-point-in-periphery t - smie-indent-basic tab-width) - - (:hook show-paren-mode - electric-pair-local-mode - acdw/setup-fringes - - (defun prog-mode@auto-fill () - (setq-local comment-auto-fill-only-comments t) - (turn-on-auto-fill))) - - (add-hook 'after-save-hook - #'executable-make-buffer-file-executable-if-script-p)) - (setup repeat ;; new for Emacs 28! (:only-if (fboundp #'repeat-mode)) @@ -1153,146 +1157,6 @@ specific to most general, they are these: (:with-feature isearch (:bind "C-'" #'avy-isearch))) -(setup (:straight circe) - (require 'circe) - (require 'acdw-irc) - - (:option acdw-irc/left-margin 12 - acdw-irc/post-my-nick "-> " - circe-channel-killed-confirmation nil - circe-color-nicks-everywhere t - circe-default-nick "acdw" - circe-default-part-message "See You, Space Cowpokes . . ." - circe-default-user "acdw" - circe-format-action - (lambda (&rest plist) - (concat - (acdw-irc/margin-format "" "*" "*" t) - " " (plist-get plist :nick) " " (plist-get plist :body))) - circe-format-say - (lambda (&rest plist) - (concat - (acdw-irc/margin-format (plist-get plist :nick) "" " |" t) - " " (plist-get plist :body))) - circe-format-self-action - (lambda (&rest plist) - (concat - (acdw-irc/margin-format "" "-*" " *" t) - " " (plist-get plist :nick) " " (plist-get plist :body))) - circe-format-self-say - (lambda (&rest plist) - (concat - (acdw-irc/margin-format (plist-get plist :nick) "-" " >" t) - " " (plist-get plist :body))) - ;; circe-highlight-nick-type 'message - circe-network-options - `(("Libera Chat" - :channels ("#emacs" "#systemcrafters" "##webpals") - :sasl-username ,circe-default-nick - :sasl-password ,(acdw/make-password-fetcher - :host "libera.chat")) - ("Tilde Chat" :host "irc.tilde.chat" :port 6697 :use-tls t - :channels ("#meta" "#bread" "#dadjokes" "#team" - "#emacs") - :sasl-username ,circe-default-nick - :sasl-password ,(acdw/make-password-fetcher - :host "tilde.chat")) - ("Casa" :host "m455.casa" :port 6697 :use-tls t - :channels ("#basement") - :sasl-username ,circe-default-nick - :sasl-password ,(acdw/make-password-fetcher - :host "m455.casa")) - ("Pissnet" :host "piss.hmm.st" :port 6697 :use-tls t - :channels ("#i-just-peed") - :sasl-username ,circe-default-nick - :sasl-password ,(acdw/make-password-fetcher - :host "piss.hmm.st")) - ;; TODO: irc.chat.twitch.tv - ) - circe-reduce-lurker-spam t - circe-server-auto-join-default-type :after-auth) - - ;; (:face circe-nick-highlight-face - ;; ((t (:inherit (modus-themes-hl-line))))) - - (:bind "C-c C-p" #'circe-command-PART - "C-l" #'lui-track-jump-to-indicator) - - (:advise circe-command-PART :after - (defun circe-part@kill-buffer (&rest _) - (let ((circe-channel-killed-confirmation nil)) - (kill-buffer))) - - circe-command-QUIT :after - (defun circe-quit@kill-buffer (&rest _) - ;; `circe-server-killed-confirmation' set to nil, and manually - ;; deleting all chat buffers, pending Github issue #402 - ;; (https://github.com/emacs-circe/circe/issues/402) - (let ((circe-server-killed-confirmation nil)) - (with-circe-server-buffer - (dolist (buf (circe-server-chat-buffers)) - (let ((circe-channel-killed-confirmation nil)) - (kill-buffer buf))) - (kill-buffer)))) - - circe-command-GQUIT :after - (defun circe-gquit@kill-buffer (&rest _) - ;; `circe-server-killed-confirmation' set to nil, and manually - ;; deleting all chat buffers, pending Github issue #402 - ;; (https://github.com/emacs-circe/circe/issues/402) - (let ((circe-server-killed-confirmation nil)) - (dolist (buf (circe-server-buffers)) - (with-current-buffer buf - (dolist (buf (circe-server-chat-buffers)) - (let ((circe-channel-killed-confirmation nil)) - (kill-buffer buf))) - (message "%s: %s" buf circe-server-killed-confirmation) - (kill-buffer)))))) - - (defun circe-command-SHORTEN (url) - "Shorten URL using `0x0-shorten-uri'." - (interactive "sURL to shorten: ") - ;; TODO: enable /shorten URL comment syntax - (let ((short-url (0x0-shorten-uri (0x0--choose-server) url))) - (circe-command-SAY short-url))) - - (:with-mode circe-chat-mode - (:hook #'acdw/stop-paren-annoyances - #'enable-circe-color-nicks - #'enable-circe-display-images - #'enable-circe-new-day-notifier - (defun circe-chat@set-prompt () - (lui-set-prompt - (concat - (propertize - (acdw-irc/margin-format (buffer-name) "" ">") - 'face 'circe-prompt-face - 'read-only t - 'intangible t - 'cursor-intangible t) - " "))))) - - (autoload 'circe-nick-color-reset "circe-color-nicks") - (add-hook 'modus-themes-after-load-theme-hook - #'circe-nick-color-reset) - - (:with-mode lui-mode - (:option lui-fill-column fill-column - lui-fill-type (repeat-string acdw-irc/left-margin " ") - lui-time-stamp-position 'right-margin - lui-time-stamp-format "%H:%M" - lui-track-behavior 'before-switch-to-buffer - lui-track-indicator 'fringe) - - (:local-set fringes-outside-margins t - right-margin-width 5 - scroll-margin 0 - word-wrap t - wrap-prefix (repeat-string acdw-irc/left-margin " ") - line-number-mode nil) - - (:hook #'enable-lui-track))) - (setup (:straight (consult :host github :repo "minad/consult")) @@ -1437,24 +1301,6 @@ specific to most general, they are these: (setup (:straight edit-indirect)) -;; requires extension: -;; https://addons.mozilla.org/en-US/firefox/addon/edit-with-emacs1/ -(setup (:straight edit-server) - (:require edit-server) - (edit-server-start) - - (:option edit-server-default-major-mode 'text-mode - edit-server-url-major-mode-alist - (list (cons (rx (| "reddit.com" - "tildes.net")) - 'markdown-mode) - (cons (rx "github.com") - 'gfm-mode))) - - (:advise edit-server-make-frame :before - (defun edit-server@set-a-variable (&rest _) - (setq-local edit-server-frame-p t)))) - (setup (:straight (electric-cursor :host github :repo "duckwork/electric-cursor")) @@ -1688,28 +1534,14 @@ specific to most general, they are these: (defvar helpful-pre-windows nil "Window configuration /before/ helpful was called.") - (:option helpful-switch-buffer-function - (defun helpful-pop-to-buffer (&rest args) - (if (eq major-mode 'helpful-mode) - (apply #'pop-to-buffer-same-window args) - (require 'winner) - (setq helpful-pre-windows (winner-conf)) - (apply #'pop-to-buffer args)))) + (:option helpful-switch-buffer-function #'pop-to-buffer) (:global " f" #'helpful-callable " v" #'helpful-variable " k" #'helpful-key " o" #'helpful-symbol) - (:bind "q" (defun helpful-quit () - (interactive) - (when (eq major-mode 'helpful-mode) - (quit-window) - (unless (or (= 1 (count-windows)) - (eq major-mode 'helpful-mode)) - (delete-window) - (ignore-errors - (winner-set helpful-pre-windows))))))) + (:bind "q" #'quit-window)) (setup (:straight hungry-delete) (:option hungry-delete-chars-to-skip " \t" @@ -1849,11 +1681,12 @@ browser defined in `browse-url-secondary-browser-function'." (setup (:straight (mastodon :host github - :repo "mooseyboots/mastodon.el") - request) + :repo "mooseyboots/mastodon.el")) (:option mastodon-instance-url "https://writing.exchange" mastodon-auth-source-file (car auth-sources) - mastodon-client--token-file (acdw/dir "mastodon.plstore")) + mastodon-client--token-file (acdw/dir "mastodon.plstore") + mastodon-tl--enable-proportional-fonts t + mastodon-tl--enable-relative-timestamps nil) (:hook #'hl-line-mode #'reading-mode)) @@ -1870,7 +1703,14 @@ browser defined in `browse-url-secondary-browser-function'." modus-themes-mode-line nil) (acdw/sunrise-sunset #'modus-themes-load-operandi - #'modus-themes-load-vivendi)) + #'modus-themes-load-vivendi) + + (add-hook 'modus-themes-after-load-theme-hook + (defun modus-themes@customize-faces () + "Customize faces of modus-themes." + (custom-set-faces + '(org-tag + ((t (:height 90 :slant italic :inherit org-tag)))))))) (setup (:straight mwim) (:global "C-a" #'mwim-beginning @@ -1949,13 +1789,16 @@ browser defined in `browse-url-secondary-browser-function'." (setup (:straight org org-contrib) - (:also-load acdw-org) ; so I don't clutter up init.el + (:also-load acdw-org ; so I don't clutter up init.el + chd) (:option org-adapt-indentation nil org-agenda-files nil ; only until I set this up org-catch-invisible-edits 'show-and-error - org-clock-clocked-in-display 'mode-line - org-clock-string-limit 7 ; gives time and not title + org-clock-clocked-in-display 'frame-title + org-clock-frame-title-format (cons '(t org-mode-line-string) + (cons " --- " frame-title-format)) + ;;org-clock-string-limit 7 ; gives time and not title org-confirm-babel-evaluate nil org-cycle-separator-lines 0 org-directory "~/org" @@ -1976,6 +1819,7 @@ browser defined in `browse-url-secondary-browser-function'." org-list-demote-modify-bullet '(("-" . "+") ("+" . "*") ("*" . "-")) + org-log-into-drawer t org-outline-path-complete-in-steps nil org-pretty-entities t org-refile-use-outline-path 'file @@ -1993,7 +1837,7 @@ browser defined in `browse-url-secondary-browser-function'." "" #'acdw-org/org-table-copy-down "M-SPC M-SPC" #'insert-zero-width-space "C-c C-l" #'org-insert-link-dwim - "M-w" #'acdw/copy-region-plain + "C-c w" #'chd/do-the-thing "C-c C-n" #'acdw/org-next-heading-widen "C-c C-p" #'acdw/org-previous-heading-widen) @@ -2026,9 +1870,50 @@ browser defined in `browse-url-secondary-browser-function'." end 999))))) - (:advise org-delete-backward-char :override #'acdw-org/delete-backward-char)) + (:advise org-delete-backward-char :override #'acdw-org/delete-backward-char) + + (el-patch-feature org) + (with-eval-after-load 'org + (el-patch-defun org-format-outline-path (path &optional width prefix separator) + "Format the outline path PATH for display. +WIDTH is the maximum number of characters that is available. +PREFIX is a prefix to be included in the returned string, +such as the file name. +SEPARATOR is inserted between the different parts of the path, +the default is \"/\"." + (setq width (or width 79)) + (setq path (delq nil path)) + (unless (> width 0) + (user-error "Argument `width' must be positive")) + (setq separator (or separator "/")) + (let* ((org-odd-levels-only nil) + (fpath (concat + prefix (and prefix path separator) + (mapconcat + (lambda (s) (replace-regexp-in-string "[ \t]+\\'" "" s)) + (cl-loop for head in path + for n from 0 + collect (el-patch-swap + (org-add-props + head nil '`face + (nth (% n org-n-level-faces) org-level-faces)) + head)) + separator)))) + (when (> (length fpath) width) + (if (< width 7) + ;; It's unlikely that `width' will be this small, but don't + ;; waste characters by adding ".." if it is. + (setq fpath (substring fpath 0 width)) + (setf (substring fpath (- width 2)) ".."))) + fpath)))) (setup (:straight org-appear) + (:option org-appear-autoemphasis t + org-appear-autoentities t + org-appear-autokeywords t + org-appear-autolinks nil + org-appear-autosubmarkers t + org-appear-delay 0) (:hook-into org-mode)) (setup (:straight package-lint)) @@ -2047,7 +1932,8 @@ browser defined in `browse-url-secondary-browser-function'." (:with-map lisp-mode-shared-map (:bind "DEL" #'paredit-backward-delete "C-M-;" #'comment-or-uncomment-sexp - "C-" #'paredit-backward-kill-word)) + "C-" #'paredit-backward-kill-word + "M-w" #'paredit-copy-as-kill)) (paredit-mode +1)) (dolist (mode lispy-modes) @@ -2078,20 +1964,8 @@ browser defined in `browse-url-secondary-browser-function'." (with-current-buffer buf (when (funcall persistent-scratch-scratch-buffer-p-function) (persistent-scratch-mode +1)))) - (buffer-list))) -(setup (:straight-if pkgbuild-mode - (executable-find "makepkg")) - (:file-match "PKGBUILD")) - -(setup (:straight powerthesaurus) - (:global "C-c l t" #'powerthesaurus-lookup-word-dwim)) - -;; (setup (:straight prism) -;; (dolist (mode lispy-modes) -;; (add-hook (intern (format "%s-hook" mode)) #'prism-mode))) - (setup prog (:option show-paren-delay 0 show-paren-style 'mixed @@ -2107,12 +1981,8 @@ browser defined in `browse-url-secondary-browser-function'." (setq-local comment-auto-fill-only-comments t) (turn-on-auto-fill))) - (mapc (lambda (buf) - (with-current-buffer buf - (when (funcall persistent-scratch-scratch-buffer-p-function) - (persistent-scratch-mode +1)))) - - (buffer-list))) + (add-hook 'after-save-hook + #'executable-make-buffer-file-executable-if-script-p)) (setup (:straight-if pkgbuild-mode (executable-find "makepkg")) @@ -2121,19 +1991,15 @@ browser defined in `browse-url-secondary-browser-function'." (setup (:straight powerthesaurus) (:global "C-c l t" #'powerthesaurus-lookup-word-dwim)) -(setup (:straight prism) - (dolist (mode lispy-modes) - (add-hook (intern (format "%s-hook" mode)) #'prism-mode))) - -(setup (:straight restart-emacs) - (defun emacs-upgrade (&optional update-packages) - "Pull config, upgrade packages, restart Emacs." - (interactive "P") - (emacs-git-pull-config) - (when update-packages - (require 'straight-x) - (straight-x-pull-all)) - (restart-emacs))) +1(setup (:straight restart-emacs) + (defun emacs-upgrade (&optional update-packages) + "Pull config, upgrade packages, restart Emacs." + (interactive "P") + (emacs-git-pull-config) + (when update-packages + (require 'straight-x) + (straight-x-pull-all)) + (restart-emacs))) (setup (:straight (shell-command+ :host nil @@ -2169,21 +2035,22 @@ browser defined in `browse-url-secondary-browser-function'." tab-bar-show 1) ;; I've put in a pull request to add the (- 0 right-margin) bit here. - (:advise simple-modeline--format :override - (defun simple-modeline@format (lefts rights) - (let* ((left (simple-modeline--format-segments lefts)) - (right (simple-modeline--format-segments rights)) - (reserve (length right))) - (concat - left - (propertize " " - 'display `((space :align-to - (- right - (- 0 right-margin) - ,reserve))) - 'face '(:inherit simple-modeline-space)) - right)))) - + (el-patch-feature simple-modeline) + (with-eval-after-load 'simple-modeline + (el-patch-defun simple-modeline--format (left-segments right-segments) + "Return a string of `window-width' length containing LEFT-SEGMENTS and RIGHT-SEGMENTS, aligned respectively." + (let* ((left (simple-modeline--format-segments left-segments)) + (right (simple-modeline--format-segments right-segments)) + (reserve (length right))) + (concat + left + (propertize " " + 'display (el-patch-swap + `(space :align-to (- right ,reserve)) + `(space :align-to (- right (- 0 right-margin) ,reserve))) + 'face '(:inherit simple-modeline-space)) + right)))) + (simple-modeline-mode +1)) (setup (:straight-if sly @@ -2304,14 +2171,14 @@ If used with a numeric prefix argument N, N backticks will be inserted." vertico-count-format nil vertico-cycle t) - (:with-map vertico-map - (:bind "" - (defun up-directory (arg) - "Move up a directory (delete backwards to /)." - (interactive "p") - (if (string-match-p "/." (minibuffer-contents)) - (zap-up-to-char (- arg) ?/) - (backward-kill-word arg))))) + ;; (:with-map vertico-map + ;; (:bind "" + ;; (defun up-directory (arg) + ;; "Move up a directory (delete backwards to /)." + ;; (interactive "p") + ;; (if (string-match-p "/." (minibuffer-contents)) + ;; (zap-up-to-char (- arg) ?/) + ;; (backward-kill-word arg))))) (when (boundp 'native-comp-deferred-compilation-deny-list) (add-to-list 'native-comp-deferred-compilation-deny-list "vertico")) @@ -2319,9 +2186,15 @@ If used with a numeric prefix argument N, N backticks will be inserted." (vertico-mode +1) ;; Extensions! - (:also-load vertico-mouse) + (:also-load vertico-mouse + vertico-directory) (vertico-mouse-mode +1) - + (:with-map vertico-map + (:bind "RET" #'vertico-directory-enter + "DEL" #'vertico-directory-delete-char + "M-DEL" #'vertico-directory-delete-word)) + (add-hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy) + ;; Prefix the current candidate with "> ". From Vertico wiki. (:advise vertico--format-candidate :around (defun vertico-format@add-arrow (orig cand pref suf index start) @@ -2345,7 +2218,12 @@ If used with a numeric prefix argument N, N backticks will be inserted." (setup (:straight wc-mode) (:option wc-modeline-format "[%tww]" wc-idle-wait 2) - (:hook-into text-mode)) + (:hook-into text-mode) + (:unbind "C-c C-w a" + "C-c C-w c" + "C-c C-w l" + "C-c C-w w" + "C-c C-w")) (setup (:straight web-mode) (:option css-level-offset 2 @@ -2413,5 +2291,27 @@ If used with a numeric prefix argument N, N backticks will be inserted." (call-interactively #'zzz-to-char) (call-interactively #'zzz-up-to-char))))) +(setup (:straight dictionary) + (:option dictionary-use-single-buffer t) + + (autoload 'dictionary-search "dictionary" + "Ask for a word and search it in all dictionaries" t) + (autoload 'dictionary-match-words "dictionary" + "Ask for a word and search all matching words in the dictionaries" t) + (autoload 'dictionary-lookup-definition "dictionary" + "Unconditionally lookup the word at point." t) + (autoload 'dictionary "dictionary" + "Create a new dictionary buffer" t) + (autoload 'dictionary-mouse-popup-matching-words "dictionary" + "Display entries matching the word at the cursor" t) + (autoload 'dictionary-popup-matching-words "dictionary" + "Display entries matching the word at the point" t) + (autoload 'dictionary-tooltip-mode "dictionary" + "Display tooltips for the current word" t) + (autoload 'global-dictionary-tooltip-mode "dictionary" + "Enable/disable dictionary-tooltip-mode for all buffers" t) + + (:with-map lookup-map + (:bind "d" #'dictionary-search))) ;;; init.el ends here diff --git a/lisp/acdw.el b/lisp/acdw.el index dcf7b19..b146f58 100644 --- a/lisp/acdw.el +++ b/lisp/acdw.el @@ -323,6 +323,43 @@ with `string<' starting with the key determined by KEY-FN." (insert-before-markers real) (delete-region (point) (marker-position end))))))))) +(defun acdw/sort-setups () + "Sort `setup' forms in the current buffer. +Actually sorts all forms, but based on the logic of `setup'. +In short, DO NOT USE THIS FUNCTION!!!" + (save-excursion + (sort-sexps + (point-min) (point-max) + (lambda (sexp) + (format "%S" (cadr sexp))) + (lambda (s1 s2) ; oh god, this is worse. + (let* ((s1 (cdr s1)) (s2 (cdr s2)) ; for the strings themselves + (s1-require (string-match ":require" s1)) + (s2-require (string-match ":require" s2)) + (s1-straight (string-match ":straight" s1)) + (s2-straight (string-match ":straight" s2)) + (s1-bare (not (or s1-require s1-straight))) + (s2-bare (not (or s2-require s2-straight)))) + (cond + ;; if both are the same, sort regular style + ((or (and s1-require s2-require) + (and s1-bare s2-bare)) + (string< s1 s2)) + ((and s1-straight s2-straight) + (let* ((r (rx ":straight" (? "-if") (* space) (? "("))) + (s1 (replace-regexp-in-string r "" s1)) + (s2 (replace-regexp-in-string r "" s2))) + (message "'%S' '%S'" s1 s2) + (string< s1 s2))) + ;; requires should go first + ((and s1-require (not s2-require)) t) + ((and (not s1-require) s2-require) nil) + ;; straights should go last + ((and s1-straight (not s2-straight)) nil) + ((and (not s1-straight) s2-straight) t) + ;; else, just sort em. + (t (string< s1 s2)))))))) + ;;; Emacs configuration functions @@ -402,6 +439,59 @@ first." (setq deactivate-mark t) nil) +;; https://emacs.stackexchange.com/questions/36366/ +(defun html-body-id-filter (output backend info) + "Remove random ID attributes generated by Org." + (when (eq backend 'html) + (replace-regexp-in-string + " id=\"[[:alpha:]-]*org[[:alnum:]]\\{7\\}\"" + "" + output t))) + +(defun html-body-div-filter (output backend info) + "Remove wrapping divs generated by Org." + (when (eq backend 'html) + (replace-regexp-in-string + "]*>\n*" "" + output t))) + +(defun org-demote-headings (backend) + (while (/= (point) (point-max)) + (org-next-visible-heading 1) + (org-demote-subtree))) + +(defun acdw/org-export-copy-html () + "Copy a tree as HTML." + (interactive) + (require 'ox-html) + (org-export-with-buffer-copy + ;; (add-hook 'org-export-before-parsing-hook #'org-demote-headings nil t) + (let ((extracted-heading (acdw/org-extract-heading-text)) + (org-export-show-temporary-export-buffer nil) + (org-export-filter-final-output-functions + '(html-body-id-filter html-body-div-filter)) + (org-export-with-smart-quotes nil) + (org-export-smart-quotes-alist nil)) + (insert "* ORG IS STUPID SOMETIMES\n") + (goto-char (point-min)) + (org-html-export-as-html nil t nil t) + (with-current-buffer "*Org HTML Export*" + (goto-char (point-min)) + (replace-regexp "

.*

" "") + (insert "

" extracted-heading "

") + (flush-lines "^$" (point-min) (point-max)) + (let ((sentence-end-double-space nil)) + (unfill-region (point-min) (point-max))) + (replace-regexp " +" "

" nil (point-min) (point-max)) + (replace-regexp " +

" "

" nil (point-min) (point-max)) + (copy-region-as-kill (point-min) (point-max))))) + (when (called-interactively-p 'interactive) + (indicate-copied-region)) + (setq deactivate-mark t) + nil) + (defun acdw/org-export-copy () "copy a tree" (interactive) @@ -409,14 +499,17 @@ first." (let ((extracted-heading (acdw/org-extract-heading-text))) ;; Export to ASCII - not async, subtree only, visible-only, body-only (let ((org-export-show-temporary-export-buffer nil)) - (org-ascii-export-as-ascii nil t t t)) + (org-ascii-export-as-ascii nil t nil t)) (with-current-buffer "*Org ASCII Export*" (goto-char (point-min)) (insert extracted-heading) - (newline) - (newline) + (newline 2) - (unfill-region (point-min) (point-max)) + (replace-regexp org-list-full-item-re " +\4") + + (let ((sentence-end-double-space nil)) + (unfill-region (point-min) (point-max))) (flush-lines "^$" (point-min) (point-max)) (copy-region-as-kill (point-min) (point-max))) @@ -435,6 +528,19 @@ first." (match-string-no-properties 2 match)) heading)))) +(defun acdw/sync-dir (&optional file make-directory) + "Return FILE from ~/Sync. +Optional argument MAKE-DIRECTORY makes the directory. +Logic is as in `acdw/dir', which see." + (let ((dir (expand-file-name (convert-standard-filename "~/Sync/")))) + (if file + (let ((file-name (expand-file-name (convert-standard-filename file) + dir))) + (when make-directory + (make-directory (file-name-directory file-name) 'parents)) + file-name) + dir))) + (defun acdw/dir (&optional file make-directory) "Place Emacs files in one place. @@ -695,6 +801,24 @@ When called with PREFIX, just kill Emacs without confirmation." (ignore-errors (delete-frame)))) +(defun acdw/disabled-command-function (&optional cmd keys) + (let ((cmd (or cmd this-command)) + (keys (or keys (this-command-keys)))) + ;; this logic stolen from original `disabled-command-function' + (if (or (eq (aref keys 0) (if (stringp keys) + (aref "\M-x" 0) + ?\M-x)) + (and (>= (length keys) 2) + (eq (aref keys 0) meta-prefix-char) + (eq (aref keys 1) ?x))) + ;; it's been run as an M-x command, we want to do it + (call-interactively cmd) + ;; else, tell the user it's disabled. + (message (substitute-command-keys + (concat "Command `%s' has been disabled. " + "Run with \\[execute-extended-command].")) + cmd)))) + ;;; cribbed -- cgit 1.4.1-21-gabe81