From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= Newsgroups: gmane.emacs.devel Subject: Re: Eglot cannot work with default completion-in-region? Date: Sun, 28 Jan 2024 14:09:50 +0000 Message-ID: <87r0i1blch.fsf@gmail.com> References: <87ttmy7pog.fsf@catern.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="37260"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: emacs-devel@gnu.org To: sbaugh@catern.com Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun Jan 28 15:10:45 2024 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1rU5rw-0009Se-Kl for ged-emacs-devel@m.gmane-mx.org; Sun, 28 Jan 2024 15:10:44 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rU5rA-00071j-3O; Sun, 28 Jan 2024 09:09:56 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rU5r7-00071S-B9 for emacs-devel@gnu.org; Sun, 28 Jan 2024 09:09:53 -0500 Original-Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rU5r5-0002Tk-5v for emacs-devel@gnu.org; Sun, 28 Jan 2024 09:09:53 -0500 Original-Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-40e7e2e04f0so27123955e9.1 for ; Sun, 28 Jan 2024 06:09:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1706450987; x=1707055787; darn=gnu.org; h=content-transfer-encoding:mime-version:user-agent:message-id:date :references:in-reply-to:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+clClhb5LT8WZV9sE5F39vjRTB5APkbcW0/eO5mxnUM=; b=JBUWn4bqG6BVdnSl1hLLNSyDUo+3U6DnQMm18raMS0dy5IkYKOby3rmC6HIybABluu bGbUyyafBeHPt6nrmktEXkhT3GqLp2DoDx8Q7KDkaYpqLgdDyC8CRsSRxqFeKFpqiKZ7 5tpVVwsD8SYWhVVieebfkHcuvHX/tAmT085B7e3QFQ8D+wmcOQyaViN8dKaKvErRERib LNBUOZmKhN1yrmGNRQcanT3XxDBmz5ntLXy/qCpcC5P09D3MTRAHDfKEkd4yB9lG0giQ IZ1OTKbOfqPpxCzXuQFRvm3GTc9NT9vqok6RoICs8LQc8gQw+W8I+ztVG7a87blh52so X8KQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706450987; x=1707055787; h=content-transfer-encoding:mime-version:user-agent:message-id:date :references:in-reply-to:subject:cc:to:from:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=+clClhb5LT8WZV9sE5F39vjRTB5APkbcW0/eO5mxnUM=; b=pBdWm8qFs3wReZkoJrnAzZyO4tKfRvcW+Vusn2abcbUO48tREXvNC+jIAAA6xdqLs1 AGKTDSkCkgJUshtKFPHwjqEbu+ltvWWwW50nQ4aiaSKYbOqWATyaY+ZTbnvSioSL5ZV5 hVvIYdPJQ/hEO8OXW0FS2n7N007Ir2J/O3t37M399jKo5NuJLSUKpEGYD8JT7zyfPa7F g3oIBcT3jQbZiS5tCA07xq3rdHBfvdcU8QE5iUOTJdly5aw5mHRnv0qJ8/zAirmDUNnB eP8jfj2IEtZm1TRseCF39aToiVv/KW/ZoBPiXPQ93bROa6TPpEpjkvV4e+7i7sPBrCo/ B4pw== X-Gm-Message-State: AOJu0Yx4hstF8BQBUY8GoJwWqR4ixR4DEKOvTyUWIHHPN/ZhyZlKl1Zv cU5z0gBjzFZku5+UYekon+LdlcRcfX7sIcXxwaoG8VVxH+zdfRCirmW44U8+ X-Google-Smtp-Source: AGHT+IFQdaXZRQIQCdkcU5VF9tHh938OVSEX/7dE9B4Qxt9kU92N+K/FYQbsw8tafoUJPA/LEb2WFA== X-Received: by 2002:a05:600c:4685:b0:40e:88be:ec58 with SMTP id p5-20020a05600c468500b0040e88beec58mr2971825wmo.31.1706450986944; Sun, 28 Jan 2024 06:09:46 -0800 (PST) Original-Received: from krug ([87.196.75.187]) by smtp.gmail.com with ESMTPSA id bi19-20020a05600c3d9300b0040ee51f1025sm6302887wmb.43.2024.01.28.06.09.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Jan 2024 06:09:46 -0800 (PST) In-Reply-To: <87ttmy7pog.fsf@catern.com> (sbaugh@catern.com's message of "Sat, 27 Jan 2024 15:37:35 +0000") Received-SPF: pass client-ip=2a00:1450:4864:20::331; envelope-from=joaotavora@gmail.com; helo=mail-wm1-x331.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:315550 Archived-At: sbaugh@catern.com writes: [Spencer, if you mail user agent has a CC option, please use it to in my CC, otherwise, you make finding these replies harder for me. This is very common practice in this list. ] > Jo=C3=A3o T=C3=A1vora writes: >> Is it? The above all return textEdits, I think. How can sortText, >> a JSON string, equal textEdit, a JSON object? > > If textEdit.range=3D=3Dthe completion region and textEdit.newText=3D=3Dso= rtText, > then the textEdit is trivial and the default completion insertion > behavior is correct and needs no special handling. So we can skip the > textEdit behavior in the exit-function. Couple of points: * How do you know that is actually the "common" case? For example, it's not uncommon at all to have some language servers provide completions for symbols which also add in an '#include', or an 'import' when you choose it (according to each languages module system, of course). * Are you familiar with how LSP expresses edits? The very same edit can be expressed in a multitude of ways. Ultimately, the only way in which an edit can be determined to be trivial is by applying it and seeing it if was trivial. >>> In that case, this code is not necessary, and Eglot doesn't need an >>> :exit-function at all. >> >> Indeed. But how do you plan to know this in advance? > > And if for all the completion items, we see that we can skip the > textEdit behavior, then we don't need an :exit-function at all. Indeed "for all". So this would mean iterating the full completion list for non-trivial computation. Even if that's manageable, are you aware that some completion lists are incomplete at first and then are resolved to complete lists as the completion session progresses? Also, I hope that you are aware that LSP fundamentally disrepects any Emacs completion style. Because unless you can somehow teach Elisp to arbitrary language servers on the spot, they really have no idea what "flex", "partial-completion", "emacs22" or "orderless" is. I consider this to be a much, much greater nuisance than the partial completion limitations that you picked to start this thread.=20 >>> Can Eglot detect this and avoid this somewhat hacky code in that case? >> >> Not easily or cleanly... > > What's the issue with the approach I described above? Seems like it > would work? The only way to know is to try it. And I don't envision easy or clean stemming from it. But if you have this approach very clear in your head and demonstrate that: * it's fast, or fast enough * it significantly improves the completion experience compared to what it is now * it doesn't break any existing use cases * it doesn't add an unmanageable amount of complexity to the already complex function Then I'll be willing to consider it, of course. But for me, this is too tall an order. I just don't see the benefit. Anyway, as I said before, I think the starting point for this would have to be a systematic structured survey of how Eglot behaves currently in a number of language servers (including yours, of course, but not limited to it) and encode that as unit tests for Eglot (failing or passing). That effort is very valuable in itself and it is a prerequisite for any deep changes to that function. You can have a look at the exiting 'eglot-test-basic-completions' and 'eglot-test-non-unique-completions' tests. I'd welcome many more such tests. >>> It should be a performance improvement and simplification anyway for all >>> completion frameworks. >> >> .. but you can try your hand at a patch. I'd love to be proven wrong. >> >>> (BTW, besides the issue with default completion-in-region, I also ran >>> into this while trying to write an OCaml-specific wrapper for >>> eglot-completion-at-point function which adds some additional >>> completions to those returned from the LSP. But if those completions >>> are chosen, then the Eglot exit-function breaks when it tries to look up >>> the insertText/textEdit. My LSP doesn't use textEdit at all, though, so >>> this is another unnecessary breakage) >> >> What contract exactly is eglot-completion-at-point breaking? > > No contract, my modification isn't staying within the bounds of any > explicit contract. So of course I shouldn't expect it to work. But > nevertheless I'd like to get it to work, and the exit-function is what > doesn't work, so I'd like to figure out a way to make it work. Maybe you can write an OCaml-server specific LSP-aware completion function for your OCaml major mode using Eglot's API. I think that's what makes the most sense. You'll be able to know for sure what the server does.=20=20 > We could add a new extra property to completion-at-point-functions, > :text-function, which gets the completion item after it's been selected, > before text properties are stripped, and returns the actual text which > should be inserted into the buffer. That's something to pitch to Stefan. But that API is pretty hairy as it is. > That would be useful to Eglot, right? It would let Eglot avoid some > hacks to work around the fact that default completion-in-region strips > the text properties before calling exit-function. I don't know exactly what you're talking about or what this loss of text-propeties actually entails. If there's a bug, I'd like to know about it, but I should be able to reproduce it. For things to be "useful for Eglot" they have to translate to actual tangible benefits for Eglot users in some server/major-mode combination (and no bugs) "Eglot users" here means user of: Emacs -Q some-file.xyz -f eglot Where "xyz" is potentially _any_ file type managed by _any_ LSP server, past or future. It doesn't mean users of: Emacs -Q -l my-special-library-or-configuration.el some-file.ocaml -f egl= ot That's _not_ to say the latter isn't useful for some, or even many, users. I just don't count that as "useful for Eglot". > And then my wrapper around eglot-completion-at-point could just provide > its own text-function which calls Eglot's text-function whenever it sees > an Eglot completion, and runs its own logic on its own completions, and > avoid any breakage. I think you should try your hand at an OCaml-speciifc LSP-ware completion function. If the Elisp API of Eglot isn't sufficiently flexible, we can make it more flexible. Jo=C3=A3o