yi-0.3: Yi/Eval.hs
{-# 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