Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to copy an entire line until a stop character in Emacs?

Tags:

emacs

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)

like image 380
starcorn Avatar asked Oct 12 '10 22:10

starcorn


3 Answers

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))))
like image 66
Trey Jackson Avatar answered Sep 27 '22 22:09

Trey Jackson


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).

like image 32
Gilles 'SO- stop being evil' Avatar answered Sep 28 '22 00:09

Gilles 'SO- stop being evil'


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.

like image 21
Joakim Hårsman Avatar answered Sep 27 '22 22:09

Joakim Hårsman