我最近决定通过 Stack 从源代码构建 XMonad 以进行自定义配置。让我先说我没有大量使用 Haskell 的经验。我的操作系统是 Linux - Arch。
设置
我正在尝试使用XMonad.Prompt
xmonad-contrib 中的包来启动一些应用程序。(https://hackage.haskell.org/package/xmonad-contrib-0.13/docs/XMonad-Prompt.html)
目前,我使用的一个提示是,它使用默认终端中提供的参数XMonad.Prompt.Man
启动程序(我默认的终端是 Alacritty)。man
(文档:https ://hackage.haskell.org/package/xmonad-contrib-0.13/docs/XMonad-Prompt-Man.html )(来源:https ://hackage.haskell.org/package/xmonad-contrib- 0.13/docs/src/XMonad-Prompt-Man.html )
我不明白的是如何使用此提示将终端启动到工作区 2,我希望在其中打开所有联机帮助页。
提示目前的工作方式:
我在 中设置了一个键绑定xmonad.hs
,如下所示:
...
, ("M-C-m", manPrompt myPromptConfig)
...
这可以按照文档所说的方式工作,但是联机帮助页始终在当前工作区中打开,而不是在我希望它们打开的工作区 2 中。
我试过的
因为man
在现有终端中打开并且不提供设置窗口名称的选项,所以我最初无法ManageHook
用于检测窗口名称并将其转移到正确的工作区,就像我对 Mozilla Firefox 之类的应用程序所做的那样:(https: //hackage.haskell.org/package/xmonad-0.15/docs/XMonad-ManageHook.html )
myManageHook = composeAll
[
...
, title =? "Mozilla Firefox" -> (doShift !! myWorkspaces 1)
...
]
我尝试使用 Alacritty 的选项将窗口名称设置为硬编码的名称,但这只会在终端生成并且已经在当前布局上调用--title
之后才移动终端,导致终端移动到不同的文本对齐方式不正确man
具有不同布局的工作区。
我认为适当的解决方案可能需要修改XMonad.Prompt.Man
.
查看源代码XMonad.Prompt.Man
,我发现这一行可能有助于更改(第 60-63 行):(https://hackage.haskell.org/package/xmonad-contrib-0.13/docs/src/XMonad-Prompt -Man.html )
manPrompt :: XPConfig -> X()
manPrompt c = do -- NOTE FROM ME: getMans and manCompl are functions defined elsewhere in the file that are not relevant here
mans <- io getMans
mkXPrompt Man c (manCompl c mans) $ runInTerm "" . (++) "man "
查看runInTerm
(from XMonad.Util.Run
) 的源代码,在我看来它需要 2 个字符串 args:第一个是选项列表,""
在manPrompt
(即默认为空白) 的情况下,第二个是要运行的命令,"man "
在的情况manPrompt
。这些都在默认终端中运行(对我来说是 Alacritty)。(文档:https ://hackage.haskell.org/package/xmonad-contrib-0.16/docs/XMonad-Util-Run.html )(来源:https ://hackage.haskell.org/package/xmonad-contrib- 0.16/docs/src/XMonad.Util.Run.html#runInTerm )
我可以做些什么来修改manPrompt
或runInTerm
指定终端在哪个工作区中manPrompt
生成?或者有没有其他人知道实现我不知道的期望行为的方法?
编辑#1
在最近的答案的建议下,我试图修补代码以从manPrompt
运行,而不是. (https://hackage.haskell.org/package/xmonad-contrib-0.13/docs/XMonad-Actions-SpawnOn.html)spawnOn
XMonad.Actions.SpawnOn
runInTerm
这是我现在所拥有的:
manPrompt :: XPConfig -> WorkspaceId -> String -> X ()
manPrompt promptConfig workspaceId terminalArgs = do
mans <- io getMans
mkXPrompt (showXPrompt "man ") promptConfig (manCompl promptConfig mans) $ spawnOn (workspaceId) $ (myTerminal) ++ " " ++ (terminalArgs) ++ " -e man "
但是,这不会编译,导致错误:
xmonad.hs:248:78: error:
* Couldn't match expected type `String -> X ()'
with actual type `X ()'
* In the second argument of `($)', namely
`spawnOn (workspaceId)
$ (myTerminal) ++ " " ++ (terminalArgs) ++ " -e man "'
In a stmt of a 'do' block:
mkXPrompt
(showXPrompt "man ") promptConfig (manCompl promptConfig mans)
$ spawnOn (workspaceId)
$ (myTerminal) ++ " " ++ (terminalArgs) ++ " -e man "
In the expression:
do mans <- io getMans
mkXPrompt
(showXPrompt "man ") promptConfig (manCompl promptConfig mans)
$ spawnOn (workspaceId)
$ (myTerminal) ++ " " ++ (terminalArgs) ++ " -e man "
|
248 | mkXPrompt (showXPrompt "man ") promptConfig (manCompl promptConfig mans) $ spawnOn (workspaceId) $ (myTerminal) ++ " " ++ (terminalArgs) ++ " -e man "
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我认为这个问题是由于我未能正确掌握 Haskell 数据类型,但我不明白......如果调用的正确方法spawnOn
是spawnOn <workspaceId> <command>
,我如何将String
bash 命令传递给函数<command>
,就像上面一样?
编辑#2——解决方案#1
我目前的解决方案是使用一个自定义补丁XMonad.Prompt.Man
,manPrompt
它看起来像下面这样:
manPrompt :: XPConfig -> WorkspaceId -> String -> X ()
manPrompt promptConfig workspaceId terminalArgs = do
mans <- io getMans
mkXPrompt Man promptConfig (manCompl promptConfig mans) $
\input -> spawnOn workspaceId $ myTerminal ++ " " ++ terminalArgs ++ " -e man " ++ input
我猜这可以编译并且可以工作,但似乎仍然会导致与在具有不同布局的工作区之间移动终端窗口时spawnOn
相同的文本对齐问题。(我在我尝试过doShift
的原始帖子中提到了这些。)
为了更好地解释“文本对齐问题”的含义,我在此处添加了一个屏幕截图:https
://ibb.co/vxjcKZh将注意力集中在生成联机帮助页的工作区上,它应该是全屏的,但是您可以看到,文本不会填满整个终端窗口;这是因为该man
命令在窗口大小被压缩时运行。)
有没有办法在终端窗口产生后以某种方式刷新终端窗口中的文本?