简体   繁体   English

基于环境变量的 Xmonad 设置布局

[英]Xmonad set layout based on enviornment variable

Suppose I have an env variable IS_REMOTE .假设我有一个环境变量IS_REMOTE I would like to have a set of layouts if it is "1", and another set if it is not, or undefined.如果它是“1”,我想有一组布局,如果不是,或者未定义,则有另一组布局。 So far I have到目前为止我有

import XMonad
import XMonad.Config.Desktop
import XMonad.Hooks.ManageDocks
import XMonad.Layout.LayoutModifier
import XMonad.Layout.MultiColumns
import XMonad.Layout.PerWorkspace
import XMonad.Layout.ThreeColumns
import Data.Maybe
import System.Environment

main = do
  isRemoteEnv <- lookupEnv "IS_REMOTE"
  xmonad $ desktopConfig
    {
      layoutHook = myLayout (fromMaybe "0" isRemoteEnv)
    }

myLayout remote = if remote == "1"
  then onWorkspace "web" (avoidStruts $ (multiCol [1] 1 0.02 (-0.5)) ||| Full) $
       (avoidStruts $ (ThreeColMid 1 0.02 (1/2)) ||| Full)
  else onWorkspace "web" (avoidStruts $ Mirror (multiCol [1] 1 0.02 (-0.5)) ||| Full) $
       (avoidStruts $ Mirror (ThreeColMid 1 0.02 (1/2)) ||| Full)

This does not compile, because (I think) the two branches of if have different types.这不会编译,因为(我认为) if的两个分支具有不同的类型。 But this is at the limit of my Haskell knowledge.但这是我对 Haskell 知识的限制。 What is the correct way to do this?这样做的正确方法是什么?

xmonad.hs:21:8: error:
    * Couldn't match type `Mirror MultiCol' with `MultiCol'
      Expected type: PerWorkspace
                       (ModifiedLayout AvoidStruts (Choose MultiCol Full))
                       (ModifiedLayout AvoidStruts (Choose ThreeCol Full))
                       a
        Actual type: PerWorkspace
                       (ModifiedLayout AvoidStruts (Choose (Mirror MultiCol) Full))
                       (ModifiedLayout AvoidStruts (Choose (Mirror ThreeCol) Full))
                       a
    * In the expression:
        onWorkspace
          "web" (avoidStruts $ Mirror (multiCol [1] 1 0.02 (- 0.5)) ||| Full)
          $ (avoidStruts $ Mirror (ThreeColMid 1 0.02 (1 / 2)) ||| Full)
      In the expression:
        if remote == "1" then
            onWorkspace
              "web" (avoidStruts $ (multiCol [1] 1 0.02 (- 0.5)) ||| Full)
              $ (avoidStruts $ (ThreeColMid 1 0.02 (1 / 2)) ||| Full)
        else
            onWorkspace
              "web" (avoidStruts $ Mirror (multiCol [1] 1 0.02 (- 0.5)) ||| Full)
              $ (avoidStruts $ Mirror (ThreeColMid 1 0.02 (1 / 2)) ||| Full)
      In an equation for `myLayout':
          myLayout remote
            = if remote == "1" then
                  onWorkspace
                    "web" (avoidStruts $ (multiCol [1] 1 0.02 (- 0.5)) ||| Full)
                    $ (avoidStruts $ (ThreeColMid 1 0.02 (1 / 2)) ||| Full)
              else
                  onWorkspace
                    "web" (avoidStruts $ Mirror (multiCol [1] 1 0.02 (- 0.5)) ||| Full)
                    $ (avoidStruts $ Mirror (ThreeColMid 1 0.02 (1 / 2)) ||| Full)
   |
21 |   else onWorkspace "web" (avoidStruts $ Mirror (multiCol [1] 1 0.02 (-0.5)) ||| Full) $
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...

The core problem here comes from Haskell's lack of first-class support for existential or union types.这里的核心问题来自 Haskell 缺乏对存在或联合类型的一流支持。 A much simpler example is that show $ if x then 'a' else "abc" is invalid, even though if x then show 'a' else show "abc" is valid.一个更简单的例子是show $ if x then 'a' else "abc"无效,即使if x then show 'a' else show "abc"是有效的。 Anyway, to solve your problem, this isn't very pretty, but it works:无论如何,为了解决您的问题,这不是很漂亮,但它有效:

import XMonad
import XMonad.Config.Desktop
import XMonad.Hooks.ManageDocks
import XMonad.Layout.LayoutModifier
import XMonad.Layout.MultiColumns
import XMonad.Layout.PerWorkspace
import XMonad.Layout.ThreeColumns
import Data.Kind
import Data.Maybe
import System.Environment

main = do
  isRemoteEnv <- lookupEnv "IS_REMOTE"
  case myLayout (fromMaybe "0" isRemoteEnv) of Layout c -> xmonad $ desktopConfig {
      layoutHook = c
    }

myLayout remote = if remote == "1"
  then Layout $ onWorkspace "web" (avoidStruts $ (multiCol [1] 1 0.02 (-0.5)) ||| Full) $
       (avoidStruts $ (ThreeColMid 1 0.02 (1/2)) ||| Full)
  else Layout $ onWorkspace "web" (avoidStruts $ Mirror (multiCol [1] 1 0.02 (-0.5)) ||| Full) $
       (avoidStruts $ Mirror (ThreeColMid 1 0.02 (1/2)) ||| Full)

It uses the Layout existential type to make both branches be the same type.它使用Layout存在类型使两个分支成为相同的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM