unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* simplifying beginning-of-defun
@ 2009-09-26 17:52 Andreas Roehler
  2009-09-26 21:44 ` Stefan Monnier
  2009-09-27 19:06 ` Glenn Morris
  0 siblings, 2 replies; 18+ messages in thread
From: Andreas Roehler @ 2009-09-26 17:52 UTC (permalink / raw)
  To: XEmacs-Beta; +Cc: emacs-devel


Hi,

simplifying forms as below should ease maintenance and speed up execution.

With var `beginning-of-defun-function' its not
necessary to fix all at once at a single place: progmodes
may write their own functions and M-x
`beginning-of-defun' will work with them.

Just to present the code for the moment. If agreed so
far, I'll send a patch next days.

Cheers


Andreas

--
https://code.launchpad.net/s-x-emacs-werkstatt/
http://bazaar.launchpad.net/~a-roehler/python-mode/python-mode.el/


;;;;;;;;;;;


;; Works with XEmacs as with GNU.
;; GNU-folks:
;; de-comment line below before checking. GNU's lisp.el
;; sets this var globally, which seems not useful for me...

;; (setq end-of-defun-function nil)

(setq defun-searchform '(if defun-prompt-regexp
                              (concat "^\\s(\\|"
                                      "\\(" defun-prompt-regexp "\\)\\s(")
                            "^\\s("))

(defun beginning-of-defun (&optional arg)
  "Move backward to the beginning of a functions definition. "
  (interactive "P")
  (or arg (setq arg 1))
  (if beginning-of-defun-function
      (funcall beginning-of-defun-function arg)
    (beginning-of-defun-raw arg)))

