unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#13207: lisp-mnt.el improvements
@ 2012-12-17 16:26 Jonas Bernoulli
  2012-12-17 17:58 ` Stefan Monnier
  0 siblings, 1 reply; 6+ messages in thread
From: Jonas Bernoulli @ 2012-12-17 16:26 UTC (permalink / raw)
  To: 13207

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

Hello

I extract information from the library headers of all packages mirrored
on the Emacsmirror.  Since many packages don't follow the header
conventions lisp-mnt.el in it's current form isn't always suitable.  So
I have written elx.el which can handle some departure from the standard;
it also includes some additions.

Now I would like to merge some of the changes back into lisp-mnt.el:

1. Add function lm-homepage
   (lm-header "\\(?:x-\\)?\\(?:homepage\\|url\\)")
   These keywords are used quite often, most often without the X- prefix.

2. lm-section-end: the end is now always before the following
   non-comment text

   Many people don't add ;;; Code: after the header.  As a result
   lm-commentary was often way of (like eof!) and lm-commentary returned
   text that isn't part of the commentary but code.

3. lm-header, lm-header-multiline: wrap with save-match-data

4. lm-header-multiline: continuation lines now need to be intended more
   than the first line.  E.g:

   ;; Keyword: value
   ;;  more value

   This is necessary because some built-in libraries contain things
   like:

   ;; Author: Kenichi HANDA <handa@etl.go.jp>
   ;; (according to ack.texi)

   And some third-party libraries contain things like:

   ;; Keywords: key words
   ;; This file is not part of Emacs

   Among the 3500 packages mirrored on the Emacsmirror there are only
   three where this change results in lines intended as continuation
   lines not to be recognised anymore.  At the same time this change
   fixes ~50 errors.

   There now have to be at least two spaces or one tab after the initial
   semicolons for a line to be considered a continuation line.

(1) and (4) should be documented in the info page.  Let me know if you
want to do that.

elx.el contains some more things that could be merged into lisp-mnt.el,
but I would first like to know how these changes are received.

  Jonas


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: lisp-mnt.patch --]
[-- Type: text/x-diff, Size: 5068 bytes --]

From c9a79155d00e48a282d7fce1b6d21838c9fa5a90 Mon Sep 17 00:00:00 2001
From: Jonas Bernoulli <jonas@bernoul.li>
Date: Mon, 17 Dec 2012 17:03:41 +0100
Subject: [PATCH] lisp/emacs-lisp/lisp-mnt.el: new function lm-homepage
 (lm-section-end): the end is now always before the following non-comment text
 (lm-header): save-match-data (lm-header-multiline): save-match-data,
 continuation lines now need to be intended more than the first line
 (lm-with-file): widen and goto beginning of buffer before reusing current
 buffer

---
 lisp-mnt.el | 75 ++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 44 insertions(+), 31 deletions(-)

diff --git a/lisp-mnt.el b/lisp-mnt.el
index f9a1c5d..7bbc033 100644
--- a/lisp-mnt.el
+++ b/lisp-mnt.el
@@ -208,10 +208,10 @@ If the given section does not exist, return nil."
 The HEADER is the section string marking the beginning of the
 section.  If the given section does not exist, return nil.
 
-The end of the section is defined as the beginning of the next
-section of the same level or lower.  The function
-`lisp-outline-level' is used to compute the level of a section.
-If no such section exists, return the end of the buffer."
+The section ends before the first non-comment text or the next
+section of the same level or lower; whatever comes first.  The
+function `lisp-outline-level' is used to compute the level of
+a section."
   (require 'outline)   ;; for outline-regexp.
   (let ((start (lm-section-start header)))
     (when start
@@ -229,9 +229,15 @@ If no such section exists, return the end of the buffer."
                            (beginning-of-line)
                            (lisp-outline-level))
                          level)))
-          (if next-section-found
-              (line-beginning-position)
-            (point-max)))))))
+	  (min (if next-section-found
+		   (progn (beginning-of-line 0)
+			  (unless (looking-at "\f")
+			    (beginning-of-line 2))
+			  (point))
+		 (point-max))
+	       (progn (goto-char start)
+		      (while (forward-comment 1))
+		      (point))))))))
 
 (defsubst lm-code-start ()
   "Return the buffer location of the `Code' start marker."
@@ -262,35 +268,32 @@ If no such section exists, return the end of the buffer."
 
 (defun lm-header (header)
   "Return the contents of the header named HEADER."
-  (goto-char (point-min))
-  (let ((case-fold-search t))
-    (when (and (re-search-forward (lm-get-header-re header) (lm-code-mark) t)
-	       ;;   RCS ident likes format "$identifier: data$"
-	       (looking-at
-		(if (save-excursion
-		      (skip-chars-backward "^$" (match-beginning 0))
-		      (= (point) (match-beginning 0)))
-		    "[^\n]+" "[^$\n]+")))
-      (match-string-no-properties 0))))
+  (save-match-data
+    (goto-char (point-min))
+    (let ((case-fold-search t))
+      (when (and (re-search-forward (lm-get-header-re header) (lm-code-mark) t)
+		 ;;   RCS ident likes format "$identifier: data$"
+		 (looking-at
+		  (if (save-excursion
+			(skip-chars-backward "^$" (match-beginning 0))
+			(= (point) (match-beginning 0)))
+		      "[^\n]+" "[^$\n]+")))
+	(match-string-no-properties 0)))))
 
 (defun lm-header-multiline (header)
   "Return the contents of the header named HEADER, with continuation lines.
 The returned value is a list of strings, one per line."
   (save-excursion
-    (goto-char (point-min))
-    (let ((res (lm-header header)))
-      (when res
-	(setq res (list res))
-	(forward-line 1)
-	(while (and (or (looking-at (concat lm-header-prefix "[\t ]+"))
-			(and (not (looking-at
-				   (lm-get-header-re "\\sw\\(\\sw\\|\\s_\\)*")))
-			     (looking-at lm-header-prefix)))
-		    (goto-char (match-end 0))
-		    (looking-at ".+"))
-	  (setq res (cons (match-string-no-properties 0) res))
-	  (forward-line 1)))
-      (nreverse res))))
+    (save-match-data
+      (goto-char (point-min))
+      (let ((res (lm-header header)))
+	(when res
+	  (setq res (list res))
+	  (forward-line 1)
+	  (while (looking-at "^;+\\(\t\\|[\t\s]\\{2,\\}\\)\\(.+\\)")
+	    (push (match-string-no-properties 2) res)
+	    (forward-line 1)))
+	(nreverse res)))))
 
 ;; These give us smart access to the header fields and commentary
 
@@ -306,6 +309,8 @@ If FILE is nil, execute BODY in the current buffer."
 	     (emacs-lisp-mode)
 	     ,@body)
 	 (save-excursion
+	   (widen)
+	   (goto-char (point-min))
 	   ;; Switching major modes is too drastic, so just switch
 	   ;; temporarily to the Emacs Lisp mode syntax table.
 	   (with-syntax-table emacs-lisp-mode-syntax-table
@@ -489,6 +494,14 @@ absent, return nil."
       (when start
         (buffer-substring-no-properties start (lm-commentary-end))))))
 
