sublimelsp / LSP

Client implementation of the Language Server Protocol for Sublime Text
https://lsp.sublimetext.io/
MIT License
1.65k stars 182 forks source link

zls: sublime doesn't seem to trigger a completion request on each keystroke, instead rely on fuzzy search #2288

Open ryuukk opened 1 year ago

ryuukk commented 1 year ago

I have reported the issue here: https://github.com/zigtools/zls/issues/1247 it contains all the information related to the bug including a video showing the bug in action

I'm not sure how to debug that, and i suspect it is a client problem rather than a server one since VSCode works properly

I will provide more information once i'm back home, don't hesitate to ask me for questions/information, or suggestions how to debug this, thanks

Environment (please complete the following information):

rchl commented 1 year ago

Without seeing the LSP logs I will guess that it's a duplicate of https://github.com/sublimelsp/LSP/issues/976 which is caused by an upstream issue https://github.com/sublimehq/sublime_text/issues/3990

rchl commented 1 year ago

https://github.com/sublimehq/sublime_text/issues/4855 might be even more relevant (it was fixed and then regressed again).

rwols commented 1 year ago

I am interested in:

ryuukk commented 1 year ago

The .sublime-syntax or .tmLanguage you're using for highlighging zig code

https://packagecontrol.io/packages/Zig%20Language

The output of view.settings().get("auto_complete_triggers") in the ST console

[{'characters': '<', 'selector': 'text.html, text.xml'}, {'rhs_empty': True, 'selector': 'punctuation.accessor'}, {'characters': '.:@]/', 'selector': 'meta.tag, source - comment - string.quoted.double.block - string.quoted.single.block - string.unquoted.heredoc', 'server': 'zig'}]
ryuukk commented 1 year ago

There seems to be something very wrong with sublime LSP

Here a different server: ols https://github.com/DanielGavin/ols/

Using sublime odin: https://github.com/odin-lang/sublime-odin

>>> view.settings().get("auto_complete_triggers")
[{'characters': '<', 'selector': 'text.html, text.xml'}, {'rhs_empty': True, 'selector': 'punctuation.accessor'}, {'characters': '.>#"/:', 'selector': 'meta.tag, source - comment - string.quoted.double.block - string.quoted.single.block - string.unquoted.heredoc', 'server': 'odin'}]
::[17: 04: 47.593]-- > odin textDocument / completion(275): {
    'textDocument': {
        'uri': 'file:///home/ryuukk/dev/kdomo/src/game/socket.odin'
    },
    'position': {
        'character': 16,
        'line': 208
    }
}
::[17: 04: 47.617] << < odin(275)(duration: 23 ms): {
    'items': [{
        'insertText': 'erro($0)',
        'detail': 'rt.erro: proc(fmt: string, args: ..any, location := caller_location)',
        'deprecated': False,
        'labelDetails': {
            'detail': '(fmt: string, args: ..any, location := caller_location)',
            'description': ''
        },
        'label': 'erro',
        'command': {
            'arguments': [],
            'command': 'editor.action.triggerParameterHints',
            'title': ''
        },
        'insertTextFormat': 2,
        'documentation': '',
        'kind': 3,
        'tags': []
    }, {
        'insertText': 'print_double($0)',
        'detail': 'rt.print_double: proc(arg: f64)',
        'deprecated': False,
        'labelDetails': {
            'detail': '(arg: f64)',
            'description': ''
        },
        'label': 'print_double',
        'command': {
            'arguments': [],
            'command': 'editor.action.triggerParameterHints',
            'title': ''
        },
        'insertTextFormat': 2,
        'documentation': '',
        'kind': 3,
        'tags': []
    }, {
        'insertText': 'readlink($0)',
        'detail': 'rt.readlink: proc(pathname: cstring, buf: ^u8, bufsiz: uint) -> int',
        'deprecated': False,
        'labelDetails': {
            'detail': '(pathname: cstring, buf: ^u8, bufsiz: uint) -> int',
            'description': ''
        },
        'label': 'readlink',
        'command': {
            'arguments': [],
            'command': 'editor.action.triggerParameterHints',
            'title': ''
        },
        'insertTextFormat': 2,
        'documentation': '',
        'kind': 3,
        'tags': []
    }, {
        'insertText': 'backtrace_symbols($0)',
        'detail': 'rt.backtrace_symbols: proc(buffer: ^uintptr, size: i32) -> [^]cstring',
        'deprecated': False,
        'labelDetails': {
            'detail': '(buffer: ^uintptr, size: i32) -> [^]cstring',
            'description': ''
        },
        'label': 'backtrace_symbols',
        'command': {
            'arguments': [],
            'command': 'editor.action.triggerParameterHints',
            'title': ''
        },
        'insertTextFormat': 2,
        'documentation': '',
        'kind': 3,
        'tags': []
    }, {
        'insertText': 'backtrace($0)',
        'detail': 'rt.backtrace: proc(buffer: ^uintptr, size: i32) -> i32',
        'deprecated': False,
        'labelDetails': {
            'detail': '(buffer: ^uintptr, size: i32) -> i32',
            'description': ''
        },
        'label': 'backtrace',
        'command': {
            'arguments': [],
            'command': 'editor.action.triggerParameterHints',
            'title': ''
        },
        'insertTextFormat': 2,
        'documentation': '',
        'kind': 3,
        'tags': []
    }, {
        'insertText': 'register($0)',
        'detail': 'rt.register: proc()',
        'deprecated': False,
        'labelDetails': {
            'detail': '()',
            'description': ''
        },
        'label': 'register',
        'command': {
            'arguments': [],
            'command': 'editor.action.triggerParameterHints',
            'title': ''
        },
        'insertTextFormat': 2,
        'documentation': '',
        'kind': 3,
        'tags': []
    }, {
        'insertText': 'popen($0)',
        'detail': 'rt.popen: proc(command: cstring, type: cstring) -> ^libc.FILE',
        'deprecated': False,
        'labelDetails': {
            'detail': '(command: cstring, type: cstring) -> ^libc.FILE',
            'description': ''
        },
        'label': 'popen',
        'command': {
            'arguments': [],
            'command': 'editor.action.triggerParameterHints',
            'title': ''
        },
        'insertTextFormat': 2,
        'documentation': '',
        'kind': 3,
        'tags': []
    }, {
        'insertText': 'print_str_len($0)',
        'detail': 'rt.print_str_len: proc(arg: cstring, len: int)',
        'deprecated': False,
        'labelDetails': {
            'detail': '(arg: cstring, len: int)',
            'description': ''
        },
        'label': 'print_str_len',
        'command': {
            'arguments': [],
            'command': 'editor.action.triggerParameterHints',
            'title': ''
        },
        'insertTextFormat': 2,
        'documentation': '',
        'kind': 3,
        'tags': []
    }, {
        'detail': 'rt.RTLD_DL_SYMENT',
        'deprecated': False,
        'label': 'RTLD_DL_SYMENT',
        'documentation': '',
        'kind': 0,
        'tags': []
    }, {
        'insertText': 'handler($0)',
        'detail': 'rt.handler: proc(sig: i32)',
        'deprecated': False,
        'labelDetails': {
            'detail': '(sig: i32)',
            'description': ''
        },
        'label': 'handler',
        'command': {
            'arguments': [],
            'command': 'editor.action.triggerParameterHints',
            'title': ''
        },
        'insertTextFormat': 2,
        'documentation': '',
        'kind': 3,
        'tags': []
    }, {
        'insertText': 'backtrace_symbols_fd($0)',
        'detail': 'rt.backtrace_symbols_fd: proc(buffer: ^uintptr, size: i32, fd: i32)',
        'deprecated': False,
        'labelDetails': {
            'detail': '(buffer: ^uintptr, size: i32, fd: i32)',
            'description': ''
        },
        'label': 'backtrace_symbols_fd',
        'command': {
            'arguments': [],
            'command': 'editor.action.triggerParameterHints',
            'title': ''
        },
        'insertTextFormat': 2,
        'documentation': '',
        'kind': 3,
        'tags': []
    }, {
        'detail': 'rt.USE_COLOR',
        'deprecated': False,
        'label': 'USE_COLOR',
        'documentation': '',
        'kind': 1,
        'tags': []
    }],
    'isIncomplete': True
}

