New patches: [SshShell deadguysfrom@gmail.com**20081103023810] { addfile ./XMonad/Prompt/SshShell.hs hunk ./XMonad/Prompt/SshShell.hs 1 +----------------------------------------------------------------------------- +-- | +-- Module : XMonad.Prompt.SshShell +-- Copyright : (C) 2008 Matt Brown +-- License : BSD3 +-- +-- Maintainer : deadguysfrom@gmail.com +-- Stability : unstable +-- Portability : unportable +-- +-- A remote shell prompt for XMonad using ssh +-- +----------------------------------------------------------------------------- + +module XMonad.Prompt.SshShell + ( -- * Usage + -- $usage + sshShellPrompt, + sshSelectLoginPrompt + ) where + +import Control.Monad +import Data.List +import System.IO +import XMonad.Util.Run +import XMonad hiding (config) +import XMonad.Prompt + +-- $usage +-- 1. In your @~\/.xmonad\/xmonad.hs@: +-- +-- > import XMonad.Prompt +-- > import XMonad.Prompt.Shell +-- +-- 2. In your keybindings add something like: +-- +-- > , ((modMask x .|. controlMask, xK_x), sshShellPrompt "user@host" defaultXPConfig) +-- > , ((modMask x .|. controlMask, xK_y), sshSelectLoginPrompt defaultXPConfig) +-- +-- For detailed instruction on editing the key binding see +-- "XMonad.Doc.Extending#Editing_key_bindings". + + +data SshShell = SshShell String +data SelectLogin = SelectLogin + +instance XPrompt SshShell where + showXPrompt (SshShell text) = text ++ ": " + completionToCommand _ = escape + +instance XPrompt SelectLogin where + showXPrompt SelectLogin = "Run as (user@host): " + + +sshSelectLoginPrompt :: XPConfig -> X () +sshSelectLoginPrompt config = mkXPrompt SelectLogin config (mkComplFunFromList []) cmd + where cmd = (\out -> sshShellPrompt out config) . encodeOutput + +sshShellPrompt :: String -> XPConfig -> X () + +sshShellPrompt login config = do + cmds <- io $ (getSshCompl login) + mkXPrompt (SshShell login) config (getShellCompl login cmds) cmd + where cmd = sshRun login . encodeOutput + +getSshCompl :: String -> IO [String] +getSshCompl login = do + fmap lines $ runProcessWithInput "ssh" [login, "compgen -c"] "" + +sshRun :: String -> String-> X () +sshRun login cmd = spawn ("ssh -X " ++ login ++ " " ++ cmd) + +getShellCompl :: String -> [String] -> String -> IO [String] +getShellCompl login cmds s | s == "" || last s == ' ' = return [] + | otherwise = do + f <- fmap lines $ runProcessWithInput "ssh" [login, "compgen -A file " ++ encodeOutput s] "" + files <- case f of + [x] -> do isdir <- isDirectory login x + if isdir + then return [x ++ "/"] + else return [x] + _ -> return f + return . map decodeInput . uniqSort $ files ++ commandCompletionFunction cmds s + +commandCompletionFunction :: [String] -> String -> [String] +commandCompletionFunction cmds str | '/' `elem` str = [] + | otherwise = filter (isPrefixOf str) cmds + +isDirectory :: String -> String -> IO Bool +isDirectory login file = do + result <- fmap lines $ runProcessWithInput "ssh" [login, "test -d " ++ file ++ "; echo $?"] "" + case result of + ["0"] -> return True + _ -> return False + + +-- | Taken from XMonad.Prompt.Shell +-- | Should probably be refactored into a common location, i.e. XMonad.Util + +escape :: String -> String +escape [] = "" +escape (' ':xs) = "\\ " ++ escape xs +escape (x:xs) + | isSpecialChar x = '\\' : x : escape xs + | otherwise = x : escape xs + +isSpecialChar :: Char -> Bool +isSpecialChar = flip elem "\\@\"'#?$*()[]{};" hunk ./xmonad-contrib.cabal 183 + XMonad.Prompt.SshShell } [SshShell Prompt Part 2 deadguysfrom@gmail.com**20081110182227 Moved escape function shared by Shell.hs, SshShell.hs to Prompt.hs. Added comments regarding passwordless requirement, and ControlMaster ] { hunk ./XMonad/Prompt/Shell.hs 117 - -escape :: String -> String -escape [] = "" -escape (' ':xs) = "\\ " ++ escape xs -escape (x:xs) - | isSpecialChar x = '\\' : x : escape xs - | otherwise = x : escape xs - -isSpecialChar :: Char -> Bool -isSpecialChar = flip elem "\\@\"'#?$*()[]{};" hunk ./XMonad/Prompt/SshShell.hs 58 + +-- | Runs a shell prompt over ssh. +-- NOTE: Passwordless login must be configured. Password prompt is not enabled (TODO). +-- If passwordless login is not enabled, XMonad will hang waiting for ssh-askpass. The only +-- way to recover is to kill ssh-askpass (you'll have to switch to another console). +-- +-- +-- To improve responsiveness, it is recommended that SSH's ControlMaster feature be used. hunk ./XMonad/Prompt/SshShell.hs 105 --- | Taken from XMonad.Prompt.Shell --- | Should probably be refactored into a common location, i.e. XMonad.Util - -escape :: String -> String -escape [] = "" -escape (' ':xs) = "\\ " ++ escape xs -escape (x:xs) - | isSpecialChar x = '\\' : x : escape xs - | otherwise = x : escape xs - -isSpecialChar :: Char -> Bool -isSpecialChar = flip elem "\\@\"'#?$*()[]{};" hunk ./XMonad/Prompt.hs 32 + , escape hunk ./XMonad/Prompt.hs 830 +-- | Escape spaces and special characters +escape :: String -> String +escape [] = "" +escape (' ':xs) = "\\ " ++ escape xs +escape (x:xs) + | isSpecialChar x = '\\' : x : escape xs + | otherwise = x : escape xs + +isSpecialChar :: Char -> Bool +isSpecialChar = flip elem "\\@\"'#?$*()[]{};" + } Context: [generic menu and window bringer Travis B. Hartwell **20081027005523] [Search.hs: +hackage search, courtesy of byorgey gwern0@gmail.com**20081031214937 Ignore-this: 24db0ceed49f8bd37ce98ccf8f8ca2ab ] [Prompt.hs rename deleteConsecutiveDuplicates gwern0@gmail.com**20081008205131 That name is really unwieldy and long. ] [Prompt.hs: have historyCompletion filter dupes gwern0@gmail.com**20081008204710 Specifically, it calls deleteConsecutiveDuplicates on the end product. uniqSort reverses order in an unfortunate way, so we don't use that. The use-case is when a user has added the same input many times - as it stands, if the history records 30 'top's or whatever, the completion will show 30 'top' entries! This fixes that. ] [Prompt.hs: tweak haddocks gwern0@gmail.com**20081008204649] [Prompt.hs: mv uniqSort to next to its confreres, and mention the trade-off gwern0@gmail.com**20081008192645] [Do not consider XMONAD_TIMER unknown Joachim Breitner **20081008195643] [Kill window without focusing it first Joachim Breitner **20081005002533 This patch requires the patch "add killWindow function" in xmonad. Before this patch, people would experience “workspace flicker” when closing a window via EWMH that is not on the current workspace, for example when quitting pidgin via the panel icon. ] [let MagnifyLess actually magnify less daniel@wagner-home.com**20081015153911] [windowPromptBringCopy deadguysfrom@gmail.com**20081023173019] [Actions.Search: add a few search engines intrigeri@boum.org**20081008104033 Add Debian {package, bug, tracking system} search engines, as well as Google Images and isohunt. ] [Implement HiddenNonEmptyWS with HiddenWS and NonEmptyWS Joachim Breitner **20081006211027 (Just to reduce code duplication) ] [Add straightforward HiddenWS to WSType Joachim Breitner **20081006210548 With NonEmptyWS and HiddenNonEmptyWS present, HiddenWS is obviously missing. ] [Merge emptyLayoutMod into redoLayout Joachim Breitner **20081005190220 This removes the emptyLayoutMod method from the LayoutModifier class, and change the Stack parameter to redoLayout to a Maybe Stack one. It also changes all affected code. This should should be a refactoring without any change in program behaviour. ] [SmartBorders even for empty layouts Joachim Breitner **20081005184426 Fixes: http://code.google.com/p/xmonad/issues/detail?id=223 ] [Paste.hs: improve haddocks gwern0@gmail.com**20080927150158] [Paste.hs: fix haddock gwern0@gmail.com**20080927145238] [minor explanatory comment daniel@wagner-home.com**20081003015919] [XMonad.Layout.HintedGrid: add GridRatio (--no-test because of haddock breakage) Lukas Mai **20080930141715] [XMonad.Util.Font: UTF8 -> USE_UTF8 Lukas Mai **20080930140056] [Paste.hs: implement noModMask suggestion gwern0@gmail.com**20080926232056] [fix a divide by zero error in Grid daniel@wagner-home.com**20080926204148] [-DUTF8 flag with -DUSE_UTF8 gwern0@gmail.com**20080921154014] [XSelection.hs: use CPP to compile against utf8-string gwern0@gmail.com**20080920151615] [add XMonad.Config.Azerty Devin Mullins **20080924044946] [flip GridRatio to match convention (x/y) Devin Mullins **20080922033354] [let Grid have a configurable aspect ratio goal daniel@wagner-home.com**20080922010950] [Paste.hs: +warning about ASCII limitations gwern0@gmail.com**20080921155038] [Paste.hs: shorten comment lines to under 80 columns per sjanssen gwern0@gmail.com**20080921154950] [Forgot to enable historyFilter :( Spencer Janssen **20080921094254] [Prompt: add configurable history filters Spencer Janssen **20080921093453] [Update my config to use 'statusBar' Spencer Janssen **20080921063513] [Rename pasteKey functions to sendKey Spencer Janssen **20080921062016] [DynamicLog: doc fixes Spencer Janssen **20080921061314] [Move XMonad.Util.XPaste to XMonad.Util.Paste Spencer Janssen **20080921060947] [Depend on X11 >= 1.4.3 Spencer Janssen **20080921055456] [statusBar now supplies the action to toggle struts Spencer Janssen **20080918013858] [cleanup - use currentTag Devin Mullins **20080921011159] [XPaste.hs: improve author info gwern0@gmail.com**20080920152342] [+XMonad.Util.XPaste: a module for pasting strings to windows gwern0@gmail.com**20080920152106] [UrgencyHook bug fix: cleanupUrgents should clean up reminders, too Devin Mullins **20080920062117] [Sketch of XMonad.Config.Monad Spencer Janssen **20080917081838] [raiseMaster seanmce33@gmail.com**20080912184830] [Add missing space between dzen command and flags Daniel Neri **20080915131009] [Big DynamicLog refactor. Added statusBar, improved compositionality for dzen and xmobar Spencer Janssen **20080913205931 Compatibility notes: - dzen type change - xmobar type change - dynamicLogDzen removed - dynamicLogXmobar removed ] [Take maintainership of XMonad.Prompt Spencer Janssen **20080911230442] [Overhaul Prompt to use a zipper for history navigation. Fixes issue #216 Spencer Janssen **20080911225940] [Use the new completion on tab setting Spencer Janssen **20080911085940] [Only start to show the completion window with more than one match Joachim Breitner **20080908110129] [XPrompt: Add showCompletionOnTab option Joachim Breitner **20080908105758 This patch partially implements http://code.google.com/p/xmonad/issues/detail?id=215 It adds a XPConfig option that, if enabled, hides the completion window until the user presses Tab once. Default behaviour is preserved. TODO: If Tab causes a unique completion, continue to hide the completion window. ] [XMonad.Actions.Plane.planeKeys: function to make easier to configure Marco Túlio Gontijo e Silva **20080714153601] [XMonad.Actions.Plane: removed unneeded hiding Marco Túlio Gontijo e Silva **20080714152631] [Improvements in documentation Marco Túlio Gontijo e Silva **20080709002425] [Fix haddock typos in XMonad.Config.{Desktop,Gnome,Kde} Spencer Janssen **20080911040808] [add clearUrgents for your keys Devin Mullins **20080909055425] [add reminder functionality to UrgencyHook Devin Mullins **20080824200548 I'm considering rewriting remindWhen and suppressWhen as UrgencyHookModifiers, so to speak. Bleh. ] [TAG 0.8 Spencer Janssen **20080905195420] Patch bundle hash: a8b3388b58131f2c7655f16620426a0edbe7fb3f