我最近決定通過 Stack 從源代碼構建 XMonad 以進行自定義配置。讓我先說我沒有大量使用 Haskell 的經驗。我的作業系統是 Linux - Arch。
設定
我正在嘗試使用XMonad.Promptxmonad-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)
...
]
I have tried setting the window name to something hard-coded using Alacritty's --title option, but that only shifts the terminal after it has been spawned and man has already been invoked on the current layout, resulting in incorrect text alignment when the terminal gets shifted to a different workspace with a different layout.
I thought a proper solution might require modifying the source code of XMonad.Prompt.Man.
Looking at the source code for XMonad.Prompt.Man, I saw that this line might be useful to change (line 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 "
Looking at the source code for runInTerm (from XMonad.Util.Run), it looks to me like it takes 2 string args: the first being a list of options, "" in the case of manPrompt (i.e. blank by default), and the second being the command to run, "man " in the case of manPrompt. These both get run in the default terminal (Alacritty for me).
(docs: https://hackage.haskell.org/package/xmonad-contrib-0.16/docs/XMonad-Util-Run.html)
(src: https://hackage.haskell.org/package/xmonad-contrib-0.16/docs/src/XMonad.Util.Run.html#runInTerm)
Is there something I can do to modify manPrompt or runInTerm so that I can specify which workspace the terminal spawned by manPrompt spawns in? Or is there any other way anyone knows of achieving my desired behavior that I do not know about?
EDIT #1
At the suggestion of a recent answer, I am attempting to patch the code for manPrompt to run spawnOn from XMonad.Actions.SpawnOn, rather than runInTerm.
(https://hackage.haskell.org/package/xmonad-contrib-0.13/docs/XMonad-Actions-SpawnOn.html)
Here is what I have right now:
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 "
However, this will not compile, resulting in the error:
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 "
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I assume this issue is with my failure to grasp Haskell datatypes properly, but I do not understand...if the proper way to invoke spawnOn is spawnOn <workspaceId> <command>, how can I pass a String bash command to the function as <command>, like above?
EDIT #2 -- SOLUTION #1
My current solution is to use a custom patch of XMonad.Prompt.Man, with a manPrompt that looks like the following:
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
This compiles and works, I guess, but it seems that the use of spawnOn still results in the same text alignment issues as with doShift when moving the terminal windows between workspaces with different layouts. (I mentioned these in the original post under What I have tried.)
To better explain what I mean by "text alignment issues," I included a screenshot here: https://ibb.co/vxjcKZh
(This screenshot is the result of summoning the prompt on a workspace with a squished layout. I then switched my focus over to the workspace that the manpages got spawned on, which should be full-screen, but you can see, the text does not fill the entire terminal window; this is because the man command ran when the window size was squished.)
有沒有辦法在終端視窗產生后以某種方式重繪 終端視窗中的文本?
uj5u.com熱心網友回復:
調整后的版本runInTerm確實很適合這里。runInTerm 定義為:
unsafeRunInTerm, runInTerm :: String -> String -> X ()
unsafeRunInTerm options command = asks (terminal . config) >>= \t ->
unsafeSpawn $ t " " options " -e " command
runInTerm = unsafeRunInTerm
unsafeSpawn又是spawnfromXMonad.Core的別名。它有一個spawnOn變體,XMonad.Actions.SpawnOn其中WorkspaceId除了要運行的命令之外還需要一個。似乎使用spawnOn定義自定義runInTerm就足以得到你想要的。
在您嘗試編輯時,最后一個引數mkXPrompt應該是一個String -> X ()函式,而不是一個X ()動作。該String引數代表用戶在提示中選擇的完成,在您的情況下,它將是man. 在 的原始實作中manPrompt,String -> X ()函式是:
runInTerm "" . ( ) "man "
或者,以一種可以說更清晰的方式重新表述它:
\completion -> runInTerm "" ("man " completion)
您manPrompt可以相應地調整:
manPromptOn :: XPConfig -> WorkspaceId -> String -> X ()
manPromptOn promptConfig workspaceId terminalArgs = do
mans <- io getMans
mkXPrompt Man promptConfig (manCompl promptConfig mans) $
\completion -> spawnOn workspaceId $
myTerminal " " terminalArgs " -e man " completion
(請注意,我另外將第一個引數更改為mkXPrompt,因為傳遞字串不起作用。我還假設這個函式被添加到模塊的修改副本中,XMonad.Prompt.Man因為構造Man函式和getMans函式都沒有被匯出由模塊的原始版本。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/440938.html
上一篇:如何在Haskell中使用Pandoc的Citeproc處理引文?
下一篇:為什么行和列的索引反轉?
