unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* cc-mode Objective C method names
@ 2020-01-01 11:27 Alan Third
  2020-01-01 15:29 ` Stefan Monnier
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Alan Third @ 2020-01-01 11:27 UTC (permalink / raw)
  To: Emacs-Devel devel

[-- Attachment #1: Type: text/plain, Size: 830 bytes --]

One small annoyance I’ve had with developing Emacs is that the
helpers for filling in the changelog entries don’t work with Objective
C methods. I’ve tried writing a patch to make it work.

For reference, an Objective C class looks something like:

@implementation ClassName

- (int)doSomething
{
  /* do that something */
  return 1;
}

- (void)doSomethingTo: (SomeClass *)object with: (int)someParam
{
  return;
}

@end

And I think the methods’ names should be written something like:

-[ClassName doSomething]
-[ClassName doSomethingTo:with:]

The ‘-’ means it’s an instance method and a ‘+’ would mean it was a
class method.

It appears to work for me, but I’m not great at Emacs lisp so I
thought it best to run this by the mailing list in case I’ve made any
boneheaded errors.

Thanks!
-- 
Alan Third

[-- Attachment #2: 0001-Add-ability-to-find-ObjC-method-names.patch --]
[-- Type: text/plain, Size: 1709 bytes --]

From 2945f1c6c57eeabdbeb8e7c058070587a9bf4c0a Mon Sep 17 00:00:00 2001
From: Alan Third <alan@idiocy.org>
Date: Mon, 30 Dec 2019 16:38:47 +0000
Subject: [PATCH] Add ability to find ObjC method names

* lisp/progmodes/cc-cmds.el (c-defun-name-1): Add Objective-C method
name ability.
---
 lisp/progmodes/cc-cmds.el | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 0343f9df32..9165398132 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -2024,6 +2024,36 @@ c-defun-name-1
 	     (c-backward-syntactic-ws)
 	     (point))))
 
+	 ((looking-at "[-+]\\s-*(")     ; Objective-C method
+	  (let ((class
+		 (save-excursion
+		   (re-search-backward "@\\(implementation\\|class\\|interface\\)")
+		   (c-forward-token-2)
+		   (thing-at-point 'word t)))
+		(type (buffer-substring-no-properties (point) (+ (point) 1)))
+		(name
+		 (save-excursion
+		   (c-forward-token-2 2 t)
+		   (let ((name ""))
+		     (while (not (looking-at "[{;]"))
+		       (let ((start (point))
+			     (end
+			      (progn
+				(c-forward-syntactic-ws)
+				(forward-word)
+				(if (looking-at ":")
+				    (+ (point) 1)
+				  (point)))))
+			 (when (looking-at ":")
+			   (c-forward-token-2)
+			   (if (looking-at "(")
+			       (c-forward-token-2 2 t)
+			     (c-forward-token-2 1 t)))
+			 (c-forward-syntactic-ws)
+			 (setq name (concat name (buffer-substring-no-properties start end)))))
+		     name))))
+	    (format "%s[%s %s]" type class name)))
+
 	 (t				; Normal function or initializer.
 	  (when (looking-at c-defun-type-name-decl-key) ; struct, etc.
 	    (goto-char (match-end 0))
-- 
2.24.0


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

* Re: cc-mode Objective C method names
  2020-01-01 11:27 cc-mode Objective C method names Alan Third
@ 2020-01-01 15:29 ` Stefan Monnier
  2020-01-02 11:02   ` Alan Third
  2020-01-01 16:41 ` Eli Zaretskii
  2020-01-04 10:48 ` Alan Mackenzie
  2 siblings, 1 reply; 7+ messages in thread
From: Stefan Monnier @ 2020-01-01 15:29 UTC (permalink / raw)
  To: Alan Third; +Cc: Emacs-Devel devel

> And I think the methods’ names should be written something like:
>
> -[ClassName doSomething]
> -[ClassName doSomethingTo:with:]

These names look very odd to me (as a non-ObjC coder, I find the
brackets rather ugly and useless for example), but if they're the
"normal" way to refer to them, then I guess it's fine.

> The ‘-’ means it’s an instance method and a ‘+’ would mean it was a
> class method.

Might be best not to include it: how often do you have both a class
method and an instance method with the same name?
[ E.g. in Elisp we use the function names and variable names as is,
  without clarifying if it's a function name or a variable name.  ]

> It appears to work for me, but I’m not great at Emacs lisp so I
> thought it best to run this by the mailing list in case I’ve made any
> boneheaded errors.

This is the code of the other Alan and I'm not very familiar with this
part of CC-mode, so don't take my opinion too seriously, but it looks
acceptable to me.

> +			   (if (looking-at "(")
> +			       (c-forward-token-2 2 t)
> +			     (c-forward-token-2 1 t))

AKA
   			   (c-forward-token-2 (if (looking-at "(") 2 1) t)


-- Stefan




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

* Re: cc-mode Objective C method names
  2020-01-01 11:27 cc-mode Objective C method names Alan Third
  2020-01-01 15:29 ` Stefan Monnier
