yi 0.10.1 → 0.11.0
raw patch · 44 files changed
+610/−272 lines, 44 filesdep ~vtydep ~yi-rope
Dependency ranges changed: vty, yi-rope
Files
- src/library/Yi/Buffer/Adjusted.hs +1/−4
- src/library/Yi/Buffer/HighLevel.hs +10/−7
- src/library/Yi/Buffer/Implementation.hs +17/−12
- src/library/Yi/Buffer/Misc.hs +30/−3
- src/library/Yi/Buffer/TextUnit.hs +3/−3
- src/library/Yi/Command.hs +5/−0
- src/library/Yi/Core.hs +54/−31
- src/library/Yi/Dired.hs +29/−19
- src/library/Yi/Editor.hs +3/−6
- src/library/Yi/Eval.hs +3/−4
- src/library/Yi/File.hs +49/−12
- src/library/Yi/Keymap/Emacs.hs +4/−3
- src/library/Yi/Keymap/Emacs/Utils.hs +32/−38
- src/library/Yi/Keymap/Vim/Ex.hs +4/−0
- src/library/Yi/Keymap/Vim/Ex/Commands/Cabal.hs +1/−1
- src/library/Yi/Keymap/Vim/Ex/Commands/Common.hs +36/−1
- src/library/Yi/Keymap/Vim/Ex/Commands/Make.hs +28/−0
- src/library/Yi/Keymap/Vim/Ex/Commands/Quit.hs +12/−15
- src/library/Yi/Keymap/Vim/Ex/Commands/Shell.hs +30/−0
- src/library/Yi/Keymap/Vim/Ex/Commands/Tag.hs +20/−2
- src/library/Yi/Keymap/Vim/Ex/Commands/Write.hs +12/−4
- src/library/Yi/Keymap/Vim/ExMap.hs +2/−2
- src/library/Yi/Keymap/Vim/InsertMap.hs +19/−10
- src/library/Yi/Keymap/Vim/Motion.hs +1/−0
- src/library/Yi/Keymap/Vim/NormalMap.hs +8/−7
- src/library/Yi/Keymap/Vim/NormalOperatorPendingMap.hs +14/−7
- src/library/Yi/Keymap/Vim/Tag.hs +48/−33
- src/library/Yi/Keymap/Vim/VisualMap.hs +15/−0
- src/library/Yi/Main.hs +2/−2
- src/library/Yi/Misc.hs +1/−1
- src/library/Yi/Mode/Compilation.hs +2/−3
- src/library/Yi/Modes.hs +7/−2
- src/library/Yi/Tag.hs +8/−7
- src/library/Yi/Types.hs +4/−3
- src/library/Yi/UI/Pango.hs +13/−10
- src/library/Yi/UI/Pango/Control.hs +13/−9
- src/library/Yi/UI/SimpleLayout.hs +9/−1
- src/library/Yi/UI/Vty.hs +6/−4
- src/library/Yi/Window.hs +4/−3
- src/tests/vimtests/delete/d00.test +12/−0
- src/tests/vimtests/find/f5.test +12/−0
- src/tests/vimtests/insertion/O3.test +11/−0
- src/tests/vimtests/insertion/o3.test +11/−0
- yi.cabal +5/−3
src/library/Yi/Buffer/Adjusted.hs view
@@ -82,12 +82,9 @@ (start, lengths) <- shapeOfBlockRegionB reg moveTo start forM_ (zip [1..] lengths) $ \(i, l) -> do- deleteN l+ B.deleteN l moveTo start lineMoveRel i- case lengths of- [l] -> adjBlock (-l)- _ -> return () return start deleteRegionWithStyleB reg style = savingPointB $ do
src/library/Yi/Buffer/HighLevel.hs view
@@ -447,10 +447,12 @@ when eol leftB transposeB Character Forward --- | Delete trailing whitespace from all lines+-- | Delete trailing whitespace from all lines. Uses 'savingPositionB'+-- to get back to where it was. deleteTrailingSpaceB :: BufferM () deleteTrailingSpaceB =- regionOfB Document >>= modifyRegionB (tru . mapLines stripEnd)+ regionOfB Document >>=+ savingPositionB . modifyRegionB (tru . mapLines stripEnd) where -- Strips the space from the end of each line, preserving -- newlines.@@ -865,11 +867,12 @@ sortLines = modifyExtendedSelectionB Line (onLines sort) -- | Helper function: revert the buffer contents to its on-disk version-revertB :: YiString -> UTCTime -> BufferM ()-revertB s now = do- r <- regionOfB Document- replaceRegionB r s- markSavedB now+revertB :: YiString -> Maybe R.ConverterName -> UTCTime -> BufferM ()+revertB s cn now = do+ r <- regionOfB Document+ replaceRegionB r s+ encodingConverterNameA .= cn+ markSavedB now -- get lengths of parts covered by block region --
src/library/Yi/Buffer/Implementation.hs view
@@ -39,7 +39,6 @@ , newBI , solPoint , solPoint'- , eolPoint , eolPoint' , charsFromSolBI , regexRegionBI@@ -347,22 +346,28 @@ -- | Point that's at EOL. Notably, this puts you right before the -- newline character if one exists, and right at the end of the text -- if one does not.-eolPoint :: Int -- ^ Line for which to grab EOL for- -> BufferImpl syntax -> Point-eolPoint l = Point . checkEol . fst . R.splitAtLine l . mem+eolPoint' :: Point+ -- ^ Point from which we take the line to find the EOL of+ -> BufferImpl syntax+ -> Point+eolPoint' p@(Point ofs) fb = Point . checkEol . fst . R.splitAtLine ln $ mem fb where- -- In case we're somewhere without trailing newline, we need to stay where we are- checkEol t = let l' = R.length t in case R.last t of- Just '\n' -> l' - 1- _ -> l'+ ln = lineAt p fb+ -- In case we're somewhere without trailing newline, we need to+ -- stay where we are+ checkEol t =+ let l' = R.length t+ in case R.last t of+ -- We're looking at EOL and we weren't asking for EOL past+ -- this point, so back up one for good visual effect+ Just '\n' | l' > ofs -> l' - 1+ -- We asked for EOL past the last newline so just go to the+ -- very end of content+ _ -> l' -- | Get begining of the line relatively to @point@. solPoint' :: Point -> BufferImpl syntax -> Point solPoint' point fb = solPoint (lineAt point fb) fb---- | Get end of the line relative to the point.-eolPoint' :: Point -> BufferImpl s -> Point-eolPoint' p fb = eolPoint (lineAt p fb) fb charsFromSolBI :: Point -> BufferImpl syntax -> YiString charsFromSolBI pnt fb = nelemsBI (fromIntegral $ pnt - sol) sol fb
src/library/Yi/Buffer/Misc.hs view
@@ -107,6 +107,7 @@ , delOverlayLayerB , savingExcursionB , savingPointB+ , savingPositionB , pendingUpdatesA , highlightSelectionA , rectangleSelectionA@@ -178,6 +179,8 @@ , decreaseFontSize , increaseFontSize , indentSettingsB+ , fontsizeVariationA+ , encodingConverterNameA ) where import Control.Applicative@@ -337,6 +340,9 @@ ro <-use readOnlyA modeNm <- gets (withMode0 modeName) unchanged <- gets isUnchangedBuffer+ enc <- use encodingConverterNameA >>= return . \case+ Nothing -> mempty+ Just cn -> T.pack $ R.unCn cn let pct | pos == 0 || s == 0 = " Top" | pos == s = " Bot"@@ -348,7 +354,7 @@ toT = T.pack . show nm <- gets $ shortIdentString (length prefix)- return $ T.concat [ readOnly', changed, " ", nm+ return $ T.concat [ enc, " ", readOnly', changed, " ", nm , " ", hexChar, " " , "L", T.justifyRight 5 ' ' (toT ln) , " "@@ -560,6 +566,7 @@ , updateTransactionInFlight = False , updateTransactionAccum = [] , fontsizeVariation = 0+ , encodingConverterName = Nothing } } epoch :: UTCTime@@ -595,7 +602,12 @@ moveTo :: Point -> BufferM () moveTo x = do forgetPreferCol- (.= x) . markPointA =<< getInsMark+ maxP <- sizeB+ let p = case () of+ _ | x < 0 -> Point 0+ | x > maxP -> maxP+ | otherwise -> x+ (.= p) . markPointA =<< getInsMark ------------------------------------------------------------------------ @@ -1024,12 +1036,27 @@ getter b = markPoint $ getMarkValueRaw mark b setter b pos = modifyMarkRaw mark (\v -> v {markPoint = pos}) b --- | perform an @BufferM a@, and return to the current point+-- | Perform an @BufferM a@, and return to the current point. savingPointB :: BufferM a -> BufferM a savingPointB f = savingPrefCol $ do p <- pointB res <- f moveTo p+ return res++-- | Perform an @BufferM a@, and return to the current line and column+-- number. The difference between this and 'savingPointB' is that here+-- we attempt to return to the specific line and column number, rather+-- than a specific number of characters from the beginning of the+-- buffer.+--+-- In case the column is further away than EOL, the point is left at+-- EOL: 'moveToLineColB' is used internally.+savingPositionB :: BufferM a -> BufferM a+savingPositionB f = savingPrefCol $ do+ (c, l) <- (,) <$> curCol <*> curLn+ res <- f+ moveToLineColB l c return res pointAt :: BufferM a -> BufferM Point
src/library/Yi/Buffer/TextUnit.hs view
@@ -314,9 +314,9 @@ genMoveB Document _ Backward = moveTo 0 -- impossible to go outside beginning of doc. genMoveB Character _ Forward = rightB genMoveB Character _ Backward = leftB-genMoveB VLine _ Forward =- do ofs <- lineMoveRel 1- when (ofs < 1) (maybeMoveB Line Forward)+genMoveB VLine _ Forward = do+ ofs <- lineMoveRel 1+ when (ofs < 1) (maybeMoveB Line Forward) genMoveB VLine _ Backward = lineUp genMoveB unit (boundDir, boundSide) moveDir = doUntilB_ (genAtBoundaryB unit boundDir boundSide) (moveB Character moveDir)
src/library/Yi/Command.hs view
@@ -108,11 +108,16 @@ cabalRun :: T.Text -> (Either SomeException ExitCode -> YiM x) -> CommandArguments -> YiM () cabalRun cmd onExit (CommandArguments args) = buildRun "cabal" (cmd:args) onExit +makeRun :: (Either SomeException ExitCode -> YiM x) -> CommandArguments -> YiM ()+makeRun onExit (CommandArguments args) = buildRun "make" args onExit+ ----------------------- -- | cabal-build cabalBuildE :: CommandArguments -> YiM () cabalBuildE = cabalRun "build" (const $ return ()) +makeBuildE :: CommandArguments -> YiM ()+makeBuildE = makeRun (const $ return ()) shell :: YiM BufferRef shell = do
src/library/Yi/Core.hs view
@@ -30,6 +30,7 @@ -- * Global editor actions , errorEditor -- :: String -> YiM () , closeWindow -- :: YiM ()+ , closeWindowEmacs -- * Interacting with external commands , runProcessWithInput -- :: String -> String -> YiM String@@ -88,7 +89,7 @@ import Yi.Style (errorStyle, strongHintStyle) import qualified Yi.UI.Common as UI import Yi.Utils-import Yi.Window (dummyWindow, bufkey, wkey, winRegion)+import Yi.Window (dummyWindow, bufkey, wkey, winRegion, isMini) import Yi.PersistentState (loadPersistentState, savePersistentState) -- | Make an action suitable for an interactive run.@@ -97,9 +98,9 @@ interactive isRefreshNeeded action = do evs <- withEditor $ use pendingEventsA logPutStrLn $ ">>> interactively" <> showEvs evs- withEditor $ (%=) buffersA (fmap $ undosA %~ addChangeU InteractivePoint)+ withEditor $ buffersA %= (fmap $ undosA %~ addChangeU InteractivePoint) mapM_ runAction action- withEditor $ (%=) killringA krEndCmd+ withEditor $ killringA %= krEndCmd when (isRefreshNeeded == MustRefresh) refreshEditor logPutStrLn "<<<" return ()@@ -278,34 +279,39 @@ -- FIXME: since we do IO here we must catch exceptions! checkFileChanges :: Editor -> IO Editor checkFileChanges e0 = do- now <- getCurrentTime- -- Find out if any file was modified "behind our back" by- -- other processes.- newBuffers <- forM (buffers e0) $ \b ->- let nothing = return (b, Nothing)- in if bkey b `elem` visibleBuffers- then- case b ^.identA of- FileBuffer fname -> do- fe <- doesFileExist fname- if not fe then nothing else do- modTime <- fileModTime fname- if b ^. lastSyncTimeA < modTime- then if isUnchangedBuffer b- then do newContents <- R.readFile fname- return (snd $ runBuffer (dummyWindow $ bkey b) b (revertB newContents now), Just msg1)- else return (b, Just msg2)- else nothing- _ -> nothing- else nothing- -- show appropriate update message if applicable- return $ case getFirst (foldMap (First . snd) newBuffers) of- Just msg -> (statusLinesA %~ DelayList.insert msg) e0 {buffers = fmap fst newBuffers}- Nothing -> e0- where msg1 = (1, (["File was changed by a concurrent process, reloaded!"], strongHintStyle))- msg2 = (1, (["Disk version changed by a concurrent process"], strongHintStyle))- visibleBuffers = fmap bufkey $ windows e0- fileModTime f = posixSecondsToUTCTime . realToFrac . modificationTime <$> getFileStatus f+ now <- getCurrentTime+ -- Find out if any file was modified "behind our back" by+ -- other processes.+ newBuffers <- forM (buffers e0) $ \b ->+ let nothing = return (b, Nothing)+ in if bkey b `elem` visibleBuffers+ then+ case b ^. identA of+ FileBuffer fname -> do+ fe <- doesFileExist fname+ if not fe then nothing else do+ modTime <- fileModTime fname+ if b ^. lastSyncTimeA < modTime+ then if isUnchangedBuffer b+ then R.readFile fname >>= return . \case+ Left m ->+ (runDummy b (readOnlyA .= True), Just $ msg3 m)+ Right (newContents, c) ->+ (runDummy b (revertB newContents (Just c) now), Just msg1)+ else return (b, Just msg2)+ else nothing+ _ -> nothing+ else nothing+ -- show appropriate update message if applicable+ return $ case getFirst (foldMap (First . snd) newBuffers) of+ Just msg -> (statusLinesA %~ DelayList.insert msg) e0 {buffers = fmap fst newBuffers}+ Nothing -> e0+ where msg1 = (1, (["File was changed by a concurrent process, reloaded!"], strongHintStyle))+ msg2 = (1, (["Disk version changed by a concurrent process"], strongHintStyle))+ msg3 x = (1, (["File changed on disk to unknown encoding, not updating buffer: " <> x], strongHintStyle))+ visibleBuffers = fmap bufkey $ windows e0+ fileModTime f = posixSecondsToUTCTime . realToFrac . modificationTime <$> getFileStatus f+ runDummy b act = snd $ runBuffer (dummyWindow $ bkey b) b act -- | Hide selection, clear "syntax dirty" flag (as appropriate). clearAllSyntaxAndHideSelection :: Editor -> Editor@@ -412,6 +418,23 @@ tabCount <- withEditor $ uses tabsA PL.length when (winCount == 1 && tabCount == 1) quitEditor withEditor tryCloseE++-- | This is a like 'closeWindow' but with emacs behaviour of C-x 0:+-- if we're trying to close the minibuffer or last buffer in the+-- editor, then just print a message warning the user about it rather+-- closing mini or quitting editor.+closeWindowEmacs :: YiM ()+closeWindowEmacs = do+ wins <- withEditor $ use windowsA+ let winCount = PL.length wins+ tabCount <- withEditor $ uses tabsA PL.length++ case () of+ _ | winCount == 1 && tabCount == 1 ->+ printMsg "Attempt to delete sole ordinary window"+ | isMini (PL._focus wins) ->+ printMsg "Attempt to delete the minibuffer"+ | otherwise -> withEditor tryCloseE onYiVar :: (Yi -> YiVar -> IO (YiVar, a)) -> YiM a onYiVar f = do
src/library/Yi/Dired.hs view
@@ -195,7 +195,10 @@ -- -- @Yi.File@ module re-exports this, you probably want to import that -- instead.-editFile :: FilePath -> YiM BufferRef+--+-- In case of a decoding failure, failure message is returned instead+-- of the 'BufferRef'.+editFile :: FilePath -> YiM (Either T.Text BufferRef) editFile filename = do f <- io $ userToCanonPath filename @@ -206,27 +209,34 @@ b <- case dupBufs of [] -> if dirExists- then diredDirBuffer f- else setupMode f =<< if fileExists- then fileToNewBuffer f- else newEmptyBuffer f- (h:_) -> return $ bkey h+ then Right <$> diredDirBuffer f+ else do+ nb <- if fileExists+ then fileToNewBuffer f+ else Right <$> newEmptyBuffer f+ case nb of+ Left m -> return $ Left m+ Right buf -> Right <$> setupMode f buf - withEditor $ switchToBufferE b >> addJumpHereE- return b- where- fileToNewBuffer :: FilePath -> YiM BufferRef- fileToNewBuffer f = do- now <- io getCurrentTime- contents <- io $ R.readFile f- permissions <- io $ getPermissions f+ (h:_) -> return . Right $ bkey h - b <- stringToNewBuffer (FileBuffer f) contents- withGivenBuffer b $ markSavedB now+ case b of+ Left m -> return $ Left m+ Right bf -> withEditor (switchToBufferE bf >> addJumpHereE) >> return b+ where+ fileToNewBuffer :: FilePath -> YiM (Either T.Text BufferRef)+ fileToNewBuffer f = io getCurrentTime >>= \n -> io (R.readFile f) >>= \case+ Left m -> return $ Left m+ Right (contents, conv) -> do+ permissions <- io $ getPermissions f - unless (writable permissions) (withGivenBuffer b $ assign readOnlyA True)+ b <- stringToNewBuffer (FileBuffer f) contents+ withGivenBuffer b $ do+ encodingConverterNameA .= Just conv+ markSavedB n+ unless (writable permissions) (readOnlyA .= True) - return b+ return $ Right b newEmptyBuffer :: FilePath -> YiM BufferRef newEmptyBuffer f =@@ -896,7 +906,7 @@ diredRefresh printMsg $ showT (st ^. diredOpSucCnt) <> " of " <> showT total <> " item(s) moved."- showNothing _ = (withEditor . printMsg) "Quit"+ showNothing _ = printMsg "Quit" total = length fs -- | copy selected files in a given directory to the target location given
src/library/Yi/Editor.hs view
@@ -133,9 +133,6 @@ import Yi.Utils hiding ((+~)) import Yi.Window -liftEditor :: MonadEditor m => EditorM a -> m a-liftEditor = withEditor- instance Binary Editor where put (Editor bss bs supply ts dv _sl msh kr _re _dir _ev _cwa ) = let putNE (x :| xs) = put x >> put xs@@ -426,8 +423,8 @@ b <- case bs of (b':_) -> return $ bkey b' [] -> stringToNewBuffer (MemBuffer "messages") mempty- let m = '(' `R.cons` listify (R.fromText <$> fst s) Mon.<> ", <function>)"- withGivenBuffer b $ botB >> insertN m+ let m = listify $ R.fromText <$> fst s+ withGivenBuffer b $ botB >> insertN (m `R.snoc` '\n') -- --------------------------------------------------------------------- -- kill-register (vim-style) interface to killring.@@ -486,7 +483,7 @@ -- | Create a new zero size window on a given buffer newZeroSizeWindow :: Bool -> BufferRef -> WindowRef -> Window-newZeroSizeWindow mini bk ref = Window mini bk [] 0 emptyRegion ref 0 Nothing+newZeroSizeWindow mini bk ref = Window mini bk [] 0 0 emptyRegion ref 0 Nothing -- | Create a new window onto the given buffer. newWindowE :: Bool -> BufferRef -> EditorM Window
src/library/Yi/Eval.hs view
@@ -194,7 +194,7 @@ publishAction :: (YiAction a x, Show x) => String -> a -> ConfigM () publishAction s a = publishedActions %= M.insert s (makeAction a) --- Evaluator based on a fixed list of published actions. Has a few+-- | Evaluator based on a fixed list of published actions. Has a few -- differences from 'ghciEvaluator': -- -- * expressions can't be evaluated@@ -218,9 +218,8 @@ -> Int -- ^ Line to jump to. -> Int -- ^ Column to jump to. -> YiM ()-jumpToE filename line column = do- _ <- editFile filename- withCurrentBuffer $ gotoLn line >> moveXorEol column+jumpToE filename line column =+ openingNewFile filename $ gotoLn line >> moveXorEol column -- | Regex parsing the error message format. errorRegex :: Regex
src/library/Yi/File.hs view
@@ -11,7 +11,8 @@ module Yi.File ( -- * File-based actions- editFile, -- :: YiM BufferRef+ editFile,+ openingNewFile, viWrite, viWriteTo, viSafeWriteTo, fwriteE, -- :: YiM ()@@ -22,11 +23,13 @@ revertE, -- :: YiM () -- * Helper functions- setFileName+ setFileName,+ deservesSave ) where import Control.Applicative-import Control.Lens+import Control.Lens hiding (act)+import Control.Monad (void) import Control.Monad.Base import Data.Monoid import qualified Data.Text as T@@ -43,19 +46,33 @@ import Yi.String import Yi.Utils +-- | Tries to open a new buffer with 'editFile' and runs the given+-- action on the buffer handle if it succeeds.+--+-- If the 'editFile' fails, just the failure message is printed.+openingNewFile :: FilePath -> BufferM a -> YiM ()+openingNewFile fp act = editFile fp >>= \case+ Left m -> printMsg m+ Right ref -> void $ withGivenBuffer ref act+ -- | Revert to the contents of the file on disk revertE :: YiM () revertE = do withCurrentBuffer (gets file) >>= \case Just fp -> do now <- io getCurrentTime- s <- liftBase $ R.readFile fp- withCurrentBuffer $ revertB s now- printMsg ("Reverted from " <> showT fp)+ rf <- liftBase $ R.readFile fp >>= \case+ Left m -> print ("Can't revert: " <> m) >> return Nothing+ Right (c, cv) -> return $ Just (c, Just cv)+ case rf of+ Nothing -> return ()+ Just (s, conv) -> do+ withCurrentBuffer $ revertB s conv now+ printMsg ("Reverted from " <> showT fp) Nothing -> printMsg "Can't revert, no file associated with buffer." --- | Try to write a file in the manner of vi\/vim+-- | Try to write a file in the manner of vi/vim -- Need to catch any exception to avoid losing bindings viWrite :: YiM () viWrite = do@@ -96,15 +113,21 @@ -- | Write a given buffer to disk if it is associated with a file. fwriteBufferE :: BufferRef -> YiM () fwriteBufferE bufferKey = do- nameContents <- withGivenBuffer bufferKey ((,) <$> gets file- <*> streamB Forward 0)+ nameContents <- withGivenBuffer bufferKey $ do+ fl <- gets file+ st <- streamB Forward 0+ conv <- use encodingConverterNameA+ return (fl, st, conv)+ case nameContents of- (Just f, contents) -> io (doesDirectoryExist f) >>= \case+ (Just f, contents, conv) -> io (doesDirectoryExist f) >>= \case True -> printMsg "Can't save over a directory, doing nothing." False -> do- liftBase $ R.writeFile f contents+ liftBase $ case conv of+ Nothing -> R.writeFileUsingText f contents+ Just cn -> R.writeFile f contents cn io getCurrentTime >>= withGivenBuffer bufferKey . markSavedB- (Nothing, _c) -> printMsg "Buffer not associated with a file"+ (Nothing, _, _) -> printMsg "Buffer not associated with a file" -- | Write current buffer to disk as @f@. The file is also set to @f@. fwriteToE :: T.Text -> YiM ()@@ -130,3 +153,17 @@ setFileName b filename = do cfn <- liftBase $ userToCanonPath filename withGivenBuffer b $ assign identA $ FileBuffer cfn++-- | Checks if the given buffer deserves a save: whether it's a file+-- buffer and whether it's pointing at a file rather than a directory.+deservesSave :: FBuffer -> YiM Bool+deservesSave b+ | isUnchangedBuffer b = return False+ | otherwise = isFileBuffer b++-- | Is there a proper file associated with the buffer?+-- In other words, does it make sense to offer to save it?+isFileBuffer :: FBuffer -> YiM Bool+isFileBuffer b = case b ^. identA of+ MemBuffer _ -> return False+ FileBuffer fn -> not <$> liftBase (doesDirectoryExist fn)
src/library/Yi/Keymap/Emacs.hs view
@@ -35,7 +35,8 @@ import Data.Text () import Yi.Buffer import Yi.Command (shellCommandE)-import Yi.Core (closeWindow, runAction, suspendEditor, userForceRefresh, withSyntax)+import Yi.Core (closeWindowEmacs, runAction, suspendEditor,+ userForceRefresh, withSyntax) import Yi.Dired import Yi.Editor import Yi.File@@ -183,7 +184,7 @@ , ctrlCh 'c' ?>> ctrlC -- All The key-bindings of the form M-c where 'c' is some character.- , metaCh ' ' ?>>! justOneSep+ , metaCh ' ' ?>>! justOneSep univArg , metaCh 'v' ?>>! scrollUpE univArg , metaCh '!' ?>>! shellCommandE , metaCh '<' ?>>! repeatingArg topB@@ -255,7 +256,7 @@ -- These keybindings are all preceded by a 'C-x' so for example to -- quit the editor we do a 'C-x C-c' ctrlX = choice [ ctrlCh 'o' ?>>! deleteBlankLinesB- , char '0' ?>>! closeWindow+ , char '0' ?>>! closeWindowEmacs , char '1' ?>>! closeOtherE , char '2' ?>>! splitE , char 'h' ?>>! selectAll
src/library/Yi/Keymap/Emacs/Utils.hs view
@@ -98,18 +98,6 @@ getModifiedBuffers :: YiM [FBuffer] getModifiedBuffers = filterM deservesSave =<< gets bufferSet -deservesSave :: FBuffer -> YiM Bool-deservesSave b- | isUnchangedBuffer b = return False- | otherwise = isFileBuffer b---- | Is there a proper file associated with the buffer?--- In other words, does it make sense to offer to save it?-isFileBuffer :: (Functor m, MonadBase IO m) => FBuffer -> m Bool-isFileBuffer b = case b ^. identA of- MemBuffer _ -> return False- FileBuffer fn -> not <$> liftBase (doesDirectoryExist fn)- -------------------------------------------------- -- Takes in a list of buffers which have been identified -- as modified since their last save.@@ -266,30 +254,28 @@ -- | Finds file and runs specified action on the resulting buffer findFileAndDo :: T.Text -- ^ Prompt- -> (BufferRef -> YiM a) -- ^ Action to run on the resulting buffer+ -> BufferM a -- ^ Action to run on the resulting buffer -> YiM () findFileAndDo prompt act = promptFile prompt $ \filename -> do- (withEditor . printMsg) $ "loading " <> filename- void $ editFile (T.unpack filename) >>= act+ printMsg $ "loading " <> filename+ openingNewFile (T.unpack filename) act -- | Open a file using the minibuffer. We have to set up some stuff to -- allow hints and auto-completion. findFile :: YiM ()-findFile = findFileAndDo "find file:" return+findFile = findFileAndDo "find file:" $ return () -- | Like 'findFile' but sets the resulting buffer to read-only. findFileReadOnly :: YiM ()-findFileReadOnly = findFileAndDo "find file (read only):" $ \b ->- withGivenBuffer b (readOnlyA .= True)+findFileReadOnly = findFileAndDo "find file (read only):" $ readOnlyA .= True -- | Open a file in a new tab using the minibuffer. findFileNewTab :: YiM () findFileNewTab = promptFile "find file (new tab): " $ \filename -> do withEditor newTabE- (withEditor . printMsg) $ "loading " <> filename+ printMsg $ "loading " <> filename void . editFile $ T.unpack filename - scrollDownE :: UnivArgument -> BufferM () scrollDownE a = case a of Nothing -> downScreenB@@ -329,27 +315,38 @@ -- | If on separators (space, tab, unicode seps), reduce multiple--- separators to just a single separator. If we aren't looking at a separator,--- insert a single space. This kind of behaves as emacs ‘just-one-space’--- function with the argument of ‘1’ but it prefers to use the separator we're--- looking at instead of assuming a space.-justOneSep :: BufferM ()-justOneSep = readB >>= \c ->+-- separators to just a single separator (or however many given+-- through 'UniversalArgument').+--+-- If we aren't looking at a separator, insert a single space. This is+-- like emacs ‘just-one-space’ but doesn't deal with negative argument+-- case but works with other separators than just space. What counts+-- as a separator is decided by 'isAnySep' modulo @\n@ character.+--+-- Further, it will only reduce a single type of separator at once: if+-- we have hard tabs followed by spaces, we are able to reduce one and+-- not the other.+justOneSep :: UnivArgument -> BufferM ()+justOneSep u = readB >>= \c -> pointB >>= \point -> case point of- Point 0 -> if isAnySep c then deleteSeparators else insertB ' '+ Point 0 -> if isSep c then deleteSeparators else insertMult c Point x ->- if isAnySep c+ if isSep c then deleteSeparators else readAtB (Point $ x - 1) >>= \d -> -- We weren't looking at separator but there might be one behind us- if isAnySep d+ if isSep d then moveB Character Backward >> deleteSeparators- else insertB ' ' -- no separators, insert a space just like emacs does+ else insertMult ' ' -- no separators, insert a space just+ -- like emacs does where+ isSep c = c /= '\n' && isAnySep c+ insertMult c = insertN $ R.replicateChar (maybe 1 (max 1) u) c+ deleteSeparators = do genMaybeMoveB unitSepThisLine (Backward, InsideBound) Backward moveB Character Forward- doIfCharB isAnySep $ deleteB unitSepThisLine Forward+ doIfCharB isSep $ deleteB unitSepThisLine Forward @@ -358,7 +355,7 @@ joinLinesE Nothing = return () joinLinesE (Just _) = do moveB VLine Forward- moveToSol >> transformB (const " ") Character Backward >> justOneSep+ moveToSol >> transformB (const " ") Character Backward >> justOneSep Nothing -- | Shortcut to use a default list when a blank list is given. -- Used for default values to emacs queries@@ -394,11 +391,8 @@ gotoTag tag = visitTagTable $ \tagTable -> case lookupTag tag tagTable of- Nothing -> fail $ "No tags containing " ++ unTag' tag- Just (filename, line) -> do- void $ editFile filename- void $ withCurrentBuffer $ gotoLn line- return ()+ [] -> printMsg $ "No tags containing " <> _unTag tag+ (filename, line):_ -> openingNewFile filename $ gotoLn line -- | Call continuation @act@ with the TagTable. Uses the global table -- and prompts the user if it doesn't exist@@ -425,7 +419,7 @@ t <- withCurrentBuffer $ getRectangle >>= \(reg, _, _) -> readRegionB reg let nls = R.countNewLines t return (if nls == 0 then 1 else nls, length $ R.words t, R.length t)- (withEditor . printMsg) $ T.unwords [ "Region has", showT l, p l "line" <> ","+ printMsg $ T.unwords [ "Region has", showT l, p l "line" <> "," , showT w, p w "word" <> ", and" , showT c, p w "character" <> "." ]
src/library/Yi/Keymap/Vim/Ex.hs view
@@ -24,10 +24,12 @@ import qualified Yi.Keymap.Vim.Ex.Commands.Edit as Edit import qualified Yi.Keymap.Vim.Ex.Commands.Global as Global import qualified Yi.Keymap.Vim.Ex.Commands.GotoLine as GotoLine+import qualified Yi.Keymap.Vim.Ex.Commands.Make as Make import qualified Yi.Keymap.Vim.Ex.Commands.Nohl as Nohl import qualified Yi.Keymap.Vim.Ex.Commands.Paste as Paste import qualified Yi.Keymap.Vim.Ex.Commands.Quit as Quit import qualified Yi.Keymap.Vim.Ex.Commands.Reload as Reload+import qualified Yi.Keymap.Vim.Ex.Commands.Shell as Shell import qualified Yi.Keymap.Vim.Ex.Commands.Substitute as Substitute import qualified Yi.Keymap.Vim.Ex.Commands.Tag as Tag import qualified Yi.Keymap.Vim.Ex.Commands.Write as Write@@ -45,11 +47,13 @@ , Edit.parse , Global.parse , GotoLine.parse+ , Make.parse , Nohl.parse , Paste.parse , Quit.parse , Reload.parse , Substitute.parse+ , Shell.parse , Tag.parse , Write.parse , Yi.parse
src/library/Yi/Keymap/Vim/Ex/Commands/Cabal.hs view
@@ -27,7 +27,7 @@ parse :: EventString -> Maybe ExCommand parse = Common.parse $ do void $ P.try (P.string "cabal build") <|> P.try (P.string "cabal")- args <- map T.pack <$> P.many (P.many1 P.space *> P.many1 P.anyChar)+ args <- Common.commandArgs return $ Common.impureExCommand { cmdShow = T.pack "cabal build" , cmdAction = YiA $ cabalBuildE $ CommandArguments args
src/library/Yi/Keymap/Vim/Ex/Commands/Common.hs view
@@ -23,6 +23,8 @@ , pureExCommand , impureExCommand , errorNoWrite+ , commandArgs+ , needsSaving ) where import Control.Applicative@@ -35,6 +37,7 @@ import Text.Read (readMaybe) import Yi.Buffer import Yi.Editor+import Yi.File import Yi.Keymap import Yi.Keymap.Vim.Common import Yi.Keymap.Vim.Ex.Types@@ -130,7 +133,7 @@ -- actual file is in the second buffer in bufferStack gets bufferStack >>= \case _ :| [] -> do- withEditor $ printMsg "filenameComplete: Expected to see minibuffer!"+ printMsg "filenameComplete: Expected to see minibuffer!" return [] _ :| bufferRef : _ -> do currentFileName <- fmap T.pack . withGivenBuffer bufferRef $@@ -173,3 +176,35 @@ -- | Show the common error message about an unsaved file on the status line. errorNoWrite :: EditorM () errorNoWrite = errorEditor "No write since last change (add ! to override)"++-- | Useful parser for any Ex command that acts kind of like a shell+commandArgs :: P.GenParser Char () [T.Text]+commandArgs = P.many commandArg++-- | Parse a single command, with a space in front+commandArg :: P.GenParser Char () T.Text+commandArg = fmap mconcat $ P.many1 P.space *> normArg++-- | Unquoted arg, allows for escaping of \, ", ', and space. Includes quoted arg+-- as a subset, because of things like aa"bbb"+normArg :: P.GenParser Char () [T.Text]+normArg = P.many1 $+ quoteArg '\"'+ <|> quoteArg '\"'+ <|> T.singleton <$> escapeChar+ <|> T.singleton <$> P.noneOf " \"\'\\"++-- | Quoted arg with char delim. Allows same escapes, but doesn't require escaping+-- of the opposite kind or space. However, it does allow escaping opposite kind like+-- normal, as well as allowing escaping of space (is this normal behavior?).+quoteArg :: Char -> P.GenParser Char () T.Text+quoteArg delim = fmap T.pack $ P.char delim + *> (P.many1 $ P.noneOf (delim:"\\") <|> escapeChar)+ <* P.char delim++-- | Parser for a single escape character+escapeChar :: P.GenParser Char () Char+escapeChar = P.char '\\' *> P.oneOf " \"\'\\"++needsSaving :: BufferRef -> YiM Bool+needsSaving = findBuffer >=> maybe (return False) deservesSave
+ src/library/Yi/Keymap/Vim/Ex/Commands/Make.hs view
@@ -0,0 +1,28 @@+{-# OPTIONS_HADDOCK show-extensions #-}++-- |+-- Module : Yi.Keymap.Vim.Ex.Commands.Make+-- License : GPL-2+-- Maintainer : yi-devel@googlegroups.com+-- Stability : experimental+-- Portability : portable++module Yi.Keymap.Vim.Ex.Commands.Make (parse) where++import Control.Applicative+import qualified Data.Text as T+import qualified Text.ParserCombinators.Parsec as P+import Yi.Command+import Yi.Keymap+import Yi.Keymap.Vim.Common+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common+import Yi.Keymap.Vim.Ex.Types+import Yi.MiniBuffer++parse :: EventString -> Maybe ExCommand+parse = Common.parse $ do+ args <- P.string "make" *> Common.commandArgs+ return $ Common.impureExCommand {+ cmdShow = T.pack "make"+ , cmdAction = YiA $ makeBuildE $ CommandArguments args+ }
src/library/Yi/Keymap/Vim/Ex/Commands/Quit.hs view
@@ -18,7 +18,7 @@ import Control.Lens import Control.Monad import Data.Foldable (find)-import Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.PointedList.Circular as PL import Data.Monoid import qualified Data.Text as T import qualified Text.ParserCombinators.Parsec as P@@ -70,33 +70,30 @@ quitWindowE :: YiM () quitWindowE = do- nw <- withCurrentBuffer needsAWindowB+ nw <- gets currentBuffer >>= Common.needsSaving ws <- withEditor $ use currentWindowA >>= windowsOnBufferE . bufkey if length ws == 1 && nw then errorEditor "No write since last change (add ! to override)"- else closeWindow+ else do+ winCount <- withEditor $ uses windowsA PL.length+ tabCount <- withEditor $ uses tabsA PL.length+ if winCount == 1 && tabCount == 1+ -- if its the last window, quitting will quit the editor+ then quitAllE+ else closeWindow quitAllE :: YiM () quitAllE = do- a :| as <- readEditor bufferStack- let needsWindow b = (b,) <$> withEditor (withGivenBuffer b needsAWindowB)- bs <- mapM needsWindow (a:as)+ let needsWindow b = (b,) <$> deservesSave b+ bs <- readEditor bufferSet >>= mapM needsWindow -- Vim only shows the first modified buffer in the error. case find snd bs of Nothing -> quitEditor Just (b, _) -> do- bufferName <- withEditor $ withGivenBuffer b $ gets file+ bufferName <- withEditor $ withGivenBuffer (bkey b) $ gets file errorEditor $ "No write since last change for buffer " <> showT bufferName <> " (add ! to override)" saveAndQuitAllE :: YiM () saveAndQuitAllE = Common.forAllBuffers fwriteBufferE >> quitEditor--needsAWindowB :: BufferM Bool-needsAWindowB = do- isWorthless <- gets (^. identA) >>= return . \case- MemBuffer _ -> True- FileBuffer _ -> False- canClose <- gets isUnchangedBuffer- return (not (isWorthless || canClose))
+ src/library/Yi/Keymap/Vim/Ex/Commands/Shell.hs view
@@ -0,0 +1,30 @@+{-# OPTIONS_HADDOCK show-extensions #-}++-- |+-- Module : Yi.Keymap.Vim.Ex.Commands.Shell+-- License : GPL-2+-- Maintainer : yi-devel@googlegroups.com+-- Stability : experimental+-- Portability : portable++module Yi.Keymap.Vim.Ex.Commands.Shell (parse) where++import Control.Applicative+import Control.Monad+import qualified Data.Text as T+import qualified Text.ParserCombinators.Parsec as P+import Yi.Command+import Yi.Keymap+import Yi.Keymap.Vim.Common+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common+import Yi.Keymap.Vim.Ex.Types++parse :: EventString -> Maybe ExCommand+parse = Common.parse $ do+ void $ P.char '!'+ cmd <- T.pack <$> P.many1 (P.noneOf " ")+ args <- Common.commandArgs+ return $ Common.impureExCommand {+ cmdShow = T.pack "!"+ , cmdAction = YiA $ buildRun cmd args (const $ return ())+ }
src/library/Yi/Keymap/Vim/Ex/Commands/Tag.hs view
@@ -10,6 +10,7 @@ module Yi.Keymap.Vim.Ex.Commands.Tag (parse) where +import Control.Applicative import Control.Monad import Data.Monoid import qualified Data.Text as T@@ -23,7 +24,12 @@ parse :: EventString -> Maybe ExCommand parse = Common.parse $ do- void $ P.string "ta"+ void $ P.string "t"+ parseTag <|> parseNext++parseTag :: P.GenParser Char () ExCommand+parseTag = do+ void $ P.string "a" void . P.optionMaybe $ P.string "g" t <- P.optionMaybe $ do void $ P.many1 P.space@@ -32,6 +38,11 @@ Nothing -> P.eof >> return (tag Nothing) Just t' -> return $! tag (Just (Tag (T.pack t'))) +parseNext :: P.GenParser Char () ExCommand+parseNext = do+ void $ P.string "next"+ return next+ tag :: Maybe Tag -> ExCommand tag Nothing = Common.impureExCommand { cmdShow = "tag"@@ -40,6 +51,13 @@ } tag (Just (Tag t)) = Common.impureExCommand { cmdShow = "tag " <> t- , cmdAction = YiA . gotoTag $ Tag t+ , cmdAction = YiA $ gotoTag (Tag t) 0 Nothing , cmdComplete = (fmap . fmap) (mappend "tag ") $ completeVimTag t+ }++next :: ExCommand+next = Common.impureExCommand {+ cmdShow = "tnext"+ , cmdAction = YiA nextTag+ , cmdComplete = return ["tnext"] }
src/library/Yi/Keymap/Vim/Ex/Commands/Write.hs view
@@ -15,6 +15,8 @@ import Data.Monoid import qualified Data.Text as T import qualified Text.ParserCombinators.Parsec as P+import Yi.Buffer+import Yi.Editor import Yi.File import Yi.Keymap import Yi.Keymap.Vim.Common@@ -23,14 +25,13 @@ parse :: EventString -> Maybe ExCommand parse = Common.parse $- P.choice [parseWrite, parseWriteAs]+ (P.try (P.string "write") <|> P.string "w")+ *> (parseWriteAs <|> parseWrite) where parseWrite = do- void $ P.try ( P.string "write") <|> P.string "w" alls <- P.many (P.try ( P.string "all") <|> P.string "a") return $! writeCmd $ not (null alls) parseWriteAs = do- void $ P.try ( P.string "write") <|> P.string "w" void $ P.many1 P.space filename <- T.pack <$> P.many1 P.anyChar return $! writeAsCmd filename@@ -38,7 +39,9 @@ writeCmd :: Bool -> ExCommand writeCmd allFlag = Common.impureExCommand { cmdShow = "write" <> if allFlag then "all" else ""- , cmdAction = YiA $ if allFlag then Common.forAllBuffers fwriteBufferE else viWrite+ , cmdAction = YiA $ if allFlag+ then Common.forAllBuffers tryWriteBuffer >> printMsg "All files written"+ else viWrite } writeAsCmd :: T.Text -> ExCommand@@ -46,3 +49,8 @@ cmdShow = "write " <> filename , cmdAction = YiA $ viWriteTo filename }++tryWriteBuffer :: BufferRef -> YiM ()+tryWriteBuffer buf = do+ ns <- Common.needsSaving buf+ when ns $ fwriteBufferE buf
src/library/Yi/Keymap/Vim/ExMap.hs view
@@ -60,7 +60,7 @@ ss -> do let s = commonTPrefix' ss updateCommand s- withEditor . printMsg . T.unwords . fmap (dropToLastWordOf s) $ ss+ printMsg . T.unwords . fmap (dropToLastWordOf s) $ ss updateCommand :: T.Text -> YiM () updateCommand s = do@@ -116,7 +116,7 @@ finishPrereq commandParsers cmdPred evs s = matchFromBool . and $ [ vsMode s == Ex- , evs == "<CR>"+ , evs `elem` ["<CR>", "<C-m>"] , case evStringToExCommand commandParsers (vsOngoingInsertEvents s) of Just cmd -> cmdPred cmd _ -> False
src/library/Yi/Keymap/Vim/InsertMap.hs view
@@ -18,7 +18,8 @@ import Data.Monoid import qualified Data.Text as T import Prelude hiding (head)-import Yi.Buffer.Adjusted hiding (Insert)+import qualified Yi.Buffer as B+import Yi.Buffer.Adjusted as BA hiding (Insert) import Yi.Editor import Yi.Event import Yi.Keymap.Vim.Common@@ -151,11 +152,19 @@ let allCursors = currentCursor :| secondaryCursors marks <- withCurrentBuffer $ forM' allCursors $ \cursor -> do moveTo cursor- -- getMarkB $ Just $ "v_I" <> show cursor getMarkB Nothing + -- Using autoindenting with multiple cursors+ -- is just too broken.+ let (insertB', insertN', deleteB', bdeleteB', deleteRegionB') =+ if null secondaryCursors+ then (BA.insertB, BA.insertN, BA.deleteB,+ BA.bdeleteB, BA.deleteRegionB)+ else (B.insertB, B.insertN, B.deleteB,+ B.bdeleteB, B.deleteRegionB)+ let bufAction = case T.unpack . _unEv $ evs of- (c:[]) -> insertB c+ (c:[]) -> insertB' c "<CR>" -> do isOldLineEmpty <- isCurrentLineEmptyB shouldTrimOldLine <- isCurrentLineAllWhiteSpaceB@@ -172,18 +181,18 @@ "<Tab>" -> do IndentSettings et _ts sw <- indentSettingsB if et- then insertN . R.fromString $ replicate sw ' '- else insertB '\t'+ then insertN' . R.fromString $ replicate sw ' '+ else insertB' '\t' "<C-t>" -> shiftIndentOfRegionB 1 =<< regionOfB Line "<C-d>" -> shiftIndentOfRegionB (-1) =<< regionOfB Line "<C-e>" -> insertCharWithBelowB "<C-y>" -> insertCharWithAboveB- "<BS>" -> bdeleteB- "<C-h>" -> bdeleteB- "<Del>" -> deleteB Character Forward- "<C-w>" -> deleteRegionB =<< regionOfPartNonEmptyB unitViWordOnLine Backward+ "<BS>" -> bdeleteB'+ "<C-h>" -> bdeleteB'+ "<Del>" -> deleteB' Character Forward+ "<C-w>" -> deleteRegionB' =<< regionOfPartNonEmptyB unitViWordOnLine Backward "<C-u>" -> bdeleteLineB- "<lt>" -> insertB '<'+ "<lt>" -> insertB' '<' evs' -> error $ "Unhandled event " <> show evs' <> " in insert mode" updatedCursors <- withCurrentBuffer $ do
src/library/Yi/Keymap/Vim/Motion.hs view
@@ -200,6 +200,7 @@ matchGotoCharMove :: String -> MatchResult Move matchGotoCharMove (m:[]) | m `elem` "fFtT" = PartialMatch+matchGotoCharMove (m:"<lt>") | m `elem` "fFtT" = matchGotoCharMove (m:"<") matchGotoCharMove (m:c:[]) | m `elem` "fFtT" = WholeMatch $ Move style False action where (dir, style, move) = case m of
src/library/Yi/Keymap/Vim/NormalMap.hs view
@@ -75,7 +75,8 @@ tagJumpBinding :: VimBinding tagJumpBinding = mkBindingY Normal (Event (KASCII ']') [MCtrl], f, id)- where f = withCurrentBuffer readCurrentWordB >>= gotoTag . Tag . R.toText+ where f = withCurrentBuffer readCurrentWordB >>= g . Tag . R.toText+ g tag = gotoTag tag 0 Nothing tagPopBinding :: VimBinding tagPopBinding = mkBindingY Normal (Event (KASCII 't') [MCtrl], f, id)@@ -276,9 +277,9 @@ , switchMode Ex) -- Undo- , (char 'u', withCountOnBuffer0 undoB >> withCurrentBuffer leftOnEol, id)- , (char 'U', withCountOnBuffer0 undoB >> withCurrentBuffer leftOnEol, id) -- TODO- , (ctrlCh 'r', withCountOnBuffer0 redoB >> withCurrentBuffer leftOnEol, id)+ , (char 'u', withCountOnBuffer undoB >> withCurrentBuffer leftOnEol, id)+ , (char 'U', withCountOnBuffer undoB >> withCurrentBuffer leftOnEol, id) -- TODO+ , (ctrlCh 'r', withCountOnBuffer redoB >> withCurrentBuffer leftOnEol, id) -- scrolling ,(ctrlCh 'b', getCountE >>= withCurrentBuffer . upScreensB, id)@@ -450,7 +451,7 @@ openFileUnderCursor :: Maybe (EditorM ()) -> YiM () openFileUnderCursor editorAction = do- fileName <- fmap R.toString . withEditor . withCurrentBuffer $ readUnitB unitViWORD+ fileName <- fmap R.toString . withCurrentBuffer $ readUnitB unitViWORD fileExists <- io $ doesFileExist fileName if (not fileExists) then withEditor . fail $ "Can't find file \"" <> fileName <> "\""@@ -505,5 +506,5 @@ withCount :: EditorM () -> EditorM () withCount action = flip replicateM_ action =<< getCountE -withCountOnBuffer0 :: BufferM () -> EditorM ()-withCountOnBuffer0 action = withCount $ withCurrentBuffer action+withCountOnBuffer :: BufferM () -> EditorM ()+withCountOnBuffer action = withCount $ withCurrentBuffer action
src/library/Yi/Keymap/Vim/NormalOperatorPendingMap.hs view
@@ -112,11 +112,12 @@ escBinding :: VimBinding escBinding = mkBindingE ReplaceSingleChar Drop (spec KEsc, return (), resetCount . switchMode Normal) -data OperandParseResult = JustTextObject !CountedTextObject- | JustMove !CountedMove- | JustOperator !Int !RegionStyle -- ^ like dd and d2vd- | PartialOperand- | NoOperand+data OperandParseResult+ = JustTextObject !CountedTextObject+ | JustMove !CountedMove+ | JustOperator !Int !RegionStyle -- ^ like dd and d2vd+ | PartialOperand+ | NoOperand parseOperand :: EventString -> String -> OperandParseResult parseOperand opChar s = parseCommand mcount styleMod opChar commandString@@ -139,6 +140,9 @@ parseCommand _ _ _ "g" = PartialOperand parseCommand n sm o s | o' == s = JustOperator (fromMaybe 1 n) (sm LineWise) where o' = T.unpack . _unEv $ o+parseCommand n sm _ "0" =+ let m = Move Exclusive False (const moveToSol)+ in JustMove (CountedMove n (changeMoveStyle sm m)) parseCommand n sm _ s = case stringToMove . Ev $ T.pack s of WholeMatch m -> JustMove $ CountedMove n $ changeMoveStyle sm m PartialMatch -> PartialOperand@@ -147,16 +151,19 @@ $ changeTextObjectStyle sm to Nothing -> NoOperand -+-- TODO: setup doctests -- Parse event string that can go after operator -- w -> (Nothing, "", "w") -- 2w -> (Just 2, "", "w") -- V2w -> (Just 2, "V", "w") -- v2V3<C-v>w -> (Just 6, "<C-v>", "w") -- vvvvvvvvvvvvvw -> (Nothing, "v", "w")+-- 0 -> (Nothing, "", "0")+-- V0 -> (Nothing, "V", "0") splitCountModifierCommand :: String -> (Maybe Int, String, String) splitCountModifierCommand = go "" Nothing [""]- where go ds count mods (h:t) | isDigit h = go (ds <> [h]) count mods t+ where go "" Nothing mods "0" = (Nothing, head mods, "0")+ go ds count mods (h:t) | isDigit h = go (ds <> [h]) count mods t go ds@(_:_) count mods s@(h:_) | not (isDigit h) = go [] (maybeMult count (Just (read ds))) mods s go [] count mods (h:t) | h `elem` "vV" = go [] count ([h]:mods) t go [] count mods s | "<C-v>" `isPrefixOf` s = go [] count ("<C-v>":mods) (drop 5 s)
src/library/Yi/Keymap/Vim/Tag.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-}@@ -16,6 +17,7 @@ module Yi.Keymap.Vim.Tag ( completeVimTag , gotoTag+ , nextTag , popTag , unpopTag ) where@@ -30,6 +32,7 @@ import GHC.Generics (Generic) #endif import Data.Maybe+import Data.Monoid import qualified Data.Text as T import Data.Typeable import System.Directory (doesFileExist)@@ -47,7 +50,7 @@ -- | List of tags and the file/line/char that they originate from. -- (the location that :tag or Ctrl-[ was called from). data VimTagStack = VimTagStack {- tagStackList :: [(Tag, FilePath, Int, Int)]+ tagStackList :: [(Tag, Int, FilePath, Int, Int)] , tagStackIndex :: Int } deriving Typeable @@ -63,7 +66,8 @@ instance Binary VimTagStack #endif -getTagList :: EditorM [(Tag, FilePath, Int, Int)]+-- | Returns tag, tag index, filepath, line number, char number+getTagList :: EditorM [(Tag, Int, FilePath, Int, Int)] getTagList = do VimTagStack ts _ <- getEditorDyn return ts@@ -73,7 +77,7 @@ VimTagStack _ ti <- getEditorDyn return ti -setTagList :: [(Tag, FilePath, Int, Int)] -> EditorM ()+setTagList :: [(Tag, Int, FilePath, Int, Int)] -> EditorM () setTagList tl = do t@(VimTagStack _ _) <- getEditorDyn putEditorDyn $ t { tagStackList = tl }@@ -84,16 +88,16 @@ putEditorDyn $ t { tagStackIndex = ti } -- | Push tag at index.-pushTagStack :: Tag -> FilePath -> Int -> Int -> EditorM ()-pushTagStack tag fp ln cn = do+pushTagStack :: Tag -> Int -> FilePath -> Int -> Int -> EditorM ()+pushTagStack tag ind fp ln cn = do tl <- getTagList ti <- getTagIndex- setTagList $ (take ti tl) ++ [(tag, fp, ln, cn)]+ setTagList $ (take ti tl) ++ [(tag, ind, fp, ln, cn)] setTagIndex $ ti + 1 -- | Get tag and decrement index (so that when a new push is done, the current -- tag is popped)-popTagStack :: EditorM (Maybe (Tag, FilePath, Int, Int))+popTagStack :: EditorM (Maybe (Tag, Int, FilePath, Int, Int)) popTagStack = do tl <- getTagList ti <- getTagIndex@@ -105,20 +109,32 @@ -- | Opens the file that contains @tag@. Uses the global tag table or uses -- the first valid tag file in @TagsFileList@.-gotoTag :: Tag -> YiM ()-gotoTag tag =- void . visitTagTable $ \tagTable ->- case lookupTag tag tagTable of- Nothing -> errorEditor $ "tag not found: " `T.append` _unTag tag- Just (filename, line) -> do+gotoTag :: Tag -> Int -> Maybe (FilePath, Int, Int) -> YiM ()+gotoTag tag ind ret =+ void . visitTagTable $ \tagTable -> do+ let lis = lookupTag tag tagTable+ if (length lis) <= ind+ then errorEditor $ "tag not found: " <> _unTag tag+ else do bufinf <- withCurrentBuffer bufInfoB- let ln = bufInfoLineNo bufinf- cn = bufInfoColNo bufinf- fn = bufInfoFileName bufinf- withEditor $ pushTagStack tag fn ln cn- void $ editFile filename- void . withCurrentBuffer $ gotoLn line + let (filename, line) = lis !! ind+ (fn, ln, cn) = case ret of+ Just ret' -> ret'+ Nothing -> (bufInfoFileName bufinf, + bufInfoLineNo bufinf, + bufInfoColNo bufinf)+ withEditor $ pushTagStack tag ind fn ln cn+ openingNewFile filename $ gotoLn line++-- | Goes to the next tag. (:tnext)+nextTag :: YiM ()+nextTag = do+ prev <- withEditor popTagStack + case prev of+ Nothing -> errorEditor $ "tag stack empty"+ Just (tag, ind, fn, ln, cn) -> gotoTag tag (ind + 1) (Just (fn, ln, cn))+ -- | Return to location from before last tag jump. popTag :: YiM () popTag = do@@ -129,9 +145,7 @@ posloc <- withEditor popTagStack case posloc of Nothing -> errorEditor "at bottom of tag stack"- Just (_, fn, ln, cn) -> do- void $ editFile fn- void . withCurrentBuffer $ moveToLineColB ln cn+ Just (_, _, fn, ln, cn) -> openingNewFile fn $ moveToLineColB ln cn -- | Go to next tag in the tag stack. Represents :tag without any -- specified tag.@@ -141,22 +155,23 @@ ti <- withEditor getTagIndex if ti >= length tl then case tl of- [] -> errorEditor "at top of tag stack"- _ -> errorEditor "tag stack empty"- else let (tag, _, _, _) = tl !! ti- in void . visitTagTable $ \tagTable ->- case lookupTag tag tagTable of- Nothing -> errorEditor $ "tag not found: " `T.append` _unTag tag- Just (filename, line) -> do+ [] -> errorEditor "tag stack empty"+ _ -> errorEditor "at top of tag stack"+ else let (tag, ind, _, _, _) = tl !! ti+ in void . visitTagTable $ \tagTable -> do+ let lis = lookupTag tag tagTable+ if (length lis) <= ind+ then errorEditor $ "tag not found: " <> _unTag tag+ else do bufinf <- withCurrentBuffer bufInfoB- let ln = bufInfoLineNo bufinf+ let (filename, line) = lis !! ind+ ln = bufInfoLineNo bufinf cn = bufInfoColNo bufinf fn = bufInfoFileName bufinf tl' = take ti tl- ++ (tag, fn, ln, cn):(drop (ti + 1) tl)+ ++ (tag, ind, fn, ln, cn):(drop (ti + 1) tl) withEditor $ setTagList tl'- void $ editFile filename- void . withCurrentBuffer $ gotoLn line+ openingNewFile filename $ gotoLn line completeVimTag :: T.Text -> YiM [T.Text] completeVimTag s =
src/library/Yi/Keymap/Vim/VisualMap.hs view
@@ -25,9 +25,12 @@ import Yi.Keymap.Vim.Operator import Yi.Keymap.Vim.StateUtils import Yi.Keymap.Vim.StyledRegion+import Yi.Keymap.Vim.Tag import Yi.Keymap.Vim.Utils import Yi.MiniBuffer import Yi.Monad+import qualified Yi.Rope as R+import Yi.Tag import Yi.Utils defVisualMap :: [VimOperator] -> [VimBinding]@@ -36,6 +39,7 @@ ++ [chooseRegisterBinding] ++ operatorBindings operators ++ digitBindings ++ [replaceBinding, switchEdgeBinding] ++ [insertBinding, exBinding, shiftDBinding]+ ++ [tagJumpBinding] escAction :: EditorM RepeatToken escAction = do@@ -241,4 +245,15 @@ modifyStateE $ \s -> s { vsSecondaryCursors = drop 1 cursors } switchModeE $ Insert (head evs) return Continue+ f _ _ = NoMatch++tagJumpBinding :: VimBinding+tagJumpBinding = VimBindingY (f . T.unpack . _unEv)+ where f "<C-]>" (VimState { vsMode = (Visual _) })+ = WholeMatch $ do + tag <- Tag . R.toText <$> withCurrentBuffer+ (regionOfSelectionB >>= readRegionB)+ withEditor $ switchModeE Normal+ gotoTag tag 0 Nothing+ return Finish f _ _ = NoMatch
src/library/Yi/Main.hs view
@@ -133,9 +133,9 @@ [] -> fail "The `-l' option must come after a file argument" File filename -> if shouldOpenInTabs && not (null (startActions cfg)) then- prependActions [YiA (editFile filename), EditorA newTabE]+ prependActions [YiA (void $ editFile filename), EditorA newTabE] else- prependAction (editFile filename)+ prependAction (void $ editFile filename) EditorNm emul -> case lookup (fmap toLower emul) editors of Just modifyCfg -> return (modifyCfg cfg, cfgcon)
src/library/Yi/Misc.hs view
@@ -196,7 +196,7 @@ -- | Shows current working directory. Also see 'cd'. pwd :: YiM ()-pwd = io getCurrentDirectory >>= withEditor . printMsg . T.pack+pwd = io getCurrentDirectory >>= printMsg . T.pack rot13Char :: Char -> Char rot13Char = onCharLetterCode (+13)
src/library/Yi/Mode/Compilation.hs view
@@ -16,7 +16,7 @@ import Yi.Buffer import Yi.Core (withSyntax) import Yi.Editor-import Yi.File (editFile)+import Yi.File (openingNewFile) import Yi.Lexer.Alex (Tok(..), Posn(..)) import qualified Yi.Lexer.Compilation as Compilation import Yi.Keymap@@ -36,6 +36,5 @@ Just t@Tok {tokT = Compilation.Report filename line col _} -> do withCurrentBuffer . moveTo . posnOfs $ tokPosn t shiftOtherWindow- _ <- editFile filename- withCurrentBuffer $ gotoLn line >> rightN col+ openingNewFile filename $ gotoLn line >> rightN col _ -> return ()
src/library/Yi/Modes.hs view
@@ -70,11 +70,16 @@ , modeGotoDeclaration = do currentPoint <- pointB currentWord <- readCurrentWordB- gotoLn 0+ currentWordBeginningPoint <- regionStart <$> regionOfB unitWord+ _ <- gotoLn 0 word <- return $ makeSimpleSearch currentWord searchResults <- regexB Forward word case searchResults of- (declarationRegion : _) -> moveTo $ regionStart declarationRegion+ (declarationRegion : _) -> do+ searchPoint <- return $ regionStart declarationRegion+ if currentWordBeginningPoint /= searchPoint+ then moveTo searchPoint+ else moveTo currentPoint [] -> moveTo currentPoint }
src/library/Yi/Tag.hs view
@@ -42,9 +42,10 @@ import GHC.Generics (Generic) #endif import Data.Default+import qualified Data.Foldable as F import Data.List (isPrefixOf) import Data.List.Split (splitOn)-import Data.Map (Map, fromList, lookup, keys)+import Data.Map (Map, fromListWith, lookup, keys) import Data.Maybe (mapMaybe) import qualified Data.Text as T import qualified Data.Text.Encoding as E@@ -83,7 +84,7 @@ , tagBaseDir :: FilePath -- ^ path to the tag file directory -- tags are relative to this path- , tagFileMap :: Map Tag (FilePath, Int)+ , tagFileMap :: Map Tag [(FilePath, Int)] -- ^ map from tags to files , tagTrie :: Trie.Trie -- ^ trie to speed up tag hinting@@ -91,20 +92,20 @@ -- | Find the location of a tag using the tag table. -- Returns a full path and line number-lookupTag :: Tag -> TagTable -> Maybe (FilePath, Int)+lookupTag :: Tag -> TagTable -> [(FilePath, Int)] lookupTag tag tagTable = do- (file, line) <- Data.Map.lookup tag $ tagFileMap tagTable+ (file, line) <- F.concat . Data.Map.lookup tag $ tagFileMap tagTable return (tagBaseDir tagTable </> file, line) -- | Super simple parsing CTag format 1 parsing algorithm -- TODO: support search patterns in addition to lineno-readCTags :: String -> Map Tag (FilePath, Int)+readCTags :: String -> Map Tag [(FilePath, Int)] readCTags =- fromList . mapMaybe (parseTagLine . words) . lines+ fromListWith (++) . mapMaybe (parseTagLine . words) . lines where parseTagLine (tag:tagfile:lineno:_) = -- remove ctag control lines if "!_TAG_" `isPrefixOf` tag then Nothing- else Just (mkTag tag, (tagfile, fst . head . reads $ lineno))+ else Just (mkTag tag, [(tagfile, fst . head . reads $ lineno)]) parseTagLine _ = Nothing -- | Read in a tag file from the system
src/library/Yi/Types.hs view
@@ -226,6 +226,7 @@ , updateTransactionInFlight :: !Bool , updateTransactionAccum :: ![Update] , fontsizeVariation :: !Int+ , encodingConverterName :: Maybe R.ConverterName -- ^ How many points (frontend-specific) to change -- the font by in this buffer } deriving Typeable@@ -233,16 +234,16 @@ instance Binary Yi.Types.Attributes where put (Yi.Types.Attributes n b u bd pc pu selectionStyle_- _proc wm law lst ro ins _dc _pfw isTransacPresent transacAccum fv) = do+ _proc wm law lst ro ins _dc _pfw isTransacPresent transacAccum fv cn) = do let putTime (UTCTime x y) = B.put (fromEnum x) >> B.put (fromEnum y) B.put n >> B.put b >> B.put u >> B.put bd B.put pc >> B.put pu >> B.put selectionStyle_ >> B.put wm B.put law >> putTime lst >> B.put ro >> B.put ins >> B.put _dc- B.put isTransacPresent >> B.put transacAccum >> B.put fv+ B.put isTransacPresent >> B.put transacAccum >> B.put fv >> B.put cn get = Yi.Types.Attributes <$> B.get <*> B.get <*> B.get <*> B.get <*> B.get <*> B.get <*> B.get <*> pure I.End <*> B.get <*> B.get <*> getTime <*> B.get <*> B.get <*> B.get- <*> pure (const False) <*> B.get <*> B.get <*> B.get+ <*> pure (const False) <*> B.get <*> B.get <*> B.get <*> B.get where getTime = UTCTime <$> (toEnum <$> B.get) <*> (toEnum <$> B.get)
src/library/Yi/UI/Pango.hs view
@@ -576,29 +576,32 @@ updateCache ui e tabs <- readIORef $ tabCache ui f <- readIORef (uiFont ui)- heights <- fold <$> mapM (getHeightsInTab ui f e) tabs+ dims <- fold <$> mapM (getDimensionsInTab ui f e) tabs let e' = (tabsA %~ fmap (mapWindows updateWin)) e- updateWin w = case M.lookup (wkey w) heights of+ updateWin w = case M.lookup (wkey w) dims of Nothing -> w- Just (h,rgn) -> w { height = h, winRegion = rgn }+ Just (wi,h,rgn) -> w { width = wi, height = h, winRegion = rgn } -- Don't leak references to old Windows let forceWin x w = height w `seq` winRegion w `seq` x return $ (foldl . tabFoldl) forceWin e' (e' ^. tabsA) -getHeightsInTab :: UI -> FontDescription -> Editor- -> TabInfo -> IO (M.Map WindowRef (Int,Region))-getHeightsInTab ui f e tab = do+-- | Width, Height+getDimensionsInTab :: UI -> FontDescription -> Editor+ -> TabInfo -> IO (M.Map WindowRef (Int,Int,Region))+getDimensionsInTab ui f e tab = do wCache <- readIORef (windowCache tab) forM wCache $ \wi -> do- (_, h) <- widgetGetSize $ textview wi+ (wid, h) <- widgetGetSize $ textview wi win <- readIORef (coreWin wi) let metrics = winMetrics wi lineHeight = ascent metrics + descent metrics- let b0 = findBufferWith (bufkey win) e+ charWidth = max (approximateCharWidth metrics) (approximateDigitWidth metrics)+ width = round $ fromIntegral wid / charWidth+ height = round $ fromIntegral h / lineHeight+ b0 = findBufferWith (bufkey win) e rgn <- shownRegion ui f wi b0- let ret= (round $ fromIntegral h / lineHeight, rgn)- return ret+ return (width, height, rgn) shownRegion :: UI -> FontDescription -> WinInfo -> FBuffer -> IO Region shownRegion ui f w b = modifyMVar (winLayoutInfo w) $ \wli -> do
src/library/Yi/UI/Pango/Control.hs view
@@ -238,28 +238,32 @@ updateCache e cacheRef <- asks tabCache tabs <- liftBase $ readIORef cacheRef- heights <- concat <$> mapM (getHeightsInTab e) tabs+ dims <- concat <$> mapM (getDimensionsInTab e) tabs let e' = (tabsA %~ fmap (mapWindows updateWin)) e- updateWin w = case find (\(ref,_,_) -> (wkey w == ref)) heights of+ updateWin w = case find (\(ref,_,_,_) -> (wkey w == ref)) dims of Nothing -> w- Just (_,h,rgn) -> w { height = h, winRegion = rgn }-+ Just (_, wi, h,rgn) -> w { width = wi+ , height = h+ , winRegion = rgn } -- Don't leak references to old Windows let forceWin x w = height w `seq` winRegion w `seq` x return $ (foldl . tabFoldl) forceWin e' (e' ^. tabsA) -getHeightsInTab :: Editor -> TabInfo -> ControlM [(WindowRef,Int,Region)]-getHeightsInTab e tab = do+-- | Width, Height+getDimensionsInTab :: Editor -> TabInfo -> ControlM [(WindowRef,Int,Int,Region)]+getDimensionsInTab e tab = do viewsRef <- asks views vs <- liftBase $ readIORef viewsRef foldlM (\a w -> case Map.lookup (wkey w) vs of Just v -> do- (_, h) <- liftBase $ widgetGetSize $ drawArea v+ (wi, h) <- liftBase $ widgetGetSize $ drawArea v let lineHeight = ascent (metrics v) + descent (metrics v)- let b0 = findBufferWith (viewFBufRef v) e+ charWidth = Gtk.approximateCharWidth $ metrics v+ b0 = findBufferWith (viewFBufRef v) e rgn <- shownRegion e v b0- let ret= (windowRef v, round $ fromIntegral h / lineHeight, rgn)+ let ret= (windowRef v, round $ fromIntegral wi / charWidth, + round $ fromIntegral h / lineHeight, rgn) return $ a <> [ret] Nothing -> return a) [] (coreTab tab ^. tabWindowsA)
src/library/Yi/UI/SimpleLayout.hs view
@@ -18,6 +18,7 @@ import Control.Monad.State (evalState, get, put) import Data.Foldable import Data.List (partition)+import Data.Maybe (fromJust) import qualified Data.List.PointedList.Circular as PL import qualified Data.Map.Strict as M import Data.Monoid@@ -78,7 +79,8 @@ heights miniWindowsWithHeights = fmap (\win -> layoutWindow win e colCount 1) miniWs- Just newWindows = PL.fromList (miniWindowsWithHeights <> bigWindowsWithHeights)+ newWindows =+ merge (miniWindowsWithHeights <> bigWindowsWithHeights) (windows e) winRects = M.fromList (bigWindowsWithRects <> miniWindowsWithRects) bigWindowsWithRects = zipWith (\w offset -> (wkey w, Rect 0 (offset + tabbarHeight) colCount (height w)))@@ -87,10 +89,16 @@ miniWindowsWithRects = map (\w -> (wkey w, Rect 0 (rowCount - 1) colCount 1)) miniWindowsWithHeights+ merge :: [Window] -> PL.PointedList Window -> PL.PointedList Window+ merge updates =+ let replace (Window { wkey = k }) = fromJust (find ((== k) . wkey) updates)+ in fmap replace + layoutWindow :: Window -> Editor -> Int -> Int -> Window layoutWindow win e w h = win { height = h+ , width = w , winRegion = mkRegion fromMarkPoint toMarkPoint , actualLines = dispLnCount }
src/library/Yi/UI/Vty.hs view
@@ -179,10 +179,12 @@ (SL.offsetY promptRect) (Vty.vertCat (fmap formatCmdLine niceCmd)) cursorPos =- case (\(w, r) -> (isMini w, cursor r)) (PL._focus windowsAndImages) of- (False, Just (y, x)) -> Vty.Cursor (toEnum x) (toEnum y)- (True, Just (_, x)) -> Vty.Cursor (toEnum x) (toEnum (rowCount - 1))- (_, Nothing) -> Vty.NoCursor+ let (w, image) = PL._focus windowsAndImages+ in case (isMini w, cursor image) of+ (False, Just (y, x)) ->+ Vty.Cursor (toEnum x) (toEnum y)+ (True, Just (_, x)) -> Vty.Cursor (toEnum x) (toEnum (rowCount - 1))+ (_, Nothing) -> Vty.NoCursor logPutStrLn "refreshing screen." Vty.update (fsVty fs) (Vty.picForLayers ([tabBarImage, cmdImage] ++ bigImages ++ miniImages))
src/library/Yi/Window.hs view
@@ -33,6 +33,7 @@ -- accessed one is first element , height :: !Int -- ^ height of the window (in number of screen -- lines displayed)+ , width :: !Int -- ^ width of the window (in number of chars) , winRegion :: !Region -- ^ view area. note that the top point is -- also available as a buffer mark. , wkey :: !WindowRef -- ^ identifier for the window (for UI sync)@@ -50,10 +51,10 @@ makeLensesWithSuffix "A" ''Window instance Binary Window where- put (Window mini bk bl _h _rgn key lns jl) =+ put (Window mini bk bl _w _h _rgn key lns jl) = put mini >> put bk >> put bl >> put key >> put lns >> put jl get = Window <$> get <*> get <*> get- <*> return 0 <*> return emptyRegion+ <*> return 0 <*> return 0 <*> return emptyRegion <*> get <*> get <*> get @@ -77,4 +78,4 @@ -- | Return a "fake" window onto a buffer. dummyWindow :: BufferRef -> Window-dummyWindow b = Window False b [] 0 emptyRegion def 0 Nothing+dummyWindow b = Window False b [] 0 0 emptyRegion def 0 Nothing
+ src/tests/vimtests/delete/d00.test view
@@ -0,0 +1,12 @@+-- Input+(1,6)+abc def ghi+123 456 789+lorem ipsum+-- Output+(1,1)+ef ghi+123 456 789+lorem ipsum+-- Events+d0
+ src/tests/vimtests/find/f5.test view
@@ -0,0 +1,12 @@+-- Input+(1,1)+Lorem ipsum dolor s<t amet+abc def ghi+qwe rty uiop+-- Output+(1,20)+Lorem ipsum dolor s<t amet+abc def ghi+qwe rty uiop+-- Events+f<lt>
+ src/tests/vimtests/insertion/O3.test view
@@ -0,0 +1,11 @@+-- Input+(2,1)+++-- Output+(2,1)++++-- Events+O<Esc>
+ src/tests/vimtests/insertion/o3.test view
@@ -0,0 +1,11 @@+-- Input+(2,1)+++-- Output+(3,1)++++-- Events+o<Esc>
yi.cabal view
@@ -1,5 +1,5 @@ name: yi-version: 0.10.1+version: 0.11.0 category: Development, Editor synopsis: The Haskell-Scriptable Editor description:@@ -169,10 +169,12 @@ Yi.Keymap.Vim.Ex.Commands.Edit Yi.Keymap.Vim.Ex.Commands.Global Yi.Keymap.Vim.Ex.Commands.GotoLine+ Yi.Keymap.Vim.Ex.Commands.Make Yi.Keymap.Vim.Ex.Commands.Nohl Yi.Keymap.Vim.Ex.Commands.Paste Yi.Keymap.Vim.Ex.Commands.Quit Yi.Keymap.Vim.Ex.Commands.Reload+ Yi.Keymap.Vim.Ex.Commands.Shell Yi.Keymap.Vim.Ex.Commands.Substitute Yi.Keymap.Vim.Ex.Commands.Tag Yi.Keymap.Vim.Ex.Commands.Write@@ -285,7 +287,7 @@ word-trie >= 0.2.0.4, yi-language >= 0.1.0.7, oo-prototypes,- yi-rope >= 0.4.1.0+ yi-rope >= 0.6.0.0 && < 0.7 ghc-options: -Wall -fno-warn-orphans ghc-prof-options: -prof -auto-all -rtsopts@@ -333,7 +335,7 @@ Yi.UI.Vty.Conversions build-depends: unix-compat >=0.1 && <0.5,- vty >= 5.2.2 && < 6+ vty >= 5.2.4 && < 6 cpp-options: -DFRONTEND_VTY other-modules: