WEditor 0.2.0.1 → 0.2.0.2
raw patch · 8 files changed
+128/−107 lines, 8 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- WEditor.Base.Editor: type EditorAction c = forall a. FixedFontEditor a c => a -> a
- WEditor.Base.Viewer: type ViewerAction c = forall a. FixedFontViewer a c => a -> a
- WEditor.Document: type ViewerAction c = forall a. FixedFontViewer a c => a -> a
+ WEditor.Base.Editor: type EditorAction c = forall e. FixedFontEditor e c => e -> e
+ WEditor.Base.Viewer: type ViewerAction c = forall v. FixedFontViewer v c => v -> v
+ WEditor.Document: type EditorAction c = forall e. FixedFontEditor e c => e -> e
+ WEditor.Document: type ViewerAction c = forall v. FixedFontViewer v c => v -> v
- WEditor.Base.Editor: breakPara :: FixedFontEditor a c => a -> EditDirection -> a
+ WEditor.Base.Editor: breakPara :: FixedFontEditor e c => e -> EditDirection -> e
- WEditor.Base.Editor: class FixedFontEditor a c | a -> c
+ WEditor.Base.Editor: class FixedFontEditor e c | e -> c
- WEditor.Base.Editor: editText :: FixedFontEditor a c => a -> EditAction c -> EditDirection -> a
+ WEditor.Base.Editor: editText :: FixedFontEditor e c => e -> EditAction c -> EditDirection -> e
- WEditor.Base.Editor: exportData :: FixedFontEditor a c => a -> [UnparsedPara c]
+ WEditor.Base.Editor: exportData :: FixedFontEditor e c => e -> [UnparsedPara c]
- WEditor.Base.Editor: getCursor :: FixedFontEditor a c => a -> (Int, Int)
+ WEditor.Base.Editor: getCursor :: FixedFontEditor e c => e -> (Int, Int)
- WEditor.Base.Editor: getEditPoint :: FixedFontEditor a c => a -> (Int, Int)
+ WEditor.Base.Editor: getEditPoint :: FixedFontEditor e c => e -> (Int, Int)
- WEditor.Base.Editor: getParaCount :: FixedFontEditor a c => a -> Int
+ WEditor.Base.Editor: getParaCount :: FixedFontEditor e c => e -> Int
- WEditor.Base.Editor: getParaSize :: FixedFontEditor a c => a -> Int
+ WEditor.Base.Editor: getParaSize :: FixedFontEditor e c => e -> Int
- WEditor.Base.Editor: moveCursor :: FixedFontEditor a c => a -> MoveDirection -> a
+ WEditor.Base.Editor: moveCursor :: FixedFontEditor e c => e -> MoveDirection -> e
- WEditor.Base.Editor: setEditPoint :: FixedFontEditor a c => a -> (Int, Int) -> a
+ WEditor.Base.Editor: setEditPoint :: FixedFontEditor e c => e -> (Int, Int) -> e
- WEditor.Base.Parser: breakLines :: FixedFontParser a c => a -> [c] -> [VisibleLine c (BreakType a)]
+ WEditor.Base.Parser: breakLines :: FixedFontParser p c => p -> [c] -> [VisibleLine c (BreakType p)]
- WEditor.Base.Parser: class FixedFontParser a c | a -> c where {
+ WEditor.Base.Parser: class FixedFontParser p c | p -> c where {
- WEditor.Base.Parser: emptyLine :: FixedFontParser a c => a -> VisibleLine c (BreakType a)
+ WEditor.Base.Parser: emptyLine :: FixedFontParser p c => p -> VisibleLine c (BreakType p)
- WEditor.Base.Parser: renderLine :: FixedFontParser a c => a -> VisibleLine c (BreakType a) -> [c]
+ WEditor.Base.Parser: renderLine :: FixedFontParser p c => p -> VisibleLine c (BreakType p) -> [c]
- WEditor.Base.Parser: setLineWidth :: FixedFontParser a c => a -> Int -> a
+ WEditor.Base.Parser: setLineWidth :: FixedFontParser p c => p -> Int -> p
- WEditor.Base.Parser: splitLine :: FixedFontParser a c => a -> Int -> VisibleLine c (BreakType a) -> (VisibleLine c (BreakType a), VisibleLine c (BreakType a))
+ WEditor.Base.Parser: splitLine :: FixedFontParser p c => p -> Int -> VisibleLine c (BreakType p) -> (VisibleLine c (BreakType p), VisibleLine c (BreakType p))
- WEditor.Base.Parser: tweakCursor :: FixedFontParser a c => a -> VisibleLine c (BreakType a) -> Int -> Int
+ WEditor.Base.Parser: tweakCursor :: FixedFontParser p c => p -> VisibleLine c (BreakType p) -> Int -> Int
- WEditor.Base.Parser: type family BreakType a :: *;
+ WEditor.Base.Parser: type family BreakType p :: *;
- WEditor.Base.Viewer: class FixedFontViewer a c | a -> c
+ WEditor.Base.Viewer: class FixedFontViewer v c | v -> c
- WEditor.Base.Viewer: getViewSize :: FixedFontViewer a c => a -> (Int, Int)
+ WEditor.Base.Viewer: getViewSize :: FixedFontViewer v c => v -> (Int, Int)
- WEditor.Base.Viewer: getVisible :: FixedFontViewer a c => a -> [[c]]
+ WEditor.Base.Viewer: getVisible :: FixedFontViewer v c => v -> [[c]]
- WEditor.Base.Viewer: setViewSize :: FixedFontViewer a c => a -> (Int, Int) -> a
+ WEditor.Base.Viewer: setViewSize :: FixedFontViewer v c => v -> (Int, Int) -> v
- WEditor.Base.Viewer: updateView :: FixedFontViewer a c => a -> ViewAction -> a
+ WEditor.Base.Viewer: updateView :: FixedFontViewer v c => v -> ViewAction -> v
- WEditor.Document: breakPara :: FixedFontEditor a c => a -> EditDirection -> a
+ WEditor.Document: breakPara :: FixedFontEditor e c => e -> EditDirection -> e
- WEditor.Document: class FixedFontEditor a c | a -> c
+ WEditor.Document: class FixedFontEditor e c | e -> c
- WEditor.Document: class FixedFontParser a c | a -> c
+ WEditor.Document: class FixedFontParser p c | p -> c
- WEditor.Document: class FixedFontViewer a c | a -> c
+ WEditor.Document: class FixedFontViewer v c | v -> c
- WEditor.Document: editText :: FixedFontEditor a c => a -> EditAction c -> EditDirection -> a
+ WEditor.Document: editText :: FixedFontEditor e c => e -> EditAction c -> EditDirection -> e
- WEditor.Document: exportData :: FixedFontEditor a c => a -> [UnparsedPara c]
+ WEditor.Document: exportData :: FixedFontEditor e c => e -> [UnparsedPara c]
- WEditor.Document: getCursor :: FixedFontEditor a c => a -> (Int, Int)
+ WEditor.Document: getCursor :: FixedFontEditor e c => e -> (Int, Int)
- WEditor.Document: getEditPoint :: FixedFontEditor a c => a -> (Int, Int)
+ WEditor.Document: getEditPoint :: FixedFontEditor e c => e -> (Int, Int)
- WEditor.Document: getParaCount :: FixedFontEditor a c => a -> Int
+ WEditor.Document: getParaCount :: FixedFontEditor e c => e -> Int
- WEditor.Document: getParaSize :: FixedFontEditor a c => a -> Int
+ WEditor.Document: getParaSize :: FixedFontEditor e c => e -> Int
- WEditor.Document: getViewSize :: FixedFontViewer a c => a -> (Int, Int)
+ WEditor.Document: getViewSize :: FixedFontViewer v c => v -> (Int, Int)
- WEditor.Document: getVisible :: FixedFontViewer a c => a -> [[c]]
+ WEditor.Document: getVisible :: FixedFontViewer v c => v -> [[c]]
- WEditor.Document: moveCursor :: FixedFontEditor a c => a -> MoveDirection -> a
+ WEditor.Document: moveCursor :: FixedFontEditor e c => e -> MoveDirection -> e
- WEditor.Document: setEditPoint :: FixedFontEditor a c => a -> (Int, Int) -> a
+ WEditor.Document: setEditPoint :: FixedFontEditor e c => e -> (Int, Int) -> e
- WEditor.Document: setViewSize :: FixedFontViewer a c => a -> (Int, Int) -> a
+ WEditor.Document: setViewSize :: FixedFontViewer v c => v -> (Int, Int) -> v
- WEditor.Document: updateView :: FixedFontViewer a c => a -> ViewAction -> a
+ WEditor.Document: updateView :: FixedFontViewer v c => v -> ViewAction -> v
- WEditor.LineWrap: appendHyphen :: WordSplitter a c => a -> [c] -> [c]
+ WEditor.LineWrap: appendHyphen :: WordSplitter s c => s -> [c] -> [c]
- WEditor.LineWrap: breakWords :: (Show a, WordSplitter a c) => a -> BreakWords c
+ WEditor.LineWrap: breakWords :: (Show s, WordSplitter s c) => s -> BreakWords c
- WEditor.LineWrap: class WordSplitter a c | a -> c
+ WEditor.LineWrap: class WordSplitter s c | s -> c
- WEditor.LineWrap: isWhitespace :: WordSplitter a c => a -> c -> Bool
+ WEditor.LineWrap: isWhitespace :: WordSplitter s c => s -> c -> Bool
- WEditor.LineWrap: isWordChar :: WordSplitter a c => a -> c -> Bool
+ WEditor.LineWrap: isWordChar :: WordSplitter s c => s -> c -> Bool
- WEditor.LineWrap: splitWord :: WordSplitter a c => a -> Int -> Int -> [c] -> Maybe [Int]
+ WEditor.LineWrap: splitWord :: WordSplitter s c => s -> Int -> Int -> [c] -> Maybe [Int]
Files
- WEditor.cabal +4/−1
- WEditor/Base/Editor.hs +25/−22
- WEditor/Base/Parser.hs +21/−13
- WEditor/Base/Viewer.hs +13/−9
- WEditor/Document.hs +11/−13
- WEditor/Internal/Para.hs +10/−12
- WEditor/LineWrap.hs +11/−8
- test/TestDocument.hs +33/−29
WEditor.cabal view
@@ -1,5 +1,5 @@ name: WEditor-version: 0.2.0.1+version: 0.2.0.2 synopsis: Generic text-editor logic for use with fixed-width fonts. description:@@ -12,6 +12,9 @@ * Customizable line-wrapping policies and word-hyphenation policies. * Automatic management of a dynamically-sized viewable area. * Support for novel character types.+ .+ Also see @<http://hackage.haskell.org/package/WEditorHyphen WEditorHyphen>@+ for language-specific hyphenation rules. homepage: https://github.com/ta0kira/wrapping-editor license: Apache-2.0
WEditor/Base/Editor.hs view
@@ -49,29 +49,32 @@ -- | Generic text editor for fixed-width fonts.-class FixedFontEditor a c | a -> c where+--+-- * @e@: Editor type providing the operations.+-- * @c@: Character type.+class FixedFontEditor e c | e -> c where -- | Apply an edit action.- editText :: a -> EditAction c -> EditDirection -> a+ editText :: e -> EditAction c -> EditDirection -> e -- | Break the current paragraph at the cursor.- breakPara :: a -> EditDirection -> a- -- | Apply a cursor movement.- moveCursor :: a -> MoveDirection -> a- -- | Get the (row,col) cursor position relative to the viewport.- getCursor :: a -> (Int,Int)- -- | Get the absolute (paragraph,char) edit position.+ breakPara :: e -> EditDirection -> e+ -- | Apply e cursor movement.+ moveCursor :: e -> MoveDirection -> e+ -- | Get the @(row,col)@ cursor position relative to the viewport.+ getCursor :: e -> (Int,Int)+ -- | Get the absolute @(paragraph,char)@ edit position. -- -- The position can be restored after cursor movements by calling -- 'setEditPoint'; however, calling 'editText' or 'breakPara' invalidates -- this position.- getEditPoint :: a -> (Int,Int)- -- | Set the absolute (paragraph,char) edit position.- setEditPoint :: a -> (Int,Int) -> a+ getEditPoint :: e -> (Int,Int)+ -- | Set the absolute @(paragraph,char)@ edit position.+ setEditPoint :: e -> (Int,Int) -> e -- | Get the number of characters in the current paragraph.- getParaSize :: a -> Int+ getParaSize :: e -> Int -- | Get the number of paragraphs in the document.- getParaCount :: a -> Int+ getParaCount :: e -> Int -- | Export the modified data.- exportData :: a -> [UnparsedPara c]+ exportData :: e -> [UnparsedPara c] -- | Actions that modify data. data EditAction c =@@ -98,17 +101,17 @@ deriving (Eq,Show) -- | Any action that updates a 'FixedFontEditor'.-type EditorAction c = forall a. FixedFontEditor a c => a -> a+type EditorAction c = forall e. FixedFontEditor e c => e -> e --- | Action for the Backspace key.+-- | Action for the @Backspace@ key. editorBackspaceAction :: EditorAction c editorBackspaceAction e = editText e DeleteText EditBefore --- | Action for the Delete key.+-- | Action for the @Delete@ key. editorDeleteAction :: EditorAction c editorDeleteAction e = editText e DeleteText EditAfter --- | Action for the Enter key.+-- | Action for the @Enter@ key. editorEnterAction :: EditorAction c editorEnterAction e = breakPara e EditBefore @@ -140,18 +143,18 @@ editorRightAction :: EditorAction c editorRightAction e = moveCursor e MoveNext --- | Action for the Home key.+-- | Action for the @Home@ key. editorHomeAction :: EditorAction c editorHomeAction e = moveCursor e MoveHome --- | Action for the End key.+-- | Action for the @End@ key. editorEndAction :: EditorAction c editorEndAction e = moveCursor e MoveEnd --- | Action for the PageUp key.+-- | Action for the @PageUp@ key. editorPageUpAction :: EditorAction c editorPageUpAction e = moveCursor e MovePageUp --- | Action for the PageDown key.+-- | Action for the @PageDown@ key. editorPageDownAction :: EditorAction c editorPageDownAction e = moveCursor e MovePageDown
WEditor/Base/Parser.hs view
@@ -32,33 +32,41 @@ -- | Line parser for fixed-width fonts.-class FixedFontParser a c | a -> c where+--+-- * @p@: Parser type providing the operations.+-- * @c@: Character type.+class FixedFontParser p c | p -> c where -- | Type used to differentiate between line-break types.- type BreakType a :: *+ type BreakType p :: * -- | Change the max line width used for parsing. A width of zero must result -- in breakLines skipping line breaks.- setLineWidth :: a -> Int -> a+ setLineWidth :: p -> Int -> p -- | Break the sequence into lines. -- -- The following must hold for all possible inputs to a 'FixedFontParser'- -- `p`:+ -- @p@: --- -- prop> concat (map vlText (breakLines p line)) == line+ -- prop> concat (map vlText (breakLines p l)) == l -- -- Implement 'renderLine' and 'tweakCursor' to make visual adjustments (such -- as adding hyphens or indentation) if necessary.- breakLines :: a -> [c] -> [VisibleLine c (BreakType a)]+ breakLines :: p -> [c] -> [VisibleLine c (BreakType p)] -- | A place-holder line for empty paragraphs.- emptyLine :: a -> VisibleLine c (BreakType a)+ emptyLine :: p -> VisibleLine c (BreakType p) -- | Render the line for viewing. Implement 'tweakCursor' if 'renderLine' -- changes the positions of any characters on the line.- renderLine :: a -> VisibleLine c (BreakType a) -> [c]+ renderLine :: p -> VisibleLine c (BreakType p) -> [c] -- | Adjust the horizontal cursor position.- tweakCursor :: a -> VisibleLine c (BreakType a) -> Int -> Int+ tweakCursor :: p -> VisibleLine c (BreakType p) -> Int -> Int tweakCursor _ _ = id -- | Split the line to create a paragraph break.- splitLine :: a+ --+ -- The following must hold for all possible inputs to a 'FixedFontParser'+ -- @p@:+ --+ -- prop> let (b,t) = splitLine p n l in vlText l == vlText b ++ vlText t+ splitLine :: p -> Int -- ^ Index to split at.- -> VisibleLine c (BreakType a) -- ^ Line to split.- -> (VisibleLine c (BreakType a),- VisibleLine c (BreakType a)) -- ^ End of original paragraph and beginning of next paragraph.+ -> VisibleLine c (BreakType p) -- ^ Line to split.+ -> (VisibleLine c (BreakType p),+ VisibleLine c (BreakType p)) -- ^ New lines at @(bottom,top)@ of previous/next paragraphs.
WEditor/Base/Viewer.hs view
@@ -35,17 +35,20 @@ -- | Generic editor viewport for fixed-width fonts.-class FixedFontViewer a c | a -> c where- -- | Set the (width,height) size of the viewport. A width < 0 must disable- -- line wrapping, and a height < 0 must disable vertical bounding.- setViewSize :: a -> (Int,Int) -> a- -- | Get the (width,height) size of the viewport.- getViewSize :: a -> (Int,Int)+--+-- * @v@: Viewer type providing the operations.+-- * @c@: Character type.+class FixedFontViewer v c | v -> c where+ -- | Set the @(width,height)@ size of the viewport. Setting either to @<=0@+ -- disables bounding in that dimension.+ setViewSize :: v -> (Int,Int) -> v+ -- | Get the @(width,height)@ size of the viewport.+ getViewSize :: v -> (Int,Int) -- | Get the visible lines in the viewport. This does not need to completely -- fill the viewport area, but it must not exceed it.- getVisible :: a -> [[c]]+ getVisible :: v -> [[c]] -- | Apply a view change.- updateView :: a -> ViewAction -> a+ updateView :: v -> ViewAction -> v -- | Actions that modify the view without affecting editing. data ViewAction =@@ -54,7 +57,7 @@ deriving (Eq,Show) -- | Any action that updates a 'FixedFontViewer'.-type ViewerAction c = forall a. FixedFontViewer a c => a -> a+type ViewerAction c = forall v. FixedFontViewer v c => v -> v -- | Action to resize the viewport. viewerResizeAction :: (Int,Int) -> ViewerAction c@@ -68,5 +71,6 @@ viewerShiftDownAction :: Int -> ViewerAction c viewerShiftDownAction n v = updateView v (ShiftVertical n) +-- | Action to attempt to fill the viewport. viewerFillAction :: ViewerAction c viewerFillAction v = updateView v FillView
WEditor/Document.hs view
@@ -169,33 +169,31 @@ resizeHeight h da@(EditingDocument bs e as w _ k c p) = (EditingDocument bs e as w h offset c p) where offset- | h < 1 = paraLinesBefore da+ | h < 1 = length $ catLinesBefore $ getBeforeLines e:bs | otherwise = boundOffset h $ min (paraLinesBefore da) k paraLinesBefore :: EditingDocument c -> Int-paraLinesBefore (EditingDocument bs e _ _ _ _ _ _) = total where- total = countLinesBefore bs'+paraLinesBefore (EditingDocument bs e _ _ h _ _ _) = total where+ total = countLinesBefore h bs' bs' = getBeforeLines e:bs paraLinesAfter :: EditingDocument c -> Int-paraLinesAfter (EditingDocument _ e as _ _ _ _ _) = total where- total = countLinesAfter as'+paraLinesAfter (EditingDocument _ e as _ h _ _ _) = total where+ total = countLinesAfter h as' as' = getAfterLines e:as getVisibleLines :: EditingDocument c -> [[c]] getVisibleLines (EditingDocument bs e as _ h k _ p) = visible where visible = map (renderLine p) $ bs2 ++ [e2] ++ as2- bs2 = takeLinesBefore getBefore before+ bs2+ | h < 1 = reverse $ catLinesBefore before+ | otherwise = reverse $ take (boundOffset h k) $ catLinesBefore before e2 = getCurrentLine e- as2 = takeLinesAfter getAfter after+ as2+ | h < 1 = catLinesAfter after+ | otherwise = take (h-length bs2-1) $ catLinesAfter after before = getBeforeLines e:bs after = getAfterLines e:as- getBefore- | h < 1 = countLinesBefore before- | otherwise = boundOffset h k- getAfter- | h < 1 = countLinesAfter after- | otherwise = h-length bs2-1 moveDocCursor :: MoveDirection -> EditingDocument c -> EditingDocument c moveDocCursor d da@(EditingDocument bs e as w h k c p) = revised where
WEditor/Internal/Para.hs view
@@ -28,6 +28,8 @@ appendToPara, atParaBack, atParaFront,+ catLinesAfter,+ catLinesBefore, countLinesAfter, countLinesBefore, editPara,@@ -50,8 +52,6 @@ setParaCursorChar, setParaEditChar, splitPara,- takeLinesAfter,- takeLinesBefore, unparsePara, unparseParaAfter, unparseParaBefore,@@ -148,19 +148,17 @@ getAfterLines :: EditingPara c b -> VisibleParaAfter c b getAfterLines = VisibleParaAfter . epAfter -takeLinesBefore :: Int -> [VisibleParaBefore c b] -> [VisibleLine c b]-takeLinesBefore n = reverse . take n . concat . map vpbLines+catLinesBefore :: [VisibleParaBefore c b] -> [VisibleLine c b]+catLinesBefore = concat . map vpbLines -takeLinesAfter :: Int -> [VisibleParaAfter c b] -> [VisibleLine c b]-takeLinesAfter n = take n . concat . map vpaLines+catLinesAfter :: [VisibleParaAfter c b] -> [VisibleLine c b]+catLinesAfter = concat . map vpaLines --- TODO: Add an upper bound, to avoid unnecessary traversal.-countLinesBefore :: [VisibleParaBefore c b] -> Int-countLinesBefore = length . concat . map vpbLines+countLinesBefore :: Int -> [VisibleParaBefore c b] -> Int+countLinesBefore n = length . take n . catLinesBefore --- TODO: Add an upper bound, to avoid unnecessary traversal.-countLinesAfter :: [VisibleParaAfter c b] -> Int-countLinesAfter = length . concat . map vpaLines+countLinesAfter :: Int -> [VisibleParaAfter c b] -> Int+countLinesAfter n = length . take n . catLinesAfter getParaCursorLine :: EditingPara c b -> Int getParaCursorLine = length . epBefore
WEditor/LineWrap.hs view
@@ -68,7 +68,10 @@ instance WordSplitter (NoSplit c) c -- | Word-splitting operations for use with 'BreakWords'.-class WordSplitter a c | a -> c where+--+-- * @s@: Splitter type providing the operations.+-- * @c@: Character type.+class WordSplitter s c | s -> c where -- | Determine where to break a word. -- -- * The splitter can refuse to process the word by returning 'Nothing'.@@ -84,28 +87,28 @@ -- line being parsed. -- 3. All remaining segments are put on separate lines between the -- current and next lines.- splitWord :: a+ splitWord :: s -> Int -- ^ Space available on the first line. -> Int -- ^ Space available on new lines. -> [c] -- ^ The word to break. -> Maybe [Int] -- ^ List of segment sizes. splitWord _ _ _ _ = Nothing -- | Predicate for characters that should be treated as a part of a word.- isWordChar :: a -> c -> Bool+ isWordChar :: s -> c -> Bool isWordChar _ _ = False -- | Predicate for detecting whitespace between words.- isWhitespace :: a -> c -> Bool+ isWhitespace :: s -> c -> Bool isWhitespace _ _ = False -- | Append the canonical hyphen character to show word breaks.- appendHyphen :: a -> [c] -> [c]+ appendHyphen :: s -> [c] -> [c] appendHyphen _ = id -- | Wrapping policy that breaks lines based on words. Use 'breakWords' to -- construct a new value.-data BreakWords c = forall a. (Show a, WordSplitter a c) => BreakWords Int a+data BreakWords c = forall s. (Show s, WordSplitter s c) => BreakWords Int s -- | Wrapping policy that breaks lines based on words.-breakWords :: (Show a, WordSplitter a c) => a -> BreakWords c+breakWords :: (Show s, WordSplitter s c) => s -> BreakWords c breakWords = BreakWords 0 data NoHyphen c = NoHyphen deriving (Show)@@ -174,7 +177,7 @@ total = length cs tweakCursor _ (VisibleLine HyphenatedWord cs) = id -breakAllLines :: WordSplitter a c => Int -> a -> [c] -> [VisibleLine c LineBreak]+breakAllLines :: WordSplitter s c => Int -> s -> [c] -> [VisibleLine c LineBreak] breakAllLines _ _ [] = [VisibleLine lineBreakEnd []] breakAllLines w s cs | w < 1 = [VisibleLine lineBreakEnd cs]
test/TestDocument.hs view
@@ -39,30 +39,30 @@ id), ("default view at top", checkEditView "original-long.txt"- "default-view.txt"+ "default-view.txt" (0,0) id), ("zero width skips wrapping", checkEditView "original-long.txt"- "no-wrap-view.txt" $+ "no-wrap-view.txt" (0,0) $ viewerResizeAction (0,snd defaultView)), ("zero height skips truncation", checkEditView "original-long.txt"- "no-bound-view.txt" $+ "no-bound-view.txt" (0,4) $ composeActions [ viewerResizeAction (fst defaultView,0), repeatAction 4 editorDownAction ]), ("move cursor below bottom", checkEditView "original-long.txt"- "below-view.txt" $+ "below-view.txt" (0,9) $ repeatAction 15 editorDownAction), ("scroll below end of doc", checkEditView "original-long.txt"- "below-bottom-view.txt" $+ "below-bottom-view.txt" (10,0) $ repeatAction 100 editorDownAction), ("page down puts edit at top and preserves cursor", checkEditView "original-long.txt"- "page-down-view.txt" $+ "page-down-view.txt" (7,0) $ composeActions [ repeatAction 4 editorRightAction, editorPageDownAction,@@ -70,7 +70,7 @@ ]), ("page up puts edit at top and preserves cursor", checkEditView "original-long.txt"- "page-up-view.txt" $+ "page-up-view.txt" (7,0) $ composeActions [ repeatAction 4 editorRightAction, repeatAction 15 editorDownAction,@@ -79,7 +79,7 @@ ]), ("fill view ignores already full", checkEditView "original-long.txt"- "fill-noop-view.txt" $+ "fill-noop-view.txt" (0,4) $ composeActions [ editorPageDownAction, repeatAction 4 editorDownAction,@@ -87,7 +87,7 @@ ]), ("fill view with short text", checkEditView "original-short.txt"- "fill-short-view.txt" $+ "fill-short-view.txt" (2,5) $ composeActions [ editorPageDownAction, -- Manually shift the view up by one line.@@ -97,7 +97,7 @@ ]), ("fill view starting past end", checkEditView "original-long.txt"- "fill-end-view.txt" $+ "fill-end-view.txt" (10,7) $ composeActions [ repeatAction 5 editorPageDownAction, repeatAction 2 editorUpAction,@@ -105,7 +105,7 @@ ]), ("shift view up within bounds", checkEditView "original-long.txt"- "shift-up-bounded-view.txt" $+ "shift-up-bounded-view.txt" (0,8) $ composeActions [ editorPageDownAction, repeatAction 4 editorDownAction,@@ -113,22 +113,22 @@ ]), ("shift view down within bounds", checkEditView "original-long.txt"- "shift-down-bounded-view.txt" $+ "shift-down-bounded-view.txt" (0,4) $ composeActions [ editorPageDownAction,- repeatAction 4 editorDownAction,+ repeatAction 8 editorDownAction, viewerShiftDownAction 4 ]), ("shift view up past doc front", checkEditView "original-long.txt"- "shift-up-unbounded-view.txt" $+ "shift-up-unbounded-view.txt" (0,4) $ composeActions [ repeatAction 4 editorDownAction, viewerShiftUpAction 4 ]), ("shift view down past doc back", checkEditView "original-long.txt"- "shift-down-unbounded-view.txt" $+ "shift-down-unbounded-view.txt" (10,0) $ composeActions [ repeatAction 5 editorPageDownAction, repeatAction 4 editorUpAction,@@ -136,14 +136,14 @@ ]), ("move previous at doc front", checkEditView "original-long.txt"- "insert-front-view.txt" $+ "insert-front-view.txt" (3,0) $ composeActions [ editorLeftAction, editorAppendAction "XYZ" ]), ("move next at doc back", checkEditView "original-long.txt"- "insert-back-view.txt" $+ "insert-back-view.txt" (13,9) $ composeActions [ -- 43 total lines after wrapping => down 42 then to end of line. repeatAction 43 editorDownAction,@@ -152,7 +152,7 @@ ]), ("insert in middle view", checkEditView "original-long.txt"- "insert-middle-view.txt" $+ "insert-middle-view.txt" (10,4) $ composeActions [ repeatAction 15 editorDownAction, repeatAction 5 editorUpAction,@@ -161,7 +161,7 @@ ]), ("line position preserved when passing short lines", checkEditView "original-long.txt"- "insert-middle-view.txt" $+ "insert-middle-view.txt" (10,4) $ composeActions [ repeatAction 7 editorRightAction, -- This traverses past empty lines after the line position is set.@@ -180,7 +180,7 @@ ]), ("delete in middle view", checkEditView "original-long.txt"- "delete-middle-view.txt" $+ "delete-middle-view.txt" (4,4) $ composeActions [ repeatAction 15 editorDownAction, repeatAction 5 editorUpAction,@@ -198,14 +198,14 @@ ]), ("join with previous", checkEditView "original-long.txt"- "join-prev-view.txt" $+ "join-prev-view.txt" (8,8) $ composeActions [ repeatAction 9 editorDownAction, editorBackspaceAction ]), ("join with next", checkEditView "original-long.txt"- "join-next-view.txt" $+ "join-next-view.txt" (8,8) $ composeActions [ repeatAction 9 editorDownAction, editorLeftAction,@@ -213,7 +213,7 @@ ]), ("break in middle before", checkEditView "original-long.txt"- "break-before-view.txt" $+ "break-before-view.txt" (3,5) $ composeActions [ repeatAction 15 editorDownAction, repeatAction 5 editorUpAction,@@ -223,7 +223,7 @@ ]), ("break in middle after", checkEditView "original-long.txt"- "break-after-view.txt" $+ "break-after-view.txt" (7,4) $ composeActions [ repeatAction 15 editorDownAction, repeatAction 5 editorUpAction,@@ -233,7 +233,7 @@ ]), ("resize smaller preserves line offset and cursor", checkEditView "original-long.txt"- "resize-smaller-view.txt" $+ "resize-smaller-view.txt" (5,4) $ composeActions [ repeatAction 15 editorDownAction, repeatAction 5 editorUpAction,@@ -243,14 +243,14 @@ ]), ("resize smaller truncates offset", checkEditView "original-long.txt"- "resize-truncate-view.txt" $+ "resize-truncate-view.txt" (0,9) $ composeActions [ repeatAction 9 editorDownAction, editorInsertAction "XYZ" ]), ("resize larger preserves line offset and cursor", checkEditView "original-long.txt"- "resize-larger-view.txt" $+ "resize-larger-view.txt" (23,4) $ composeActions [ repeatAction 15 editorDownAction, repeatAction 5 editorUpAction,@@ -425,11 +425,15 @@ let restored = joinParas $ exportData edit checkCondition ("\n" ++ restored) (restored == view) -checkEditView fx fy f = do+checkEditView fx fy c f = do edit <- fmap (f . loadDoc breakExact) $ readFile (testFilesRoot </> fx) view <- fmap (map trimSpace . lines) $ readFile (testFilesRoot </> fy) let restored = map trimSpace $ getVisible edit- checkCondition ("\n" ++ unlines restored) (restored == view)+ let cursor = getCursor edit+ checkConditions [+ ("Cursor: " ++ show cursor,cursor == c),+ ("View:\n" ++ unlines restored,restored == view)+ ] checkEditCursor b fx c e f = do edit <- fmap (f . loadDoc b) $ readFile (testFilesRoot </> fx)