I'm trying to select text between parentheses. This text is not
code. This is my block of text:
(
foo
bar
baz
)
Problem is that it selects the whole first line after the first
parentheses, so I get a whole line of white space in front of the first
character. I'd like the selection to start at the first character after
the first parentheses and end at the last character before the last
parentheses. I tried adding (delete-horizontal-space).
Any pointers as to how I can do this?.
(require 'simple)
(defun set-selection-around-parens()
(interactive)
(let ( (right-paren (save-excursion ; using save-excursion because
; we don't want to move the
; point.
(re-search-forward ")" nil t))) ; bound nil
; no-error t
(left-paren (save-excursion (re-search-backward "(" nil t))))
(when (and right-paren left-paren)
;; this is actually a way to activate a mark
;; you have to move your point to one side
(push-mark (- right-paren 1))
(goto-char (+ left-paren 1))
(delete-horizontal-space)
(activate-mark)
)))
-- Esben Stien is b0ef@e s a http://www. s t n m
irc://irc. b - i . e/%23contact
sip:b0ef@ e e jid:b0ef@ n n
> I'm trying to select text between parentheses. This text is not
> code. This is my block of text: > (
> foo
> bar
> baz
> )
> Problem is that it selects the whole first line after the first
> parentheses, so I get a whole line of white space in front of > the first character. I'd like the selection to start at the first > character after the first parentheses and end at the last
> character before the last parentheses. I tried adding
> (delete-horizontal-space).
> Any pointers as to how I can do this?.
> (require 'simple)
You never need to require `simple.el[c]'. It is preloaded.
Someone else might have another suggestion. Or you can tweak this.
If you do not want to select only whitespace between parens - e.g.,
for `( )', then you might change \\(.+\\) to \\(\\S-+.*\\).
That is, "(\\(\\s-\\|[\n]\\)*\\(\\S-+.*\\)\\(\\s-\\|[\n]\\)*)".
The regexp matches `(' followed by perhaps some whitespace (including newlines):
"(\\(\\s-\\|[\n]\\)*"
Followed by a non-empty stretch of any chars "\\(.+\\)"
(or perhaps "\\(\\S-+.*\\)").
Followed by perhaps some whitespace (maybe newlines)
followed by `)': "(\\(\\s-\\|[\n]\\)*)".
The regexp's first subgroup matches the possible first stretch of whitespace.
Its second subgroup matches the text you want. So you pick up the text from
(match-beginning 2) to (match-end 2).
Set `deactivate-mark' to nil at the end of a command where you want the mark to
remain active.
What that code, which you say does nothing, does is to set the mark where the
2nd subgroup-match starts, then move point to where the 2nd subgroup-match ends,
then ensure that the mark remains active after the command.
> nothing seems to happen when I run this code.
> No selection is made.
Works for me. Be sure you corrected the typo from \s- to \\s-.
And be sure you have `transient-mark-mode' turned on.
But again, this is not a real parsing of lists, so there is no treatment of,
say, nested lists. The \\S-+ matches any non-whitespace chars, including ( and
). So using it on (foo (bar))) selects "foo (bar))": everything between the
first ( and the last ).
If you want to handle lists correctly (e.g. nesting) then use the Elisp
functions for traversing or parsing lists/sexps.
And as I say, perhaps someone else will help you more, or differently.
> What that code, which you say does nothing, does is to set the mark
> where the 2nd subgroup-match starts, then move point to where the 2nd
> subgroup-match ends, then ensure that the mark remains active after
> the command.
I've tried this on two platforms now; on my own distro, where I run
emacs-22.3.2 and on an Ubuntu 12.04 with emacs-23.3.1
I place my point on "b" in bar in this code:
(
foo
bar
baz
)
, then I M-x everything-of-interest-between-parens RET, but the point
stands at the same place and nothing is selected.
I have transient-mark-mode enabled.
> But again, this is not a real parsing of lists, so there is no treatment of,
> say, nested lists.
Nope. I have no need for that.
> And as I say, perhaps someone else will help you more, or differently.
Thank you very much for your help so far.
-- Esben Stien is b0ef@e s a http://www. s t n m
irc://irc. b - i . e/%23contact
sip:b0ef@ e e jid:b0ef@ n n
> I've tried this on two platforms now; on my own distro, where I run
> emacs-22.3.2 and on an Ubuntu 12.04 with emacs-23.3.1
> I place my point on "b" in bar in this code: > (
> foo
> bar
> baz
> )
Put the cursor before the (, not after it. Or redefine the command accordingly.
I did not hear you say that you wanted it to start with point between the
parens. As I described, the regexp I gave looks first for a (.
Also, . matches any char except a newline. If you want to pick up newlines
also, and not other whitespace, then change \\(.+\\) to
\\(\\(\\S-\\|[\n]\\)+\\). But if you want to pick up whitespace too, as in (foo
bar baz) or
(
foo bar
baz
)
then use just \\([^)]\\), IOW, just pick up everything up to the first ).
It depends what you want. Read the Elisp manual's section about regexps.
. matches any char except a newline.
[\n] matches only a newline.
\\s- matches a whitespace char (but not a newline).
\\S- matches a non-whitespace, non-newline char.