Skip to content

Commit

Permalink
Better "evaluate" positions for code lens
Browse files Browse the repository at this point in the history
- Show "evaluate" above outline headers.
- Show "evaluate" above top-level cells which are divided by 2 empty lines mimic the behavior of a wl file opened in FrontEnd.
  • Loading branch information
kenkangxgwe committed Sep 19, 2022
1 parent 0b3f3f7 commit f6ab8d2
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 10 deletions.
36 changes: 30 additions & 6 deletions src/WolframLanguageServer/Server.wl
Original file line number Diff line number Diff line change
Expand Up @@ -1947,13 +1947,13 @@ handleRequest["textDocument/codeLens", msg_, state_] := With[
"character" -> 0
|>
|>,
"data" -> <|
"command" -> Command[<|
"title" -> "$(workflow) Evaluate File",
"command" -> "dap-wl.evaluate-file",
"arguments" -> {<|
"uri" -> uri
|>}
|>
|>]
|>],
Table[
CodeLens[<|
Expand All @@ -1964,16 +1964,40 @@ handleRequest["textDocument/codeLens", msg_, state_] := With[
(* // ReplaceKey[{"end", "line"} -> codeRange["start"]["line"]]
// ReplaceKey[{"end", "character"} -> 1] *)
),
"data" -> <|
"title" -> "$(play) Evaluate",
"command" -> Command[<|
"title" -> (
{codeRange["start"]["line"] + 1, codeRange["end"]["line"] + 1}
// Apply[If[Equal,
StringTemplate["$(play) Evaluate line `1`"],
StringTemplate["$(play) Evaluate line `1`~`2`"]
]] // Through
),
"command" -> "dap-wl.evaluate-range",
"arguments" -> {<|
"uri" -> uri,
"range" -> codeRange
|>}
|>
|>]
|>],
{codeRange, doc // FindTopLevelRanges}
],
Table[
CodeLens[<|
(* range can only span one line *)
"range" -> (
heading["range"]
// ReplaceKey["end" -> heading["range"]["start"]]
),
"command" -> Command[<|
"title" -> (heading["style"] // StringTemplate["$(play) Evaluate `1`"]),
"command" -> "dap-wl.evaluate-range",
"arguments" -> {<|
"uri" -> uri,
"range" -> heading["range"]
|>}
|>]
|>],
{codeRange, doc // FindAllCodeRanges}
{heading, doc // FindHeadings}
]
},
{}
Expand Down
50 changes: 46 additions & 4 deletions src/WolframLanguageServer/TextDocument.wl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ FindDocumentHighlight::usage = "FindDocumentHighlight[doc_TextDocument, pos_LspP
PositionValidQ::usage = "PositionValidQ[doc_TextDocument, pos_LspPosition] returns true if the pos is valid in the doc."
GetSymbolAtPosition::usage = "GetSymbolAtPosition[doc_TextDocument, pos_LspPosition] returns the symbol at the given location, otherwise Missing[\"NotFound\"]."
GetSymbolRangeAtPosition::usage = "GetSymbolRangeAtPosition[doc_TextDocument, pos_LspPosition] returns the range of the symbol at the given location, otherwise Missing[\"NotFound\"]."
FindTopLevelRanges::usage = "FindTopLevelRanges[doc_TextDocument] returns a list of LspRange which locate all the code ranges (cells) in the given doc."
FindAllCodeRanges::usage = "FindAllCodeRanges[doc_TextDocument] returns a list of LspRange which locate all the code ranges (cells) in the given doc."
FindHeadings::usage = "FindHeadings[doc_TextDocument] returns a list of Associations that includes range and style of all heading cells in the given doc."
GetCodeActionsInRange::usage = "GetCodeActionsInRange[doc_TextDocument, range_LspRange] returns a list of CodeAction related to specified range."
GetDocumentText::usage = "GetDocumentText[doc_TextDocument] returns the text of the whole doc except for the shebang line (if exists).\n\
GetDocumentText[doc_TextDocument, range_LspRange] returns the text of the doc at given range."
Expand Down Expand Up @@ -452,6 +454,17 @@ ScriptFileQ[uri_String] := URLParse[uri, "Path"] // Last // FileExtension // Equ
(*Code Range*)


getCodeCells[doc_TextDocument] := (
If[(doc["uri"] // MissingQ) || ($CodeCells[doc["uri"]] // MissingQ),
doc
// divideCells
// Last,
$CodeCells[doc["uri"]]
// Keys
// Part[#, All, 1]&
]
)

getCodeRanges[doc_TextDocument, _:All] := (
If[(doc["uri"] // MissingQ) || ($CodeRange[doc["uri"]] // MissingQ),
doc
Expand Down Expand Up @@ -602,17 +615,18 @@ rangeToSyntaxTree[doc_TextDocument, ranges:{{_Integer, _Integer}...}] := With[
AssociateTo[$CodeRange[uri], newRules // KeyTake[addRanges]];
$CodeRange
// Lookup[uri]
// Lookup[newRules // Keys]
// KeyTake[newRules // Keys]
]
]
// Replace[err:Except[{KeyValuePattern[{"cst" -> _List, "ast" -> _List}]...}] :> (
// Replace[err:Except[Association[({_Integer, _Integer} -> KeyValuePattern[{"cst" -> _List, "ast" -> _List}])...]] :> (
LogError[{"rangeToSyntaxTree: ", err}]; {}
)]
]


rangeToAst = rangeToSyntaxTree /* Map[Lookup["ast"]] /* Catenate
rangeToCst = rangeToSyntaxTree /* Map[Lookup["cst"]] /* Catenate
rangeToAst = rangeToSyntaxTree /* Values /* Map[Lookup["ast"]] /* Catenate
rangeToCst = rangeToSyntaxTree /* Values /* Map[Lookup["cst"]] /* Catenate
rangeToTopLevelRanges = rangeToSyntaxTree /* Keys


rangeToCode[doc_TextDocument, {startLine_Integer, endLine_Integer}] := (
Expand Down Expand Up @@ -772,6 +786,34 @@ GetSymbolRangeAtPosition[doc_TextDocument, pos_LspPosition] := With[
]


FindTopLevelRanges[doc_TextDocument] := (
doc
// getCodeCells
// Map[
rangeToTopLevelRanges[doc, #]&
/* (ranges \[Function] (
SequenceCases[ranges, {{_, prevEnd_}, {start_, _}} /; (prevEnd + 2 < start) :> start, Overlaps -> True]
// {# // Prepend[ranges // First // First], (# - 3) // Append[ranges // Last // Last]}&
// Transpose
))
]
// Catenate
// Map[ToLspRange[doc, #]&]
)


FindHeadings[doc_TextDocument] := (
doc
// getCell
// Cases[#, CellNode[KeyValuePattern[{"style" -> style_?HeadingQ, "range" -> range_}]] :> (
<|
"style" -> style,
"range" -> (ToLspRange[doc, range])
|>
), {1, -3}]& // LogDebug
)


FindAllCodeRanges[doc_TextDocument] := (
doc
// getCodeRanges
Expand Down

0 comments on commit f6ab8d2

Please sign in to comment.