tplumb/basic: avoid wrap around in file:1:2 (#158) - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 73ea36569e83560168cfd7e40d85d9d247bce593
 (DIR) parent a9e66ffa4eb61a4728d536d20f916a5a02ab5626
 (HTM) Author: Martin Kühl <martin.kuehl@gmail.com>
       Date:   Wed, 14 Nov 2018 05:59:04 +0100
       
       plumb/basic: avoid wrap around in file:1:2 (#158)
       
       Fixes #122, #140.
       
       As reported in #122, `file:1:1` moves to the end of the file,
       and `file:1:2` fails with “address out of range”.
       
       I’ll use file:2:3 as an example so we can tell the line and column number apart.
       
       What’s happening is this:
       plumb/basic matches `2:3` using twocolonaddr (from plumb/fileaddr),
       tthen sets addr to `2-#1+#3`
       (the 1 is constant and was introduced because column numbers are 1-based).
       Acme interprets this in three steps:
       
       1. find the range (q0, q1) that contains line 2
       2. create the range (q2, q2) where q2 = q0 - 1
       3. create the range (q3, q3) where q3 = q2 + 3
       
       The second step has a branch where if q0 == 0 and 1 > 0
       (remember that 1 is constant and comes form plumb/basic),
       q0 is set to the end of the file.
       This makes addressing things at the end of the file easier.
       
       The problem then is that if we select line 1,
       which starts at the beginning of the file,
       q0 is always 0 and the branch in step 2) will always be used.
       `1:1` is interpreted as `1-#1+#1` which starts at 0, wraps around to the end of the file, then moves 1 character backwards and then forwards again, ending at the end of the file.
       `1:2` is interpretes as `1-#1+#2` which starts at 0, wraps around to the end od the file, then moves 1 character backwards and tries moving 2 characters forwards beyond the end of the file, resulting in the out of range error.
       
       In #140 @rsc proposed transforming `:X:Y` into `:X-#0+#Y-#1` instead since that
       avoids wrapping around by not moving backwards at first.
       This change modifies `plumb/basic` to do that.
       Diffstat:
         M plumb/basic                         |       4 ++--
       
       1 file changed, 2 insertions(+), 2 deletions(-)
       ---
 (DIR) diff --git a/plumb/basic b/plumb/basic
       t@@ -64,7 +64,7 @@ type is text
        data matches '([.a-zA-Z¡-￿0-9_/\-@]*[a-zA-Z¡-￿0-9_/\-])':$twocolonaddr,$twocolonaddr
        arg isfile     $1
        data set       $file
       -attr add       addr=$2-#1+#$3,$4-#1+#$5
       +attr add       addr=$2-#0+#$3-#1,$4-#0+#$5-#1
        plumb to edit
        plumb client $editor
        
       t@@ -73,7 +73,7 @@ type is text
        data matches '([.a-zA-Z¡-￿0-9_/\-@]*[a-zA-Z¡-￿0-9_/\-])':$twocolonaddr
        arg isfile     $1
        data set       $file
       -attr add       addr=$2-#1+#$3
       +attr add       addr=$2-#0+#$3-#1
        plumb to edit
        plumb client $editor