2011-12-27 10 views
5

Ho una nuova idea dell'uso di XMonad.Prompt.Input di xmonad. Ho pensato che sarebbe stato davvero bello, se si potesse fare una semplice calcolatrice che calcolasse ciò che l'utente inserisce e restituisca il risultato nel testo del prossimo prompt, finendo quando l'utente preme la fuga ... Il problema è che io non si sa bene come trattare con i tipi ...Calcolatrice semplice nel prompt xmonad

Finora ho questo:

che non funziona. Ottengo:

Couldn't match expected type `[Char]' with actual type `IO String' 
Expected type: String 
Actual type: IO String 
In the return type of a call of `runAndGetOutput' 
In the second argument of `calcPrompt', namely 
`(runAndGetOutput ("calc" ++ next))' 

Capisco che abbia qualcosa a che fare con il fatto che runAndGetOutput ritorna IO String e ho bisogno di una stringa normale per inputPrompt incluso dall'importazione XMonad.Prompt.Input. Ma non ho idea di come affrontarlo ...

Grazie mille per il vostro aiuto!

EDIT: Ora ho questo:

runAndGetOutput :: String -> IO String 
runAndGetOutput cmd = do 
    (_, pout, _, phandle) <- runInteractiveCommand cmd 
    a <- hGetContents pout 
     waitForProcess phandle 
     return a 

calcPrompt :: XPConfig -> String -> X() 
calcPrompt c ans = 
    inputPrompt c ans ?+ \next -> 
     liftIO (runAndGetOutput ("echo -n " ++ next)) >>= calcPrompt c 

che compila, ma non funziona come previsto. Posso aprire il prompt, inserire del testo, quindi lancia il comando shell, ma poi scarta il valore stdo invece di usarlo come nuovo testo di prompt.

Mi aspetto che la versione con echo segua: Quando apro il prompt, viene mostrata una stringa predefinita. Quando inserisco un valore e premo Invio, viene visualizzato un altro prompt con il valore inserito in precedenza (grazie a echo che restituisce solo ciò che ha ottenuto). Se ha funzionato con echo, sostituire echo con alcuni script bash per eseguire i calcoli e restituire il risultato anziché l'eco.

MODIFICO recente: Finalmente risolto. Il codice finale del mio piccolo frammento di calc è nella mia auto-risposta :) Grazie a tutti.

risposta

2

Si dovrebbero usare le funzioni disponibili in XMonad.Util.Run, che si occupano di alcuni dettagli specifici di xmonad (alcuni gestiscono il segnale, penso).

+0

Ciò ha funzionato. Molte grazie! –

1

X ha un'istanza MonadIO, così

calcPrompt c ans = 
    inputPrompt c ans ?+ \next -> 
     liftIO (runAndGetOutput ("calc" ++ next)) >>= calcPrompt c 

dovrebbe funzionare, penso.

+0

Grazie mille. Compila bene ora. Tuttavia, non funziona come previsto. Ho sostituito "calc" con "echo", che, secondo la mia idea, dovrebbe riportare il valore dall'utente su un altro calcPromt, e il nuovo calcPrompt dovrebbe mostrare l'ultimo valore inserito nel precedente. Tuttavia, il prompt successivo non viene mai visualizzato.Viene eseguito il comando in runAndGetOutput (ho provato con "touch") sebbene ... –

0

Grazie ragazzi ... Siete fantastici :) Ora funziona. Il mio codice finale è così breve:

... 
import XMonad.Prompt 
import XMonad.Prompt.Input 
import Data.Char (isSpace) 

...  

calcPrompt :: XPConfig -> String -> X() 
calcPrompt c ans = 
    inputPrompt c (trim ans) ?+ \input -> 
     liftIO(runProcessWithInput "qalc" [input] "") >>= calcPrompt c 
    where 
     trim = f . f 
      where f = reverse . dropWhile isSpace 

Solo per gli altri: per utilizzare questo piccolo calc integrato nel xmonad, io lo chiamo da una chiave vincolante come questo:

, ((modm, xK_KP_Multiply), calcPrompt defaultXPConfig "qalc") 

Naturalmente è necessario qalc installato. Penso che questo sia uno snippet piuttosto utile, perché non è solo un calcolo, puoi praticamente chiamare qualsiasi eseguibile che produce un breve output: calcolatrice, dizionario, qualsiasi cosa tu voglia ...