Re: [Xmonad] xmonad-utils: small x apps for xmonad

On 0, Andrea Rossato
On Wed, Aug 22, 2007 at 10:02:40AM -0400, Gwern Branwen wrote:
Hey: would it be possible to have a version of hxsel which is a function you could call in Xmonad's Config.hs?
well, you've got that version: it's just the code below...;-)
I didn't test it but it looks fine to me.
else do destroyWindow dpy win >> return "" -- Is destroyWindow really needed?
yes, as far as I remember, otherwise we leak memory.
Ah, I suspected as much - I would've been surprised if you could create windows and not have to manually free them.
You can send it as a contrib module if you feel like.
Generally speaking I prefer to keep this stuff outside XMonad: less memory, less code, less bugs, but this is a matter of personal taste I think.
Cheers,
Andrea
Well, my reasoning is that given that Xmonad is already linking in so much X-related stuff, that calling the shell to call another program (with all the overhead involved in those indirections and standalone binaries,, like the 500KB RTS system GHC inserts) is less of a win than just putting in some stripped down code. Plus, shells are often sources of problems, and it's tidier to have all the logic in one place. Anyway, I don't think I'll send in a contrib module just yet. hxsel should probably be factored out into two functions, a main that prints stuff to stdout and the actual selection-fetching code; that way it doesn't have to be duplicated. Further, I'm having problems integrating it into Config.hs: I finally got it to compile like this: , ((modMask .|. shiftMask, xK_g ), spawn $ "google" ++ unsafePerformIO(getSelection)) But notice I used unsafePerformIO. The reason is that if you try to simply concatenate "google" and getSelection, there's a type mismatch. You can then try using liftM to do it, like ("google"++) `liftM` getSelection, and that will work well. Unfortunately, spawn :: String -> X (), so spawn needs to be lifted. (The internal /bin/sh stuff apparently requires a String too, so it's not spawn's fault.) But if you go 'spawn (("google"++) `liftM` getSelection' - which on its own would work - the resulting type is something like IO ( X ()). And that just can't be allowed inside 'keys'. At least, the only solution I could find was to just slice the Gordian knot and avoid introducing the IO signature in the first place. Monads may be the greatest thing since sliced bread, but most of the time they're just a pain :( -- gwern extraction Iris MITM Fortezza FBIS Chelsea Love Coderpunks 64 stakeout

On Wed, Aug 22, 2007 at 12:09:21PM -0400, Gwern Branwen wrote:
, ((modMask .|. shiftMask, xK_g ), spawn $ "google" ++ unsafePerformIO(getSelection))
But notice I used unsafePerformIO. The reason is that if you try to simply concatenate "google" and getSelection, there's a type mismatch. You can then try using liftM to do it, like ("google"++) `liftM` getSelection, and that will work well. Unfortunately, spawn :: String -> X (), so spawn needs to be lifted. (The internal /bin/sh stuff apparently requires a String too, so it's not spawn's fault.) But if you go 'spawn (("google"++) `liftM` getSelection' - which on its own would work - the resulting type is something like IO ( X ()). And that just can't be allowed inside 'keys'. At least, the only solution I could find was to just slice the Gordian knot and avoid introducing the IO signature in the first place. Monads may be the greatest thing since sliced bread, but most of the time they're just a pain :(
It's a lot easier if you use the 'io' function, type forall a. IO a -> X a : spawn . ("google " ++) =<< io getSelection Stefan

On 0, Stefan O'Rear
On Wed, Aug 22, 2007 at 12:09:21PM -0400, Gwern Branwen wrote:
, ((modMask .|. shiftMask, xK_g ), spawn $ "google" ++ unsafePerformIO(getSelection))
But notice I used unsafePerformIO. The reason is that if you try to simply concatenate "google" and getSelection, there's a type mismatch. You can then try using liftM to do it, like ("google"++) `liftM` getSelection, and that will work well. Unfortunately, spawn :: String -> X (), so spawn needs to be lifted. (The internal /bin/sh stuff apparently requires a String too, so it's not spawn's fault.) But if you go 'spawn (("google"++) `liftM` getSelection' - which on its own would work - the resulting type is something like IO ( X ()). And that just can't be allowed inside 'keys'. At least, the only solution I could find was to just slice the Gordian knot and avoid introducing the IO signature in the first place. Monads may be the greatest thing since sliced bread, but most of the time they're just a pain :(
It's a lot easier if you use the 'io' function, type forall a. IO a -> X a :
spawn . ("google " ++) =<< io getSelection
Stefan
And as usual the experts chime in with 'Oh, that's easy!' :) Yes, that works well. I didn't realize it was possible to convert an X () to an IO () (which is what io is doing, if I understand correctly). Still don't quite understand the use of bind and composition, but it works, and obviates the need for xclip! Subjectively, it's also faster. -- gwern "genie" MEU/SOCPSAC Iraq NASA Bunny Amherst Egret Meade import Kvashnin

On Wed, Aug 22, 2007 at 10:36:43PM -0400, Gwern Branwen wrote:
On 0, Stefan O'Rear
scribbled: On Wed, Aug 22, 2007 at 12:09:21PM -0400, Gwern Branwen wrote:
, ((modMask .|. shiftMask, xK_g ), spawn $ "google" ++ unsafePerformIO(getSelection))
But notice I used unsafePerformIO. The reason is that if you try to simply concatenate "google" and getSelection, there's a type mismatch. You can then try using liftM to do it, like ("google"++) `liftM` getSelection, and that will work well. Unfortunately, spawn :: String -> X (), so spawn needs to be lifted. (The internal /bin/sh stuff apparently requires a String too, so it's not spawn's fault.) But if you go 'spawn (("google"++) `liftM` getSelection' - which on its own would work - the resulting type is something like IO ( X ()). And that just can't be allowed inside 'keys'. At least, the only solution I could find was to just slice the Gordian knot and avoid introducing the IO signature in the first place. Monads may be the greatest thing since sliced bread, but most of the time they're just a pain :(
It's a lot easier if you use the 'io' function, type forall a. IO a -> X a :
spawn . ("google " ++) =<< io getSelection
Stefan
And as usual the experts chime in with 'Oh, that's easy!' :)
Yes, that works well. I didn't realize it was possible to convert an X () to an IO () (which is what io is doing, if I understand correctly). Still don't quite understand the use of bind and composition, but it works, and obviates the need for xclip! Subjectively, it's also faster.
I'd say that io converts IO () to X (). It's easier to read (I'd say) in the notation: do selection <- io getSelection spawn ("google " ++ selection) -- David Roundy http://www.darcs.net

On Wednesday 22 August 2007 11:09:21 Gwern Branwen wrote:
Anyway, I don't think I'll send in a contrib module just yet. hxsel should probably be factored out into two functions, a main that prints stuff to stdout and the actual selection-fetching code; that way it doesn't have to be duplicated. Further, I'm having problems integrating it into Config.hs: I finally got it to compile like this: , ((modMask .|. shiftMask, xK_g ), spawn $ "google" ++ unsafePerformIO(getSelection))
Yikes! :) Here's one way to do it: do sel <- getSelection; spawn ("google" ++ sel) Pointfree: spawn ("google" ++) =<< getSelection Cheers, Spencer Janssen
participants (4)
-
David Roundy
-
Gwern Branwen
-
Spencer Janssen
-
Stefan O'Rear