2011-12-27 22 views
5

tengo una nueva idea de usar Xmonad's XMonad.Prompt.Input. Pensé que sería genial si se pudiera hacer una calculadora simple que calcule lo que el usuario ingresa y devuelva el resultado en el texto del siguiente aviso, terminando cuando el usuario presione escape ... El problema es que no lo hago se sabe muy bien cómo hacer frente a los tipos ...Calculadora simple en el prompt xmonad

hasta ahora tengo esto:

que no funciona. Me sale:

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))' 

entiendo que tiene algo que ver con el hecho de que runAndGetOutput vuelve IO cadena y necesito una cadena normal para inputPrompt incluido desde XMonad.Prompt.Input importación. Pero no tengo ni idea de cómo lidiar con eso ...

¡Muchas gracias por su ayuda!

EDIT: Ahora tengo unas pocas cosas:

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 

que compila, pero no funciona como se esperaba. Puedo abrir el mensaje, ingresar un texto, luego se lanza el comando de shell, pero luego simplemente descarta el valor de stdo en lugar de usarlo como un nuevo texto de solicitud.

Esperaría que la versión con echo do siguiente: Cuando abro el prompt, se muestra una cadena predeterminada. Cuando ingreso un valor y presiono regresar, se abre otro mensaje con el valor ingresado previamente (gracias al eco que simplemente devuelve lo que tiene). Si funcionó con echo, reemplazaría echo con algún script bash para realizar los cálculos y devolver el resultado en lugar de echo.

EDIT reciente: Resuelto finalmente. El código final de mi pequeño fragmento de cal está en mi respuesta automática :) Gracias a todos.

Respuesta

2

Debería utilizar las funciones disponibles en XMonad.Util.Run, que se ocupan de algunos detalles específicos de xmonad (algo de manejo de señales, creo).

+0

Eso funcionó. ¡Muchas gracias! –

1

X tiene una instancia MonadIO, por lo

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

debería funcionar, creo.

+0

Muchas gracias. Se compila bien ahora. Sin embargo, no funciona como se esperaba. Reemplacé "calc" por "echo", que según mi idea debería llevar el valor del usuario a otra calcPromt, y el nuevo calcPrompt debería mostrar el último valor ingresado en el anterior. Sin embargo, el siguiente aviso nunca se muestra.El comando en runAndGetOutput se realiza (lo intenté con "touch") aunque ... –

0

Gracias chicos ... Eres genial :) Ahora funciona. Mi código final es tan corto:

... 
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 

Sólo por los demás: para utilizar esta pequeña Calc integrado en xmonad, lo llamo por una clave de unión como ésta:

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

Por supuesto que necesita qalc instalado. Creo que es un fragmento bastante práctico, porque no es solo un cálculo, básicamente se puede llamar a cualquier ejecutable que produzca algún resultado corto: calculadora, diccionario, lo que quiera ...