(defun beginning-of-defun-raw (&optional arg)
  "Called if progmodes didn't set beginning-of-defun-function. "
  (when
      (re-search-backward (eval defun-searchform) nil 'move (or arg 1))
    (goto-char (match-beginning 0))))

(defun end-of-defun (&optional arg)
  "Move backward to the end of a function. "
  (interactive "P")
  (or arg (setq arg 1))
  (if end-of-defun-function
      (funcall end-of-defun-function arg)
    (end-of-defun-raw arg)))

(defun end-of-defun-raw (&optional arg)
    "Called if progmodes didn't set end-of-defun-function. "
  (unless (looking-at (eval defun-searchform))
    (beginning-of-defun 1))
  (forward-sexp 1)
  (when (re-search-forward (eval defun-searchform) nil t arg)
  (goto-char (match-beginning 0))
  (forward-sexp 1)))

;;;;;;;




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-26 17:52 simplifying beginning-of-defun Andreas Roehler
@ 2009-09-26 21:44 ` Stefan Monnier
  2009-09-27  8:10   ` Andreas Roehler
  2009-09-27 10:26   ` Andreas Roehler
  2009-09-27 19:06 ` Glenn Morris
  1 sibling, 2 replies; 18+ messages in thread
From: Stefan Monnier @ 2009-09-26 21:44 UTC (permalink / raw)
  To: Andreas Roehler; +Cc: emacs-devel, XEmacs-Beta

> simplifying forms as below should ease maintenance and speed up execution.

To what extent does it preserve compatibility?

Apparently it makes beginning-of-defun-raw ignore
beginning-of-defun-function, and it calls end-of-defun-function with one
argument contrary to the current situation where it's called without
any argument.  So your code wouldn't be acceptable as is since it would
likely break several packages.

Which performance problem is it trying to solve?

The main difference I see between your beginning-of-defun and Emacs's
one is that yours doesn't try to handle the case where
beginning-of-defun-function, defun-prompt-regexp, and
open-paren-in-column-0-is-defun-start and all nil.  This case was added
fairly recently (Emacs-22, IIRC) after a long discussion.  I do not like
this extra case at all, actually, but if you're trying to get rid of it,
please make it a separate thread.

In other words, if you send new code just to simplify the existing one,
than make sure the incompatibilities are clearly understood and
"minor".  Otherwise, better focus on the proposal for the change in
behavior, and then accompany that with a patch showing how you suggest
to implement this change.


        Stefan




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-26 21:44 ` Stefan Monnier
@ 2009-09-27  8:10   ` Andreas Roehler
  2009-09-27 18:40     ` Stefan Monnier
  2009-09-27 10:26   ` Andreas Roehler
  1 sibling, 1 reply; 18+ messages in thread
From: Andreas Roehler @ 2009-09-27  8:10 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, python-mode, XEmacs-Beta

Stefan Monnier wrote:
>> simplifying forms as below should ease maintenance and speed up execution.
> 
> To what extent does it preserve compatibility?

Don't see anything incompatible for the moment. OTOH it will take some feasible bugs from progmodes.

It underlines a paradigm change, which was introduced
with var `beginning-of-defun-function' already.

These facility departs from all-at-once solutions,
which have been likely creating a bug in the back,
while solving one in the forehead.

With `beginning-of-defun-function',
`end-of-defun-function' python-mode for example

https://launchpad.net/python-mode

may set its own function and M-x beginning-of-defun then
will work still - which is not the case presently and my point of
depart here.


> 
> Apparently it makes beginning-of-defun-raw ignore
> beginning-of-defun-function, and it calls end-of-defun-function with one
> argument contrary to the current situation where it's called without
> any argument. 

An argument is useful here: as a repeat or specifier.

 So your code wouldn't be acceptable as is since it would
> likely break several packages.
> 
> Which performance problem is it trying to solve?

All which useless code execution causes.
Regard the lines of code saved that way to have an approximation.


> 
> The main difference I see between your beginning-of-defun and Emacs's
> one is that yours doesn't try to handle the case where
> beginning-of-defun-function, defun-prompt-regexp, and
> open-paren-in-column-0-is-defun-start and all nil.  This case was added
> fairly recently (Emacs-22, IIRC) after a long discussion. 

Gladly to see, discussions here seldom turn out that badly. :)

open-paren-in-column-0-is-defun-start is purely redundant, as the regexp may specify that
- and indeed does already(?) its just that what I read with "^\\s("


 I do not like
> this extra case at all, actually, but if you're trying to get rid of it,
> please make it a separate thread.
> 
> In other words, if you send new code just to simplify the existing one,
> than make sure the incompatibilities

Mentioned code of a end-of-defun-function in lisp.el is a bug.
Suggest to cancel it.

Let the -raw functions do everything needed for emacs-lisp.
Funcalls of beginning-of-defun-function, end-of-defun-function should be reserved for progmodes.

BTW if mode-specific, probably it should be introduced as a local var from the very beginning?

 are clearly understood and
> "minor". 

 Otherwise, better focus on the proposal for the change in
> behavior, and then accompany that with a patch showing how you suggest
> to implement this change.
> 
> 
>         Stefan
> 

Found a bug still in end-of-defun. Changed code below:



;; GNU's lisp.el
;; unhappily sets this var globally, ignoring its use for progmodes
(when (featurep 'emacs) (setq end-of-defun-function nil))

(setq defun-searchform '(if defun-prompt-regexp
                              (concat "^\\s(\\|"
                                      "\\(" defun-prompt-regexp "\\)\\s(")
                            "^\\s("))

(defun beginning-of-defun (&optional arg)
  "Move backward to the beginning of a functions definition. "
  (interactive "P")
  (or arg (setq arg 1))
  (if beginning-of-defun-function
      (funcall beginning-of-defun-function arg)
    (beginning-of-defun-raw arg)))

(defun beginning-of-defun-raw (&optional arg)
  "Called if progmodes didn't set beginning-of-defun-function. "
  (when
      (re-search-backward (eval defun-searchform) nil 'move (or arg 1))
    (goto-char (match-beginning 0))))

(defun end-of-defun (&optional arg)
  "Move backward to the end of a function. "
  (interactive "P")
  (or arg (setq arg 1))
  (if end-of-defun-function
      (funcall end-of-defun-function arg)
    (end-of-defun-raw arg)))

(defun end-of-defun-raw (&optional arg)
    "Called if progmodes didn't set end-of-defun-function. "
    (skip-chars-forward " \t\r\n\f")
  (when (looking-at (eval defun-searchform))
    (forward-char -1))
  (when (re-search-forward (eval defun-searchform) nil t arg)
  (goto-char (match-beginning 0))
  (forward-sexp 1)))

;;;;;;;;;;;

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-26 21:44 ` Stefan Monnier
  2009-09-27  8:10   ` Andreas Roehler
@ 2009-09-27 10:26   ` Andreas Roehler
  2009-09-27 11:17     ` Eric M. Ludlam
  1 sibling, 1 reply; 18+ messages in thread
From: Andreas Roehler @ 2009-09-27 10:26 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: XEmacs-Beta, emacs-devel

...
> any argument.  So your code wouldn't be acceptable as is since it would
> likely break several packages.
> 

...


Hi Stefan,

reflecting this question a little bit further:

as expressive settings of `push-mark' are removed, some functions
while rely upon and fail then.

However, `push-mark' is a very basic and considerable
editing command. If a function needs it, it should implement it at place.

Suggest keeping things apart: move functions should
move, not deliver a hair-cut. :)

If more is needed, another function should take over than.

All-at-once essays create complexity and never ending
bugs finally.

So far, think simplifying is worthwhile on the longer run.


Andreas

--
https://code.launchpad.net/s-x-emacs-werkstatt/
http://bazaar.launchpad.net/~a-roehler/python-mode/python-mode.el/




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-27 10:26   ` Andreas Roehler
@ 2009-09-27 11:17     ` Eric M. Ludlam
  2009-09-27 18:53       ` Stefan Monnier
  0 siblings, 1 reply; 18+ messages in thread
From: Eric M. Ludlam @ 2009-09-27 11:17 UTC (permalink / raw)
  To: Andreas Roehler; +Cc: emacs-devel, Stefan Monnier, XEmacs-Beta

On Sun, 2009-09-27 at 12:26 +0200, Andreas Roehler wrote:
> ...
> > any argument.  So your code wouldn't be acceptable as is since it would
> > likely break several packages.
> > 
> 
> ...
> 
> 
> Hi Stefan,
> 
> reflecting this question a little bit further:
> 
> as expressive settings of `push-mark' are removed, some functions
> while rely upon and fail then.
> 
> However, `push-mark' is a very basic and considerable
> editing command. If a function needs it, it should implement it at place.
> 
> Suggest keeping things apart: move functions should
> move, not deliver a hair-cut. :)
> 
> If more is needed, another function should take over than.
> 
> All-at-once essays create complexity and never ending
> bugs finally.
> 
> So far, think simplifying is worthwhile on the longer run.
> 
> 
> Andreas

