unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: "Andreas Röhler" <andreas.roehler@online.de>
To: emacs-devel@gnu.org
Cc: Stefan Monnier <monnier@iro.umontreal.ca>,
	Richard Stallman <rms@gnu.org>
Subject: Re: sh-script beg-end of function
Date: Fri, 23 Nov 2007 16:33:36 +0100	[thread overview]
Message-ID: <200711231633.37286.andreas.roehler@online.de> (raw)
In-Reply-To: <jwvejeic6rc.fsf-monnier+emacs@gnu.org>

Am Donnerstag, 22. November 2007 22:49 schrieb Stefan Monnier:
> > Your code adresses a function in it's literally sence,
> > whereas my code adresses "top-level-form", a more
> > abstract thing. A "top-level-form" form BTW already
> > is adressed by Emacs-Lisp `end-of-defun' or
> > `beginning-of-defun' and I already remarked the naming
> > as somehow misleading therefore, but that's a matter
> > from the past.
>
> I understand, but the way I see it, either you're in an sh buffer which
> has functions, in which case the defun-prompt-regexp will work fine, or
> you're in an sh buffer which basically only contains "unstructured"
> "straight-line" code.  You want to cater to this latter case as well.
>
> It might be OK, but in my experience which units are useful in this case
> is hard to know in general because it depends a lot on the writing style
> used (which is anything but standardized sadly).  In many cases
> paragraph-based navigation will work best.
>

That's true. Took your hint to make changes rely on paragraph-.

> I don't claim that my defun-prompt-regexp setting is the
> end-all-be-all here.  It's just a good starting point.  But also any
> replacement should be at least as good.  Most importantly: jumping to
> the end of a real function should jump to the closing "}".
>
Not, if exists usually no closing "}" while writing. I prefer to
set closings last and manually - the reports I get then
are more valuable than possible savings before.

> If you want to submit an improvement, please send it as a patch against
> the current sh-script.el code.  This will make it easier for us to
> integrate your code.

Here a small diff to enable modes to set beginning-of-defun-function without 
disturbing each other:

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

diff -c emacs-lisp/lisp.el lisp.el
*** /emacs-lisp/lisp.el	2007-07-26 07:26:47.000000000 +0200
--- lisp.el	2007-11-23 15:49:52.000000000 +0100
***************
*** 178,183 ****
--- 178,184 ----
  The function (of no args) should go to the line on which the current
  defun starts, and return non-nil, or should return nil if it can't
  find the beginning.")
