Compare commits

...

8 commits

Author SHA1 Message Date
ec7cea96b6 Updated corfu hack 2025-08-10 10:13:56 -05:00
Benson Chu
aadb9ea399 I want mail aliases in my commit message buffers 2025-08-08 15:03:36 -05:00
Benson Chu
acfd8f5e72 I think I finally figured out the terminal key stuff 2025-08-08 15:03:16 -05:00
Benson Chu
358ca792f5 Spacing 2025-08-07 14:23:59 -05:00
Benson Chu
5baa65c2fc My custom org capture template 2025-07-22 09:21:54 -05:00
Benson Chu
bf9cde10c2 I like this a lot better 2025-07-21 17:09:19 -05:00
Benson Chu
675047fdad I should really read documentation more... 2025-07-18 13:37:00 -05:00
Benson Chu
2631db3ad8 There we go, that's how it's done 2025-07-18 13:37:00 -05:00
9 changed files with 396 additions and 129 deletions

View file

@ -295,33 +295,29 @@
#+end_src
* navigation
#+begin_src emacs-lisp
;; Scrollkeeper is helpful for scrolling up and down
(defvar window-third-height nil)
(defun update-window-third-height (&optional arg)
(let ((win
(cond ((framep arg)
(frame-selected-window arg))
((windowp arg)
arg)
((null arg) (selected-window)))))
;; (message "Updating window height for %s" (window-buffer win))
(when (not (active-minibuffer-window))
(setq next-screen-context-lines
(max 1 (* 2 (/ (window-height win) 3)))))))
(defun update-window-third-height (win &rest args)
;; (message "Updating window height for %s" (window-buffer win))
(setq window-third-height
(max 1 (/ (window-height win) 3))))
(update-window-third-height)
(advice-add #'select-window
:after
'update-window-third-height)
(add-hook 'window-selection-change-functions
#'update-window-third-height)
(defun scroll-up-third ()
(interactive)
;; (pulse-momentary-highlight-one-line (point))
(scroll-up (or window-third-height 10)))
(add-hook 'window-configuration-change-hook
#'update-window-third-height)
(defun scroll-down-third ()
(interactive)
;; (pulse-momentary-highlight-one-line (point))
(scroll-down (or window-third-height 10)))
(global-set-key (kbd "C-v") 'scroll-up-third)
(global-set-key (kbd "M-v") 'scroll-down-third)
;; (use-package scrollkeeper)
;; (global-set-key (kbd "C-v") 'scrollkeeper-down)
;; (global-set-key (kbd "M-v") 'scrollkeeper-up)
;; (advice-add #'select-window
;; :after
;; 'update-window-third-height)
;; Word navigation
(global-set-key (kbd "M-f") 'forward-to-word)
@ -1042,6 +1038,6 @@
#+end_src
* Terminal compatibility
#+begin_src emacs-lisp
(global-set-key (kbd "M-[ emacs-C-SPC") #'set-mark-command)
(global-set-key (kbd "M-[ emacs-C-/") #'undo)
(when (null window-system)
(require 'term-compat))
#+end_src

View file

@ -139,11 +139,9 @@
(setq projectile-require-project-root t)
(setq projectile-indexing-method 'hybrid)
(setq projectile-auto-update-cache nil)
(if (and (not (daemonp))
(null window-system))
(global-set-key (kbd "C-c M-[ emacs-C-.") 'projectile-command-map)
(global-set-key (kbd "C-c C-.") 'projectile-command-map)
(global-set-key (kbd "C-c M-[ emacs-C-.") 'projectile-command-map)))
(global-set-key (kbd "C-c C-.") 'projectile-command-map)
(global-set-key (kbd "C-c M-[ emacs-C-.") 'projectile-command-map))
:config
(projectile-mode)
(add-to-list 'projectile-globally-ignored-directories

View file

@ -57,7 +57,7 @@
;; (get-focused-monitor-geometry)
(defun advise-corfu-make-frame-with-monitor-awareness (orig-fun frame x y width height)
(defun advise-corfu-make-frame-with-monitor-awareness (orig-fun frame x y width height buffer)
"Advise `corfu--make-frame` to be monitor-aware, adjusting X and Y according to the focused monitor."
;; Get the geometry of the currently focused monitor
(let* ((monitor-geometry (get-focused-monitor-geometry))
@ -72,7 +72,7 @@
(new-y (+ monitor-y y)))
;; Call the original function with potentially adjusted coordinates
(funcall orig-fun frame new-x new-y width height)))
(funcall orig-fun frame new-x new-y width height buffer)))
(advice-add 'corfu--make-frame :around #'advise-corfu-make-frame-with-monitor-awareness)

View file

@ -43,7 +43,7 @@
(find-file-noselect file))
(save-excursion
(goto-char (point-min))
(let ((r (rx line-start (+ (or "|" ";" "/" "#")) (+ " ") "RUN:" (+ space) (group(+ nonl) line-end)))
(let ((r (rx line-start (+ (or "|" ";" "/" "#")) (+ " ") "RUN:" (+ space) (group (+ nonl) line-end)))
(temp "")
l)
(while (re-search-forward r nil t)

View file

@ -120,97 +120,14 @@
:override
#'my/magit-transient-read-person)
(defun my/transient--show ()
(transient--timer-cancel)
(setq transient--showp t)
(let ((transient--shadowed-buffer (current-buffer))
(focus nil))
(setq transient--buffer (get-buffer-create transient--buffer-name))
(with-current-buffer transient--buffer
(when transient-enable-popup-navigation
(setq focus (or (button-get (point) 'command)
(and (not (bobp))
(button-get (1- (point)) 'command))
(transient--heading-at-point))))
(erase-buffer)
(run-hooks 'transient-setup-buffer-hook)
(when transient-force-fixed-pitch
(transient--force-fixed-pitch))
(setq window-size-fixed 'width)
(when (bound-and-true-p tab-line-format)
(setq tab-line-format nil))
(setq header-line-format nil)
(setq mode-line-format
(if (or (natnump transient-mode-line-format)
(eq transient-mode-line-format 'line))
nil
transient-mode-line-format))
(setq mode-line-buffer-identification
(symbol-name (oref transient--prefix command)))
(if transient-enable-popup-navigation
(setq-local cursor-in-non-selected-windows 'box)
(setq cursor-type nil))
(setq display-line-numbers nil)
(setq show-trailing-whitespace nil)
(transient--insert-groups)
(when (or transient--helpp transient--editp)
(transient--insert-help))
(when-let ((line (transient--separator-line)))
(insert line)))
(unless (window-live-p transient--window)
(setq transient--window
(display-buffer transient--buffer
transient-display-buffer-action)))
(when (window-live-p transient--window)
(with-selected-window transient--window
;; Save the previous value of the 'no-other-window window parameter.
(set-window-parameter nil 'prev--no-other-window
(window-parameter nil 'no-other-window))
(goto-char (point-min))
(when transient-enable-popup-navigation
(transient--goto-button focus))
(transient--fit-window-to-buffer transient--window)))))
(defun my/transient--show-post ()
(setq transient--buffer (get-buffer-create transient--buffer-name))
(with-current-buffer transient--buffer
(setq window-size-fixed 'width)))
(advice-add #'transient--show
:override
#'my/transient--show)
;; What's so great about the above advice? Why can't the below work?!
;;
;; (defun my/transient--show-post ()
;; (let ((transient--shadowed-buffer (current-buffer))
;; (focus nil))
;; (setq transient--buffer (get-buffer-create transient--buffer-name))
;; (with-current-buffer transient--buffer
;; (when transient-enable-popup-navigation
;; (setq focus (or (button-get (point) 'command)
;; (and (not (bobp))
;; (button-get (1- (point)) 'command))
;; (transient--heading-at-point)))))
;; (when (window-live-p transient--window)
;; (with-selected-window transient--window
;; (set-window-parameter nil 'prev--no-other-window
;; (window-parameter nil 'no-other-window))
;; (set-window-parameter nil 'no-other-window t)
;; (goto-char (point-min))
;; (when transient-enable-popup-navigation
;; (transient--goto-button focus))
;; (transient--fit-window-to-buffer transient--window)))))
;; (advice-add #'transient--show
;; :after
;; #'my/transient--show-post)
(defun my/transient--delete-win-restore-window-param (&rest ignore)
(when (window-live-p transient--window)
(with-selected-window transient--window
;; Restore the value
(set-window-parameter nil 'no-other-window
(window-parameter nil 'prev--no-other-window)))))
(advice-add #'transient--delete-window
:before
#'my/transient--delete-win-restore-window-param)
:after
#'my/transient--show-post)
(provide 'magit-overrides)
;;; magit-overrides.el ends here

View file

@ -0,0 +1,338 @@
;;; my-extra-template-type.el --- -*- lexical-binding: t -*-
;; Copyright (C) 2025 Benson Chu
;; Author: Benson Chu <bensonchu457@gmail.com>
;; Created: [2025-07-18 13:43]
;; This file is not part of GNU Emacs
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(defun my/org-capture-fill-template (&optional template initial annotation)
"Fill a TEMPLATE and return the filled template as a string.
The template may still contain \"%?\" for cursor positioning.
INITIAL content and/or ANNOTATION may be specified, but will be overridden
by their respective `org-store-link-plist' properties if present.
Expansion occurs in a temporary Org mode buffer."
(let* ((template (or template (org-capture-get :template)))
(buffer (org-capture-get :buffer))
(file (buffer-file-name (or (buffer-base-buffer buffer) buffer)))
(time (let* ((c (or (org-capture-get :default-time) (current-time)))
(d (decode-time c)))
(if (< (nth 2 d) org-extend-today-until)
(org-encode-time 0 59 23 (1- (nth 3 d)) (nth 4 d) (nth 5 d))
c)))
(v-t (format-time-string (org-time-stamp-format nil) time))
(v-T (format-time-string (org-time-stamp-format t) time))
(v-u (format-time-string (org-time-stamp-format nil t) time))
(v-U (format-time-string (org-time-stamp-format t t) time))
(v-c (and kill-ring (current-kill 0)))
(v-x (or (org-get-x-clipboard 'PRIMARY)
(org-get-x-clipboard 'CLIPBOARD)
(org-get-x-clipboard 'SECONDARY)
"")) ;ensure it is a string
;; `initial' and `annotation' might have been passed. But if
;; the property list has them, we prefer those values.
(v-i (or (plist-get org-store-link-plist :initial)
(and (stringp initial) (org-no-properties initial))
(org-capture-get :initial)
""))
(v-a
(let ((a (or (plist-get org-store-link-plist :annotation)
annotation
(org-capture-get :annotation)
"")))
;; Is the link empty? Then we do not want it...
(if (equal a "[[]]") "" a)))
(l-re "\\[\\[\\(.*?\\)\\]\\(\\[.*?\\]\\)?\\]")
(v-A (if (and v-a (string-match l-re v-a))
(replace-match "[[\\1][%^{Link description}]]" nil nil v-a)
v-a))
(v-l (if (and v-a (string-match l-re v-a))
(replace-match "[[\\1]]" nil nil v-a)
v-a))
(v-L (if (and v-a (string-match l-re v-a))
(replace-match "\\1" nil nil v-a)
v-a))
(v-n user-full-name)
(v-k (if (marker-buffer org-clock-marker)
(org-no-properties org-clock-heading)
""))
(v-K (if (marker-buffer org-clock-marker)
(let ((original-link-plist org-store-link-plist)
(clocked-task-link (org-with-point-at org-clock-marker
(org-store-link nil nil))))
(setq org-store-link-plist original-link-plist)
clocked-task-link)
""))
(v-f (or (org-capture-get :original-file-nondirectory) ""))
(v-F (or (org-capture-get :original-file) ""))
(src-block-mode
(with-current-buffer (org-capture-get :original-buffer)
(let ((mode-string (symbol-name major-mode)))
(progn
(string-match (rx line-start
(group (+ nonl)) "-mode"
line-end)
mode-string)
(match-string 1 mode-string)))))
(org-capture--clipboards
(delq nil
(list v-i
(org-get-x-clipboard 'PRIMARY)
(org-get-x-clipboard 'CLIPBOARD)
(org-get-x-clipboard 'SECONDARY)
v-c))))
(setq org-store-link-plist (plist-put org-store-link-plist :annotation v-a))
(setq org-store-link-plist (plist-put org-store-link-plist :initial v-i))
(unless template
(setq template "")
(message "no template") (ding)
(sit-for 1))
(save-window-excursion
(switch-to-buffer-other-window (get-buffer-create "*Capture*"))
(erase-buffer)
(setq buffer-file-name nil)
(setq mark-active nil)
(insert template)
(org-mode)
(goto-char (point-min))
;; %[] insert contents of a file.
(save-excursion
(while (re-search-forward "%\\[\\(.+\\)\\]" nil t)
(let ((filename (expand-file-name (match-string 1)))
(beg (copy-marker (match-beginning 0)))
(end (copy-marker (match-end 0))))
(unless (org-capture-escaped-%)
(delete-region beg end)
(set-marker beg nil)
(set-marker end nil)
(condition-case error
(insert-file-contents filename)
(error
(insert (format "%%![could not insert %s: %s]"
filename
error))))))))
;; Mark %() embedded elisp for later evaluation.
(org-capture-expand-embedded-elisp 'mark)
;; Expand non-interactive templates.
(let ((regexp "%\\(:[-A-Za-z]+\\|<\\([^>\n]+\\)>\\|[aAcfFikKlLntTuUxs]\\)"))
(save-excursion
(while (re-search-forward regexp nil t)
;; `org-capture-escaped-%' may modify buffer and cripple
;; match-data. Use markers instead. Ditto for other
;; templates.
(let ((pos (copy-marker (match-beginning 0)))
(end (copy-marker (match-end 0)))
(value (match-string 1))
(time-string (match-string 2)))
(unless (org-capture-escaped-%)
(delete-region pos end)
(set-marker pos nil)
(set-marker end nil)
(let* ((inside-sexp? (org-capture-inside-embedded-elisp-p))
(replacement
(pcase (string-to-char value)
(?< (format-time-string time-string time))
(?:
(or (plist-get org-store-link-plist (intern value))
""))
(?i
(if inside-sexp? v-i
;; Outside embedded Lisp, repeat leading
;; characters before initial place holder
;; every line.
(let ((lead (concat "\n"
(org-current-line-string t))))
(replace-regexp-in-string "\n" lead v-i nil t))))
(?s
(if (string-empty-p v-i)
""
(concat
"#+begin_src " src-block-mode "\n"
(string-trim v-i "\n") "\n"
"#+end_src\n")))
(?a v-a)
(?A v-A)
(?c v-c)
(?f v-f)
(?F v-F)
(?k v-k)
(?K v-K)
(?l v-l)
(?L v-L)
(?n v-n)
(?t v-t)
(?T v-T)
(?u v-u)
(?U v-U)
(?x v-x))))
(insert
(if inside-sexp?
;; Escape sensitive characters.
(replace-regexp-in-string "[\\\"]" "\\\\\\&" replacement)
replacement))))))))
;; Expand %() embedded Elisp. Limit to Sexp originally marked.
(org-capture-expand-embedded-elisp)
;; Expand interactive templates. This is the last step so that
;; template is mostly expanded when prompting happens. Turn on
;; Org mode and set local variables. This is to support
;; completion in interactive prompts.
(let ((org-inhibit-startup t)) (org-mode))
(org-clone-local-variables buffer "\\`org-")
(let (strings) ; Stores interactive answers.
(save-excursion
(let ((regexp "%\\^\\(?:{\\([^}]*\\)}\\)?\\([CgGLptTuU]\\)?"))
(while (re-search-forward regexp nil t)
(let* ((items (and (match-end 1)
(save-match-data
(split-string (match-string-no-properties 1)
"|"))))
(key (match-string 2))
(beg (copy-marker (match-beginning 0)))
(end (copy-marker (match-end 0)))
(prompt (nth 0 items))
(default (nth 1 items))
(completions (nthcdr 2 items)))
(unless (org-capture-escaped-%)
(delete-region beg end)
(set-marker beg nil)
(set-marker end nil)
(pcase key
((or "G" "g")
(let* ((org-last-tags-completion-table
(org-global-tags-completion-table
(cond ((equal key "G") (org-agenda-files))
(file (list file))
(t nil))))
(org-add-colon-after-tag-completion t)
(ins (mapconcat
#'identity
(let ((crm-separator "[ \t]*:[ \t]*"))
(completing-read-multiple
(if prompt (concat prompt ": ") "Tags: ")
org-last-tags-completion-table nil nil nil
'org-tags-history))
":")))
(when (org-string-nw-p ins)
(unless (eq (char-before) ?:) (insert ":"))
(insert ins)
(unless (eq (char-after) ?:) (insert ":"))
(when (org-at-heading-p) (org-align-tags)))))
((or "C" "L")
(let ((insert-fun (if (equal key "C") #'insert
(lambda (s) (org-insert-link 0 s)))))
(pcase org-capture--clipboards
(`nil nil)
(`(,value) (funcall insert-fun value))
(`(,first-value . ,_)
(funcall insert-fun
(read-string "Clipboard/kill value: "
first-value
'org-capture--clipboards
first-value)))
(_ (error "Invalid `org-capture--clipboards' value: %S"
org-capture--clipboards)))))
("p"
;; We remove keyword properties inherited from
;; target buffer so `org-read-property-value' has
;; a chance to find allowed values in sub-trees
;; from the target buffer.
(setq-local org-keyword-properties nil)
(let* ((origin (set-marker (make-marker)
(org-capture-get :pos)
(org-capture-get :buffer)))
;; Find location from where to get allowed
;; values. If `:target-entry-p' is
;; non-nil, the current headline in the
;; target buffer is going to be a parent
;; headline, so location is fine.
;; Otherwise, find the parent headline in
;; the target buffer.
(pom (if (org-capture-get :target-entry-p) origin
(let ((level (progn
(while (org-up-heading-safe))
(org-current-level))))
(org-with-point-at origin
(let ((l (if (org-at-heading-p)
(org-current-level)
most-positive-fixnum)))
(while (and l (>= l level))
(setq l (org-up-heading-safe)))
(if l (point-marker)
(point-min-marker)))))))
(value
(org-read-property-value prompt pom default)))
(org-set-property prompt value)))
((or "t" "T" "u" "U")
;; These are the date/time related ones.
(let* ((upcase? (equal (upcase key) key))
(org-end-time-was-given nil)
(time (org-read-date upcase? t nil prompt)))
(org-insert-timestamp
time (or org-time-was-given upcase?)
(member key '("u" "U"))
nil nil (list org-end-time-was-given))))
(`nil
;; Load history list for current prompt.
(setq org-capture--prompt-history
(gethash prompt org-capture--prompt-history-table))
(push (org-completing-read
(org-format-prompt (or prompt "Enter string") default)
completions
nil nil nil 'org-capture--prompt-history default)
strings)
(insert (car strings))
;; Save updated history list for current prompt.
(puthash prompt org-capture--prompt-history
org-capture--prompt-history-table))
(_
(error "Unknown template placeholder: \"%%^%s\""
key))))))))
;; Replace %n escapes with nth %^{...} string.
(setq strings (nreverse strings))
(save-excursion
(while (re-search-forward "%\\\\\\([1-9][0-9]*\\)" nil t)
(unless (org-capture-escaped-%)
(replace-match
(nth (1- (string-to-number (match-string 1))) strings)
nil t)))))
;; Make sure there are no empty lines before the text, and that
;; it ends with a newline character or it is empty.
(skip-chars-forward " \t\n")
(delete-region (point-min) (line-beginning-position))
(goto-char (point-max))
(skip-chars-backward " \t\n")
(if (bobp) (delete-region (point) (line-end-position))
(end-of-line)
(delete-region (point) (point-max))
(insert "\n"))
;; Return the expanded template and kill the capture buffer.
(untabify (point-min) (point-max))
(set-buffer-modified-p nil)
(prog1 (buffer-substring-no-properties (point-min) (point-max))
(kill-buffer (current-buffer))))))
(advice-add #'org-capture-fill-template
:override
#'my/org-capture-fill-template)
(provide 'my-extra-template-type)
;;; my-extra-template-type.el ends here

View file

@ -25,6 +25,7 @@
;;; Code:
(require 'org-roam)
(require 'org-roam-util)
(require 'my-extra-template-type)
(defvar my/current-logger-cache (make-hash-table))
(defvar my/org-roam-logger-filter-fun nil)
@ -36,7 +37,7 @@
(file+head+olp "%<%Y%m%d%H%M%S>-${slug}.org"
"#+title: ${title}\n"
("Journal" "%<%b %d, %Y>")))
("J" "Journal with source" entry "* %<%H:%M> %?\n:PROPERTIES:\n:LOCATION: %a\n:END:"
("J" "Journal with source" entry "* %<%H:%M> %?\n:PROPERTIES:\n:LOCATION: %a\n:END:\n\n%s"
:unnarrowed t
:target
(file+head+olp "%<%Y%m%d%H%M%S>-${slug}.org"

View file

@ -24,16 +24,22 @@
;;; Code:
(global-set-key (kbd "M-[ emacs-C-SPC") #'set-mark-command)
(global-set-key (kbd "M-[ emacs-M-SPC") #'cycle-spacing)
(global-set-key (kbd "M-[ emacs-C-/") #'undo)
(require 'term/xterm)
(xterm--init-modify-other-keys)
(xterm-mouse-mode 1)
;; (global-set-key (kbd "M-[ emacs-C-SPC") #'set-mark-command)
;; (global-set-key (kbd "M-[ emacs-M-SPC") #'cycle-spacing)
;; (global-set-key (kbd "M-[ emacs-C-/") #'undo)
(global-set-key (kbd "M-[ emacs-C-<backspace>") #'backward-kill-word)
(with-eval-after-load 'org
(define-key org-mode-map (kbd "C-c M-[ emacs-C-,") #'org-insert-structure-template)
(define-key org-mode-map (kbd "M-[ emacs-C-<return>") #'org-insert-heading-respect-content)
;; (define-key org-mode-map (kbd "C-c M-[ emacs-C-,") #'org-insert-structure-template)
;; (define-key org-mode-map (kbd "M-[ emacs-C-<return>") #'org-insert-heading-respect-content)
(define-key org-mode-map (kbd "M-[ emacs-M-S-<return>") #'org-insert-todo-heading)
(define-key org-mode-map (kbd "M-[ emacs-C-S-<return>") #'org-insert-todo-heading-respect-content))
;; (define-key org-mode-map (kbd "M-[ emacs-C-S-<return>") #'org-insert-todo-heading-respect-content)
)
(with-eval-after-load 'vterm
(define-key vterm-mode-map (kbd "M-[ emacs-C-<backspace>")

View file

@ -226,5 +226,16 @@
(when my-ec/enable-mail
(require 'work-mail))
(defun always-expand-mail-abbrevs-in-commit-buffer (orig)
(or with-editor-mode
(funcall orig)))
(add-hook 'with-editor-mode-hook
#'mail-abbrevs-setup)
(advice-add #'mail-abbrev-in-expansion-header-p
:around
#'always-expand-mail-abbrevs-in-commit-buffer)
(provide 'work-config)
;;; work-config.el ends here