It should show erro

Yet it doesn't:

image

I tried to cycle through the list but what you see is all there is

Until i type at least 3 first characters:

image

VSCode works as expected on 1st char:

image

rchl commented 1 year ago

Could be the same issue.

If you type rt., then cancel the completion popup and then type e then it works?

ryuukk commented 1 year ago

Could be the same issue.

If you type rt., then cancel the completion popup and then type e then it works?

No luck, it still doesn't show erro

Here, i removed all other functions to remove noise, i only left erro

::[17: 27: 56.400]-- > odin textDocument / completion(55): {
    'textDocument': {
        'uri': 'file:///home/ryuukk/dev/kdomo/src/game/socket.odin'
    },
    'position': {
        'line': 208,
        'character': 16
    }
}
::[17: 27: 56.403] << < odin(55)(duration: 2 ms): {
    'items': [{
        'insertTextFormat': 2,
        'tags': [],
        'detail': 'rt.erro: proc(fmt: string, args: ..any, location := caller_location)',
        'command': {
            'arguments': [],
            'command': 'editor.action.triggerParameterHints',
            'title': ''
        },
        'documentation': '',
        'deprecated': False,
        'label': 'erro',
        'insertText': 'erro($0)',
        'kind': 3,
        'labelDetails': {
            'detail': '(fmt: string, args: ..any, location := caller_location)',
            'description': ''
        }
    }],
    'isIncomplete': True
}

Something strange

ryuukk commented 1 year ago

Some logging information when it builds the CompletionItem, i put some print in completion.py file

trigger: erro(fmt: string, args: ..any, location := caller_location) annotation: rt.erro: proc(fmt: string, args: ..any, location := caller_location)

rchl commented 1 year ago

Having space characters and/or braces and colons is something that probably throws off ST. But I'm guessing at this point

rchl commented 1 year ago

It would probably work better if the server wouldn't provide detail.

ryuukk commented 1 year ago

Same problem if the server doesn't send the detail

If it works with vscode, it should work with sublime

How do i debug this further?

ryuukk commented 1 year ago

image

On the left

rt.er : sublime text show no completion, despite the item being on the json

log:

trigger: erro(fmt: string, args: ..any, location := caller_location)
annotation: rt.erro: proc(fmt: string, args: ..any, location := caller_location)

And on the right

rt.err : sublime now show the completion item!

log:

trigger: erro(fmt: string, args: ..any, location := caller_location)
annotation: rt.erro: proc(fmt: string, args: ..any, location := caller_location)

It literally receive the same json.. why one shows it, the other don't?

My guess: a bug in Sublime Text 's CompletionItem API

Version: 4143

ryuukk commented 1 year ago

Even if i change the symbol's name, it's always the same:

2 first character doesn't show the completiton, it always starts at the 3rd character i type, definitely a bug with ST