@ 2020-01-01 16:41 ` Eli Zaretskii
  2020-01-04 10:48 ` Alan Mackenzie
  2 siblings, 0 replies; 7+ messages in thread
From: Eli Zaretskii @ 2020-01-01 16:41 UTC (permalink / raw)
  To: Alan Third; +Cc: emacs-devel

> Date: Wed, 1 Jan 2020 11:27:57 +0000
> From: Alan Third <alan@idiocy.org>
> 
> It appears to work for me, but I’m not great at Emacs lisp so I
> thought it best to run this by the mailing list in case I’ve made any
> boneheaded errors.

A few minor nits below:

> +		(type (buffer-substring-no-properties (point) (+ (point) 1)))

I'd use instead

                (type (char-after))

(You'll also need to change the format to use %c instead of %s.)

> +		   (let ((name ""))

There's no need to initialize 'name' to an empty string, because
'append' can DTRT with nil as well:

   (append nil "foo") => "foo"

So just
                   (let (name)

should do.



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

* Re: cc-mode Objective C method names
  2020-01-01 15:29 ` Stefan Monnier
@ 2020-01-02 11:02   ` Alan Third
  0 siblings, 0 replies; 7+ messages in thread
From: Alan Third @ 2020-01-02 11:02 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs-Devel devel

On Wed, Jan 01, 2020 at 10:29:42AM -0500, Stefan Monnier wrote:
> > And I think the methods’ names should be written something like:
> >
> > -[ClassName doSomething]
> > -[ClassName doSomethingTo:with:]
> 
> These names look very odd to me (as a non-ObjC coder, I find the
> brackets rather ugly and useless for example), but if they're the
> "normal" way to refer to them, then I guess it's fine.

I think it’s the normal way, I’m not very clear as there are very few
examples of people referring to methods without the class being
already known.

For example Apple’s documentation only ever refers to methods like this:

- initWithFrame:

or like this:

- (instancetype)initWithFrame:(NSRect)frameRect;

but in neither case does it tell you which class it’s from, you have
to pick it up from other clues on the page.

> > The ‘-’ means it’s an instance method and a ‘+’ would mean it was a
> > class method.
> 
> Might be best not to include it: how often do you have both a class
> method and an instance method with the same name?
> [ E.g. in Elisp we use the function names and variable names as is,
>   without clarifying if it's a function name or a variable name.  ]

It happens quite often, but not in the Emacs code base, which is
presumably the only place this is of use. So I’ll get rid of that.

> > It appears to work for me, but I’m not great at Emacs lisp so I
> > thought it best to run this by the mailing list in case I’ve made any
> > boneheaded errors.
> 
> This is the code of the other Alan and I'm not very familiar with this
> part of CC-mode, so don't take my opinion too seriously, but it looks
> acceptable to me.

I’ll wait a while and see if he has any comments.

> > +			   (if (looking-at "(")
> > +			       (c-forward-token-2 2 t)
> > +			     (c-forward-token-2 1 t))
> 
> AKA
>    			   (c-forward-token-2 (if (looking-at "(") 2 1) t)

Thanks!
-- 
Alan Third



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

* Re: cc-mode Objective C method names
  2020-01-01 11:27 cc-mode Objective C method names Alan Third
  2020-01-01 15:29 ` Stefan Monnier
  2020-01-01 16:41 ` Eli Zaretskii
@ 2020-01-04 10:48 ` Alan Mackenzie
  2020-01-04 11:07   ` HaiJun Zhang
  2020-01-04 17:09   ` Alan Third
  2 siblings, 2 replies; 7+ messages in thread
From: Alan Mackenzie @ 2020-01-04 10:48 UTC (permalink / raw)
  To: Alan Third; +Cc: Emacs-Devel devel

Hello, Alan.

On Wed, Jan 01, 2020 at 11:27:57 +0000, Alan Third wrote:
> One small annoyance I’ve had with developing Emacs is that the
> helpers for filling in the changelog entries don’t work with Objective
> C methods. I’ve tried writing a patch to make it work.

> For reference, an Objective C class looks something like:

> @implementation ClassName

> - (int)doSomething
> {
>   /* do that something */
>   return 1;
> }

> - (void)doSomethingTo: (SomeClass *)object with: (int)someParam
> {
>   return;
> }

> @end

> And I think the methods’ names should be written something like:

> -[ClassName doSomething]
> -[ClassName doSomethingTo:with:]

> The ‘-’ means it’s an instance method and a ‘+’ would mean it was a
> class method.

If either ClassName or doSomethingTo is long, you might be taking up too
much space on, for example, the first line of a commit message.  But
you've probably already thought this through.  How long are these
extended names in practice?

> It appears to work for me, but I’m not great at Emacs lisp so I
> thought it best to run this by the mailing list in case I’ve made any
> boneheaded errors.

I've got just a few comments to add to Eli's and Stefan's, so ....

> Thanks!
> -- 
> Alan Third

> >>From 2945f1c6c57eeabdbeb8e7c058070587a9bf4c0a Mon Sep 17 00:00:00 2001
> From: Alan Third <alan@idiocy.org>
> Date: Mon, 30 Dec 2019 16:38:47 +0000
> Subject: [PATCH] Add ability to find ObjC method names

> * lisp/progmodes/cc-cmds.el (c-defun-name-1): Add Objective-C method
> name ability.
> ---
>  lisp/progmodes/cc-cmds.el | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)

> diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
> index 0343f9df32..9165398132 100644
> --- a/lisp/progmodes/cc-cmds.el
> +++ b/lisp/progmodes/cc-cmds.el
> @@ -2024,6 +2024,36 @@ c-defun-name-1
>  	     (c-backward-syntactic-ws)
>  	     (point))))
 
> +	 ((looking-at "[-+]\\s-*(")     ; Objective-C method

I'd be happier here if you could also check we're really in Objc with
(c-major-mode-is 'objc-mode).

> +	  (let ((class
> +		 (save-excursion
> +		   (re-search-backward "@\\(implementation\\|class\\|interface\\)")

Here, you might want to give a NOERROR argument to re-search-backward,
so that if implementation etc., isn't found, you can handle the error
gracefully.  Something like

                   (if (re-search-backward "@\\(....\\)" nil t)
		       (progn
		         (c-forward-token-2)
			 .....)
	             "")

> +		   (c-forward-token-2)
> +		   (thing-at-point 'word t)))
> +		(type (buffer-substring-no-properties (point) (+ (point) 1)))
> +		(name
> +		 (save-excursion
> +		   (c-forward-token-2 2 t)

c-forward-token-2 might not be the best function, here.  It moves to the
next token, but if there isn't a next token it doesn't move at all.
c-forward-over-token-and-ws might be better.  Alternatively, you could
check the result of c-forward-token-2 (say, with zerop) and take special
action if the call has failed.  This comment also applies to the later
uses of c-forward-token-2.

> +		   (let ((name ""))

I feel there ought to be a standard CC Mode function which would do the
following scanning to the {, but I can't find it at the moment.

> +		     (while (not (looking-at "[{;]"))

Or, (not (memq (char-after) '(?{ ?\;))), which would be minutely faster.
It would also not change the match-data if you cared about that (which
you don't, here).

> +		       (let ((start (point))
> +			     (end
> +			      (progn
> +				(c-forward-syntactic-ws)
> +				(forward-word)
> +				(if (looking-at ":")
> +				    (+ (point) 1)
> +				  (point)))))
> +			 (when (looking-at ":")
> +			   (c-forward-token-2)
> +			   (if (looking-at "(")
> +			       (c-forward-token-2 2 t)
> +			     (c-forward-token-2 1 t)))
> +			 (c-forward-syntactic-ws)
> +			 (setq name (concat name (buffer-substring-no-properties start end)))))

Just a small point: isn't name always the empty string before this form?
If so, you could get rid of the concat and just use
buffer-substring-no-properties.

> +		     name))))
> +	    (format "%s[%s %s]" type class name)))

As an alternative to format, you could use (concat type "[" class " "
                                            name "]")
, which is more direct, but probably doesn't matter here.

> +
>  	 (t				; Normal function or initializer.
>  	  (when (looking-at c-defun-type-name-decl-key) ; struct, etc.
>  	    (goto-char (match-end 0))
> -- 
> 2.24.0

-- 
Alan Mackenzie (Nuremberg, Germany).



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

* Re: cc-mode Objective C method names
  2020-01-04 10:48 ` Alan Mackenzie
@ 2020-01-04 11:07   ` HaiJun Zhang
  2020-01-04 17:09   ` Alan Third
  1 sibling, 0 replies; 7+ messages in thread
From: HaiJun Zhang @ 2020-01-04 11:07 UTC (permalink / raw)
  To: Alan Third, Alan Mackenzie; +Cc: Emacs-Devel devel

[-- Attachment #1: Type: text/plain, Size: 4800 bytes --]

There is a related bug: #38749.
在 2020年1月4日 +0800 PM6:49,Alan Mackenzie <acm@muc.de>,写道:
> Hello, Alan.
>
> On Wed, Jan 01, 2020 at 11:27:57 +0000, Alan Third wrote:
> > One small annoyance I’ve had with developing Emacs is that the
> > helpers for filling in the changelog entries don’t work with Objective
> > C methods. I’ve tried writing a patch to make it work.
>
> > For reference, an Objective C class looks something like:
>
> > @implementation ClassName
>
> > - (int)doSomething
> > {
> > /* do that something */
> > return 1;
> > }
>
> > - (void)doSomethingTo: (SomeClass *)object with: (int)someParam
> > {
> > return;
> > }
>
> > @end
>
> > And I think the methods’ names should be written something like:
>
> > -[ClassName doSomething]
> > -[ClassName doSomethingTo:with:]
>
> > The ‘-’ means it’s an instance method and a ‘+’ would mean it was a
> > class method.
>
> If either ClassName or doSomethingTo is long, you might be taking up too
> much space on, for example, the first line of a commit message. But
> you've probably already thought this through. How long are these
> extended names in practice?
>
> > It appears to work for me, but I’m not great at Emacs lisp so I
> > thought it best to run this by the mailing list in case I’ve made any
> > boneheaded errors.
>
> I've got just a few comments to add to Eli's and Stefan's, so ....
>
> > Thanks!
> > --
> > Alan Third
>
> > > > From 2945f1c6c57eeabdbeb8e7c058070587a9bf4c0a Mon Sep 17 00:00:00 2001
> > From: Alan Third <alan@idiocy.org>
> > Date: Mon, 30 Dec 2019 16:38:47 +0000
> > Subject: [PATCH] Add ability to find ObjC method names
>
> > * lisp/progmodes/cc-cmds.el (c-defun-name-1): Add Objective-C method
> > name ability.
> > ---
> > lisp/progmodes/cc-cmds.el | 30 ++++++++++++++++++++++++++++++
> > 1 file changed, 30 insertions(+)
>
> > diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
> > index 0343f9df32..9165398132 100644
> > --- a/lisp/progmodes/cc-cmds.el
> > +++ b/lisp/progmodes/cc-cmds.el
> > @@ -2024,6 +2024,36 @@ c-defun-name-1
> > (c-backward-syntactic-ws)
> > (point))))
>
> > + ((looking-at "[-+]\\s-*(") ; Objective-C method
>
> I'd be happier here if you could also check we're really in Objc with
> (c-major-mode-is 'objc-mode).
>
> > + (let ((class
> > + (save-excursion
> > + (re-search-backward "@\\(implementation\\|class\\|interface\\)")
>
> Here, you might want to give a NOERROR argument to re-search-backward,
> so that if implementation etc., isn't found, you can handle the error
> gracefully. Something like
>
> (if (re-search-backward "@\\(....\\)" nil t)
> (progn
> (c-forward-token-2)
> .....)
> "")
>
> > + (c-forward-token-2)
> > + (thing-at-point 'word t)))
> > + (type (buffer-substring-no-properties (point) (+ (point) 1)))
> > + (name
> > + (save-excursion
> > + (c-forward-token-2 2 t)
>
> c-forward-token-2 might not be the best function, here. It moves to the
> next token, but if there isn't a next token it doesn't move at all.
> c-forward-over-token-and-ws might be better. Alternatively, you could
> check the result of c-forward-token-2 (say, with zerop) and take special
> action if the call has failed. This comment also applies to the later
> uses of c-forward-token-2.
>
> > + (let ((name ""))
>
> I feel there ought to be a standard CC Mode function which would do the
> following scanning to the {, but I can't find it at the moment.
>
> > + (while (not (looking-at "[{;]"))
>
> Or, (not (memq (char-after) '(?{ ?\;))), which would be minutely faster.
> It would also not change the match-data if you cared about that (which
> you don't, here).
>
> > + (let ((start (point))
> > + (end
> > + (progn
> > + (c-forward-syntactic-ws)
> > + (forward-word)
> > + (if (looking-at ":")
> > + (+ (point) 1)
> > + (point)))))
> > + (when (looking-at ":")
> > + (c-forward-token-2)
> > + (if (looking-at "(")
> > + (c-forward-token-2 2 t)
> > + (c-forward-token-2 1 t)))
> > + (c-forward-syntactic-ws)
> > + (setq name (concat name (buffer-substring-no-properties start end)))))
>
> Just a small point: isn't name always the empty string before this form?
> If so, you could get rid of the concat and just use
> buffer-substring-no-properties.
>
> > + name))))
> > + (format "%s[%s %s]" type class name)))
>
> As an alternative to format, you could use (concat type "[" class " "
> name "]")
> , which is more direct, but probably doesn't matter here.
>
> > +
> > (t ; Normal function or initializer.
> > (when (looking-at c-defun-type-name-decl-key) ; struct, etc.
> > (goto-char (match-end 0))
> > --
> > 2.24.0
>
> --
> Alan Mackenzie (Nuremberg, Germany).
>

[-- Attachment #2: Type: text/html, Size: 9118 bytes --]

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

* Re: cc-mode Objective C method names
  2020-01-04 10:48 ` Alan Mackenzie
  2020-01-04 11:07   ` HaiJun Zhang
@ 2020-01-04 17:09   ` Alan Third
  1 sibling, 0 replies; 7+ messages in thread
From: Alan Third @ 2020-01-04 17:09 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: Emacs-Devel devel

[-- Attachment #1: Type: text/plain, Size: 1612 bytes --]

On Sat, Jan 04, 2020 at 10:48:54AM +0000, Alan Mackenzie wrote:
> Hello, Alan.
> 
> On Wed, Jan 01, 2020 at 11:27:57 +0000, Alan Third wrote:
> > And I think the methods’ names should be written something like:
> 
> > -[ClassName doSomething]
> > -[ClassName doSomethingTo:with:]
> 
> > The ‘-’ means it’s an instance method and a ‘+’ would mean it was a
> > class method.
> 
> If either ClassName or doSomethingTo is long, you might be taking up too
> much space on, for example, the first line of a commit message.  But
> you've probably already thought this through.  How long are these
> extended names in practice?

They can be extremely long, but our code doesn’t tend to have these
very long names.

I’m not sure what we could do to shorten them unless we really don’t
care very much about accuracy. For example we could drop the class
names, but we don’t limit classes to one per file, so we can easily
end up with two classes with the same method name in the same file.
Alternatively we could not list the parameter labels, but we
definitely have methods that only differ by their parameter lists in
Emacs.

FWIW, I’ve not run into any problems so far.

> > It appears to work for me, but I’m not great at Emacs lisp so I
> > thought it best to run this by the mailing list in case I’ve made any
> > boneheaded errors.
> 
> I've got just a few comments to add to Eli's and Stefan's, so ....

I was working through them when I thought of a neater way to do this,
but it’s probably less like the rest of the code in cc mode. Hopefully
it’s OK. Patch attached.
-- 
Alan Third

[-- Attachment #2: v2-0001-Add-ability-to-find-ObjC-method-names.patch --]
[-- Type: text/plain, Size: 1585 bytes --]

From b75a1ac30204d10f395c1885e1ad80692317c94e Mon Sep 17 00:00:00 2001
From: Alan Third <alan@idiocy.org>
Date: Mon, 30 Dec 2019 16:38:47 +0000
Subject: [PATCH v2] Add ability to find ObjC method names

* lisp/progmodes/cc-cmds.el (c-defun-name-1): Add Objective-C method
name ability.
---
 lisp/progmodes/cc-cmds.el | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 0343f9df32..18fb459e40 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -2024,6 +2024,23 @@ c-defun-name-1
 	     (c-backward-syntactic-ws)
 	     (point))))
 
+	 ((and (c-major-mode-is 'objc-mode) (looking-at "[-+]\\s-*("))     ; Objective-C method
+	  ;; Move to the beginning of the method name.
+	  (c-forward-token-2 2 t)
+	  (let* ((class
+		  (save-excursion
+		    (when (re-search-backward
+			   "^\\s-*@\\(implementation\\|class\\|interface\\)\\s-+\\(\\sw+\\)" nil t)
+		      (match-string-no-properties 2))))
+		 (limit (save-excursion (re-search-forward "[;{]" nil t)))
+		 (method (when (re-search-forward "\\(\\sw+:?\\)" limit t)
+			   (match-string-no-properties 1))))
+	    (when (and class method)
+	      ;; Add the parameter labels onto name.  They always end in ':'.
+	      (while (re-search-forward "\\(\\sw+:\\)" limit 1)
+		(setq method (concat method (match-string-no-properties 1))))
+	      (concat "[" class " " method "]"))))
+
 	 (t				; Normal function or initializer.
 	  (when (looking-at c-defun-type-name-decl-key) ; struct, etc.
 	    (goto-char (match-end 0))
-- 
2.24.0


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

end of thread, other threads:[~2020-01-04 17:09 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-01 11:27 cc-mode Objective C method names Alan Third
2020-01-01 15:29 ` Stefan Monnier
2020-01-02 11:02   ` Alan Third
2020-01-01 16:41 ` Eli Zaretskii
2020-01-04 10:48 ` Alan Mackenzie
2020-01-04 11:07   ` HaiJun Zhang
2020-01-04 17:09   ` Alan Third

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).