unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#62892: proposal to extend mark-sexp to go forward and backward on command
@ 2023-04-17  2:25 Zachary Kanfer
  2023-04-17  3:06 ` Ruijie Yu via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-04-17  7:11 ` Juri Linkov
  0 siblings, 2 replies; 43+ messages in thread
From: Zachary Kanfer @ 2023-04-17  2:25 UTC (permalink / raw)
  To: 62892


[-- Attachment #1.1: Type: text/plain, Size: 1218 bytes --]

C-M-@ is bound to `#'mark-sexp`. This command works incrementally -- that
is, calling this once marks the sexp after point; calling it again marks
one more sexp (in total, the two sexps after point).

It would be convenient to easily be able to mark sexps backwards as well.

If you've already marked sexps backwards, mark-sexp extends the region
backwards. But if you haven't, the only way to mark backwards is to pass a
negative prefix argument.

It often is a better experience to iteratively select the sexps you want.
Finally, there's no way to mark both directions, e.g., one sexp forward and
two backwards.

Attached is a patch to add #'mark-sexp-forwards and #'mark-sexp-backwards.
These functions extend the region by sexps forward and backward. They are
mutually incremental: you can call mark-sexp-fowards, then
mark-sexp-backwards twice, then mark-sexp-forwards. After this, the region
will consist of the two sexps before point and the two sexps after point.

These functions are very similar to #'mark-sexp:
- They will extend the region if it already exists.
- They can be called from lisp code with a numeric argument.
- They can take a prefix argument if called interactively.

Thanks,
Zachary Kanfer

[-- Attachment #1.2: Type: text/html, Size: 1356 bytes --]

[-- Attachment #2: 0001-Add-mark-sexp-forward-mark-sexp-backward.patch --]
[-- Type: text/x-patch, Size: 2967 bytes --]

From 3a35790a79eff3d597e13a17d740357bc556d81e Mon Sep 17 00:00:00 2001
From: Zachary Kanfer <zkanfer@gmail.com>
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.
+
 \f
 * 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


^ permalink raw reply related	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2023-06-01  6:32 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-17  2:25 bug#62892: proposal to extend mark-sexp to go forward and backward on command Zachary Kanfer
2023-04-17  3:06 ` Ruijie Yu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-04-20  5:25   ` Zachary Kanfer
2023-04-20  7:16     ` Eli Zaretskii
2023-04-21  5:04       ` Zachary Kanfer
2023-04-21  6:07         ` Eli Zaretskii
2023-04-21  7:24           ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-04-21  9:51           ` Visuwesh
2023-04-21 13:10   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-04-23  5:33     ` Zachary Kanfer
2023-04-25 22:26       ` Daniel Martín via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-04-26  4:41         ` Zachary Kanfer
2023-04-26  6:28           ` Eli Zaretskii
2023-04-27  2:37             ` Zachary Kanfer
2023-04-27 12:25               ` Eli Zaretskii
2023-04-27 18:12                 ` Juri Linkov
2023-04-28  5:28                   ` Zachary Kanfer
2023-05-06  8:49                   ` Eli Zaretskii
2023-04-28 17:04       ` Juri Linkov
2023-04-28 19:28         ` Drew Adams
2023-05-04  4:48           ` Zachary Kanfer
2023-05-08 12:28             ` Zachary Kanfer
2023-05-18  3:17               ` Zachary Kanfer
2023-05-18  6:52                 ` Eli Zaretskii
2023-05-21  5:46                   ` Zachary Kanfer
2023-05-21  5:58                     ` Eli Zaretskii
2023-05-21 14:31                       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-21 14:39                         ` Eli Zaretskii
2023-05-21 14:54                           ` Eli Zaretskii
2023-05-21 14:56                         ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-21 15:11                           ` Eli Zaretskii
2023-05-21 15:41                             ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-22 22:02                 ` Richard Stallman
2023-05-23 14:11                   ` Zachary Kanfer
2023-05-25 22:32                     ` Richard Stallman
2023-05-26  6:06                       ` Eli Zaretskii
2023-05-31  3:23                         ` Zachary Kanfer
2023-05-31 12:01                           ` Eli Zaretskii
2023-06-01  3:54                             ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-06-01  6:32                               ` Eli Zaretskii
2023-05-03  6:10         ` Zachary Kanfer
2023-05-03 17:29           ` Juri Linkov
2023-04-17  7:11 ` Juri Linkov

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).