From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: Re: end-of-defun is fubsr. Date: Wed, 4 Feb 2009 00:14:45 +0000 Message-ID: <20090204001445.GI1396@muc.de> References: <20090202202703.GB11077@muc.de> <20090203105035.GB1396@muc.de> <20090203122906.GC1396@muc.de> <20090203130028.GD1396@muc.de> <20090203160941.GE1396@muc.de> <20090203185812.GH1396@muc.de> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1233705329 13332 80.91.229.12 (3 Feb 2009 23:55:29 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 3 Feb 2009 23:55:29 +0000 (UTC) Cc: Miles Bader , emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Feb 04 00:56:43 2009 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1LUV8C-0007iq-Jr for ged-emacs-devel@m.gmane.org; Wed, 04 Feb 2009 00:56:41 +0100 Original-Received: from localhost ([127.0.0.1]:58997 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LUV6t-0006k0-T2 for ged-emacs-devel@m.gmane.org; Tue, 03 Feb 2009 18:55:19 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LUV6p-0006ju-JI for emacs-devel@gnu.org; Tue, 03 Feb 2009 18:55:15 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LUV6o-0006ji-R7 for emacs-devel@gnu.org; Tue, 03 Feb 2009 18:55:15 -0500 Original-Received: from [199.232.76.173] (port=52448 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LUV6o-0006jf-O5 for emacs-devel@gnu.org; Tue, 03 Feb 2009 18:55:14 -0500 Original-Received: from colin.muc.de ([193.149.48.1]:3779 helo=mail.muc.de) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LUV6n-0002r5-Pw for emacs-devel@gnu.org; Tue, 03 Feb 2009 18:55:14 -0500 Original-Received: (qmail 36883 invoked by uid 3782); 3 Feb 2009 23:55:04 -0000 Original-Received: from acm.muc.de (pD9E51F3C.dip.t-dialin.net [217.229.31.60]) by colin2.muc.de (tmda-ofmipd) with ESMTP; Wed, 04 Feb 2009 00:55:02 +0100 Original-Received: (qmail 30886 invoked by uid 1000); 4 Feb 2009 00:14:45 -0000 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.9i X-Delivery-Agent: TMDA/1.1.5 (Fettercairn) X-Primary-Address: acm@muc.de X-detected-operating-system: by monty-python.gnu.org: FreeBSD 4.6-4.9 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:108709 Archived-At: Hi, Stefan! On Tue, Feb 03, 2009 at 03:50:36PM -0500, Stefan Monnier wrote: > Yes, the code should be fixed to only move one line forward if it's > necessary (i.e. if we're not yet at a line beginning). Agreed. > >> This might be linked to the above problem. For Elisp it seems to > >> work correctly. > > (ii) When point is BETWEEN two C functions (more precisely JUST AFTER > > the end of the previous function), C-M-e doesn't move over the next > > function. This is because it gets its knickers in a twist, first > > calling BOD-raw, then EOD-function, trying to check if its succeeded > > yet, etc. ......... This is crazy! > I don't see this problem (actually in my tests, it seems to work fine > in C mode as well). Can you provide a test case. Visit src/buffer.c, goto L313 which contains the closing brace of DEFUN Fget_file_buffer, put point AFTER the "}". Or put point on the next line (L314). In either case C-M-e leaves point at BOL315. > > The problem is that end-of-defun calls beginning-of-defun-raw at each > > iteration (over ARG). It thus discards the information as to whether > > point began in a defun or between 2 defuns. > I don't think so. Quite the opposite: it uses BOD and EOD to figure out > whether we started inside a defun or between two defuns. Doing BOD-raw then (funcall EOD-function) can leave point after where it started, so the test which should trigger another (funcall EOD-function) (unless (or (> (point) pos) (eq (point) retry-point)) , fails. I'm not sure it's possible to determine in the general case, using only BOD and EOD, whether a given position is inside a defun or not. THIS IS CRITICALLY AND ESSENTIALLY CRUCIAL. If one were to define a variable end-of-defun-RAW-function, which is defined to leave point just after the last bit of the function, perhaps that would work, but it would break existing 3rd party code. > Unless by "the problem" you're talking about the performance problem, in > which case I understand that each time we call BOD (except for the first > call), we know that we're "outside" of a defun (unless there's nesting, > of course) but we don't tell that to BOD which may have to redo the work > of figuring it out. WILL have to do the work. There's a CC Mode function `c-where-wrt-brace-construct' which figures it out. It is computationally expensive, and is called exactly once per call of c-[be]-of-defun. > > What's bugging the Hades out of me is that I've put a LOT of effort into > > optimising c-\(beginning\|end\)-of-defun, and that's being rendered > > completely useless, at least for C-M-e, by an inept way of calling these > > functions. Several bug reports which made this work necessary came > > directly from Emacs Developers (for example, C-x 4 a taking a minute to > > run, or hassle with potential K&R regions taking just as long). > None of the above invloved EOD as far as I can tell. These all do > a single call to BOD. C-x 4 a used to do, I think, 5 calls in total to c-[be]-of-defun; one or two of these were certainly to c-end-of-defun. Instead, it now calls `c-defun-name' exactly once, which is all it wanted anyway. > > Surely there's nobody here who isn't sick and fed up with this defun > > movement business? Surely to goodness, after 25 years, we should be able > > to do major-mode specific defun movement as a matter of course? > Yes, it worked fine and fast in Emacs-21. I wasn't the one who insisted > that we should scan the whole buffer just in order to make sure that > we're not bumping into the super-rare case of K&R declaration. Now, I wonder, who could that have been? ;-) Oh, how I'd love just to get rid of these stupid K&R declarations, which NOBODY uses at all nowadays, except on >20 year old code bases. ;-) Why don't we flush them out of Emacs C source? (No, you don't have to answer.) Actually, in Emacs-21, ARG was ignored, presumed nil, when [be]-of-defun-function were non-nil, which was even worse. > I'd *much* rather that C-mode's BOD gets it wrong every blue moon, > rather than the current "let's parse the whole damn thing". > On my 800MHz machine, C-mode is often borderline unusable nowadays. > And it's not the fault of end-of-defun. There are one or two "it's too slow" bugs I'm desperately trying to fix. A dearth of braces makes CC Mode very slow, right now. I'm aware that some things are horribly slow. I'm doing my best to fix them, but there's only one of me at the moment. > > It's changed from "move to next end of function" to "move to the end of > > the function at whose beginning we now are", > Right. As you may notice, the second is a subset of the first (with > a few caveats for nested functions, of course, but that shouldn't matter > for C-mode), so if your implementation works for the first, it should > work for the second as well. It's called backward compatibility. c-end-of-defun's functionality "needs" to stay the same to support other Emacsen. For Emacs-23's EOD-function, It would barely need to be more than (search-forward-regexp "{") (backward-char) (foward-sexp) , except "of course", for having to move over any dangling bits at the end like the "bar ;" of "struct BAR { .... } bar ;". You've just got to love C, haven't you? ;-( > > and its default value is `forward-sexp'. `c-end-of-defun' was a good > > fit for the variable as it formerly was, but is now > > severely suboptimal. > At most by a factor of 2. I.e. if it's slow now, it sure wasn't > zippy before. By a factor a great deal more than 2, highly dependent on ARG. > >> Not sure about restoring the previous semantics. But I could agree to > >> the additional ARG argument, which could even let it "take over" (so > >> beginning-of-defun-raw is not called in that case). > > :-) Let's do it! > I knew you'd like it. :-) > >> > 3/- end-of-defun should be restructured along the lines of > >> > beginning-of-defun. > >> I don't think that's a good idea. The main reason is to deal with > >> languages that allow nested functions. > > Don't follow - In the upcoming CC Mode 5.32 code (in the CVS > > repository at SourceForge), C-M-[ae] works just fine for C++ defuns > > nested inside classes/namespaces and so on. The mechanism is > > entirely within CC Mode. > Yes, but I maintain Emacs, not CC-mode, so I care to move the > functionality to the generic code so that all modes (not just CC-modes) > benefit. OK. I think I can see what you're saying, now. Were you thinking of any (non CC Mode) languages in particular? Did this ever get discussed on emacs-devel? I might well have been asleep at the time. I've a suspicion that changing the meaning of EOD-function, even if it's only "restricting" how it's being called, is essentially a loss of backward compatibility, because any such function needs to be optimised differently. Good night for now! > Stefan -- Alan Mackenzie (Nuremberg, Germany).