Git Product home page Git Product logo

Comments (19)

mawww avatar mawww commented on May 26, 2024 1

When you use <ret> to validate the selection, you also add a newline just after it, then once the menu gets hidden, kakoune detects that the cursor is not preceeded by the completion text anymore and filters that out.

I think the existing logic in Kakoune side is too brittle, we should probably keep track of the inserted ranges instead of trying to infer them back from cursor positions and buffer text.

from kakoune-lsp.

mawww avatar mawww commented on May 26, 2024 1

fc3e5ea419aa79c7adf38a9252586d867b3eb19b should have improved things, keen to get feedback.

from kakoune-lsp.

krobelus avatar krobelus commented on May 26, 2024 1

2637b26 takes care of adding the import statements, thanks for the test case

from kakoune-lsp.

vnagarnaik avatar vnagarnaik commented on May 26, 2024

Could you prioritize this feature please? Along with adding support for "additionalTextEdits"?

I am using a C++ language server that provides completions and suggests the appropriate #include header file through "additionalTextEdits". This would make working in kakoune much more productive.

I don't know much rust to be helpful with an actual PR.

from kakoune-lsp.

ul avatar ul commented on May 26, 2024

Yes, I think it would be useful to have this done. It should be much easier to implement now because we have textEdit counterparts in lsp.kak. The only problem which remains is that we should cancel Kakoune's autocompletion when item is selected and do our own text edit instead. I'm not sure how to do it in elegant way, going to ask around at IRC channel.

from kakoune-lsp.

vnagarnaik avatar vnagarnaik commented on May 26, 2024

Cool, thanks. I can help with testing it if you have pre-release candidates after the change.

from kakoune-lsp.

ul avatar ul commented on May 26, 2024

Unfortunately I still don't know how to solve bottleneck I flagged in my previous comment. I raised an issue in Kakoune repo to get some advice.

from kakoune-lsp.

ul avatar ul commented on May 26, 2024

This issue seems to be solvable now when we've got completions-commands branch in Kakoune, which I think eventually will be merged.

It's still non-trivial, though.

  1. Applying and clearing textEdit and additionalTextEdits live while the user is cycling through completions menu is fragile as it involves many operations and can interrupt completions engine. I think the complexity of the solution doesn't worth it, and we will stick with default completions behaviour for cycling through items and will apply edits only when completion is confirmed.

  2. As language server is not aware of multiselection, kak-lsp should take care of projecting textEdit to all selections, either by offsetting textEdit for the main selection or by making multiple requests to language server (which has an interesting side-effect that we can take the intersection of all responses to have only candidates which are relevant for all selections). We also need to assume something about additionalTextEdits, for example, that they are always used only for auto-inserting imports and we should apply them only once even in multiselection case.

from kakoune-lsp.

Avi-D-coder avatar Avi-D-coder commented on May 26, 2024

tsserver sends adtional text edits adding namespace prefixes.

If the additional edits given by a completion at the intersection of the multiselection differ in content or range they should both be applied unless they overlap.

from kakoune-lsp.

ul avatar ul commented on May 26, 2024

Does anyone want to give this issue a go? I consistently find myself failing to allocate enough time to have a proper look into it. This is a non-trivial feature which should be quite rewarding once implemented. Of course, I'm keen to help as much as I can.

from kakoune-lsp.

ul avatar ul commented on May 26, 2024

Waiting on mawww/kakoune#2898

from kakoune-lsp.

tadeokondrak avatar tadeokondrak commented on May 26, 2024

I was trying to implement this, but it seems that the argument to the InsertCompletionHide hook is empty if you use <ret> to accept the completion.

from kakoune-lsp.

ul avatar ul commented on May 26, 2024

it seems that the argument to the InsertCompletionHide hook is empty if you use to accept the completion.

@mawww do you have any ideas why is this the case?

from kakoune-lsp.

krobelus avatar krobelus commented on May 26, 2024

I have a rough prototype for this in krobelus@textedit-completion

Here is how to try it:

cat > test.c << EOF
void foobar(int x) {}
void main() {
        foba
}
EOF

cat > min-kak-lsp.toml << EOF
[language.c_cpp]
filetypes = ["c", "cpp"]
command = "ccls"
roots = []
EOF

