commit d542daa9f47c109b34807290fe27d2a590a5867c
parent 271cad9631fff8eb474414e286d6f014d2d61b19
Author: andsy10 <andsy1016@gmail.com>
Date: Fri, 16 Oct 2026 05:29:19 +0800
Replace expand-region with hui-select-based expand commands
Diffstat:
5 files changed, 170 insertions(+), 41 deletions(-)
diff --git a/lisp/init-edit.el b/lisp/init-edit.el
@@ -23,6 +23,22 @@
:hook
(after-init . global-subword-mode))
+;; repeat
+(my-use-package repeat
+ :straight nil
+ :config
+ (setq eshell-prompt-repeat-map nil
+ eshell-command-repeat-map nil
+ comint-repeat-map nil
+ shell-repeat-map nil
+ other-window-repeat-map nil
+ rotate-windows-repeat-map nil
+ window-layout-rotate-repeat-map nil
+ ghostel-prompt-repeat-map nil
+ org-navigation-repeat-map nil
+ outline-navigation-repeat-map nil
+ jinx-repeat-map nil))
+
;; show where your are
(my-use-package which-func
:straight nil
@@ -68,15 +84,6 @@
:config
(setq kmacro-x-mc-live-preview t))
-;; expand-region
-(my-use-package expand-region
- :commands
- (er/mark-symbol er/mark-word)
- :config
- (setq expand-region-smart-cursor t)
- (setq expand-region-reset-fast-key "r")
- (setq expand-region-contract-fast-key "c"))
-
;; pinyinlib
(my-use-package pinyinlib
:autoload pinyinlib-build-regexp-string
diff --git a/lisp/init-kbd-func.el b/lisp/init-kbd-func.el
@@ -15,6 +15,38 @@
(or (find-file custom-file)
(user-error "No custom file")))
+(defun my-bounds-of-next-thing (thing)
+ "Return the bounds of THING at or after point."
+ (or (bounds-of-thing-at-point thing)
+ (save-excursion (ignore-errors (forward-thing thing 1))
+ (bounds-of-thing-at-point thing))))
+
+(defun my-bounds-of-symbol-at-point-or-next-sexp ()
+ (let* ((symbol (my-bounds-of-next-thing 'symbol))
+ (sexp (my-bounds-of-next-thing 'sexp))
+ (at-point-p (bounds-of-thing-at-point 'symbol)))
+ (if at-point-p
+ symbol
+ sexp)))
+
+(defun my-mark-sexp-hack (&optional arg allow-extend)
+ (unless (and allow-extend
+ (or (and (eq last-command this-command) (mark t))
+ (and transient-mark-mode mark-active)))
+ (when-let* ((bounds (or (my-bounds-of-symbol-at-point-or-next-sexp)
+ (bounds-of-thing-at-point 'sexp)))
+ (pos (car bounds)))
+ (goto-char pos))))
+(advice-add #'mark-sexp :before #'my-mark-sexp-hack)
+
+(defun my-mark-word-hack (&optional arg allow-extend)
+ (unless (and allow-extend
+ (or (and (eq last-command this-command) (mark t))
+ (region-active-p)))
+ (when-let* ((pos (car (my-bounds-of-next-thing 'word))))
+ (goto-char pos))))
+(advice-add #'mark-word :before #'my-mark-word-hack)
+
;; from Bozhidar Batsov's crux
(defun my-kill-line-backwards ()
"Kill line backwards and adjust the indentation."
diff --git a/lisp/init-kbd.el b/lisp/init-kbd.el
@@ -38,9 +38,7 @@
"M-N" #'drag-stuff-down
"M-F" #'drag-stuff-right
"M-B" #'drag-stuff-left
- [remap mark-sexp] #'er/mark-symbol
- [remap mark-word] #'er/mark-word
- "C-c e" #'er/expand-region
+ "C-c e" #'my-hui-er/expand
"M-z" #'avy-zap-to-char-dwim
"M-Z" #'avy-zap-up-to-char-dwim
"C-<" #'kmacro-x-mc-mark-previous
@@ -86,6 +84,7 @@
;; other
"C-h h" #'hyperbole
+ "C-c /" #'hui-search-web
"M-RET" #'my-hkey-either-lazy
"C-;" #'embark-act
"M-s M-b" #'eww-list-bookmarks
diff --git a/lisp/init-package.el b/lisp/init-package.el
@@ -408,17 +408,102 @@ Prefix ARG controls sort order, see `proced-sort-interactive'."
;; hyperbole
(my-use-package hyperbole
+ :commands hui-search-web
:straight
(hyperbole :type git :host github :repo "rswgnu/hyperbole")
- :defer 5
:delight
(hywiki-mode nil hywiki)
(hyperbole-mode nil hyperbole)
- :bind
- (("C-h h" . hyperbole))
+ :init
+ (defun my-hkey-either-lazy (&optional arg)
+ (interactive "P")
+ (require 'hyperbole)
+ (hyperbole-mode 1)
+ (keymap-global-unset "M-RET")
+ (hkey-either arg))
+
+ ;; a very interesting part
+ ;; not as trusty as original expand-region though
+ (defvar my-hui-er/history nil)
+
+ (defvar my-hui-er/original-point nil)
+
+ (defun my-hui-er/snapshot ()
+ "Return a copy of current hui-select state, or nil."
+ (when hui-select-region
+ (cons hui-select-previous
+ (cons (car hui-select-region) (cdr hui-select-region)))))
+
+ (defun my-hui-er/select (start end type)
+ "Select START to END as thing TYPE and update hui-select state."
+ (setq hui-select-previous type)
+ (hui-select-set-region start end)
+ (goto-char start)
+ (set-mark end)
+ (activate-mark))
+
+ (defun my-hui-er/expand ()
+ "Select the syntactical thing at point."
+ (interactive)
+ (require 'hyperbole)
+ (when (not (use-region-p))
+ (setq my-hui-er/history nil
+ my-hui-er/original-point (point))
+ (hui-select-reset))
+ (let ((snap (my-hui-er/snapshot)))
+ (hui-select-thing)
+ (if (not (equal snap (my-hui-er/snapshot)))
+ (progn
+ (when snap (push snap my-hui-er/history))
+ (goto-char (car hui-select-region))
+ (set-mark (cdr hui-select-region))
+ (activate-mark)
+ (message "%s" hui-select-previous))
+ (message "(hui-er): `%s' is the largest selectable region" hui-select-previous))))
+
+ (defun my-hui-er/contract ()
+ "Shrink region back to the previous selection."
+ (interactive)
+ (if-let* ((top (pop my-hui-er/history))
+ (start (cadr top))
+ (end (cddr top))
+ (type (car top)))
+ (progn (my-hui-er/select start end type)
+ (message "%s" hui-select-previous))
+ (my-hui-er/reset t)
+ (message "(hui-er): `%s' is the smallest selectable region" hui-select-previous)))
+
+ (defun my-hui-er/reset (&optional silent)
+ "Restore original point, clear history."
+ (interactive)
+ (setq my-hui-er/history nil)
+ (when my-hui-er/original-point
+ (goto-char my-hui-er/original-point))
+ (deactivate-mark)
+ (hui-select-reset)
+ (unless silent
+ (message "(hui-er): selection reset")))
+
+ (defun my-hui-er/quit-hack ()
+ (when (and (region-active-p)
+ (or (eq last-command #'my-hui-er/expand)
+ (eq last-command #'my-hui-er/contract)))
+ (my-hui-er/reset t)))
+ (advice-add #'keyboard-quit :before #'my-hui-er/quit-hack)
+
+ (defvar-keymap my-hui-er-repeat-map
+ :repeat t
+ "e" #'my-hui-er/expand
+ "c" #'my-hui-er/contract
+ "r" #'my-hui-er/reset)
+ (put 'my-hui-er/expand 'repeat-map 'my-hui-er-repeat-map)
+ (put 'my-hui-er/contract 'repeat-map 'my-hui-er-repeat-map)
+ (put 'my-hui-er/reset 'repeat-map 'my-hui-er-repeat-map)
+
:config
(setq hsys-org-enable-smart-keys :buttons)
- (hyperbole-mode 1))
+ (hyperbole-mode 1)
+ (repeat-mode 1))
;; elfeed
(my-use-package elfeed my-enable-unessentials
diff --git a/lisp/init-terminal.el b/lisp/init-terminal.el
@@ -213,29 +213,37 @@ there's a region, all lines that region covers will be duplicated."
(setq end (point)))
(goto-char (+ origin (* (length region) arg) arg))))
-(defun er/looking-back-on-line (regexp)
- "Version of `looking-back' that only checks current line."
- (looking-back regexp (line-beginning-position)))
-
-(defun er/mark-symbol ()
- "Mark the entire symbol around or in front of point."
- (interactive)
- (let ((symbol-regexp "\\s_\\|\\sw"))
- (when (or (looking-at symbol-regexp)
- (er/looking-back-on-line symbol-regexp))
- (skip-syntax-forward "_w")
- (set-mark (point))
- (skip-syntax-backward "_w"))))
-
-(defun er/mark-word ()
- "Mark the entire word around or in front of point."
- (interactive)
- (let ((word-regexp "\\sw"))
- (when (or (looking-at word-regexp)
- (er/looking-back-on-line word-regexp))
- (skip-syntax-forward "w")
- (set-mark (point))
- (skip-syntax-backward "w"))))
+(defun my-bounds-of-next-thing (thing)
+ "Return the bounds of THING at or after point."
+ (or (bounds-of-thing-at-point thing)
+ (save-excursion (ignore-errors (forward-thing thing 1))
+ (bounds-of-thing-at-point thing))))
+
+(defun my-bounds-of-symbol-at-point-or-next-sexp ()
+ (let* ((symbol (my-bounds-of-next-thing 'symbol))
+ (sexp (my-bounds-of-next-thing 'sexp))
+ (at-point-p (bounds-of-thing-at-point 'symbol)))
+ (if at-point-p
+ symbol
+ sexp)))
+
+(defun my-mark-sexp-hack (&optional arg allow-extend)
+ (unless (and allow-extend
+ (or (and (eq last-command this-command) (mark t))
+ (and transient-mark-mode mark-active)))
+ (when-let* ((bounds (or (my-bounds-of-symbol-at-point-or-next-sexp)
+ (bounds-of-thing-at-point 'sexp)))
+ (pos (car bounds)))
+ (goto-char pos))))
+(advice-add #'mark-sexp :before #'my-mark-sexp-hack)
+
+(defun my-mark-word-hack (&optional arg allow-extend)
+ (unless (and allow-extend
+ (or (and (eq last-command this-command) (mark t))
+ (region-active-p)))
+ (when-let* ((pos (car (my-bounds-of-next-thing 'word))))
+ (goto-char pos))))
+(advice-add #'mark-word :before #'my-mark-word-hack)
;; scratch buffer
(if (eq system-type 'darwin)
@@ -264,8 +272,6 @@ there's a region, all lines that region covers will be duplicated."
(keymap-global-set "M-l" #'downcase-dwim)
(keymap-global-set "C-," #'my-duplicate-current-line-or-region)
(keymap-global-set "M-y" #'yank-from-kill-ring)
-(keymap-global-set "C-M-@" #'er/mark-symbol)
-(keymap-global-set "M-@" #'er/mark-word)
(keymap-global-set "C-M-h" #'backward-kill-sexp)
(keymap-global-set "C-c k" #'comment-line)