Hi,

Jason McIntyre writes:
> ok by me. note that posix ex(1) does detail a working [s]ubstitute command,
> so i'm not sure whether we should support this or not.

Hm, so it does. I think I would prefer to follow POSIX in this case.
Here's a diff to allow "substitute" to work.

Annoyingly, there's an ambiguity in the POSIX synopsis (and ours).

     [2addr] s[ubstitute][/pattern/repl/[options][count][flags]]

This implies that "su" could expand to "substitute". But it expands (and
should expand) to "suspend" instead. Since in our vi the first match
always wins, the simplest way to implement this is to use separate ex
commands:

     [2addr] s[/pattern/repl/[options][count][flags]]
     [2addr] sub[stitute][/pattern/repl/[options][count][flags]]

There are already plenty of duplicate commands (e.g., "#"/"nu",
"cd"/"chd", "co"/"t"...) so I think it's an acceptable approach.

Index: docs/USD.doc/vi.man/vi.1
===================================================================
RCS file: /cvs/src/usr.bin/vi/docs/USD.doc/vi.man/vi.1,v
retrieving revision 1.67
diff -u -p -r1.67 vi.1
--- docs/USD.doc/vi.man/vi.1    15 Jun 2017 06:44:47 -0000      1.67
+++ docs/USD.doc/vi.man/vi.1    19 Jun 2017 09:19:23 -0000
@@ -356,7 +356,7 @@ matches the end of the word.
 .It
 .Sq ~
 matches the replacement part of the last
-.Cm substitute
+.Cm s
 command.
 .El
 .Sh BUFFERS
@@ -1996,52 +1996,65 @@ Grow or shrink the current screen.
 Rewind the argument list.
 .Pp
 .It Xo
-.Cm se Ns Op Cm t
+.Op Ar range
 .Sm off
-.Op option Oo = Oo value Oc Oc \ \&...
+.Cm s
+.Oo Cm / Ar pattern Cm / Ar replace Cm /
+.Op Ar options
+.Op Ar count
+.Op Ar flags
+.Oc
 .Sm on
-.Pf \ \& Op nooption ...
-.Op option? ...
-.Op Ar all
-.Xc
-Display or set editor options.
-.Pp
-.It Cm sh Ns Op Cm ell
-Run a shell program.
-.Pp
-.It Xo
-.Cm so Ns Op Cm urce
-.Ar file
 .Xc
-Read and execute
-.Nm ex
-commands from a file.
-.Pp
 .It Xo
 .Op Ar range
-.Cm s Ns Op Cm ubstitute
 .Sm off
-.Op / Ar pattern No / Ar replace  No /
-.Sm on
-.Pf \ \& Op Ar options
+.Cm sub Op Cm stitute
+.Oo Cm / Ar pattern Cm / Ar replace Cm /
+.Op Ar options
 .Op Ar count
 .Op Ar flags
+.Sm on
 .Xc
 .It Xo
 .Op Ar range
+.Sm off
 .Cm &
 .Op Ar options
 .Op Ar count
 .Op Ar flags
+.Sm on
 .Xc
 .It Xo
 .Op Ar range
+.Sm off
 .Cm ~
 .Op Ar options
 .Op Ar count
 .Op Ar flags
+.Sm on
 .Xc
-Make substitutions.
+Substitute the regular expression
+.Ar pattern
+with
+.Ar replace .
+When invoked as
+.Cm & ,
+or if
+.Cm / Ns Ar pattern Ns Cm / Ns Ar replace Ns Cm /
+is omitted,
+.Ar pattern
+and
+.Ar replace
+from the most recent
+.Cm s
+command are used.
+.Cm ~
+behaves like
+.Cm & ,
+except the pattern used is the most recent regular expression used by any
+command.
+.Pp
 The
 .Ar replace
 field may contain any of the following sequences:
