Простой калькулятор в командной строке xmonad - PullRequest
5 голосов
/ 27 декабря 2011

У меня есть новая идея использовать XMonad XMonad.Prompt.Input.Я подумал, что было бы здорово, если бы можно было создать простой калькулятор, который вычислял бы то, что пользователь вводит, и возвращал результат в тексте следующего приглашения, заканчивая, когда пользователь нажимает 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 возвращает IO String, и мне нужна нормальная String для inputPrompt, включенная из import XMonad.Prompt.Input.Но я понятия не имею, как с этим справиться ...

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

РЕДАКТИРОВАТЬ: Теперь у меня есть это:

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

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

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

Ответы [ 3 ]

2 голосов
/ 27 декабря 2011

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

1 голос
/ 27 декабря 2011

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

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

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

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

...