From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: Generalizing find-definition Date: Mon, 03 Nov 2014 09:30:56 -0500 Message-ID: References: <20141102151524.0d9c665c@forcix> <20141102172944.0f7944e3@forcix> <20141103084433.12117c03@forcix> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1415025305 15828 80.91.229.3 (3 Nov 2014 14:35:05 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 3 Nov 2014 14:35:05 +0000 (UTC) Cc: emacs-devel@gnu.org To: Jorgen Schaefer Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Nov 03 15:34:57 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 1XlIif-0008G8-BP for ged-emacs-devel@m.gmane.org; Mon, 03 Nov 2014 15:34:57 +0100 Original-Received: from localhost ([::1]:35183 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XlIie-00066I-SY for ged-emacs-devel@m.gmane.org; Mon, 03 Nov 2014 09:34:56 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:48084) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XlIev-0008BY-D0 for emacs-devel@gnu.org; Mon, 03 Nov 2014 09:31:12 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XlIen-0006wN-Jq for emacs-devel@gnu.org; Mon, 03 Nov 2014 09:31:05 -0500 Original-Received: from ironport2-out.teksavvy.com ([206.248.154.181]:33016) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XlIen-0006wF-DW for emacs-devel@gnu.org; Mon, 03 Nov 2014 09:30:57 -0500 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AhoNAOatTlRFpY87/2dsb2JhbABcgw6BLII2hn7HP4QUBAICgRwXAQF8hAMBAQMBViMFCwsOHwcSFA0LDSQTiCwDCQnFLQ2GOAEBAQcCAR+OToI6BwqEQQWLZI0ugj6RYoRugW+EFh8vgksBAQE X-IPAS-Result: AhoNAOatTlRFpY87/2dsb2JhbABcgw6BLII2hn7HP4QUBAICgRwXAQF8hAMBAQMBViMFCwsOHwcSFA0LDSQTiCwDCQnFLQ2GOAEBAQcCAR+OToI6BwqEQQWLZI0ugj6RYoRugW+EFh8vgksBAQE X-IronPort-AV: E=Sophos;i="5.04,797,1406606400"; d="scan'208";a="95842466" Original-Received: from 69-165-143-59.dsl.teksavvy.com (HELO pastel.home) ([69.165.143.59]) by ironport2-out.teksavvy.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 03 Nov 2014 09:30:56 -0500 Original-Received: by pastel.home (Postfix, from userid 20848) id 1C7F48597; Mon, 3 Nov 2014 09:30:56 -0500 (EST) In-Reply-To: <20141103084433.12117c03@forcix> (Jorgen Schaefer's message of "Mon, 3 Nov 2014 08:44:33 +0100") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 206.248.154.181 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:176275 Archived-At: > The only benefit would be that M-, is now "go back after M-.", which is > what a lot of the packages that redefine M-. do to the key. Hence the > suggestion to swap the two keys, to unify that apparently rather > widespread use of M-,. If Emacs would prefer to keep M-, as is, that is > fine with me, too. I see, so it's compatibility with other packages vs. compatibility with etags.el. Luckily, I think there is no hurry to make this choice. So we could poll the users. >> So on the UI side we mostly have: >> - "jump to *the* definition of thing at point". >> - "list definitions of thing at point". > Agreed. So far, I would say this is the same key binding (M-.) > which then either jumps to the definition if there is one, or lists them > if there is more than one. IIUC the first is only used when there's only one definition. I guess it's OK, and it reduces the pressure on key-bindings. >> - "list uses of thing at point". > What key binding would you suggest for that? SLIME apparently uses M-_ > and M-? (i.e. the key right of . in different keyboard layouts). AFAICT there're both unbound currently, so either is fine. Of course, we could also re-use M-. for that (see below). >> And on the backend side we have: >> - identifier-at-point-function > Why do we need this? I thought we already agreed that we need a language-aware way to determine what is the identifier at point (taking into account the current namespace/package/etc..). > It does not make much sense for this functionality in languages with > combined identifiers. For example, in Python, "foo.bar()" can be > pretty much anything, it depends heavily on the context. Libraries for > introspection expect a position in a file/buffer, not an identifier, > to find the definitions. But if we also want the user to type the identifier via `C-u M-.', then we need find-definition-function to be able to deal with a string rather than a buffer position. So let's simply say that find-definition-function will be called either with a string or with a buffer position. If the function prefers only working from strings, it can call identifier-at-point-function to turn the buffer position into a string. >> - find-definition-function (with an argument to decide whether we want >> a whole list or just the best/first candidate). > I am not sure if it is generally easily possible to sort the list of > candidates like that. I guess tags often has the problem of knowing > more than one possible candidate, so it would be preferable for tags to > default to a single destination? In etags.el, it doesn't take noticeably more time to get the full list rather than just the first match, so I guess it's OK if we just always return the full list. >> Etags.el currently offers some additional functionality: >> - jump to definition of any identifier, with TAB-completion. > C-u M-. could call a separate function when set, which would be > provided by the mode author to prompt for an identifier (with tab > completion if possible) and goes to the definition of that symbol. Right. I guess the prompting can be part of the generic code, and the completion-table can be provided by an appropriate foo-function set by the backend providing find-definition-function. [ Side note: I expect that identifier-at-point-function would pretty much always be provided by the major mode, but I expect that find-definition-function (as well as the TAB-completion function) will sometimes be provided by the major mode, and sometimes by a mode-agnostic package (like etags.el). ] Helmut Eller writes: > We also have a group of bindings for similar but not so important > commands: > > C-c C-w c -- who calls (lists callers) > C-c C-w w -- calls who (lists functions called by the current function) > C-c C-w r -- who references (for global variables) > C-c C-w s -- who sets (for global variables) > C-c C-w b -- who binds (for dynamic variables) > C-c C-w s -- who specializes (lists methods specialized for a specific class) > C-c < -- list callers > C-c > -- list callees Right, this brings up two issues: - distinguish different kinds of uses: definitions, accesses, assignments, refinements (via advice-add, defmethod, ...), let-binds, ... - distinguish different categories of "identifiers" (e.g. classes, variables, functions, types, methods, ...). So far the proposal is to forget about the second distinction, tho if we pass buffer-positions to find-definition-function, find-definition-function can make those distinctions on its own. We could additionally have some kind of convention for disambiguation when using identifier strings, e.g. type "foobar variable" in the minibuffer prompt to state explicitly that you're interested in the foobar variable rather than the foobar type. For the first distinction, at the UI level we could do: - Specify the kind of use by the key-binding (M-. to find definitions, M-? to find uses). This doesn't work too well if there are many more refinements. - Specify the kind of use via a minibuffer prompt. E.g. C-u M-. would first prompt for an identifier (defaulting to the one at point), and then prompt for the kind of use to look for. - Specify the use by filtering in the "found matches" buffer. For "definition", this kind of sucks since in many cases there'd be only one definition, but you'd first have to go through the complete list displayed in a buffer, and then use some key-binding to filter the sole definition out of that. - A mix of the above. E.g. M-. searches only for one particular subset of uses (e.g. definitions and refinements), while M-? search for the complementary subset (or for all possible uses, including the ones already provided under M-.), and after M-? you can filter the results in the buffer. At the backend level, in order to accommodate those different possible UIs, the find-definition-function would seem to need to receive 2 args: one specifying the identifier, and the other specifying the kind of uses and the elements of the returned list should not just be positions but pairs of "position and use-kind". Stefan