packages feed

yi-contrib 0.6.6.0 → 0.6.7.0

raw patch · 2 files changed

+153/−5 lines, 2 filesdep +mtldep ~directorydep ~splitdep ~yinew-uploader

Dependencies added: mtl

Dependency ranges changed: directory, split, yi

Files

+ src/Yi/FuzzyOpen.hs view
@@ -0,0 +1,146 @@++{- This file aims to provide (the essential subset of) the same functionality+   that vim plugins ctrlp and command-t provide.++   Setup:++     Add something like this to your config:++       (ctrlCh 'p' ?>>! fuzzyOpen)++   Usage:++     <C-p> (or whatever mapping user chooses) starts fuzzy open dialog.++     Typing something filters filelist.++     <Enter> opens currently selected file+     in current (the one that fuzzyOpen was initited from) window.++     <C-t> opens currently selected file in a new tab.+     <C-s> opens currently selected file in a split.++     <KUp> and <C-p> moves selection up+     <KDown> and <C-n> moves selection down++     Readline shortcuts <C-a> , <C-e>, <C-u> and <C-k> work as usual.+-}++module Yi.FuzzyOpen+    ( fuzzyOpen+    ) where++import Prelude ()+import Yi+import Yi.MiniBuffer+import Yi.Completion++import Control.Monad (replicateM, replicateM_)+import Control.Monad.Trans (liftIO)+import System.Directory (doesDirectoryExist, getDirectoryContents)+import System.FilePath (FilePath, (</>))+import Data.List (filter, map, intersperse, drop)+import Data.Maybe (isJust)++fuzzyOpen :: YiM ()+fuzzyOpen = do+    withEditor splitE+    bufRef <- withEditor newTempBufferE+    fileList <- liftIO $ getRecursiveContents "."+    updateMatchList bufRef fileList+    withEditor $ spawnMinibufferE "" $ const $ localKeymap bufRef fileList+    return ()++-- shamelessly stolen from Chapter 9 of Real World Haskell+-- takes about 3 seconds to traverse linux kernel, which is not too outrageous+-- TODO: check if it works at all with cyclic links +-- TODO: perform in background, limit file count or directory depth+getRecursiveContents :: FilePath -> IO [FilePath]+getRecursiveContents topdir = do+    names <- getDirectoryContents topdir+    let properNames = filter (`notElem` [".", "..", ".git", ".svn"]) names+    paths <- forM properNames $ \name -> do+        let path = topdir </> name+        isDirectory <- doesDirectoryExist path+        if isDirectory+            then getRecursiveContents path+            else return [path]+    return (concat paths)++localKeymap :: BufferRef -> [FilePath] -> Keymap+localKeymap bufRef fileList =+              choice [spec KEnter  ?>>! openInThisWindow bufRef+                     , ctrlCh 't'  ?>>! openInNewTab bufRef+                     , ctrlCh 's'  ?>>! openInSplit bufRef+                     , spec KEsc   ?>>! replicateM 2 closeBufferAndWindowE+                     , ctrlCh 'h'  ?>>! updatingB (deleteB Character Backward)+                     , spec KBS    ?>>! updatingB (deleteB Character Backward)+                     , spec KDel   ?>>! updatingB (deleteB Character Backward)+                     , ctrlCh 'a'  ?>>! moveToSol+                     , ctrlCh 'e'  ?>>! moveToEol+                     , spec KLeft  ?>>! moveXorSol 1+                     , spec KRight ?>>! moveXorEol 1+                     , ctrlCh 'p'  ?>>! moveSelectionUp bufRef+                     , spec KUp    ?>>! moveSelectionUp bufRef+                     , ctrlCh 'n'  ?>>! moveSelectionDown bufRef+                     , spec KDown  ?>>! moveSelectionDown bufRef+                     , ctrlCh 'w'  ?>>! updatingB (deleteB unitWord Backward)+                     , ctrlCh 'u'  ?>>! updatingB (moveToSol >> deleteToEol)+                     , ctrlCh 'k'  ?>>! updatingB deleteToEol+                ]+             <|| (insertChar >>! update)+    where update = updateMatchList bufRef fileList+          updatingB bufAction = withBuffer bufAction >> update+          updatingE editorAction = withEditor editorAction >> update++showFileList :: [FilePath] -> String+showFileList = concat . intersperse "\n" . map ("  " ++)++{- Implementation detail:+   The index of selected file is stored as vertical cursor position.+   Asterisk position is always synchronized with cursor position.++   TODO: store index of selected file explicitly to make things more obvious.+-}++updateMatchList :: BufferRef -> [FilePath] -> YiM ()+updateMatchList bufRef fileList = do+    needle <- withBuffer elemsB+    let filteredFiles = filter (subsequenceMatch needle) fileList+    withEditor $ withGivenBuffer0 bufRef $ do+        replaceBufferContent $ showFileList filteredFiles+        moveTo 0+        replaceCharB '*'+    return ()++openInThisWindow :: BufferRef -> YiM ()+openInThisWindow = openRoutine (return ())++openInSplit :: BufferRef -> YiM ()+openInSplit = openRoutine splitE++openInNewTab :: BufferRef -> YiM ()+openInNewTab = openRoutine newTabE++openRoutine :: EditorM () -> BufferRef -> YiM ()+openRoutine preOpenAction bufRef = do+    chosenFile <- fmap (drop 2) $ withEditor $ withGivenBuffer0 bufRef readLnB+    withEditor $ do+        replicateM_ 2 closeBufferAndWindowE+        preOpenAction+    discard $ editFile chosenFile++insertChar :: Keymap+insertChar = textChar >>= write . insertB++moveSelectionUp :: BufferRef -> EditorM ()+moveSelectionUp bufRef = withGivenBuffer0 bufRef $ do+    replaceCharB ' '+    lineUp+    replaceCharB '*'++moveSelectionDown :: BufferRef -> EditorM ()+moveSelectionDown bufRef = withGivenBuffer0 bufRef $ do+    replaceCharB ' '+    lineDown+    replaceCharB '*'
yi-contrib.cabal view
@@ -1,5 +1,5 @@ name:           yi-contrib-version:        0.6.6.0+version:        0.6.7.0 category:       Development, Editor synopsis:       Add-ons to Yi, the Haskell-Scriptable Editor description:@@ -12,7 +12,7 @@ homepage:       http://haskell.org/haskellwiki/Yi bug-reports:    http://code.google.com/p/yi-editor/issues/list Cabal-Version:  >= 1.6-tested-with:    GHC==7.4.1+tested-with:    GHC==7.4.2 build-type:     Simple  library@@ -28,12 +28,14 @@     Yi.Config.Users.Reiner     Yi.Style.Misc     Yi.Templates+    Yi.FuzzyOpen    build-depends:     base >=4.0 && <5,     containers,     data-accessor >= 0.2.1.4 && < 0.3,-    directory < 1.2,+    directory < 1.3,     filepath < 1.4,-    split ==0.1.*,-    yi == 0.6.6.0+    split >= 0.1 && < 0.3,+    mtl >= 0.1.0.1,+    yi == 0.6.7.0