1-- Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2-- SPDX-License-Identifier: Apache-2.0
4{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE OverloadedStrings #-}
6{-# LANGUAGE DuplicateRecordFields #-}
7{-# LANGUAGE BlockArguments #-}
8module Development.IDE.Types.Diagnostics (
14 LSP.DiagnosticSeverity(..),
17 DiagnosticRelatedInformation(..),
29 showDiagnosticsColored,
30 prettyDiagnosticStore,
35 getDiagnosticsFromStore
38import Control.Exception
39import Data.Either.Combinators
40import Data.Maybe as Maybe
42import qualified Data.Map as Map
43import qualified Data.Text as T
44import Data.Text.Prettyprint.Doc.Syntax
45import qualified Text.PrettyPrint.Annotated.HughesPJClass as Pretty
46import Language.Haskell.LSP.Types as LSP (
47 DiagnosticSeverity(..)
52 , DiagnosticRelatedInformation(..)
55import Language.Haskell.LSP.Diagnostics
57import Development.IDE.Types.Location
59ideErrorText :: FilePath -> T.Text -> FileDiagnostic
60ideErrorText fp = errorDiag fp "Ide Error"
62ideErrorPretty :: Pretty.Pretty e => FilePath -> e -> FileDiagnostic
63ideErrorPretty fp = ideErrorText fp . T.pack . Pretty.prettyShow
65errorDiag :: FilePath -> T.Text -> T.Text -> FileDiagnostic
67 (fp, diagnostic noRange LSP.DsError src msg)
69-- | This is for compatibility with our old diagnostic type
71 -> LSP.DiagnosticSeverity
73 -> T.Text -- ^ message
75diagnostic rng sev src msg
82 _relatedInformation = Nothing
85-- | Any optional field is instantiated to Nothing
88 T.Text -> -- ^ error message
90defDiagnostic _range _message = LSP.Diagnostic {
96 , _relatedInformation = Nothing
103filterSeriousErrors fp =
104 filter (maybe False hasSeriousErrors . LSP._relatedInformation)
106 hasSeriousErrors :: List DiagnosticRelatedInformation -> Bool
107 hasSeriousErrors (List a) = any ((/=) uri . _uri . _location) a
108 uri = LSP.filePathToUri fp
113 DiagnosticStore -> DiagnosticStore
114addDiagnostics fp diags ds =
117 (LSP.filePathToUri fp)
119 partitionBySource diags
121ideTryIOException :: FilePath -> IO a -> IO (Either FileDiagnostic a)
122ideTryIOException fp act =
123 mapLeft (\(e :: IOException) -> ideErrorText fp $ T.pack $ show e) <$> try act
125-- | Human readable diagnostics for a specific file.
127-- This type packages a pretty printed, human readable error message
128-- along with the related source location so that we can display the error
129-- on either the console or in the IDE at the right source location.
131type FileDiagnostics = (FilePath, [Diagnostic])
132type FileDiagnostic = (FilePath, Diagnostic)
134prettyRange :: Range -> Doc SyntaxClass
135prettyRange Range{..} = f _start <> "-" <> f _end
136 where f Position{..} = pretty (_line+1) <> colon <> pretty _character
138stringParagraphs :: T.Text -> Doc a
139stringParagraphs = vcat . map (fillSep . map pretty . T.words) . T.lines
141showDiagnostics :: [FileDiagnostic] -> T.Text
142showDiagnostics = srenderPlain . prettyDiagnostics
144showDiagnosticsColored :: [FileDiagnostic] -> T.Text
145showDiagnosticsColored = srenderColored . prettyDiagnostics
148prettyDiagnostics :: [FileDiagnostic] -> Doc SyntaxClass
149prettyDiagnostics = vcat . map prettyDiagnostic
151prettyDiagnostic :: FileDiagnostic -> Doc SyntaxClass
152prettyDiagnostic (fp, LSP.Diagnostic{..}) =
154 [ slabel_ "File: " $ pretty fp
155 , slabel_ "Range: " $ prettyRange _range
156 , slabel_ "Source: " $ pretty _source
157 , slabel_ "Severity:" $ pretty $ show sev
158 , slabel_ "Message: "
160 LSP.DsError -> annotate ErrorSC
161 LSP.DsWarning -> annotate WarningSC
162 LSP.DsInfo -> annotate InfoSC
163 LSP.DsHint -> annotate HintSC
164 $ stringParagraphs _message
165 , slabel_ "Code:" $ pretty _code
168 sev = fromMaybe LSP.DsError _severity
170prettyDiagnosticStore :: DiagnosticStore -> Doc SyntaxClass
171prettyDiagnosticStore ds =
173 map (\(uri, diags) -> prettyFileDiagnostics (fromMaybe noFilePath $ uriToFilePath uri, diags)) $
175 Map.map getDiagnosticsFromStore ds
177prettyFileDiagnostics :: FileDiagnostics -> Doc SyntaxClass
178prettyFileDiagnostics (filePath, diags) =
179 slabel_ "Compiler error in" $ vcat
180 [ slabel_ "File:" $ pretty filePath
181 , slabel_ "Errors:" $ vcat $ map (prettyDiagnostic . (filePath,)) diags
184getDiagnosticsFromStore :: StoreItem -> [Diagnostic]
185getDiagnosticsFromStore (StoreItem _ diags) =
186 toList =<< Map.elems diags
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list