From 3a35790a79eff3d597e13a17d740357bc556d81e Mon Sep 17 00:00:00 2001 From: Zachary Kanfer Date: Sun, 16 Apr 2023 22:16:39 -0400 Subject: [PATCH] Add mark-sexp-forward, mark-sexp-backward --- etc/NEWS | 4 ++++ lisp/emacs-lisp/lisp.el | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index c61a9ec3c5f..9f2b7d21f9b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -81,6 +81,10 @@ mistaken compositions, this will now work as well. This works like 'kill-matching-buffers', but without asking for confirmation. +--- +** New commands 'mark-sexp-forward' and 'mark-sexp-backward'. +These work like mark-sexp, but explicitly allow sexps to be marked forward and backward. + * Changes in Specialized Modes and Packages in Emacs 30.1 diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el index 417c218c6d7..d6649b2497d 100644 --- a/lisp/emacs-lisp/lisp.el +++ b/lisp/emacs-lisp/lisp.el @@ -129,6 +129,47 @@ mark-sexp (point)) nil t)))) +(defun mark-sexp-helper (number-of-expressions) + "A helper function for 'mark-sexp-[forward, backward]'. + +If NUMBER-OF-EXPRESSIONS is positive, mark that many sexps forward; +otherwise, amrk backward." + (if (use-region-p) + (let* ((forward (>= number-of-expressions 0)) + (beginning-of-region (region-beginning)) + (end-of-region (region-end)) + (at-end-of-region (= end-of-region (point))) + (new-border-point + (save-excursion + (goto-char (if forward (region-end) (region-beginning))) + (condition-case nil + (forward-sexp number-of-expressions) + (scan-error (user-error "No more s-expressions there!"))) + (point))) + (new-beginning-of-region (min beginning-of-region new-border-point)) + (new-end-of-region (max end-of-region new-border-point))) + (goto-char (if at-end-of-region + new-end-of-region + new-beginning-of-region)) + (set-mark (if at-end-of-region + new-beginning-of-region + new-end-of-region))) + (mark-sexp number-of-expressions))) + +(defun mark-sexp-forward (&optional number-of-expressions) + "Mark NUMBER-OF-EXPRESSIONS s-expressions forward. + + Repeated calls to this mark more s-expressions." + (interactive "p") + (mark-sexp-helper (or number-of-expressions 1))) + +(defun mark-sexp-backward (&optional number-of-expressions) + "Mark NUMBER-OF-EXPRESSIONS s-expressions backward. + + Repeated calls to this mark more s-expressions." + (interactive "p") + (mark-sexp-helper (- (or number-of-expressions 1)))) + (defun forward-list (&optional arg interactive) "Move forward across one balanced group of parentheses. This command will also work on other parentheses-like expressions -- 2.38.4