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
next prev parent 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).