diff --git a/yi-keymap-vim/src/Yi/Keymap/Vim/Ex.hs b/yi-keymap-vim/src/Yi/Keymap/Vim/Ex.hs index e0a7b2bcc..b75d754ed 100644 --- a/yi-keymap-vim/src/Yi/Keymap/Vim/Ex.hs +++ b/yi-keymap-vim/src/Yi/Keymap/Vim/Ex.hs @@ -17,6 +17,7 @@ module Yi.Keymap.Vim.Ex import Yi.Keymap.Vim.Common (EventString) import qualified Yi.Keymap.Vim.Ex.Commands.Buffer as Buffer (parse) +import qualified Yi.Keymap.Vim.Ex.Commands.BufferCycle as BufferCycle (parse) import qualified Yi.Keymap.Vim.Ex.Commands.BufferDelete as BufferDelete (parse) import qualified Yi.Keymap.Vim.Ex.Commands.BufferNew as BufferNew (parse) import qualified Yi.Keymap.Vim.Ex.Commands.Buffers as Buffers (parse) @@ -48,6 +49,7 @@ import Yi.Keymap.Vim.Ex.Types (ExCommand (..), evStrin defExCommandParsers :: [EventString -> Maybe ExCommand] defExCommandParsers = [ Buffer.parse + , BufferCycle.parse , Buffers.parse , BufferDelete.parse , BufferNew.parse diff --git a/yi-keymap-vim/src/Yi/Keymap/Vim/Ex/Commands/BufferCycle.hs b/yi-keymap-vim/src/Yi/Keymap/Vim/Ex/Commands/BufferCycle.hs new file mode 100644 index 000000000..e95c359ca --- /dev/null +++ b/yi-keymap-vim/src/Yi/Keymap/Vim/Ex/Commands/BufferCycle.hs @@ -0,0 +1,34 @@ +{-# LANGUAGE OverloadedStrings #-} +module Yi.Keymap.Vim.Ex.Commands.BufferCycle (parse) where + +import Control.Applicative (Alternative ((<|>))) +import Control.Monad +import Data.List +import qualified Data.Attoparsec.Text as P +import Lens.Micro.Platform +import Yi.Editor +import Yi.Keymap (Action (EditorA)) +import Yi.Window +import Yi.Keymap.Vim.Common (EventString) +import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common +import Yi.Keymap.Vim.Ex.Types (ExCommand (cmdAction, cmdShow)) + +parse :: EventString -> Maybe ExCommand +parse = Common.parse $ do + void (P.char 'b') <|> return () + direction <- (fmap (const False) $ P.string "prev" <|> P.string "previous") <|> fmap (const True) (P.string "next") + return $ Common.pureExCommand { + cmdShow = if direction then "next" else "previous", + cmdAction = EditorA $ currentWindowA %= \window -> let + cl = bufkey window : bufAccessList window + cl' = if direction + then last cl : init cl + else tail cl ++ [head cl] + in forceSpine cl' `seq` window { bufkey = head cl', bufAccessList = tail cl' } + } + +{-# INLINE forceSpine #-} +forceSpine :: [a] -> () +forceSpine = go where + go [] = () + go (_:r) = go r diff --git a/yi-keymap-vim/yi-keymap-vim.cabal b/yi-keymap-vim/yi-keymap-vim.cabal index 6109256ff..4282b0374 100644 --- a/yi-keymap-vim/yi-keymap-vim.cabal +++ b/yi-keymap-vim/yi-keymap-vim.cabal @@ -77,6 +77,7 @@ library Yi.Keymap.Vim.EventUtils Yi.Keymap.Vim.Ex Yi.Keymap.Vim.Ex.Commands.Buffer + Yi.Keymap.Vim.Ex.Commands.BufferCycle Yi.Keymap.Vim.Ex.Commands.BufferDelete Yi.Keymap.Vim.Ex.Commands.Buffers Yi.Keymap.Vim.Ex.Commands.Cabal