xmonad

Don´t be shy, Linux is fun! =)
Post Reply
User avatar
leetnigga
Fame ! Where are the chicks?!
Fame ! Where are the chicks?!
Posts: 447
Joined: 28 Jul 2009, 16:00
14

xmonad

Post by leetnigga »

I've started using the xmonad window manager.

It's really nice and fast and it's written in Haskell which is one of my favorite languages.

Here's my xmodmap.hs:

Code: Select all

import XMonad
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.ManageDocks
import XMonad.Util.Run
import XMonad.Util.EZConfig(additionalKeys)
import XMonad.Prompt
import XMonad.Prompt.Input
import XMonad.Actions.WindowGo
import XMonad.Layout.NoBorders
import System.IO

fPrintScreen :: String -> X ()
fPrintScreen file = spawn $ "scrot " ++ file

printScreen :: X ()
printScreen = inputPrompt defaultXPConfig "Print screen to file" ?+ fPrintScreen

myTerminal = "urxvt"

main = do
  xmobar <- spawnPipe "xmobar"
  xmonad $ defaultConfig {
               manageHook = manageHook defaultConfig <+>
                            composeAll
                            [ className =? "Conkeror" --> doShift "internet",
                              manageDocks
                            ],
               layoutHook = noBorders $ avoidStruts $ layoutHook defaultConfig,
               logHook = dynamicLogWithPP $ xmobarPP
               {
                 ppOutput = hPutStrLn xmobar,
                 ppTitle = xmobarColor "white" "" . shorten 50,
                 ppCurrent = xmobarColor "orange" "" . wrap "[" "]",
                 ppHiddenNoWindows = xmobarColor "white" "" . wrap "(" ")",
                 ppHidden = xmobarColor "white" "" . wrap "(" ")",
                 ppUrgent = xmobarColor "red" ""
               },
               modMask = mod4Mask,
               terminal = myTerminal,
               workspaces = ["emacs", "internet", "irc", "msn"]
             } `additionalKeys`
             [ ((mod4Mask .|. shiftMask, xK_l), spawn
                "xlock -username \"Username: \" -validate \"Checking credentials...\" -invalid \"Access denied.\" +showdate +description -mode matrix -info \"\""),
               ((0, xK_Print), printScreen),
               ((mod4Mask, xK_f), (runOrRaise "conkeror" (className =? "Conkeror"))),
               ((mod4Mask, xK_e), (runOrRaise "emacs" (className =? "Emacs"))),
               ((mod4Mask, xK_c), spawn myTerminal)
             ]
and my .xmobarrc:

Code: Select all

Config { font = "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"
       , bgColor = "black"
       , fgColor = "grey"
       , position = TopW L 90
       , lowerOnStart = True
       , commands = [ Run Weather "EHGG" ["-t","<station>: <tempC>°C","-L","18","-H","25","--normal","green","--high","red","--low","lightblue"] 36000
                    , Run Com "uname" ["-s","-r","-m"] "" 36000
    		    , Run Date "%a %b %_d %Y %H:%M:%S" "date" 10
		    , Run StdinReader
                    ]
       , sepChar = "%"
       , alignSep = "}{"
       , template = "%StdinReader% }{ <fc=#ee9a00>%date%</fc> | %EHGG% | %uname%"
       }
Here's a screenshot:

Image

Notice how I added print screen functionality just like this:

Code: Select all

fPrintScreen :: String -> X ()
fPrintScreen file = spawn $ "scrot " ++ file

printScreen :: X ()
printScreen = inputPrompt defaultXPConfig "Print screen to file" ?+ fPrintScreen

...
((0, xK_Print), printScreen),
...
When I press the Print Screen button an input prompt is shown, allowing me to enter a file name after which a scrot (screenshot program) process is spawned that is passed my input file name as its argument. This same method could be used to write interfaces to all kinds of command line programs.
Last edited by leetnigga on 29 Oct 2009, 07:39, edited 1 time in total.

MariaLara
suck-o-fied!
suck-o-fied!
Posts: 99
Joined: 27 Feb 2008, 17:00
16
Contact:

