CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-lsp-server

Python Language Server Protocol implementation providing code intelligence features for Python development

Pending
Overview
Eval results
Files

utilities-helpers.mddocs/

Utilities and Helpers

Comprehensive utility functions for LSP operations, text manipulation, URI handling, Python-specific operations, and code formatting. Provides essential helper functions for plugin development and server operations.

Capabilities

Decorators and Function Control

Utility decorators for controlling function execution timing and frequency.

def debounce(interval_s, keyed_by=None):
    """
    Debounce function calls until interval_s seconds have passed.
    
    Parameters:
    - interval_s: float, debounce interval in seconds
    - keyed_by: str, parameter name to key debouncing by
    
    Returns:
    decorator: Function decorator
    """

def throttle(seconds=1):
    """
    Throttle function calls to at most once per interval.
    
    Parameters:
    - seconds: float, minimum interval between calls
    
    Returns:
    decorator: Function decorator
    """

File and Path Utilities

Functions for finding and manipulating file paths.

def find_parents(root, path, names):
    """
    Find files matching names in parent directories.
    
    Parameters:
    - root: str, root directory to stop searching at
    - path: str, starting path for search
    - names: list, file/directory names to find
    
    Returns:
    list: Found file paths
    """

def path_to_dot_name(path):
    """
    Convert filesystem path to Python dot notation.
    
    Parameters:
    - path: str, filesystem path to Python file
    
    Returns:
    str: Python module path in dot notation
    """

def match_uri_to_workspace(uri, workspaces):
    """
    Match URI to appropriate workspace.
    
    Parameters:
    - uri: str, document URI
    - workspaces: list, available Workspace instances
    
    Returns:
    Workspace: Best matching workspace
    """

Data Manipulation Utilities

Functions for working with data structures and strings.

def list_to_string(value):
    """
    Convert list to comma-separated string.
    
    Parameters:
    - value: list or str, value to convert
    
    Returns:
    str: Comma-separated string
    """

def merge_dicts(dict_a, dict_b):
    """
    Recursively merge dictionaries.
    
    Parameters:
    - dict_a: dict, base dictionary
    - dict_b: dict, dictionary to merge in
    
    Returns:
    dict: Merged dictionary
    """

Text and Content Formatting

Functions for formatting text content for LSP clients.

def escape_plain_text(contents):
    """
    Escape text for plain text display.
    
    Parameters:
    - contents: str, text to escape
    
    Returns:
    str: Escaped text
    """

def escape_markdown(contents):
    """
    Escape text for Markdown display.
    
    Parameters:
    - contents: str, text to escape
    
    Returns:  
    str: Escaped Markdown text
    """

def wrap_signature(signature):
    """
    Wrap function signature in code block.
    
    Parameters:
    - signature: str, function signature
    
    Returns:
    str: Wrapped signature
    """

def choose_markup_kind(client_supported_markup_kinds):
    """
    Choose best supported markup kind for client.
    
    Parameters:
    - client_supported_markup_kinds: list, client-supported markup kinds
    
    Returns:
    str: Best markup kind to use
    """

def format_docstring(contents, markup_kind, signatures=None, signature_config=None):
    """
    Format docstring as LSP MarkupContent.
    
    Parameters:
    - contents: str, docstring content
    - markup_kind: str, markup kind ("plaintext" or "markdown")
    - signatures: list, optional function signatures
    - signature_config: dict, signature formatting options
    
    Returns:
    dict: LSP MarkupContent with 'kind' and 'value'
    """

Position and Text Manipulation

Functions for working with LSP positions and text coordinates.

def clip_column(column, lines, line_number):
    """
    Normalize column position within line bounds.
    
    Parameters:
    - column: int, column position
    - lines: list, document lines
    - line_number: int, line number (0-based)
    
    Returns:
    int: Clipped column position
    """

def position_to_jedi_linecolumn(document, position):
    """
    Convert LSP position to Jedi line/column format.
    
    Parameters:
    - document: Document, document instance
    - position: dict, LSP position with 'line' and 'character'
    
    Returns:
    tuple: (line, column) for Jedi (1-based line, 0-based column)
    """

