~vdupras/duskos

d30142337aa8b5cd6a63ae45a41375d3f8f27a72 — Virgil Dupras 13 days ago a1a541c
text/ged: move screen only when selection goes out of it

... rather than keeping selection on the top line of the screen. Now we're
beginning to have something that behaves like a real text editor!
3 files changed, 38 insertions(+), 13 deletions(-)

M fs/doc/tips.txt
M fs/text/ed.fs
M fs/text/ged.fs
M fs/doc/tips.txt => fs/doc/tips.txt +11 -0
@@ 8,3 8,14 @@ and "key" are there) of your init, you can create a fork of it to allow you to
boot to the old init if needed. Example:

    key 'z' = [if] f<< /init2.fs \s [then]

## next

If you want to save yourself some painful debugging sessions, don't ever call a
struct field "next" or, if you do, make sure that this struct doesn't ever
define words in its namespace, otherwise it overrides core's "next" and all hell
breaks loose, sometimes (that's the worst), in subtle ways!

This can happen when describing a structure that is a linked list. Name this
field anything but "next", you probably won't use it anyways as iterating over a
LL is clearer with "llnext" anyways.

M fs/text/ed.fs => fs/text/ed.fs +12 -7
@@ 6,9 6,15 @@
: nspcs ( n -- ) ?dup if >r begin SPC stdout next then ;

struct[ Line
  sfield next
  sfield _next
  sfield cnt
  sfield ptr

  : :itern ( n line -- iter-n line )
    over not if exit then over >r \ V1=asked-n
    swap >r begin ( line )
      dup llnext ?dup if nip else r> r> -^ swap exit then next ( line )
    r> swap ;
]struct

extends IO struct[ Edbuf


@@ 27,10 33,10 @@ extends IO struct[ Edbuf
  : _cbounds ( self -- ) dup cpos over sel Line cnt min swap to cpos ;
  : _sel! ( line self -- ) tuck to sel _cbounds ;
  : :godown ( n self -- )
    over if swap >r dup sel begin ( self line )
        dup llnext if llnext over 1 swap to+ lpos else leave then next
      else nip dup lines then ( self line )
    swap _sel! ;
    over not if 2drop exit then ( n self )
    swap >r dup sel begin ( self line )
      dup llnext if llnext over 1 swap to+ lpos else leave then next
    ( self line ) swap _sel! ;

  : _eol? ( self -- f ) dup cpos swap sel Line cnt = ;
  : _eof? ( self -- f ) dup sel llnext not swap _eol? and ;


@@ 65,8 71,7 @@ extends IO struct[ Edbuf

  : :empty ( self -- )
    dup buf Arena :reset
    0 over to cpos
    dup _newline swap 2dup to lines to sel ;
    dup _newline over to lines _sel$$ ;

  : :new ( -- edbuf )
    Arena :new here ( arena edbuf )

M fs/text/ged.fs => fs/text/ged.fs +15 -6
@@ 9,11 9,20 @@ require /sys/grid.fs
  dup if swap Line ptr over grid :write else nip then ( n )
  grid COLS -^ ?dup if nspcs then grid :spitoff ;

: _spitpage ( -- )
  grid LINES 1- >r 0 edbuf sel begin ( lineno line )
    dup if over grid COLS * over _spitline else over grid :clrline then
    dup if llnext then swap 1+ swap next 2drop
  edbuf cpos grid :pos! ;
: _spitpage ( fromline -- )
  grid LINES 1- >r 0 swap begin ( lineno line )
   dup if over grid COLS * over _spitline else over grid :clrline then
  dup if llnext then swap 1+ swap next 2drop ;

0 value _top
: _top! ( lineno -- )
  dup to _top edbuf lines Line :itern nip _spitpage ;
: _zoom ( -- )
  _top edbuf lpos tuck > if _top! else ( lpos )
    grid LINES 1- - max0 _top over <= if _top! else drop then then ;

: _refresh ( -- )
  _zoom edbuf lpos _top - grid COLS * edbuf cpos + grid :pos! ;

S" qhjklHL[]" const KEYS
KEYS c@ wordtbl handlers


@@ 28,5 37,5 @@ KEYS c@ wordtbl handlers
:w pagesz edbuf :godown ;

: ged begin
    _spitpage key KEYS c@+ [c]? ( idx )
    _refresh key KEYS c@+ [c]? ( idx )
    dup 0>= if handlers swap wexec else drop then again ;
\ No newline at end of file