456 lines
16 KiB
Python
456 lines
16 KiB
Python
import os
|
|
from functools import wraps
|
|
from typing import Dict, List
|
|
|
|
import requests
|
|
|
|
BASE_SERVER_URL = os.environ.get("DEVCHAT_IDE_SERVICE_URL", "http://localhost:3000")
|
|
|
|
|
|
def rpc_call(f):
|
|
@wraps(f)
|
|
def wrapper(*args, **kwargs):
|
|
if os.environ.get("DEVCHAT_IDE_SERVICE_URL", "") == "":
|
|
# maybe in a test, user don't want to mock services functions
|
|
return
|
|
|
|
try:
|
|
function_name = f.__name__
|
|
url = f"{BASE_SERVER_URL}/{function_name}"
|
|
|
|
data = dict(zip(f.__code__.co_varnames, args))
|
|
data.update(kwargs)
|
|
headers = {"Content-Type": "application/json"}
|
|
|
|
response = requests.post(url, json=data, headers=headers)
|
|
|
|
if response.status_code != 200:
|
|
raise Exception(f"Server error: {response.status_code}")
|
|
|
|
response_data = response.json()
|
|
if "error" in response_data:
|
|
raise Exception(f"Server returned an error: {response_data['error']}")
|
|
return response_data["result"]
|
|
except ConnectionError as err:
|
|
# TODO
|
|
raise err
|
|
|
|
return wrapper
|
|
|
|
|
|
@rpc_call
|
|
def get_lsp_bridge_port() -> int:
|
|
"""
|
|
Retrieves the port number on which the LSP (Language Server Protocol) bridge is running.
|
|
|
|
Returns:
|
|
int: The port number of the LSP bridge.
|
|
|
|
Note:
|
|
This function is expected to interact with an environment variable or a service
|
|
that provides the LSP bridge port. The actual implementation details are not
|
|
provided here and should be handled appropriately in the production code.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def install_python_env(command_name: str, requirements_file: str) -> str:
|
|
"""
|
|
Installs a Python environment with the specified requirements.
|
|
|
|
:param command_name: The name of the command associated with the environment.
|
|
:param requirements_file: The path to the requirements file.
|
|
:return: A string representing the Python command to activate the environment
|
|
or an empty string if unsuccessful.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def update_slash_commands():
|
|
"""
|
|
Updates the slash commands for the DevChat application.
|
|
|
|
:return: A boolean indicating if the update was successful.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def open_folder(folder: str):
|
|
"""
|
|
Opens a folder in the IDE.
|
|
|
|
:param folder: The path to the folder to open.
|
|
:return: A boolean indicating if the folder was successfully opened.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def ide_language() -> str:
|
|
"""
|
|
Retrieves the current language setting for the DevChat application.
|
|
|
|
:return: A string representing the language code (e.g., 'en' for English,
|
|
'zh' for Simplified Chinese).
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def log_info(message: str):
|
|
"""
|
|
Logs an informational message to the DevChat application's logger.
|
|
|
|
:param message: The message to log.
|
|
:return: A boolean indicating if the logging was successful.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def log_warn(message: str):
|
|
"""
|
|
Logs a warning message to the DevChat application's logger.
|
|
|
|
:param message: The message to log.
|
|
:return: A boolean indicating if the logging was successful.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def log_error(message: str):
|
|
"""
|
|
Logs an error message to the DevChat application's logger.
|
|
|
|
:param message: The message to log.
|
|
:return: A boolean indicating if the logging was successful.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def visible_lines() -> Dict:
|
|
"""
|
|
Fetches the currently visible lines in the active text editor.
|
|
|
|
This function simulates an RPC call to an interface that retrieves the visible text range
|
|
from a code editor (such as Visual Studio Code). The actual implementation of the RPC call
|
|
is not provided here.
|
|
|
|
Returns:
|
|
A dictionary with the following keys:
|
|
- "filePath" (str): The file path of the document in the active text editor.
|
|
- "visibleText" (str): The text that is currently visible in the active text editor.
|
|
- "visibleRange" (list): A list containing two integers, the start and end line numbers
|
|
of the visible text range in the active text editor.
|
|
|
|
If there is no active text editor, the function returns:
|
|
- "filePath" as an empty string.
|
|
- "visibleText" as an empty string.
|
|
- "visibleRange" as a list with two elements, both set to -1.
|
|
|
|
Example return value:
|
|
{
|
|
"filePath": "/path/to/file.py",
|
|
"visibleText": "def foo():\n return 'bar'\n",
|
|
"visibleRange": [10, 12]
|
|
}
|
|
|
|
or, if there is no active editor:
|
|
|
|
{
|
|
"filePath": "",
|
|
"visibleText": "",
|
|
"visibleRange": [-1, -1]
|
|
}
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def selected_lines() -> Dict:
|
|
"""
|
|
Retrieves the currently selected lines from the active text editor.
|
|
|
|
Returns:
|
|
A dictionary with the following keys:
|
|
- "filePath": str - The file path of the current document.
|
|
- "selectedText": str - The text that is currently selected.
|
|
- "selectedRange": list - A list containing the start line, start character,
|
|
end line, and end character of the selection.
|
|
The line numbers are 0-based.
|
|
|
|
If no text editor is active or no text is selected, the function returns:
|
|
- "filePath": ""
|
|
- "selectedText": ""
|
|
- "selectedRange": [-1, -1, -1, -1]
|
|
|
|
Note:
|
|
This function is a wrapper for an RPC interface and assumes that the
|
|
underlying RPC call is properly implemented and handles the communication
|
|
with the text editor (e.g., Visual Studio Code).
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def document_symbols(abspath: str) -> List:
|
|
"""
|
|
Retrieves a list of symbols defined in a document at the given absolute path.
|
|
|
|
Parameters:
|
|
- abspath (str): The absolute path to the document for which symbols are requested.
|
|
|
|
Returns:
|
|
- list: A list of symbol dictionaries. Each symbol dictionary contains the following keys:
|
|
- 'name': The name of the symbol (str).
|
|
- 'kind': The kind of the symbol (int), corresponding to the SymbolKind enum in the
|
|
language server protocol.
|
|
- 'detail': Optional detail for the symbol (str), such as the type of a function.
|
|
- 'range': A dictionary representing the range of the symbol with keys 'start_line',
|
|
'start_col', 'end_line', 'end_col' (integers).
|
|
- 'selectionRange': A dictionary representing the selection range of the symbol with keys
|
|
'start_line', 'start_col', 'end_line', 'end_col' (integers).
|
|
- 'children': An optional list of child symbol dictionaries (recursively structured like
|
|
the parent symbol dictionary).
|
|
- 'location': (Only for SymbolInformation) A dictionary with a 'uri' key for the document
|
|
URI (str) and a 'range' key as defined above.
|
|
- 'containerName': (Only for SymbolInformation) The name of the container that holds the
|
|
symbol (str), such as the name of a class or a namespace.
|
|
|
|
Example:
|
|
[
|
|
{
|
|
'name': 'MyClass',
|
|
'kind': 5, # Corresponds to SymbolKind.Class
|
|
'detail': 'class MyClass',
|
|
'range': {'start_line': 1, 'start_col': 0, 'end_line': 10, 'end_col': 1},
|
|
'selectionRange': {'start_line': 1, 'start_col': 6, 'end_line': 1, 'end_col': 13},
|
|
'children': [
|
|
{
|
|
'name': '__init__',
|
|
'kind': 11, # Corresponds to SymbolKind.Constructor
|
|
'detail': 'def __init__(self, param1)',
|
|
'range': {'start_line': 2, 'start_col': 4, 'end_line': 4, 'end_col': 5},
|
|
'selectionRange':
|
|
{'start_line': 2, 'start_col': 8, 'end_line': 2, 'end_col': 16},
|
|
'children': []
|
|
}
|
|
]
|
|
},
|
|
{
|
|
'name': 'my_function',
|
|
'kind': 12, # Corresponds to SymbolKind.Function
|
|
'location': {
|
|
'uri': 'file:///path/to/file.py',
|
|
'range': {'start_line': 12, 'start_col': 0, 'end_line': 15, 'end_col': 1}
|
|
},
|
|
'containerName': 'MyModule'
|
|
}
|
|
]
|
|
|
|
Note:
|
|
This function is a placeholder for the actual implementation that would interact with an RPC
|
|
(Remote Procedure Call) interface to retrieve document symbols. The 'kind' values correspond to
|
|
the SymbolKind enum defined in the language server protocol and must be mapped to appropriate
|
|
values in the actual implementation.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def workspace_symbols(query: str) -> List:
|
|
"""
|
|
This function is a Python interface for the workspace_symbols RPC endpoint.
|
|
It retrieves symbols from a workspace based on a given query string.
|
|
|
|
:param query: A string representing the query to search for symbols in the workspace.
|
|
:return: A list of symbol information objects. Each object typically contains
|
|
information like the symbol's name, location, kind (e.g., class, function),
|
|
and container name. The exact structure of these objects can be found
|
|
by referring to the document_symbols interface definition.
|
|
|
|
Note: The actual implementation of querying the symbols and converting them to
|
|
plain objects is not included in this interface definition.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def find_definition(abspath: str, line: int, col: int) -> List:
|
|
"""
|
|
This function is a Python interface for the RPC 'find_definition' method. It returns
|
|
a list of locations or location links where the definition of a symbol is found in the code.
|
|
|
|
Args:
|
|
abspath (str): The absolute path to the file in which to find the definition.
|
|
line (int): The line number (0-indexed) where the symbol is located.
|
|
col (int): The column number (0-indexed) where the symbol is located.
|
|
|
|
Returns:
|
|
list: A list of dictionaries, each representing either a vscode.Location or
|
|
vscode.LocationLink object. Each dictionary has one of the following
|
|
structures:
|
|
|
|
vscode.Location representation:
|
|
{
|
|
'uri': str, # The URI of the file containing the definition.
|
|
'range': {
|
|
'start_line': int, # The start line number of the definition range (0-indexed).
|
|
'start_col': int, # The start column number of the definition range (0-indexed).
|
|
'end_line': int, # The end line number of the definition range (0-indexed).
|
|
'end_col': int, # The end column number of the definition range (0-indexed).
|
|
}
|
|
}
|
|
|
|
vscode.LocationLink representation:
|
|
{
|
|
'originSelectionRange': Optional[dict],
|
|
# The range of the symbol being searched for (if available).
|
|
'targetUri': str, # The URI of the target file containing the definition.
|
|
'targetRange': {
|
|
'start_line': int, # The start line number of the target range (0-indexed).
|
|
'start_col': int, # The start column number of the target range (0-indexed).
|
|
'end_line': int, # The end line number of the target range (0-indexed).
|
|
'end_col': int, # The end column number of the target range (0-indexed).
|
|
},
|
|
'targetSelectionRange': {
|
|
'start_line': int,
|
|
# The start line number of the target selection range (0-indexed).
|
|
'start_col': int,
|
|
# The start column number of the target selection range (0-indexed).
|
|
'end_line': int, # The end line number of the target selection range (0-indexed).
|
|
'end_col': int, # The end column number of the target selection range (0-indexed).
|
|
}
|
|
}
|
|
|
|
Example return value:
|
|
[
|
|
# vscode.Location example
|
|
{
|
|
'uri': 'file:///path/to/definition.py',
|
|
'range': {
|
|
'start_line': 10,
|
|
'start_col': 4,
|
|
'end_line': 10,
|
|
'end_col': 20,
|
|
}
|
|
},
|
|
# vscode.LocationLink example
|
|
{
|
|
'originSelectionRange': {
|
|
'start_line': 8,
|
|
'start_col': 12,
|
|
'end_line': 8,
|
|
'end_col': 16,
|
|
},
|
|
'targetUri': 'file:///path/to/definition.py',
|
|
'targetRange': {
|
|
'start_line': 10,
|
|
'start_col': 4,
|
|
'end_line': 10,
|
|
'end_col': 20,
|
|
},
|
|
'targetSelectionRange': {
|
|
'start_line': 10,
|
|
'start_col': 4,
|
|
'end_line': 10,
|
|
'end_col': 20,
|
|
}
|
|
}
|
|
]
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def find_type_definition(abspath: str, line: int, col: int) -> dict:
|
|
"""
|
|
This function is a Python interface for the find_type_definition RPC call.
|
|
It is designed to find the type definition of a symbol at a given position in a file.
|
|
|
|
:param abspath: The absolute path to the file containing the symbol.
|
|
:param line: The line number (0-indexed) where the symbol is located.
|
|
:param col: The column number (0-indexed) where the symbol is located.
|
|
|
|
:return: A dictionary containing the type definition information.
|
|
The structure of the returned dictionary should be similar to the one
|
|
returned by the find_definition RPC interface.
|
|
|
|
Note: The actual implementation of the communication with the RPC server is not included.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def find_declaration(abspath: str, line: int, col: int) -> dict:
|
|
"""
|
|
This function is a Python interface for the find_declaration RPC call.
|
|
|
|
:param abspath: The absolute path to the file in which the declaration is to be found.
|
|
:param line: The line number (0-indexed) where the declaration search will start.
|
|
:param col: The column number (0-indexed) where the declaration search will start.
|
|
:return: A dictionary containing the declaration information. For the structure of the
|
|
return value, refer to the documentation of the find_definition RPC interface.
|
|
|
|
Note: The actual implementation of the RPC call is not provided here. This function is
|
|
only a stub
|
|
representing the interface.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def find_implementation(abspath: str, line: int, col: int) -> dict:
|
|
"""
|
|
This function is a Python interface for the find_implementation RPC method.
|
|
It is intended to find the implementation of a symbol in the code.
|
|
|
|
:param abspath: The absolute path to the file containing the symbol.
|
|
:param line: The line number (0-indexed) where the symbol is located.
|
|
:param col: The column number (0-indexed) where the symbol is located.
|
|
|
|
:return: A dictionary containing the result of the find_implementation operation.
|
|
The structure of the returned dictionary should follow the format
|
|
specified by the find_definition interface's return value.
|
|
|
|
Note: The actual implementation of this function is not provided here.
|
|
This is only the function signature with parameter and return type annotations.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def find_reference(abspath: str, line: int, col: int) -> dict:
|
|
"""
|
|
Provides a Python interface for the find_reference RPC endpoint.
|
|
|
|
:param abspath: The absolute path to the file containing the symbol.
|
|
:param line: The line number in the file where the symbol is located.
|
|
:param col: The column number in the file where the symbol is located.
|
|
:return: A dictionary containing the references found. The structure of the return value
|
|
is analogous to the one provided by the find_definition interface.
|
|
|
|
Note: This function is a stub and does not contain actual implementation.
|
|
"""
|
|
pass
|
|
|
|
|
|
@rpc_call
|
|
def diff_apply(filepath: str, content: str) -> bool:
|
|
"""
|
|
Opens a diff view to visually see the specific changes in the code.
|
|
|
|
Parameters:
|
|
filepath (str): The path to the file for which the diff will be applied.
|
|
content (str): The modified content to be compared with the original file content.
|
|
|
|
Returns:
|
|
bool: True if the diff view was successfully opened, False otherwise.
|
|
"""
|
|
pass
|