I agree with the basic mechanics of what Andreas is providing here, not
any specific feature change involved in the patch.  If there were some
function like the -raw functions he proposed that program modes would
use if they wanted exactly that behavior, and a separate interactive
function, then that opens the door for improvements on the interactive
function.

This comes up specifically with CEDET, where I can use parser
information to do a real `beginning-of-defun' for langauges whos defuns
don't happen to start with a ( in the first column.  From an interactive
point of view, a total win.  From a programs point of view, this would
mean disaster if all their code was expecting the cursor to show up on
some opening {, and not on the text actually starting the defun.

For modes like cc-mode that write their own correct
`beginning-of-defun', they would use that internally anyway, so no loss.


Right now, the feature I describe in CEDET/Semantic is done with advice
and various if statements making sure not to do the modification in
non-interactive cases.  The code is in senator.el.

http://cedet.cvs.sourceforge.net/viewvc/cedet/cedet/semantic/senator.el?view=markup

Eric




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-27  8:10   ` Andreas Roehler
@ 2009-09-27 18:40     ` Stefan Monnier
  2009-09-28  6:50       ` Andreas Roehler
  0 siblings, 1 reply; 18+ messages in thread
From: Stefan Monnier @ 2009-09-27 18:40 UTC (permalink / raw)
  To: Andreas Roehler; +Cc: XEmacs-Beta, python-mode, emacs-devel

>>> simplifying forms as below should ease maintenance and speed up execution.
>> To what extent does it preserve compatibility?
> Don't see anything incompatible for the moment.

I actually mentionned obvious incompatibilities in the email to which
you reply.

> With `beginning-of-defun-function',
> `end-of-defun-function' python-mode for example
> https://launchpad.net/python-mode
> may set its own function and M-x beginning-of-defun then
> will work still - which is not the case presently and my point of
> depart here.

I do not understand the above paragraph.

>> Apparently it makes beginning-of-defun-raw ignore
>> beginning-of-defun-function, and it calls end-of-defun-function with one
>> argument contrary to the current situation where it's called without
>> any argument.
> An argument is useful here: as a repeat or specifier.

I was pointing out incompatibilities.  Also the current way
end-of-defun-function is defined, it does not need a repeat because it
only jumps from the beginning of a defun to its end (i.e. it doesn't do
the same as end-of-defun).

>> Which performance problem is it trying to solve?
> All which useless code execution causes.
> Regard the lines of code saved that way to have an approximation.

This is much too general: OT1H it's not true (larger code is not
necessarily slower), OTOH (and more importantly) it doesn't help me
understand which specific performance problem this is aiming to address.

> open-paren-in-column-0-is-defun-start is purely redundant, as the
> regexp may specify that - and indeed does already(?) its just that
> what I read with "^\\s("

Again, please move this discussion to a separate thread.

> Mentioned code of a end-of-defun-function in lisp.el is a bug.
> Suggest to cancel it.

I do not know which code nor which bug you talking about.  Your code?
Emacs's code?

> Let the -raw functions do everything needed for emacs-lisp.

AFAICT, that's already the way it's designed (that's why it doesn't set
the mark, for example).

> Funcalls of beginning-of-defun-function, end-of-defun-function should
> be reserved for progmodes.

I have no idea what you mean by "progmodes".

> BTW if mode-specific, probably it should be introduced as a local var
> from the very beginning?

I'm not sure I understand.  Are you suggesting we
(make-varible-buffer-local 'beginning-of-defun-function)?


        Stefan




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-27 11:17     ` Eric M. Ludlam
@ 2009-09-27 18:53       ` Stefan Monnier
  2009-09-27 20:07         ` Eric M. Ludlam
  0 siblings, 1 reply; 18+ messages in thread
From: Stefan Monnier @ 2009-09-27 18:53 UTC (permalink / raw)
  To: eric; +Cc: emacs-devel, Andreas Roehler, XEmacs-Beta

> I agree with the basic mechanics of what Andreas is providing here, not
> any specific feature change involved in the patch.  If there were some
> function like the -raw functions he proposed that program modes would
> use if they wanted exactly that behavior, and a separate interactive
> function, then that opens the door for improvements on the interactive
> function.

We already have beginning-of-defun and beginning-of-defun-raw exactly
for these kinds of reasons.

> This comes up specifically with CEDET, where I can use parser
> information to do a real `beginning-of-defun' for langauges whos defuns
> don't happen to start with a ( in the first column.  From an interactive
> point of view, a total win.

So you mean you'd want both beginning-of-defun-raw-function and
beginning-of-defun-function (additionally to (define-key map [remap
beginning-of-defun] ...), of course)?
I'd have to think about it.

> From a programs point of view, this would mean disaster if all their
> code was expecting the cursor to show up on some opening {, and not on
> the text actually starting the defun.  For modes like cc-mode that
> write their own correct `beginning-of-defun', they would use that
> internally anyway, so no loss.

So you mean we should provide a default-beginning-of-defun which is not
subject to any *-function fiddling and change some of the calls to
beginning-of-defun to use that function instead, so they're more robust
in cases where something like CEDET sets beginning-of-defun-function?
That makes sense, yet.

> Right now, the feature I describe in CEDET/Semantic is done with advice
> and various if statements making sure not to do the modification in
> non-interactive cases.  The code is in senator.el.