Post by MariaLara »

=D> me likey
The only true wisdom is in knowing you know nothing.

User avatar
bad_brain
Site Owner
Site Owner
Posts: 11636
Joined: 06 Apr 2005, 16:00
18
Location: In your eye floaters.
Contact:

Post by bad_brain »

yeah, real nice man! :D
I like the syntax, definitely easier and more effective than beating your brain with sed and awk (in the example you've shown)... :-k

User avatar
leetnigga
Fame ! Where are the chicks?!
Fame ! Where are the chicks?!
Posts: 447
Joined: 28 Jul 2009, 16:00
14

Post by leetnigga »

I'm glad you guys like it too :)

I'm very happy with it.
bad_brain wrote:I like the syntax, definitely easier and more effective than beating your brain with sed and awk (in the example you've shown)... :-k
I'm not sure what you mean by that, but I did come by a nice example of use of parsers instead of things like sed and awk when I was looking at the xmobar code. I had to patch it for FreeBSD. FreeBSD has a linux-like procfs but it's mounted at /compat/linux/proc on my system, and the path /proc was hardcoded in xmobar. Also there was a difference between FreeBSD's /compat/linux/proc/meminfo that required a change in the code. I'll probably submit that patch later today.

xmobar has plugins, and some of them are so called monitors which parse some kind of statistic like the current CPU usage, usually using the /proc pseudo filesystem.

Code: Select all

cpuParser :: B.ByteString -> [Float]
cpuParser =
    map read . map B.unpack . tail . B.words . flip (!!) 0 . B.lines
This parses input like:

Code: Select all

cpu 5270248 60671 1844145 31421782
cpu0 2274902 25882 868254 16101763
cpu1 2995346 34788 975890 15320019
disk 0 0 0 0
page 0 0
swap 0 0
intr 0
ctxt 0
btime 1256304004
(/proc/stat)
I thought the code was quite elegant. It's a composition of functions using the (.) operator.

Code: Select all

map read . map B.unpack . tail . B.words . flip (!!) 0 . B.lines
Here's how it works:

Code: Select all

B.lines
turns the above /proc/stat output into a list of lines

Code: Select all

flip (!!) 0
flips the arguments of the (!!) function. (!!) usually works like this:

Code: Select all

["aye","bee","see"] !! 0
In this cased it's used infix, which is equivalent to the following prefix notation:

Code: Select all

(!!) ["aye","bee","see"] 0
So the flip in our original code lets us use (!!) this way:

Code: Select all

flip (!!) 0 ["aye","bee","see"]
!! is used to access list elements by their indices, so all of the above would result in "aye" (list element at index 0). Moving on:
So what happened is we took the output of /proc/stat, split them up into lines and then took the first line, which is this:

Code: Select all

cpu 5270248 60671 1844145 31421782
Now for the rest of the code:

Code: Select all

B.words
This splits the above up into words, just like lines did with lines. So we have the list:

Code: Select all

["cpu","5270248","60671","1844145","31421782"]
Now:

Code: Select all

tail
This takes the tail or the rest of the list, so excluding the head:

Code: Select all

["5270248","60671","1844145","31421782"]
Continuing:

Code: Select all

map B.unpack
The unpack function is mapped over the list above to unpack all those bytestrings into regular strings:

Code: Select all

["5270248","60671","1844145","31421782"]
And finally:

Code: Select all

map read
read is mapped over the list to turn all those into floats:

Code: Select all

[5270248.0,60671.0,1844145.0,31421782.0]
I think that's some very nice code. And fast too, after being optimized by the compiler.

Here are some more nice examples of Haskell code: Blow your mind.

User avatar
lilrofl
Siliconoclast
Siliconoclast
Posts: 1363
Joined: 28 Jan 2009, 17:00
15
Location: California, USA
Contact:

Post by lilrofl »

Off topic:

there should be an emoticon for 'Way Over lilrofls' Head'

Back to topic:

I'm sure this is fascinating... um... lemme hit up that google thing...

Post Reply