Простой калькулятор в подсказке xmonad

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

Пока у меня это:

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

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

Что не работает. Я получил:

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 возвращает строку ввода-вывода, и мне нужна обычная строка для inputPrompt, включенная из import 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 вместо того, чтобы использовать его в качестве нового текста приглашения.

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

Недавнее EDIT: Окончательно решено. Окончательный код моего небольшого фрагмента калькулятора находится в моем ответе самому себе :) Спасибо всем.


person Jan Hadáček    schedule 27.12.2011    source источник


Ответы (3)


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

person Daniel Wagner    schedule 27.12.2011

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

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

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

person Daniel Fischer    schedule 27.12.2011
comment
Большое спасибо. Теперь компилируется нормально. Однако это не работает так, как ожидалось. Я заменил calc на echo , который по моей задумке должен проталкивать значение от пользователя обратно в другой calcPromt, а новый calcPrompt должен показывать последнее введенное значение в предыдущем. Однако следующее приглашение никогда не отображается. Хотя команда в runAndGetOutput выполняется (пробовал касанием)... - person Jan Hadáček; 27.12.2011

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

...
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. Я думаю, что это довольно удобный фрагмент, потому что это не просто калькулятор, вы можете вызвать любой исполняемый файл, который выдает какой-то короткий вывод: калькулятор, словарь, что угодно...

person Jan Hadáček    schedule 27.12.2011