I think that interactive/noninteractive is not the right distinction
(there are non-interactive cases which would also benefit from using an
improved implementation).  It's probably the best (conservative)
solution you could use, because the right solution requires more changes
to other packages.


        Stefan




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-26 17:52 simplifying beginning-of-defun Andreas Roehler
  2009-09-26 21:44 ` Stefan Monnier
@ 2009-09-27 19:06 ` Glenn Morris
  1 sibling, 0 replies; 18+ messages in thread
From: Glenn Morris @ 2009-09-27 19:06 UTC (permalink / raw)
  To: Andreas Roehler; +Cc: emacs-devel, XEmacs-Beta

Andreas Roehler wrote:

> Just to present the code for the moment. If agreed so far, I'll send
> a patch next days.

I thought you were opposed in principle to completing a copyright
assignment. If so, there isn't really any point in you sending code to
emacs-devel.

http://lists.gnu.org/archive/html/emacs-devel/2008-03/msg00029.html




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-27 18:53       ` Stefan Monnier
@ 2009-09-27 20:07         ` Eric M. Ludlam
  2009-09-27 22:52           ` Stefan Monnier
  0 siblings, 1 reply; 18+ messages in thread
From: Eric M. Ludlam @ 2009-09-27 20:07 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, Andreas Roehler, XEmacs-Beta

On Sun, 2009-09-27 at 14:53 -0400, Stefan Monnier wrote:
> > I agree with the basic mechanics of what Andreas is providing here, not
> > any specific feature change involved in the patch.  If there were some
> > function like the -raw functions he proposed that program modes would
> > use if they wanted exactly that behavior, and a separate interactive
> > function, then that opens the door for improvements on the interactive
> > function.
> 
> We already have beginning-of-defun and beginning-of-defun-raw exactly
> for these kinds of reasons.

Ok.  I didn't research before responding. ;)

I just now grepped around, and no programs use beginning-of-defun-raw,
but they do use beginning-of-defun, and some use
MODE-beginning-of-defun.

> > This comes up specifically with CEDET, where I can use parser
> > information to do a real `beginning-of-defun' for langauges whos defuns
> > don't happen to start with a ( in the first column.  From an interactive
> > point of view, a total win.
> 
> So you mean you'd want both beginning-of-defun-raw-function and
> beginning-of-defun-function (additionally to (define-key map [remap
> beginning-of-defun] ...), of course)?
> I'd have to think about it.

I think there are these variants:

* A program wants the default behavior

* A major mode wants to change the interactive form

* A program wants use the major-mode behavior

* A third tool (ie - cedet) wants to change the interactive forms
  without breaking the above three, and without modifying the global map

