{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE InstanceSigs #-}
{-# OPTIONS_HADDOCK show-extensions #-}
module Yi.Fuzzy (fuzzyOpen, fuzzyOpenWithDepth, defaultDepth) where
import Control.Monad (void)
import Control.Monad.Base (liftBase)
import Control.Monad.State (gets)
import Data.Binary (Binary(..), Word8)
import Data.Default (Default(..))
import Data.Foldable (Foldable(..))
import Data.List (isSuffixOf)
import Data.List.NonEmpty (NonEmpty(..), nonEmpty)
import Data.List.PointedList (PointedList(..))
import Data.Maybe (fromMaybe)
import Data.Monoid ((<>))
import Data.Text (Text)
import Data.Typeable (Typeable)
import GHC.Generics (Generic)
import GHC.Natural (Natural)
import System.Directory (doesDirectoryExist, getDirectoryContents)
import System.FilePath ((</>))
import System.IO.Error (tryIOError)
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Data.Map.Strict as M
import qualified Data.List.PointedList as PL
import Data.List.PointedList.Extras as PL
import Yi
import Yi.Completion
import Yi.MiniBuffer
import Yi.Types
import Yi.Utils ()
import qualified Yi.Rope as R
data FuzzyState = FuzzyState
{ FuzzyState -> Maybe (PointedList FuzzyItem)
items :: !(Maybe (PointedList FuzzyItem))
, FuzzyState -> Text
search :: !Text
} deriving (Int -> FuzzyState -> ShowS
[FuzzyState] -> ShowS
FuzzyState -> String
(Int -> FuzzyState -> ShowS)
-> (FuzzyState -> String)
-> ([FuzzyState] -> ShowS)
-> Show FuzzyState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FuzzyState] -> ShowS
$cshowList :: [FuzzyState] -> ShowS
show :: FuzzyState -> String
$cshow :: FuzzyState -> String
showsPrec :: Int -> FuzzyState -> ShowS
$cshowsPrec :: Int -> FuzzyState -> ShowS
Show, (forall x. FuzzyState -> Rep FuzzyState x)
-> (forall x. Rep FuzzyState x -> FuzzyState) -> Generic FuzzyState
forall x. Rep FuzzyState x -> FuzzyState
forall x. FuzzyState -> Rep FuzzyState x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep FuzzyState x -> FuzzyState
$cfrom :: forall x. FuzzyState -> Rep FuzzyState x
Generic, Typeable)
data FuzzyItem
= FileItem !Text
| BufferItem !BufferId
deriving (Typeable)
instance Show FuzzyItem where
show :: FuzzyItem -> String
show :: FuzzyItem -> String
show i :: FuzzyItem
i@(FileItem Text
_) = String
"File " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> FuzzyItem -> String
itemAsStr FuzzyItem
i
show i :: FuzzyItem
i@(BufferItem BufferId
_) = String
"Buffer " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> FuzzyItem -> String
itemAsStr FuzzyItem
i
itemAsTxt :: FuzzyItem -> Text
itemAsTxt :: FuzzyItem -> Text
itemAsTxt (FileItem Text
x) = Text
x
itemAsTxt (BufferItem (MemBuffer Text
x)) = Text
x
itemAsTxt (BufferItem (FileBuffer String
x)) = String -> Text
T.pack String
x
itemAsStr :: FuzzyItem -> String
itemAsStr :: FuzzyItem -> String
itemAsStr = Text -> String
T.unpack (Text -> String) -> (FuzzyItem -> Text) -> FuzzyItem -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FuzzyItem -> Text
itemAsTxt
defaultDepth :: Natural
defaultDepth :: Natural
defaultDepth = Natural
5
fuzzyOpen :: YiM ()
fuzzyOpen :: YiM ()
fuzzyOpen = Natural -> YiM ()
fuzzyOpenWithDepth Natural
defaultDepth
fuzzyOpenWithDepth :: Natural -> YiM ()
fuzzyOpenWithDepth :: Natural -> YiM ()
fuzzyOpenWithDepth Natural
d = do
[FuzzyItem]
fileList <- (([String] -> [FuzzyItem]) -> YiM [String] -> YiM [FuzzyItem]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([String] -> [FuzzyItem]) -> YiM [String] -> YiM [FuzzyItem])
-> ((String -> FuzzyItem) -> [String] -> [FuzzyItem])
-> (String -> FuzzyItem)
-> YiM [String]
-> YiM [FuzzyItem]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> FuzzyItem) -> [String] -> [FuzzyItem]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) (Text -> FuzzyItem
FileItem (Text -> FuzzyItem) -> (String -> Text) -> String -> FuzzyItem
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack) (IO [String] -> YiM [String]
forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
liftBase (IO [String] -> YiM [String]) -> IO [String] -> YiM [String]
forall a b. (a -> b) -> a -> b
$ Natural -> String -> IO [String]
getRecursiveContents Natural
d String
".")
[FuzzyItem]
bufList <- (([FBuffer] -> [FuzzyItem]) -> YiM [FBuffer] -> YiM [FuzzyItem]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([FBuffer] -> [FuzzyItem]) -> YiM [FBuffer] -> YiM [FuzzyItem])
-> ((FBuffer -> FuzzyItem) -> [FBuffer] -> [FuzzyItem])
-> (FBuffer -> FuzzyItem)
-> YiM [FBuffer]
-> YiM [FuzzyItem]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FBuffer -> FuzzyItem) -> [FBuffer] -> [FuzzyItem]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) (BufferId -> FuzzyItem
BufferItem (BufferId -> FuzzyItem)
-> (FBuffer -> BufferId) -> FBuffer -> FuzzyItem
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Attributes -> BufferId
ident (Attributes -> BufferId)
-> (FBuffer -> Attributes) -> FBuffer -> BufferId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FBuffer -> Attributes
attributes) (EditorM [FBuffer] -> YiM [FBuffer]
forall (m :: * -> *) a. MonadEditor m => EditorM a -> m a
withEditor ((Editor -> [FBuffer]) -> EditorM [FBuffer]
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets (Map BufferRef FBuffer -> [FBuffer]
forall k a. Map k a -> [a]
M.elems (Map BufferRef FBuffer -> [FBuffer])
-> (Editor -> Map BufferRef FBuffer) -> Editor -> [FBuffer]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Editor -> Map BufferRef FBuffer
buffers)))
BufferRef
promptRef <- EditorM BufferRef -> YiM BufferRef
forall (m :: * -> *) a. MonadEditor m => EditorM a -> m a
withEditor (Text -> KeymapEndo -> EditorM BufferRef
spawnMinibufferE Text
"" (Keymap -> KeymapEndo
forall a b. a -> b -> a
const Keymap
localKeymap))
let initialState :: FuzzyState
initialState = Maybe (PointedList FuzzyItem) -> Text -> FuzzyState
FuzzyState ([FuzzyItem] -> Maybe (PointedList FuzzyItem)
forall a. [a] -> Maybe (PointedList a)
PL.fromList ([FuzzyItem] -> [FuzzyItem]
filterNotCommon [FuzzyItem]
bufList [FuzzyItem] -> [FuzzyItem] -> [FuzzyItem]
forall a. Semigroup a => a -> a -> a
<> [FuzzyItem]
fileList)) Text
""
BufferRef -> BufferM () -> YiM ()
forall (m :: * -> *) a.
MonadEditor m =>
BufferRef -> BufferM a -> m a
withGivenBuffer BufferRef
promptRef (BufferM () -> YiM ()) -> BufferM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ FuzzyState -> BufferM ()
forall a (m :: * -> *).
(YiVariable a, MonadState FBuffer m, Functor m) =>
a -> m ()
putBufferDyn FuzzyState
initialState
EditorM () -> YiM ()
forall (m :: * -> *) a. MonadEditor m => EditorM a -> m a
withEditor (FuzzyState -> EditorM ()
renderE FuzzyState
initialState)
where
filterNotCommon :: [FuzzyItem] -> [FuzzyItem]
filterNotCommon :: [FuzzyItem] -> [FuzzyItem]
filterNotCommon = (FuzzyItem -> Bool) -> [FuzzyItem] -> [FuzzyItem]
forall a. (a -> Bool) -> [a] -> [a]
filter ((\Text
n -> Bool -> Bool
not (Text
n Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"console" Bool -> Bool -> Bool
|| Text
n Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"messages")) (Text -> Bool) -> (FuzzyItem -> Text) -> FuzzyItem -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FuzzyItem -> Text
itemAsTxt)
getRecursiveContents :: Natural -> FilePath -> IO [FilePath]
getRecursiveContents :: Natural -> String -> IO [String]
getRecursiveContents Natural
d String
t
| Natural
d Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== Natural
0 = [String] -> IO [String]
forall (m :: * -> *) a. Monad m => a -> m a
return [String]
forall a. Monoid a => a
mempty
| Bool
otherwise = do
Either IOError [String]
x <- IO [String] -> IO (Either IOError [String])
forall a. IO a -> IO (Either IOError a)
tryIOError (String -> IO [String]
getDirectoryContents String
t)
case Either IOError [String]
x of
Left IOError
_ -> [String] -> IO [String]
forall (m :: * -> *) a. Monad m => a -> m a
return [String]
forall a. Monoid a => a
mempty
Right [String]
names -> do
[[String]]
paths <- (String -> IO [String]) -> [String] -> IO [[String]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM String -> IO [String]
withName ((String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter String -> Bool
isProperName [String]
names)
[String] -> IO [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> IO [String]) -> [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ [[String]] -> [String]
forall a. Monoid a => [a] -> a
mconcat [[String]]
paths
where
isProperName :: FilePath -> Bool
isProperName :: String -> Bool
isProperName String
fileName = [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and
[ String
fileName String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [String
".", String
"..", String
".git", String
".svn"]
, Bool -> Bool
not (String
".hi" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
fileName)
, Bool -> Bool
not (String
"-boot" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
fileName)
]
withName :: FilePath -> IO [FilePath]
withName :: String -> IO [String]
withName String
name = do
let path :: String
path = String
t String -> ShowS
</> String
name
Bool
isDirectory <- String -> IO Bool
doesDirectoryExist String
path
if Bool
isDirectory then Natural -> String -> IO [String]
getRecursiveContents (Natural
d Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
- Natural
1) String
path else [String] -> IO [String]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [String
path]
localKeymap :: Keymap
localKeymap :: Keymap
localKeymap =
[Keymap] -> Keymap
forall (m :: * -> *) w e a.
(MonadInteract m w e, MonadFail m) =>
[m a] -> m a
choice
[ Key -> Event
spec Key
KEnter Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
openInThisWindow
, Char -> Event
ctrlCh Char
't' Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
openInNewTab
, Char -> Event
ctrlCh Char
's' Event -> YiM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! YiM ()
openInSplit
, Key -> Event
spec Key
KEsc Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
cleanupE
, Char -> Event
ctrlCh Char
'g' Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! EditorM ()
cleanupE
, Char -> Event
ctrlCh Char
'h' Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> EditorM ()
updatingB (TextUnit -> Direction -> BufferM ()
deleteB TextUnit
Character Direction
Backward)
, Key -> Event
spec Key
KBS Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> EditorM ()
updatingB (TextUnit -> Direction -> BufferM ()
deleteB TextUnit
Character Direction
Backward)
, Key -> Event
spec Key
KDel Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> EditorM ()
updatingB (TextUnit -> Direction -> BufferM ()
deleteB TextUnit
Character Direction
Backward)
, Char -> Event
ctrlCh Char
'a' Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM ()
moveToSol
, Char -> Event
ctrlCh Char
'e' Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM ()
moveToEol
, Key -> Event
spec Key
KLeft Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! Int -> BufferM ()
moveXorSol Int
1
, Key -> Event
spec Key
KRight Event -> BufferM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! Int -> BufferM ()
moveXorEol Int
1
, Char -> Event
ctrlCh Char
'p' Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! (FuzzyState -> FuzzyState) -> EditorM ()
modifyE FuzzyState -> FuzzyState
goPrevious
, Char -> Event
ctrlCh Char
'n' Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! (FuzzyState -> FuzzyState) -> EditorM ()
modifyE FuzzyState -> FuzzyState
goNext
, Key -> Event
spec Key
KDown Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! (FuzzyState -> FuzzyState) -> EditorM ()
modifyE FuzzyState -> FuzzyState
goNext
, Key -> [Modifier] -> Event
Event Key
KTab [Modifier
MShift] Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! (FuzzyState -> FuzzyState) -> EditorM ()
modifyE FuzzyState -> FuzzyState
goPrevious
, Key -> [Modifier] -> Event
Event Key
KTab [] Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! (FuzzyState -> FuzzyState) -> EditorM ()
modifyE FuzzyState -> FuzzyState
goNext
, Char -> Event
ctrlCh Char
'w' Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> EditorM ()
updatingB (TextUnit -> Direction -> BufferM ()
deleteB TextUnit
unitWord Direction
Backward)
, Char -> Event
ctrlCh Char
'u' Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> EditorM ()
updatingB (BufferM ()
moveToSol BufferM () -> BufferM () -> BufferM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> BufferM ()
deleteToEol)
, Char -> Event
ctrlCh Char
'k' Event -> EditorM () -> Keymap
forall (m :: * -> *) a x.
(MonadInteract m Action Event, YiAction a x, Show x) =>
Event -> a -> m ()
?>>! BufferM () -> EditorM ()
updatingB BufferM ()
deleteToEol
]
Keymap -> KeymapEndo
forall (f :: * -> *) w e a.
MonadInteract f w e =>
f a -> f a -> f a
<|| (Keymap
insertChar Keymap -> EditorM () -> Keymap
forall (m :: * -> *) a x b.
(MonadInteract m Action Event, YiAction a x, Show x) =>
m b -> a -> m ()
>>! (BufferM FuzzyState -> EditorM FuzzyState
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer BufferM FuzzyState
updateNeedleB EditorM FuzzyState -> (FuzzyState -> EditorM ()) -> EditorM ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= FuzzyState -> EditorM ()
renderE))
where
updatingB :: BufferM () -> EditorM ()
updatingB :: BufferM () -> EditorM ()
updatingB BufferM ()
bufAction = BufferM FuzzyState -> EditorM FuzzyState
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM ()
bufAction BufferM () -> BufferM FuzzyState -> BufferM FuzzyState
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> BufferM FuzzyState
updateNeedleB) EditorM FuzzyState -> (FuzzyState -> EditorM ()) -> EditorM ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= FuzzyState -> EditorM ()
renderE
updateNeedleB :: BufferM FuzzyState
updateNeedleB :: BufferM FuzzyState
updateNeedleB = do
Text
s <- YiString -> Text
R.toText (YiString -> Text) -> BufferM YiString -> BufferM Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BufferM YiString
readLnB
FuzzyState
oldState <- BufferM FuzzyState
forall (m :: * -> *) a.
(Default a, YiVariable a, MonadState FBuffer m, Functor m) =>
m a
getBufferDyn
let newState :: FuzzyState
newState = FuzzyState
oldState FuzzyState -> Text -> FuzzyState
`filterState` Text
s
FuzzyState -> BufferM ()
forall a (m :: * -> *).
(YiVariable a, MonadState FBuffer m, Functor m) =>
a -> m ()
putBufferDyn FuzzyState
newState
FuzzyState -> BufferM FuzzyState
forall (m :: * -> *) a. Monad m => a -> m a
return FuzzyState
newState
where
filterState :: FuzzyState -> Text -> FuzzyState
filterState :: FuzzyState -> Text -> FuzzyState
filterState FuzzyState
old Text
s = FuzzyState
old { search :: Text
search = Text
s, items :: Maybe (PointedList FuzzyItem)
items = Maybe (PointedList FuzzyItem)
newItems }
where
newItems :: Maybe (PointedList FuzzyItem)
newItems :: Maybe (PointedList FuzzyItem)
newItems = do
PointedList FuzzyItem
o <- FuzzyState -> Maybe (PointedList FuzzyItem)
items FuzzyState
old
PointedList FuzzyItem
f <- Text -> PointedList FuzzyItem -> Maybe (PointedList FuzzyItem)
filterItems Text
s PointedList FuzzyItem
o
Int -> PointedList FuzzyItem -> Maybe (PointedList FuzzyItem)
forall a. Int -> PointedList a -> Maybe (PointedList a)
PL.moveTo Int
0 PointedList FuzzyItem
f
filterItems :: Text -> PointedList FuzzyItem -> Maybe (PointedList FuzzyItem)
filterItems :: Text -> PointedList FuzzyItem -> Maybe (PointedList FuzzyItem)
filterItems Text
s PointedList FuzzyItem
zipper = (FuzzyItem -> Bool)
-> PointedList FuzzyItem -> Maybe (PointedList FuzzyItem)
forall a. (a -> Bool) -> PointedList a -> Maybe (PointedList a)
PL.filterr (Text -> Text -> Bool
subsequenceTextMatch Text
s (Text -> Bool) -> (FuzzyItem -> Text) -> FuzzyItem -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FuzzyItem -> Text
itemAsTxt) PointedList FuzzyItem
zipper
modifyE :: (FuzzyState -> FuzzyState) -> EditorM ()
modifyE :: (FuzzyState -> FuzzyState) -> EditorM ()
modifyE FuzzyState -> FuzzyState
f = do
FuzzyState
prevState <- BufferM FuzzyState -> EditorM FuzzyState
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer BufferM FuzzyState
forall (m :: * -> *) a.
(Default a, YiVariable a, MonadState FBuffer m, Functor m) =>
m a
getBufferDyn
let newState :: FuzzyState
newState = FuzzyState -> FuzzyState
f FuzzyState
prevState
BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (FuzzyState -> BufferM ()
forall a (m :: * -> *).
(YiVariable a, MonadState FBuffer m, Functor m) =>
a -> m ()
putBufferDyn FuzzyState
newState)
FuzzyState -> EditorM ()
renderE FuzzyState
newState
goNext :: FuzzyState -> FuzzyState
goNext :: FuzzyState -> FuzzyState
goNext = (PointedList FuzzyItem -> Maybe (PointedList FuzzyItem))
-> FuzzyState -> FuzzyState
changeIndex PointedList FuzzyItem -> Maybe (PointedList FuzzyItem)
forall a. PointedList a -> Maybe (PointedList a)
PL.next
goPrevious :: FuzzyState -> FuzzyState
goPrevious :: FuzzyState -> FuzzyState
goPrevious = (PointedList FuzzyItem -> Maybe (PointedList FuzzyItem))
-> FuzzyState -> FuzzyState
changeIndex PointedList FuzzyItem -> Maybe (PointedList FuzzyItem)
forall a. PointedList a -> Maybe (PointedList a)
PL.previous
changeIndex :: (PointedList FuzzyItem -> Maybe (PointedList FuzzyItem)) -> FuzzyState -> FuzzyState
changeIndex :: (PointedList FuzzyItem -> Maybe (PointedList FuzzyItem))
-> FuzzyState -> FuzzyState
changeIndex PointedList FuzzyItem -> Maybe (PointedList FuzzyItem)
dir FuzzyState
fs = FuzzyState
fs { items :: Maybe (PointedList FuzzyItem)
items = FuzzyState -> Maybe (PointedList FuzzyItem)
items FuzzyState
fs Maybe (PointedList FuzzyItem)
-> (PointedList FuzzyItem -> Maybe (PointedList FuzzyItem))
-> Maybe (PointedList FuzzyItem)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= PointedList FuzzyItem -> Maybe (PointedList FuzzyItem)
dir }
renderE :: FuzzyState -> EditorM ()
renderE :: FuzzyState -> EditorM ()
renderE (FuzzyState Maybe (PointedList FuzzyItem)
maybeZipper Text
s) =
case Maybe (NonEmpty Text)
mcontent of
Maybe (NonEmpty Text)
Nothing -> Text -> EditorM ()
forall (m :: * -> *). MonadEditor m => Text -> m ()
printMsg Text
"No match found"
Just NonEmpty Text
content -> Status -> EditorM ()
forall (m :: * -> *). MonadEditor m => Status -> m ()
setStatus (NonEmpty Text -> [Text]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty Text
content, StyleName
defaultStyle)
where
tshow :: Show s => s -> Text
tshow :: s -> Text
tshow = String -> Text
T.pack (String -> Text) -> (s -> String) -> s -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> String
forall a. Show a => a -> String
show
mcontent :: Maybe (NonEmpty Text)
mcontent :: Maybe (NonEmpty Text)
mcontent = do
PointedList FuzzyItem
zipper <- Maybe (PointedList FuzzyItem)
maybeZipper
PointedList (FuzzyItem, Bool)
zipper' <- PointedList FuzzyItem -> PointedList (FuzzyItem, Bool)
forall a. PointedList a -> PointedList (a, Bool)
PL.withFocus (PointedList FuzzyItem -> PointedList (FuzzyItem, Bool))
-> Maybe (PointedList FuzzyItem)
-> Maybe (PointedList (FuzzyItem, Bool))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> PointedList FuzzyItem -> Maybe (PointedList FuzzyItem)
filterItems Text
s PointedList FuzzyItem
zipper
[Text] -> Maybe (NonEmpty Text)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty ([Text] -> Maybe (NonEmpty Text))
-> (PointedList Text -> [Text])
-> PointedList Text
-> Maybe (NonEmpty Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PointedList Text -> [Text]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (PointedList Text -> Maybe (NonEmpty Text))
-> PointedList Text -> Maybe (NonEmpty Text)
forall a b. (a -> b) -> a -> b
$ ((FuzzyItem, Bool) -> Text)
-> PointedList (FuzzyItem, Bool) -> PointedList Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((FuzzyItem -> Bool -> Text) -> (FuzzyItem, Bool) -> Text
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((FuzzyItem -> Bool -> Text) -> (FuzzyItem, Bool) -> Text)
-> (FuzzyItem -> Bool -> Text) -> (FuzzyItem, Bool) -> Text
forall a b. (a -> b) -> a -> b
$ (Bool -> FuzzyItem -> Text) -> FuzzyItem -> Bool -> Text
forall a b c. (a -> b -> c) -> b -> a -> c
flip Bool -> FuzzyItem -> Text
renderItem) PointedList (FuzzyItem, Bool)
zipper'
renderItem :: Bool -> FuzzyItem -> Text
renderItem :: Bool -> FuzzyItem -> Text
renderItem Bool
isFocus FuzzyItem
fi = Bool -> Text -> Text
renderStar Bool
isFocus (Int -> Char -> Text -> Text
T.justifyLeft Int
79 Char
' ' (Text -> Text) -> (FuzzyItem -> Text) -> FuzzyItem -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text) -> (FuzzyItem -> String) -> FuzzyItem -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FuzzyItem -> String
forall a. Show a => a -> String
show (FuzzyItem -> Text) -> FuzzyItem -> Text
forall a b. (a -> b) -> a -> b
$ FuzzyItem
fi)
renderStar :: Bool -> (Text -> Text)
renderStar :: Bool -> Text -> Text
renderStar Bool
y = if Bool
y then (Text
"* "Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) else (Text
" "Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>)
openInThisWindow :: YiM ()
openInThisWindow :: YiM ()
openInThisWindow = EditorM () -> YiM ()
openRoutine (() -> EditorM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())
openInSplit :: YiM ()
openInSplit :: YiM ()
openInSplit = EditorM () -> YiM ()
openRoutine EditorM ()
splitE
openInNewTab :: YiM ()
openInNewTab :: YiM ()
openInNewTab = EditorM () -> YiM ()
openRoutine EditorM ()
newTabE
openRoutine :: EditorM () -> YiM ()
openRoutine :: EditorM () -> YiM ()
openRoutine EditorM ()
preOpenAction = do
Maybe (PointedList FuzzyItem)
mzipper <- FuzzyState -> Maybe (PointedList FuzzyItem)
items (FuzzyState -> Maybe (PointedList FuzzyItem))
-> YiM FuzzyState -> YiM (Maybe (PointedList FuzzyItem))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BufferM FuzzyState -> YiM FuzzyState
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer BufferM FuzzyState
forall (m :: * -> *) a.
(Default a, YiVariable a, MonadState FBuffer m, Functor m) =>
m a
getBufferDyn
case Maybe (PointedList FuzzyItem)
mzipper of
Maybe (PointedList FuzzyItem)
Nothing -> Text -> YiM ()
forall (m :: * -> *). MonadEditor m => Text -> m ()
printMsg Text
"Nothing selected"
Just (PointedList [FuzzyItem]
_ FuzzyItem
f [FuzzyItem]
_) -> do
EditorM () -> YiM ()
forall (m :: * -> *) a. MonadEditor m => EditorM a -> m a
withEditor (EditorM () -> YiM ()) -> EditorM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ do
EditorM ()
cleanupE
EditorM ()
preOpenAction
FuzzyItem -> YiM ()
action FuzzyItem
f
where
action :: FuzzyItem -> YiM ()
action :: FuzzyItem -> YiM ()
action (FileItem Text
x) = YiM (Either Text BufferRef) -> YiM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (String -> YiM (Either Text BufferRef)
editFile (Text -> String
T.unpack Text
x))
action (BufferItem BufferId
x) = EditorM () -> YiM ()
forall (m :: * -> *) a. MonadEditor m => EditorM a -> m a
withEditor (EditorM () -> YiM ()) -> EditorM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ do
[(BufferRef, FBuffer)]
bufs <- (Editor -> [(BufferRef, FBuffer)])
-> EditorM [(BufferRef, FBuffer)]
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets (Map BufferRef FBuffer -> [(BufferRef, FBuffer)]
forall k a. Map k a -> [(k, a)]
M.assocs (Map BufferRef FBuffer -> [(BufferRef, FBuffer)])
-> (Editor -> Map BufferRef FBuffer)
-> Editor
-> [(BufferRef, FBuffer)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Editor -> Map BufferRef FBuffer
buffers)
case ((BufferRef, FBuffer) -> Bool)
-> [(BufferRef, FBuffer)] -> [(BufferRef, FBuffer)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((BufferId -> BufferId -> Bool
forall a. Eq a => a -> a -> Bool
==BufferId
x) (BufferId -> Bool)
-> ((BufferRef, FBuffer) -> BufferId)
-> (BufferRef, FBuffer)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Attributes -> BufferId
ident (Attributes -> BufferId)
-> ((BufferRef, FBuffer) -> Attributes)
-> (BufferRef, FBuffer)
-> BufferId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FBuffer -> Attributes
attributes (FBuffer -> Attributes)
-> ((BufferRef, FBuffer) -> FBuffer)
-> (BufferRef, FBuffer)
-> Attributes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BufferRef, FBuffer) -> FBuffer
forall a b. (a, b) -> b
snd) [(BufferRef, FBuffer)]
bufs of
[] -> String -> EditorM ()
forall a. HasCallStack => String -> a
error (String
"Couldn't find " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> BufferId -> String
forall a. Show a => a -> String
show BufferId
x)
(BufferRef
bufRef, FBuffer
_):[(BufferRef, FBuffer)]
_ -> BufferRef -> EditorM ()
switchToBufferE BufferRef
bufRef
insertChar :: Keymap
insertChar :: Keymap
insertChar = KeymapM Char
textChar KeymapM Char -> (Char -> Keymap) -> Keymap
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= BufferM () -> Keymap
forall (m :: * -> *) ev a x.
(MonadInteract m Action ev, YiAction a x, Show x) =>
a -> m ()
write (BufferM () -> Keymap) -> (Char -> BufferM ()) -> Char -> Keymap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> BufferM ()
insertB
cleanupE :: EditorM ()
cleanupE :: EditorM ()
cleanupE = EditorM ()
clrStatus EditorM () -> EditorM () -> EditorM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> EditorM ()
closeBufferAndWindowE
instance Binary FuzzyItem where
put :: FuzzyItem -> Put
put (FileItem Text
x) = Word8 -> Put
forall t. Binary t => t -> Put
put (Word8
0 :: Word8) Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Put
forall t. Binary t => t -> Put
put Text
x
put (BufferItem BufferId
x) = Word8 -> Put
forall t. Binary t => t -> Put
put (Word8
1 :: Word8) Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> BufferId -> Put
forall t. Binary t => t -> Put
put BufferId
x
get :: Get FuzzyItem
get = do
Word8
tag :: Word8 <- Get Word8
forall t. Binary t => Get t
get
case Word8
tag of
Word8
0 -> Text -> FuzzyItem
FileItem (Text -> FuzzyItem) -> Get Text -> Get FuzzyItem
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Text
forall t. Binary t => Get t
get
Word8
1 -> BufferId -> FuzzyItem
BufferItem (BufferId -> FuzzyItem) -> Get BufferId -> Get FuzzyItem
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get BufferId
forall t. Binary t => Get t
get
Word8
_ -> String -> Get FuzzyItem
forall a. HasCallStack => String -> a
error String
"Unexpected FuzzyItem Binary."
instance Binary FuzzyState where
put :: FuzzyState -> Put
put (FuzzyState Maybe (PointedList FuzzyItem)
mzipper Text
s) = do
Maybe (PointedList FuzzyItem) -> Put
forall t. Binary t => t -> Put
put Maybe (PointedList FuzzyItem)
mzipper
ByteString -> Put
forall t. Binary t => t -> Put
put (Text -> ByteString
T.encodeUtf8 Text
s)
get :: Get FuzzyState
get = Maybe (PointedList FuzzyItem) -> Text -> FuzzyState
FuzzyState (Maybe (PointedList FuzzyItem) -> Text -> FuzzyState)
-> Get (Maybe (PointedList FuzzyItem)) -> Get (Text -> FuzzyState)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (Maybe (PointedList FuzzyItem))
forall t. Binary t => Get t
get Get (Text -> FuzzyState) -> Get Text -> Get FuzzyState
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (ByteString -> Text) -> Get ByteString -> Get Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Text
T.decodeUtf8 Get ByteString
forall t. Binary t => Get t
get
instance Default FuzzyState where
def :: FuzzyState
def = Maybe (PointedList FuzzyItem) -> Text -> FuzzyState
FuzzyState Maybe (PointedList FuzzyItem)
forall a. Maybe a
Nothing Text
forall a. Monoid a => a
mempty
instance YiVariable FuzzyState