mirror of
https://github.com/swarm-game/swarm.git
synced 2024-08-16 18:10:23 +03:00
Update to depend on lsp-2.4.0.0
(#1762)
Update to use the `lsp-2.4` API. Closes #1350. Initially I hoped that any `lsp-2.x` would work. However, the `SeverDefinition` record changed in `2.2` so I initially set that as a lower bound. But then it turns out that `2.4` changed which module it is importing `Rope` from; since we work with ropes in the `Hover` module it matters since we have to import the matching module. Updating to the new `Rope` type also required some changes as the API provided by the new `Rope.Mixed` module is a bit different than the old module, so we would not even be able to easily put in CPP to conditionally depend on the right rope module depending on the `lsp` version. Finally, this means dropping support for GHC 9.0 since `lsp-2.4` does not support it. Along the way I also fixed a minor issue related to showing type information returned by the LSP server, so that it uses `prettyTypeLine` to display the type on a single line (in my editor, when the type does not use a single line it gets cut off). For comparison see also #1610. This refactoring was a big pain because a lot of things (names of types and constructors, locations of exports, etc...) changed from 1.x to 2.x, but there was not much in the way of documenting what had changed. =( I am pretty sure that all functionality has been preserved but I would appreciate independent confirmation. This is also a prerequisite for updating other dependencies such as the `base` version (I will open a follow-up PR soon) since the old `lsp-1.x` versions do not allow many newer versions of various dependencies.
This commit is contained in:
parent
bce45cc0fe
commit
c4a6e273c1
50
.github/workflows/haskell-ci.yml
vendored
50
.github/workflows/haskell-ci.yml
vendored
@ -17,9 +17,9 @@
|
||||
#
|
||||
# For more information, see https://github.com/haskell-CI/haskell-ci
|
||||
#
|
||||
# version: 0.16.3
|
||||
# version: 0.17.20240109
|
||||
#
|
||||
# REGENDATA ("0.16.3",["github","--config=cabal.haskell-ci","--copy-fields=all","swarm.cabal"])
|
||||
# REGENDATA ("0.17.20240109",["github","--config=cabal.haskell-ci","--copy-fields=all","swarm.cabal"])
|
||||
#
|
||||
name: Haskell-CI
|
||||
on:
|
||||
@ -57,24 +57,19 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- compiler: ghc-9.6.2
|
||||
- compiler: ghc-9.6.4
|
||||
compilerKind: ghc
|
||||
compilerVersion: 9.6.2
|
||||
compilerVersion: 9.6.4
|
||||
setup-method: ghcup
|
||||
allow-failure: false
|
||||
- compiler: ghc-9.4.5
|
||||
- compiler: ghc-9.4.8
|
||||
compilerKind: ghc
|
||||
compilerVersion: 9.4.5
|
||||
compilerVersion: 9.4.8
|
||||
setup-method: ghcup
|
||||
allow-failure: false
|
||||
- compiler: ghc-9.2.7
|
||||
- compiler: ghc-9.2.8
|
||||
compilerKind: ghc
|
||||
compilerVersion: 9.2.7
|
||||
setup-method: ghcup
|
||||
allow-failure: false
|
||||
- compiler: ghc-9.0.2
|
||||
compilerKind: ghc
|
||||
compilerVersion: 9.0.2
|
||||
compilerVersion: 9.2.8
|
||||
setup-method: ghcup
|
||||
allow-failure: false
|
||||
fail-fast: false
|
||||
@ -84,10 +79,10 @@ jobs:
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5
|
||||
mkdir -p "$HOME/.ghcup/bin"
|
||||
curl -sL https://downloads.haskell.org/ghcup/0.1.19.2/x86_64-linux-ghcup-0.1.19.2 > "$HOME/.ghcup/bin/ghcup"
|
||||
curl -sL https://downloads.haskell.org/ghcup/0.1.20.0/x86_64-linux-ghcup-0.1.20.0 > "$HOME/.ghcup/bin/ghcup"
|
||||
chmod a+x "$HOME/.ghcup/bin/ghcup"
|
||||
"$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false)
|
||||
"$HOME/.ghcup/bin/ghcup" install cabal 3.10.1.0 || (cat "$HOME"/.ghcup/logs/*.* && false)
|
||||
"$HOME/.ghcup/bin/ghcup" install cabal 3.10.2.0 || (cat "$HOME"/.ghcup/logs/*.* && false)
|
||||
env:
|
||||
HCKIND: ${{ matrix.compilerKind }}
|
||||
HCNAME: ${{ matrix.compiler }}
|
||||
@ -99,11 +94,13 @@ jobs:
|
||||
echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV"
|
||||
echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV"
|
||||
HCDIR=/opt/$HCKIND/$HCVER
|
||||
HC=$HOME/.ghcup/bin/$HCKIND-$HCVER
|
||||
HC=$("$HOME/.ghcup/bin/ghcup" whereis ghc "$HCVER")
|
||||
HCPKG=$(echo "$HC" | sed 's#ghc$#ghc-pkg#')
|
||||
HADDOCK=$(echo "$HC" | sed 's#ghc$#haddock#')
|
||||
echo "HC=$HC" >> "$GITHUB_ENV"
|
||||
echo "HCPKG=$HOME/.ghcup/bin/$HCKIND-pkg-$HCVER" >> "$GITHUB_ENV"
|
||||
echo "HADDOCK=$HOME/.ghcup/bin/haddock-$HCVER" >> "$GITHUB_ENV"
|
||||
echo "CABAL=$HOME/.ghcup/bin/cabal-3.10.1.0 -vnormal+nowrap" >> "$GITHUB_ENV"
|
||||
echo "HCPKG=$HCPKG" >> "$GITHUB_ENV"
|
||||
echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV"
|
||||
echo "CABAL=$HOME/.ghcup/bin/cabal-3.10.2.0 -vnormal+nowrap" >> "$GITHUB_ENV"
|
||||
HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')
|
||||
echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV"
|
||||
echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV"
|
||||
@ -153,7 +150,7 @@ jobs:
|
||||
- name: cache (tools)
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ matrix.compiler }}-tools-1d2d1963
|
||||
key: ${{ runner.os }}-${{ matrix.compiler }}-tools-fda4bbd7
|
||||
path: ~/.haskell-ci-tools
|
||||
- name: install cabal-plan
|
||||
run: |
|
||||
@ -167,8 +164,8 @@ jobs:
|
||||
- name: install cabal-docspec
|
||||
run: |
|
||||
mkdir -p $HOME/.cabal/bin
|
||||
curl -sL https://github.com/phadej/cabal-extras/releases/download/cabal-docspec-0.0.0.20230517/cabal-docspec-0.0.0.20230517-x86_64-linux.xz > cabal-docspec.xz
|
||||
echo '3b31bbe463ad4d671abbc103db49628562ec48a6604cab278207b5b6acd21ed7 cabal-docspec.xz' | sha256sum -c -
|
||||
curl -sL https://github.com/phadej/cabal-extras/releases/download/cabal-docspec-0.0.0.20231219/cabal-docspec-0.0.0.20231219-x86_64-linux.xz > cabal-docspec.xz
|
||||
echo '8b60448275466bbe2b9409741b5dd07a41c541283017b95b44efe6e31379d067 cabal-docspec.xz' | sha256sum -c -
|
||||
xz -d < cabal-docspec.xz > $HOME/.cabal/bin/cabal-docspec
|
||||
rm -f cabal-docspec.xz
|
||||
chmod a+x $HOME/.cabal/bin/cabal-docspec
|
||||
@ -183,7 +180,7 @@ jobs:
|
||||
uses: actions/cache/save@v3
|
||||
if: always()
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ matrix.compiler }}-tools-1d2d1963
|
||||
key: ${{ runner.os }}-${{ matrix.compiler }}-tools-fda4bbd7
|
||||
path: ~/.haskell-ci-tools
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
@ -245,6 +242,13 @@ jobs:
|
||||
- name: hlint
|
||||
run: |
|
||||
if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_swarm} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 -XBangPatterns -XDeriveAnyClass -XDeriveDataTypeable -XDeriveFunctor -XDeriveGeneric -XDeriveTraversable -XExplicitForAll -XFlexibleContexts -XFlexibleInstances -XGADTSyntax -XMultiParamTypeClasses -XNumericUnderscores -XRankNTypes -XScopedTypeVariables -XStandaloneDeriving -XTupleSections -XTypeApplications -XTypeOperators -XImportQualifiedPost -XLambdaCase -XStrictData src) ; fi
|
||||
if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_swarm} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 -XBangPatterns -XDeriveAnyClass -XDeriveDataTypeable -XDeriveFunctor -XDeriveGeneric -XDeriveTraversable -XExplicitForAll -XFlexibleContexts -XFlexibleInstances -XGADTSyntax -XMultiParamTypeClasses -XNumericUnderscores -XRankNTypes -XScopedTypeVariables -XStandaloneDeriving -XTupleSections -XTypeApplications -XTypeOperators -XImportQualifiedPost -XLambdaCase -XStrictData src/swarm-util) ; fi
|
||||
if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_swarm} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 -XBangPatterns -XDeriveAnyClass -XDeriveDataTypeable -XDeriveFunctor -XDeriveGeneric -XDeriveTraversable -XExplicitForAll -XFlexibleContexts -XFlexibleInstances -XGADTSyntax -XMultiParamTypeClasses -XNumericUnderscores -XRankNTypes -XScopedTypeVariables -XStandaloneDeriving -XTupleSections -XTypeApplications -XTypeOperators -XImportQualifiedPost -XLambdaCase -XStrictData src/swarm-web) ; fi
|
||||
if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_swarm} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 -XBangPatterns -XDeriveAnyClass -XDeriveDataTypeable -XDeriveFunctor -XDeriveGeneric -XDeriveTraversable -XExplicitForAll -XFlexibleContexts -XFlexibleInstances -XGADTSyntax -XMultiParamTypeClasses -XNumericUnderscores -XRankNTypes -XScopedTypeVariables -XStandaloneDeriving -XTupleSections -XTypeApplications -XTypeOperators -XImportQualifiedPost -XLambdaCase -XStrictData src/swarm-engine) ; fi
|
||||
if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_swarm} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 -XBangPatterns -XDeriveAnyClass -XDeriveDataTypeable -XDeriveFunctor -XDeriveGeneric -XDeriveTraversable -XExplicitForAll -XFlexibleContexts -XFlexibleInstances -XGADTSyntax -XMultiParamTypeClasses -XNumericUnderscores -XRankNTypes -XScopedTypeVariables -XStandaloneDeriving -XTupleSections -XTypeApplications -XTypeOperators -XImportQualifiedPost -XLambdaCase -XStrictData src/swarm-scenario) ; fi
|
||||
if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_swarm} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 -XBangPatterns -XDeriveAnyClass -XDeriveDataTypeable -XDeriveFunctor -XDeriveGeneric -XDeriveTraversable -XExplicitForAll -XFlexibleContexts -XFlexibleInstances -XGADTSyntax -XMultiParamTypeClasses -XNumericUnderscores -XRankNTypes -XScopedTypeVariables -XStandaloneDeriving -XTupleSections -XTypeApplications -XTypeOperators -XImportQualifiedPost -XLambdaCase -XStrictData src/swarm-lang) ; fi
|
||||
if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_swarm} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 -XBangPatterns -XDeriveAnyClass -XDeriveDataTypeable -XDeriveFunctor -XDeriveGeneric -XDeriveTraversable -XExplicitForAll -XFlexibleContexts -XFlexibleInstances -XGADTSyntax -XMultiParamTypeClasses -XNumericUnderscores -XRankNTypes -XScopedTypeVariables -XStandaloneDeriving -XTupleSections -XTypeApplications -XTypeOperators -XImportQualifiedPost -XLambdaCase app/doc) ; fi
|
||||
if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_swarm} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 -XBangPatterns -XDeriveAnyClass -XDeriveDataTypeable -XDeriveFunctor -XDeriveGeneric -XDeriveTraversable -XExplicitForAll -XFlexibleContexts -XFlexibleInstances -XGADTSyntax -XMultiParamTypeClasses -XNumericUnderscores -XRankNTypes -XScopedTypeVariables -XStandaloneDeriving -XTupleSections -XTypeApplications -XTypeOperators -XImportQualifiedPost -XLambdaCase app/scene) ; fi
|
||||
if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_swarm} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 -XImportQualifiedPost app) ; fi
|
||||
- name: cabal check
|
||||
run: |
|
||||
|
14
.mergify.yml
14
.mergify.yml
@ -14,10 +14,9 @@ queue_rules:
|
||||
- or:
|
||||
- check-success=Enforce issue references
|
||||
- -files~=\.hs$
|
||||
- check-success=Haskell-CI - Linux - ghc-9.6.2
|
||||
- check-success=Haskell-CI - Linux - ghc-9.4.5
|
||||
- check-success=Haskell-CI - Linux - ghc-9.2.7
|
||||
- check-success=Haskell-CI - Linux - ghc-9.0.2
|
||||
- check-success=Haskell-CI - Linux - ghc-9.6.4
|
||||
- check-success=Haskell-CI - Linux - ghc-9.4.8
|
||||
- check-success=Haskell-CI - Linux - ghc-9.2.8
|
||||
|
||||
pull_request_rules:
|
||||
- actions:
|
||||
@ -44,10 +43,9 @@ pull_request_rules:
|
||||
- or:
|
||||
- check-success=Enforce issue references
|
||||
- -files~=\.hs$
|
||||
- check-success=Haskell-CI - Linux - ghc-9.6.2
|
||||
- check-success=Haskell-CI - Linux - ghc-9.4.5
|
||||
- check-success=Haskell-CI - Linux - ghc-9.2.7
|
||||
- check-success=Haskell-CI - Linux - ghc-9.0.2
|
||||
- check-success=Haskell-CI - Linux - ghc-9.6.4
|
||||
- check-success=Haskell-CI - Linux - ghc-9.4.8
|
||||
- check-success=Haskell-CI - Linux - ghc-9.2.8
|
||||
- label=merge me
|
||||
- ! '#approved-reviews-by>=1'
|
||||
- ! '#changes-requested-reviews-by=0'
|
||||
|
@ -19,7 +19,7 @@ benchmarks: True
|
||||
|
||||
-- Run HLint
|
||||
hlint: True
|
||||
hlint-job: 9.4.5
|
||||
hlint-job: 9.4.8
|
||||
hlint-yaml: .hlint.yaml
|
||||
hlint-download-binary: True
|
||||
|
||||
|
@ -10,14 +10,15 @@ module Swarm.Language.LSP where
|
||||
import Control.Lens (to, (^.))
|
||||
import Control.Monad (void)
|
||||
import Control.Monad.IO.Class
|
||||
import Data.Int (Int32)
|
||||
import Data.Maybe (fromMaybe, mapMaybe)
|
||||
import Data.Text (Text)
|
||||
import Data.Text.IO qualified as Text
|
||||
import Language.LSP.Diagnostics
|
||||
import Language.LSP.Protocol.Lens qualified as LSP
|
||||
import Language.LSP.Protocol.Message qualified as LSP
|
||||
import Language.LSP.Protocol.Types qualified as LSP
|
||||
import Language.LSP.Server
|
||||
import Language.LSP.Types (Hover (Hover))
|
||||
import Language.LSP.Types qualified as J
|
||||
import Language.LSP.Types.Lens qualified as J
|
||||
import Language.LSP.VFS (VirtualFile (..), virtualFileText)
|
||||
import Swarm.Language.LSP.Hover qualified as H
|
||||
import Swarm.Language.LSP.VarUsage qualified as VU
|
||||
@ -34,30 +35,32 @@ lspMain =
|
||||
void $
|
||||
runServer $
|
||||
ServerDefinition
|
||||
{ onConfigurationChange = const $ const $ Right ()
|
||||
, defaultConfig = ()
|
||||
{ defaultConfig = ()
|
||||
, configSection = "swarm"
|
||||
, parseConfig = const $ const $ Right ()
|
||||
, onConfigChange = const $ return ()
|
||||
, doInitialize = \env _req -> pure $ Right env
|
||||
, staticHandlers = handlers
|
||||
, staticHandlers = const handlers
|
||||
, interpretHandler = \env -> Iso (runLspT env) liftIO
|
||||
, options =
|
||||
defaultOptions
|
||||
{ -- set sync options to get DidSave event, as well as Open and Close events.
|
||||
textDocumentSync =
|
||||
optTextDocumentSync =
|
||||
Just
|
||||
( J.TextDocumentSyncOptions
|
||||
( LSP.TextDocumentSyncOptions
|
||||
(Just True)
|
||||
(Just syncKind)
|
||||
(Just False)
|
||||
(Just False)
|
||||
(Just . J.InR . J.SaveOptions $ Just True)
|
||||
(Just . LSP.InR . LSP.SaveOptions $ Just True)
|
||||
)
|
||||
}
|
||||
}
|
||||
where
|
||||
-- Using SyncFull seems to handle the debounce for us.
|
||||
-- The alternative is to use SyncIncremental, but then then
|
||||
-- handler is called for each key-stroke.
|
||||
syncKind = J.TdSyncFull
|
||||
-- The alternative is to use SyncIncremental, but then the
|
||||
-- handler is called for each keystroke.
|
||||
syncKind = LSP.TextDocumentSyncKind_Full
|
||||
|
||||
diagnosticSourcePrefix :: Text
|
||||
diagnosticSourcePrefix = "swarm-lsp"
|
||||
@ -65,7 +68,9 @@ diagnosticSourcePrefix = "swarm-lsp"
|
||||
debug :: (MonadIO m) => Text -> m ()
|
||||
debug msg = liftIO $ Text.hPutStrLn stderr $ "[swarm-lsp] " <> msg
|
||||
|
||||
validateSwarmCode :: J.NormalizedUri -> J.TextDocumentVersion -> Text -> LspM () ()
|
||||
type TextDocumentVersion = Int32
|
||||
|
||||
validateSwarmCode :: LSP.NormalizedUri -> Maybe TextDocumentVersion -> Text -> LspM () ()
|
||||
validateSwarmCode doc version content = do
|
||||
-- debug $ "Validating: " <> from (show doc) <> " ( " <> content <> ")"
|
||||
|
||||
@ -101,32 +106,36 @@ validateSwarmCode doc version content = do
|
||||
publishDiags $
|
||||
map makeParseErrorDiagnostic parsingErrs
|
||||
where
|
||||
publishDiags :: [J.Diagnostic] -> LspM () ()
|
||||
publishDiags :: [LSP.Diagnostic] -> LspM () ()
|
||||
publishDiags = publishDiagnostics 1 doc version . partitionBySource
|
||||
|
||||
makeUnusedVarDiagnostic :: (J.Range, Text) -> J.Diagnostic
|
||||
makeUnusedVarDiagnostic :: (LSP.Range, Text) -> LSP.Diagnostic
|
||||
makeUnusedVarDiagnostic (range, msg) =
|
||||
J.Diagnostic
|
||||
LSP.Diagnostic
|
||||
range
|
||||
(Just J.DsWarning) -- severity
|
||||
(Just LSP.DiagnosticSeverity_Warning) -- severity
|
||||
Nothing -- code
|
||||
Nothing -- code description
|
||||
(Just diagnosticSourcePrefix) -- source
|
||||
msg
|
||||
(Just (J.List [J.DtUnnecessary])) -- tags
|
||||
(Just [LSP.DiagnosticTag_Unnecessary]) -- tags
|
||||
Nothing -- related source code info
|
||||
makeParseErrorDiagnostic :: ((Int, Int), (Int, Int), Text) -> J.Diagnostic
|
||||
Nothing -- data
|
||||
makeParseErrorDiagnostic :: ((Int, Int), (Int, Int), Text) -> LSP.Diagnostic
|
||||
makeParseErrorDiagnostic ((startLine, startCol), (endLine, endCol), msg) =
|
||||
J.Diagnostic
|
||||
( J.Range
|
||||
(J.Position (fromIntegral startLine) (fromIntegral startCol))
|
||||
(J.Position (fromIntegral endLine) (fromIntegral endCol))
|
||||
LSP.Diagnostic
|
||||
( LSP.Range
|
||||
(LSP.Position (fromIntegral startLine) (fromIntegral startCol))
|
||||
(LSP.Position (fromIntegral endLine) (fromIntegral endCol))
|
||||
)
|
||||
(Just J.DsError) -- severity
|
||||
(Just LSP.DiagnosticSeverity_Error) -- severity
|
||||
Nothing -- code
|
||||
Nothing -- code description
|
||||
(Just diagnosticSourcePrefix) -- source
|
||||
msg
|
||||
Nothing -- tags
|
||||
(Just (J.List []))
|
||||
(Just []) -- related info
|
||||
Nothing -- data
|
||||
|
||||
showTypeErrorPos :: Text -> ContextualTypeErr -> ((Int, Int), (Int, Int), Text)
|
||||
showTypeErrorPos code (CTE l _ te) = (minusOne start, minusOne end, msg)
|
||||
@ -141,30 +150,30 @@ showTypeErrorPos code (CTE l _ te) = (minusOne start, minusOne end, msg)
|
||||
handlers :: Handlers (LspM ())
|
||||
handlers =
|
||||
mconcat
|
||||
[ notificationHandler J.SInitialized $ \_not -> do
|
||||
[ notificationHandler LSP.SMethod_Initialized $ \_not -> do
|
||||
debug "Initialized"
|
||||
, notificationHandler J.STextDocumentDidSave $ \msg -> do
|
||||
let doc = msg ^. J.params . J.textDocument . J.uri
|
||||
content = fromMaybe "?" $ msg ^. J.params . J.text
|
||||
validateSwarmCode (J.toNormalizedUri doc) Nothing content
|
||||
, notificationHandler J.STextDocumentDidOpen $ \msg -> do
|
||||
let doc = msg ^. J.params . J.textDocument . J.uri
|
||||
content = msg ^. J.params . J.textDocument . J.text
|
||||
validateSwarmCode (J.toNormalizedUri doc) Nothing content
|
||||
, notificationHandler J.STextDocumentDidChange $ \msg -> do
|
||||
let doc = msg ^. J.params . J.textDocument . J.uri . to J.toNormalizedUri
|
||||
, notificationHandler LSP.SMethod_TextDocumentDidSave $ \msg -> do
|
||||
let doc = msg ^. LSP.params . LSP.textDocument . LSP.uri
|
||||
content = fromMaybe "?" $ msg ^. LSP.params . LSP.text
|
||||
validateSwarmCode (LSP.toNormalizedUri doc) Nothing content
|
||||
, notificationHandler LSP.SMethod_TextDocumentDidOpen $ \msg -> do
|
||||
let doc = msg ^. LSP.params . LSP.textDocument . LSP.uri
|
||||
content = msg ^. LSP.params . LSP.textDocument . LSP.text
|
||||
validateSwarmCode (LSP.toNormalizedUri doc) Nothing content
|
||||
, notificationHandler LSP.SMethod_TextDocumentDidChange $ \msg -> do
|
||||
let doc = msg ^. LSP.params . LSP.textDocument . LSP.uri . to LSP.toNormalizedUri
|
||||
mdoc <- getVirtualFile doc
|
||||
case mdoc of
|
||||
Just vf@(VirtualFile _ version _rope) -> do
|
||||
validateSwarmCode doc (Just $ fromIntegral version) (virtualFileText vf)
|
||||
validateSwarmCode doc (Just (fromIntegral version)) (virtualFileText vf)
|
||||
_ -> debug $ "No virtual file found for: " <> from (show msg)
|
||||
, requestHandler J.STextDocumentHover $ \req responder -> do
|
||||
let doc = req ^. J.params . J.textDocument . J.uri . to J.toNormalizedUri
|
||||
pos = req ^. J.params . J.position
|
||||
, requestHandler LSP.SMethod_TextDocumentHover $ \req responder -> do
|
||||
let doc = req ^. LSP.params . LSP.textDocument . LSP.uri . to LSP.toNormalizedUri
|
||||
pos = req ^. LSP.params . LSP.position
|
||||
mdoc <- getVirtualFile doc
|
||||
let maybeHover = do
|
||||
vf <- mdoc
|
||||
(markdownText, maybeRange) <- H.showHoverInfo doc Nothing pos vf
|
||||
return $ Hover (J.HoverContents $ J.MarkupContent J.MkMarkdown markdownText) maybeRange
|
||||
responder $ Right maybeHover
|
||||
(markdownText, maybeRange) <- H.showHoverInfo doc pos vf
|
||||
return $ LSP.Hover (LSP.InL $ LSP.MarkupContent LSP.MarkupKind_Markdown markdownText) maybeRange
|
||||
responder . Right . LSP.maybeToNull $ maybeHover
|
||||
]
|
||||
|
@ -26,14 +26,15 @@ import Data.Map qualified as M
|
||||
import Data.Maybe (catMaybes, fromMaybe)
|
||||
import Data.Text (Text)
|
||||
import Data.Text qualified as T
|
||||
import Data.Text.Utf16.Rope qualified as R
|
||||
import Language.LSP.Types qualified as J
|
||||
import Data.Text.Lines qualified as R
|
||||
import Data.Text.Utf16.Rope.Mixed qualified as R
|
||||
import Language.LSP.Protocol.Types qualified as J
|
||||
import Language.LSP.VFS
|
||||
import Swarm.Language.Context as Ctx
|
||||
import Swarm.Language.Module (Module (..))
|
||||
import Swarm.Language.Parse (readTerm', unTuple)
|
||||
import Swarm.Language.Pipeline (ProcessedTerm (..), processParsedTerm)
|
||||
import Swarm.Language.Pretty (prettyText)
|
||||
import Swarm.Language.Pretty (prettyText, prettyTextLine)
|
||||
import Swarm.Language.Syntax
|
||||
import Swarm.Language.Typecheck (inferConst)
|
||||
import Swarm.Language.Types
|
||||
@ -53,11 +54,10 @@ lspToRopePosition (J.Position myLine myCol) =
|
||||
|
||||
showHoverInfo ::
|
||||
J.NormalizedUri ->
|
||||
J.TextDocumentVersion ->
|
||||
J.Position ->
|
||||
VirtualFile ->
|
||||
Maybe (Text, Maybe J.Range)
|
||||
showHoverInfo _ _ p vf@(VirtualFile _ _ myRope) =
|
||||
showHoverInfo _ p vf@(VirtualFile _ _ myRope) =
|
||||
case readTerm' content of
|
||||
Left _ -> Nothing
|
||||
Right Nothing -> Nothing
|
||||
@ -73,20 +73,19 @@ showHoverInfo _ _ p vf@(VirtualFile _ _ myRope) =
|
||||
where
|
||||
content = virtualFileText vf
|
||||
absolutePos =
|
||||
maybe 0 (R.length . fst) $
|
||||
R.splitAtPosition (lspToRopePosition p) myRope
|
||||
R.charLength . fst $ R.charSplitAtPosition (lspToRopePosition p) myRope
|
||||
|
||||
posToRange :: R.Rope -> SrcLoc -> Maybe J.Range
|
||||
posToRange myRope foundSloc = do
|
||||
(s, e) <- case foundSloc of
|
||||
SrcLoc s e -> Just (s, e)
|
||||
_ -> Nothing
|
||||
(startRope, _) <- R.splitAt (fromIntegral s) myRope
|
||||
(endRope, _) <- R.splitAt (fromIntegral e) myRope
|
||||
let (startRope, _) = R.charSplitAt (fromIntegral s) myRope
|
||||
(endRope, _) = R.charSplitAt (fromIntegral e) myRope
|
||||
return $
|
||||
J.Range
|
||||
(ropeToLspPosition $ R.lengthAsPosition startRope)
|
||||
(ropeToLspPosition $ R.lengthAsPosition endRope)
|
||||
(ropeToLspPosition $ R.charLengthAsPosition startRope)
|
||||
(ropeToLspPosition $ R.charLengthAsPosition endRope)
|
||||
|
||||
descend ::
|
||||
ExplainableType ty =>
|
||||
@ -170,7 +169,7 @@ instance ExplainableType () where
|
||||
eq _ _ = False
|
||||
|
||||
instance ExplainableType Polytype where
|
||||
prettyType = prettyText
|
||||
prettyType = prettyTextLine
|
||||
getInnerType = fmap $ \case
|
||||
(l :->: _r) -> l
|
||||
(TyCmd t) -> t
|
||||
|
@ -12,7 +12,7 @@ import Data.Set (Set)
|
||||
import Data.Set qualified as S
|
||||
import Data.Text (Text)
|
||||
import Data.Text qualified as T
|
||||
import Language.LSP.Types qualified as J
|
||||
import Language.LSP.Protocol.Types qualified as J
|
||||
import Swarm.Language.Parse qualified as P
|
||||
import Swarm.Language.Syntax
|
||||
import Swarm.Util qualified as U
|
||||
|
@ -3,6 +3,9 @@ extra-deps:
|
||||
- hsnoise-0.0.3@sha256:260b39175b8a3e3b1719ad3987b7d72a3fd7a0fa99be8639b91cf4dc3f1c8796,1476
|
||||
- simple-enumeration-0.2.1@sha256:8625b269c1650d3dd0e3887351c153049f4369853e0d525219e07480ea004b9f,1178
|
||||
- boolexpr-0.2@sha256:07f38a0206ad63c2c893e3c6271a2e45ea25ab4ef3a9e973edc746876f0ab9e8,853
|
||||
- unification-fd-0.11.2@sha256:b2e11811b703b63682076ae326bd856fd47caf7db881e9e5b896a6342bceb51f,3736
|
||||
- logict-0.8.0.0@sha256:3d5d87a1d892a4732351c9a0b022d2d07bbb14e60582967c3c703c6ed69de88a,1800
|
||||
- lsp-2.4.0.0
|
||||
- vty-6.1@sha256:524d124223c02373260ebc409ddd622fbe97cacd1ea0ee98476b5992bddbc4f3,3661
|
||||
- vty-crossplatform-0.4.0.0@sha256:50593f91ad16777d921138475a8d2784d538fd206addd30664c620278d6c8544,3172
|
||||
- vty-unix-0.2.0.0@sha256:2af3d0bdae3c4b7b7e567ee374efe32c7439fabdf9096465ce011a6c6736e9ae,2932
|
||||
@ -10,11 +13,7 @@ extra-deps:
|
||||
- brick-2.1.1
|
||||
- brick-list-skip-0.1.1.8
|
||||
- astar-0.3.0.0
|
||||
# We should update to lsp-2.0 and lsp-types-2.0 but it involves some
|
||||
# breaking changes; see https://github.com/swarm-game/swarm/issues/1350
|
||||
- lsp-1.6.0.0
|
||||
- lsp-types-1.6.0.0
|
||||
- megaparsec-9.6.1
|
||||
- AhoCorasick-0.0.4
|
||||
resolver: lts-21.25
|
||||
resolver: lts-22.10
|
||||
|
||||
|
@ -32,7 +32,7 @@ maintainer: byorgey@gmail.com
|
||||
bug-reports: https://github.com/swarm-game/swarm/issues
|
||||
copyright: Brent Yorgey 2021
|
||||
category: Game
|
||||
tested-with: GHC ==9.0.2 || ==9.2.7 || ==9.4.5 || ==9.6.2
|
||||
tested-with: GHC ==9.2.8 || ==9.4.8 || ==9.6.4
|
||||
extra-source-files: CHANGELOG.md
|
||||
example/*.sw
|
||||
editors/emacs/*.el
|
||||
@ -131,7 +131,7 @@ library swarm-lang
|
||||
containers,
|
||||
extra,
|
||||
lens,
|
||||
lsp >= 1.6 && < 1.7,
|
||||
lsp >= 2.4 && < 2.5,
|
||||
hashable,
|
||||
megaparsec,
|
||||
mtl,
|
||||
|
Loading…
Reference in New Issue
Block a user