refactor(command-system): replace legacy CommandSystem with SourceViewCommandSystem
- Remove CommandSystem and CommandSystemMixin - Introduce SourceViewCommandSystem and shared libs/command_system - Update CommandsController to use new command system - Adjust package exports accordingly feat(lsp): clean up and normalize LSP configurations - Fix invalid JSON in Godot LSP config (processId -> null, formatting) - Remove embedded jedi-language-server config from main Python LSP config - Add separate jedi-lsp-server-config.json refactor(markers): rename move_word -> move_along_word for clarity - Update all usages in MarkerManager chore: minor formatting and whitespace fixes
This commit is contained in:
@@ -7,46 +7,46 @@
|
|||||||
"socket": "ws://127.0.0.1:9999/gdscript",
|
"socket": "ws://127.0.0.1:9999/gdscript",
|
||||||
"socket-two": "ws://127.0.0.1:9999/?name=gdscript",
|
"socket-two": "ws://127.0.0.1:9999/?name=gdscript",
|
||||||
"initialization-options": {
|
"initialization-options": {
|
||||||
"processId": ,
|
"processId": null,
|
||||||
"clientInfo": {
|
"clientInfo": {
|
||||||
"name": "Godot",
|
"name": "Godot",
|
||||||
"version": "4.4"
|
"version": "4.4"
|
||||||
},
|
|
||||||
"rootUri": "file://{workspace.folder}",
|
|
||||||
"capabilities": {
|
|
||||||
"workspace": {
|
|
||||||
"applyEdit": true,
|
|
||||||
"workspaceEdit": {
|
|
||||||
"documentChanges": true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"textDocument": {
|
"rootUri": "file://{workspace.folder}",
|
||||||
"synchronization": {
|
"capabilities": {
|
||||||
"dynamicRegistration": true,
|
"workspace": {
|
||||||
"willSave": false,
|
"applyEdit": true,
|
||||||
"didSave": true,
|
"workspaceEdit": {
|
||||||
"willSaveWaitUntil": false
|
"documentChanges": true
|
||||||
},
|
|
||||||
"completion": {
|
|
||||||
"dynamicRegistration": true,
|
|
||||||
"completionItem": {
|
|
||||||
"snippetSupport": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hover": {
|
"textDocument": {
|
||||||
"dynamicRegistration": true
|
"synchronization": {
|
||||||
},
|
"dynamicRegistration": true,
|
||||||
"definition": {
|
"willSave": false,
|
||||||
"dynamicRegistration": true
|
"didSave": true,
|
||||||
},
|
"willSaveWaitUntil": false
|
||||||
"references": {
|
},
|
||||||
"dynamicRegistration": true
|
"completion": {
|
||||||
},
|
"dynamicRegistration": true,
|
||||||
"documentSymbol": {
|
"completionItem": {
|
||||||
"dynamicRegistration": true
|
"snippetSupport": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hover": {
|
||||||
|
"dynamicRegistration": true
|
||||||
|
},
|
||||||
|
"definition": {
|
||||||
|
"dynamicRegistration": true
|
||||||
|
},
|
||||||
|
"references": {
|
||||||
|
"dynamicRegistration": true
|
||||||
|
},
|
||||||
|
"documentSymbol": {
|
||||||
|
"dynamicRegistration": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
"trace": "off"
|
||||||
"trace": "off"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
{
|
||||||
|
"info": "https://github.com/python-lsp/python-lsp-server",
|
||||||
|
"command": "lsp-ws-proxy -- pylsp",
|
||||||
|
"alt-command": "pylsp",
|
||||||
|
"alt-command2": "lsp-ws-proxy --listen 4114 -- pylsp",
|
||||||
|
"alt-command3": "pylsp --ws --port 4114",
|
||||||
|
"socket": "ws://127.0.0.1:9999/python",
|
||||||
|
"socket-two": "ws://127.0.0.1:9999/?name=pylsp",
|
||||||
|
"initialization-options": {
|
||||||
|
"pylsp": {
|
||||||
|
"rope": {
|
||||||
|
"ropeFolder": "{user.home}/.config/newton/lsps/ropeproject"
|
||||||
|
},
|
||||||
|
"plugins": {
|
||||||
|
"ruff": {
|
||||||
|
"enabled": true,
|
||||||
|
"extendSelect": ["I"],
|
||||||
|
"lineLength": 80
|
||||||
|
},
|
||||||
|
"pycodestyle": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"pyflakes": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"pylint": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"mccabe": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"pylsp_rope": {
|
||||||
|
"rename": false
|
||||||
|
},
|
||||||
|
"rope_rename": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"rope_autoimport": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"rope_completion": {
|
||||||
|
"enabled": false,
|
||||||
|
"eager": false
|
||||||
|
},
|
||||||
|
"jedi_rename": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"jedi_completion": {
|
||||||
|
"enabled": true,
|
||||||
|
"include_class_objects": true,
|
||||||
|
"include_function_objects": true,
|
||||||
|
"fuzzy": false
|
||||||
|
},
|
||||||
|
"jedi": {
|
||||||
|
"root_dir": "file://{workspace.folder}",
|
||||||
|
"extra_paths": [
|
||||||
|
"{user.home}/Portable_Apps/py-venvs/pylsp-venv/venv/lib/python3.10/site-packages"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"python - jedi-language-server": {
|
||||||
|
"hidden": true,
|
||||||
|
"info": "https://pypi.org/project/jedi-language-server/",
|
||||||
|
"command": "jedi-language-server",
|
||||||
|
"alt-command": "lsp-ws-proxy --listen 3030 -- jedi-language-server",
|
||||||
|
"socket": "ws://127.0.0.1:9999/python",
|
||||||
|
"socket-two": "ws://127.0.0.1:9999/?name=jedi-language-server",
|
||||||
|
"initialization-options": {
|
||||||
|
"jediSettings": {
|
||||||
|
"autoImportModules": [],
|
||||||
|
"caseInsensitiveCompletion": true,
|
||||||
|
"debug": false
|
||||||
|
},
|
||||||
|
"completion": {
|
||||||
|
"disableSnippets": false,
|
||||||
|
"resolveEagerly": false,
|
||||||
|
"ignorePatterns": []
|
||||||
|
},
|
||||||
|
"markupKindPreferred": "markdown",
|
||||||
|
"workspace": {
|
||||||
|
"extraPaths": [
|
||||||
|
"{user.home}/Portable_Apps/py-venvs/pylsp-venv/venv/lib/python3.10/site-packages"
|
||||||
|
],
|
||||||
|
"environmentPath": "{user.home}/Portable_Apps/py-venvs/gtk-apps-venv/venv/bin/python",
|
||||||
|
"symbols": {
|
||||||
|
"ignoreFolders": [
|
||||||
|
".nox",
|
||||||
|
".tox",
|
||||||
|
".venv",
|
||||||
|
"__pycache__",
|
||||||
|
"venv"
|
||||||
|
],
|
||||||
|
"maxSymbols": 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -60,41 +60,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"python - jedi-language-server": {
|
|
||||||
"hidden": true,
|
|
||||||
"info": "https://pypi.org/project/jedi-language-server/",
|
|
||||||
"command": "jedi-language-server",
|
|
||||||
"alt-command": "lsp-ws-proxy --listen 3030 -- jedi-language-server",
|
|
||||||
"socket": "ws://127.0.0.1:9999/python",
|
|
||||||
"socket-two": "ws://127.0.0.1:9999/?name=jedi-language-server",
|
|
||||||
"initialization-options": {
|
|
||||||
"jediSettings": {
|
|
||||||
"autoImportModules": [],
|
|
||||||
"caseInsensitiveCompletion": true,
|
|
||||||
"debug": false
|
|
||||||
},
|
|
||||||
"completion": {
|
|
||||||
"disableSnippets": false,
|
|
||||||
"resolveEagerly": false,
|
|
||||||
"ignorePatterns": []
|
|
||||||
},
|
|
||||||
"markupKindPreferred": "markdown",
|
|
||||||
"workspace": {
|
|
||||||
"extraPaths": [
|
|
||||||
"{user.home}/Portable_Apps/py-venvs/pylsp-venv/venv/lib/python3.10/site-packages"
|
|
||||||
],
|
|
||||||
"environmentPath": "{user.home}/Portable_Apps/py-venvs/gtk-apps-venv/venv/bin/python",
|
|
||||||
"symbols": {
|
|
||||||
"ignoreFolders": [
|
|
||||||
".nox",
|
|
||||||
".tox",
|
|
||||||
".venv",
|
|
||||||
"__pycache__",
|
|
||||||
"venv"
|
|
||||||
],
|
|
||||||
"maxSymbols": 20
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -2,4 +2,4 @@
|
|||||||
Code Command System Package
|
Code Command System Package
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .command_system import CommandSystem
|
from .source_view_command_system import SourceViewCommandSystem
|
||||||
|
|||||||
@@ -1,120 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from libs.event_factory import Event_Factory, Code_Event_Types
|
|
||||||
|
|
||||||
from ..mixins.command_system_mixin import CommandSystemMixin
|
|
||||||
from ..source_view import SourceView
|
|
||||||
|
|
||||||
from . import commands
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CommandSystem(CommandSystemMixin):
|
|
||||||
def __init__(self):
|
|
||||||
super(CommandSystem, self).__init__()
|
|
||||||
|
|
||||||
self.data: list = ()
|
|
||||||
|
|
||||||
|
|
||||||
def set_data(self, *args, **kwargs):
|
|
||||||
self.data = (args, kwargs)
|
|
||||||
|
|
||||||
def exec(self, command: str) -> any:
|
|
||||||
if not hasattr(commands, command): return
|
|
||||||
method = getattr(commands, command)
|
|
||||||
|
|
||||||
args, kwargs = self.data
|
|
||||||
return method.execute(*args, **kwargs)
|
|
||||||
|
|
||||||
def exec_with_args(self, command: str, *args, **kwargs) -> any:
|
|
||||||
if not hasattr(commands, command): return
|
|
||||||
|
|
||||||
method = getattr(commands, command)
|
|
||||||
return method.execute(*args, **kwargs)
|
|
||||||
|
|
||||||
def add_command(self, command_name: str, command: callable):
|
|
||||||
setattr(commands, command_name, command)
|
|
||||||
|
|
||||||
def remove_command(self, command_name: str, command: callable):
|
|
||||||
if hasattr(commands, command_name):
|
|
||||||
delattr(commands, command_name)
|
|
||||||
|
|
||||||
|
|
||||||
def emit(self, event: Code_Event_Types.CodeEvent):
|
|
||||||
""" Monkey patch 'emit' from command controller... """
|
|
||||||
...
|
|
||||||
|
|
||||||
def emit_to(self, controller: str, event: Code_Event_Types.CodeEvent):
|
|
||||||
""" Monkey patch 'emit_to' from command controller... """
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# def filter_out_loaded_files(self, uris: list[str]):
|
|
||||||
# event = Event_Factory.create_event(
|
|
||||||
# "filter_out_loaded_files",
|
|
||||||
# uris = uris
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# self.emit_to("files", event)
|
|
||||||
#
|
|
||||||
# return event.response
|
|
||||||
#
|
|
||||||
# def set_info_labels(self, data: tuple[str]):
|
|
||||||
# event = Event_Factory.create_event(
|
|
||||||
# "set_info_labels",
|
|
||||||
# info = data
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# self.emit_to("plugins", event)
|
|
||||||
#
|
|
||||||
# def get_file(self, view: SourceView):
|
|
||||||
# event = Event_Factory.create_event(
|
|
||||||
# "get_file",
|
|
||||||
# view = view,
|
|
||||||
# buffer = view.get_buffer()
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# self.emit_to("files", event)
|
|
||||||
#
|
|
||||||
# return event.response
|
|
||||||
#
|
|
||||||
# def get_swap_file(self, view: SourceView):
|
|
||||||
# event = Event_Factory.create_event(
|
|
||||||
# "get_swap_file",
|
|
||||||
# view = view,
|
|
||||||
# buffer = view.get_buffer()
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# self.emit_to("files", event)
|
|
||||||
#
|
|
||||||
# return event.response
|
|
||||||
#
|
|
||||||
# def new_file(self, view: SourceView):
|
|
||||||
# event = Event_Factory.create_event("add_new_file", view = view)
|
|
||||||
#
|
|
||||||
# self.emit_to("files", event)
|
|
||||||
#
|
|
||||||
# return event.response
|
|
||||||
#
|
|
||||||
# def remove_file(self, view: SourceView):
|
|
||||||
# event = Event_Factory.create_event(
|
|
||||||
# "remove_file",
|
|
||||||
# view = view,
|
|
||||||
# buffer = view.get_buffer()
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# self.emit_to("files", event)
|
|
||||||
#
|
|
||||||
# return event.response
|
|
||||||
#
|
|
||||||
# def request_completion(self, view: SourceView):
|
|
||||||
# event = Event_Factory.create_event(
|
|
||||||
# "request_completion",
|
|
||||||
# view = view,
|
|
||||||
# buffer = view.get_buffer()
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# self.emit_to("completion", event)
|
|
||||||
@@ -4,12 +4,19 @@
|
|||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from libs.event_factory import Event_Factory, Code_Event_Types
|
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||||
|
from libs.command_system import CommandSystem
|
||||||
|
|
||||||
from ..source_view import SourceView
|
from ..source_view import SourceView
|
||||||
|
|
||||||
|
|
||||||
|
from . import commands
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SourceViewCommandSystem(CommandSystem):
|
||||||
|
def __init__(self):
|
||||||
|
super(SourceViewCommandSystem, self).__init__(commands)
|
||||||
|
|
||||||
class CommandSystemMixin:
|
|
||||||
def toggle_plugins_ui(self):
|
def toggle_plugins_ui(self):
|
||||||
event = Event_Factory.create_event( "toggle_plugins_ui" )
|
event = Event_Factory.create_event( "toggle_plugins_ui" )
|
||||||
|
|
||||||
@@ -81,3 +88,11 @@ class CommandSystemMixin:
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.emit_to("completion", event)
|
self.emit_to("completion", event)
|
||||||
|
|
||||||
|
def emit(self, event: Code_Event_Types.CodeEvent):
|
||||||
|
""" Monkey patch 'emit' from command controller... """
|
||||||
|
...
|
||||||
|
|
||||||
|
def emit_to(self, controller: str, event: Code_Event_Types.CodeEvent):
|
||||||
|
""" Monkey patch 'emit_to' from command controller... """
|
||||||
|
...
|
||||||
@@ -7,7 +7,7 @@ from libs.controllers.controller_base import ControllerBase
|
|||||||
|
|
||||||
from libs.event_factory import Code_Event_Types
|
from libs.event_factory import Code_Event_Types
|
||||||
|
|
||||||
from ..command_system import CommandSystem
|
from ..command_system import SourceViewCommandSystem
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ class CommandsController(ControllerBase, list):
|
|||||||
event.response = self.get_new_command_system()
|
event.response = self.get_new_command_system()
|
||||||
|
|
||||||
def get_new_command_system(self):
|
def get_new_command_system(self):
|
||||||
command_system = CommandSystem()
|
command_system = SourceViewCommandSystem()
|
||||||
command_system.emit = self.emit
|
command_system.emit = self.emit
|
||||||
command_system.emit_to = self.emit_to
|
command_system.emit_to = self.emit_to
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ class MarkerManager(MarkSupportMixin):
|
|||||||
buffer.move_mark(start_mark, collapse_itr)
|
buffer.move_mark(start_mark, collapse_itr)
|
||||||
buffer.move_mark(end_mark, collapse_itr)
|
buffer.move_mark(end_mark, collapse_itr)
|
||||||
|
|
||||||
def move_word(self, itr: Gtk.TextIter, count: int):
|
def move_along_word(self, itr: Gtk.TextIter, count: int):
|
||||||
def not_is_word(ch: str):
|
def not_is_word(ch: str):
|
||||||
return not is_word(ch)
|
return not is_word(ch)
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ class MarkerManager(MarkSupportMixin):
|
|||||||
if mode == "char":
|
if mode == "char":
|
||||||
itr_.forward_char() if is_forward else itr_.backward_char()
|
itr_.forward_char() if is_forward else itr_.backward_char()
|
||||||
elif mode == "word":
|
elif mode == "word":
|
||||||
self.move_word(itr_, 1 if is_forward else -1)
|
self.move_along_word(itr_, 1 if is_forward else -1)
|
||||||
elif mode == "line":
|
elif mode == "line":
|
||||||
line = itr_.get_line()
|
line = itr_.get_line()
|
||||||
offset = itr_.get_line_offset()
|
offset = itr_.get_line_offset()
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ class SourceViewsMultiInsertState(SourceViewsBaseState):
|
|||||||
buffer.insert(start_itr, text, -1)
|
buffer.insert(start_itr, text, -1)
|
||||||
|
|
||||||
self.marker_manager.apply_to_marks(buffer, replace_word)
|
self.marker_manager.apply_to_marks(buffer, replace_word)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def move_cursor(
|
def move_cursor(
|
||||||
|
|||||||
50
src/libs/command_system.py
Normal file
50
src/libs/command_system.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# Python imports
|
||||||
|
import types
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
from .event_factory import Event_Factory, Code_Event_Types
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CommandSystem:
|
||||||
|
def __init__(self, commands: dict | types.ModuleType):
|
||||||
|
super(CommandSystem, self).__init__()
|
||||||
|
|
||||||
|
self.commands: dict | types.ModuleType = commands
|
||||||
|
self.data: tuple = ()
|
||||||
|
|
||||||
|
|
||||||
|
def set_data(self, *args, **kwargs):
|
||||||
|
self.data = (args, kwargs)
|
||||||
|
|
||||||
|
def exec(self, command: str) -> any:
|
||||||
|
"""
|
||||||
|
The 'exec' method passes the default 'self.data' to commands where custom args are not needed.
|
||||||
|
Ex: The 'code' widget has many internally created commands that
|
||||||
|
only need 'source_view' and so 'set_data' is called to set that.
|
||||||
|
"""
|
||||||
|
if not hasattr(self.commands, command): return
|
||||||
|
method = getattr(self.commands, command)
|
||||||
|
|
||||||
|
args, kwargs = self.data
|
||||||
|
return method.execute(*args, **kwargs)
|
||||||
|
|
||||||
|
def exec_with_args(self, command: str, *args, **kwargs) -> any:
|
||||||
|
"""
|
||||||
|
The 'exec_with_args' method passes custom args with the understanding
|
||||||
|
that the recipient has proper method signature to accept it- whether
|
||||||
|
*args or **kwargs or something else entirely.
|
||||||
|
"""
|
||||||
|
if not hasattr(self.commands, command): return
|
||||||
|
|
||||||
|
method = getattr(self.commands, command)
|
||||||
|
return method.execute(*args, **kwargs)
|
||||||
|
|
||||||
|
def add_command(self, command_name: str, command: callable):
|
||||||
|
setattr(self.commands, command_name, command)
|
||||||
|
|
||||||
|
def remove_command(self, command_name: str, command: callable):
|
||||||
|
if hasattr(self.commands, command_name):
|
||||||
|
delattr(self.commands, command_name)
|
||||||
Reference in New Issue
Block a user