commit 1fdc7a6038d7fbca96de1cfbdccf9abb2d458feb
parent 0f2ea4dcd385766ad63ee6577dd78b2cc6c51158
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Mon, 20 Feb 2023 19:40:14 -0500
text/ed: add :nextword and :nextws
Diffstat:
6 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/fs/doc/text/ed.txt b/fs/doc/text/ed.txt
@@ -130,6 +130,14 @@ Words:
:goright ( n self -- )
Move position right by "n" characters, not crossing line boundaries.
+:nextword ( self -- )
+ If the cursor is on a whitespace, advance it to the next non-whitespace
+ character on the same line, if any. If the cursor is on a non-whitespace,
+ advance to the next whitespace, then to the next non-whitespace.
+
+:nextws ( self -- )
+ Same as :nextword, but switch "whitespace" and "non-whitespace".
+
:find ( str self -- )
Find occurence of "str" in buffer, starting from current position. If found,
position is moved to that occurence. If not, position stays unchanged.
diff --git a/fs/doc/text/ged.txt b/fs/doc/text/ged.txt
@@ -33,6 +33,10 @@ h Go left
j Go down
k Go up
l Go right
+H Go to the beginning of the line
+L Go to the end of the line
+w Advance to next word
+s Advance to next whitespace
i Insert
o Insert line after
O Insert line before
diff --git a/fs/lib/str.fs b/fs/lib/str.fs
@@ -36,12 +36,16 @@ create _buf STR_MAXSZ allot
: rtrimright ( n a u -- a u ) rot - max0 ;
: rtrimleft ( n a u -- a u ) rot tuck - max0 rot> + swap ;
-: rmatch ( c range -- f )
+: rmatch ( c pairs -- f )
>r 8b to@+ V1 >> ( len/2 ) for ( c )
dup 8b to@+ V1 8b to@+ V1 ( c c lo hi )
=><= if drop 1 break then
next ( c ) drop 0 then rdrop ;
+: rfind ( a u pairs -- idx ) >r \ V1=pairs
+ 0 swap for2 ( a ) c@+ V1 rmatch if drop i break then next
+ ( a ) drop -1 then rdrop ;
+
create _ 2 c, ," 09"
: 0-9? ( c -- f ) _ rmatch ;
create _ 4 c, ," AZaz"
diff --git a/fs/tests/lib/str.fs b/fs/tests/lib/str.fs
@@ -16,6 +16,10 @@ S" baz" list sfind -1 #eq
'z' alnum? #
'0' alnum? #
+create _num 2 c, ," 09"
+S" hello" c@+ _num rfind -1 #eq
+S" foo9bar" c@+ _num rfind 3 #eq
+
S" bar" S" foobar" c@+ [str]? 3 #eq
S" baz" S" foobar" c@+ [str]? -1 #eq
S" foo" NULLSTR c@+ [str]? -1 #eq
diff --git a/fs/text/ed.fs b/fs/text/ed.fs
@@ -61,6 +61,16 @@ extends IO struct[ Edbuf
i swap joinpos V1 to pos break then ( -1 ) drop next then ( ) rdrop
else ( idx ) 1+ r> to+ pos then ;
: :find ( str self -- ) swap _findstr strmove :findnext ;
+ create _word 2 c, SPC 1+ c, $ff c,
+ create _ws 2 c, 0 c, SPC c,
+ : _topair ( pair self -- ) >r \ V1=self
+ V1 :cpos 1+ V1 :sel Line :range rtrimleft ( pair a u )
+ rot rfind dup 0>= if 1+ r> to+ pos else drop rdrop then ;
+ : _toword _word swap _topair ;
+ : _tows _ws swap _topair ;
+ : _curchar bi :cpos | :sel Line ptr + c@ ;
+ : :nextword dup _curchar _word rmatch if dup _tows then _toword ;
+ : :nextws dup _curchar _ws rmatch if dup _toword then _tows ;
: _sel$ ( self -- ) 0 swap to pos ;
diff --git a/fs/text/ged.fs b/fs/text/ged.fs
@@ -48,7 +48,7 @@ grid COLS grid LINES * 1- const _maxpos
: _rdln[] rdln :range 1- ;
: _pagerefresh _top _top! ;
-S" qhjklHLifnoOzvD[]:" const KEYS
+S" qhjklHLwsifnoOzvD[]:" const KEYS
KEYS c@ wordtbl handlers
:w _statusline quit ;
:w 1 edbuf :goleft ;
@@ -57,6 +57,8 @@ KEYS c@ wordtbl handlers
:w 1 edbuf :goright ;
:w $ffff edbuf :goleft ;
:w $ffff edbuf :goright ;
+:w edbuf :nextword ;
+:w edbuf :nextws ;
:w _typeline if _rdln[] edbuf :write then _pagerefresh ;
:w _typeline if _rdln[] []>str edbuf :find then ;
:w edbuf :findnext ;