module Editfield(EditField, moveField, replaceField, setFieldDir, getField,getField',
deselectField, getSelection, getLastLineNo, getAft, getBef, getLnoEdge,
createField, dirint, splitnl, nlines) where
import HbcUtils(breakAt)
import Edtypes
--export EditField,newline,nlines,splitnl,
data EditField = F EDirection String String String Int Int
deriving (Eq, Ord)
-- bef sel aft ^ lastlineno
-- lno for selection edge
nlines s = length (filter (== newline) s)
splitnl = breakAt newline
dirint ERight = 1
dirint ELeft = -1
befaft dir bef sel aft =
if dir == ELeft then (bef, sel ++ aft) else (sel ++ bef, aft)
createField s = F ERight [] [] s 0 (nlines s)
getLnoEdge (F dir bef sel aft elno lno) =
(elno, befaft dir bef sel aft)
getBef (F dir bef sel aft elno lno) = bef
getAft (F dir bef sel aft elno lno) = aft
getLastLineNo (F dir bef sel aft elno lno) = lno
getSelection (F dir bef sel aft elno lno) =
if dir == ELeft then sel else reverse sel
deselectField (F dir bef sel aft elno lno) =
let (bef', aft') = befaft dir bef sel aft
in F dir bef' [] aft' elno lno
getField f = reverse (getBef f) ++ getSelection f ++ getAft f
getField' f = (reverse (getBef f),getSelection f,getAft f)
setFieldDir ndir field@(F dir bef sel aft elno lno) =
if ndir == dir then
field
else
let elno' = elno + dirint ndir * nlines sel
in F ndir bef (reverse sel) aft elno' lno
replaceField (F dir bef sel aft elno lno) s =
let linessel = nlines sel
liness = nlines s
elno' = elno + liness - (if dir == ERight then linessel else 0)
lno' = lno + (liness - linessel)
in F ERight (reverse s ++ bef) [] aft elno' lno'
moveField :: IsSelect -> EditField -> EditStopFn -> (EditField,String)
moveField issel (F dir bef sel aft elno lno) sf =
let mo dir' bef' sel' aft' elno' acc sf =
let stop = (F dir' bef' sel' aft' elno' lno, acc)
(b, a) = befaft dir' bef' sel' aft'
in case sf b a of
EdStop -> stop
EdGo wdir sf' ->
let next c dir'' bef'' sel'' aft'' =
let elno'' =
if c == newline then
dirint wdir + elno'
else
elno'
in mo dir'' bef'' sel'' aft'' elno'' (c:acc) sf'
in if wdir == dir' || null sel' then
case wdir of
ELeft -> case bef' of
[] -> stop
c:bef'' -> next c wdir bef'' (c:sel') aft'
ERight -> case aft' of
[] -> stop
c:aft'' -> next c wdir bef' (c:sel') aft''
else
let c:sel'' = sel'
in case dir' of
ELeft -> next c dir' (c:bef') sel'' aft'
ERight -> next c dir' bef' sel'' (c:aft')
(field, acc) = mo dir bef sel aft elno [] sf
in if issel then (field, acc) else (deselectField field, [])