+ (make-variable-buffer-local 'beginning-of-defun-function)
  
  (defun beginning-of-defun (&optional arg)
    "Move backward to the beginning of a defun.
***************
*** 291,296 ****
--- 292,298 ----
  This is used to find the end of the defun instead of using the normal
  recipe (see `end-of-defun').  Major modes can define this if the
  normal method is not appropriate.")
+ (make-variable-buffer-local 'end-of-defun-function)
  
  (defun buffer-end (arg)
    "Return the \"far end\" position of the buffer, in direction ARG.

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

> BTW, `end-of-defun-function' seems to be used in end-of-defun in
> a ... weird way, so maybe you'll want to fix that first. 

This should be done with this diff above.

Remaining bugs AFAIS occur occasionally but are deep-rooted
from underlying move-functions and not to adress here.

> Maybe I'll 
> post a suggestion about it on this list later.
>
>
>         Stefan
>
>
> PS: Comments about your original code:
> - the "defcustom beginning-of-defun-function" is wrong: you can only
>   use defcustom for variable you *create* (that are your own), not to set
>   variables defined in other packages.

OK, thanks. Dropped that part.

> - The docstring of sh-beginning-of-function is unusable.  It could
>   instead explain what is considered as a "defun".

Changed.

> - Instead of (parse-partial-sexp (point-min) (point)), you can use
>   syntax-ppss.

Dropped that part of code completely. 

BTW, reading doku of `syntax-ppss'
"The returned value is the same as `parse-partial-sexp'
except that the 2nd and 6th values of the returned
state cannot be relied upon." 
I say: so let's take `parse-partial-sexp' and rely
upon... Maybe I'm wrong here?

> - the docstring of `comment-beginning' says "Find the beginning of the
>   enclosing comment" so I'm wondering why you decided to use that in
>   a context where you have no idea whether or not you're inside
>   a comment.  Why don't you just use (forward-comment (- (point-max)))

Thanks. Simply wasn't aware of that. Rewrote the
code. Changed "function" to "form" too in order to avoid
misunderstandings.

>   and skip the 
>   newcomment madness  
Wouldn't dare to speak that out :)
...

Thanks again

Andreas Röhler


;;; sh-beg-end.el --- Something for C-M-a,
;;; C-M-e, M-a and M-e in shell-script-mode

;; Copyright (C) 2007 by Andreas Röhler
;; <andreas.roehler@online.de>

;; Keywords: languages

;; This file is free software; you can redistribute it
;; and/or modify it under the terms of the GNU General
;; Public License as published by the Free Software
;; Foundation; either version 3, or (at your option)
;; any later version.

;; This file is distributed in the hope that it will be
;; useful, but WITHOUT ANY WARRANTY; without even the
;; implied warranty of MERCHANTABILITY or FITNESS FOR A
;; PARTICULAR PURPOSE.  See the GNU General Public
;; License for more details.

;; You should have received a copy of the GNU General
;; Public License along with GNU Emacs; see the file
;; COPYING.  If not, write to the Free Software
;; Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;; Commentary: 

;; C-M-a, C-M-e: jump to the beginning or end of a
;; top-level-form in sh-mode - "Shell-script"-mode. 

;; M-a, M-e: jump to the beginning or end of command in
;; a given line, forward or backward next beginning or
;; end with. With argument do this as many times.

;;; Code:


;; this belongs into sh-script.el
(make-variable-buffer-local 'beginning-of-defun-function)
(make-variable-buffer-local 'end-of-defun-function)
 
(defcustom sh-beginning-of-form-regexp "^[A-Za-z_][A-Za-z_0-9]*"
  " "
  :type 'regexp
  :group 'lisp)

(defun sh-beginning-of-form ()
  "Move to the beginning of a top-level-form in sh-script.
With numeric argument, do it that many times."
  (interactive)
  (re-search-backward sh-beginning-of-form-regexp nil t 1))

(defun sh-end-of-form (&optional arg)
  "Move to the end of a top-level-form in sh-script.
With numeric argument, do it that many times."
  (interactive "p")
  (let ((arg (or arg 1)))
    (while (forward-comment 1) (forward-comment 1))
    (unless (looking-back "^[ \t]*")
      (setq arg (1+ arg)))
    (forward-paragraph arg)
    (skip-chars-backward " \t\r\n\f")
    (unless (looking-at "}")
      (back-to-indentation))
    (if (looking-back "^[ \t]+")
	(progn 
	  (end-of-line) 
	  (sh-end-of-form))
      (end-of-line)
      (skip-chars-backward " \t\r\n\f"))))
    
(defun sh-set-beginning-of-form ()
  "'sh-beginning-of-form"
  (interactive)
 (setq beginning-of-defun-function 'sh-beginning-of-form))

(defun sh-set-end-of-form ()
  "'sh-end-of-form"
  (interactive)
  (setq end-of-defun-function 'sh-end-of-form))

(defun sh-beginning-of-command (&optional arg) 
  "Move point to successive beginnings of commands."
  (interactive "p")
  (let ((arg (or arg 1))
	(pos (point)))
    (back-to-indentation)
    (unless (eq pos (point))
      (setq arg (1- arg)))
    (while (< 0 arg)
      (forward-line (- arg))
      (setq arg (1- arg))
      ;; skip comments and empty lines and closing braces
      (let ((pos (point)))
	(if (forward-comment -1)
	    (while (forward-comment -1) (forward-comment -1))
	  (goto-char pos)))
      (while (or (empty-line-p)
		 (looking-at "}"))
	(forward-line -1))
      (back-to-indentation))))

(defun sh-end-of-command (&optional arg) 
  "Move point to successive ends of commands."
  (interactive "p")
  (let ((arg (or arg 1))
	(pos (point)))
    (end-of-line)
    (skip-chars-backward " \t\r\n\f" (line-beginning-position))
    (unless (eq pos (point))
      (setq arg (1- arg)))
    (while (< 0 arg)
      (forward-line arg)
      (setq arg (1- arg)))
    (end-of-line)
    (skip-chars-backward " \t\r\n\f" (line-beginning-position))
    (while (or
	    (empty-line-p)
	    (forward-comment 1)) 
      (forward-line 1)
      (end-of-line))
    (skip-chars-backward " \t\r\n\f")))

(add-hook 'sh-mode-hook 'sh-set-beginning-of-form)
(add-hook 'sh-mode-hook 'sh-set-end-of-form)

(provide 'sh-beg-end)

;;; sh-beg-end.el ends here

  reply	other threads:[~2007-11-23 15:33 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-19 20:43 sh-script beg-end of function Andreas Röhler
2007-11-21 12:05 ` Richard Stallman
2007-11-21 15:52   ` Andreas Röhler
2007-11-22  8:22     ` Richard Stallman
2007-11-21 20:19   ` Stefan Monnier
2007-11-22  7:26     ` Andreas Röhler
2007-11-22 17:39       ` Stefan Monnier
2007-11-22 18:56         ` Andreas Röhler
2007-11-22 21:49           ` Stefan Monnier
2007-11-23 15:33             ` Andreas Röhler [this message]
2007-11-23 16:34               ` Stefan Monnier
2007-11-24 13:45                 ` Andreas Röhler
2007-11-23 15:56             ` Andreas Röhler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200711231633.37286.andreas.roehler@online.de \
    --to=andreas.roehler@online.de \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=rms@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).