haskell Xmonad:如何将窗口属性与列表进行比较,而不仅仅是与单个字符串进行比较

siv3szwd  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(111)

在钩子、键绑定等等中,人们可以将窗口属性与字符串进行比较,但我也希望能够将窗口属性与列表进行比较。
我的具体用例,使用XMonad.Actions.PerWindowKeys,是一个简化的形式,除了类似这样的东西,它工作得很好(如果焦点窗口是xterm,则打开termite,否则杀死焦点窗口):

, ((modMask, xK_e), bindFirst [(className =? "xterm", spawn "termite") , (pure True, kill)])

我希望能够做一些大致如下的事情(如果聚焦窗口是st或xterm,则打开termite,否则杀死聚焦窗口--这不起作用:

, ((modMask, xK_e), bindFirst [(className =? ["st", "xterm"], spawn "termite") , (pure True, kill)])

className检查失败,并显示:

Couldn't match type ‘[Char]’ with ‘Char’
      Expected type: String
        Actual type: [[Char]]

我最初认为这将是很容易解决(它可能是...),但作为一个Haskell菜鸟,我已经花了几个小时,它已经没有成功。
=?似乎真的只需要一个字符串,我找不到一种方法来修改参数,使其接受它们,即使从contrib中广泛咨询了源代码。我也无法在contrib中找到任何替代函数,以我的理解,它能满足我的需要。
我的一个想法是引入elem函数来检查数组中是否有任何元素与类名匹配,但这失败了,因为elem返回“正常”的布尔值,而=?似乎可以处理特定的查询布尔值,而且我无法找到任何方法将这些布尔值合并到一个函数中。

rxztt3cl

rxztt3cl1#

以下是您可以执行此操作的方法:

, ((modMask, xK_e), bindFirst [(className =? "st" <||> className =? "xterm", spawn "termite") , (pure True, kill)])

为避免重复,您可以定义一个执行多重比较的自定义运算符:

(=??) :: Eq a => Query a -> [a] -> Query Bool
q =?? [] = pure False
q =?? (x:xs) = q =? x <||> (q =?? xs)

那么你可以这样使用它:

, ((modMask, xK_e), bindFirst [(className =?? ["st", "xterm"], spawn "termite") , (pure True, kill)])

相关问题