xmonadにstackを使う
xmonad、デフォルトだと新しい機能を自作したりしようとするとシステムグローバルに突っ込む必要が出てきます。 それは面倒だし、管理が煩雑になるのでそもそもstackを使用できるようにします。
Xmonadをstackでコンパイルできるようにする
Xmonadのコンパイル方法を指定する方法
xmonadの recompileは、
XMonad.Core.recompile
によって行われています。 そして内部を読んでみると、 cfgdir </> "build"
が存在すればそれを読むということが分かります。
recompile :: MonadIO m => Bool -> m Bool
recompile force = io $ do
    cfgdir  <- getXMonadDir
    datadir <- getXMonadDataDir
    let binn = "xmonad-"++arch++"-"++os
        bin  = datadir </> binn
        err  = datadir </> "xmonad.errors"
        src  = cfgdir </> "xmonad.hs"
        lib  = cfgdir </> "lib"
        buildscript = cfgdir </> "build"
    -- ...
    useBuildscript <- do
      exists <- doesFileExist buildscript
      if exists
        then do
          isExe <- isExecutable buildscript
          if isExe
            then do
              trace $ "XMonad will use build script at " ++ show buildscript ++ " to recompile."
              return True
            else do
cfgdir は
- $XMONAD_CONFIG_DIR
- ~/.xmonad
- $XDG_CONFIG_HOME/xmonad
のいずれかになります。
今回は、変更点をあまり作らないためにとりあえず ~/.xmonad
にしようと思います(そのうち XDG_CONFIG_HOME 以下に移したい)
build スクリプトを書く
コマンドを使用することになるので、shellscriptで書くのが妥当かなと思います。
build スクリプトは以下のように呼ばれます。
-- ...
then do
  -- temporarily disable SIGCHLD ignoring:
  uninstallSignalHandlers
  status <- bracket (openFile err WriteMode) hClose $ \errHandle ->
  waitForProcess =<< if useBuildscript
             then compileScript bin cfgdir buildscript errHandle
             else compileGHC bin cfgdir errHandle
compileScript bin dir script errHandle =
        runProcess script [bin] (Just dir) Nothing Nothing Nothing (Just errHandle)
runProcess は、
System.Process.runProcess
であり、上記の使い方だと script というプログラムに bin
を引数として与え、 dir
をワーキングディレクトリとしてから実行することになります。