def get_eol_chars(text):
    """
    Get end-of-line characters used in text.
    
    Parameters:
    - text: str, text to analyze
    
    Returns:
    str: EOL characters ("\r\n", "\r", or "\n") or None if none found
    """

def format_signature(signature, config, signature_formatter):
    """
    Format function signature using ruff or black formatter.
    
    Parameters:
    - signature: str, function signature to format
    - config: dict, formatting configuration with line_length
    - signature_formatter: str, formatter name ("ruff" or "black")
    
    Returns:
    str: Formatted signature
    """

def convert_signatures_to_markdown(signatures, config):
    """
    Convert list of signatures to markdown code block.
    
    Parameters:
    - signatures: list, function signatures
    - config: dict, formatting configuration
    
    Returns:
    str: Markdown-formatted signatures
    """

Process Utilities

Functions for process management and monitoring.

def is_process_alive(pid):
    """
    Check if process is still alive.
    
    Parameters:
    - pid: int, process ID
    
    Returns:
    bool: True if process is alive
    """

URI Utilities

Functions for working with URIs and filesystem paths.

def urlparse(uri):
    """
    Parse and decode URI parts.
    
    Parameters:
    - uri: str, URI to parse
    
    Returns:
    tuple: Parsed URI components (scheme, netloc, path, params, query, fragment)
    """

def urlunparse(parts):
    """
    Unparse and encode URI parts.
    
    Parameters:
    - parts: tuple, URI components
    
    Returns:
    str: Assembled URI
    """

def to_fs_path(uri):
    """
    Convert URI to filesystem path.
    
    Parameters:
    - uri: str, file URI
    
    Returns:
    str: Filesystem path
    """

def from_fs_path(path):
    """
    Convert filesystem path to URI.
    
    Parameters:
    - path: str, filesystem path
    
    Returns:
    str: File URI
    """

def uri_with(uri, **parts):
    """
    Return URI with specified parts replaced.
    
    Parameters:
    - uri: str, base URI
    - **parts: URI components to replace
    
    Returns:
    str: Modified URI
    """

Text Edit Utilities

Functions for manipulating and applying text edits.

def get_well_formatted_range(lsp_range):
    """
    Normalize LSP range format.
    
    Parameters:
    - lsp_range: dict, LSP range with 'start' and 'end'
    
    Returns:
    dict: Normalized range
    """

def get_well_formatted_edit(text_edit):
    """
    Normalize LSP text edit format.
    
    Parameters:
    - text_edit: dict, LSP TextEdit
    
    Returns:
    dict: Normalized text edit
    """

def compare_text_edits(a, b):
    """
    Compare text edits for sorting.
    
    Parameters:
    - a: dict, first text edit
    - b: dict, second text edit
    
    Returns:
    int: Comparison result (-1, 0, 1)
    """

def merge_sort_text_edits(text_edits):
    """
    Sort text edits by position.
    
    Parameters:
    - text_edits: list, text edits to sort
    
    Returns:
    list: Sorted text edits
    """

def apply_text_edits(doc, text_edits):
    """
    Apply text edits to document.
    
    Parameters:
    - doc: Document, document to edit
    - text_edits: list, text edits to apply
    
    Returns:
    str: Document text after applying edits
    """

Code Formatters

Classes for code formatting with different tools.

class Formatter:
    """Base class for code formatters."""
    
    @property
    def is_installed(self):
        """
        Check if formatter is available.
        
        Returns:
        bool: True if formatter is installed
        """
    
    def format(self, code, line_length=79):
        """
        Format code.
        
        Parameters:
        - code: str, code to format
        - line_length: int, maximum line length
        
        Returns:
        str: Formatted code
        """

class RuffFormatter(Formatter):
    """Ruff code formatter."""

class BlackFormatter(Formatter):
    """Black code formatter."""

Constants

Utility constants used throughout the server.

JEDI_VERSION = "0.19.1"  # Jedi library version

# End-of-line character sequences in preference order
EOL_CHARS = ["\r\n", "\r", "\n"]

# Regex for matching EOL characters  
EOL_REGEX = re.compile(r"(\r\n|\r|\n)")

