<filename>jedi_language_server/pygls_utils.py
"""Utilities to work with pygls.

Helper functions that simplify working with pygls
"""


from typing import Optional

from pygls.lsp.types import Position, Range
from pygls.workspace import Document


def char_before_cursor(
    document: Document, position: Position, default: str = ""
) -> str:
    """Get the character directly before the cursor."""
    try:
        return document.lines[position.line][position.character - 1]
    except IndexError:
        return default


def char_after_cursor(
    document: Document, position: Position, default: str = ""
) -> str:
    """Get the character directly before the cursor."""
    try:
        return document.lines[position.line][position.character]
    except IndexError:
        return default


def current_word_range(
    document: Document, position: Position
) -> Optional[Range]:
    """Get the range of the word under the cursor."""
    word = document.word_at_position(position)
    word_len = len(word)
    line: str = document.lines[position.line]
    start = 0
    for _ in range(1000):  # prevent infinite hanging in case we hit edge case
        begin = line.find(word, start)
        if begin == -1:
            return None
        end = begin + word_len
        if begin <= position.character <= end:
            return Range(
                start=Position(line=position.line, character=begin),
                end=Position(line=position.line, character=end),
            )
        start = end
    return None

<filename>jedi_language_server/pygls_utils.py
"""Utilities to work with pygls.

Helper functions that simplify working with pygls
"""


from typing import Optional

from pygls.lsp.types import Position, Range
from pygls.workspace import Document


def char_before_cursor(
    document: Document, position: Position, default: str = ""
) -> str:
    """Get the character directly before the cursor."""
    try:
        return document.lines[position.line][position.character - 1]
    except IndexError:
        return default


def char_after_cursor(
    document: Document, position: Position, default: str = ""
) -> str:
    """Get the character directly before the cursor."""
    try:
        return document.lines[position.line][position.character]
    except IndexError:
        return default


def current_word_range(
    document: Document, position: Position
) -> Optional[Range]:
    """Get the range of the word under the cursor."""
    word = document.word_at_position(position)
    word_len = len(word)
    line: str = document.lines[position.line]
    start = 0
    for _ in range(1000):  # prevent infinite hanging in case we hit edge case
        begin = line.find(word, start)
        if begin == -1:
            return None
        end = begin + word_len
        if begin <= position.character <= end:
            return Range(
                start=Position(line=position.line, character=begin),
                end=Position(line=position.line, character=end),
            )
        start = end
    return None

Utilities to work with pygls.  Helper functions that simplify working with pygls Get the character directly before the cursor. Get the character directly before the cursor. Get the range of the word under the cursor. # prevent infinite hanging in case we hit edge case