mirror of
https://github.com/anoma/juvix.git
synced 2025-01-05 14:34:03 +03:00
Add juvix-repl-mode for emacs (#1612)
* Adds a major mode for juvix-repl * juvix-mode: C-c C-l loads file into REPL, if the REPL is running * Detect ANSI support in Emacs REPL / shell by using hSupportsANSIColor API * Disable comint echo handling. Juvix REPL does not echo * repl: whitespace strip input to compile/eval/infer commands
This commit is contained in:
parent
aa00d34c8c
commit
6d66d0ab13
@ -28,7 +28,7 @@ runAppIO g root pkg = interpret $ \case
|
||||
RenderStdOut t
|
||||
| g ^. globalOnlyErrors -> return ()
|
||||
| otherwise -> embed $ do
|
||||
sup <- Ansi.hSupportsANSI stdout
|
||||
sup <- Ansi.hSupportsANSIColor stdout
|
||||
renderIO (not (g ^. globalNoColors) && sup) t
|
||||
AskGlobalOptions -> return g
|
||||
AskPackage -> return pkg
|
||||
|
@ -161,7 +161,7 @@ runCommand opts = do
|
||||
<$> doEvalIO False defaultLoc (ctx ^. replContextExpContext . contextCoreResult . Core.coreResultTable) n
|
||||
|
||||
compileString :: Repl (Either JuvixError Core.Node)
|
||||
compileString = liftIO $ compileExpressionIO' ctx (pack s)
|
||||
compileString = liftIO $ compileExpressionIO' ctx (strip (pack s))
|
||||
|
||||
bindEither :: Monad m => m (Either e a) -> (a -> m (Either e b)) -> m (Either e b)
|
||||
bindEither x f = join <$> (x >>= mapM f)
|
||||
@ -172,7 +172,7 @@ runCommand opts = do
|
||||
gopts <- State.gets (^. replStateGlobalOptions)
|
||||
case ctx of
|
||||
Just ctx' -> do
|
||||
compileRes <- liftIO (compileExpressionIO' ctx' (pack input))
|
||||
compileRes <- liftIO (compileExpressionIO' ctx' (strip (pack input)))
|
||||
case compileRes of
|
||||
Left err -> printError gopts err
|
||||
Right n -> renderOut gopts (Core.ppOut (project' @GenericOptions gopts) n)
|
||||
@ -184,7 +184,7 @@ runCommand opts = do
|
||||
gopts <- State.gets (^. replStateGlobalOptions)
|
||||
case ctx of
|
||||
Just ctx' -> do
|
||||
compileRes <- liftIO (inferExpressionIO' ctx' (pack input))
|
||||
compileRes <- liftIO (inferExpressionIO' ctx' (strip (pack input)))
|
||||
case compileRes of
|
||||
Left err -> printError gopts err
|
||||
Right n -> renderOut gopts (Internal.ppOut (project' @GenericOptions gopts) n)
|
||||
@ -282,7 +282,7 @@ compileExpressionIO' ctx = compileExpressionIO "" (ctx ^. replContextExpContext)
|
||||
|
||||
render' :: (MonadIO m, P.HasAnsiBackend a, P.HasTextBackend a) => GlobalOptions -> a -> m ()
|
||||
render' g t = liftIO $ do
|
||||
hasAnsi <- Ansi.hSupportsANSI stdout
|
||||
hasAnsi <- Ansi.hSupportsANSIColor stdout
|
||||
P.renderIO (not (g ^. globalNoColors) && hasAnsi) t
|
||||
|
||||
renderOut :: (MonadIO m, P.HasAnsiBackend a, P.HasTextBackend a) => GlobalOptions -> a -> m ()
|
||||
@ -290,5 +290,5 @@ renderOut g t = render' g t >> liftIO (putStrLn "")
|
||||
|
||||
printError :: MonadIO m => GlobalOptions -> JuvixError -> m ()
|
||||
printError opts e = liftIO $ do
|
||||
hasAnsi <- Ansi.hSupportsANSI stderr
|
||||
hasAnsi <- Ansi.hSupportsANSIColor stderr
|
||||
liftIO $ hPutStrLn stderr $ run (runReader (project' @GenericOptions opts) (Error.render (not (opts ^. globalNoColors) && hasAnsi) False e))
|
||||
|
@ -2,6 +2,7 @@
|
||||
(require 'juvix-highlight)
|
||||
(require 'juvix-input)
|
||||
(require 'flycheck-juvix)
|
||||
(require 'juvix-repl)
|
||||
|
||||
(defgroup juvix nil
|
||||
"Major mode for Juvix files."
|
||||
@ -56,7 +57,8 @@
|
||||
(eval (read (shell-command-to-string
|
||||
(concat "juvix " (if juvix-disable-embedded-stdlib "--no-stdlib " "") (if juvix-stdlib-path (concat "--stdlib-path " juvix-stdlib-path " ") "") "dev highlight "
|
||||
(buffer-file-name)))))
|
||||
(save-buffer))
|
||||
(save-buffer)
|
||||
(juvix-repl-load-file (buffer-file-name)))
|
||||
|
||||
(defun juvix-format-buffer ()
|
||||
"Format the current buffer."
|
||||
|
50
juvix-mode/juvix-repl.el
Normal file
50
juvix-mode/juvix-repl.el
Normal file
@ -0,0 +1,50 @@
|
||||
(require 'comint)
|
||||
|
||||
(defgroup juvix-repl nil
|
||||
"Interaction mode for Juvix"
|
||||
:group 'juvix)
|
||||
|
||||
(defvar juvix-repl-program "juvix"
|
||||
"The Juvix program.")
|
||||
|
||||
(defvar juvix-repl-program-args '("repl")
|
||||
"The argument to pass to Juvix to launch the REPL.")
|
||||
|
||||
(defvar juvix-repl-mode-map
|
||||
(nconc (make-sparse-keymap) comint-mode-map))
|
||||
|
||||
(defvar juvix-repl-buffer-name "*juvix-repl*"
|
||||
"The name of the buffer to use for the `juvix-repl' comint instance.")
|
||||
|
||||
(defun run-juvix-repl ()
|
||||
"Run an inferior instance of `juvix repl' inside Emacs."
|
||||
(interactive)
|
||||
(let* ((juvix-program juvix-repl-program)
|
||||
(juvix-program-args juvix-repl-program-args)
|
||||
(buffer (get-buffer-create juvix-repl-buffer-name))
|
||||
(proc-alive (comint-check-proc buffer))
|
||||
(process (get-buffer-process buffer)))
|
||||
(unless proc-alive
|
||||
(with-current-buffer buffer
|
||||
(apply 'make-comint-in-buffer "juvix-repl" buffer
|
||||
juvix-program nil juvix-program-args)
|
||||
(juvix-repl-mode)))
|
||||
(when buffer
|
||||
(pop-to-buffer buffer))))
|
||||
|
||||
(defun juvix-repl--initialize ()
|
||||
"Helper function to initalize juvix-repl."
|
||||
(setq comint-process-echoes nil))
|
||||
|
||||
(define-derived-mode juvix-repl-mode comint-mode "Juvix REPL" "Major mode for juvix-repl")
|
||||
|
||||
(add-hook 'juvix-mode-hook 'juvix-repl--initialize)
|
||||
|
||||
(defun juvix-repl-load-file (filename)
|
||||
"Load FILENAME into the juvix-repl if it is running."
|
||||
(let* ((buffer (get-buffer juvix-repl-buffer-name))
|
||||
(proc-alive (comint-check-proc buffer)))
|
||||
(when proc-alive
|
||||
(comint-simple-send juvix-repl-buffer-name (concat ":load " filename)))))
|
||||
|
||||
(provide 'juvix-repl)
|
@ -88,7 +88,7 @@ printErrorText e = renderText e >>= \txt -> embed (hPutStrLn stderr txt)
|
||||
printErrorAnsiSafe :: (ToGenericError e, Members '[Embed IO, Reader GenericOptions] r) => e -> Sem r ()
|
||||
printErrorAnsiSafe e =
|
||||
ifM
|
||||
(embed (Ansi.hSupportsANSI stderr))
|
||||
(embed (Ansi.hSupportsANSIColor stderr))
|
||||
(printErrorAnsi e)
|
||||
(printErrorText e)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user