> > From a programs point of view, this would mean disaster if all their
> > code was expecting the cursor to show up on some opening {, and not on
> > the text actually starting the defun.  For modes like cc-mode that
> > write their own correct `beginning-of-defun', they would use that
> > internally anyway, so no loss.
> 
> So you mean we should provide a default-beginning-of-defun which is not
> subject to any *-function fiddling and change some of the calls to
> beginning-of-defun to use that function instead, so they're more robust
> in cases where something like CEDET sets beginning-of-defun-function?
> That makes sense, yet.

That is one solution, though I'm not sure about the
beginning-of-defun-function setting, as the major mode may expect the
function to be set as done in the major-mode.

> > Right now, the feature I describe in CEDET/Semantic is done with advice
> > and various if statements making sure not to do the modification in
> > non-interactive cases.  The code is in senator.el.
> 
> I think that interactive/noninteractive is not the right distinction
> (there are non-interactive cases which would also benefit from using an
> improved implementation).  It's probably the best (conservative)
> solution you could use, because the right solution requires more changes
> to other packages.

Exactly.

By way of example, the `set-mark' function has doc that specifically
says not to use it in programs, and suggests some other function to use.
Thus, someone could add advice to `set-mark' or `set-mark-command' to
add some glitz, but programs remain safe from the change.

I think of CEDET as being able to 'glitz' up functions like
beginning-of-defun by making them accurate.  Programs that actually want
to use CEDET to get the more accurate behavior will not use
'beginning-of-defun' at all.  They would instead get the current tag at
point, from which the location of the start/end of the tag is readily
available, along with a bunch of other info.  Tweaking
beginning-of-defun is only useful as a way of giving the user a better
experience.

Other packages that use beginning-of-defun as a function currently work
as is, so we don't want to change the behavior for those uses.  If those
packages want the new behavior, there are plenty of APIs in
CEDET/Semantic to do what they want at their leisure.

Eric




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-27 20:07         ` Eric M. Ludlam
@ 2009-09-27 22:52           ` Stefan Monnier
  2009-09-28  2:04             ` Eric M. Ludlam
  0 siblings, 1 reply; 18+ messages in thread
From: Stefan Monnier @ 2009-09-27 22:52 UTC (permalink / raw)
  To: eric; +Cc: emacs-devel, Andreas Roehler, XEmacs-Beta

>> We already have beginning-of-defun and beginning-of-defun-raw exactly
>> for these kinds of reasons.
> Ok.  I didn't research before responding. ;)
> I just now grepped around, and no programs use beginning-of-defun-raw,
> but they do use beginning-of-defun, and some use
> MODE-beginning-of-defun.

Yes, this area is sufficiently messy (and different between versions
and flavors of Emacs) that only the main entry point is ever used.

> I think there are these variants:

> * A program wants the default behavior
> * A major mode wants to change the interactive form
> * A program wants use the major-mode behavior
> * A third tool (ie - cedet) wants to change the interactive forms
>   without breaking the above three, and without modifying the global map

I can't think of a reason why #3 wouldn't want to be affected by #4.
Note that for #2, it's not just the interactive form, since it also
affects #3 (e.g. mark-defun, send-defun-to-inferior-process, younameit,
...).

> That is one solution, though I'm not sure about the
> beginning-of-defun-function setting, as the major mode may expect the
> function to be set as done in the major-mode.

Yes, it appears that some major-mode that set
beginning-of-defun-function also call beginning-of-defun, so there's
a chance that one of those calls actually is wrong and should call the
major-mode's code rather than going through beginning-of-defun-function.
It's OK: such bugs need to be fixed, it's not CEDET's responsibility if
the major mode breaks in this case.

>> I think that interactive/noninteractive is not the right distinction
>> (there are non-interactive cases which would also benefit from using an
>> improved implementation).  It's probably the best (conservative)
>> solution you could use, because the right solution requires more changes
>> to other packages.
[...]
> I think of CEDET as being able to 'glitz' up functions like
> beginning-of-defun by making them accurate.  Programs that actually want
> to use CEDET to get the more accurate behavior will not use
> 'beginning-of-defun' at all.

What about programs that want to use CEDET but that also want to work
when CEDET is not available?  They would most likely want to use
beginning-of-defun.


        Stefan




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-27 22:52           ` Stefan Monnier
@ 2009-09-28  2:04             ` Eric M. Ludlam
  2009-09-28  4:06               ` Stefan Monnier
  2009-09-29  6:50               ` Alan Mackenzie
  0 siblings, 2 replies; 18+ messages in thread
From: Eric M. Ludlam @ 2009-09-28  2:04 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, Andreas Roehler, XEmacs-Beta

On Sun, 2009-09-27 at 18:52 -0400, Stefan Monnier wrote:

> 
> > I think there are these variants:
> 
> > * A program wants the default behavior
> > * A major mode wants to change the interactive form
> > * A program wants use the major-mode behavior
> > * A third tool (ie - cedet) wants to change the interactive forms
> >   without breaking the above three, and without modifying the global map
> 
> I can't think of a reason why #3 wouldn't want to be affected by #4.
> Note that for #2, it's not just the interactive form, since it also
> affects #3 (e.g. mark-defun, send-defun-to-inferior-process, younameit,
> ...).

Hmmm.  A dilemma.  Given this C code:

int
main()
{
  return 0;
}

The original beginning-of-defun stops at the {.  (ie, if you unset
beginning-of-defun-function).

The c variant knows to stop at the i in int.
CEDET also knows to stop at the i in int.

In effect, cc-mode, and CEDET agree.  It doesn't matter who takes over
beginning-of-defun duty.

In this C++ example:


namespace foo {

  int myfcn() {
    return 1;
  }

}

If the cursor is on the "return", beginning-of-defun-raw gets completely
lost, cc-mode jumps to namespace, and CEDET jumps to the i in int.

For the range of interactive fcns you mentioned above, when used
interactively, the CEDET behavior is preferred.  Within cc-mode, it
likely needs to land on the namespace line because that is what it
historically has done.  The base behavior, of course, is not really
desirable.  Sure, a user could re-indent their code, but that is not
always an option.

Of course, perhaps I am wrong in thinking that stopping on 'int' is
preferred, but I do know it is preferred by me.  Would this make the
CEDET behavior as found in 'senator' completely new in some way?


> > I think of CEDET as being able to 'glitz' up functions like
> > beginning-of-defun by making them accurate.  Programs that actually want
> > to use CEDET to get the more accurate behavior will not use
> > 'beginning-of-defun' at all.
> 
> What about programs that want to use CEDET but that also want to work
> when CEDET is not available?  They would most likely want to use
> beginning-of-defun.

I had not contemplated this in the context of beginning-of-defun.
Ideally they would not need some if statement to deal with the issue.
Of course, the need here would be pretty basic stuff too if it was
robust to the actual landing place being different for different
situations, sort of the way narrow-to-defun might not care exactly where
it lands, so long as it goes somewhere.

Eric




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-28  2:04             ` Eric M. Ludlam
@ 2009-09-28  4:06               ` Stefan Monnier
  2009-09-28 11:20                 ` Eric M. Ludlam
  2009-09-29  6:50               ` Alan Mackenzie
  1 sibling, 1 reply; 18+ messages in thread
From: Stefan Monnier @ 2009-09-28  4:06 UTC (permalink / raw)
  To: eric; +Cc: emacs-devel, Andreas Roehler, XEmacs-Beta

>> I can't think of a reason why #3 wouldn't want to be affected by #4.
>> Note that for #2, it's not just the interactive form, since it also
>> affects #3 (e.g. mark-defun, send-defun-to-inferior-process, younameit,
>> ...).
> Hmmm.  A dilemma.  Given this C code:

I'm not sure what problem/dilemma you're alluding to.

> Of course, perhaps I am wrong in thinking that stopping on 'int' is
> preferred, but I do know it is preferred by me.  Would this make the
> CEDET behavior as found in 'senator' completely new in some way?

I guess it would, but then again I have no idea why it would matter
whether it's completely new or not (i.e. I don't understand what you're
trying to say, I guess).

>> What about programs that want to use CEDET but that also want to work
>> when CEDET is not available?  They would most likely want to use
>> beginning-of-defun.
> I had not contemplated this in the context of beginning-of-defun.
> Ideally they would not need some if statement to deal with the issue.

Exactly.

> Of course, the need here would be pretty basic stuff too if it was
> robust to the actual landing place being different for different
> situations, sort of the way narrow-to-defun might not care exactly where
> it lands, so long as it goes somewhere.

Very much so, indeed.
I'd say that pretty much all calls to beginning-of-defun(-raw) should
follow this principle.


        Stefan




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-27 18:40     ` Stefan Monnier
@ 2009-09-28  6:50       ` Andreas Roehler
  2009-09-28 22:46         ` Stefan Monnier
  0 siblings, 1 reply; 18+ messages in thread
From: Andreas Roehler @ 2009-09-28  6:50 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, Eric M. Ludlam, XEmacs-Beta

Stefan Monnier wrote:
>>>> simplifying forms as below should ease maintenance and speed up execution.
>>> To what extent does it preserve compatibility?
>> Don't see anything incompatible for the moment.
> 
> I actually mentionned obvious incompatibilities in the email to which
> you reply.
> 
>> With `beginning-of-defun-function',
>> `end-of-defun-function' python-mode for example
>> https://launchpad.net/python-mode
>> may set its own function and M-x beginning-of-defun then
>> will work still - which is not the case presently and my point of
>> depart here.
> 
> I do not understand the above paragraph.
> 
>>> Apparently it makes beginning-of-defun-raw ignore
>>> beginning-of-defun-function, and it calls end-of-defun-function with one
>>> argument contrary to the current situation where it's called without
>>> any argument.
>> An argument is useful here: as a repeat or specifier.
> 
> I was pointing out incompatibilities. 


Can't see any. If you write

>>> Apparently it makes beginning-of-defun-raw ignore
>>> beginning-of-defun-function,

it should do exactly that IMHO. Beginning-of-defun-function
was already called  by beginning-of-defun in my scheme - if necessary.


 Also the current way
> end-of-defun-function is defined, it does not need a repeat because it
> only jumps from the beginning of a defun to its end (i.e. it doesn't do
> the same as end-of-defun).
> 


Why not let modes say what they want and need? An argument must not mean a
repeat BTW. In python-mode is a selection to deliver too.



>>> Which performance problem is it trying to solve?
>> All which useless code execution causes.
>> Regard the lines of code saved that way to have an approximation.
> 
> This is much too general: OT1H it's not true (larger code is not
> necessarily slower), OTOH (and more importantly) it doesn't help me
> understand which specific performance problem this is aiming to address.
> 
>> open-paren-in-column-0-is-defun-start is purely redundant, as the
>> regexp may specify that - and indeed does already(?) its just that
>> what I read with "^\\s("
> 
> Again, please move this discussion to a separate thread.
> 
>> Mentioned code of a end-of-defun-function in lisp.el is a bug.
>> Suggest to cancel it.
> 
> I do not know which code nor which bug you talking about.  Your code?
> Emacs's code?