+(defun lm-homepage (&optional file)
+  "Return the homepage in file FILE, or current buffer if FILE is nil."
+  (let ((page (lm-with-file file
+		(lm-header "\\(?:x-\\)?\\(?:homepage\\|url\\)"))))
+    (if (and page (string-match "^<.+>$" page))
+	(substring page 1 -1)
+      page)))
+
 ;;; Verification and synopses
 
 (defun lm-insert-at-column (col &rest strings)
-- 
1.8.0.1


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

* bug#13207: lisp-mnt.el improvements
  2012-12-17 16:26 bug#13207: lisp-mnt.el improvements Jonas Bernoulli
@ 2012-12-17 17:58 ` Stefan Monnier
  2012-12-17 21:58   ` Jonas Bernoulli
  0 siblings, 1 reply; 6+ messages in thread
From: Stefan Monnier @ 2012-12-17 17:58 UTC (permalink / raw)
  To: Jonas Bernoulli; +Cc: 13207

> 1. Add function lm-homepage
>    (lm-header "\\(?:x-\\)?\\(?:homepage\\|url\\)")
>    These keywords are used quite often, most often without the X- prefix.

Sounds OK.

> 2. lm-section-end: the end is now always before the following
>    non-comment text
>    Many people don't add ;;; Code: after the header.  As a result
>    lm-commentary was often way of (like eof!) and lm-commentary returned
>    text that isn't part of the commentary but code.

Good.

> 3. lm-header, lm-header-multiline: wrap with save-match-data

This one doesn't sound right.  The callers should be fixed instead.

> 4. lm-header-multiline: continuation lines now need to be intended more
>    than the first line.  E.g:
>    ;; Keyword: value
>    ;;  more value
>    This is necessary because some built-in libraries contain things
>    like:
>    ;; Author: Kenichi HANDA <handa@etl.go.jp>
>    ;; (according to ack.texi)
>    And some third-party libraries contain things like:
>    ;; Keywords: key words
>    ;; This file is not part of Emacs
>    Among the 3500 packages mirrored on the Emacsmirror there are only
>    three where this change results in lines intended as continuation
>    lines not to be recognised anymore.  At the same time this change
>    fixes ~50 errors.

An important measure is how much breakage/improvement does it introduce
when applied to files that are expected to do thing right (e.g. files in
emacs/lisp and in elpa/packages).  I'm OK with making lisp-mnt.el more
forgiving, but it should not come at the cost of those packages that do
things right.


        Stefan





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

* bug#13207: lisp-mnt.el improvements
  2012-12-17 17:58 ` Stefan Monnier
@ 2012-12-17 21:58   ` Jonas Bernoulli
  2012-12-18  1:29     ` Stefan Monnier
  0 siblings, 1 reply; 6+ messages in thread
From: Jonas Bernoulli @ 2012-12-17 21:58 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 13207


>> 3. lm-header, lm-header-multiline: wrap with save-match-data
>
> This one doesn't sound right.  The callers should be fixed instead.

Okay.  On second though: it wouldn't be very useful to use the match
data set by these functions.  Why not save the match-data here once so
that no caller has to ever worry about it?  Is there a general policy
that this kinda thing shouldn't be done?

>> 4. lm-header-multiline: continuation lines now need to be intended more
>>    than the first line.  E.g:
>>    ;; Keyword: value
>>    ;;  more value
>>    This is necessary because some built-in libraries contain things
>>    like:
>>    ;; Author: Kenichi HANDA <handa@etl.go.jp>
>>    ;; (according to ack.texi)
>>    And some third-party libraries contain things like:
>>    ;; Keywords: key words
>>    ;; This file is not part of Emacs
>>    Among the 3500 packages mirrored on the Emacsmirror there are only
>>    three where this change results in lines intended as continuation
>>    lines not to be recognised anymore.  At the same time this change
>>    fixes ~50 errors.
>
> An important measure is how much breakage/improvement does it introduce
> when applied to files that are expected to do thing right (e.g. files in
> emacs/lisp and in elpa/packages).  I'm OK with making lisp-mnt.el more
> forgiving, but it should not come at the cost of those packages that do
> things right.

The 3500 packages from which I extracted metadata include all built-in
and fsf-elpa packages (though I did not process every library, just the
"main library" of each package).  The three packages affected in a
negative way didn't do things right, and they aren't fsf packages.

This should be possible

  ;; Author: Kenichi HANDA <handa@etl.go.jp>
  ;; (according to ack.texi)

and this can be sacrificed

  ;; Author: Kenichi HANDA <handa@etl.go.jp>
  ;; Jonas Bernoulli <jonas@bernoul.li>

-- Jonas





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

* bug#13207: lisp-mnt.el improvements
  2012-12-17 21:58   ` Jonas Bernoulli
@ 2012-12-18  1:29     ` Stefan Monnier
  2012-12-19 15:38       ` Jonas Bernoulli
  0 siblings, 1 reply; 6+ messages in thread
From: Stefan Monnier @ 2012-12-18  1:29 UTC (permalink / raw)
  To: Jonas Bernoulli; +Cc: 13207

> Okay.  On second though: it wouldn't be very useful to use the match
> data set by these functions.  Why not save the match-data here once so
> that no caller has to ever worry about it?  Is there a general policy
> that this kinda thing shouldn't be done?

Yes, the general policy is: all functions should be presumed to trash
the match-data, except for a very few exceptions.

> The 3500 packages from which I extracted metadata include all built-in
> and fsf-elpa packages (though I did not process every library, just the
> "main library" of each package).  The three packages affected in a
> negative way didn't do things right, and they aren't fsf packages.

OK, thanks for checking.  It sounds good then.  Can you send a "final" patch?


        Stefan





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

* bug#13207: lisp-mnt.el improvements
  2012-12-18  1:29     ` Stefan Monnier
@ 2012-12-19 15:38       ` Jonas Bernoulli
  2012-12-19 19:52         ` Stefan Monnier
  0 siblings, 1 reply; 6+ messages in thread
From: Jonas Bernoulli @ 2012-12-19 15:38 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 13207

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


>> The 3500 packages from which I extracted metadata include all built-in
>> and fsf-elpa packages (though I did not process every library, just the
>> "main library" of each package).  The three packages affected in a
>> negative way didn't do things right, and they aren't fsf packages.
>
> OK, thanks for checking.  It sounds good then.  Can you send a "final" patch?

I have also updated the info page.

  Jonas


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: lisp-mnt.patch --]
[-- Type: text/x-diff, Size: 5158 bytes --]

From 001bdfead8d2fa19ef2b7b339ed01f8cf909257d Mon Sep 17 00:00:00 2001
From: Jonas Bernoulli <jonas@bernoul.li>
Date: Wed, 19 Dec 2012 16:32:08 +0100
Subject: [PATCH] * lisp/emacs-lisp/lisp-mnt.el: new function lm-homepage
 (lm-section-end): the end is now always before the following non-comment text
 (lm-header-multiline): continuation lines now need to be intended more than
 the first line (lm-with-file): widen and goto beginning of buffer before
 reusing current buffer

* doc/lispref/tips.texi: new header keyword Homepage, continuation
lines can use two or more spaces instead of a tab after the
semicolons
---
 doc/lispref/tips.texi       |  7 +++++--
 lisp/emacs-lisp/lisp-mnt.el | 39 +++++++++++++++++++++++++--------------
 2 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/doc/lispref/tips.texi b/doc/lispref/tips.texi
index d54d91b..854ce8f 100644
--- a/doc/lispref/tips.texi
+++ b/doc/lispref/tips.texi
@@ -942,6 +942,7 @@ explains these conventions, starting with an example:
 ;; Created: 14 Jul 2010
 @group
 ;; Keywords: languages
+;; Homepage: http://example.com/foo
 
 ;; This file is not part of GNU Emacs.
 
@@ -980,8 +981,7 @@ the conventional possibilities for @var{header-name}:
 @item Author
 This line states the name and email address of at least the principal
 author of the library.  If there are multiple authors, list them on
-continuation lines led by @code{;;} and whitespace (this is easier
-for tools to parse than having more than one author on one line).
+continuation lines led by @code{;;} and a tab or at least two spaces.
 We recommend including a contact email address, of the form
 @samp{<@dots{}>}.  For example:
 
@@ -1028,6 +1028,9 @@ The name of this field is unfortunate, since people often assume it is
 the place to write arbitrary keywords that describe their package,
 rather than just the relevant Finder keywords.
 
+@item Homepage
+This line states the homepage of the library.
+
 @item Package-Version
 If @samp{Version} is not suitable for use by the package manager, then
 a package can define @samp{Package-Version}; it will be used instead.
diff --git a/lisp/emacs-lisp/lisp-mnt.el b/lisp/emacs-lisp/lisp-mnt.el
index f9a1c5d..4d210c2 100644
--- a/lisp/emacs-lisp/lisp-mnt.el
+++ b/lisp/emacs-lisp/lisp-mnt.el
@@ -208,10 +208,10 @@ If the given section does not exist, return nil."
 The HEADER is the section string marking the beginning of the
 section.  If the given section does not exist, return nil.
 
-The end of the section is defined as the beginning of the next
-section of the same level or lower.  The function
-`lisp-outline-level' is used to compute the level of a section.
-If no such section exists, return the end of the buffer."
+The section ends before the first non-comment text or the next
+section of the same level or lower; whatever comes first.  The
+function `lisp-outline-level' is used to compute the level of
+a section."
   (require 'outline)   ;; for outline-regexp.
   (let ((start (lm-section-start header)))
     (when start
@@ -229,9 +229,15 @@ If no such section exists, return the end of the buffer."
                            (beginning-of-line)
                            (lisp-outline-level))
                          level)))
-          (if next-section-found
-              (line-beginning-position)
-            (point-max)))))))
+	  (min (if next-section-found
+		   (progn (beginning-of-line 0)
+			  (unless (looking-at "\f")
+			    (beginning-of-line 2))
+			  (point))
+		 (point-max))
+	       (progn (goto-char start)
+		      (while (forward-comment 1))
+		      (point))))))))
 
 (defsubst lm-code-start ()
   "Return the buffer location of the `Code' start marker."
@@ -282,13 +288,8 @@ The returned value is a list of strings, one per line."
       (when res
 	(setq res (list res))
 	(forward-line 1)
-	(while (and (or (looking-at (concat lm-header-prefix "[\t ]+"))
-			(and (not (looking-at
-				   (lm-get-header-re "\\sw\\(\\sw\\|\\s_\\)*")))
-			     (looking-at lm-header-prefix)))
-		    (goto-char (match-end 0))
-		    (looking-at ".+"))
-	  (setq res (cons (match-string-no-properties 0) res))
+	(while (looking-at "^;+\\(\t\\|[\t\s]\\{2,\\}\\)\\(.+\\)")
+	  (push (match-string-no-properties 2) res)
 	  (forward-line 1)))
       (nreverse res))))
 
