packages feed

rasa-ext-cursors (empty) → 0.1.0.0

raw patch · 6 files changed

+251/−0 lines, 6 filesdep +basedep +data-defaultdep +lenssetup-changed

Dependencies added: base, data-default, lens, mtl, rasa, rasa-ext-style, text, text-lens, yi-rope

Files

+ LICENSE view
@@ -0,0 +1,21 @@+The MIT License++Copyright (c) 2016 Chris Penner++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ rasa-ext-cursors.cabal view
@@ -0,0 +1,39 @@+name:                rasa-ext-cursors+version:             0.1.0.0+synopsis:            Rasa Ext adding cursor(s)+description:         Rasa Ext adding cursor(s)+homepage:            https://github.com/ChrisPenner/rasa/+license:             MIT+license-file:        LICENSE+author:              Chris Penner+maintainer:          christopher.penner@gmail.com+copyright:           2016 Chris Penner+category:            Extension+build-type:          Simple+-- extra-source-files:+cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:     Rasa.Ext.Cursors+  other-modules:+                       Rasa.Ext.Cursors.Actions+                       Rasa.Ext.Cursors.Base+  build-depends:       base >= 4.7 && < 5+                     , rasa+                     , rasa-ext-style+                     , text-lens+                     , lens+                     , mtl+                     , text+                     , yi-rope+                     , data-default+  default-language:    Haskell2010++  default-extensions:++  ghc-options:         -Wall++source-repository head+  type:     git+  location: https://github.com/ChrisPenner/rasa
+ src/Rasa/Ext/Cursors.hs view
@@ -0,0 +1,31 @@+module Rasa.Ext.Cursors+  (+  -- * Main+  cursors+  -- * Actions+  , delete+  , insertText+  , findNext+  , findNextFrom+  , findPrev+  , findPrevFrom++  -- * Working with Cursor Ranges+  , eachRange+  , addRange+  , ranges+  , rangeDo+  , rangeDo_+  , overRanges+  , moveRangesByN+  , moveRangesByC+  ) where++import Rasa.Ext.Cursors.Base+import Rasa.Ext.Cursors.Actions++import Rasa.Ext++-- | Registers hooks for the extension. The user should add this to their config.+cursors :: Scheduler ()+cursors = beforeRender $ bufDo displayRange
+ src/Rasa/Ext/Cursors/Actions.hs view
@@ -0,0 +1,79 @@+module Rasa.Ext.Cursors.Actions+  ( delete+  , insertText+  , findNext+  , findPrev+  , findNextFrom+  , findPrevFrom+  , moveRangesByN+  , moveRangesByC+  ) where++import qualified Data.Text as T++import Control.Lens+import Control.Lens.Text+import Rasa.Ext+import Rasa.Ext.Cursors.Base++-- | Moves all Ranges that are on the same END row as the given range by the coord's row and column+-- This is used to adjust cursors when things have been inserted/deleted before them in the row.+moveSameLineRangesBy :: Range -> Coord -> BufAction ()+moveSameLineRangesBy (Range _ (Coord endRow endCol)) amt = do+  let moveInLine r@(Range (Coord startRow startCol) _) = return $+        if endRow == startRow && startCol > endCol+           then moveRange amt r+           else r+  ranges <~ rangeDo moveInLine++-- | Delete the text of all ranges in a buffer+delete :: BufAction ()+delete = rangeDo_ $ \r -> do+  deleteRange r+  moveSameLineRangesBy r (negate $ sizeOfR r)++-- | Insert text at the beginning of all ranges in the buffer.+insertText :: T.Text -> BufAction ()+insertText txt = rangeDo_ $ \r@(Range s _) -> do+  insertAt s txt+  moveSameLineRangesBy r (Coord 0 (T.length txt))++-- | Move all ranges to the location of the next occurence of the given text.+findNext :: T.Text -> BufAction ()+findNext pat = do+  res <- rangeDo $ \(Range _ e) -> do+    off <- findNextFrom pat e+    let end = moveCursorByN 1 off+    return $ Range off end+  ranges .= res++-- | Get the 'Coord' of the next occurence of the given text after the given 'Coord'+findNextFrom :: T.Text -> Coord -> BufAction Coord+findNextFrom pat c = do+  distance <- use (rope . afterC c . asText . tillNext pat . from asText . to sizeOf)+  return (distance + c)++-- | Move all ranges to the location of the previous occurence of the given text.+findPrev :: T.Text -> BufAction ()+findPrev pat = do+  res <- rangeDo $ \(Range s _) -> do+    off <- findPrevFrom pat s+    let end = moveCursorByN 1 off+    return $ Range off end+  ranges .= res++-- | Get the 'Coord' of the previous occurence of the given text before the given 'Coord'+findPrevFrom :: T.Text -> Coord -> BufAction Coord+findPrevFrom pat c = do+  txt <- use rope+  let Offset o = c^.from (asCoord txt)+  distance <- use (text . before o . tillPrev pat . to T.length .to negate)+  return ((Offset $ distance + o)^.asCoord txt)++-- | Move all ranges by the given number of columns+moveRangesByN :: Int -> BufAction ()+moveRangesByN n = overRanges $ return . moveRangeByN n++-- | Move all ranges by the given number of rows and columns+moveRangesByC :: Coord -> BufAction ()+moveRangesByC c = overRanges $ return . moveRange c
+ src/Rasa/Ext/Cursors/Base.hs view
@@ -0,0 +1,79 @@+{-# LANGUAGE TemplateHaskell, OverloadedStrings, Rank2Types #-}++module Rasa.Ext.Cursors.Base+  ( rangeDo+  , rangeDo_+  , ranges+  , displayRange+  , eachRange+  , overRanges+  , addRange+  ) where+++import Rasa.Ext+import Rasa.Ext.Style++import Control.Monad.State+import Control.Lens+import Data.Typeable+import Data.List+import Data.Default+import qualified Yi.Rope as Y++-- | Stores the cursor ranges in each buffer.+data Cursors = Cursors+  { _cursors :: [Range]+  } deriving (Typeable, Show)++makeLenses ''Cursors++instance Default Cursors where+  def = Cursors {+  _cursors=[Range (Coord 0 0) (Coord 0 1)]+}++-- | Adjusts input ranges to contain at least one character.+ensureSize :: Range -> Range+ensureSize r@(Range s e)+  | s == e = Range s (moveCursorByN 1 e)+  | otherwise = r++-- | Sorts Ranges, removes duplicates, ensures they contain at least one character+-- and restricts them to fit within the given text.+cleanRanges :: Y.YiString -> [Range] -> [Range]+cleanRanges txt = fmap (ensureSize . clampRange txt) . reverse . nub . sort++-- | A lens over all the stored cursor ranges for a buffer+ranges :: Lens' Buffer [Range]+ranges = lens getter setter+  where getter buf = buf^.bufExt.cursors+        setter buf new = let txt = buf^.rope+                          in buf & bufExt.cursors .~ cleanRanges txt new++-- | A Traversal over each Range for the given buffer.+eachRange :: Traversal' Buffer Range+eachRange = ranges.traverse++-- | Sequences actions over each range as a 'BufAction'+rangeDo :: (Range -> BufAction a) -> BufAction [a]+rangeDo f = use ranges >>= mapM f++-- | 'rangeDo' with void return.+rangeDo_ :: (Range -> BufAction a) -> BufAction ()+rangeDo_ = void . rangeDo++-- | Sequences actions over each range and replaces each range with its result.+overRanges :: (Range -> BufAction Range) -> BufAction ()+overRanges f = ranges <~ rangeDo f++-- | Adds a new range to the list of ranges.+addRange :: Range -> BufAction ()+addRange r = ranges <>= [r]++-- | Sets style attributes to show a given range.+displayRange ::  BufAction ()+displayRange = rangeDo_ setStyle+  where+    setStyle :: Range -> BufAction ()+    setStyle r = addStyle r (flair ReverseVideo)