mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-08-11 02:02:11 -07:00
Use Stack instead of list in X.Prompt.history*Matching
This commit is contained in:
@@ -62,6 +62,7 @@ module XMonad.Prompt
|
|||||||
, HistoryMatches
|
, HistoryMatches
|
||||||
, initMatches
|
, initMatches
|
||||||
, historyUpMatching
|
, historyUpMatching
|
||||||
|
, historyDownMatching
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Prelude hiding (catch)
|
import Prelude hiding (catch)
|
||||||
@@ -881,38 +882,44 @@ deleteAllDuplicates, deleteConsecutive :: [String] -> [String]
|
|||||||
deleteAllDuplicates = nub
|
deleteAllDuplicates = nub
|
||||||
deleteConsecutive = map head . group
|
deleteConsecutive = map head . group
|
||||||
|
|
||||||
newtype HistoryMatches = HistoryMatches (IORef ([String],[String]))
|
newtype HistoryMatches = HistoryMatches (IORef ([String],Maybe (W.Stack String)))
|
||||||
|
|
||||||
-- | Initializes a new HistoryMatches structure to be passed
|
-- | Initializes a new HistoryMatches structure to be passed
|
||||||
-- to historyUpMatching
|
-- to historyUpMatching
|
||||||
initMatches :: (Functor m, MonadIO m) => m HistoryMatches
|
initMatches :: (Functor m, MonadIO m) => m HistoryMatches
|
||||||
initMatches = HistoryMatches <$> liftIO (newIORef ([],[]))
|
initMatches = HistoryMatches <$> liftIO (newIORef ([],Nothing))
|
||||||
|
|
||||||
|
historyNextMatching :: HistoryMatches -> (W.Stack String -> W.Stack String) -> XP ()
|
||||||
|
historyNextMatching hm@(HistoryMatches ref) next = do
|
||||||
|
(completed,completions) <- io $ readIORef ref
|
||||||
|
input <- getInput
|
||||||
|
if input `elem` completed
|
||||||
|
then case completions of
|
||||||
|
Just cs -> do
|
||||||
|
let cmd = W.focus cs
|
||||||
|
modify $ setCommand cmd
|
||||||
|
modify $ \s -> s { offset = length cmd }
|
||||||
|
io $ writeIORef ref (cmd:completed,Just $ next cs)
|
||||||
|
Nothing -> return ()
|
||||||
|
else do -- the user typed something new, recompute completions
|
||||||
|
io . writeIORef ref . ((,) [input]) . filterMatching input =<< gets commandHistory
|
||||||
|
historyNextMatching hm next
|
||||||
|
where filterMatching :: String -> W.Stack String -> Maybe (W.Stack String)
|
||||||
|
filterMatching prefix = W.filter (prefix `isPrefixOf`) . next
|
||||||
|
|
||||||
-- | Retrieve the next history element that starts with
|
-- | Retrieve the next history element that starts with
|
||||||
-- the current input. Pass it an IORef containing two empty lists
|
-- the current input. Pass it the result of initMatches
|
||||||
-- when creating the prompt. Example:
|
-- when creating the prompt. Example:
|
||||||
--
|
--
|
||||||
-- > ..
|
-- > ..
|
||||||
-- > ((modMask,xK_p), shellPrompt . myPrompt =<< initMatches)
|
-- > ((modMask,xK_p), shellPrompt . myPrompt =<< initMatches)
|
||||||
-- > ..
|
-- > ..
|
||||||
-- > myPrompt ref = defaultPrompt
|
-- > myPrompt ref = defaultPrompt
|
||||||
-- > { promptKeymap = M.union [((0,xK_Up), historyMatching ref)] (promptKeymap defaultPrompt)
|
-- > { promptKeymap = M.union [((0,xK_Up), historyMatching ref)
|
||||||
|
-- > ,((0,xK_Down), historyMatching ref)]
|
||||||
|
-- > (promptKeymap defaultPrompt)
|
||||||
-- > , .. }
|
-- > , .. }
|
||||||
--
|
--
|
||||||
historyUpMatching :: HistoryMatches -> XP ()
|
historyUpMatching, historyDownMatching :: HistoryMatches -> XP ()
|
||||||
historyUpMatching hm@(HistoryMatches ref) = do
|
historyUpMatching hm = historyNextMatching hm W.focusUp'
|
||||||
(completed,completions) <- io $ readIORef ref
|
historyDownMatching hm = historyNextMatching hm W.focusDown'
|
||||||
input <- getInput
|
|
||||||
if input `elem` completed
|
|
||||||
then case completions of
|
|
||||||
(c:cs) -> do
|
|
||||||
modify (setCommand c)
|
|
||||||
modify $ \s -> s { offset = length c }
|
|
||||||
io $ writeIORef ref (c:completed,cs)
|
|
||||||
_ -> return ()
|
|
||||||
else do -- the user typed something new, recompute completions
|
|
||||||
io . writeIORef ref . ((,) [input]) . filterMatching input =<< gets commandHistory
|
|
||||||
historyUpMatching hm
|
|
||||||
where filterMatching :: String -> W.Stack String -> [String]
|
|
||||||
filterMatching prefix =
|
|
||||||
filter (prefix `isPrefixOf`) . tail . cycle . nub . W.integrate
|
|
Reference in New Issue
Block a user