@@ -306,6 +307,8 @@ If FILE is nil, execute BODY in the current buffer."
 	     (emacs-lisp-mode)
 	     ,@body)
 	 (save-excursion
+	   (widen)
+	   (goto-char (point-min))
 	   ;; Switching major modes is too drastic, so just switch
 	   ;; temporarily to the Emacs Lisp mode syntax table.
 	   (with-syntax-table emacs-lisp-mode-syntax-table
@@ -489,6 +492,14 @@ absent, return nil."
       (when start
         (buffer-substring-no-properties start (lm-commentary-end))))))
 
+(defun lm-homepage (&optional file)
+  "Return the homepage in file FILE, or current buffer if FILE is nil."
+  (let ((page (lm-with-file file
+		(lm-header "\\(?:x-\\)?\\(?:homepage\\|url\\)"))))
+    (if (and page (string-match "^<.+>$" page))
+	(substring page 1 -1)
+      page)))
+
 ;;; Verification and synopses
 
 (defun lm-insert-at-column (col &rest strings)
-- 
1.8.0.1


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

* bug#13207: lisp-mnt.el improvements
  2012-12-19 15:38       ` Jonas Bernoulli
@ 2012-12-19 19:52         ` Stefan Monnier
  0 siblings, 0 replies; 6+ messages in thread
From: Stefan Monnier @ 2012-12-19 19:52 UTC (permalink / raw)
  To: Jonas Bernoulli; +Cc: 13207

> I have also updated the info page.

Thanks, installed,


        Stefan





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

end of thread, other threads:[~2012-12-19 19:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-17 16:26 bug#13207: lisp-mnt.el improvements Jonas Bernoulli
2012-12-17 17:58 ` Stefan Monnier
2012-12-17 21:58   ` Jonas Bernoulli
2012-12-18  1:29     ` Stefan Monnier
2012-12-19 15:38       ` Jonas Bernoulli
2012-12-19 19:52         ` Stefan Monnier

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