Emacs équivalent à VIM ci "?

13

Emacs a-t-il l'équivalent de la commande VIMs ci "? En gros, je veux remplacer le texte à l'intérieur d'un ensemble de guillemets.

Dans vim je peux ci) ou ci] ou ci} pour "changer intérieur *" ...

erikcw
la source

Réponses:

19

Du haut de ma tête, la commande la plus proche est celle M-z "qui supprime tout du point à la prochaine occurrence du "caractère".

Il y a aussi C-M-k, alias "tuer l'expression équilibrée", qui supprimera une instruction entre parenthèses complète ou une chaîne entre guillemets, etc. basée sur la définition des modes actuels de "l'expression équilibrée" et le caractère actuellement sous le point (c'est-à-dire que cela ne fonctionne que si le curseur est sur l'ouverture "" "ou" ("etc.).

Justin Smith
la source
7

De manière similaire à la suggestion de Justin, CM-SPACE vous donne "mark-sexp" qui sélectionnera la paren d'équilibrage, la citation, etc. et ensuite vous pouvez Cw ou quoi que ce soit pour le faire disparaître. Si vous souhaitez voir ce que vous êtes sur le point de supprimer avant de le supprimer ...

Brian Postow
la source
3

Je suis juste tombé sur cette question; voici une solution personnalisée qui a fonctionné pour moi:

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

Ensuite, liez la suppression entre paires à la clé que vous souhaitez. Pour moi, je l'ai lié sur Cz i.

ozataman
la source
2

J'ai bien peur de ne pas connaître la fonctionnalité ci de VIM, mais avez-vous regardé la regexp Emacs remplacer? Je ne peux pas parler de la sémantique exacte ou de la facilité d'utilisation en comparaison, mais c'est ce que j'utiliserais pour ce que je pense que vous voulez.

Michael H.
la source
emacs regexp replace est l'équivalent de vi: s / regex / remplacement /, ce qu'il veut, c'est une pression sur une touche pour supprimer et remplacer l'expression équilibrée actuelle au point.
Justin Smith
2

J'ai créé un mode mineur qui fournit certaines de ces installations Vim appelées Markit .

Daimrod
la source
0

Voici ma version qui supprimera tout dans (ou y compris) une paire de caractères correspondante. Les paires de caractères sont définies dans une liste afin que le caractère de début / fin correspondant soit connu. Je l'ai mappé à "Cc i" pour le changement et "Cc a" pour le changement de tous.

Il copie également les caractères supprimés dans le presse-papiers pour un collage ultérieur.

; 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)
user2549917
la source
0

C'était quelque chose qui me manquait à Vim, et zap-to-charne semblait pas le faire correctement.

Voici mon humble tentative de recréer "ci" et "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))
)

Normalement, la condition-case n'est pas nécessaire, car le troisième paramètre (facultatif) de search-forward / search-backward est destiné à indiquer quoi faire en cas d'échec de la recherche. Mais pour une raison quelconque, placer une seconde recherche comme troisième paramètre pour la première donne un comportement étrange.

vladimird
la source
0

J'ai essayé les solutions ici, mais j'ai trouvé que chacune d'elles manquait d'une certaine manière, alors j'ai trouvé cela. Il accepte un délimiteur de début ou de fin et utilise des fonctions Emacs intégrées pour éviter d'avoir besoin d'une table de traduction pour les délimiteurs.

(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) 
blujay
la source