from GNU lisp.el.

"(defvar end-of-defun-function
  (lambda () ...."

Giving it a value here, it will be called. Which is
to avoid, as only languages-modes should set and use it.

This setting reintroduces all the mess, beginning/end-of-defun-function are invented for.



> 
>> Let the -raw functions do everything needed for emacs-lisp.
> 
> AFAICT, that's already the way it's designed (that's why it doesn't set
> the mark, for example).
> 
>> Funcalls of beginning-of-defun-function, end-of-defun-function should
>> be reserved for progmodes.
> 
> I have no idea what you mean by "progmodes".

Modes of other programming languages than emacs-lisp

> 
>> BTW if mode-specific, probably it should be introduced as a local var
>> from the very beginning?
> 
> I'm not sure I understand.  Are you suggesting we
> (make-varible-buffer-local 'beginning-of-defun-function)?
> 

Yes, that's the question. I.e it should be mode-specific, in any case not global.

Andreas
> 
>         Stefan
> 
> 
> 





^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-28  4:06               ` Stefan Monnier
@ 2009-09-28 11:20                 ` Eric M. Ludlam
  0 siblings, 0 replies; 18+ messages in thread
From: Eric M. Ludlam @ 2009-09-28 11:20 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, Andreas Roehler, XEmacs-Beta

On Mon, 2009-09-28 at 00:06 -0400, Stefan Monnier wrote:
> 
> > Of course, the need here would be pretty basic stuff too if it was
> > robust to the actual landing place being different for different
> > situations, sort of the way narrow-to-defun might not care exactly where
> > it lands, so long as it goes somewhere.
> 
> Very much so, indeed.
> I'd say that pretty much all calls to beginning-of-defun(-raw) should
> follow this principle.

I think this sums up our difference in opinion.  If this is true, then
none of my previous arguments make sense.  If this is not the case, then
the code that does depend on very specific behaviors from
beginning-of-defun will break if CEDET were to change them.

I'll follow whichever convention you like.

Eric




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-28  6:50       ` Andreas Roehler
@ 2009-09-28 22:46         ` Stefan Monnier
  2009-09-29  6:53           ` Andreas Roehler
  2009-09-29  8:29           ` Andreas Roehler
  0 siblings, 2 replies; 18+ messages in thread
From: Stefan Monnier @ 2009-09-28 22:46 UTC (permalink / raw)
  To: Andreas Roehler; +Cc: emacs-devel, Eric M. Ludlam, XEmacs-Beta

>> I was pointing out incompatibilities. 
> Can't see any. If you write
>>>> Apparently it makes beginning-of-defun-raw ignore
>>>> beginning-of-defun-function,
> it should do exactly that IMHO.

Maybe it should, maybe it shouuldn't.  My point is that it currently
does whereas in your patch it doesn't, so that's an incompatibility.
That doesn't mean it's a problem, just a place that requires
careful attention.

> Why not let modes say what they want and need? An argument must not mean a
> repeat BTW. In python-mode is a selection to deliver too.

end-of-defun's docstring says "With argument, do it that many times", so
if a major mode uses it for other purposes, it's abusing it.  It would
probably be better in such a case to just define a new command and remap
keys to that new command.

>>> Mentioned code of a end-of-defun-function in lisp.el is a bug.
>>> Suggest to cancel it.
>> I do not know which code nor which bug you talking about.  Your code?
>> Emacs's code?
> from GNU lisp.el.

> "(defvar end-of-defun-function
>   (lambda () ...."

> Giving it a value here, it will be called.  Which is
> to avoid, as only languages-modes should set and use it.

Who says?

> This setting reintroduces all the mess,
> beginning/end-of-defun-function are invented for.

I do not know what you're referring to.

>>> Funcalls of beginning-of-defun-function, end-of-defun-function should
>>> be reserved for progmodes.
>> I have no idea what you mean by "progmodes".
> Modes of other programming languages than emacs-lisp

Why would such a concept matter here?  emacs-lisp-mode should not be
treated specially.

>>> BTW if mode-specific, probably it should be introduced as a local var
>>> from the very beginning?
>> I'm not sure I understand.  Are you suggesting we
>> (make-varible-buffer-local 'beginning-of-defun-function)?
> Yes, that's the question. I.e it should be mode-specific, in any case
> not global.

It's definitely meant to be buffer-local.  That doesn't mean there
shouldn't be a meaningful default for those buffers which don't want to
bother to set it themselves.


        Stefan




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-28  2:04             ` Eric M. Ludlam
  2009-09-28  4:06               ` Stefan Monnier
@ 2009-09-29  6:50               ` Alan Mackenzie
  1 sibling, 0 replies; 18+ messages in thread
From: Alan Mackenzie @ 2009-09-29  6:50 UTC (permalink / raw)
  To: Eric M. Ludlam; +Cc: XEmacs-Beta, Andreas Roehler, Stefan Monnier, emacs-devel

Hi, Eric!

On Sun, Sep 27, 2009 at 10:04:48PM -0400, Eric M. Ludlam wrote:

[ .... ]

> In this C++ example:


> namespace foo {

>   int myfcn() {
>     return 1;
>   }

> }

> If the cursor is on the "return", beginning-of-defun-raw gets completely
> lost, cc-mode jumps to namespace, and CEDET jumps to the i in int.

As a matter of interest, the c-beginning-of-defun in the upcoming CC Mode
5.32 now also jumps to the "int".  (There will, of course, be an option
variable for people who really, really want to carry on going back to
"namespace".)  I'm hoping to release this sometime next decade.

> Eric

-- 
Alan Mackenzie (Nuremberg, Germany).




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-28 22:46         ` Stefan Monnier
@ 2009-09-29  6:53           ` Andreas Roehler
  2009-09-29  8:29           ` Andreas Roehler
  1 sibling, 0 replies; 18+ messages in thread
From: Andreas Roehler @ 2009-09-29  6:53 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: XEmacs-Beta, emacs-devel

Stefan Monnier wrote:
>>> I was pointing out incompatibilities. 
>> Can't see any. If you write
>>>>> Apparently it makes beginning-of-defun-raw ignore
>>>>> beginning-of-defun-function,
>> it should do exactly that IMHO.
> 
> Maybe it should, maybe it shouuldn't.  My point is that it currently
> does whereas in your patch it doesn't, so that's an incompatibility.
> That doesn't mean it's a problem, just a place that requires
> careful attention.


Just did range things differently - and weeded out a little bit.

Maybe lets rest the issue for now. Should a bug report hit the matter. I'll
point you to it again.


> 
>> Why not let modes say what they want and need? An argument must not mean a
>> repeat BTW. In python-mode is a selection to deliver too.
> 
> end-of-defun's docstring says "With argument, do it that many times", so
> if a major mode uses it for other purposes, it's abusing it.

This docstring now belongs to the -raw function. (Or -intern, as I will
call it.) Thanks for the hint.



  It would
> probably be better in such a case to just define a new command and remap
> keys to that new command.
>

No need for such things. Everything should work as before,
but some bugs shall be gone. (Beside the GNU-push-mark case, but didn't encounter any
broken function from it for now)

>>>> Mentioned code of a end-of-defun-function in lisp.el is a bug.
>>>> Suggest to cancel it.
>>> I do not know which code nor which bug you talking about.  Your code?
>>> Emacs's code?
>> from GNU lisp.el.
> 
>> "(defvar end-of-defun-function
>>   (lambda () ...."
> 
>> Giving it a value here, it will be called.  Which is
>> to avoid, as only languages-modes should set and use it.
> 
> Who says?
> 

>> This setting reintroduces all the mess,
>> beginning/end-of-defun-function are invented for.
> 
> I do not know what you're referring to.
> 
>>>> Funcalls of beginning-of-defun-function, end-of-defun-function should
>>>> be reserved for progmodes.
>>> I have no idea what you mean by "progmodes".
>> Modes of other programming languages than emacs-lisp
> 
> Why would such a concept matter here?  emacs-lisp-mode should not be
> treated specially.

Why not? Its a special mode and deserves its attention.


> 
>>>> BTW if mode-specific, probably it should be introduced as a local var
>>>> from the very beginning?
>>> I'm not sure I understand.  Are you suggesting we
>>> (make-varible-buffer-local 'beginning-of-defun-function)?
>> Yes, that's the question. I.e it should be mode-specific, in any case
>> not global.
> 
> It's definitely meant to be buffer-local.  That doesn't mean there
> shouldn't be a meaningful default for those buffers which don't want to
> bother to set it themselves.

Ok. So I introduce these forms still:

(make-variable-buffer-local 'beginning-of-defun-function)
(make-variable-buffer-local 'end-of-defun-function)

Thanks again

Andreas
> 
> 
>         Stefan
> 
> 
> 





^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: simplifying beginning-of-defun
  2009-09-28 22:46         ` Stefan Monnier
  2009-09-29  6:53           ` Andreas Roehler
@ 2009-09-29  8:29           ` Andreas Roehler
  1 sibling, 0 replies; 18+ messages in thread
From: Andreas Roehler @ 2009-09-29  8:29 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: Alan Mackenzie, Stephen J. Turnbull, XEmacs-Beta, emacs-devel,
	Eric M. Ludlam

...

> 
> It's definitely meant to be buffer-local.  That doesn't mean there
> shouldn't be a meaningful default 

Hi Stefan,

you are indicating the appropriate name, thanks.

Below a slightly revisited code again.

Renamed beginning/end-of-defun-raw into beginning/end-of-defun-default
Declared beginning/end-of-defun-function buffer-local
Updated the docstrings,


Enjoy!

Andreas

;;;;;;;;;;;;;;

;; For modes other than Emacs-Lisp only, remove wrongly set value
(when (featurep 'emacs) (setq end-of-defun-function nil))

(defvar beginning-of-defun-function nil
  "If non-nil, called by `beginning-of-defun' instead of
`beginning-of-defun-default'. Useful, if `defun-prompt-regexp' is
not sufficient to handle a mode's needs. It's buffer-local. ")
(make-variable-buffer-local 'beginning-of-defun-function)

(defvar end-of-defun-function nil
  "If non-nil, called by `end-of-defun' instead of
`end-of-defun-default'.  Useful if default function is not
appropriate. It's buffer-local. ")
(make-variable-buffer-local 'end-of-defun-function)

(setq defun-searchform '(if defun-prompt-regexp
                              (concat "^\\s(\\|"
                                      "\\(" defun-prompt-regexp "\\)\\s(")
                            "^\\s("))

(defun beginning-of-defun (&optional arg)
  "Move backward to the beginning of a functions definition.
For ARGUMENT see documentation in  `beginning-of-defun-default' resp. in `beginning-of-defun-function', if set. "
  (interactive "P")
  (if beginning-of-defun-function
      (funcall beginning-of-defun-function arg)
    (beginning-of-defun-default arg)))

(defun beginning-of-defun-default (&optional arg)
  "Move backward to next beginning of function definition.
With argument, do it that many times.
Called if modes didn't set beginning-of-defun-function. "
  (or arg (setq arg 1))
  (when
      (re-search-backward (eval defun-searchform) nil 'move (or arg 1))
    (goto-char (match-beginning 0))))

(defun end-of-defun (&optional arg)
  "Move forward to the end of a function.
For ARGUMENT see documentation in `end-of-defun-default' resp. in `end-of-defun-function', if set. "
  (interactive "P")
  (if end-of-defun-function
      (funcall end-of-defun-function arg)
    (end-of-defun-default arg)))

(defun end-of-defun-default (&optional arg)
  "Move forward to next end of function definition.
With argument, do it that many times.
Called if modes didn't set end-of-defun-function. "
  (or arg (setq arg 1))
  (skip-chars-forward " \t\r\n\f")
  (unless (looking-at (eval defun-searchform))
    (beginning-of-defun 1))
  (when (re-search-forward (eval defun-searchform) nil t arg)
    (goto-char (match-beginning 0))
    (forward-sexp 1)))

;;;;;;;;;;;;

for those buffers which don't want to
> bother to set it themselves.
> 
> 
>         Stefan
> 
> 
> 





^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2009-09-29  8:29 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-26 17:52 simplifying beginning-of-defun Andreas Roehler
2009-09-26 21:44 ` Stefan Monnier
2009-09-27  8:10   ` Andreas Roehler
2009-09-27 18:40     ` Stefan Monnier
2009-09-28  6:50       ` Andreas Roehler
2009-09-28 22:46         ` Stefan Monnier
2009-09-29  6:53           ` Andreas Roehler
2009-09-29  8:29           ` Andreas Roehler
2009-09-27 10:26   ` Andreas Roehler
2009-09-27 11:17     ` Eric M. Ludlam
2009-09-27 18:53       ` Stefan Monnier
2009-09-27 20:07         ` Eric M. Ludlam
2009-09-27 22:52           ` Stefan Monnier
2009-09-28  2:04             ` Eric M. Ludlam
2009-09-28  4:06               ` Stefan Monnier
2009-09-28 11:20                 ` Eric M. Ludlam
2009-09-29  6:50               ` Alan Mackenzie
2009-09-27 19:06 ` Glenn Morris

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).