diff --git a/.editorconfig b/.editorconfig index 4421c37..180db47 100644 --- a/.editorconfig +++ b/.editorconfig @@ -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 diff --git a/newt-vscode-lsp/src/lsp.ts b/newt-vscode-lsp/src/lsp.ts index e2b3ecf..4e227b7 100644 --- a/newt-vscode-lsp/src/lsp.ts +++ b/newt-vscode-lsp/src/lsp.ts @@ -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, }, })); diff --git a/newt-vscode-lsp/src/newt.d.ts b/newt-vscode-lsp/src/newt.d.ts index 7ae6b8b..eab337e 100644 --- a/newt-vscode-lsp/src/newt.d.ts +++ b/newt-vscode-lsp/src/newt.d.ts @@ -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; + diff --git a/src/LSP.newt b/src/LSP.newt index ac24670..75b0769 100644 --- a/src/LSP.newt +++ b/src/LSP.newt @@ -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 diff --git a/src/Lib/Derive.newt b/src/Lib/Derive.newt index 399ef7a..b1a7421 100644 --- a/src/Lib/Derive.newt +++ b/src/Lib/Derive.newt @@ -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. diff --git a/src/Lib/ProcessDecl.newt b/src/Lib/ProcessDecl.newt index b64c851..6128eba 100644 --- a/src/Lib/ProcessDecl.newt +++ b/src/Lib/ProcessDecl.newt @@ -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