{-# LANGUAGE PatternSignatures #-} module Yi.Eval ( -- * Eval\/Interpretation evalE, jumpToErrorE, consoleKeymap, ) where import Control.Monad import Control.Monad.Trans import Data.Array import Data.List import Prelude hiding (error) import System.Directory import Text.Regex.Posix import Yi.Core import Yi.Debug import Yi.Editor import Yi.Kernel import Yi.Keymap import Yi.Interact hiding (write) import Yi.Event import Yi.Buffer import Yi.Buffer.HighLevel import Yi.Dired #ifdef DYNAMIC evalToStringE :: String -> YiM String evalToStringE string = withKernel $ \kernel -> do result <- evalMono kernel ("show (" ++ string ++ ")") return $ case result of Left err -> err Right x -> x #else evalToStringE :: (Monad m) => a -> m a evalToStringE = return #endif -- | Evaluate some text and show the result in the message line. evalE :: String -> YiM () evalE s = evalToStringE s >>= msgEditor jumpToE :: String -> Int -> Int -> YiM () jumpToE filename line column = do bs <- readEditor $ findBufferWithName filename -- FIXME: should find by associated file-name case bs of [] -> do found <- lift $ doesFileExist filename if found then fnewE filename else error "file not found" (b:_) -> withEditor $ switchToBufferOtherWindowE b withBuffer $ do gotoLn line moveXorEol column parseErrorMessage :: String -> Maybe (String, Int, Int) parseErrorMessage ln = do result :: (Array Int String) <- ln =~~ "^(.+):([0-9]+):([0-9]+):.*$" return (result!1, read (result!2), read (result!3)) parseErrorMessageB :: BufferM (String, Int, Int) parseErrorMessageB = do ln <- readLnB let Just location = parseErrorMessage ln return location jumpToErrorE :: YiM () jumpToErrorE = do (f,l,c) <- withBuffer parseErrorMessageB jumpToE f l c prompt :: String prompt = "Yi> " takeCommand :: String -> String takeCommand x | prompt `isPrefixOf` x = drop (length prompt) x | otherwise = x consoleKeymap :: Keymap consoleKeymap = do event (Event KEnter []) write $ do x <- withBuffer readLnB case parseErrorMessage x of Just (f,l,c) -> jumpToE f l c Nothing -> do withBuffer $ do p <- pointB botB p' <- pointB when (p /= p') $ insertN ("\n" ++ prompt ++ takeCommand x) insertN "\n" pt <- pointB insertN prompt bm <- getBookmarkB "errorInsert" setMarkPointB bm pt execEditorAction $ takeCommand x