Pimp Your XMonad #3: Prompt

This is a big post that I’ve been putting off for a long time. There are a lot of awesome modules in the XMonad.Prompt.* family, and so there’s a lot to cover here.

XMonad.Prompt itself defines a library for displaying prompts to the user, with autocompletion and customizable look and feel. This module is a back-end library, not intended for use in configurations. What follows is a description and use cases for what I consider the most important modules in the Prompt family, a breakdown of how to customize the look and feel, and a quick rundown of the remaining Prompt modules as of 0.8.

Binding a Prompt action to a key
Nearly all Prompt actions are performed using key bindings. You can bind them to whichever keys you wish, and they all take the same basic form. First, you need to import the relevant module, for example

import XMonad.Prompt.Shell

Second, you need to create a keybinding to call a function from it

( modMask conf .|. xK_s, shellPrompt myXPConfig )

or using XMonad.Util.EZConfig (which will be the subject of a future PYXM)

("M-s", shellPrompt myXPConfig)

The myXPConfig argument is how you customize the look and feel of the prompts. See the section called “Look and Feel Customization” below on how to do this.

Running Commands and Launching Applications: Shell, RunOrRaise, DirExec
One obvious application of Prompt is using it to run shell commands and launch applications. XMonad.Prompt.Shell.shellPrompt works similarly to dmenu, though it allows command-line arguments to be provided as well, and more complete look-and-feel customization.

XMonad.Prompt.RunOrRaise.runOrRaisePrompt uses the XMonad.Actions.RunOrRaise functionality to prompt for an application, launch it if it isn’t running, and summon it if it is.

XMonad.Prompt.DirExec.dirExecPrompt can be used when you want to run programs from a directory not necessarily in your path.

Navigating by Window Titles: Window
XMonad.Prompt.Window‘s windowPromptGoto and windowPromptBring functions present an autocompleting list of window titles for all the windows in your session, and either take you to the window you name, or bring it to your location. This can be very helpful both for tracking down windows you’ve misplaced, and for bringing remote windows here without going to find them.

Minimally Disruptive Note-Taking: AppendFile
XMonad.Prompt.AppendFile is my personal favourite find from my research for this article. That might not be fair to Shell and Window, I knew they were there so they weren’t “finds”. What AppendFile does is prompt you for one line of text, which it then appends to a file named in your xmonad.hs. The intended purpose (there are probably others) is to be able to jot down quick notes by hitting a key binding and typing one line, without disrupting whatever other task you were doing.

Arbitrary XMonad Actions: XMonad
XMonad.Prompt.XMonad can be viewed as an extension of your key bindings. It displays an autocompleting list of actions, each action bound to an arbitrary X (), like a key binding. You can use the provided default bindings using xmonadPrompt (which seem to correspond to roughly the same actions as the default key bindings) or create your own list of (name,action) pairs with xmonadPromptC.

Look and Feel Customization: XPConfig
The XPConfig data type is defined in XMonad.Prompt, and it defines the various colours and other parameters that determine the appearance, position, font, size and behaviour of the Prompt box. Following is a rundown of the parameters and what they control.

  • font — a String naming a font in the X format, eg. "-*-terminus-*-*-*-*-16-*-*-*-*-*-*-*" (default: "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*")
  • fgColor,bgColorStrings in "#rrggbb" format, defining the fore- and background colours. (defaults: "#333333" and "#FFFFFF")
  • fgHLight,bgHLightStrings as above, defining the highlight colour for a completion entry. (defaults: "#000000" and "#BBBBBB")
  • borderColor — a String as above, defining the border colour. (default: "#FFFFFF")
  • promptBorderWidth — the border width in pixels. (default: 1)
  • position — either Top or Bottom, the constructors of the XPPosition data type. (default: Bottom)
  • height — the height of the Prompt bar in pixels (make sure it’s large enough for your font!) (default: 18)
  • historySize — the number of history entries to save. (default: 256)
  • defaultText — a String defining the text initially in the Prompt box when it opens. (default: "")
  • autoComplete — a Maybe Int that controls the autocompletion behaviour. If Nothing, you must press Enter to select the entry. If Just x, it will select a unique entry after x microseconds. For example, Just 1000000 would wait 1 full second. (default: Nothing)

Remaining modules
These modules are well worth mentioning but are straightforward enough to just list quickly:

  • Workspace — takes a String -> X () function and gives it the name of the workspace you specify in the prompt. Could be used to focus the named workspace, bring all the windows on it to the current workspace, or any other action.
  • Ssh — given a host name in the prompt, creates an SSH session in a terminal.
  • Man — displays the man page for the subject you provide in the prompt.
  • AppLauncher — functionality similar to dmenu.

Conclusion
The XMonad.Prompt.* family is a prime example of the awesome functionality just waiting to be discovered. Depending on how they use XMonad, I have seen Ssh, Window and RunOrRaise all make an xmonad user’s day.

5 Responses to Pimp Your XMonad #3: Prompt

  1. Wei says:

    Thanks for your post.
    How do I use xft fonts instead of core fonts?
    I had something like this in xmonad.hs:
    font = “xft:Bitstream Vera Sans Mono:pixelsize=14”

    urxvt understands this font name, but xmonad doesn’t seem to. I’ve compiled in xft support for xmonad-contrib.

    Thanks!

  2. Dw says:

    Hello,

    Great post. However, I have one nagging question: How can I get the user input at a prompt to be passed to a command-line utility.

    For instance, I type my hotkey to show the prompt, I type in some text, and it passes that text to a ‘twitter update’ command that updates my twitter status.

    I can’t seem to find an example in the config archive or in the API docs.

    • bradenshep says:

      I’m not sure how I’d handle this in general.

      First, though, I’d check that the Twitter update command really can’t take the status on the command line using some flag. That seems like an obvious feature to me, but maybe it can’t.

      If it can’t, since we’re talking about a short bit of text here, you could get away with
      echo "Twitter text here" | twitter_update

      Like I said, I don’t know what I’d do in the general case of multi-line text. I guess at that point you’re typing so much in you might as well open a proper xterm.

  3. Jorge says:

    Thanks for the post (from Argentina)!
    Althought I’m starting with Haskell/Xmonad, this shows me that I choosed well a “mouse killer” window manager.

  4. retroj says:

    helpful post.. autoComplete was exactly what i was looking for, for use with workspacePrompt. What about key bindings within prompts? I would love to be able to have C-i work as a tab key in prompts.

Leave a reply to retroj Cancel reply