From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Dmitry Gutov Newsgroups: gmane.emacs.devel Subject: Re: Emacs completion matches selection UI Date: Thu, 09 Jan 2014 11:12:20 +0400 Message-ID: <52CE4BD4.4020808@yandex.ru> References: <20140108025840.GA7365@c3po> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1389251559 22698 80.91.229.3 (9 Jan 2014 07:12:39 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 9 Jan 2014 07:12:39 +0000 (UTC) Cc: emacs-devel@gnu.org To: Toby Cubitt Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Jan 09 08:12:46 2014 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1W19nI-0002Vu-T1 for ged-emacs-devel@m.gmane.org; Thu, 09 Jan 2014 08:12:45 +0100 Original-Received: from localhost ([::1]:50369 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W19nF-0006t1-Rq for ged-emacs-devel@m.gmane.org; Thu, 09 Jan 2014 02:12:41 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:52552) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W19n6-0006oI-Kx for emacs-devel@gnu.org; Thu, 09 Jan 2014 02:12:38 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W19n1-0008BC-50 for emacs-devel@gnu.org; Thu, 09 Jan 2014 02:12:32 -0500 Original-Received: from mail-la0-x234.google.com ([2a00:1450:4010:c03::234]:60932) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W19n0-0008AZ-O5 for emacs-devel@gnu.org; Thu, 09 Jan 2014 02:12:27 -0500 Original-Received: by mail-la0-f52.google.com with SMTP id y1so1836659lam.25 for ; Wed, 08 Jan 2014 23:12:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; bh=Y6l+aov6VtIxaGoBVvrpNJpmTLXAu6XaKGP3BWMyaGg=; b=K4ewsVRTaKsGWoLQiwpqxkToo99mwk9lpj41bMv0CswhH3WZNMoYgDsTgE/VxOE815 +w0rxSQZVOQepM2GRoC8G6RYik1trw/pOI1UkyKztXIg1TVQVCCrKtDuCrHLi6Y11nMB ng5S7cp/Bz2x86ZPiZXZ/USF2CFn5ihRGB2AfnRPPYeOJ4ajUpAula3JXI6I7g8FOeQ8 IagSJur8vlx+VkxjvyiqCalU5IGc5ZtE3VhfbhqVgx9Wf2wFMxaDfPLV8NUdiJ6aa5EC x1Q2vR6H9layZGlRkPcDdP12akF0kB3c+QNmkhdxHX5HakplUmzU/pQkS5/U2abb3HDu idZA== X-Received: by 10.152.19.65 with SMTP id c1mr517478lae.49.1389251544721; Wed, 08 Jan 2014 23:12:24 -0800 (PST) Original-Received: from [192.168.1.3] ([178.252.98.87]) by mx.google.com with ESMTPSA id bl6sm615039lbb.5.2014.01.08.23.12.23 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 08 Jan 2014 23:12:23 -0800 (PST) User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 In-Reply-To: <20140108025840.GA7365@c3po> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4010:c03::234 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 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.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:167865 Archived-At: On 08.01.2014 06:58, Toby Cubitt wrote: >> I don't really see why a non-prefix completion UI (or any other one) has >> to modify the buffer text. Company has an inline "preview" frontend, but >> it uses an overlay, and so the buffer text remains unmodified. > > Ah, you mean using the `before-string' or `after-string' overlay > property? That does sound like a better implementation. Yep. Company's popup and popup.el are also implemented using this property. > Neither Company nor CAPF support refining the completion list by adding > more characters to the prefix/pattern (somewhat similar to > isearch). Completion-UI does, and it's very useful. Indeed, this is one > of the desired features Ted explicitly asked for in his recent post. Company has as isearch-like function (press `C-s' when you see the completions popup). It doesn't *add* to the pattern as much as just searches within the candidates list. It could refine it, though. Again, there's no buffer modification going on during that. > At the very least, you need to store which completion backend > was used (which I think Company does too; CAPF makes this trickier, since > it doesn't have a simple way of identifying completion sources). You may be able to get away with just storing the value returned by the completion function. Instead of refreshing the completion boundaries after each command, you could just assume that they stay in place, and the closing boundary just moves according to the amount of text inserted/removed during completion. > If the former, we'll very likely want to record which CAPF source > returned the completions somehow. If the latter, then the equivalent of > the backend name is fine. (In the current Completion-UI implementation, > this property stores the completion source name, which modulo > implementation differences is directly equivalent to your backend names.) Come to think of it, that should be easy to do in `completion--capf-wrapper', as long as FUN is a symbol, not an anonymous function. > But how would we use that in the Customization interface, to allow users > to customize the UI in different ways for different sources? Hm, maybe the function name too, see above. We'll need to retain all PROPS anyway. > What I don't see at the > moment is how Customize would discover what all the possible CAPF source > names are, in order to conveniently list them as options in a menu. I don't really see that happening at all. >> The opaqueness in c-a-p-f is bad because the exact values of >> `company-backends' and `completion-at-point-functions' are significant. >> A third-party package author can only push a function in either of these >> lists, but they can be responsible for the eventual order of the elements. >> >> And the order matters, because it influences which completion backend >> will get picked when several are suitable. When we get to the grouped >> backends, which I've mentioned several times, which Company supports, >> and CAPF will hopefully support in the future, being able to understand >> and maybe change the values of either list becomes even more important. > > I completely agree. > > How do you suggest we could improve it, without replacing CAPF or > breaking backwards compatibility? > > This is something you care about more and have more experience of in > Company than I do with Predictive. I'm pretty confident that I can adapt > the Completion-UI code to whatever API we settle on for defining > completion sources and selection logic, without too much pain. Sorry, no idea. `company-backends' is not a hook, and this simple nature makes it more transparent, while somewhat less powerful. Making c-a-p-f less powerful is probably a non-starter. >> My question was, if you could point out problems with any of our bundled >> backends (or, failing that, third-party ones). If they look okay, maybe > > Did some text get cut off here in your reply? Sorry, forgot to finish it. Roughly the idea is this: if the backends we bundle look okay and flexible enough, maybe the API is sounds for most cases, barring extreme examples. Anyway, this doesn't matter much, because we'll be refining CAPF. >> 1) Adding some pre-completion hook which would allow you to run some >> code once, set a buffer-local variable, which all backend functions for >> LaTeX can refer to later in `prefix' action. > > I don't think this can work, because the choice of source depends on the > location of point and the text in the buffer, which changes from > completion to completion. One *per completion*, of course. As opposed to once per backend per completion. > For the Predictive LaTeX support, I use a mish mash of piggy-backing on > jit-lock where possible, some regexp match tests, and a limited form of > incremental parsing of the LaTeX code when the rest aren't enough. (I > used to exclusively use the latter, implemented using my auto-overlays > package. Surprisingly this was more than efficient enough to cause no > noticeable delay when typing and auto-completing, even on very old > hardware. But writing and debugging the incremental parser definitions > were a nightmare, largely because TeX doesn't have a well-defined > grammar. So I replaced as much as possible of the parsing with simpler > methods.) Sounds scary. > This effectively means moving the selection logic out of Company and into > Predictive. Which isn't necessarily a bad solution. It's how I used to do > it in Predictive, until I generalised the selection logic and moved it > into Completion-UI so other sources could make use of it. > > If we stick with the CAPF API, I suspect I'll end up moving my source > selection logic back into Predictive, and making it Predictive-specific > again. I don't think you have to. A completion function can similarly return different completion tables based on the context. >> Regexps we have already (company-grab-...), > > How fast is this if you have to go through, say, 100 moderately complex > regexps checking for a match? (See the predictive-latex.el in the old > Predictive tarball release for examples.) I'm not really sure what to look at. `predictive-latex-load-regexps'? I probably won't be able to measure it without rewriting that code. > In Completion-UI, I implemented combined completion sources through a > `completion-ui-combining-complete' wrapper function. (They're not > functionally equivalent to your merged sources, but the requirements are > somewhat similar.) > > Would using something like that to build merged CAPF functions be a > solution for Company? I know this isn't particularly user-friendly if you > want to allow users to easily define their own merged sources. I don't > know if that's something people regularly do in Company. In Company, you just add a list value to `company-backends'. There is one in the default value already. Its handling is not perfect, but does the job currently, as long as the backends are compatible enough. > There's one thing we should perhaps think a bit more about. > > Is it right to say that the majority of the Company backends are selected > based on global properties of a buffer (e.g. major-modes)? This seems to > be the case for the default `company-backends' list. In Completion-UI I > was almost entirely focused on selecting backends based on local > properties at different locations within a buffer (regexps, faces, > syntax, etc.). > > How do you envisage supporting local source selection in the new (or > enhanced CAPF) API? Would this kind of local completion source selection > always be implemented within a single backend, like the Company CEDET > backend? Or should there be a convenient way of supporting it in the > generic source selection API? Generally, you'd just replace several existing entries in `completion-at-point-functions' with a new one that would first check local properties and then call an appropriate function among the replaced ones. Or, if the new function does not handle existing completion functions, scratch out he "replace[d]" bit. > Following the code path is unnecessarily convoluted. I can't tell that > company-dabbrev-code internally delegates to the company-dabbrev backend > just from looking at `company-backends'. If it looked more like: > > ((use-dabbrev-code-p . dabbrev-completion) > (use-dabbrev-p . dabbrev-completion)) > > it would be immediately obvious that these are two different ways of > using the same source of completions. This wouldn't work because company-dabbrev-code uses case-sensitive search and doesn't downcase the results, as opposed to company-dabbrev. But they share code anyway. > The question for now is, what should go in the generic Emacs API? Vanilla > CAPF, perhaps with some additional standard PROPS properties? If the > generic Emacs API can't replace company-backends in Company, then in my > view the API is no good. > > You're the expert here :) So far I don't see obvious missing parts in CAPF API. But there are some that could be harder to support in frontends, like partial completion, and it also seems to be suboptimal for implementing backends with external services, see the tangential discussion at http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16334. > The way I imagine it, completion packages like Company would rarely need > to use the API for defining new widgets. (Unless they're defining custom > widgets that are so package-specific they don't belong in core Emacs. But > that seems like a rare case.) > > What they *will* all use is the API for *invoking* the completion > interface, which we began to discuss below. Yep. > Erm, I don't see any major shortcomings in the API. Probably that hasn't > come across in the discussion :-) > > Minor ones that have come here were: > > - No support for non-prefix completion (but it looks easy enough to > extend the API). So far I don't see an easy way to visualize non-prefix completion in frontends. Specifically, the way candidates relate to an input string. With prefix completion, it's easy: just highlight the prefix, but partial completion, for example, requires re-parsing the returned candidates on the fly, to try to match the separate letters. > - Difficult (impossible?) to distinguish between "no completions > available" and "backend not applicable". That's easy. "Backend not applicable" means `prefix' returned nil. "No completion available" means `prefix' returned non-nil, but `candidates' returned nil. > OK, makes sense. If I understand correctly, CAPF is fine for letting > users decide the order of trying backends. I'm not sure. When someone's using `add-hook', you don't really look at the order of all elements, you just add a new one at the beginning or the end of the list. Should be all right most of the time, though. > It would be nice to define a Customization interface that lists the > available CAPF functions in a drop-down menu (whilst also allowing > free-form entries, of course). If I find a way of porting the > Completion-UI auto-updating customization interface magic to CAPF, this > would be feasible... This looks impossible to me. CAPF functions are defined in many places, including third-party packages, using plain `defun' interface. Can there really be a way to track them?