add hover function
This commit is contained in:
@@ -17,10 +17,15 @@ KIND_MAP = {
|
||||
|
||||
class StandardCompletionItems:
|
||||
def __init__(self):
|
||||
self.__json_data: dict = self.__load_json()
|
||||
self.__tcl_keyword_list = self.__load_tcl_keyword()
|
||||
self.__nx_procs = self.__load_nx_procs()
|
||||
self.__nx_variables = self.__load_nx_variables()
|
||||
|
||||
@property
|
||||
def json_data(self):
|
||||
return self.__json_data
|
||||
|
||||
@property
|
||||
def tcl_keyword_list(self):
|
||||
return self.__tcl_keyword_list
|
||||
@@ -33,11 +38,15 @@ class StandardCompletionItems:
|
||||
def nx_variables(self):
|
||||
return self.__nx_variables
|
||||
|
||||
def __load_tcl_keyword(self) -> list[lsp.CompletionItem]:
|
||||
def __load_json(self) -> dict:
|
||||
with open(
|
||||
pathlib.Path(__file__).parent.joinpath("completion_list.json"), "r"
|
||||
) as f:
|
||||
data = json.load(f)
|
||||
return data
|
||||
|
||||
def __load_tcl_keyword(self) -> list[lsp.CompletionItem]:
|
||||
data = self.json_data
|
||||
|
||||
items = []
|
||||
for i in data.get("tcl", []):
|
||||
@@ -50,10 +59,7 @@ class StandardCompletionItems:
|
||||
return items
|
||||
|
||||
def __load_nx_variables(self):
|
||||
with open(
|
||||
pathlib.Path(__file__).parent.joinpath("completion_list.json"), "r"
|
||||
) as f:
|
||||
data = json.load(f)
|
||||
data = self.json_data
|
||||
items = []
|
||||
for var in data.get("mom_variables", []):
|
||||
label = var.get("label", "")
|
||||
@@ -85,11 +91,7 @@ class StandardCompletionItems:
|
||||
return items
|
||||
|
||||
def __load_nx_procs(self) -> list[lsp.CompletionItem]:
|
||||
with open(
|
||||
pathlib.Path(__file__).parent.joinpath("completion_list.json"), "r"
|
||||
) as f:
|
||||
data = json.load(f)
|
||||
|
||||
data = self.json_data
|
||||
items = []
|
||||
for proc in data.get("MOM_procs", []):
|
||||
label = proc.get("label", "")
|
||||
|
||||
@@ -13,6 +13,7 @@ import sys
|
||||
import sysconfig
|
||||
import traceback
|
||||
from typing import Any, Optional, Sequence
|
||||
import re
|
||||
|
||||
|
||||
# **********************************************************
|
||||
@@ -106,6 +107,72 @@ def on_completion(params: lsp.CompletionParams) -> list[lsp.CompletionItem]:
|
||||
return lsp.CompletionList(is_incomplete=False, items=items)
|
||||
|
||||
|
||||
@LSP_SERVER.feature(lsp.TEXT_DOCUMENT_HOVER)
|
||||
def hover(params: lsp.HoverParams) -> lsp.Hover:
|
||||
pos = params.position
|
||||
document_uri = params.text_document.uri
|
||||
document = LSP_SERVER.workspace.get_text_document(document_uri)
|
||||
col = params.position.character
|
||||
|
||||
try:
|
||||
line = document.lines[pos.line]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
for m in re.finditer(r"\b\w+\b", line):
|
||||
if m.start() <= col <= m.end():
|
||||
token = m.group(0)
|
||||
break
|
||||
else:
|
||||
return None
|
||||
|
||||
command = token
|
||||
data = standard_items.json_data
|
||||
|
||||
all_items = data.get("MOM_procs", []) + data.get("mom_variables", [])
|
||||
|
||||
match = next((item for item in all_items if item["label"] == command), None)
|
||||
if not match:
|
||||
return None
|
||||
|
||||
if not match.get("kind") == "function":
|
||||
return None
|
||||
|
||||
label = match.get("label", "")
|
||||
|
||||
parameters = match.get("parameters", [])
|
||||
param_lines = (
|
||||
"\n".join(f"- `{p['name']}`: {p['desc']}" for p in parameters) or "_None_"
|
||||
)
|
||||
|
||||
example_data = match.get("example", [])
|
||||
example_md = "\n".join(f"{line}" for line in example_data)
|
||||
|
||||
returns_data = match.get("returns", ["None"])
|
||||
returns_md = "\n".join(f"- {line}" for line in returns_data)
|
||||
|
||||
doc_md = f"""\
|
||||
### 📘 {label}
|
||||
|
||||
**Purpose**
|
||||
{match.get("description", "No description available.")}
|
||||
|
||||
**Format**
|
||||
`{match.get("format", label)}`
|
||||
|
||||
**Parameters**
|
||||
{param_lines}
|
||||
|
||||
**Return value**
|
||||
{returns_md}
|
||||
|
||||
**Example**
|
||||
```tcl
|
||||
{example_md}"""
|
||||
|
||||
return lsp.Hover(lsp.MarkupContent(kind=lsp.MarkupKind.Markdown, value=doc_md))
|
||||
|
||||
|
||||
# **********************************************************
|
||||
# Linting features end here
|
||||
# **********************************************************
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
// Lark grammar for Tcl scripts with proc definitions and optional args
|
||||
|
||||
%import common.CNAME -> IDENTIFIER
|
||||
%import common.INT -> INT
|
||||
%import common.FLOAT -> FLOAT
|
||||
%import common.ESCAPED_STRING -> STRING_LITERAL
|
||||
%import common.WS_INLINE -> WS_INLINE
|
||||
%import common.NEWLINE -> NEWLINE
|
||||
|
||||
// Ignore only spaces, tabs; treat newlines as separators
|
||||
%ignore WS_INLINE
|
||||
// Tcl comments
|
||||
%ignore COMMENT
|
||||
|
||||
start: script
|
||||
script: statement*
|
||||
|
||||
statement: command (";" | NEWLINE)?
|
||||
|
||||
command: set_command
|
||||
| proc_command
|
||||
| r_break
|
||||
| r_continue
|
||||
|
||||
proc_command: "proc" IDENTIFIER "{" argument_list "}" body_block
|
||||
|
||||
argument_list: [argument (argument)*]
|
||||
|
||||
argument: IDENTIFIER -> required_arg
|
||||
| "{" IDENTIFIER (value)? "}" -> optional_arg
|
||||
|
||||
|
||||
|
||||
value: STRING_LITERAL
|
||||
| FLOAT
|
||||
| INT
|
||||
| IDENTIFIER
|
||||
| list
|
||||
|
||||
list: LBRACE [value (WS_INLINE value)*] RBRACE
|
||||
|
||||
body_block: LBRACE body_content RBRACE -> body
|
||||
body_content: ( /[^{}]+/ | body_block )* // allow nested braces
|
||||
|
||||
set_command: "set" IDENTIFIER index? value
|
||||
// Index: parentheses with comma-separated items
|
||||
index: "(" index_item ("," index_item)* ")"
|
||||
index_item: INT -> index_int
|
||||
| STRING_VAR -> index_string
|
||||
| "$" IDENTIFIER index? -> nested_index
|
||||
|
||||
|
||||
r_break: "break"
|
||||
r_continue: "continue"
|
||||
|
||||
LBRACE: "{"
|
||||
RBRACE: "}"
|
||||
|
||||
STRING_VAR: /(?:[^"\\]|\\.)+/
|
||||
COMMENT: /#[^\r\n]*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user