[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: end-of-defun is fubsr.

From: Andreas Roehler
Subject: Re: end-of-defun is fubsr.
Date: Thu, 05 Feb 2009 11:37:56 +0100
User-agent: Thunderbird (X11/20070801)

Alan Mackenzie wrote:
> Hi, Stefan,
> On Wed, Feb 04, 2009 at 09:29:20AM -0500, Stefan Monnier wrote:
>>>>> 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.  
>>>> Oh, so we just disagree about what is the correct behavior.  As far
>>>> as I'm concerned, if C-M-e gets you to BOL315, that means that the
>>>> end of the function is BOL315, which implies that EOL313 is inside
>>>> the function, so it's correct for C-M-e to just move to BOL315.
>>> WADR, this is sophistry.  Correct behaviour is to go to the end of the
>>> defun.  In C, this is the closing }.  It CAN'T be anywhere else.  Take a
>>> straw poll of 100 C hackers and ask them.  It's the place where a
>>> compiler would give an error message if you chop off the buffer before
>>> it.
>>> The doc string for `end-of-defun' is crystal clear here: "Move forward to
>>> next end of defun".
>> There are 2 issues:
>> - Should M-C-e from within that function jump to BOL315 or to EOL313?
> Either EOL313 or BOL314 (was your "315" a typo?).  It would be nice to be
> definite here, but history necessitates vagueness.
>> - given that it jumps to BOL315, should C-M-e from EOL313 also jump to
>>   BOL315 or to the end of the next function?
> EOL313 is AT the end of the defun.  C-M-e move to the NEXT EOD, therefore
> it MUST jump to L331/332.  From a pragmatic point of view, what hacker
> wouldn't be aggravated by C-M-e taking him from EOL313 to BOL314?
>> My reply only concerned the second question, whereas your above argument
>> seems to apply to the first.
>>>>> 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,
>>>> That's what end-of-defun-function should do, indeed.
>>> I would agree.  I detest sloppy definitions, but EOD-function has been
>>> sloppily defined for years.  I think we should accept that EOD-functions
>>> in existing modes DON'T all go to this ideal point, but themselves
>>> correct for WS.
>>>>> perhaps that would work, but it would break existing 3rd party code.
>>>> Like which code?
>>> Well, in my first page of 50 in a google search for
>>> "end-of-defun-function", I came up with these, all of which set
>>> end-of-defun-function:
>> I know such functions exist, but which ones of these are (would be) broken?
> Haven't a clue, and can't be bothered to investigate.  It's a fair
> assumption that several or many would be broken.  I think the onus is on
> the person advocating the change to show that things are OK, rather than
> for opponents to show that things will definitely break.
>>> A user option c-recognize-k&r would be the way to go, I suppose.  It
>>> would be trivially easy to implement and would improve the
>>> performance of C Mode.  I was thinking more of purging the K&R
>>> declarations from the Emacs source code.  Perhaps for Emacs 24?  This
>>> surely would be a forward step now, even if it wouldn't have been in
>>> 1990.
>> No need to purge them before removing C-mode support for them.
>> AFAIK they were not supported by Emacs-21's C-mode either (at least in
>> the sense that BOD/EOD always did the right thing for them).
>>>> If that can solve the performance issues, I'm all for it.  After all,
>>>> Emacs-21 didn't get it right and I haven't heard significant complains
>>>> about it.  It's not like Emacs is always expected to understand every
>>>> little bit of a language's syntax anyway.
>>> Well, we could get philosophical about this.  I think that every little
>>> glitch which "isn't quite right" detracts from quality, and if there are
>>> enough such glitches, the user's impression will be of general low
>>> quality.
>> If you want to go there, you need to use the corresponding tools:
>> e.g. a real parser.
> I do want to go there, and without a real parser.  Therefore I can only
> approach closely.  
>>> WITH FUTURE IMPLEMENTATIONS OF end-of-defun-function.
>> Potential breakage comes with *any* change.  So I'm not interested
>> in it.  Show me actual breakage.
> That's sophistry again, Stefan.  It's true that any change risks
> breakage.  But with most changes we make, we take care to minimise the
> risk of breakage.  This particular change positively provokes it.  And
> fixing any such breakage will be boring tedious drudgery, regardless of
> whether one of us, or J. Random Hacker has to do it.  
>>> It isn't slow for ARG=1, except for some ill-conditioned files (perhaps
>>> src/lisp.h).
>> regex.c is pretty painful as well.
> OK.  I'll look at that.
>>> Somebody other than me will care about ARG > 1.  She'll care a lot
>>> when Emacs 23 hangs for 5, 10, 20, 50 seconds.  People who will use
>>> C-M-e to move large distances over files, for example.  In Emacs-22,
>>> this is fast - the speed is essentially independent of ARG.  Why
>>> should we slap them in the face when we release Emacs-23?
>> Check Emacs-22's code again: it also calls EOD-function ARG times.
>> So we're still talking just a constant factor.  The fact that you don't
>> know that indicates that it's clearly not a big issue.
> Sorry, you're wrong, at least as far as CC Mode is concerned. ;-)  In
> cc-mode.el appears this:
>   ;; (April 2006): RMS has now approved these commands as defaults.
>   (unless (memq 'argumentative-bod-function c-emacs-features)
>     (define-key c-mode-base-map "\e\C-a"    'c-beginning-of-defun)
>     (define-key c-mode-base-map "\e\C-e"    'c-end-of-defun))
> In Emacs-22, C-M-[ae] were bound directly to the CC Mode functions.  In
> Emacs-23, the unless clause prevents this.  Would you object if I
> restored these CC Mode bindings in Emacs 23?  That's not a rhetorical
> question.  Then we'd both get what we want, more or less.  Except that
> this matter would stay unresolved, and raise its ugly head yet again some
> time in the future.  I'm thoroughly sick of it, and I expect you are too.
>> Mind you, I do agree that it might be good to solve this "ARG times
>> slow".  I just don't think it's high on the list of things to fix.
> I regard it as already fixed.  I fixed it, at the cost of a vast amount
> of refactoring and many, many evenings' hacking in 2006.  I protest most
> strongly at losing the fruits of that work, even if only for the EOD
> case.  Should I just restore the C-M-[ae] bindings in c-mode-base-map?
>>> It won't work when point is outside a defun.  And a combination of
>>> (BOD) and (EOD) isn't capable of reliably determining if point is
>>> outside a defun.
>> Why wouldn't it work to compare the starting position with the position
>> after BOD+EOD?
> Because the sloppiness of the general EOD-function will have left point
> at some random position in the WS between defun-0 and defun-1.  If you
> start somewhere in that WS, BOD+EOD will also leave you somewhere in that
> WS, so comparing those positions gives at best heuristic information.
> To get firm information, you'd have to start doing things like
> c-backward-syntactic-ws and see if you end up before where EOD put you.
> You can't rely on checking for a paren/brace/bracket, because not all
> languages use them (shell script, haskell, ?pascal for example).
> Even (BOD) (BOD -1) isn't necessarily any good, since
> beginning-of-defun-function might well be implemented to go to the
> textually nearest defun regardless of nesting level.  Martin Stjernholm
> suggested this algorithm for CC Mode a while back - it's a good
> suggestion.
>>         Stefan

Hi Alan,

seeing you struggle with well known and long-time
disputed issues, lets take a IMO related source of bugs
and confusion into consideration:

`forward-word' and a couple of similar functions don't
stop at the last char of THING, but one char behind.

Surely there are reasons for it. However, from the
perspective of editing, that seems not comfortable.

After a `forward' you are outside already. So what
should `word-at-point' for example return then?
Logically nil.

Now the fixing may start saying: well, let's consider
just one char behind as inside. Although, with cursor
at single whitespace between two words, where remains
justice, if the word before is taken, but the word
after not?

People must remember illogical behaviour at these
occasions, workarounds with bug-risks are the result.

That's the point I started out to write
`thing-at-point-utils.el'. Fixing this opened
the path to a whole range of useful functions.

For editing C-modes all the delimiting functions as
`braced-atpt' should be of interest.

You get it at


Thanks all

Andreas Röhler

reply via email to

[Prev in Thread] Current Thread [Next in Thread]