Files
Python-With-Gtk-Template/plugins/code/ui/lsp_manager/AGENTS.md
itdominator 220a8c2743 Moved plugins and add loaded file filtering
- Moved prettify_json and lsp_completer plugins to sub categories
- Add filter_out_loaded_files to prevent opening already-loaded files
- Refactor code events into single events module
- Fix signal blocking during file load operations
- Include READONLY state in source view lifecycle handling
2026-03-08 00:46:21 -06:00

3.8 KiB

AGENTS.md - LSP Manager Plugin

Project Overview

This is a Newton editor plugin providing LSP (Language Server Protocol) code completion via WebSocket. Written in Python using GTK3/GtkSource.

Build/Lint/Test Commands

Running Tests

# Run all websocket library tests
python -m unittest discover -s libs/websocket/tests

# Run a single test file
python -m unittest libs.websocket.tests.test_websocket

# Run a single test
python -m unittest libs.websocket.tests.test_websocket.WebSocketTest.test_default_timeout

Environment

  • Python 3.x
  • GTK 3.0 with GtkSource 4
  • No build system (pyproject.toml/setup.py) - direct execution

Code Style Guidelines

Import Organization

Always use three-section ordering:

# Python imports
import json
from os import path

# Lib imports
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('GtkSource', '4')
from gi.repository import Gtk

# Application imports
from libs.event_factory import Event_Factory
from plugins.plugin_types import PluginCode
from .lsp_manager import LSPManager

Formatting

  • 4-space indentation
  • Line length: ~100 chars (soft limit)
  • No trailing whitespace
  • Use f-strings for string formatting: f"{variable} text"

Naming Conventions

  • Classes: PascalCase (LSPManager, ProviderResponseCache)
  • Methods/functions: snake_case (create_client, load_lsp_servers_config)
  • Private members: leading underscore (_setup_styling, _init_params)
  • Constants: SCREAMING_SNAKE_CASE

Type Hints

  • Use Python 3.x type hints
  • Common types: str, int, dict, list, bool
  • For untyped parameters, use any:
    def execute(view: any, *args, **kwargs)
    

Error Handling

  • Use try/except blocks with specific exception types
  • Use logger.error() for logging errors with context
  • Return early on failure conditions:
    if not lang_id: return
    if not lang_id in self.servers_config: return
    

Class Structure

class LSPManager(Gtk.Dialog):
    def __init__(self):
        super(LSPManager, self).__init__()
        self._setup_styling()
        self._setup_signals()
        self._subscribe_to_events()
        self._load_widgets()

    def _setup_styling(self):
        ...

    def _setup_signals(self):
        ...

GTK Patterns

  • Use gi.require_version() before importing GTK modules
  • Use GLib.idle_add() for deferred UI updates
  • Connect signals with widget.connect("signal_name", handler)

Empty Methods

Use ellipsis for stub/placeholder methods:

def _subscribe_to_events(self):
    ...

Logging

  • Import logger from application (available globally)
  • Use logger.debug(), logger.error() for appropriate levels
  • Include context in error messages:
    logger.error( f"LSP Controller: {_LSP_INIT_CONFIG}\n\t\t{repr(e)}" )
    

Inheritance Patterns

class Provider(GObject.GObject, GtkSource.CompletionProvider):
    __gtype_name__ = 'LSPProvider'

    def do_get_name(self):
        return "LSP Code Completion"

Testing Patterns (websocket library)

  • Use unittest.TestCase
  • Skip tests with decorators:
    @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
    def test_remote(self):
        ...
    
  • Environment variables for test configuration:
    • TEST_WITH_INTERNET=1 - enable internet tests
    • LOCAL_WS_SERVER_PORT=9999 - enable local server tests

File Organization

  • Main plugin: plugin.py
  • Core logic: lsp_manager.py, provider.py, provider_response_cache.py
  • Controllers: controllers/ directory
  • Config: configs/ directory
  • Embedded libs: libs/websocket/

Anti-Patterns to Avoid

  • Avoid bare except: - use specific exceptions
  • Avoid global mutable state where possible
  • Don't commit secrets or credentials