# Markup kinds supported by server
SERVER_SUPPORTED_MARKUP_KINDS = {"plaintext", "markdown"}

# Available formatters
formatters = {
    "ruff": RuffFormatter(),
    "black": BlackFormatter()
}

Exceptions

Custom exceptions for text editing operations.

class OverLappingTextEditException(Exception):
    """Raised when text edits overlap and cannot be applied."""

Usage Examples

Debouncing and Throttling

from pylsp._utils import debounce, throttle

# Debounce linting to avoid excessive calls  
@debounce(0.5, keyed_by='document')
def run_linting(document):
    # Linting logic here
    pass

# Throttle progress updates
@throttle(seconds=1)
def update_progress(message):
    # Progress update logic
    pass

Path and File Operations

from pylsp._utils import find_parents, path_to_dot_name

# Find configuration files
config_files = find_parents(
    "/project", 
    "/project/src/module.py",
    ["setup.cfg", "pyproject.toml"]
)

# Convert path to module name
module_name = path_to_dot_name("/project/src/utils/helper.py")
print(module_name)  # "src.utils.helper"

Text Formatting

from pylsp._utils import (
    format_docstring, escape_markdown, wrap_signature,
    format_signature, convert_signatures_to_markdown
)

# Format docstring for hover
docstring = format_docstring(
    "Function description\n\nArgs:\n    x: parameter",
    "markdown",
    signatures=["def func(x: int) -> str"]
)

# Escape markdown content
escaped = escape_markdown("Text with *special* chars")

# Wrap signature
wrapped = wrap_signature("def example(param: str) -> int")

# Format signature with black or ruff
config = {"line_length": 88}
formatted_sig = format_signature("def func(a,b,c):", config, "black")

# Convert multiple signatures to markdown
sigs = ["def func1(x: int) -> str", "def func2(y: float) -> bool"]
markdown_sigs = convert_signatures_to_markdown(sigs, config)

Position Conversion

from pylsp._utils import position_to_jedi_linecolumn, clip_column

# Convert LSP position to Jedi format
lsp_pos = {"line": 5, "character": 10}
jedi_line, jedi_col = position_to_jedi_linecolumn(document, lsp_pos)

# Clip column to line bounds
clipped_col = clip_column(100, document.lines, 5)  # Won't exceed line length

URI Handling

from pylsp.uris import to_fs_path, from_fs_path, uri_with

# Convert between URIs and paths
path = to_fs_path("file:///project/src/main.py")  # "/project/src/main.py"
uri = from_fs_path("/project/src/main.py")        # "file:///project/src/main.py"

# Modify URI components
new_uri = uri_with("file:///project/old.py", path="/project/new.py")

Text Edits

from pylsp.text_edit import apply_text_edits, merge_sort_text_edits

# Apply text edits to document
edits = [
    {
        "range": {
            "start": {"line": 0, "character": 0},
            "end": {"line": 0, "character": 5}
        },
        "newText": "print"
    }
]

# Sort edits and apply
sorted_edits = merge_sort_text_edits(edits)
new_text = apply_text_edits(document, sorted_edits)

Code Formatting

from pylsp._utils import formatters

# Use available formatters
black_formatter = formatters["black"]
if black_formatter.is_installed:
    formatted_code = black_formatter.format("def f():pass", line_length=88)

ruff_formatter = formatters["ruff"]  
if ruff_formatter.is_installed:
    formatted_code = ruff_formatter.format(code, line_length=100)

Data Manipulation

from pylsp._utils import merge_dicts, list_to_string

# Merge configuration dictionaries
base_config = {"plugins": {"pyflakes": {"enabled": True}}}
user_config = {"plugins": {"pyflakes": {"ignore": ["E203"]}}}
merged = merge_dicts(base_config, user_config)

# Convert list to string
error_codes = ["E203", "W503", "E501"]
ignore_string = list_to_string(error_codes)  # "E203,W503,E501"

Install with Tessl CLI

npx tessl i tessl/pypi-python-lsp-server

docs

configuration-system.md

index.md

plugin-development.md

server-management.md

utilities-helpers.md

workspace-management.md

tile.json