URI: 
       ed: Add the x and X commands - sbase - suckless unix tools
  HTML git clone git://git.suckless.org/sbase
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 77f8d7e5934c146d047c6c38b97067ae046268d9
   DIR parent 5765a6e6b434ce692a15ed2e64bc2ea0d1c5a2e1
  HTML Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
       Date:   Sat, 13 Dec 2025 12:51:11 +0100
       
       ed: Add the x and X commands
       
       These are extensions to the POSIX standard but very useful
       in situations like writing a commit message where the exit
       status can discard the full edit session.
       
       Diffstat:
         M ed.1                                |      19 ++++++++++++++++---
         M ed.c                                |       9 +++++++++
         A tests/0019-ed.sh                    |      18 ++++++++++++++++++
         A tests/0020-ed.sh                    |      19 +++++++++++++++++++
       
       4 files changed, 62 insertions(+), 3 deletions(-)
       ---
   DIR diff --git a/ed.1 b/ed.1
       @@ -216,6 +216,16 @@ instead.
        .It (.+1)
        An address without a command prints the addressed line.
        Sets the dot to that line.
       +.It (1,$)x file
       +Like the w command
       +but after saving the file
       +it exits with an exit status of 0
       +independently of previous errors.
       +.It (1,$)X file
       +Like the W command
       +but after saving the file
       +it exits with an exit status of 0
       +independently of previous errors.
        .It (+) Ns Ic z Ns Ar n
        Scrolls
        .Ar n
       @@ -273,6 +283,9 @@ The dot is unchanged.
        POSIX.1-2013.
        Except where noted here:
        g and v operate on single commands rather than lists delimited with '\e'.
       -The command
       -.Cm z
       -is an extension to that specification.
       +The command,
       +.Cm z ,
       +.Cm x ,
       +and
       +.Cm X
       +are an extension to that specification.
   DIR diff --git a/ed.c b/ed.c
       @@ -1431,6 +1431,15 @@ repeat:
                        chkprint(1);
                        optprompt ^= 1;
                        break;
       +        case 'x':
       +                trunc = 1;
       +        case 'X':
       +                ensureblank();
       +                if (nlines > 0)
       +                        goto unexpected;
       +                exstatus = 0;
       +                deflines(nextln(0), lastln);
       +                dowrite(getfname(cmd), trunc);
                case 'Q':
                case 'q':
                        if (nlines > 0)
   DIR diff --git a/tests/0019-ed.sh b/tests/0019-ed.sh
       @@ -0,0 +1,18 @@
       +#!/bin/sh
       +tmp=tmp.$$
       +
       +trap 'rm -f $tmp' EXIT
       +trap 'rm -f $tmp; kill -KILL $$' HUP INT TERM
       +
       +set -e
       +
       +../ed -s $tmp <<EOF >/dev/null
       +a
       +1
       +2
       +.
       +5d
       +x
       +EOF
       +
       +printf '1\n2\n' | diff -u $tmp -
   DIR diff --git a/tests/0020-ed.sh b/tests/0020-ed.sh
       @@ -0,0 +1,19 @@
       +#!/bin/sh
       +tmp=tmp.$$
       +
       +trap 'rm -f $tmp' EXIT
       +trap 'rm -f $tmp; kill -KILL $$' HUP INT TERM
       +
       +set -e
       +
       +../ed -s $tmp <<EOF >/dev/null
       +a
       +1
       +2
       +.
       +w
       +5d
       +X
       +EOF
       +
       +printf '1\n2\n1\n2\n' | diff -u $tmp -