diff --git a/BUILD b/BUILD index f9729f4..af874e6 100644 --- a/BUILD +++ b/BUILD @@ -12,8 +12,8 @@ package(default_visibility = ["//visibility:public"]) # # bazel run -c opt //:buildifier # -load("@com_github_bazelbuild_buildtools//buildifier:def.bzl", "buildifier") +#load("@com_github_bazelbuild_buildtools//buildifier:def.bzl", "buildifier") -buildifier( - name = "buildifier", -) +#buildifier( +# name = "buildifier", +#) diff --git a/WORKSPACE b/WORKSPACE index 6f59836..4895464 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -138,46 +138,46 @@ nixpkgs_python_configure( load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") -http_archive( - name = "io_bazel_rules_go", - sha256 = "f99a9d76e972e0c8f935b2fe6d0d9d778f67c760c6d2400e23fc2e469016e2bd", - urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.21.2/rules_go-v0.21.2.tar.gz", - "https://github.com/bazelbuild/rules_go/releases/download/v0.21.2/rules_go-v0.21.2.tar.gz", - ], -) +#http_archive( +# name = "io_bazel_rules_go", +# sha256 = "f99a9d76e972e0c8f935b2fe6d0d9d778f67c760c6d2400e23fc2e469016e2bd", +# urls = [ +# "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.21.2/rules_go-v0.21.2.tar.gz", +# "https://github.com/bazelbuild/rules_go/releases/download/v0.21.2/rules_go-v0.21.2.tar.gz", +# ], +#) -load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") +#load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") -go_rules_dependencies() +#go_rules_dependencies() -go_register_toolchains() +#go_register_toolchains() -http_archive( - name = "bazel_gazelle", - sha256 = "be9296bfd64882e3c08e3283c58fcb461fa6dd3c171764fcc4cf322f60615a9b", - urls = [ - "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/bazel-gazelle/releases/download/0.18.1/bazel-gazelle-0.18.1.tar.gz", - "https://github.com/bazelbuild/bazel-gazelle/releases/download/0.18.1/bazel-gazelle-0.18.1.tar.gz", - ], -) +#http_archive( +# name = "bazel_gazelle", +# sha256 = "be9296bfd64882e3c08e3283c58fcb461fa6dd3c171764fcc4cf322f60615a9b", +# urls = [ +# "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/bazel-gazelle/releases/download/0.18.1/bazel-gazelle-0.18.1.tar.gz", +# "https://github.com/bazelbuild/bazel-gazelle/releases/download/0.18.1/bazel-gazelle-0.18.1.tar.gz", +# ], +#) -load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") +#load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") -gazelle_dependencies() +#gazelle_dependencies() -http_archive( - name = "com_google_protobuf", - strip_prefix = "protobuf-master", - urls = ["https://github.com/protocolbuffers/protobuf/archive/master.zip"], -) +#http_archive( +# name = "com_google_protobuf", +# strip_prefix = "protobuf-master", +# urls = ["https://github.com/protocolbuffers/protobuf/archive/master.zip"], +#) -load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") +#load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") -protobuf_deps() +#protobuf_deps() -http_archive( - name = "com_github_bazelbuild_buildtools", - strip_prefix = "buildtools-master", - url = "https://github.com/bazelbuild/buildtools/archive/master.zip", -) +#http_archive( +# name = "com_github_bazelbuild_buildtools", +# strip_prefix = "buildtools-master", +# url = "https://github.com/bazelbuild/buildtools/archive/master.zip", +#) diff --git a/ghc.nix b/ghc.nix index 5c2d4b5..b45d0de 100644 --- a/ghc.nix +++ b/ghc.nix @@ -36,5 +36,7 @@ in haskellPackages.ghcWithPackages (p: with p; [ vector xml-conduit xml-types + xmonad + xmonad-contrib # tons of other packages here ]) diff --git a/treetide/thirdparty/haskell/BUILD b/treetide/thirdparty/haskell/BUILD index 01eb244..ec68848 100644 --- a/treetide/thirdparty/haskell/BUILD +++ b/treetide/thirdparty/haskell/BUILD @@ -20,6 +20,8 @@ haskell_toolchain_library(name = "containers") haskell_toolchain_library(name = "deepseq") +haskell_toolchain_library(name = "directory") + haskell_toolchain_library(name = "mtl") haskell_toolchain_library(name = "text") @@ -49,6 +51,9 @@ haskell_toolchain_library(name = "xml-conduit") haskell_toolchain_library(name = "xml-types") +haskell_toolchain_library(name = "xmonad") +haskell_toolchain_library(name = "xmonad-contrib") + # ... # # Tons of stuff here again diff --git a/xmonad/BUILD b/xmonad/BUILD new file mode 100644 index 0000000..89aaf8c --- /dev/null +++ b/xmonad/BUILD @@ -0,0 +1,37 @@ +package(default_visibility = ["//visibility:public"]) + +load( + "@rules_haskell//haskell:defs.bzl", + "haskell_library", + "haskell_test", + "haskell_binary", +) +load( + "//treetide/haskell/build_defs:build.bzl", + "prebuilt", + "extended", +) + +#haskell_library( +# name = "foo", +# srcs = ["foo.hs"], +# deps = [ +# extended("attoparsec"), +# prebuilt("base"), +# prebuilt("text"), +# ], +#) + + +haskell_binary( + name = "xmonad", + srcs = ["xmonad.hs"], + deps = [ + prebuilt("base"), + prebuilt("containers"), + prebuilt("directory"), + prebuilt("xmonad"), + prebuilt("xmonad-contrib"), + ], +) + diff --git a/xmonad/xmonad.hs b/xmonad/xmonad.hs new file mode 100644 index 0000000..8f51fa8 --- /dev/null +++ b/xmonad/xmonad.hs @@ -0,0 +1,314 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE ScopedTypeVariables #-} + +import Control.Exception +import Control.Monad +import qualified Data.Map as M +import Debug.Trace +import System.Directory (XdgDirectory (XdgCache), + getXdgDirectory) +import System.Environment (getArgs) +import System.Exit +import System.IO +--import XMonad (ManageHook, XConfig, X(), Window, Layout, WindowAttributes, Rectangle, startupHook, handleEventHook, logHook, workspaces, terminal) +import XMonad hiding (display, config) +--import XMonad.Actions.CycleRecentWS +import XMonad.Actions.CycleWS (shiftNextScreen, swapNextScreen) +import XMonad.Actions.GridSelect +import XMonad.Actions.SpawnOn +--import XMonad.Actions.UpdatePointer +import XMonad.Actions.Warp (warpToWindow) +--import XMonad.Config +import XMonad.Config.Desktop +import XMonad.Hooks.DynamicBars +import XMonad.Hooks.DynamicLog +import XMonad.Hooks.EwmhDesktops +--import XMonad.Hooks.ManageDocks +import XMonad.Hooks.SetWMName +--import XMonad.Hooks.UrgencyHook +import XMonad.Layout.LayoutModifier --(ModifiedLayout) +import XMonad.Layout.NoBorders (smartBorders) +import XMonad.Layout.Tabbed +import qualified XMonad.StackSet as W +import XMonad.Util.Dmenu +import XMonad.Util.EZConfig +--import XMonad.Util.NamedWindows (NamedWindow, getName) +import XMonad.Util.Run (spawnPipe) +--import XMonad.Util.Themes +import XMonad.Util.XUtils (fi) + +myNormalBorderColor :: String +myNormalBorderColor = "#7a7a7a" + +myFocusedBorderColor :: String +myFocusedBorderColor = "cadetblue3" + +colYellow :: String +colYellow = "#b58900" + +-- myTabConfig = def { inactiveBorderColor = "#4c7899" +-- --, inactiveColor = +-- , urgentColor = "#a13310" +-- , activeBorderColor = "#285577" +-- , inactiveTextColor = "#ffffff" +-- --, urgentTextColor = "" +-- --, urgentBorderColor = "" +-- , activeTextColor = "#000000" +-- , fontName = "xft:RobotoMono Nerd Font:size=11:antialias=true" +-- } + +--toggleStrutsKey :: XConfig t -> (KeyMask, KeySym) +--toggleStrutsKey XConfig{modMask = modm} = (modm, xK_b ) + +myXmobarPP :: PP +myXmobarPP = def { ppCurrent = xmobarColor "yellow" "" . wrap "[" "]" + , ppTitle = xmobarColor "green" "" . shorten 40 + , ppSep = " " + , ppLayout = const "" + , ppVisible = wrap "(" ")" + , ppUrgent = xmobarColor "red" "yellow" + } + +-- myXmobar XConfig conf => conf +--myXmobar :: LayoutClass l Window => XConfig l -> IO (XConfig (ModifiedLayout AvoidStruts l)) +--myXmobar conf = statusBar "xmobar" myXmobarPP toggleStrutsKey conf + +-- don't forget to set _JAVA_AWT_WM_NONREPARENTING=1 as per +-- and https://wiki.archlinux.org/index.php/Java#Applications_not_resizing_with_WM.2C_menus_immediately_closing + +main :: IO () +main = do + args <- getArgs + appendFile "/tmp/xmonad.log" $ show args + xmonad $ myConfig $ traceShowId args + +-- getName :: Window -> X NamedWindow + +myTheme :: Theme +myTheme = def { + fontName = "xft:RobotoMono Nerd Font:size=10:antialias=true" + , decoHeight = 20 + , activeColor = "#545d75" + , activeBorderColor = "grey" + , activeTextColor = "white" + , inactiveColor = "#30343d" + , inactiveBorderColor = "darkgrey" + , inactiveTextColor = "#646464" + } + -- kavonBluesTheme + -- kavonLakeTheme + -- donaldTheme + +myLogHook :: X () +myLogHook = do + focused <- gets (W.peek . windowset) + -- XMonad.trace $ show focused + -- x <- catchIO $ updateEnv $ whenJust focused getName + whenJust focused (\w -> updateFo w) -- warpToWindow 0.3 0.3 >> + where + updateFo :: Window -> X() + updateFo w = do + -- wname <- getName w + s <- withDisplay $ \d -> fmap resClass $ liftIO $ getClassHint d w + catchIO $ updateEnv $ app s + where + app :: String -> Maybe String + app "Emacs" = Just "emacs" + app "jetbrains-idea" = Just "intellij" + app _ = Nothing + updateEnv :: Maybe String -> IO () + updateEnv name = do + focusFile <- getXdgDirectory XdgCache "focus" + maybe (return ()) (\n -> writeFile focusFile $ "TERMLINK_APP=" ++ n ++ "\n") name + +debugInfo :: X () +debugInfo = withDisplay showInfo + where showInfo display = do + ws <- gets windowset + let window = W.peek ws + let defaultRect = screenRect $ W.screenDetail $ W.current ws + rect <- case window of + Nothing -> return defaultRect + Just w -> do tryAttributes <- io $ try $ getWindowAttributes display w + return $ case tryAttributes of + Left (_ :: SomeException) -> defaultRect + Right attributes -> windowAttributesToRectangle attributes + root <- asks theRoot + _mouseIsMoving <- asks mouseFocused + --(_sameRoot,_,currentWindow,rootX,rootY,_,_,_) <- io $ queryPointer display root + (_sameRoot,_,_currentWindow,_rootX,_rootY,_,_,_) <- io $ queryPointer display root + whenJust window (\_ -> warpToWindow 0.5 0.5) + -- io $ warpPointer display none root 0 0 0 0 + io $ writeFile "/tmp/debugInfo" $ (show rect) ++ " --- " ++ (show root) + +windowAttributesToRectangle :: WindowAttributes -> Rectangle +windowAttributesToRectangle wa = Rectangle (fi (wa_x wa)) + (fi (wa_y wa)) + (fi (wa_width wa + 2 * wa_border_width wa)) + (fi (wa_height wa + 2 * wa_border_width wa)) + +confirm :: String -> X () -> X () +confirm msg f = do + a <- menuArgs "dmenu" ["-p", msg] ["y", "n"] + when (a=="y") f + +-- Debug.Trace.trace "adsf" () + +myStatusBars :: XConfig l -> XConfig l +myStatusBars conf = conf + { startupHook = startupHook conf >> dynStatusBarStartup myStatusBar (return ()) + , handleEventHook = handleEventHook conf <+> dynStatusBarEventHook myStatusBar (return ()) + , logHook = logHook conf >> multiPP myXmobarPP unfocusedPP + } + +myStatusBar :: ScreenId -> IO Handle +myStatusBar (S n) = spawnPipe $ "xmobar -o -x " <> show n + +unfocusedPP :: PP +unfocusedPP = myXmobarPP + { ppCurrent = xmobarColor colYellow "" + } + +-- focusedPP :: PP +-- focusedPP = def +-- { ppCurrent = xmobarColor colOrange "" +-- , ppHidden = xmobarColor colBase1 "" . take 5 +-- , ppVisible = xmobarColor colGreen "" +-- , ppHiddenNoWindows = xmobarColor colBase01 "" . take 5 +-- , ppUrgent = xmobarColor colRed "" +-- , ppSep = colSep " : " +-- , ppTitle = xmobarColor colBase00 "" . shorten 30 +-- , ppLayout = unwords . map smartSplit . words +-- , ppWsSep = "\0" -- changed by lastDecor +-- , ppOrder = \(x:xs) -> lastDecor x : xs +-- , ppSort = (namedScratchpadFilterOutWorkspace .) `liftM` DW.getSortByOrder +-- , ppExtras = [ wrapL (colSep "<") (colSep ">") $ ppWinCopies `fmap` wsContainingCopies ] +-- } where +-- -- This does some extra formatting, very last, to ws list (adds ws keys) +-- lastDecor = L.intercalate " " +-- . zipWith (\k ys -> k ++ dropWhile (== '\0') ys) wsKeys' +-- . L.groupBy (const (/= '\0')) + +-- wsKeys' = map (xmobarColor colYellow "" . reverse . L.delete ' ') wsKeys +-- ++ repeat "N/A" + +-- ppWinCopies [] = Nothing +-- ppWinCopies xs = Just $ xmobarColor "white" "" $ L.intercalate ", " xs + +-- colSep = xmobarColor colBase01 "" + +myConfig :: [String] -> XConfig (XMonad.Layout.LayoutModifier.ModifiedLayout + XMonad.Hooks.ManageDocks.AvoidStruts + (Choose + (XMonad.Layout.LayoutModifier.ModifiedLayout + (XMonad.Layout.Decoration.Decoration + TabbedDecoration XMonad.Layout.Decoration.DefaultShrinker) + XMonad.Layout.Simplest.Simplest) + (XMonad.Layout.LayoutModifier.ModifiedLayout + XMonad.Layout.NoBorders.SmartBorder Full))) +myConfig args = + myStatusBars $ initialConfig `additionalKeysP` prettyKeys `plusKeys` keys' + where + initialConfig = desktopConfig { + terminal = "termite" + , normalBorderColor = myNormalBorderColor + , focusedBorderColor = myFocusedBorderColor + -- hyper (super is mod4Mask) + , modMask = mod4Mask + , workspaces = myWorkspaces + , startupHook = startup (null args) + , logHook = myLogHook <+> logHook desktopConfig + , handleEventHook = fullscreenEventHook <+> handleEventHook desktopConfig + , layoutHook = desktopLayoutModifiers $ tabbed shrinkText myTheme ||| smartBorders Full + , manageHook = manageSpawn <+> manageHook' + } + plusKeys config keyMap = additionalKeys config $ keyMap config + prettyKeys = [ + ("M-S-q", confirm "Really exit?" $ io (exitWith ExitSuccess)) -- %! Quit xmonad + , ("M-", windows W.shiftMaster) + , ("M-", windows W.focusUp) + , ("M-", windows W.focusDown) + , ("M-S-", windows W.swapUp) + , ("M-S-", windows W.swapDown) + , ("M-f", withFocused float) + , ("M-S-r", spawn "xmonad --recompile && xmonad --restart") -- %! Restart xmonad + , ("", spawn "screenshot") + , ("M-h", debugInfo) + , ("M1-C-", spawn "xscreensaver-command -lock") + , ("", spawn "display-auto") + , ("", spawn "pactl -- set-source-mute @DEFAULT_SOURCE@ toggle") + , ("", spawn "pactl -- set-sink-mute @DEFAULT_SINK@ toggle") + , ("", spawn "pactl -- set-sink-volume @DEFAULT_SINK@ +5%") + , ("", spawn "pactl -- set-sink-volume @DEFAULT_SINK@ -5%") + ] + keys' XConfig { modMask = modMask } = + [((m .|. modMask, k), windows $ f i) + | (i, k) <- zip myWorkspaces [xK_1 .. xK_9] + , (f, m) <- [(W.view, 0), (\ws -> (W.view ws) . (W.shift ws), shiftMask)]] + + +startup :: Bool -> X () +startup _initial = do + setWMName "LG3D" + when False $ do + spawnOn (myWorkspaces !! 0) "termite" +-- spawnOn "3" "emacs" + spawnOn (myWorkspaces !! 1) "firefox" +-- spawnOn "4" "spotify" + +manageHook' :: ManageHook +manageHook' = composeAll + [ className =? "Xmessage" --> doFloat + , className =? "Gimp" --> doFloat + , className =? "Inkscape" --> doFloat + , className =? "zoom" --> doFloat + , className =? "xpad" --> doFloat + , title =? "Downloads" --> doFloat + , title =? "Save As..." --> doFloat + , title =? "Open" --> doFloat + ] + +keys' :: XConfig Layout -> M.Map (KeyMask, KeySym) (X ()) +keys' conf@(XConfig {XMonad.modMask = modMask}) = M.fromList $ + [ + -- https://hackage.haskell.org/package/X11-1.6.1.1/docs/Graphics-X11-Types.html + -- https://hackage.haskell.org/package/X11-1.6.1.1/docs/Graphics-X11-ExtraTypes.html + -- some defaults copied from http://code.haskell.org/xmonad/XMonad/Config.hs + ((modMask, xK_Return), spawnHere $ XMonad.terminal conf) -- %! Launch terminal + , ((modMask, xK_p ), spawn "dmenu_run") -- %! Launch dmenu + , ((modMask, xK_c ), kill) -- %! Close the focused window + , ((modMask, xK_space ), windows W.swapMaster) -- %! Set the focused window as master + --, ((modMask, xK_Tab ), windows W.focusDown) -- %! Move focus to the next window + --, ((modMask .|. shiftMask, xK_Tab), windows W.focusUp) -- %! Move focus to the next window + --, ((modMask, xK_Left ), windows W.focusLeft) -- %! Move focus to the next window + --, ((modMask, xK_Right ), windows W.focusRight) -- %! Move focus to the next window + , ((modMask, xK_Up ), windows W.focusUp) -- %! Move focus to the next window + , ((modMask, xK_Down ), windows W.focusDown) -- %! Move focus to the next window + , ((modMask, xK_minus ), sendMessage Shrink) -- %! Shrink the master area + , ((modMask, xK_equal ), sendMessage Expand) -- %! Expand the master area + , ((modMask, xK_t ), withFocused $ windows . W.sink) -- %! Push window back into tiling + , ((modMask, xK_g ), goToSelected def) + , ((modMask .|. shiftMask, xK_q), io (exitWith ExitSuccess)) -- %! Quit xmonad + , ((modMask .|. shiftMask, xK_o), shiftNextScreen) + , ((modMask .|. mod1Mask, xK_o), swapNextScreen) + ] + ++ + -- workspaces + [((m .|. modMask, k), windows $ f i) + | (i, k) <- zip (XMonad.workspaces conf) [xK_1 .. xK_9] + , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]] + ++ + -- mod-[',.] %! Switch to physical/Xinerama screens 1, 2, or 3 + -- mod-shift-[',.] %! Move client to screen 1, 2, or 3 + [((m .|. modMask, key), screenWorkspace sc >>= flip whenJust (windows . f)) + | (key, sc) <- zip [xK_quoteright, xK_comma, xK_period] [0..] + , (f, m) <- [(W.view, 0), (W.shift, shiftMask)]] + + ++ + -- my custom additions + [ + ((modMask, xK_l), spawn "i3lock -c000000") + ] + +myWorkspaces :: [String] +myWorkspaces = ["1:term","2:web","3:code","4:vm","5:media"] ++ map show [6..9]