From 4e4539f736081ed167b9907add4f50eae3ef4146 Mon Sep 17 00:00:00 2001 From: Lukasz Czajka Date: Fri, 8 Nov 2024 19:15:27 +0100 Subject: [PATCH] --vscode option --- app/App.hs | 8 +++++++- app/Commands/Repl.hs | 8 +++++++- app/GlobalOptions.hs | 7 +++++++ src/Juvix/Data/Error/GenericError.hs | 24 ++++++++++++++++-------- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/app/App.hs b/app/App.hs index 2bf3965352..50b5f73f8b 100644 --- a/app/App.hs +++ b/app/App.hs @@ -144,7 +144,13 @@ reAppIO args@RunAppIOArgs {..} = . mkAnsiText . run . runReader (project' @GenericOptions g) - $ Error.render (not (_runAppIOArgsGlobalOptions ^. globalNoColors)) (g ^. globalIdeEndErrorChar) e + $ Error.render renderType (g ^. globalIdeEndErrorChar) e + where + renderType :: Error.RenderType + renderType + | g ^. globalVSCode = Error.RenderVSCode + | g ^. globalNoColors = Error.RenderText + | otherwise = Error.RenderAnsi getEntryPoint' :: (Members '[App, EmbedIO, TaggedLock] r) => diff --git a/app/Commands/Repl.hs b/app/Commands/Repl.hs index 8b35def495..23a732c9f5 100644 --- a/app/Commands/Repl.hs +++ b/app/Commands/Repl.hs @@ -427,7 +427,13 @@ catchAll = Repline.dontCrash . catchJuvixError . hPutStrLn stderr . run . runReader (project' @GenericOptions opts) - $ Error.render (not (opts ^. globalNoColors) && hasAnsi) Nothing e + $ Error.render (renderType opts hasAnsi) Nothing e + where + renderType :: GlobalOptions -> Bool -> Error.RenderType + renderType opts hasAnsi + | opts ^. globalVSCode = Error.RenderVSCode + | opts ^. globalNoColors || not hasAnsi = Error.RenderText + | otherwise = Error.RenderAnsi catchErrorS :: ReplS () -> ReplS () catchErrorS = (`Except.catchError` printErrorS) diff --git a/app/GlobalOptions.hs b/app/GlobalOptions.hs index fa17a693f0..471717c691 100644 --- a/app/GlobalOptions.hs +++ b/app/GlobalOptions.hs @@ -15,6 +15,7 @@ import Juvix.Data.Field data GlobalOptions = GlobalOptions { _globalNoColors :: Bool, + _globalVSCode :: Bool, _globalShowNameIds :: Bool, _globalBuildDir :: Maybe (AppPath Dir), _globalIdeEndErrorChar :: Maybe Char, @@ -60,6 +61,7 @@ defaultGlobalOptions :: GlobalOptions defaultGlobalOptions = GlobalOptions { _globalNoColors = False, + _globalVSCode = False, _globalNumThreads = defaultNumThreads, _globalShowNameIds = False, _globalIdeEndErrorChar = Nothing, @@ -85,6 +87,11 @@ parseGlobalFlags = do ( long "no-colors" <> help "Disable ANSI formatting" ) + _globalVSCode <- + switch + ( long "vscode" + <> help "Enable VSCode compatible output" + ) _globalBuildDir <- optional ( parseBuildDir diff --git a/src/Juvix/Data/Error/GenericError.hs b/src/Juvix/Data/Error/GenericError.hs index ef11cd05db..e8e07b6c54 100644 --- a/src/Juvix/Data/Error/GenericError.hs +++ b/src/Juvix/Data/Error/GenericError.hs @@ -3,12 +3,18 @@ module Juvix.Data.Error.GenericError ) where +import Data.Text qualified as Text import Juvix.Data.Loc import Juvix.Prelude.Base import Juvix.Prelude.Pretty import Prettyprinter.Render.Terminal qualified as Ansi import System.Console.ANSI qualified as Ansi +data RenderType + = RenderAnsi + | RenderText + | RenderVSCode + data GenericError = GenericError { _genericErrorLoc :: Interval, _genericErrorMessage :: AnsiText, @@ -68,29 +74,31 @@ errorIntervals e = do e' <- genericError e return (e' ^. genericErrorIntervals) -render :: (ToGenericError e, Member (Reader GenericOptions) r) => Bool -> Maybe Char -> e -> Sem r Text -render ansi endChar err = do +render :: (ToGenericError e, Member (Reader GenericOptions) r) => RenderType -> Maybe Char -> e -> Sem r Text +render renderType endChar err = do g <- genericError err let gMsg = g ^. genericErrorMessage header = genericErrorHeader g - helper f x = (f . layoutPretty defaultLayoutOptions) (header <> x <> lastChar) - if - | ansi -> return $ helper Ansi.renderStrict (toAnsiDoc gMsg) - | otherwise -> return $ helper renderStrict (toTextDoc gMsg) + helper f x = f (header <> x <> lastChar) + return $ + case renderType of + RenderAnsi -> helper (Ansi.renderStrict . layoutPretty defaultLayoutOptions) (toAnsiDoc gMsg) + RenderText -> helper (renderStrict . layoutPretty defaultLayoutOptions) (toTextDoc gMsg) + RenderVSCode -> Text.replace "\n" " " $ helper (renderStrict . layoutCompact) (toTextDoc gMsg) where lastChar :: Doc a lastChar = maybe "" pretty endChar -- | Render the error to Text. renderText :: (ToGenericError e, Member (Reader GenericOptions) r) => e -> Sem r Text -renderText = render False Nothing +renderText = render RenderText Nothing renderTextDefault :: (ToGenericError e) => e -> Text renderTextDefault = run . runReader defaultGenericOptions . renderText -- | Render the error with Ansi formatting (if any). renderAnsiText :: (ToGenericError e, Member (Reader GenericOptions) r) => e -> Sem r Text -renderAnsiText = render True Nothing +renderAnsiText = render RenderAnsi Nothing printErrorAnsi :: (ToGenericError e, Members '[EmbedIO, Reader GenericOptions] r) => e -> Sem r () printErrorAnsi e = renderAnsiText e >>= \txt -> hPutStrLn stderr txt