Xmonad中将Shell命令输出作为Prompt补全选项遇编译错误
解决Xmonad Prompt调用Shell命令输出作为补全选项的问题
首先明确核心问题:Xmonad Prompt的补全函数要求类型为String -> X [String],你之前的尝试要么类型不匹配,要么错误处理了IO操作的结果。以下是具体的实现方案:
必要的导入模块
确保配置文件导入这些模块:
import XMonad.Prompt import XMonad.Util.Run (runProcessWithInput) import Control.Monad.IO.Class (liftIO) -- 如需拆分多行输出,额外导入split包模块 import Data.List.Split (splitOn)
基础实现(单输出项,比如date命令)
编写返回date命令输出作为补全选项的函数:
-- 补全函数:忽略用户当前输入,返回date命令的输出作为唯一补全项 dateCompl :: String -> X [String] dateCompl _ = do -- 用runProcessWithInput执行shell命令,通过liftIO将IO操作提升到X monad rawOutput <- liftIO $ runProcessWithInput "date" [] "" -- 去掉输出末尾的换行符,包装成列表 let complOptions = [filter (/= '\n') rawOutput] return complOptions
调用mkXPrompt时使用这个函数:
mkXPrompt TestPrompt config dateCompl testFun
多行输出处理(比如ls命令)
如果命令输出有多行(如ls),拆分每一行作为独立补全选项:
lsCompl :: String -> X [String] lsCompl _ = do rawOutput <- liftIO $ runProcessWithInput "ls" [] "" -- 按换行拆分输出,过滤空行避免无效补全 let complOptions = filter (not . null) $ splitOn "\n" rawOutput return complOptions
你之前尝试失败的原因
- 类型不匹配:
mkComplFunFromList只接受纯[String]列表,无法直接处理IO产生的动态内容,必须自己实现返回X [String]的函数。 - 错误的IO操作组合:
liftIO $ putStrLn $ runProcessWithInput...是错误的,putStrLn返回IO (),不能绑定到output变量,应直接绑定runProcessWithInput的结果(它返回IO String)。 - 不必要的readIO:
readIO是将字符串解析为特定类型的操作,你需要的是原始字符串,完全不需要这一步。
内容的提问来源于stack exchange,提问作者lwndt
相关产品推荐
相关产品推荐

