Task

Demonstrate how to achieve movement of the terminal cursor:

 how to move the cursor one position to the left
 how to move the cursor one position to the right
 how to move the cursor up one line (without affecting its horizontal position)
 how to move the cursor down one line (without affecting its horizontal position)
 how to move the cursor to the beginning of the line
 how to move the cursor to the end of the line
 how to move the cursor to the top left corner of the screen
 how to move the cursor to the bottom right corner of the screen


For the purpose of this task, it is not permitted to overwrite any characters or attributes on any part of the screen (so outputting a space is not a suitable solution to achieve a movement to the right).



Handling of out of bounds locomotion
This task has no specific requirements to trap or correct cursor movement beyond the terminal boundaries, so the implementer should decide what behavior fits best in terms of the chosen language.   Explanatory notes may be added to clarify how an out of bounds action would behave and the generation of error messages relating to an out of bounds cursor position is permitted.




--
-- demo\rosetta\Cursor_movement.exw
-- ================================
--
-- These may vary by platform/hardware... (this program is ideal for sorting such things out)
--
constant HOME  = 327,
         END   = 335,
         UP    = 328,
         DOWN  = 336,
         LEFT  = 331,
         RIGHT = 333,
         PGUP  = 329,   -- (goto top left)
         PGDN  = 337    -- (goto bottom right)
 
constant {maxl,maxc} = video_config()[VC_SCRNLINES..VC_SCRNCOLS]
 
procedure move_cursor(integer dy, integer dx)
    integer {l,c} = sq_add(get_position(),{dy,dx})
    if l>=1 and l<=maxl
    and c>=1 and c<=maxc then
        position(l,c)
    end if
end procedure
 
procedure move_to(integer ny=-1, integer nx=-1)
    integer {l,c} = get_position()
    if ny!=-1 then l = ny end if
    if nx!=-1 then c = nx end if
    position(l,c)
end procedure
 
procedure showkey(integer key)
    integer {l,c} = get_position()
    position(2,maxc-5)
    ?key
    position(l,c)
end procedure
 
while 1 do
    integer key = wait_key()
    if key=#1B then exit end if -- escape quits
    showkey(key)
    if    key=HOME  then move_to(nx:=1)     -- home
    elsif key=END   then move_to(nx:=maxc)  -- end
    elsif key=UP    then move_cursor(-1, 0) -- up
    elsif key=DOWN  then move_cursor(+1, 0) -- down
    elsif key=LEFT  then move_cursor( 0,-1) -- left
    elsif key=RIGHT then move_cursor( 0,+1) -- right
    elsif key=PGUP  then move_to(1,1)       -- page_up
    elsif key=PGDN  then move_to(maxl,maxc) -- page_down
    end if
end while
