Risposte:
Dalla parte superiore della mia testa, il comando più vicino è M-z "
che elimina tutto dal punto alla prossima occorrenza del "personaggio.
C'è anche C-M-k
, noto come "uccidi espressione bilanciata", che cancellerà un'istruzione parentesi completa o una stringa tra virgolette doppie ecc. In base alla definizione delle modalità correnti di "espressione equilibrata" e al carattere attualmente sotto punto (cioè. Funziona solo se il cursore è sull'apertura '"' o '(' ecc.).
Analogamente al suggerimento di Justin CM-SPACE ti dà "mark-sexp" che selezionerà la parentesi, la citazione, ecc. E poi puoi Cw o qualsiasi altra cosa per farla sparire. Nel caso in cui desideri VEDERE ciò che stai per eliminare prima di eliminarlo ...
Sì! L'equivalente di VIMs "comando in Emacs è ... ci" :-)
http://www.emacswiki.org/emacs-de/Vimpulse
Mi sono appena imbattuto in questa domanda; ecco una soluzione personalizzata che ha funzionato per me:
(defun seek-backward-to-char (chr)
"Seek backwards to a character"
(interactive "cSeek back to char: ")
(while (not (= (char-after) chr))
(forward-char -1)))
(defun delete-between-pair (char)
"Delete in between the given pair"
(interactive "cDelete between char: ")
(seek-backward-to-char char)
(forward-char 1)
(zap-to-char 1 char)
(insert char)
(forward-char -1))
Quindi associa delete-between-pair alla chiave che preferisci. Per me, ho legato a Cz i.
Temo di non conoscere la funzionalità ci di VIM, ma hai mai visto Emacs regexp sostituire? Non posso parlare con la semantica esatta o quanto sia facile da usare in confronto, ma è quello che userei per quello che penso tu voglia.
Magnars (autore del sito EmacsRocks) ha scritto questo plugin per fare esattamente quello che stai chiedendo.
https://github.com/magnars/change-inner.el
Ovviamente, puoi anche usare la modalità Evil.
Ecco la mia versione che eliminerà tutto all'interno (o includendo) una coppia di caratteri corrispondente. Le coppie di caratteri sono definite in un elenco in modo che il carattere iniziale / finale corrispondente sia noto. L'ho mappato su "Cc i" per la modifica e "Cc a" per la modifica di tutti.
Copia anche i caratteri rimossi negli Appunti per incollarli in seguito.
; Re-create ci" ca"...
(defun seek-backward-to-char (chr)
"Seek backwards to a character"
(interactive "cSeek back to char: ")
(while (not (= (char-after) chr))
(forward-char -1)))
(setq char-pairs
'(( ?\" . ?\" )
( ?\' . ?\' )
( ?\( . ?\) )
( ?\[ . ?\] )
( ?\{ . ?\} )
( ?< . ?> )))
(defun get-char-pair (chr)
(let ((result ()))
(dolist (x char-pairs)
(setq start (car x))
(setq end (cdr x))
(when (or (= chr start) (= chr end))
(setq result x)))
result))
(defun get-start-char (chr)
(car (get-char-pair chr)))
(defun get-end-char (chr)
(cdr (get-char-pair chr)))
(defun seek-to-matching-char (start end count)
(while (> count 0)
(if (= (following-char) end)
(setq count (- count 1))
(if (= (following-char) start)
(setq count (+ count 1))))
(forward-char 1)))
(defun seek-backward-to-matching-char (start end count)
(if (= (following-char) end)
(forward-char -1))
(while (> count 0)
(if (= (following-char) start)
(setq count (- count 1))
(if (= (following-char) end)
(setq count (+ count 1))))
(if (> count 0)
(forward-char -1))))
(defun delete-between-pair (char)
"Delete in between the given pair"
(interactive "cDelete between char: ")
(seek-backward-to-matching-char (get-start-char char) (get-end-char char) 1)
(forward-char 1)
(setq mark (point))
(seek-to-matching-char (get-start-char char) (get-end-char char) 1)
(forward-char -1)
(kill-region mark (point)))
(defun delete-all-pair (char)
"Delete in between the given pair and the characters"
(interactive "cDelete all char: ")
(seek-backward-to-matching-char (get-start-char char) (get-end-char char) 1)
(setq mark (point))
(forward-char 1)
(seek-to-matching-char (get-start-char char) (get-end-char char) 1)
(kill-region mark (point)))
(global-set-key (kbd "C-c i") 'delete-between-pair)
(global-set-key (kbd "C-c a") 'delete-all-pair)
Questo era qualcosa che mi mancava da Vim e zap-to-char
non sembrava tagliarlo bene.
Ecco il mio umile tentativo di ricreare "ci" e "ca":
(defun change-outer (str)
(interactive "sChange outer: ")
(condition-case nil
(search-backward str (line-beginning-position))
(error (search-forward str (line-end-position))
(forward-char -1)))
(kill-sexp)
)
(defun change-inner (str)
(interactive "sChange inner: ")
(condition-case nil
(search-backward str (line-beginning-position))
(error (search-forward str (line-end-position))
(forward-char -1)))
(push-mark)
(forward-sexp)
(forward-char -1)
(exchange-point-and-mark)
(forward-char 1)
(kill-region (point) (mark))
)
Normalmente, il caso condizione non è necessario, poiché il terzo parametro (facoltativo) di ricerca-avanti / ricerca-indietro ha lo scopo di indicare cosa fare nel caso in cui la ricerca fallisca. Ma per qualche motivo, posizionare una seconda ricerca come terzo parametro per il primo produce un comportamento strano.
Ho provato le soluzioni qui, ma ho trovato ognuna delle loro necessità in qualche modo, quindi ho pensato a questo. Accetta un delimitatore iniziale o finale e utilizza le funzioni Emacs integrate per evitare la necessità di una tabella di traduzione per i delimitatori.
(defun change-inner (prefix character)
"Kill region inside delimiters, using either beginning or
ending delimiter. With prefix arg, kill including delimiters."
(interactive "p\nc")
(let ((initial-point (point))
(start)
(end)
(move-point-by (if (> prefix 1) 0 1)))
(condition-case nil
(progn
;; Search forward for given char
(search-forward (char-to-string character))
(setq end (- (point) move-point-by))
(condition-case nil
(backward-sexp)
(error (backward-list)))
(setq start (+ (point) move-point-by))
(kill-region start end)
(or prefix (forward-char)))
(error (progn
;; Reset and search backward for given char
(goto-char initial-point)
(search-backward (char-to-string character))
(setq start (+ (point) move-point-by))
(condition-case nil
(forward-list)
(error (forward-sexp))))
(setq end (- (point) move-point-by))
(kill-region start end)
(or prefix (backward-char))))))
(global-set-key (kbd "M-i") 'change-inner)
(defun change-outer ()
(interactive)
(let ((current-prefix-arg '(4)))
(call-interactively 'change-inner)))
(global-set-key (kbd "M-o") 'change-outer)