Emacs setara dengan VIM ci "?

13

Apakah emacs memiliki persamaan dengan perintah VIMs ci? Pada dasarnya saya ingin mengganti teks di dalam satu set tanda kutip.

Dalam vim saya dapat ci) atau ci] atau ci} untuk "mengubah bagian dalam *" ...

erikcw
sumber

Jawaban:

19

Dari atas kepala saya, perintah terdekat adalah M-z "yang menghapus semuanya dari titik ke kejadian berikutnya "" karakter.

Ada juga C-M-k, alias "kill balanced expression", yang akan menghapus pernyataan tanda kurung penuh atau string yang dikutip ganda, dll. Berdasarkan pada definisi mode saat ini dari "ekspresi seimbang" dan karakter yang saat ini dalam poin (mis. Hanya berfungsi jika kursor ada di pembukaan '"' atau '(' dll).

Justin Smith
sumber
7

Demikian pula dengan saran Justin CM-SPACE memberi Anda "mark-sexp" yang akan memilih untuk menyeimbangkan paren, kutipan, dll. Dan kemudian Anda dapat Cw atau apa pun untuk membuatnya pergi. Jika Anda ingin MELIHAT apa yang akan Anda hapus sebelum Anda menghapusnya ...

Brian Postow
sumber
3

Baru saja menemukan pertanyaan ini; berikut adalah solusi khusus yang berfungsi untuk saya:

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

Kemudian ikat hapus-antara-pasangan ke tombol apa pun yang Anda suka. Bagi saya, saya memilikinya terikat pada Cz i.

ozataman
sumber
2

Saya khawatir saya tidak tahu tentang fitur ci VIM, tetapi apakah Anda sudah melihat Emacs regexp ganti? Saya tidak dapat berbicara dengan semantik yang tepat atau betapa mudahnya untuk digunakan sebagai perbandingan, tetapi itulah yang akan saya gunakan untuk apa yang saya pikir Anda inginkan.

Michael H.
sumber
emacs regexp replace setara dengan vi: s / regex / replacement /, yang dia inginkan adalah penekanan tombol untuk menghapus dan mengganti ekspresi seimbang saat ini pada titik.
Justin Smith
2

Saya telah membuat mode minor yang menyediakan beberapa fasilitas Vim yang disebut Markit .

Daimrod
sumber
0

Inilah versi saya yang akan menghapus semuanya dalam (atau termasuk) sepasang karakter yang cocok. Pasangan karakter didefinisikan dalam daftar sehingga karakter awal / akhir yang cocok diketahui. Saya telah memetakannya ke "Cc i" untuk perubahan dan "Cc a" untuk mengubah semuanya.

Itu juga menyalin karakter yang dihapus ke papan klip untuk ditempelkan nanti.

; 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)
pengguna2549917
sumber
0

Ini adalah sesuatu yang saya lewatkan dari Vim, dan zap-to-charsepertinya tidak memotongnya dengan benar.

Ini adalah upaya sederhana saya untuk membuat ulang "ci" dan "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))
)

Biasanya, case-condition tidak diperlukan, karena parameter ketiga (opsional) dari search-forward / search-backward dimaksudkan untuk menunjukkan apa yang harus dilakukan jika pencarian gagal. Tetapi karena alasan tertentu, menempatkan pencarian kedua sebagai parameter ketiga untuk yang pertama menghasilkan perilaku aneh.

vladimird
sumber
0

Saya mencoba solusinya di sini, tetapi menemukan masing-masing dari mereka menginginkan sesuatu, jadi saya datang dengan ini. Ini menerima pembatas awal atau akhir, dan menggunakan fungsi Emacs bawaan untuk menghindari memerlukan tabel terjemahan untuk pembatas.

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