Câu trả lời:
Ngoài đỉnh đầu của tôi, lệnh gần nhất là M-z "
xóa mọi thứ từ điểm này đến lần xuất hiện tiếp theo của "ký tự.
Ngoài ra C-M-k
, còn có "giết biểu thức cân bằng", sẽ xóa một câu lệnh được ngoặc đơn đầy đủ hoặc chuỗi trích dẫn kép, v.v. dựa trên định nghĩa chế độ hiện tại của "biểu thức cân bằng" và ký tự hiện tại (ví dụ: nó chỉ hoạt động nếu con trỏ đang mở '' 'hoặc' ('v.v.).
Tương tự như đề xuất của Justin, CM-SPACE cung cấp cho bạn "mark-sexp" sẽ chọn paren cân bằng, trích dẫn, v.v. và sau đó bạn có thể Cw hoặc bất cứ điều gì để làm cho nó biến mất. Trong trường hợp bạn muốn XEM những gì bạn sắp xóa trước khi xóa nó ...
Đúng! Tương đương với lệnh "VIMs ci" trong Emacs là ... ci ":-)
http://www.emacswiki.org/emacs-de/Vimpulse
Chỉ vấp phải câu hỏi này; đây là một giải pháp tùy chỉnh phù hợp với tôi:
(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))
Sau đó liên kết xóa giữa các cặp với bất kỳ khóa nào bạn thích. Đối với tôi, tôi có nó ràng buộc vào Cz i.
Tôi sợ rằng tôi không biết về tính năng ci của VIM, nhưng bạn đã xem xét thay thế regac của Emacs chưa? Tôi không thể nói với ngữ nghĩa chính xác hoặc cách dễ dàng sử dụng để so sánh, nhưng đó là những gì tôi sẽ sử dụng cho những gì tôi nghĩ bạn muốn.
Magnars (tác giả của trang EmacsRocks) đã viết plugin này để làm chính xác những gì bạn đang yêu cầu.
https://github.com/magnars/change-inner.el
Rõ ràng, bạn cũng có thể sử dụng chế độ Evil.
Đây là phiên bản của tôi sẽ xóa mọi thứ trong (hoặc bao gồm) một cặp ký tự trùng khớp. Các cặp ký tự được xác định trong một danh sách để biết ký tự bắt đầu / kết thúc phù hợp. Tôi đã ánh xạ nó tới "Cc i" để thay đổi và "Cc a" để thay đổi tất cả.
Nó cũng sao chép các ký tự đã xóa vào bảng clip để dán sau.
; 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)
Đây là thứ mà tôi đã thiếu từ Vim, và zap-to-char
dường như không cắt nó đúng.
Đây là nỗ lực khiêm tốn của tôi để tạo lại "ci" và "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))
)
Thông thường, trường hợp điều kiện là không cần thiết, vì tham số thứ ba (tùy chọn) của tìm kiếm chuyển tiếp / tìm kiếm ngược có nghĩa là chỉ ra những việc cần làm trong trường hợp tìm kiếm thất bại. Nhưng vì một số lý do, việc đặt tìm kiếm thứ hai làm tham số thứ ba cho lần đầu tiên mang lại hành vi lạ.
Tôi đã thử các giải pháp ở đây, nhưng thấy mỗi người trong số họ muốn theo một cách nào đó, vì vậy tôi đã nghĩ ra điều này. Nó chấp nhận một dấu phân cách bắt đầu hoặc kết thúc và sử dụng các hàm Emacs tích hợp để tránh cần một bảng dịch cho các dấu phân cách.
(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)