tags:

views:

128

answers:

5

Today I saw a neat copy function in VI, in which you could copy an entire line until a stop character.

e.g. if( copy == this );

With VI he could copy everything inside the parenthesis. I wonder if you can do it with emacs as well? (Without using ctrl+space and manually marking what I want to kill)

A: 

Sure, define a macro. Start your macro recording by typing c-x (. Then do the sequence of commands you want to repeat:

c-s (
c-space
c-s )
M-w

Then finish your macro with c-x ). Use it with c-x e.

Something like that... It's probably got fencepost problems. If you don't want it to move your mark, save that and restore it at the start of the macro.

More info on macros (like how to save bind them to other keys) here:

http://www.emacswiki.org/emacs/KeyboardMacros

Paul McMillan
A: 

Emacs has a gazillion commands, so there could well be one that does exactly that.

What I do in such a situation is mark my spot (with ctrl-space), then do a forward search (ctrl-s) and type in what I'm searching for (in your case an end-paren, but it could be something more verbose like Pascal's "end My_Procedure_Name;"). That will select all the text from where I marked up to where it found the search pattern. Then I ctrl-k to cut the text into the kill buffer.

In short:

ctrl-space
ctrl-s
) return
ctrl-k

(and a ctrl-_ if you want to keep the text where it is too).

There may be quicker/better/etc. ways, but that's the subset of emacs commands I know well enough to do without having to stop to think about it.

T.E.D.
That's how I do it if I need to do it once. If I need to do it with any regularity, I make a macro...
Paul McMillan
+11  A: 

Try

M-z CHAR

Which kills the text through the next occurrence of CHAR. Aka M-x zap-to-char. Of interest might be the documentation for Other Kill Commands.

Edited to add: Upon request, here is zap-to-before-char, which just took the source code for zap-to-char and removed a comment (and updated doc string):

(defun zap-to-before-char (arg char)
  "Kill up to and ARGth occurrence of CHAR.
Case is ignored if `case-fold-search' is non-nil in the current buffer.
Goes backward if ARG is negative; error if CHAR not found."
  (interactive "p\ncZap to char: ")
  ;; Avoid "obsolete" warnings for translation-table-for-input.
  (with-no-warnings
    (if (char-table-p translation-table-for-input)
        (setq char (or (aref translation-table-for-input char) char))))
  (kill-region (point) (progn
                         (search-forward (char-to-string char) nil nil arg)
                         (goto-char (if (> arg 0) (1- (point)) (1+ (point))))
                         (point))))
Trey Jackson
I wish that there was M-x zap-to-regexp. or atleast M-x zap-before-char.
aartist
@aartist `zap-to-before-char` is easy - I've amended the answer to include that, the change was in the source code, just commented out. Sounds like you weren't the first to want this.
Trey Jackson
+1  A: 

If the cursor is between the parentheses, the shortest sequence I can think of to copy the whole parenthesised group (including the parentheses) is C-M-u C-M-SPC M-w (backward-up-list, mark-sexp, kill-ring-save). If you want to kill that text, C-M-u C-M-k (backward-up-sexp, kill-sexp). The sexp commands are generally the easiest way of dealing with parenthesized groups; other important commands are C-M-b (backward-sexp) and C-M-f (forward-sexp) (notice the C-M- theme).

Gilles
A: 

The beauty of Emacs is that it's very easy to write some elisp to make it do what you want:

(defun mark-inside-delimiters ()
"Mark all chars inside the balanced expression point is in"
  (interactive)
  (let (p start pairs stop)
    (skip-chars-backward "^<({[\"'")
    (setq p (point))
    (setq start (char-to-string (preceding-char)))
    (setq pairs '(("<" . ">")("(" . ")")("{" . "}")
                  ("[" . "]")("\"" . "\"")("'" . "'")))
    (setq stop (cdr (assoc start pairs)))
    (skip-chars-forward (concat"^" stop))
    (set-mark p)))

(global-set-key (kbd "C-c m") 'mark-inside-delimiters)

This particular example isn't syntax-aware so it won't handle strings that contain escaped quotes, or parentheses inside strings, but it works for most cases.

Joakim Hårsman
i'm not much of a emacs hacker, but where should I add that part in emacs?
starcorn
In your ".emacs" file which has all your Emacs settings. Inside Emacs, Press `C-x C-f` (press and hold Ctrl, then press and release x, then f). You'll be prompted for a file name. Type `~/.emacs` and press enter. Paste the above code anywhere you like in that file.
Joakim Hårsman