@@ -2051,13 +2064,13 @@ The text matched by
 .Ar pattern .
 .It Sq \(a~
 The replacement part of the previous
-.Cm substitute
+.Cm s
 command.
 .It Sq %
 If this is the entire
 .Ar replace
 pattern, the replacement part of the previous
-.Cm substitute
+.Cm s
 command.
 .It Sq \e#
 Where
@@ -2082,6 +2095,40 @@ to be converted to uppercase.
 Causes the next character to be converted to uppercase.
 .El
 .Pp
+The
+.Ar options
+field may contain any of the following characters:
+.Bl -tag -width Ds
+.It Sq c
+Prompt for confirmation before each replacement is done.
+.It Sq g
+Replace all instances of
+.Ar pattern
+in a line, not just the first.
+.El
+.Pp
+.It Xo
+.Cm se Ns Op Cm t
+.Sm off
+.Op option Oo = Oo value Oc Oc \ \&...
+.Sm on
+.Pf \ \& Op nooption ...
+.Op option? ...
+.Op Ar all
+.Xc
+Display or set editor options.
+.Pp
+.It Cm sh Ns Op Cm ell
+Run a shell program.
+.Pp
+.It Xo
+.Cm so Ns Op Cm urce
+.Ar file
+.Xc
+Read and execute
+.Nm ex
+commands from a file.
+.Pp
 .It Xo
 .Cm su Ns Op Cm spend Ns
 .Op Cm !\&
@@ -2291,7 +2338,9 @@ Remember the values of the
 and
 .Sq g
 suffixes to the
-.Cm substitute
+.Cm s , &
+and
+.Cm ~
 commands, instead of initializing them as unset for each new command.
 .It Cm escapetime Bq 1
 The tenths of a second
Index: ex/ex_cmd.c
===================================================================
RCS file: /cvs/src/usr.bin/vi/ex/ex_cmd.c,v
retrieving revision 1.10
diff -u -p -r1.10 ex_cmd.c
--- ex/ex_cmd.c 19 Nov 2015 07:53:31 -0000      1.10
+++ ex/ex_cmd.c 19 Jun 2017 09:19:23 -0000
@@ -288,8 +288,8 @@ EXCMDLIST const cmds[] = {
  * Adding new commands starting with 's' may break the substitute command code
  * in ex_cmd() (the ex parser).  Read through the comments there, first.
  */
-/* C_SUBSTITUTE */
-       {"s",           ex_s,           E_ADDR2,
+/* C_S */
+       {"s",   ex_s,                   E_ADDR2,
            "s",
            "[line [,line]] s [[/;]RE[/;]repl[/;] [cgr] [count] [#lp]]",
            "substitute on lines matching an RE"},
@@ -323,6 +323,11 @@ EXCMDLIST const cmds[] = {
            "!",
            "su[spend][!]",
            "suspend the edit session"},
+/* C_SUBSTITUTE */
+       {"substitute",  ex_s,           E_ADDR2,
+           "s",
+           "[line [,line]] sub[stitute] [[/;]RE[/;]repl[/;] [cgr] [count] 
[#lp]]",
+           "substitute on lines matching an RE"},
 /* C_T */
        {"t",           ex_copy,        E_ADDR2|E_AUTOPRINT,
            "l1",
Index: include/ex_def.h
===================================================================
RCS file: /cvs/src/usr.bin/vi/include/ex_def.h,v
retrieving revision 1.5
diff -u -p -r1.5 ex_def.h
--- include/ex_def.h    19 Nov 2015 07:53:31 -0000      1.5
+++ include/ex_def.h    19 Jun 2017 09:19:23 -0000
@@ -46,31 +46,32 @@
 #define C_RECOVER 43
 #define C_RESIZE 44
 #define C_REWIND 45
-#define C_SUBSTITUTE 46
+#define C_S 46
 #define C_SCRIPT 47
 #define C_SET 48
 #define C_SHELL 49
 #define C_SOURCE 50
 #define C_STOP 51
 #define C_SUSPEND 52
-#define C_T 53
-#define C_TAG 54
-#define C_TAGNEXT 55
-#define C_TAGPOP 56
-#define C_TAGPREV 57
-#define C_TAGTOP 58
-#define C_UNDO 59
-#define C_UNABBREVIATE 60
-#define C_UNMAP 61
-#define C_V 62
-#define C_VERSION 63
-#define C_VISUAL_EX 64
-#define C_VISUAL_VI 65
-#define C_VIUSAGE 66
-#define C_WRITE 67
-#define C_WN 68
-#define C_WQ 69
-#define C_XIT 70
-#define C_YANK 71
-#define C_Z 72
-#define C_SUBTILDE 73
+#define C_SUBSTITUTE 53
+#define C_T 54
+#define C_TAG 55
+#define C_TAGNEXT 56
+#define C_TAGPOP 57
+#define C_TAGPREV 58
+#define C_TAGTOP 59
+#define C_UNDO 60
+#define C_UNABBREVIATE 61
+#define C_UNMAP 62
+#define C_V 63
+#define C_VERSION 64
+#define C_VISUAL_EX 65
+#define C_VISUAL_VI 66
+#define C_VIUSAGE 67
+#define C_WRITE 68
+#define C_WN 69
+#define C_WQ 70
+#define C_XIT 71
+#define C_YANK 72
+#define C_Z 73
+#define C_SUBTILDE 74

Reply via email to