packages feed

text-zipper 0.8.3 → 0.9

raw patch · 4 files changed

+51/−33 lines, 4 files

Files

CHANGELOG view
@@ -1,3 +1,11 @@+0.9+---++- insertChar and insertMany now only insert printable characters and+  newlines (subject to text zipper line limits)+- The GenericTextZipper class now requires a new method,+  toList :: a -> [Char]+ 0.8.3 ----- 
src/Data/Text/Zipper.hs view
@@ -46,6 +46,7 @@  import Control.Applicative ((<$>)) import Control.DeepSeq+import Data.Char (isPrint) import Data.Monoid import qualified Data.Text as T import qualified Data.Vector as V@@ -64,6 +65,7 @@        , init_ :: a -> a        , null_ :: a -> Bool        , lines_ :: a -> [a]+       , toList_ :: a -> [Char]        , lineLimit :: Maybe Int        } @@ -118,19 +120,21 @@          -- ^'null'.          -> (a -> [a])          -- ^'lines'.+         -> (a -> [Char])+         -- ^'toList'.          -> [a]          -- ^The initial lines of text.          -> Maybe Int          -- ^Limit to this many lines of text ('Nothing' means no limit).          -> TextZipper a-mkZipper fromCh drp tk lngth lst int nl linesFunc ls lmt =+mkZipper fromCh drp tk lngth lst int nl linesFunc toListF ls lmt =     let limitedLs = case lmt of           Nothing -> ls           Just n -> take n ls         (first, rest) = if null limitedLs                         then (mempty, mempty)                         else (head limitedLs, tail limitedLs)-    in TZ mempty first [] rest fromCh drp tk lngth lst int nl linesFunc lmt+    in TZ mempty first [] rest fromCh drp tk lngth lst int nl linesFunc toListF lmt  -- |Get the text contents of the zipper. getText :: (Monoid a) => TextZipper a -> [a]@@ -184,36 +188,37 @@ currentLine :: (Monoid a) => TextZipper a -> a currentLine tz = (toLeft tz) `mappend` (toRight tz) --- |Insert a character at the current cursor position.  Move the--- cursor one position to the right.+-- |Insert a character at the current cursor position.+--+-- If the character is a newline, break the current line.+--+-- If the character is non-printable, ignore it.+--+-- Otherwise insert the character and move the cursor one position to+-- the right. insertChar :: (Monoid a) => Char -> TextZipper a -> TextZipper a-insertChar '\n' tz = breakLine tz-insertChar ch tz = tz { toLeft = toLeft tz `mappend` (fromChar tz ch) }+insertChar ch tz = maybe tz id $ insertChar_ ch tz +insertChar_ :: (Monoid a) => Char -> TextZipper a -> Maybe (TextZipper a)+insertChar_ ch tz+    | ch == '\n' = breakLine_ tz+    | isPrint ch = Just $ tz { toLeft = toLeft tz `mappend` (fromChar tz ch) }+    | otherwise  = Nothing+ -- |Insert many characters at the current cursor position. Move the--- cursor one position to the end of the inserted text.+-- cursor to the end of the inserted text. insertMany :: (Monoid a) => a -> TextZipper a -> TextZipper a-insertMany cs tz =-    let ls = lines_ tz cs-        go []     z = z-        go (a:as) z = let maybeBreak = if null as then id else breakLine-                      in go as $ maybeBreak $ z { toLeft = toLeft z `mappend` a }-    in case lineLimit tz of-        Nothing    ->-            let toInsert = ls-            in go toInsert tz-        Just limit ->-            -- How many more lines can we add without violating the-            -- limit?-            let toInsert = take remainingLines ls-                remainingLines = max 0 (limit - totalLines)-                totalLines = length (above tz) +-                             length (below tz)-            in go toInsert tz+insertMany str tz =+    let go [] z = z+        go (c:cs) z = maybe z (go cs) $ insertChar_ c z+    in go (toList_ tz str) tz  -- |Insert a line break at the current cursor position. breakLine :: (Monoid a) => TextZipper a -> TextZipper a-breakLine tz =+breakLine tz = maybe tz id $ breakLine_ tz++breakLine_ :: (Monoid a) => TextZipper a -> Maybe (TextZipper a)+breakLine_ tz =     -- Plus two because we count the current line and the line we are     -- about to create; if that number of lines exceeds the limit,     -- ignore this operation.@@ -222,9 +227,10 @@                       }     in case lineLimit tz of           Just lim -> if length (above tz) + length (below tz) + 2 > lim-                      then tz-                      else modified-          Nothing -> modified+                      then Nothing+                      else Just modified+          Nothing -> Just modified+ -- |Move the cursor to the end of the current line. gotoEOL :: (Monoid a) => TextZipper a -> TextZipper a gotoEOL tz = tz { toLeft = currentLine tz@@ -393,12 +399,12 @@ -- |Construct a zipper from list values. stringZipper :: [String] -> Maybe Int -> TextZipper String stringZipper =-    mkZipper (:[]) drop take length last init null lines+    mkZipper (:[]) drop take length last init null lines id  -- |Construct a zipper from vectors of characters. vectorZipper :: [V.Vector Char] -> Maybe Int -> TextZipper (V.Vector Char) vectorZipper =-    mkZipper V.singleton V.drop V.take V.length V.last V.init V.null V.vecLines+    mkZipper V.singleton V.drop V.take V.length V.last V.init V.null V.vecLines V.toList  -- |Empty a zipper. clearZipper :: (Monoid a) => TextZipper a -> TextZipper a@@ -412,4 +418,4 @@ -- |Construct a zipper from 'T.Text' values. textZipper :: [T.Text] -> Maybe Int -> TextZipper T.Text textZipper =-    mkZipper T.singleton T.drop T.take T.length T.last T.init T.null T.lines+    mkZipper T.singleton T.drop T.take T.length T.last T.init T.null T.lines T.unpack
src/Data/Text/Zipper/Generic.hs view
@@ -24,6 +24,7 @@   init      :: a -> a   null      :: a -> Bool   lines     :: a -> [a]+  toList    :: a -> [Char]  instance GenericTextZipper [Char] where   singleton = (:[])@@ -34,6 +35,7 @@   init      = Prelude.init   null      = Prelude.null   lines     = Prelude.lines+  toList    = id  instance GenericTextZipper T.Text where   singleton = T.singleton@@ -44,6 +46,7 @@   init      = T.init   null      = T.null   lines     = T.lines+  toList    = T.unpack  instance GenericTextZipper (V.Vector Char) where   singleton = V.singleton@@ -54,8 +57,9 @@   init      = V.init   null      = V.null   lines     = V.vecLines+  toList    = V.toList  textZipper :: GenericTextZipper a =>               [a] -> Maybe Int -> TextZipper a textZipper =-  mkZipper singleton drop take length last init null lines+  mkZipper singleton drop take length last init null lines toList
text-zipper.cabal view
@@ -1,5 +1,5 @@ name:                text-zipper-version:             0.8.3+version:             0.9 synopsis:            A text editor zipper library description:         This library provides a zipper and API for editing text. license:             BSD3