(I'm using ccls, I did not test with other language servers.)

cargo build
: > log
HOME=$PWD kak test.c +3:11 -e '
	source rc/lsp.kak
	set global lsp_cmd "target/debug/kak-lsp -s %val{session} -c min-kak-lsp.toml -vvv --log log"
	lsp-enable
'
pkill -f target/debug/kak-lsp

What already works:

  • i<c-n><esc> -> line 3 will be foobar(
  • i<c-n>x -> line 3 will be foobar(x

What doesn't work:

  • i<c-n><ret> -> leftover indentation from <ret> (see 2.)
  • multiple selections
  • multi-line completions
  • non-ASCII source files (I am experiencing some glitches, see 3.)

There are two problems I'm still facing

  1. The range passed to InsertCompletionHide includes the last character typed by
    the user when accepting the completion.
    I use a quite ugly workaround where I just drop the last character of the range.
    @mawww, maybe we should change InsertCompletionHide to
    also pass the raw completion text (which I use to identify the textEdit to apply).

  2. If the cursor is in the middle of the token to complete
    as in fo%()ba, then after accepting the completion by typing any character, we want to:

    a) replace the completion label with the original text edit
    b) replace the stray ba

I couldn't figure out how to do that reliably with <ret> which autoindents.

  1. When selecting a completion in insert mode we first receive a new
    textDocument/completion and only after that receive the
    textDocument/didChange event that tells kak-lsp that we inserted the
    completion earlier. Because of this wrong ordering, the textDocument/completion
    event contains a completion that is out-of-bounds in the buffer that kak-lsp knows
    about. This causes a panic in the handler for textDocument/completion.

I added a horrible workaround in src/position.rs` that assumes ASCII characters.
This is probably why I'm getting bad results when completing identifiers
with non-ASCII chars.

I'm not yet sure how to fix that. Probably the order of textDocument/completion and
textDocument/didChange should be swapped.

from kakoune-lsp.

krobelus avatar krobelus commented on May 26, 2024

I've implemented a different approach now, see #551 if you wanna try it.
Some tricky issues are remaining, e.g. if/how we should support multi-selections.

Does anyone know a server that sends additionalTextEdits, then I can test that. Thanks.

from kakoune-lsp.

daboross avatar daboross commented on May 26, 2024

I believe rust-analyzer uses additionalTextEdits when completing an autocomplete suggestion which requires adding an additional import.

If I have the following program:

fn main() {
    println!("Hello, world!");
    let x = Hash<cursor here>
}

Then autocomplete in VS Code with rust-analyzer plugin and select the second option, "HashMap (use std::collections::HashMap)`, it results in the following program:

use std::collections::HashMap;

fn main() {
    println!("Hello, world!");
    let x = HashMap<cursor here>
}

Note, I'm pretty sure rust-analyzer also specifically disables this functionality if the client does not report additionalTextEdit support, so that might be something to watch out for.

I don't have time right now to test this myself, but I hope this info helps!

from kakoune-lsp.

krobelus avatar krobelus commented on May 26, 2024

let x = Hash

yeah, rust-analyzer does not compute the additionalTextEdits eagerly, so we need to call completionItem/resolve.
But first we need to expose that capability (like VSCode), otherwise rust-analyzer won't even send the HashMap completion

diff --git a/src/general.rs b/src/general.rs
index c35ee43..0c7a362 100644
--- a/src/general.rs
+++ b/src/general.rs
@@ -103,7 +103,13 @@ pub fn initialize(root_path: &str, meta: EditorMeta, ctx: &mut Context) {
                         preselect_support: Some(false),
                         tag_support: None,
                         insert_replace_support: None,
-                        resolve_support: None,
+                        resolve_support: Some(CompletionItemCapabilityResolveSupport {
+                            properties: vec![
+                                "documentation".to_string(),
+                                "detail".to_string(),
+                                "additionalTextEdits".to_string(),
+                            ],
+                        }),
                         insert_text_mode_support: None,
                         label_details_support: None,
                     }),

Then, whenever the user confirms (not just selects!) a completion, we'd need to call completionItem/resolve and apply the resulting text edits.

Here's how Emacs' lsp-mode does it. Apparently nvim doesn't support this.

The problem is that in Kakoune (like in Vim) there is no difference between selecting and confirming a completion, so this might get tricky. The server does undo the import statements, so we'd need to clean up, or leave them around.
LSP and Kakoune have different ideas of how completion works, and I don't think it's possible to reconcile them without changing one of them.

As a workaround, we can use :lsp-code-actions Import after inserting the completion. I'm not sure however if we should lie about resolve_support, maybe we can just ask rust-analyzer to compute additionalTextEdits eagerly if the client does not support resolve. They can just send two batches of completions, unresolved and resolved.


BTW the original issue here should be solved for many practical cases by
c413929 (Use column from textEdit as completion start instead of heuristic, 2021-09-12)

from kakoune-lsp.

krobelus avatar krobelus commented on May 26, 2024

Ok nevermind I believe we can use InsertCompletionHide to figure out when a completion was "accepted", so additionalTextEdits should be doable.

from kakoune-lsp.

krobelus avatar krobelus commented on May 26, 2024

Gotta go now but krobelus@completion-additionalTextEdits is a quick-and-dirty fix for the rust-analyzer example.
In some scenarios it will also add the import of the selected item if you hit backspace, I'm not sure how to avoid that.
This happens when you type HashMap, select the completion, then type backspace. The backspace makes kak-lsp ask for completions again, so it triggers another InsertCompletionHide and InsertCompletionShow

from kakoune-lsp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.