* Re: Help with keybinding to delete between {}
2007-12-05 1:33 Help with keybinding to delete between {} lampshade
@ 2007-12-05 10:48 ` Bernardo Bacic
2007-12-05 12:55 ` William Xu
` (4 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: Bernardo Bacic @ 2007-12-05 10:48 UTC (permalink / raw)
Cc: help-gnu-emacs
it was a dark and stormy night when lampshade said, On 12/05/2007 12:33 PM:
> I would really like a keybinding that would allow me to delete any
> text between sexp's like {} (), etc no matter where I am between them
> and whether or not that text has spaces.
mark-sexp + delete-region ?
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Help with keybinding to delete between {}
2007-12-05 1:33 Help with keybinding to delete between {} lampshade
2007-12-05 10:48 ` Bernardo Bacic
@ 2007-12-05 12:55 ` William Xu
2007-12-05 13:30 ` Andreas Röhler
` (3 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: William Xu @ 2007-12-05 12:55 UTC (permalink / raw)
To: help-gnu-emacs
lampshade <mwolffedu@gmail.com> writes:
> Anyone have any improvements or help they could give me?
How does this feel?
,----
| (defun delete-between ()
| (interactive)
| (save-excursion
| (let ((beg (re-search-backward "{\\|(" nil t 1))
| (end (re-search-forward "}\\|)" nil t 1)))
| (when (and beg end)
| (kill-region (1+ beg) (1- end))))))
`----
--
William
http://williamxu.net9.org
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Help with keybinding to delete between {}
2007-12-05 1:33 Help with keybinding to delete between {} lampshade
2007-12-05 10:48 ` Bernardo Bacic
2007-12-05 12:55 ` William Xu
@ 2007-12-05 13:30 ` Andreas Röhler
2007-12-05 23:50 ` Ilya Zakharevich
` (2 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: Andreas Röhler @ 2007-12-05 13:30 UTC (permalink / raw)
To: help-gnu-emacs
Am Mittwoch, 5. Dezember 2007 02:33 schrieb lampshade:
> Hello,
>
>
> I would really like a keybinding that would allow me to delete any
> text between sexp's like {} (), etc no matter where I am between them
> and whether or not that text has spaces.
>
> For example
> {asdfdsfa asdfasdf asd}
> I would like to delete between leaving only the {} with my cursor
> inside ready to type. So far I've been trying
> (defun delete_between ()
> (interactive)
> (backward-sexp)
> (kill-sexp))
> (global-set-key [(control meta k)] 'delete_between)
>
> but that doesn't quite work. Anyone have any improvements or help
> they could give me?
>
> Thanks in advance,
> lampshade
> _______________________________________________
Maybe try thingatpt-utils1.7 in gnu-emacs-sources.
Changed `delimited-atpt', so `kill-delimited-atpt'
should do it now.
Remains to provide a key for it.
Andreas Röhler
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Help with keybinding to delete between {}
2007-12-05 1:33 Help with keybinding to delete between {} lampshade
` (2 preceding siblings ...)
2007-12-05 13:30 ` Andreas Röhler
@ 2007-12-05 23:50 ` Ilya Zakharevich
2007-12-06 6:33 ` Xah Lee
2007-12-07 16:30 ` Stefan Monnier
5 siblings, 0 replies; 15+ messages in thread
From: Ilya Zakharevich @ 2007-12-05 23:50 UTC (permalink / raw)
To: help-gnu-emacs
[A complimentary Cc of this posting was sent to
lampshade
<mwolffedu@gmail.com>], who wrote in article <598472b5-c766-483a-93e5-15b31bfd880f@b40g2000prf.googlegroups.com>:
> Hello,
>
>
> I would really like a keybinding that would allow me to delete any
> text between sexp's like {} (), etc no matter where I am between them
> and whether or not that text has spaces.
>
> For example
> {asdfdsfa asdfasdf asd}
> I would like to delete between leaving only the {} with my cursor
> inside ready to type. So far I've been trying
> (defun delete_between ()
> (interactive)
> (backward-sexp)
(up-list -1)
> (kill-sexp))
> (global-set-key [(control meta k)] 'delete_between)
>
> but that doesn't quite work. Anyone have any improvements or help
> they could give me?
In my setup, backspace kills back, delete forward; control-whatever
acts in words; meta-left/right acts in sexps, meta-up/down does
(up-list 1/-1). shift- adds some pepper (changes search-* to
replace-*, changes kill-word to kill-up-to-begin/end-of-line, changes
movement to move-and-modify-CUA-selection).
But I do not have kill-by-sexp commands. Instead, I do a shifted-move
(to select), and kill-CUA-selected. So to do what you want, I would
M-up, S-M-right, S-backspace. More keystrokes, but much more flexible
- I rarely want to delete something as simple as sexp, usually I
combine several move-and-modify-CUA-selection commands...
Probably this does not help your problem much...
Ilya
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Help with keybinding to delete between {}
2007-12-05 1:33 Help with keybinding to delete between {} lampshade
` (3 preceding siblings ...)
2007-12-05 23:50 ` Ilya Zakharevich
@ 2007-12-06 6:33 ` Xah Lee
2007-12-06 17:14 ` Xah Lee
2007-12-14 11:43 ` Xah Lee
2007-12-07 16:30 ` Stefan Monnier
5 siblings, 2 replies; 15+ messages in thread
From: Xah Lee @ 2007-12-06 6:33 UTC (permalink / raw)
To: help-gnu-emacs
you wrote:
<<I would really like a keybinding that would allow me to delete any
text between sexp's like {} (), etc no matter where I am between them
and whether or not that text has spaces.>>
I wrote a code few months ago that does exactly what you asked.
(defun delete-enclosed-text ()
"Delete texts between any pair of delimiters."
(interactive)
(skip-chars-backward "^<>()""")
(delete-char (skip-chars-forward "^<>()""")))
For more, see:
http://xahlee.org/emacs/elisp_examples.html
These days i don't use the above. Instead, i have a extend-selection
that selects text inside matching pairs. (then i can delete or cop or
cut with another keystroke) Here's the code:
(defun extend-selection ()
"Highlight a region between the nearest left and right delimiters.
Delimiters are paired characters: ()[]<><<>>""''「」, including \"\".
When the function is run again, it extends the
selection to the next level of enclosing delimiters. "
(interactive)
(if
(or (and (eq last-command this-command) (mark t))
(and transient-mark-mode mark-active))
(let ((e1 (region-beginning)) (e2 (region-end)) b1 b2)
(goto-char (- e1 1))
(skip-chars-backward "^<>("{[「<<\"")
(setq b1 (point))
(goto-char (+ e2 1))
(skip-chars-forward "^<>)"}]」>>\"")
(setq b2 (point))
(push-mark b1 nil t)
)
(progn
(push-mark
(save-excursion
(skip-chars-backward "^<>("{[「<<\"")
(point)
) nil t)
(skip-chars-forward "^<>)"}]」>>\"")
)
)
)
This is currently assigned to Alt+7.
In the near future i'll rework the code so that, on repeated press of
Alt+7, it extend to outer matching pairs. (skiping pairs of delimiters
that's siblings) For more detail on this concept, see:
A Text Editor Feature: Syntax Tree Walk
http://xahlee.org/emacs/syntax_tree_walk.html
This concept of code selection is far more powerful (and simpler) than
existing sexp forward/backward or the whole set of paren-edit.el, in
particular when combined with a auto-lisp-formater.
(detailed at:
A Simple Lisp Code Formatter
http://xahlee.org/emacs/lisp_formatter.html
)
PS this message is posted thur groups.google.com. It in the past half
a year has been diddling with the french quote charaters "<<>>" (double
angle quotes; unicode U+00AB and U+00BB) that i use often for quation
in my posts.
For a period google groups will omit them, another period it'll
replace it with << and >>, and in the past week sometimes it'll omit
the closing char. In this post, the elisp code above also contain the
french quote. Let's see what google transformed it to this time.
Xah
xah@xahlee.org
\xAD\xF4 http://xahlee.org/
On Dec 4, 5:33 pm, lampshade <mwolff...@gmail.com> wrote:
> Hello,
>
> I would really like a keybinding that would allow me to delete any
> text between sexp's like {} (), etc no matter where I am between them
> and whether or not that text has spaces.
>
> For example
> {asdfdsfa asdfasdf asd}
> I would like to delete between leaving only the {} with my cursor
> inside ready to type. So far I've been trying
> (defun delete_between ()
> (interactive)
> (backward-sexp)
> (kill-sexp))
> (global-set-key [(control meta k)] 'delete_between)
>
> but that doesn't quite work. Anyone have any improvements or help
> they could give me?
>
> Thanks in advance,
> lampshade
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Help with keybinding to delete between {}
2007-12-06 6:33 ` Xah Lee
@ 2007-12-06 17:14 ` Xah Lee
2007-12-12 9:20 ` lampshade
` (3 more replies)
2007-12-14 11:43 ` Xah Lee
1 sibling, 4 replies; 15+ messages in thread
From: Xah Lee @ 2007-12-06 17:14 UTC (permalink / raw)
To: help-gnu-emacs
for some reason my code in the previous post is completely non-
functional. (i swear i used it for few months. Perhaps when i put on
the website i got smart and edited it "for the better" without
testing)
Here's the correct version:
(defun delete-enclosed-text ()
"Delete texts between any pair of delimiters.
Note: if you have nested matching pairs, the cursor
should be inside the inner most one. Else it gets confused.
This code should to be fixed in the future."
(interactive)
(save-excursion
(let (p1 p2)
(skip-chars-backward "^(<["<<") (setq p1 (point))
(skip-chars-forward "^)>]">>") (setq p2 (point))
(delete-region p1 p2)
)
)
)
Xah
xah@xahlee.org
\xAD\xF4 http://xahlee.org/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Help with keybinding to delete between {}
2007-12-06 17:14 ` Xah Lee
@ 2007-12-12 9:20 ` lampshade
2007-12-13 3:59 ` Mike Mattie
` (2 subsequent siblings)
3 siblings, 0 replies; 15+ messages in thread
From: lampshade @ 2007-12-12 9:20 UTC (permalink / raw)
To: help-gnu-emacs
On Dec 6, 11:14 am, Xah Lee <x...@xahlee.org> wrote:
> for some reason my code in the previous post is completely non-
> functional. (i swear i used it for few months. Perhaps when i put on
> the website i got smart and edited it "for the better" without
> testing)
>
> Here's the correct version:
>
> (defun delete-enclosed-text ()
> "Delete texts between any pair of delimiters.
> Note: if you have nested matching pairs, the cursor
> should be inside the inner most one. Else it gets confused.
> This code should to be fixed in the future."
> (interactive)
> (save-excursion
> (let (p1 p2)
> (skip-chars-backward "^(<["<<") (setq p1 (point))
> (skip-chars-forward "^)>]">>") (setq p2 (point))
> (delete-region p1 p2)
> )
> )
> )
>
> Xah
> x...@xahlee.org
> \xAD\xF4http://xahlee.org/
I'm glad to see you in this thread! I actually came across your code
and tried that first. Unfortunately, that version wasn't working so I
moved on to trying to write one myself. Your implementation was
pretty well exactly what I was looking for. Thank you for the updated
version!
Thank you!
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Help with keybinding to delete between {}
2007-12-06 17:14 ` Xah Lee
2007-12-12 9:20 ` lampshade
@ 2007-12-13 3:59 ` Mike Mattie
[not found] ` <mailman.4961.1197518641.18990.help-gnu-emacs@gnu.org>
2007-12-13 10:44 ` Mike Mattie
3 siblings, 0 replies; 15+ messages in thread
From: Mike Mattie @ 2007-12-13 3:59 UTC (permalink / raw)
To: help-gnu-emacs
[-- Attachment #1.1: Type: text/plain, Size: 1703 bytes --]
On Thu, 6 Dec 2007 09:14:12 -0800 (PST)
Xah Lee <xah@xahlee.org> wrote:
> for some reason my code in the previous post is completely non-
> functional. (i swear i used it for few months. Perhaps when i put on
> the website i got smart and edited it "for the better" without
> testing)
>
> Here's the correct version:
>
> (defun delete-enclosed-text ()
> "Delete texts between any pair of delimiters.
> Note: if you have nested matching pairs, the cursor
> should be inside the inner most one. Else it gets confused.
> This code should to be fixed in the future."
> (interactive)
> (save-excursion
> (let (p1 p2)
> (skip-chars-backward "^(<["<<") (setq p1 (point))
> (skip-chars-forward "^)>]">>") (setq p2 (point))
> (delete-region p1 p2)
> )
> )
> )
I don't this this can be right. on a single line it has three string quotation characters.
(defun delete-enclosed-text ()
"Delete texts between any pair of delimiters.
Note: if you have nested matching pairs, the cursor
should be inside the inner most one. Else it gets confused.
This code should to be fixed in the future."
(interactive)
(skip-chars-forward "^)>>")
(delete-backward-char (skip-chars-backward "^(<<")))
this version doesn't change the mark so I dropped the save-excursion. It is not quite right because
it does not handle nested sexp at all. I don't understand the elisp flavor of regex yet, so it's
probably an easy fix.
> Xah
> xah@xahlee.org
> ∑ http://xahlee.org/
> _______________________________________________
> help-gnu-emacs mailing list
> help-gnu-emacs@gnu.org
> http://lists.gnu.org/mailman/listinfo/help-gnu-emacs
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
[-- Attachment #2: Type: text/plain, Size: 152 bytes --]
_______________________________________________
help-gnu-emacs mailing list
help-gnu-emacs@gnu.org
http://lists.gnu.org/mailman/listinfo/help-gnu-emacs
^ permalink raw reply [flat|nested] 15+ messages in thread
[parent not found: <mailman.4961.1197518641.18990.help-gnu-emacs@gnu.org>]
* Re: Help with keybinding to delete between {}
[not found] ` <mailman.4961.1197518641.18990.help-gnu-emacs@gnu.org>
@ 2007-12-13 10:39 ` Xah Lee
0 siblings, 0 replies; 15+ messages in thread
From: Xah Lee @ 2007-12-13 10:39 UTC (permalink / raw)
To: help-gnu-emacs
Google Groups diddles with my unicode chars.
The unadulterated code can be found here:
http://xahlee.org/emacs/elisp_examples.html
--------------
am not sure what's the prob with google. Don't know if they are still
experimenting with unicode chars in posts or what. I often use U+00AB
and U+00BB (french double angle quotes, here: <<>>). But starting about
2007-09, google groups either deletes them, or replace them with <<
and >>, or botched the replacement lopsided. (and this transformation
apparantly took place before it is posted, so it's distributed to all
other places, not just a displaying issue on goople groups) This week
i also noticed that they replace my bullet char "*" by a asterisk "*".
i'll be using one of the chinese quotations "「」『』〈〉《》" for posting i
think. For the bullet i might use a start "★" or heart "♥".
Xah
xah@xahlee.org
∑ http://xahlee.org/
On Dec 12, 7:59 pm, Mike Mattie <codermat...@gmail.com> wrote:
> On Thu, 6 Dec 2007 09:14:12 -0800 (PST)
>
>
>
> Xah Lee <x...@xahlee.org> wrote:
> > for some reason my code in the previous post is completely non-
> > functional. (i swear i used it for few months. Perhaps when i put on
> > the website i got smart and edited it "for the better" without
> > testing)
>
> > Here's the correct version:
>
> > (defun delete-enclosed-text ()
> > "Delete texts between any pair of delimiters.
> > Note: if you have nested matching pairs, the cursor
> > should be inside the inner most one. Else it gets confused.
> > This code should to be fixed in the future."
> > (interactive)
> > (save-excursion
> > (let (p1 p2)
> > (skip-chars-backward "^(<["<<") (setq p1 (point))
> > (skip-chars-forward "^)>]">>") (setq p2 (point))
> > (delete-region p1 p2)
> > )
> > )
> > )
>
> I don't this this can be right. on a single line it has three string quotation characters.
>
> (defun delete-enclosed-text ()
> "Delete texts between any pair of delimiters.
> Note: if you have nested matching pairs, the cursor
> should be inside the inner most one. Else it gets confused.
> This code should to be fixed in the future."
> (interactive)
> (skip-chars-forward "^)>>")
> (delete-backward-char (skip-chars-backward "^(<<")))
>
> this version doesn't change the mark so I dropped the save-excursion. It is not quite right because
> it does not handle nested sexp at all. I don't understand the elisp flavor of regex yet, so it's
> probably an easy fix.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Help with keybinding to delete between {}
2007-12-06 17:14 ` Xah Lee
` (2 preceding siblings ...)
[not found] ` <mailman.4961.1197518641.18990.help-gnu-emacs@gnu.org>
@ 2007-12-13 10:44 ` Mike Mattie
2007-12-13 12:46 ` Mike Mattie
2007-12-13 13:01 ` Peter Dyballa
3 siblings, 2 replies; 15+ messages in thread
From: Mike Mattie @ 2007-12-13 10:44 UTC (permalink / raw)
To: help-gnu-emacs
[-- Attachment #1.1: Type: text/plain, Size: 5528 bytes --]
On Thu, 6 Dec 2007 09:14:12 -0800 (PST)
Xah Lee <xah@xahlee.org> wrote:
> for some reason my code in the previous post is completely non-
> functional. (i swear i used it for few months. Perhaps when i put on
> the website i got smart and edited it "for the better" without
> testing)
>
> Here's the correct version:
>
> (defun delete-enclosed-text ()
> "Delete texts between any pair of delimiters.
> Note: if you have nested matching pairs, the cursor
> should be inside the inner most one. Else it gets confused.
> This code should to be fixed in the future."
> (interactive)
> (save-excursion
> (let (p1 p2)
> (skip-chars-backward "^(<["<<") (setq p1 (point))
> (skip-chars-forward "^)>]">>") (setq p2 (point))
> (delete-region p1 p2)
> )
> )
> )
I decided to fix it in regards to nested lists. My implementation works
however it is purely for elucidation. It is a recursive implementation
that is nth recursive where n is the number of nested delimiters in the list.
that means that if you use this on a list with deep nesting it *will* crash
after exhausting the recursion limit. So don't use it for real.
A reliable solution would likely be based off something from thingatpoint.el ?
there must be something like this in the code-motion code for elisp.
This sort of function/feature? is dangerous even when implemented procedurally
because it will go wild if your delimiters aren't matched correctly.
Other flaws:
* error path in bounds scan marked by "error ?" not implemented because I have
not studied elisp error handling yet.
* does not handle multi-byte characters due to use of aref in bounds-scan-{forward,backward}
With that said it does illustrate the value of lexical-let, and solves the
problem in a general way. It would be quite easy to add variations that
kill instead of deleting, or whatever other features you want.
I implemented it recursively simply because It looked prettier to me, probably
since I started with scheme. anyways here goes.
one last big fat warning: this code is for fun, it will eat your children eventually.
;; --- start of elisp
(defun bounds-scan ( seek-bounds open-bound-p close-bound-p restart-position position level )
"scan for the delimitation of a region. This is a general form of a
simple algorithm that counts opening and closing delimiters to scan
past nested delimited spans."
(progn
(goto-char position) ;; move to the starting position before scanning.
(funcall seek-bounds)
(cond
((funcall open-bound-p)
(bounds-scan seek-bounds open-bound-p close-bound-p restart-position
(funcall restart-position) (+ level 1)))
((funcall close-bound-p)
(if (> level 0)
;; when we have a positive level to start with
;; scan again with a decremented level.
(bounds-scan seek-bounds open-bound-p close-bound-p restart-position
(funcall restart-position) (- level 1))
;; return point as we are done
(point)
))
;; error ?
)))
(defun bounds-scan-forward ( delimiters position )
"entry point for bounds-scan forward. given delimiters: a
string containing a pair of delimiting characters, which must
be in \"open close\" order, scan forward for the bounding
delimiter returning the position before the delimiter"
(lexical-let
((open-delimiter (aref delimiters 0))
(close-delimiter (aref delimiters 1)))
(bounds-scan
(lambda ()
(skip-chars-forward (concat "^" delimiters)))
(lambda ()
(char-equal open-delimiter (char-after)))
(lambda ()
(char-equal close-delimiter (char-after)))
(lambda ()
(+ (point) 1))
position 0)))
(defun bounds-scan-backward ( delimiters position)
"entry point for bounds-scan backward. given delimiters: a
string containing a pair of delimiting characters, which must
be in \"open close\" order, scan backward for the bounding
delimiter returning the position after the delimiter"
(lexical-let
;; note the inversion of the order since we are looking backwards
((open-delimiter (aref delimiters 1))
(close-delimiter (aref delimiters 0)))
(bounds-scan
(lambda ()
(skip-chars-backward (concat "^" delimiters)))
(lambda ()
(char-equal open-delimiter (char-before)))
(lambda ()
(char-equal close-delimiter (char-before)))
(lambda ()
(- (point) 1))
position 0)))
(defun scan-lisp-list-close ()
"wrapper for bounds-scan that searches for the closing delimiter of a lisp list"
(let*
((start-at (point))
(close-at (bounds-scan-forward "()" start-at)))
(if (> close-at start-at)
(- close-at 1)
start-at)
))
(defun scan-lisp-list-open ()
"wrapper for bounds-scan that searches for the opening delimiter of a lisp list"
(let*
((start-at (point))
(open-at (bounds-scan-backward "()" start-at)))
(if (< open-at start-at)
(+ open-at 1)
start-at)
))
(defun lisp-list-delete-body ()
"delete the body of a lisp list including any nested lists"
(interactive)
(let
((open-pos (scan-lisp-list-open))
(close-pos (scan-lisp-list-close)))
(delete-backward-char (- close-pos open-pos))))
;;----- end of elisp
Cheers,
Mike Mattie
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
[-- Attachment #2: Type: text/plain, Size: 152 bytes --]
_______________________________________________
help-gnu-emacs mailing list
help-gnu-emacs@gnu.org
http://lists.gnu.org/mailman/listinfo/help-gnu-emacs
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Help with keybinding to delete between {}
2007-12-13 10:44 ` Mike Mattie
@ 2007-12-13 12:46 ` Mike Mattie
2007-12-13 13:01 ` Peter Dyballa
1 sibling, 0 replies; 15+ messages in thread
From: Mike Mattie @ 2007-12-13 12:46 UTC (permalink / raw)
To: help-gnu-emacs
[-- Attachment #1.1: Type: text/plain, Size: 6110 bytes --]
On Thu, 13 Dec 2007 02:44:00 -0800
Mike Mattie <codermattie@gmail.com> wrote:
> On Thu, 6 Dec 2007 09:14:12 -0800 (PST)
> Xah Lee <xah@xahlee.org> wrote:
>
> > for some reason my code in the previous post is completely non-
> > functional. (i swear i used it for few months. Perhaps when i put on
> > the website i got smart and edited it "for the better" without
> > testing)
> >
> > Here's the correct version:
> >
> > (defun delete-enclosed-text ()
> > "Delete texts between any pair of delimiters.
> > Note: if you have nested matching pairs, the cursor
> > should be inside the inner most one. Else it gets confused.
> > This code should to be fixed in the future."
> > (interactive)
> > (save-excursion
> > (let (p1 p2)
> > (skip-chars-backward "^(<["<<") (setq p1 (point))
> > (skip-chars-forward "^)>]">>") (setq p2 (point))
> > (delete-region p1 p2)
> > )
> > )
> > )
>
> I decided to fix it in regards to nested lists. My implementation
> works however it is purely for elucidation. It is a recursive
> implementation that is nth recursive where n is the number of nested
> delimiters in the list.
>
> that means that if you use this on a list with deep nesting it *will*
> crash after exhausting the recursion limit. So don't use it for real.
>
> A reliable solution would likely be based off something from
> thingatpoint.el ? there must be something like this in the
> code-motion code for elisp.
>
> This sort of function/feature? is dangerous even when implemented
> procedurally because it will go wild if your delimiters aren't
> matched correctly.
>
> Other flaws:
> * error path in bounds scan marked by "error ?" not implemented
> because I have not studied elisp error handling yet.
>
> * does not handle multi-byte characters due to use of aref in
> bounds-scan-{forward,backward}
>
> With that said it does illustrate the value of lexical-let, and
> solves the problem in a general way. It would be quite easy to add
> variations that kill instead of deleting, or whatever other features
> you want.
>
> I implemented it recursively simply because It looked prettier to me,
> probably since I started with scheme. anyways here goes.
>
> one last big fat warning: this code is for fun, it will eat your
> children eventually.
a small re-factor I noticed when I read the code a bit later. the check
for motion in the scan is hoisted into bounds-scan-{forward,backward} so
it isn't duplicated needlessly.
> ;; --- start of elisp
(defun bounds-scan ( seek-bounds open-bound-p close-bound-p restart-position position level )
"scan for the delimitation of a region. This is a general form of a
simple algorithm that counts opening and closing delimiters to scan
past nested delimited spans."
(progn
(goto-char position) ;; move to the starting position before scanning.
(funcall seek-bounds)
(cond
((funcall open-bound-p)
(bounds-scan seek-bounds open-bound-p close-bound-p restart-position
(funcall restart-position) (+ level 1)))
((funcall close-bound-p)
(if (> level 0)
;; when we have a positive level to start with
;; scan again with a decremented level.
(bounds-scan seek-bounds open-bound-p close-bound-p restart-position
(funcall restart-position) (- level 1))
;; return point as we are done
(point)
))
;; error ?
)))
(defun bounds-scan-forward ( delimiters position )
"entry point for bounds-scan forward. given delimiters: a
string containing a pair of delimiting characters, which must
be in \"open close\" order, scan forward for the bounding
delimiter returning the position before the delimiter"
(lexical-let
((open-delimiter (aref delimiters 0))
(close-delimiter (aref delimiters 1)))
(let
((close-at (bounds-scan
(lambda ()
(skip-chars-forward (concat "^" delimiters)))
(lambda ()
(char-equal open-delimiter (char-after)))
(lambda ()
(char-equal close-delimiter (char-after)))
(lambda ()
(+ (point) 1))
position 0)))
(if (> close-at position)
(- close-at 1)
position)
)))
(defun bounds-scan-backward ( delimiters position )
"entry point for bounds-scan backward. given delimiters: a
string containing a pair of delimiting characters, which must
be in \"open close\" order, scan backward for the bounding
delimiter returning the position after the delimiter"
(lexical-let
;; note the inversion of the order since we are looking backwards
((open-delimiter (aref delimiters 1))
(close-delimiter (aref delimiters 0)))
(let
((open-at (bounds-scan
(lambda ()
(skip-chars-backward (concat "^" delimiters)))
(lambda ()
(char-equal open-delimiter (char-before)))
(lambda ()
(char-equal close-delimiter (char-before)))
(lambda ()
(- (point) 1))
position 0)))
(if (< open-at position)
(+ open-at 1)
position)
)))
(defun scan-lisp-list-close ()
"wrapper for bounds-scan that searches for the closing delimiter of a lisp list"
(bounds-scan-forward "()" (point)))
(defun scan-lisp-list-open ()
"wrapper for bounds-scan that searches for the opening delimiter of a lisp list"
(bounds-scan-backward "()" (point)))
(defun lisp-list-delete-body ()
"delete the body of a lisp list including any nested lists"
(interactive)
(let
((open-pos (scan-lisp-list-open))
(close-pos (scan-lisp-list-close)))
(delete-backward-char (- close-pos open-pos))))
>
> ;;----- end of elisp
>
> Cheers,
> Mike Mattie
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
[-- Attachment #2: Type: text/plain, Size: 152 bytes --]
_______________________________________________
help-gnu-emacs mailing list
help-gnu-emacs@gnu.org
http://lists.gnu.org/mailman/listinfo/help-gnu-emacs
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Help with keybinding to delete between {}
2007-12-13 10:44 ` Mike Mattie
2007-12-13 12:46 ` Mike Mattie
@ 2007-12-13 13:01 ` Peter Dyballa
1 sibling, 0 replies; 15+ messages in thread
From: Peter Dyballa @ 2007-12-13 13:01 UTC (permalink / raw)
To: Mike Mattie; +Cc: help-gnu-emacs
[-- Attachment #1.1: Type: text/plain, Size: 777 bytes --]
Am 13.12.2007 um 11:44 schrieb Mike Mattie:
> A reliable solution would likely be based off something from
> thingatpoint.el ?
Isn't there also a problem when some such character is there in a
comment? Wouldn't it make more sense to use sexpressions? One of:
backward-sexp/backward-up-list/up-list? This could be used to climb
higher one level, if the previous region isn't worth enough to be
deleted. With kill-sexp.
These backward-sexp/backward-up-list/up-list should take into account
what is defined as delimiter.
--
Greetings
<]
Pete o __o |__ o recumbo
___o /I -\<, |o \ -\),-% ergo sum!
___/\ /\___./ \___...O/ O____.....`-O-'-()--o_________________
[-- Attachment #1.2: Signierter Teil der Nachricht --]
[-- Type: application/pgp-signature, Size: 194 bytes --]
[-- Attachment #2: Type: text/plain, Size: 152 bytes --]
_______________________________________________
help-gnu-emacs mailing list
help-gnu-emacs@gnu.org
http://lists.gnu.org/mailman/listinfo/help-gnu-emacs
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Help with keybinding to delete between {}
2007-12-06 6:33 ` Xah Lee
2007-12-06 17:14 ` Xah Lee
@ 2007-12-14 11:43 ` Xah Lee
1 sibling, 0 replies; 15+ messages in thread
From: Xah Lee @ 2007-12-14 11:43 UTC (permalink / raw)
To: help-gnu-emacs
today i took some closer look at cursor moving commands for editing
lisp code.
`C-M-n' Move forward over a parenthetical group (`forward-list').
`C-M-p' Move backward over a parenthetical group (`backward-
list').
`C-M-u' Move up in parenthesis structure (`backward-up-list').
`C-M-d' Move down in parenthesis structure (`down-list').
`C-M-f' Move forward over a balanced expression (`forward-sexp').
`C-M-b' Move backward over a balanced expression (`backward-
sexp').
`C-M-k' Kill balanced expression forward (`kill-sexp').
`C-M-<SPC>' Put mark after following expression (`mark-sexp').
which i was aware for about a year but never really used. I think they
are FANTASTIC. Previously i thought the extend-selection idea i had
was more powerful, but not really. (the extend-selection idea is
simply backward-up-list followed by mark-sexp)
The keybinding choices are pretty bad though. I now set them thus:
(global-set-key (kbd "M-<up>") 'backward-up-list)
(global-set-key (kbd "M-<down>") 'down-list)
(global-set-key (kbd "M-<left>") 'backward-sexp)
(global-set-key (kbd "M-<right>") 'forward-sexp)
(global-set-key (kbd "M-S-<left>") 'backward-list)
(global-set-key (kbd "M-S-<right>") 'forward-list)
Xah
xah@xahlee.org
\xAD\xF4 http://xahlee.org/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Help with keybinding to delete between {}
2007-12-05 1:33 Help with keybinding to delete between {} lampshade
` (4 preceding siblings ...)
2007-12-06 6:33 ` Xah Lee
@ 2007-12-07 16:30 ` Stefan Monnier
5 siblings, 0 replies; 15+ messages in thread
From: Stefan Monnier @ 2007-12-07 16:30 UTC (permalink / raw)
To: help-gnu-emacs
> I would really like a keybinding that would allow me to delete any
> text between sexp's like {} (), etc no matter where I am between them
> and whether or not that text has spaces.
You could start with C-M-u C-M-k. The only problem is if you're inside
a string or a comment, in which case it probably won't do what you want.
Stefan
^ permalink raw reply [flat|nested] 15+ messages in thread