LSP document symbols

This commit is contained in:
2026-03-07 21:33:12 -08:00
parent 90e36d8faf
commit 92ced8dcd2
6 changed files with 75 additions and 33 deletions

View File

@@ -4,5 +4,8 @@ end_of_line = lf
insert_final_newline = true
indent_size = 2
indent_style = space
trim_trailing_whitespace = true
insert_final_newline = true
[Makefile]
indent_style = tab

View File

@@ -5,7 +5,7 @@
* vscode LSP server module.
*/
import { LSP_checkFile, LSP_updateFile, LSP_hoverInfo, LSP_codeActionInfo } from './newt.js'
import { LSP_checkFile, LSP_updateFile, LSP_hoverInfo, LSP_codeActionInfo, LSP_docSymbols } from './newt.js'
import {
createConnection,
@@ -118,12 +118,20 @@ connection.onCodeAction(({textDocument, range}) => {
return actions
})
connection.onDocumentSymbol((params) => {
const uri = params.textDocument.uri;
let symbols = LSP_docSymbols(uri);
console.log("docs got", symbols)
return symbols;
})
connection.onInitialize((_params: InitializeParams): InitializeResult => ({
capabilities: {
textDocumentSync: TextDocumentSyncKind.Incremental,
hoverProvider: true,
definitionProvider: true,
codeActionProvider: true,
documentSymbolProvider: true,
},
}));

View File

@@ -1,4 +1,4 @@
import { CodeAction, Diagnostic, Location } from "vscode-languageserver";
import { CodeAction, Diagnostic, DocumentSymbol, Location } from "vscode-languageserver";
export function LSP_updateFile(name: string, content: string): (eta: any) => any;
export function LSP_checkFile(name: string): Diagnostic[];
@@ -8,3 +8,5 @@ interface HoverResult {
}
export function LSP_hoverInfo(name: string, row: number, col: number): HoverResult|boolean|null;
export function LSP_codeActionInfo(name: string, row: number, col: number): CodeAction[]|null;
export function LSP_docSymbols(name: string): DocumentSymbol[] | null;

View File

@@ -29,7 +29,6 @@ pfunc js_castObj : Array (String × JSObject) → JSObject := `(data) => {
return rval
}`
-- need case split
jsonToJObject : Json JSObject
jsonToJObject (JsonInt x) = js_castInt x
jsonToJObject (JsonNull) = js_null
@@ -173,6 +172,36 @@ errorToDiag err =
-- These shouldn't escape
errorToDiag (Postpone fc qn msg) = errorToDiag $ E fc "Postpone \{show qn} \{msg}"
getSymbols : M (List Json)
getSymbols = do
top <- getTop
let defs = listValues top.currentMod.modDefs
putStrLn "scan \{show $ length' defs} defs"
go Nil defs
where
getKind : Def Int
getKind Axiom = 12
getKind (TCon _ _) = 23
getKind (DCon _ _ _ _) = 10
getKind (Fn _) = 12
getKind (PrimTCon _) = 23
getKind (PrimFn _ _ _) = 12
getKind (PrimOp _) = 12
-- highlight where hx!
go : List Json List TopEntry M (List Json)
go acc Nil = pure $ reverse acc
go acc ((MkEntry fc name type def eflags) :: rest) =
let range = fcToRange fc in
let kind = getKind def in
let diag = JsonObj
$ ("name" , JsonStr (name.baseName))
:: ("range", range)
:: ("selectionRange", range)
:: ("kind", JsonInt kind)
-- detail
:: Nil
in go (diag :: acc) rest
getInfos : M (List Json)
getInfos = do
@@ -225,6 +254,24 @@ checkFile fn = unsafePerformIO $ do
modifyIORef state $ [ topContext := top ]
pure $ jsonToJObject $ JsonArray json
docSymbols : String JSObject
docSymbols fn = unsafePerformIO $ do
let (base, modName) = decomposeName fn
st <- readIORef state
putStrLn "Symbols for \{fn}"
if st.baseDir /= base
then resetState base
else pure MkUnit
repo <- lspFileSource
(Right (top, json)) <- (do
mod <- processModule emptyFC repo Nil modName
modifyTop [ currentMod := mod; ops := mod.modOps ]
getSymbols).runM st.topContext
| Left err => do
pure $ jsonToJObject $ JsonNull
modifyIORef state $ [ topContext := top ]
pure $ jsonToJObject $ JsonArray json
compileJS : String JSObject
compileJS fn = unsafePerformIO $ do
let (base, modName) = decomposeName fn
@@ -246,4 +293,4 @@ compileJS fn = unsafePerformIO $ do
#export updateFile checkFile hoverInfo codeActionInfo compileJS
#export updateFile checkFile hoverInfo codeActionInfo compileJS docSymbols

View File

@@ -127,25 +127,3 @@ deriveShow fc name = do
pure (left, Just right)
-- -- A description would be nice.
-- deriveShow : FC → QName → M Raw
-- deriveShow fc qn = do
-- top <- getTop
-- case lookup qn top : Maybe TopEntry of
-- Nothing => error {Raw} fc "Can't find \{show qn} in derive Show"
-- -- I want case split too... I need to tie the editor into the repl.
-- (Just (MkEntry fc name type (TCon _ conNames) eflags) ) => ?
-- (Just (MkEntry fc name type (Axiom) eflags) ) => ?
-- (Just (MkEntry fc name type (DCon _ _ _ _) eflags) ) => ?
-- (Just (MkEntry fc name type (Fn _) eflags) ) => ?
-- (Just (MkEntry fc name type (PrimTCon _) eflags) ) => ?
-- (Just (MkEntry fc name type (PrimFn _ _ _) eflags) ) => ?
-- (Just (MkEntry fc name type (PrimOp _) eflags) ) => ?
-- error fc "TODO"
-- HasFC as example of user-defined derivation (when we get to that)
-- SetFC would be nice, too.

View File

@@ -28,15 +28,19 @@ dumpEnv ctx =
go : List String -> Int -> List (Val × String × Val) -> List String -> M (List String)
go _ _ Nil acc = pure acc
go names k ((v, n, ty) :: xs) acc = if isVar k v
-- TODO - use Doc and add <+/> as appropriate to printing
then do
-- don't show the = bit for now. Lean folds it.
go names k ((v, n, ty) :: xs) acc = do
ty' <- quote ctx.lvl ty
go names (1 + k) xs (" \{n} : \{render 90 $ pprint names ty'}":: acc)
else do
v' <- quote ctx.lvl v
ty' <- quote ctx.lvl ty
go names (1 + k) xs (" \{n} = \{render 90 $ pprint names v'} : \{render 90 $ pprint names ty'}":: acc)
-- go names k ((v, n, ty) :: xs) acc = if isVar k v
-- then do
-- ty' <- quote ctx.lvl ty
-- go names (1 + k) xs (" \{n} : \{render 90 $ pprint names ty'}":: acc)
-- else do
-- v' <- quote ctx.lvl v
-- ty' <- quote ctx.lvl ty
-- go names (1 + k) xs (" \{n} = \{render 90 $ pprint names v'} : \{render 90 $ pprint names ty'}":: acc)
logMetas : List MetaEntry -> M Unit