You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

你之前尝试失败的原因

  1. 类型不匹配:mkComplFunFromList只接受纯[String]列表,无法直接处理IO产生的动态内容,必须自己实现返回X [String]的函数。
  2. 错误的IO操作组合:liftIO $ putStrLn $ runProcessWithInput...是错误的,putStrLn返回IO (),不能绑定到output变量,应直接绑定runProcessWithInput的结果(它返回IO String)。
  3. 不必要的readIO:readIO是将字符串解析为特定类型的操作,你需要的是原始字符串,完全不需要这一步。

内容的提问来源于stack exchange,提问作者lwndt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:15:30