packages feed

text-zipper 0.11 → 0.13

raw patch · 5 files changed

Files

− CHANGELOG
@@ -1,116 +0,0 @@--0.11-------API changes:- * Added `gotoBOF`, `gotoEOF`, `killToBOF`, and `killToEOF` functions-   (thanks Itai Y. Efrat)--0.10.1--------- * WordSpec: fix a test verification bug (fixed #11)- * WordSpec: generation of random text should never include newlines--0.10-------- Integrated word editing and navigation functions-  courtesy of Hans-Peter Deifel's hledger-iadd project (see-  Data.Text.Zipper.Generic.Words)-- Added currentChar, nextChar, and previousChar (thanks @kRITZCREEK)--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--------- Fixed insertMany accidental addition of trailing newline--0.8.2--------- Fixed insertMany for zippers with no line limit--0.8.1--------- Added Github links and CHANGELOG to package--0.8------- Added 'transposeChars' function--0.7.1--------- Generic: import everything from Monoid for older GHCs--0.7------- API changes: Add Generic module to abstract over text container types--0.6.1--------- Make insertMany respect the zipper's line limit--0.6------- Add insertMany for faster bulk insertion--0.5------- Added killToBOL function (thanks Hans-Peter Deifel)-- Enabled -Wall-- Added dependency on deepseq-- Added NFData instance for TextZipper--0.4------- Added clearZipper-- Added isFirstLine (thanks Kwang Yul Seo)-- Renamed lastLine to isLastLine (thanks Kwang Yul Seo)--0.3.1--------- Fixed export of vectorZipper--0.3------- Added vectorZipper for zipping over vectors of characters--0.2.1--------- Exported getLineLimit to permit obtaining a zipper's line limit--0.2------- Added support for limiting the number of lines in the zipper-- insertChar "\n" is now equivalent to breakLine-- Improved Show instance for TextZipper--0.1.1--------- Updated package metadata--0.1------Initial release (originally split off from vty-ui)
+ CHANGELOG.md view
@@ -0,0 +1,132 @@++0.13+----++Bug fixes:+ * The zipper constructors now ignores non-printable characters (see+   also #13)+ * `insertMany` now no longer drops the input following a non-printable+   character (#13)++0.12+----++API changes:+ * Added `moveCursorClosest` to allow cursor placement as near as+   possible to a specified location.++0.11+----++API changes:+ * Added `gotoBOF`, `gotoEOF`, `killToBOF`, and `killToEOF` functions+   (thanks Itai Y. Efrat)++0.10.1+------++ * WordSpec: fix a test verification bug (fixed #11)+ * WordSpec: generation of random text should never include newlines++0.10+----++- Integrated word editing and navigation functions+  courtesy of Hans-Peter Deifel's hledger-iadd project (see+  Data.Text.Zipper.Generic.Words)+- Added currentChar, nextChar, and previousChar (thanks @kRITZCREEK)++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+-----++- Fixed insertMany accidental addition of trailing newline++0.8.2+-----++- Fixed insertMany for zippers with no line limit++0.8.1+-----++- Added Github links and CHANGELOG to package++0.8+---++- Added 'transposeChars' function++0.7.1+-----++- Generic: import everything from Monoid for older GHCs++0.7+---++- API changes: Add Generic module to abstract over text container types++0.6.1+-----++- Make insertMany respect the zipper's line limit++0.6+---++- Add insertMany for faster bulk insertion++0.5+---++- Added killToBOL function (thanks Hans-Peter Deifel)+- Enabled -Wall+- Added dependency on deepseq+- Added NFData instance for TextZipper++0.4+---++- Added clearZipper+- Added isFirstLine (thanks Kwang Yul Seo)+- Renamed lastLine to isLastLine (thanks Kwang Yul Seo)++0.3.1+-----++- Fixed export of vectorZipper++0.3+---++- Added vectorZipper for zipping over vectors of characters++0.2.1+-----++- Exported getLineLimit to permit obtaining a zipper's line limit++0.2+---++- Added support for limiting the number of lines in the zipper+- insertChar "\n" is now equivalent to breakLine+- Improved Show instance for TextZipper++0.1.1+-----++- Updated package metadata++0.1+---++Initial release (originally split off from vty-ui)
src/Data/Text/Zipper.hs view
@@ -27,6 +27,7 @@      -- * Navigation functions     , moveCursor+    , moveCursorClosest     , moveRight     , moveLeft     , moveUp@@ -58,6 +59,7 @@ import Control.Applicative ((<$>)) import Control.DeepSeq import Data.Char (isPrint)+import Data.List (foldl') import Data.Monoid import qualified Data.Text as T import qualified Data.Vector as V@@ -145,7 +147,10 @@         (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 toListF lmt+        numLines = length ls+        insertLine z (i, l) = (if i < numLines - 1 then breakLine else id) $ insertMany l z+        loadInitial z = foldl' insertLine z $ zip [0..] (first:rest)+    in loadInitial $ TZ mempty mempty mempty mempty fromCh drp tk lngth lst int nl linesFunc toListF lmt  -- | Get the text contents of the zipper. getText :: (Monoid a) => TextZipper a -> [a]@@ -185,6 +190,22 @@                , toRight = drop_ tz col (t !! row)                } +-- | Move the cursor to the specified row and column. Invalid cursor+-- positions will be reinterpreted as the closest valid position. Valid+-- cursor positions range as described for 'cursorPosition'.+moveCursorClosest :: (Monoid a) => (Int, Int) -> TextZipper a -> TextZipper a+moveCursorClosest (row, col) tz =+    let t = getText tz+        bestRow = min (max 0 $ length t - 1) $ max 0 row+        bestCol = if bestRow < length t+                  then min (length_ tz (t !! bestRow)) $ max 0 col+                  else 0+    in tz { above = take bestRow t+          , below = drop (bestRow + 1) t+          , toLeft = take_ tz bestCol (t !! bestRow)+          , toRight = drop_ tz bestCol (t !! bestRow)+          }+ isFirstLine :: TextZipper a -> Bool isFirstLine = null . above @@ -207,28 +228,19 @@ -- Otherwise insert the character and move the cursor one position to -- the right. insertChar :: (Monoid a) => Char -> TextZipper a -> TextZipper a-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+insertChar ch tz+    | ch == '\n' = breakLine tz+    | isPrint ch = tz { toLeft = toLeft tz `mappend` (fromChar tz ch) }+    | otherwise  = tz  -- | Insert many characters at the current cursor position. Move the -- cursor to the end of the inserted text. insertMany :: (Monoid a) => a -> TextZipper a -> TextZipper a-insertMany str tz =-    let go [] z = z-        go (c:cs) z = maybe z (go cs) $ insertChar_ c z-    in go (toList_ tz str) tz+insertMany str tz = foldl' (flip insertChar) tz $ toList_ tz str  -- | Insert a line break at the current cursor position. breakLine :: (Monoid a) => TextZipper a -> TextZipper a-breakLine tz = maybe tz id $ breakLine_ tz--breakLine_ :: (Monoid a) => TextZipper a -> Maybe (TextZipper a)-breakLine_ tz =+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.@@ -237,9 +249,9 @@                       }     in case lineLimit tz of           Just lim -> if length (above tz) + length (below tz) + 2 > lim-                      then Nothing-                      else Just modified-          Nothing -> Just modified+                      then tz+                      else modified+          Nothing -> modified  -- | Move the cursor to the end of the current line. gotoEOL :: (Monoid a) => TextZipper a -> TextZipper a
tests/WordsSpec.hs view
@@ -3,8 +3,6 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} module WordsSpec (spec) where --- This test suite is Copyright (c) Hans-Peter Deifel- import Test.Hspec import Test.QuickCheck @@ -17,10 +15,30 @@  spec :: Spec spec = do+    constructorSpec+    insertCharSpec+    insertManySpec     moveWordLeftSpec     moveWordRightSpec     deletePrevWordSpec     deleteWordSpec++constructorSpec :: Spec+constructorSpec = describe "constructor" $ do+    it "inserts only printable characters at construction time" $+      (stringZipper ["abc\x1b def"] Nothing) `shouldBe` (stringZipper ["abc def"] Nothing)++insertCharSpec :: Spec+insertCharSpec = describe "insertChar" $ do+    it "ignores an insert of a non-printable character" $+      let z = stringZipper [] Nothing+      in (insertChar '\x1b' z) `shouldBe` z++insertManySpec :: Spec+insertManySpec = describe "insertMany" $ do+    it "ignores an insert of a non-printable character" $+      let z = stringZipper ["abc"] Nothing+      in (insertMany "ghi\x1bjkl" z) `shouldBe` (insertMany "ghijkl" z)  moveWordLeftSpec :: Spec moveWordLeftSpec = describe "moveWordLeft" $ do
text-zipper.cabal view
@@ -1,5 +1,5 @@ name:                text-zipper-version:             0.11+version:             0.13 synopsis:            A text editor zipper library description:         This library provides a zipper and API for editing text. license:             BSD3@@ -10,7 +10,7 @@ category:            Text build-type:          Simple cabal-version:       >=1.10-data-files:          CHANGELOG+data-files:          CHANGELOG.md homepage:            https://github.com/jtdaugherty/text-zipper/ bug-reports:         https://github.com/jtdaugherty/text-zipper/issues