yi-core 0.14.1 → 0.15.0
raw patch · 10 files changed
+70/−270 lines, 10 filesdep −QuickCheckdep −randomdep −semigroupsdep ~yi-rope
Dependencies removed: QuickCheck, random, semigroups
Dependency ranges changed: yi-rope
Files
- src/Yi/Buffer/Adjusted.hs +0/−83
- src/Yi/Buffer/HighLevel.hs +29/−20
- src/Yi/Buffer/Misc.hs +4/−7
- src/Yi/Buffer/Undo.hs +7/−0
- src/Yi/Core.hs +15/−10
- src/Yi/Misc.hs +1/−4
- src/Yi/Syntax/Tree.hs +0/−125
- src/Yi/Types.hs +0/−2
- src/Yi/UI/Common.hs +9/−7
- yi-core.cabal +5/−12
− src/Yi/Buffer/Adjusted.hs
@@ -1,83 +0,0 @@-{-# OPTIONS_HADDOCK show-extensions #-}---- |--- Module : Yi.Buffer.Adjusted--- License : GPL-2--- Maintainer : yi-devel@googlegroups.com--- Stability : experimental--- Portability : portable------ This module re-exports Yi.Buffer overriding insert* and delete* functions--- with their more indent-aware variants. It is intended to be imported--- instead of Yi.Buffer or qualified to avoid name clashes.--module Yi.Buffer.Adjusted- ( bdeleteB- , insertB- , insertN- , insertNAt- , deleteB- , deleteN- , deleteRegionB- , deleteRegionWithStyleB- , module Yi.Buffer- ) where--import Control.Monad (forM_, when)-import Yi.Buffer hiding (bdeleteB, insertB, insertN, insertNAt- , deleteB, deleteN, deleteNAt- , deleteRegionB, deleteRegionWithStyleB)-import qualified Yi.Buffer as B (deleteN, insertB, insertNAt)-import Yi.Misc (adjBlock)-import qualified Yi.Rope as R (YiString, countNewLines, length, take)-import Yi.Utils (SemiNum ((~-)))--insertNAt :: R.YiString -> Point -> BufferM ()-insertNAt rope point | R.countNewLines rope > 0 = B.insertNAt rope point-insertNAt rope point = B.insertNAt rope point >> adjBlock (R.length rope)---- | Insert the list at current point, extending size of buffer-insertN :: R.YiString -> BufferM ()-insertN rope = insertNAt rope =<< pointB---- | Insert the char at current point, extending size of buffer-insertB :: Char -> BufferM ()-insertB c = B.insertB c >> adjBlock 1---- | @deleteNAt n p@ deletes @n@ characters forwards from position @p@-deleteNAt :: Direction -> Int -> Point -> BufferM ()-deleteNAt dir n pos = do- els <- R.take n <$> streamB Forward pos- applyUpdate (Delete pos dir els)- when (R.countNewLines els == 0) $- adjBlock (-(R.length els))--deleteN :: Int -> BufferM ()-deleteN n = pointB >>= deleteNAt Forward n--deleteB :: TextUnit -> Direction -> BufferM ()-deleteB unit dir = deleteRegionB =<< regionOfPartNonEmptyB unit dir--bdeleteB :: BufferM ()-bdeleteB = deleteB Character Backward--deleteRegionB :: Region -> BufferM ()-deleteRegionB r =- deleteNAt (regionDirection r)- (fromIntegral (regionEnd r ~- regionStart r))- (regionStart r)--deleteRegionWithStyleB :: Region -> RegionStyle -> BufferM Point-deleteRegionWithStyleB reg Block = savingPointB $ do- (start, lengths) <- shapeOfBlockRegionB reg- moveTo start- forM_ (zip [1..] lengths) $ \(i, l) -> do- B.deleteN l- moveTo start- lineMoveRel i- return start--deleteRegionWithStyleB reg style = savingPointB $ do- effectiveRegion <- convertRegionToStyleB reg style- deleteRegionB effectiveRegion- return $! regionStart effectiveRegion
src/Yi/Buffer/HighLevel.hs view
@@ -127,6 +127,7 @@ import Control.Monad.State (gets) import Data.Char (isDigit, isHexDigit, isOctDigit, isSpace, isUpper, toLower, toUpper) import Data.List (intersperse, sort)+import Data.List.NonEmpty (NonEmpty(..)) import Data.Maybe (catMaybes, fromMaybe, listToMaybe) import Data.Monoid ((<>)) import qualified Data.Set as Set@@ -586,10 +587,13 @@ -- | Move cursor to the bottom of the screen scrollCursorToBottomB :: BufferM () scrollCursorToBottomB = do- MarkSet _ i _ <- markLines- r <- winRegionB- t <- lineOf (regionEnd r - 1)- scrollB $ i - t+ -- NOTE: This is only an approximation.+ -- The correct scroll amount depends on how many lines just above+ -- the current viewport are going to be wrapped. We don't have this+ -- information here as wrapping is done in the frontend.+ MarkSet f i _ <- markLines+ h <- askWindow actualLines+ scrollB $ i - f - h + 1 -- | Scroll by n lines. scrollB :: Int -> BufferM ()@@ -604,15 +608,17 @@ -- Scroll line above window to the bottom. scrollToLineAboveWindowB :: BufferM ()-scrollToLineAboveWindowB = do downFromTosB 0- replicateM_ 1 lineUp- scrollCursorToBottomB+scrollToLineAboveWindowB = do+ downFromTosB 0+ replicateM_ 1 lineUp+ scrollCursorToBottomB -- Scroll line below window to the top. scrollToLineBelowWindowB :: BufferM ()-scrollToLineBelowWindowB = do upFromBosB 0- replicateM_ 1 lineDown- scrollCursorToTopB+scrollToLineBelowWindowB = do+ upFromBosB 0+ replicateM_ 1 lineDown+ scrollCursorToTopB -- | Move the point to inside the viewable region snapInsB :: BufferM ()@@ -628,7 +634,7 @@ indexOfSolAbove :: Int -> BufferM Point indexOfSolAbove n = pointAt $ gotoLnFrom (negate n) -data RelPosition = Above | Below | Within+data RelPosition = Above | Below | Within deriving (Show) -- | return relative position of the point @p@@@ -641,7 +647,7 @@ pointScreenRelPosition _ _ _ = Within -- just to disable the non-exhaustive pattern match warning -- | Move the visible region to include the point-snapScreenB :: Maybe ScrollStyle ->BufferM Bool+snapScreenB :: Maybe ScrollStyle -> BufferM Bool snapScreenB style = do w <- askWindow wkey movePoint <- Set.member w <$> use pointFollowsWindowA@@ -957,30 +963,33 @@ splitBlockRegionToContiguousSubRegionsB :: Region -> BufferM [Region] splitBlockRegionToContiguousSubRegionsB reg = savingPointB $ do (start, lengths) <- shapeOfBlockRegionB reg- moveTo start- forM lengths $ \l -> do+ forM (zip [0..] lengths) $ \(i, l) -> do+ moveTo start+ void $ lineMoveRel i p0 <- pointB moveXorEol l p1 <- pointB let subRegion = mkRegion p0 p1- moveTo p0- void $ lineMoveRel 1 return subRegion -deleteRegionWithStyleB :: Region -> RegionStyle -> BufferM Point+-- Return list containing a single point for all non-block styles.+-- For Block return all the points along the left edge of the region+deleteRegionWithStyleB :: Region -> RegionStyle -> BufferM (NonEmpty Point) deleteRegionWithStyleB reg Block = savingPointB $ do (start, lengths) <- shapeOfBlockRegionB reg moveTo start- forM_ (zip [1..] lengths) $ \(i, l) -> do+ points <- forM (zip [1..] lengths) $ \(i, l) -> do deleteN l+ p <- pointB moveTo start lineMoveRel i- return start+ return (if l == 0 then Nothing else Just p)+ return $ start :| drop 1 (catMaybes points) deleteRegionWithStyleB reg style = savingPointB $ do effectiveRegion <- convertRegionToStyleB reg style deleteRegionB effectiveRegion- return $! regionStart effectiveRegion+ return $! pure (regionStart effectiveRegion) readRegionRopeWithStyleB :: Region -> RegionStyle -> BufferM YiString readRegionRopeWithStyleB reg Block = savingPointB $ do
src/Yi/Buffer/Misc.hs view
@@ -136,7 +136,6 @@ , modePrettifyA , modeKeymapA , modeIndentA- , modeAdjustBlockA , modeFollowA , modeIndentSettingsA , modeToggleCommentSelectionA@@ -483,8 +482,9 @@ -- | Mark the current point in the undo list as a saved state. markSavedB :: UTCTime -> BufferM ()-markSavedB t = do undosA %= setSavedFilePointU- lastSyncTimeA .= t+markSavedB t = do+ undosA %= setSavedFilePointU+ lastSyncTimeA .= t bkey :: FBuffer -> BufferRef bkey = view bkey__A@@ -495,9 +495,7 @@ startUpdateTransactionB :: BufferM () startUpdateTransactionB = do transactionPresent <- use updateTransactionInFlightA- if transactionPresent- then error "Already started update transaction"- else do+ when (not transactionPresent) $ do undosA %= addChangeU InteractivePoint updateTransactionInFlightA .= True @@ -573,7 +571,6 @@ modePrettify = const $ return (), modeKeymap = id, modeIndent = \_ _ -> return (),- modeAdjustBlock = \_ _ -> return (), modeFollow = const emptyAction, modeIndentSettings = IndentSettings { expandTabs = True
src/Yi/Buffer/Undo.hs view
@@ -48,6 +48,7 @@ module Yi.Buffer.Undo ( emptyU , addChangeU+ , deleteInteractivePointsU , setSavedFilePointU , isAtSavedFilePointU , undoU@@ -87,6 +88,12 @@ addChangeU :: Change -> URList -> URList addChangeU InteractivePoint (URList us rs) = URList (addIP us) rs addChangeU u (URList us _) = URList (u S.<| us) S.empty++deleteInteractivePointsU :: URList -> URList+deleteInteractivePointsU (URList us rs) = URList (go us) rs+ where+ go (S.viewl -> InteractivePoint S.:< x) = go x+ go x = x -- | Add a saved file point so that we can tell that the buffer has not -- been modified since the previous saved file point.
src/Yi/Core.hs view
@@ -20,21 +20,22 @@ ( -- * Construction and destruction startEditor- , quitEditor -- :: YiM ()+ , quitEditor -- :: YiM ()+ , quitEditorWithExitCode -- :: ExitCode -> YiM () -- * User interaction- , refreshEditor -- :: YiM ()- , suspendEditor -- :: YiM ()+ , refreshEditor -- :: YiM ()+ , suspendEditor -- :: YiM () , userForceRefresh -- * Global editor actions- , errorEditor -- :: String -> YiM ()- , closeWindow -- :: YiM ()+ , errorEditor -- :: String -> YiM ()+ , closeWindow -- :: YiM () , closeWindowEmacs -- * Interacting with external commands- , runProcessWithInput -- :: String -> String -> YiM String- , startSubprocess -- :: FilePath -> [String] -> YiM ()+ , runProcessWithInput -- :: String -> String -> YiM String+ , startSubprocess -- :: FilePath -> [String] -> YiM () , sendToProcess -- * Misc@@ -71,7 +72,7 @@ import Data.Traversable (forM) import GHC.Conc (labelThread) import System.Directory (doesFileExist)-import System.Exit (ExitCode)+import System.Exit (ExitCode (ExitSuccess)) import System.IO (Handle, hPutStr, hWaitForInput) import System.PosixCompat.Files (getFileStatus, modificationTime) import System.Process (ProcessHandle,@@ -223,10 +224,14 @@ -- | Quit. quitEditor :: YiM ()-quitEditor = do+quitEditor = quitEditorWithExitCode ExitSuccess++-- | Quit with an exit code. (This is used to implement vim's :cq command)+quitEditorWithExitCode :: ExitCode -> YiM ()+quitEditorWithExitCode exitCode = do savePersistentState onYiVar $ terminateSubprocesses (const True)- withUI (`UI.end` True)+ withUI (`UI.end` (Just exitCode)) -- | Update (visible) buffers if they have changed on disk. -- FIXME: since we do IO here we must catch exceptions!
src/Yi/Misc.hs view
@@ -14,7 +14,7 @@ -- Various high-level functions to further classify. module Yi.Misc ( getAppropriateFiles, getFolder, cd, pwd, matchingFileNames- , rot13Char, placeMark, selectAll, adjBlock, adjIndent+ , rot13Char, placeMark, selectAll, adjIndent , promptFile , promptFileChangingHints, matchFile, completeFile , printFileInfoE, debugBufferContent ) where@@ -122,9 +122,6 @@ -- | Select the contents of the whole buffer selectAll :: BufferM () selectAll = botB >> placeMark >> topB >> setVisibleSelection True--adjBlock :: Int -> BufferM ()-adjBlock x = withSyntaxB' (\m s -> modeAdjustBlock m s x) -- | A simple wrapper to adjust the current indentation using -- the mode specific indentation function but according to the
src/Yi/Syntax/Tree.hs view
@@ -46,11 +46,6 @@ import Yi.Region (Region (regionEnd, regionStart), mkRegion) import Yi.String (showT) -#ifdef TESTING-import Test.QuickCheck-import Test.QuickCheck.Property (unProperty)-#endif- -- Fundamental types type Path = [Int] type Node t = (Path, t)@@ -301,123 +296,3 @@ sepBy1 :: (Alternative f) => f a -> f v -> f [a] sepBy1 p s = (:) <$> p <*> many (s *> p)---------------------------------------------------------- Testing code.--#ifdef TESTING--nodeRegion :: IsTree tree => Node (tree (Tok a)) -> Region-nodeRegion n = subtreeRegion t- where Just t = walkDown n--data Test a = Empty | Leaf a | Bin (Test a) (Test a) deriving (Show, Eq, Foldable)--instance IsTree Test where- uniplate (Bin l r) = ([l,r],\[l',r'] -> Bin l' r')- uniplate t = ([],\[] -> t)- emptyNode = Empty--type TT = Tok ()--instance Arbitrary (Test TT) where- arbitrary = sized $ \size -> do- arbitraryFromList [1..size+1]- shrink (Leaf _) = []- shrink (Bin l r) = [l,r] <> (Bin <$> shrink l <*> pure r) <> (Bin <$> pure l <*> shrink r)--tAt :: Point -> TT-tAt idx = Tok () 1 (Posn (idx * 2) 0 0)--arbitraryFromList :: [Int] -> Gen (Test TT)-arbitraryFromList [] = error "arbitraryFromList expects non empty lists"-arbitraryFromList [x] = pure (Leaf (tAt (fromIntegral x)))-arbitraryFromList xs = do- m <- choose (1,length xs - 1)- let (l,r) = splitAt m xs- Bin <$> arbitraryFromList l <*> arbitraryFromList r--newtype NTTT = N (Node (Test TT)) deriving Show--instance Arbitrary NTTT where- arbitrary = do- t <- arbitrary- p <- arbitraryPath t- return $ N (p,t)--arbitraryPath :: Test t -> Gen Path-arbitraryPath (Leaf _) = return []-arbitraryPath (Bin l r) = do- c <- choose (0,1)- let Just n' = index c [l,r]- (c :) <$> arbitraryPath n'--regionInside :: Region -> Gen Region-regionInside r = do- b :: Int <- choose (fromIntegral $ regionStart r, fromIntegral $ regionEnd r)- e :: Int <- choose (b, fromIntegral $ regionEnd r)- return $ mkRegion (fromIntegral b) (fromIntegral e)--pointInside :: Region -> Gen Point-pointInside r = do- p :: Int <- choose (fromIntegral $ regionStart r, fromIntegral $ regionEnd r)- return (fromIntegral p)--prop_fromLeafAfterToFinal :: NTTT -> Property-prop_fromLeafAfterToFinal (N n) = let- fullRegion = subtreeRegion $ snd n- in forAll (pointInside fullRegion) $ \p -> do- let final@(_, (_, finalSubtree)) = fromLeafAfterToFinal p n- finalRegion = subtreeRegion finalSubtree- initialRegion = nodeRegion n-- whenFail (do putStrLn $ "final = " <> show final- putStrLn $ "final reg = " <> show finalRegion- putStrLn $ "initialReg = " <> show initialRegion- putStrLn $ "p = " <> show p- )- ((regionStart finalRegion <= p) && (initialRegion `includedRegion` finalRegion))--prop_allLeavesAfter :: NTTT -> Property-prop_allLeavesAfter (N n@(xs,t)) = property $ do- let after = allLeavesRelative afterChild n- (xs',t') <- elements after- let t'' = walkDown (xs',t)- unProperty $ whenFail (do- putStrLn $ "t' = " <> show t'- putStrLn $ "t'' = " <> show t''- putStrLn $ "xs' = " <> show xs'- ) (Just t' == t'' && xs <= xs')--prop_allLeavesBefore :: NTTT -> Property-prop_allLeavesBefore (N n@(xs,t)) = property $ do- let after = allLeavesRelative beforeChild n- (xs',t') <- elements after- let t'' = walkDown (xs',t)- unProperty $ whenFail (do- putStrLn $ "t' = " <> show t'- putStrLn $ "t'' = " <> show t''- putStrLn $ "xs' = " <> show xs'- ) (Just t' == t'' && xs' <= xs)--prop_fromNodeToLeafAfter :: NTTT -> Property-prop_fromNodeToLeafAfter (N n) = forAll (pointInside (subtreeRegion $ snd n)) $ \p -> do- let after = fromLeafToLeafAfter p n- afterRegion = nodeRegion after- whenFail (do putStrLn $ "after = " <> show after- putStrLn $ "after reg = " <> show afterRegion- )- (regionStart afterRegion >= p)--prop_fromNodeToFinal :: NTTT -> Property-prop_fromNodeToFinal (N t) = forAll (regionInside (subtreeRegion $ snd t)) $ \r -> do- let final@(_, finalSubtree) = fromNodeToFinal r t- finalRegion = subtreeRegion finalSubtree- whenFail (do putStrLn $ "final = " <> show final- putStrLn $ "final reg = " <> show finalRegion- putStrLn $ "leaf after = " <> show (fromLeafToLeafAfter (regionEnd r) t)- ) $ do- r `includedRegion` finalRegion--#endif
src/Yi/Types.hs view
@@ -297,8 +297,6 @@ -- ^ Buffer-local keymap modification , modeIndent :: syntax -> IndentBehaviour -> BufferM () -- ^ emacs-style auto-indent line- , modeAdjustBlock :: syntax -> Int -> BufferM ()- -- ^ adjust the indentation after modification , modeFollow :: syntax -> Action -- ^ Follow a \"link\" in the file. (eg. go to location of error message) , modeIndentSettings :: IndentSettings
src/Yi/UI/Common.hs view
@@ -2,6 +2,8 @@ module Yi.UI.Common where +import System.Exit (ExitCode)+ {- | Record presenting a frontend's interface. The functions 'layout' and 'refresh' are both run by the editor's main loop,@@ -44,13 +46,13 @@ should wrap GUI updates in @postGUIAsync@. -} data UI e = UI- { main :: IO () -- ^ Main loop- , end :: Bool -> IO () -- ^ Clean up, and also terminate if given 'true'- , suspend :: IO () -- ^ Suspend (or minimize) the program- , refresh :: e -> IO () -- ^ Refresh the UI with the given state- , userForceRefresh :: IO () -- ^ User force-refresh (in case the screen has been messed up from outside)- , layout :: e -> IO e -- ^ Set window width and height- , reloadProject :: FilePath -> IO () -- ^ Reload cabal project views+ { main :: IO () -- ^ Main loop+ , end :: Maybe ExitCode -> IO () -- ^ Clean up, and also terminate if given an exit code.+ , suspend :: IO () -- ^ Suspend (or minimize) the program+ , refresh :: e -> IO () -- ^ Refresh the UI with the given state+ , userForceRefresh :: IO () -- ^ User force-refresh (in case the screen has been messed up from outside)+ , layout :: e -> IO e -- ^ Set window width and height+ , reloadProject :: FilePath -> IO () -- ^ Reload cabal project views } dummyUI :: UI e
yi-core.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.17.0.+-- This file has been generated from package.yaml by hpack version 0.17.1. -- -- see: https://github.com/sol/hpack name: yi-core-version: 0.14.1+version: 0.15.0 synopsis: Yi editor core library category: Yi homepage: https://github.com/yi-editor/yi#readme@@ -72,8 +72,7 @@ , unordered-containers >= 0.1.3 , xdg-basedir >= 0.2.1 , yi-language >= 0.1.1.0- , yi-rope >= 0.7.0.0- , semigroups+ , yi-rope >= 0.7.0.0 && < 0.9 if os(win32) build-depends: Win32@@ -89,15 +88,9 @@ cpp-options: -DHINT build-depends: hint > 0.3.1- if flag(testing)- cpp-options: -DTESTING- build-depends:- QuickCheck >= 2.7- , random exposed-modules: Yi Yi.Buffer- Yi.Buffer.Adjusted Yi.Buffer.HighLevel Yi.Buffer.Indent Yi.Buffer.Normal@@ -207,7 +200,7 @@ , unordered-containers >= 0.1.3 , xdg-basedir >= 0.2.1 , yi-language >= 0.1.1.0- , yi-rope >= 0.7.0.0+ , yi-rope >= 0.7.0.0 && < 0.9 , tasty , tasty-hunit , tasty-quickcheck@@ -265,7 +258,7 @@ , unordered-containers >= 0.1.3 , xdg-basedir >= 0.2.1 , yi-language >= 0.1.1.0- , yi-rope >= 0.7.0.0+ , yi-rope >= 0.7.0.0 && < 0.9 , yi-core , criterion , deepseq