Emacs äquivalent zu VIM ci "?

13

Entspricht der Befehl "emacs" dem Befehl "VIMs ci"? Grundsätzlich möchte ich den Text in Anführungszeichen setzen.

In vim kann ich ci) oder ci] oder ci} "inner * ändern" ...

erikcw
quelle

Antworten:

19

Aus dem Kopf heraus ist der nächste Befehl, M-z "der alles vom Punkt bis zum nächsten Auftreten des "Zeichens löscht.

Es gibt auch den C-M-kBegriff "ausgewogener Ausdruck töten", der eine vollständig in Klammern gesetzte Anweisung oder eine Zeichenfolge in doppelten Anführungszeichen usw. löscht, basierend auf der aktuellen Modusdefinition von "ausgewogener Ausdruck" und dem Zeichen, das gerade unter dem Punkt steht (dh, es funktioniert nur, wenn der Cursor steht) steht an der öffnung '"' oder '(' etc.).

Justin Smith
quelle
7

Ähnlich wie bei Justins Vorschlag gibt CM-SPACE Ihnen "mark-sexp", das den Abgleich von Paren, Zitat usw. auswählt, und dann können Sie Cw oder was auch immer zum Verschwinden bringen. Falls Sie SEHEN möchten, was Sie löschen möchten, bevor Sie es löschen ...

Brian Postow
quelle
3

Bin gerade auf diese Frage gestoßen; Hier ist eine benutzerdefinierte Lösung, die für mich funktioniert hat:

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

Binden Sie anschließend Delete-Between-Pair an einen beliebigen Schlüssel. Für mich habe ich es an Cz i gebunden.

Ozataman
quelle
2

Ich fürchte, ich kenne die Ci-Funktion von VIM nicht, aber haben Sie sich Emacs regexp replace angesehen? Ich kann nicht mit der genauen Semantik sprechen oder sagen, wie einfach es im Vergleich ist, aber es ist das, was ich für das verwenden würde, was ich denke, dass Sie wollen.

Michael H.
quelle
emacs regexp replace ist das Äquivalent von vi: s / regex / replacement /. Was er möchte, ist ein Tastendruck zum Löschen und Ersetzen des aktuellen ausgeglichenen Ausdrucks am Punkt.
Justin Smith
2

Ich habe einen Nebenmodus erstellt, der einige dieser Vim-Funktionen namens Markit enthält .

Daimrod
quelle
0

Hier ist meine Version, die alles innerhalb (oder einschließlich) eines übereinstimmenden Zeichenpaares löscht. Die Zeichenpaare werden in einer Liste definiert, so dass die übereinstimmenden Start- / Endzeichen bekannt sind. Ich habe es "Cc i" für die Änderung in und "Cc a" für die Änderung aller zugeordnet.

Es kopiert auch die entfernten Zeichen in die Zwischenablage, um sie später einzufügen.

; 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
quelle
0

Dies war etwas, was ich bei Vim vermisst hatte und zap-to-charnicht richtig zu schneiden schien.

Hier ist mein bescheidener Versuch, "ci" und "ca" neu zu erstellen:

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

Normalerweise ist der Bedingungsfall nicht erforderlich, da der dritte (optionale) Parameter von Suche vorwärts / Suche rückwärts angeben soll, was zu tun ist, wenn die Suche fehlschlägt. Aus irgendeinem Grund führt die Platzierung der zweiten Suche als dritter Parameter für die erste zu einem merkwürdigen Verhalten.

vladimird
quelle
0

Ich habe die Lösungen hier ausprobiert, aber festgestellt, dass sie alle in irgendeiner Weise fehlten, und bin auf diese Idee gekommen. Es akzeptiert entweder einen Anfangs- oder einen Endbegrenzer und verwendet integrierte Emacs-Funktionen, um zu vermeiden, dass eine Übersetzungstabelle für Begrenzer benötigt wird.

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