This commit is contained in:
Case Duckworth 2022-05-09 20:37:17 -05:00
commit 4c4dd0e782
14 changed files with 251 additions and 151 deletions

View File

@ -140,7 +140,7 @@ See `no-littering' for examples.")
;; Setup `setup'
(add-to-list 'setup-modifier-list 'setup-wrap-to-demote-errors)
(add-to-list 'setup-modifier-list '+setup-wrap-to-demote-errors)
(unless (memq debug-on-error '(nil init))
(define-advice setup (:around (fn head &rest args) +setup-report)
(+with-progress ((format "[Setup] %S..." head))

154
init.el
View File

@ -14,6 +14,14 @@
;; - Be kind to yourself.
;; - Make good choices.
;;; Commentary
;; My init.el. There are many like it, but this one is mine.
;; Ideas:
;; [[https://emacs.stackexchange.com/questions/17278/truncate-only-certain-lines-and-use-continuation-lines-elsewhere][Truncate org-mode headings]]
;; [[https://emacs.stackexchange.com/questions/7432/make-visual-line-mode-more-compatible-with-org-mode][another link that might be useful for truncating]]
;;; Code:
(let ((early-features `((early-init . ,(locate-user-emacs-file "early-init"))
@ -104,6 +112,8 @@
(:with-mode Custom-mode
(:local-set imenu-generic-expression +cus-edit-imenu-generic-expression)))
(setup (:require find-script))
(setup (:require goto-addr)
(if (fboundp #'global-goto-address-mode)
(global-goto-address-mode)
@ -242,17 +252,15 @@
(:option +browse-url-transformations `((,(rx (or "youtube.com"
"youtu.be"))
. ,+invidious-host)
("twitter\\.com"
. "nitter.net")
("instagram\\.com"
. "bibilogram.art")
("twitter\\.com" . "nitter.net")
("instagram\\.com" . "bibilogram.art")
(,(rx (or "reddit.com"
"old.reddit.com"))
. "teddit.net")
("medium\\.com"
. "scribe.rip")
("www\\.npr\\.org"
. "text.npr.org")))
("medium\\.com" . "scribe.rip")
("www\\.npr\\.org" . "text.npr.org")
;;TODO: Various paste sites
))
(+browse-url-transform-url-global-mode +1))
(setup calendar
@ -294,7 +302,7 @@
#'lin-mode
#'+dired-dim-git-ignores)
(+with-ensure-after-init ; Necessary because jabber loads later
(:+key "C-x C-j" #'dired-jump))
(:+key "C-x C-j" #'dired-jump))
(dolist (refresh-after-func '(dired-do-flagged-delete))
(advice-add refresh-after-func :after #'revert-buffer))
(with-eval-after-load 'frowny
@ -308,10 +316,12 @@
(:also-load +elisp)
(:option eval-expression-print-length nil
eval-expression-print-level nil)
(:with-map (emacs-lisp-mode-map lisp-interaction-mode-map)
(:bind "C-c C-c" #'eval-defun
"C-c C-k" #'+elisp-eval-region-or-buffer
"C-c C-z" #'ielm))
(:with-mode emacs-lisp-mode
(:hook #'checkdoc-minor-mode))
(:bind-into (emacs-lisp-mode-map lisp-interaction-mode-map)
"C-c C-c" #'eval-defun
"C-c C-k" #'+elisp-eval-region-or-buffer
"C-c C-z" #'ielm)
(advice-add #'eval-region :around #'+eval-region@pulse))
(setup eshell
@ -362,7 +372,7 @@
;; Bind keys
(dolist (binding '(("C-d" . +eshell-quit-or-delete-char)))
(define-key eshell-mode-map
(kbd (car binding)) (cdr binding)))
(kbd (car binding)) (cdr binding)))
;; Environment variables
(dolist (environment '(("PAGER" . "cat")))
(setenv (car environment) (cdr environment)))))
@ -461,7 +471,8 @@
'(context-menu-ffap
context-menu-region
context-menu-undo
context-menu-dictionary))
;; context-menu-dictionary
))
(context-menu-mode +1))
(dolist (click '(;; Fix scrolling in the margin
wheel-down double-wheel-down triple-wheel-down
@ -470,9 +481,25 @@
(global-set-key (vector 'left-margin click) 'mwheel-scroll)))
(setup net-utils
(:needs "traceroute")
(:require +finger) ; fixes `finger' to use var below
(:option finger-X.500-host-regexps '(".") ; only send username
))
)
(require 'transient)
(transient-define-prefix net-utils ()
"Networking utilities"
["Actions"
("p" "Ping" ping)
("i" "Ifconfig" ifconfig)
("w" "Iwconfig" iwconfig)
("n" "Netstat" netstat)
("a" "Arp" arp)
("r" "Route" route)
("h" "Nslookup host" nslookup-host)
("d" "Dig" dig)
("s" "Smb Client" smbclient)
("t" "Traceroute" traceroute)])
(:+key "C-z M-n" #'net-utils))
(setup notmuch
(:load-from "~/usr/share/emacs/site-lisp/")
@ -561,7 +588,7 @@
org-fontify-done-headline t
org-fontify-quote-and-verse-blocks t
org-fontify-whole-heading-line t
org-hide-emphasis-markers t
org-hide-emphasis-markers nil
org-html-coding-system 'utf-8-unix
org-image-actual-width (list (* (window-font-width)
(- fill-column 8)))
@ -620,11 +647,20 @@
"C-c C-p" #'+org-previous-heading-widen
"C-c C-o" #'+org-open-at-point-dwim
"`" #'+org-insert-tilde
"~" #'+org-insert-backtick)
"~" #'+org-insert-backtick
"C-c C-x l" #'org-toggle-link-display
"C-c C-x m" (lambda () (interactive)
(setq-local org-hide-emphasis-markers
(not org-hide-emphasis-markers))
(font-lock-update))
"C-c C-x r" #'+org-drawer-list-add-resource
"C-M-k" #'kill-paragraph
"C-M-t" #'transpose-paragraphs)
(:global [f8] #'org-clock-in
[f9] #'org-clock-out
"C-c l" #'org-store-link)
(:hook #'variable-pitch-mode
#'visual-fill-column-mode
#'turn-off-auto-fill
#'org-indent-mode
#'prettify-symbols-mode
@ -632,6 +668,12 @@
(:local-set prettify-symbols-alist '(("DEADLINE:" . ?→)
("SCHEDULED:" . ?↷)
("CLOSED:" . ?✓))
;; electric-pair-pairs
;; (append electric-pair-pairs
;; (mapcar (lambda (emph)
;; (let ((ch (string-to-char (car emph))))
;; (cons ch ch)))
;; org-emphasis-alist))
;;+modeline-position-function #'+org-count-words-stupidly
)
(:local-hook user-save-hook #'+org-before-save@prettify-buffer)
@ -649,6 +691,9 @@
(org-link-set-parameters "sms" :follow #'+org-sms-open)
(setf (alist-get "\\.x?html?\\'" org-file-apps nil nil #'equal)
#'+org-open-html))
(:face 'org-done '((t (:inherit (modus-themes-subtle-green))))
'org-tag '((t (:inherit (secondary-selection))))
'org-todo '((t (:inherit (modus-themes-subtle-red)))))
;; Extra keywords
(font-lock-add-keywords
'org-mode
@ -1167,10 +1212,6 @@
(:hook #'visual-line-mode
#'enable-lui-track
#'visual-fill-column-mode
(defun +disable-electric-pair-mode ()
"Disable `electric-pair-mode' in the current buffer."
(interactive)
(electric-pair-local-mode -1))
#'enable-lui-autopaste)
(:local-set fringes-outside-margins t
right-margin-width (length lui-time-stamp-format)
@ -1187,6 +1228,7 @@
(setf (alist-get 'lui-next-button-or-complete vertico-multiform-commands)
'(flat))))
(tracking-mode +1)
(:with-mode tracking-mode
(:option tracking-position 'before-modes)
(:bind "C-c C-SPC" (lambda () (interactive)
@ -1304,19 +1346,20 @@
(with-eval-after-load 'vertico-multiform
(setf (alist-get 'consult-buffer vertico-multiform-commands) '(flat))
(dolist (buf-cmd '(consult-find
consult-yank-pop
consult-locate
consult-grep
consult-git-grep
consult-ripgrep
consult-line
consult-line-multi
consult-multi-occur
consult-keep-lines
consult-flymake
consult-focus-lines
consult-git-grep
consult-grep
consult-imenu
consult-imenu-multi
consult-outline))
consult-keep-lines
consult-line
consult-line-multi
consult-locate
consult-multi-occur
consult-outline
consult-ripgrep
consult-yank-pop))
(setf (alist-get buf-cmd vertico-multiform-commands) nil)))))
(setup (:straight consult-dir)
@ -1514,6 +1557,11 @@
(add-hook 'embark-collect-mode-hook #'consult-preview-at-point-mode))
(setup (:straight embrace)
(dolist (mode '(LaTeX-mode org-mode ruby-mode))
(add-hook (intern (format "%s-hook" mode))
(intern (format "embrace-%s-hook" mode))))
(:face 'embrace-help-pair-face '((t ( :inverse-video nil
:inherit font-lock-keyword-face))))
(:+key "C-," #'embrace-commander))
(setup (:straight (ement
@ -1619,7 +1667,7 @@
(setup (:straight (forge
:host github :repo "magit/forge")
(eq system-type 'gnu/linux))
(require 'forge)
(:quit) ; XXX: Somehow missing compat-26
(add-to-list 'forge-alist
'("tildegit.org" "tildegit.org/api/v1" "tildegit.org"
forge-gitea-repository)))
@ -1632,6 +1680,7 @@
(setup (:straight (frowny
:host github
:repo "duckwork/frowny.el"))
(:option frowny-eyes (rx (any ":=") (opt "'") (? "-")))
(global-frowny-mode +1))
(setup (:straight gcmh)
@ -1759,9 +1808,6 @@
:fork ( :host nil
:repo "https://codeberg.org/acdw/emacs-jabber")))
(:also-load +jabber)
(defvar +jabber-ws-prefix 0 "Width to pad left side of chats.")
(defvar +jabber-pre-prompt " \n"
"String to show before a prompt.")
(:option jabber-account-list '(("acdw@hmm.st"))
jabber-groupchat-buffer-format "%n"
jabber-chat-buffer-format "%n"
@ -1770,7 +1816,7 @@
jabber-muc-decorate-presence-patterns
'(("\\( enters the room ([^)]+)\\| has left the chatroom\\)$")
("." . jabber-muc-presence-dim))
jabber-muc-colorize-foreign t
jabber-muc-colorize-foreign nil ; colorizing doesn't match my color theme
jabber-chat-foreign-prompt-format (concat +jabber-pre-prompt
"[%t] %n\n"
(make-string +jabber-ws-prefix
@ -1804,7 +1850,6 @@
jabber-console-mode))
(let ((hook (intern (format "%s-hook" mode))))
(add-hook hook #'visual-fill-column-mode)))
(add-hook 'jabber-activity-mode-hook #'tracking-mode)
(with-eval-after-load 'tracking
(add-to-list 'tracking-ignored-buffers "discuss@conference.soprani.ca"))
(:with-mode jabber-chat-mode
@ -1816,7 +1861,10 @@
wrap-prefix (make-string +jabber-ws-prefix ?\ )))
(:+leader "C-j" jabber-global-keymap)
(advice-add 'jabber-activity-add :after #'+jabber-tracking-add)
(advice-add 'jabber-activity-add-muc :after #'+jabber-tracking-add-muc))
(advice-add 'jabber-activity-add-muc :after #'+jabber-tracking-add-muc)
;;; Alerting hooks --- remove echo messages
(remove-hook 'jabber-alert-muc-hooks 'jabber-muc-echo)
(remove-hook 'jabber-alert-presence-hooks 'jabber-presence-echo))
(setup (:straight (keepassxc-shim
:host github :repo "duckwork/keepassxc-shim.el"))
@ -1899,6 +1947,7 @@
(setup (:straight mastodon)
(:option mastodon-instance-url "https://tiny.tilde.website"
mastodon-active-user "acdw"
mastodon-client--token-file (.etc "mastodon.plstore")
mastodon-auth-source-file (seq-some (lambda (i)
(when (and (stringp i)
@ -1950,8 +1999,8 @@
(,(intern (format "modus-themes-heading-%s" facen))
fixed-pitch))
:now)))))
(:face 'modus-themes-tab-active '((t :bold nil))
'modus-themes-tab-inactive '((t :italic t)))
(:face 'modus-themes-tab-active '((t ( :bold nil)))
'modus-themes-tab-inactive '((t ( :italic t))))
(define-advice modus-themes--current-theme (:around (fn &rest r))
"Fix a \"nil is not a Modus theme\" error."
@ -2027,7 +2076,7 @@
(:option completion-styles '(substring orderless basic)
completion-category-defaults nil
completion-category-overrides
'((file (styles partial-completion))
'((file (styles basic partial-completion))
(command (styles +orderless-with-initialism))
(variable (styles +orderless-with-initialism))
(symbol (styles +orderless-with-initialism)))
@ -2067,6 +2116,7 @@
(local-set-key (kbd "C-c M-o") 'org-mime-org-buffer-htmlize))))
(setup (:straight org-modern)
(:quit "I think I can do most of this myself.")
(:option org-modern-hide-stars nil
org-modern-star nil
org-modern-list nil
@ -2092,7 +2142,9 @@
(org-visibility-enable-hooks))
(setup (:straight orglink)
(global-orglink-mode +1))
(:option orglink-activate-in-modes '(text-mode prog-mode))
(global-orglink-mode +1)
(global-goto-address-mode -1))
(setup (:straight package-lint))
@ -2211,9 +2263,7 @@
",")
+modeline-input-method
+modeline-position
,(+modeline-concat
'(+modeline-minions
+modeline-major-mode))
+modeline-major-mode
+modeline-file-percentage
)))
(simple-modeline-mode +1))
@ -2222,6 +2272,8 @@
(:also-load +slack)
(:option slack-prefer-current-team t
slack-buffer-emojify t
slack-thread-also-send-to-room nil
slack-typing-visibility 'buffer
slack-buffer-create-on-notify t
slack-enable-wysiwyg t
slack-file-dir (xdg-user-dir "DOWNLOAD")
@ -2255,9 +2307,15 @@
(sophomore-enable #'narrow-to-region)
(sophomore-disable ; These are mostly annoying commands
#'view-hello-file
#'describe-gnu-project)
#'describe-gnu-project
#'suspend-frame)
(sophomore-mode +1))
(setup (:straight (spongebob-case
:host github
:repo "duckwork/spongebob-case.el"))
(define-key +casing-map (kbd "M-s") #'spongebob-case-dwim))
(setup (:straight ssh-config-mode)
(:file-match (rx "/.ssh/config" eos)
(rx "/ssh" (? "d") "_config" eos))
@ -2269,7 +2327,7 @@
(setup (:straight super-save)
(:option auto-save-default nil
super-save-auto-save-when-idle t
super-save-idle-duration 60
super-save-idle-duration 30
super-save-exclude '(".gpg")
super-save-remote-files nil)
(auto-save-visited-mode -1)

View File

@ -120,9 +120,9 @@ ARGS are ignored here, but passed on for later processing."
;; along with the rest of the args, in a list to the original caller (probably
;; `browse-url'.)
(apply 'list
(cl-loop with url = (substring-no-properties
(if (consp url) (car url) url))
for (regex . transformation) in +browse-url-transformations
(cl-loop with url = (substring-no-properties
(if (consp url) (car url) url))
for (regex . transformation) in +browse-url-transformations
if (string-match regex url)
return (replace-match transformation nil nil url)
;; else

View File

@ -5,7 +5,7 @@
(defun +consult-project-root ()
"Return either the current project, or the VC root, of current file."
(if (and (functionp 'project-current)
(project-current))
(project-current))
(car (project-roots (project-current)))
(vc-root-dir)))

View File

@ -2,18 +2,17 @@
;;; Code:
(require 'vertico)
(defun +dired-goto-file (file)
"ADVICE for `dired-goto-file' to make RET call `vertico-exit'."
(interactive ; stolen from `dired-goto-file'
(prog1
(list (dlet ((vertico-map (copy-keymap vertico-map)))
(define-key vertico-map (kbd "RET") #'vertico-exit)
(expand-file-name (read-file-name "Goto file: "
(dired-current-directory)))))
(push-mark)))
(dired-goto-file file))
(with-eval-after-load 'vertico
(defun +dired-goto-file (file)
"ADVICE for `dired-goto-file' to make RET call `vertico-exit'."
(interactive ; stolen from `dired-goto-file'
(prog1
(list (dlet ((vertico-map (copy-keymap vertico-map)))
(define-key vertico-map (kbd "RET") #'vertico-exit)
(expand-file-name (read-file-name "Goto file: "
(dired-current-directory)))))
(push-mark)))
(dired-goto-file file)))
;;; [[https://www.reddit.com/r/emacs/comments/u2lf9t/weekly_tips_tricks_c_thread/i4n9aoa/?context=3][Dim files in .gitignore]]

View File

@ -72,11 +72,10 @@ are sorted lexigraphically."
;; otherwise, sort lexigraphically
(t (string< s1 s2)))))))))
;; Return to original point relative to the defun we were in
(goto-char (point-min))
(re-search-forward current-defun-re)
(beginning-of-defun)
(goto-char (+ (point) defun-point))
))
(ignore-errors (goto-char (point-min))
(re-search-forward current-defun-re)
(beginning-of-defun)
(goto-char (+ (point) defun-point)))))
(defun +init-sort-then-save ()
"Sort init.el, then save it."

View File

@ -10,6 +10,18 @@
(require 'jabber)
(require 'tracking)
(defgroup +jabber nil
"Extra jabber.el customizations."
:group 'jabber)
(defcustom +jabber-ws-prefix 0
"Width to pad left side of chats."
:type 'string)
(defcustom +jabber-pre-prompt " \n"
"String to put before the prompt."
:type 'string)
(defvar +jabber-tracking-show-p #'jabber-activity-show-p-default
"Function that checks if the given JID should be shown in the mode line.
This does the same as `jabber-activity-show-p', but for the

View File

@ -19,9 +19,9 @@
;; I need to define this map before the proper mode map.
(defvar +key-leader-map (let ((map (make-sparse-keymap))
(c-z (global-key-binding "\C-z")))
(define-key map "\C-z" c-z)
map)
(c-z (global-key-binding "\C-z")))
;;(define-key map "\C-z" c-z)
map)
"A leader keymap under the \"C-z\" bind.")
;; http://xahlee.info/emacs/emacs/emacs_menu_app_keys.html and

View File

@ -126,9 +126,18 @@ and appended with `truncate-string-ellipsis'."
(propertize ;; (+string-truncate (format-mode-line mode-name) 16)
(format-mode-line mode-name)
'face 'font-lock-keyword-face
'keymap mode-line-major-mode-keymap
'help-echo (concat (format-mode-line mode-name)
" mode\nmouse-1: show menu.")
'keymap (let ((map (make-sparse-keymap)))
(bindings--define-key map [mode-line down-mouse-1]
`(menu-item "Menu Bar" ignore
:filter ,(lambda (_) (mouse-menu-major-mode-map))))
(define-key map [mode-line mouse-2] 'describe-mode)
(bindings--define-key map [mode-line down-mouse-3]
`(menu-item "Minions" minions-minor-modes-menu))
map)
'help-echo (+concat (list (format-mode-line mode-name) " mode")
"mouse-1: show menu"
"mouse-2: describe mode"
"mouse-3: display minor modes")
'mouse-face 'mode-line-highlight)))
(defcustom +modeline-modified-icon-alist '((ephemeral . "*")
@ -302,9 +311,10 @@ The order of elements matters: whichever one matches first is applied."
(defun +modeline-line-column (&optional spacer) ; adapted from `simple-modeline'
"Display the current cursor line and column depending on modes."
(funcall (+modeline-concat '(+modeline-line
+modeline-column)
"|")))
(concat (or spacer +modeline-default-spacer)
(+modeline-line "")
"|"
(+modeline-column "")))
(defcustom +modeline-position-function nil
"Function to use instead of `+modeline-position' in modeline."
@ -312,17 +322,16 @@ The order of elements matters: whichever one matches first is applied."
function)
:local t)
(defun +modeline-position (&optional _)
(defun +modeline-position (&optional spacer)
"Display the current cursor position.
See `line-number-mode', `column-number-mode', and
`file-percentage-mode'. If `+modeline-position-function' is set
to a function in the current buffer, call that function instead."
(funcall (if +modeline-position-function
+modeline-position-function
(+modeline-concat '(+modeline-region
+modeline-line-column
;; +modeline-file-percentage
)))))
(concat (or spacer +modeline-default-spacer)
(if +modeline-position-function
(funcall +modeline-position-function)
(concat (+modeline-region)
(+modeline-line-column)))))
(defun +modeline-vc (&optional spacer)
"Display the version control branch of the current buffer in the modeline."

View File

@ -588,19 +588,6 @@ and POST-PROCESS are passed to `org-export-to-file'."
("" "---"))))
(replace-match replace nil nil)))))
;;; Toggle org-hide-emphasis-markers
(define-minor-mode +org-show-mode
"Show emphasis markers and full links in `org-mode'."
:lighter "/*/"
(setq org-hide-emphasis-markers (not +org-show-mode)
org-link-descriptive (not +org-show-mode))
(funcall (if +org-show-mode
#'remove-from-invisibility-spec
#'add-to-invisibility-spec)
'(org-link))
(font-lock-update))
;;; go forward and backward in the tree, ~ cleanly ~
;; https://stackoverflow.com/a/25201697/10756297

View File

@ -29,23 +29,37 @@
"Warn the user that something bad happened in `setup'."
(display-warning 'setup (format message args)))
(defun +setup-wrap-to-demote-errors (body name)
"Wrap BODY in a `with-demoted-errors' block.
This behavior is prevented if `setup-attributes' contains the
symbol `without-error-demotion'.
This function differs from `setup-wrap-to-demote-errors' in that
it includes the NAME of the setup form in the warning output."
(if (memq 'without-error-demotion setup-attributes)
body
`(with-demoted-errors ,(format "Error in setup form on line %d (%s): %%S"
(line-number-at-pos)
name)
,body)))
(setup-define :quit
'setup-quit
:documentation "Quit the current `setup' form.
Good for commenting.")
(setup-define :face
(lambda (face spec)
`(custom-set-faces (list ,face ,spec 'now "Customized by `setup'.")))
(lambda (face spec)
`(custom-set-faces (list ,face ,spec 'now "Customized by `setup'.")))
:documentation "Customize FACE with SPEC using `custom-set-faces'."
:repeatable t)
(setup-define :load-after
(lambda (&rest features)
(let ((body `(require ',(setup-get 'feature))))
(dolist (feature (nreverse features))
(setq body `(with-eval-after-load ',feature ,body)))
body))
(lambda (&rest features)
(let ((body `(require ',(setup-get 'feature))))
(dolist (feature (nreverse features))
(setq body `(with-eval-after-load ',feature ,body)))
body))
:documentation "Load the current feature after FEATURES.")
(setup-define :load-from
@ -88,50 +102,7 @@ If PATH does not exist, abort the evaluation."
',recipe)
,(setup-quit))
(:success t)))
(defun setup--straight-handle-arg (arg var)
(cond
((and (boundp var) (symbol-value var)) t)
((keywordp arg) (set var t))
((functionp arg) (set var nil) (funcall arg))
((listp arg) (set var nil) (eval arg :lexical))))
(setup-define :straight
(lambda (recipe &rest predicates)
(let* ((skp (make-symbol "straight-keyword-p"))
(straight-use-p
(cl-every (lambda (f) (setup--straight-handle-arg f skp))
predicates))
(form `(unless (and ,straight-use-p
(condition-case e
(straight-use-package ',recipe)
(error
(+setup-warn ":straight error: %S"
',recipe)
,(setup-quit))
(:success t)))
,(setup-quit))))
;; Keyword arguments --- :quit is special and should short-circuit
(if (memq :quit predicates)
(setq form `,(setup-quit))
;; Otherwise, handle the rest of them ...
(when-let ((after (cadr (memq :after predicates))))
(setq form `(with-eval-after-load ,(if (eq after t)
(setup-get 'feature)
after)
,form))))
;; Finally ...
form))
:documentation "Install RECIPE with `straight-use-package'.
If PREDICATES are given, only install RECIPE if all of them return non-nil.
The following keyword arguments are also recognized:
- :quit --- immediately stop evaluating. Good for commenting.
- :after FEATURE --- only install RECIPE after FEATURE is loaded.
If FEATURE is t, install RECIPE after the current feature."
:repeatable nil
:indent 1
:shorthand (lambda (sexp)
(let ((recipe (cadr sexp)))
(or (car-safe recipe) recipe)))) ,(setup-quit))))
,(setup-quit))))
;; Keyword arguments --- :quit is special and should short-circuit
(if (memq :quit predicates)
(setq form `,(setup-quit))
@ -155,6 +126,13 @@ The following keyword arguments are also recognized:
(let ((recipe (cadr sexp)))
(or (car-safe recipe) recipe)))))
(setup-define :needs
(lambda (executable)
`(unless (executable-find ,executable)
,(setup-quit)))
:documentation "If EXECUTABLE is not in the path, stop here."
:repeatable 1)
;;; Redefines of `setup' forms

View File

@ -34,6 +34,7 @@ all of them, for reasons that should be obvious.
With a prefix argument, it also pulls the packages FROM-UPSTREAM."
(interactive "P")
(straight-pull-recipe-repositories)
(straight-pull-all from-upstream)
(straight-rebuild-all))

View File

@ -138,6 +138,10 @@ active, or else the entire buffer."
(= (line-beginning-position) (line-end-position)))
(insert "\n")))))
(defcustom +open-paragraph-ignore-modes '(special-mode lui-mode comint-mode)
"Modes in which `+open-paragraph' makes no sense."
:type '(repeat function))
(defun +open-paragraph (&optional arg)
"Open a paragraph after paragraph at point.
A paragraph is defined as continguous non-empty lines of text
@ -148,7 +152,7 @@ Called with prefix ARG, open a paragraph before point."
;; TODO: Take an integer as ARG, allowing for skipping paragraphs up and down.
(interactive "*P")
;; TODO: add `+open-paragraph-ignore-modes'
(unless (derived-mode-p 'special-mode 'lui-mode 'comint-mode)
(unless (apply #'derived-mode-p +open-paragraph-ignore-modes)
;; Go to next blank line. This /isn't/ `end-of-paragraph-text' because
;; that's weird with org, and I'm guessing other modes too.
(unless (looking-at "^$") (forward-line (if arg -1 +1)))
@ -426,5 +430,22 @@ This calls `indent-rigidly' and passes ARG to it."
(goto-char (line-end-position)))
(call-interactively #'indent-rigidly))
(defun +sort-lines (reverse beg end)
"Sort lines in region, ignoring leading whitespace.
REVERSE non-nil means descending order; interactively, REVERSE is
the prefix argument, and BEG and END are the region. The
variable `sort-fold-case' determines whether case affects the
sort order."
(interactive "P\nr")
(save-excursion
(save-restriction
(narrow-to-region beg end)
(goto-char (point-min))
(let ((inhibit-field-text-motion t))
(sort-subr reverse
#'forward-line
#'end-of-line
#'beginning-of-line-text)))))
(provide 'acdw)
;;; acdw.el ends here

36
lisp/find-script.el Normal file
View File

@ -0,0 +1,36 @@
;;; find-script.el --- Find a script in $PATH -*- lexical-binding: t; -*-
;;; Commentary:
;; This package makes it easier to find a script to edit in $PATH. The initial
;; `rehash-exes' is slow, but it's stored in `*exes*' as a caching mechanism.
;; However, I'm sure it could be improved.
;; In addition, `*exes*' currently contains /all/ executables in $PATH, which
;; ... maybe only the ones stored in some text format should be shown.
;;; Code:
(defvar *exes* nil
"All the exectuables in $PATH.
Run `rehash-exes' to refresh this variable.")
(defun rehash-exes ()
"List all the executables in $PATH.
Also sets `*exes*' parameter."
(setq *exes*
(cl-loop for dir in exec-path
append (file-expand-wildcards (concat dir "*"))
into exes
finally return exes)))
;;;###autoload
(defun find-script (script)
"Find a file in $PATH."
(interactive
(list (let ((exes (or *exes* (rehash-exes))))
(completing-read "Script> " exes nil t))))
(find-file script))
(provide 'find-script)
;;; find-script.el ends here