bug#81342: [PATCH] viper-cmd: Simplify quoting by using comment-region

Joshua Murphy <[email protected]> Wed, 05 Aug 2026 21:41:24 +0000
Newsgroups gmane.emacs.bugs
Message-ID <[email protected]>
> But maybe we could do double-comma?  Is that compatible with Viper's
> existing use of commas?

The current command for comma is viper-repeat-find-opposite which
doesn't take any movements, so turning it into a prefix wouldn't work
very well.

> I think it's worth investigating this possibility further, too.

I came up with a rough patch for it that's not too invasive (attached).
It keeps the buffer search working while adding the comment
functionality.
There's a different way to implement it by changing viper-prefix-arg-com,
but it required a lot of gross code changes. I think using a function
for the prefix is the better way of doing it.

-- 
Joshua Murphy
[email protected]
0001-viper-cmd-add-buffer-prefix.patch (text/x-patch, 3.6 KB)
From 9420e3e3ecf5fbc7250b652adbc6adc6110eeae4 Mon Sep 17 00:00:00 2001
From: Joshua Murphy <[email protected]>
Date: Wed, 22 Jul 2026 15:34:54 -0400
Subject: [PATCH] viper-cmd: add buffer prefix

* lisp/emulation/viper-cmd.el (viper-prefix-arg-com):
Remove viper-buffer-search-char commands
(viper-buffer-search-enable):
Use viper-buffer-prefix for viper-buffer-search-char command
(viper-buffer-prefix):
Add prefix for viper-buffer-search-char
---
 lisp/emulation/viper-cmd.el | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el
index 3cbdcddac0a..04fb822b930 100644
--- a/lisp/emulation/viper-cmd.el
+++ b/lisp/emulation/viper-cmd.el
@@ -1035,8 +1035,7 @@ as a Meta key and any number of multiple escapes are allowed."
 	cmd-to-exec-at-end)
     (while (and cont
                 (memq char
-                      (list ?c ?d ?y ?! ?< ?> ?= ?# ?r ?R ?\"
-                            viper-buffer-search-char)))
+                      (list ?c ?d ?y ?! ?< ?> ?= ?# ?r ?R ?\")))
       (if com
 	  ;; this means that we already have a command character, so we
 	  ;; construct a com list and exit while.  however, if char is "
@@ -1083,7 +1082,6 @@ as a Meta key and any number of multiple escapes are allowed."
 	      (viper-digit-command-p char)
 	      (viper-regsuffix-command-p char)
 	      (viper= char ?!) ; bang command
-	      (viper= char ?g) ; the gg command (like G0)
 	      (user-error viper-ViperBell))
 	  (setq cmd-to-exec-at-end
 		(viper-exec-form-in-vi
@@ -1116,8 +1114,6 @@ as a Meta key and any number of multiple escapes are allowed."
 	 ((equal com '(?> . ?>)) (viper-line (cons value ?>)))
 	 ((equal com '(?! . ?!)) (viper-line (cons value ?!)))
 	 ((equal com '(?= . ?=)) (viper-line (cons value ?=)))
-	 ;; gg  acts as G0
-	 ((equal (car com) ?g)   (viper-goto-line 0))
 	 (t (user-error viper-ViperBell)))))
 
     (if cmd-to-exec-at-end
@@ -3774,7 +3770,7 @@ Null string will repeat previous search."
 	   (char-to-string viper-buffer-search-char))
           (t (error "viper-buffer-search-char: Wrong value type, %S"
 		    viper-buffer-search-char)))
-    #'viper-command-argument)
+    #'viper-buffer-prefix)
   (aset viper-exec-array viper-buffer-search-char #'viper-exec-buffer-search)
   (setq viper-prefix-commands
 	(cons viper-buffer-search-char viper-prefix-commands)))
@@ -4239,6 +4235,30 @@ type \\[help-command] at that time."
 	  (t (user-error viper-ViperBell))
 	  )))
 
+(defun viper-buffer-prefix (arg)
+  "Do buffer prefix command with ARG."
+  (interactive "P")
+  (let ((char (read-char)))
+    (cond ((viper= char ?g)
+           (viper-goto-line (or arg 1)))
+          ((viper= char ?c)
+           (let ((movement (read-char)))
+             (if (viper-movement-command-p movement)
+                 (progn
+                   (push-mark nil t t)
+                   (funcall (viper-exec-form-in-vi
+                             `(key-binding (char-to-string ,movement)))
+                            arg)
+                   (comment-region (region-beginning) (region-end)))
+               (user-error viper-ViperBell))))
+          ((viper-movement-command-p char)
+           (setq viper-com-point (point))
+           (funcall (viper-exec-form-in-vi
+                     `(key-binding (char-to-string ,char)))
+                    arg)
+           (viper-exec-buffer-search nil nil))
+          (t (user-error viper-ViperBell)))))
+
 ;; Algorithm: If first invocation of this command save mark on ring, goto
 ;; mark, M0, and pop the most recent elt from the mark ring into mark,
 ;; making it into the new mark, M1.
-- 
2.55.0