X.Prompt: X constraint for historyCompletion[P]

This is needed because the cache directory is now a part of XConf, which
is calculated once on startup and hence any recalculation would be
fragile.

Some internal functions that are not exposed (like writeHistory) were
also changed to accept that directory as an argument.
This commit is contained in:
slotThe
2020-12-27 19:26:08 +01:00
parent 3213925b6b
commit 9d520dc880
2 changed files with 25 additions and 23 deletions

View File

@@ -363,18 +363,16 @@ namedEngine name (SearchEngine _ site) = searchEngineF name site
Prompt's result, passes it to a given searchEngine and opens it in a given Prompt's result, passes it to a given searchEngine and opens it in a given
browser. -} browser. -}
promptSearchBrowser :: XPConfig -> Browser -> SearchEngine -> X () promptSearchBrowser :: XPConfig -> Browser -> SearchEngine -> X ()
promptSearchBrowser config browser (SearchEngine name site) = promptSearchBrowser config browser (SearchEngine name site) = do
mkXPrompt (Search name) config (historyCompletionP ("Search [" `isPrefixOf`)) $ search browser site hc <- historyCompletionP ("Search [" `isPrefixOf`)
mkXPrompt (Search name) config hc $ search browser site
{- | Like 'promptSearchBrowser', but only suggest previous searches for the {- | Like 'promptSearchBrowser', but only suggest previous searches for the
given 'SearchEngine' in the prompt. -} given 'SearchEngine' in the prompt. -}
promptSearchBrowser' :: XPConfig -> Browser -> SearchEngine -> X () promptSearchBrowser' :: XPConfig -> Browser -> SearchEngine -> X ()
promptSearchBrowser' config browser (SearchEngine name site) = promptSearchBrowser' config browser (SearchEngine name site) = do
mkXPrompt hc <- historyCompletionP (searchName `isPrefixOf`)
(Search name) mkXPrompt (Search name) config hc $ search browser site
config
(historyCompletionP (searchName `isPrefixOf`))
$ search browser site
where where
searchName = showXPrompt (Search name) searchName = showXPrompt (Search name)

View File

@@ -543,7 +543,8 @@ mkXPromptImplementation historyKey conf om = do
XConf { display = d, theRoot = rw } <- ask XConf { display = d, theRoot = rw } <- ask
s <- gets $ screenRect . W.screenDetail . W.current . windowset s <- gets $ screenRect . W.screenDetail . W.current . windowset
numlock <- gets X.numberlockMask numlock <- gets X.numberlockMask
hist <- io readHistory cachedir <- getXMonadCacheDir
hist <- io $ readHistory cachedir
fs <- initXMF (font conf) fs <- initXMF (font conf)
st' <- io $ st' <- io $
bracket bracket
@@ -562,7 +563,7 @@ mkXPromptImplementation historyKey conf om = do
releaseXMF fs releaseXMF fs
when (successful st') $ do when (successful st') $ do
let prune = take (historySize conf) let prune = take (historySize conf)
io $ writeHistory $ io $ writeHistory cachedir $
M.insertWith M.insertWith
(\xs ys -> prune . historyFilter conf $ xs ++ ys) (\xs ys -> prune . historyFilter conf $ xs ++ ys)
historyKey historyKey
@@ -1560,21 +1561,21 @@ type History = M.Map String [String]
emptyHistory :: History emptyHistory :: History
emptyHistory = M.empty emptyHistory = M.empty
getHistoryFile :: IO FilePath getHistoryFile :: FilePath -> FilePath
getHistoryFile = fmap (++ "/prompt-history") getXMonadCacheDir getHistoryFile cachedir = cachedir ++ "/prompt-history"
readHistory :: IO History readHistory :: FilePath -> IO History
readHistory = readHist `E.catch` \(SomeException _) -> return emptyHistory readHistory cachedir = readHist `E.catch` \(SomeException _) -> return emptyHistory
where where
readHist = do readHist = do
path <- getHistoryFile let path = getHistoryFile cachedir
xs <- bracket (openFile path ReadMode) hClose hGetLine xs <- bracket (openFile path ReadMode) hClose hGetLine
readIO xs readIO xs
writeHistory :: History -> IO () writeHistory :: FilePath -> History -> IO ()
writeHistory hist = do writeHistory cachedir hist = do
path <- getHistoryFile let path = getHistoryFile cachedir
let filtered = M.filter (not . null) hist filtered = M.filter (not . null) hist
writeFile path (show filtered) `E.catch` \(SomeException e) -> writeFile path (show filtered) `E.catch` \(SomeException e) ->
hPutStrLn stderr ("error writing history: "++show e) hPutStrLn stderr ("error writing history: "++show e)
setFileMode path mode setFileMode path mode
@@ -1667,14 +1668,17 @@ breakAtSpace s
-- | 'historyCompletion' provides a canned completion function much like -- | 'historyCompletion' provides a canned completion function much like
-- 'getShellCompl'; you pass it to mkXPrompt, and it will make completions work -- 'getShellCompl'; you pass it to mkXPrompt, and it will make completions work
-- from the query history stored in the XMonad cache directory. -- from the query history stored in the XMonad cache directory.
historyCompletion :: ComplFunction historyCompletion :: X ComplFunction
historyCompletion = historyCompletionP (const True) historyCompletion = historyCompletionP (const True)
-- | Like 'historyCompletion' but only uses history data from Prompts whose -- | Like 'historyCompletion' but only uses history data from Prompts whose
-- name satisfies the given predicate. -- name satisfies the given predicate.
historyCompletionP :: (String -> Bool) -> ComplFunction historyCompletionP :: (String -> Bool) -> X ComplFunction
historyCompletionP p x = fmap (toComplList . M.filterWithKey (const . p)) readHistory historyCompletionP p = do
where toComplList = deleteConsecutive . filter (isInfixOf x) . M.foldr (++) [] cd <- getXMonadCacheDir
pure $ \x ->
let toComplList = deleteConsecutive . filter (isInfixOf x) . M.foldr (++) []
in toComplList . M.filterWithKey (const . p) <$> readHistory cd
-- | Sort a list and remove duplicates. Like 'deleteAllDuplicates', but trades off -- | Sort a list and remove duplicates. Like 'deleteAllDuplicates', but trades off
-- laziness and stability for efficiency. -- laziness and stability for efficiency.