2011-12-27 1 views
5

У меня есть новая идея использования XMonad XMonad.Prompt.Input. Я подумал, что это было бы здорово, если бы можно было сделать простой калькулятор, который бы вычислил, что пользователь вводит и возвращает результат в тексте следующего приглашения, заканчивая, когда пользователь нажимает кнопку ... Проблема в том, что я не делаю знаю, как иметь дело с типами ...Простой калькулятор в подсказке xmonad

до сих пор у меня есть это:

Который не работает. Я получаю:

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

Я понимаю, что что-то делать с тем фактом, что runAndGetOutput возвращает IO String и мне нужна нормальная строка для inputPrompt включенных от импорта XMonad.Prompt.Input. Но я понятия не имею, как с этим справиться ...

Большое спасибо за вашу помощь!

EDIT: Теперь у меня есть это:

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 

Что компилирует, но не работает, как ожидалось. Я могу открыть приглашение, ввести текст, затем он запускает команду оболочки, но затем она просто отбрасывает значение stdo вместо того, чтобы использовать его в качестве нового текста приглашения.

Я ожидаю, что версия с эхом сделает следующее: Когда я открываю приглашение, отображается строка по умолчанию. Когда я вводим значение и нажимаю return, открывается другое приглашение с ранее введенным значением (благодаря эхо, которое возвращает только то, что у него есть). Если он работал с echo, я бы заменил echo некоторым скриптом bash для выполнения вычислений и вернул результат вместо echo.

Последнее изменение: Окончательно разрешено. Окончательный код моего небольшого отрывка из блокнот в моем ответе :) Спасибо всем.

ответ

2

Вы должны использовать функции, доступные в XMonad.Util.Run, которые позаботятся о нескольких деталях, специфичных для xmonad (я думаю, что некоторые обработки сигналов).

+0

Это сработало. Большое спасибо! –

1

X имеет MonadIO экземпляр, так

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

должен работать, я думаю.

+0

Большое спасибо. Теперь он компилируется. Однако он не работает должным образом. Я заменил «calc» на «echo», который, согласно моей идее, должен отодвинуть значение от пользователя обратно к другому calcPromt, а новый calcPrompt должен показать последнее введенное значение в предыдущем. Однако следующее приглашение никогда не отображается.Выполняется команда в runAndGetOutput (я пытался с «touch»), хотя ... –

0

Спасибо, ребята, вы здоровы :) Теперь это работает. Мой последний код настолько короток:

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

Просто для остальные: использовать этот крошечные известково интегрированные в xmonad, я называю это с помощью ключа привязки, как это:

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

Конечно вам нужно qalc установлен. Я думаю, что это довольно удобный фрагмент, потому что это не просто калькулятор, вы можете в принципе вызвать любой исполняемый файл, который производит короткий результат: калькулятор, словарь, что угодно ...