Thay thế văn bản bên trong các dấu phân cách khác nhau (ví dụ: ngoặc, ngoặc kép)


9

Tôi thường thực hiện một số triển khai thử nghiệm với các giá trị được mã hóa cứng mà sau này tôi muốn thay đổi. Giống

ref = open('specific-file-name')

Mà tôi muốn đổi thành

ref = open(fname)

Tôi đã quen với vim và ở đó tôi có thể gõ ci(fnamegiả sử rằng điểm đó nằm trong dấu ngoặc. ( ci(viết tắt của dấu ngoặc trong).

Làm thế nào tôi có thể đạt được một cái gì đó như 'thay thế bên trong' trong emacs?

Câu trả lời:


9

Sử dụng expand-region

Tôi sẽ khuyên bạn nên cài đặt expand-regiongói (cũng có sẵn trên Melpa). Nó sẽ hữu ích cho việc chỉnh sửa các tình huống được đề cập trong ví dụ của bạn và nhiều hơn nữa.

expand-regionthông minh. Dựa trên chế độ chính, nó sẽ cố gắng tìm ra những gì bạn đang cố gắng chọn. Tôi không biết từ ngôn ngữ nào bạn có đoạn mã ví dụ nên tôi sẽ sử dụng đoạn mã ví dụ của bạn và sửa đổi một chút cho Python (remove;). Vì vậy, lời giải thích dưới đây của tôi là với đoạn mã dưới đây trong một python-modebộ đệm.

ref = open('specific-file-name') 

Nếu điểm nằm cạnh một trích dẫn

Các hình chữ nhật dọc màu đen bên dưới cho biết con trỏ sẽ trông như thế nào.

# point on left of left quote, the cursor is hiding the quote under it
ref = open(▮specific-file-name') 

# point on left of right parenthesis, the cursor is hiding the parenthesis under it       
ref = open('specific-file-name'▮

Trong cả hai trường hợp, khi bạn làm M-x er/expand-region, 'specific-file-name'sẽ được chọn và sau đó bạn có thể nhấn DEL(hoặc xóa lùi) để xóa lựa chọn.

Nếu bạn đã delete-selection-modebật (tôi muốn bật cá nhân đó), bạn có thể bắt đầu nhập sau khi thực hiện lựa chọn và điều đó sẽ ghi đè lên lựa chọn.

Tất nhiên, nếu bạn sử dụng er/expand-regionnhiều, bạn sẽ liên kết nó với một ràng buộc khóa ngắn. Tôi thích ràng buộc nó với C-\. Vì vậy, với điểm bên cạnh một trích dẫn duy nhất: C-\fnamesẽ cho tôiref = open(fname);

nhập mô tả hình ảnh ở đây

Nếu điểm là một nơi nào đó bên trong dấu ngoặc kép

Sử dụng expand-region, điểm không cần phải ở gần dấu ngoặc kép. Nhưng trong trường hợp này, bạn sẽ chỉ cần thêm một vài (thường là một hoặc hai) phím nữa.

Giả sử vị trí con trỏ như bây giờ:

# cursor shown below is hiding the i character under it
ref = open('specif▮c-file-name')

Sử dụng cùng một ràng buộc như tôi đã sử dụng ở trên:

  • Lần đầu tiên tôi nhấn C-\sẽ chọn specific.
  • Bây giờ tôi chỉ cần nhấn \để mở rộng vùng chọn ( expand-regiontính năng). Điều đó sẽ chọn specific-file-name.

    Nếu bạn đã bị ràng buộc er/expand-regionđể C-=, đánh =một lần nữa sẽ làm việc mở rộng gia tăng. Đọc tài liệu của nó về cách ràng buộc các khóa để mở rộng / thu hẹp lựa chọn.

  • Đánh \một lần nữa sẽ chọn 'specific-file-name'.
  • Bây giờ bạn tiến hành nhấn DELđể xóa lựa chọn và sau đó gõ fname. Nếu delete-selection-modeđược kích hoạt, bạn có thể bỏ qua DELđột quỵ.

Tóm lại, với delete-selection-modekích hoạt, các nét chính trông như : C-\\\fname.

nhập mô tả hình ảnh ở đây


Sử dụng change-inner

Tôi cũng đã xem qua change-innergói bởi các expand-regiontác giả magnars (trong đó sử dụng expand-regionnhư back-end) để thực hiện chính xác những gì Vim cikhông (và cũng có thể thay đổi bên ngoài ).

Từ gói README:

change-innercung cấp cho bạn cilệnh của vim , xây dựng trên expand-region. Nó được giải thích dễ dàng nhất bằng ví dụ:

function test() {
  return "semantic kill";
}

Với điểm sau từ ngữ nghĩa

change-inner "sẽ giết nội dung của chuỗi
change-outer "sẽ giết toàn bộ chuỗi
change-inner {sẽ giết câu lệnh return
change-outer {sẽ giết toàn bộ khối


3

Với một khu vực

Để làm điều này với một khu vực, bắt đầu từ:

ref = open(|'specific-file-name');

nhấn C-SPC C-b C-M-n C-b C-w.

Cách nhanh hơn

Bắt đầu từ điểm trước paren, giống như trong Vim:

ref = open|('specific-file-name');

C-M-k( kill-sexp) sẽ dẫn đến:

ref = open|;

Nếu bạn có electric-pair-mode, bạn chỉ có thể chèn ()lại (. Vì vậy, chuỗi khóa đầy đủ là C-M-k (- không dài hơn nhiều ci(.


1
Ngoài ra, nếu điểm là trước trích dẫn bên trái ref = open(|'specific-file-name');, C-M-ksẽ đưa ra ref = open(|);. Báo giá cũng được cân bằng giới tính .
Kaushal Modi

Tôi đã nghĩ về delete-everything-inside-parensloại điều, không delete-first-sexp-inside-parens.
abo-abo

Giải pháp tốt đẹp nhưng nó đòi hỏi tôi phải di chuyển điểm trước biểu thức tôi muốn thay thế. Gói 'thay đổi bên trong' hoạt động khi điểm nằm ở bất kỳ vị trí nào trong biểu thức (giống như vi).
kain88

1

evil mô phỏng hầu hết Vim và nó thực hiện các đối tượng văn bản ngoài hộp.

Nói cách khác, với việc evilkích hoạt và sử dụng các ràng buộc khóa mặc định, ci(sẽ thực hiện chính xác những gì bạn đang hỏi: thay đổi những gì bên trong dấu ngoặc đơn kèm theo.

Chính xác hơn, ci(sẽ chuỗi evil-changeđến evil-inner-paren. Bạn cũng có thể tạo các đối tượng văn bản tùy ý của riêng bạn như bạn muốn.


Tôi biết về cái ác (tôi đã sử dụng nó một thời gian rồi). Tôi muốn biết làm thế nào điều này có thể được thực hiện trong emacs 'tinh khiết'.
kain88

@ kain88: đủ công bằng: Tôi hình dung sẽ có nhiều câu trả lời cho câu hỏi này. Tuy nhiên, vì tò mò, nếu bạn đã sử dụng evil, tại sao bạn lại muốn evilthay thế?
Dân

(bình luận không nghiêm túc) @Dan Có lẽ anh ấy đang chuẩn bị đến mặt tối.
Kaushal Modi

Tôi nhận thấy rằng đôi khi ác không chơi tốt với các chế độ khác. Ngoài ra, tôi tò mò muốn xem cách chỉnh sửa sẽ chỉ sử dụng emacs
kain88

1

Sử dụng smartparens

Giết chết

1) Sử dụng C-M-u( sp-backward-up-sexp) để thoát khỏi 'dấu phân cách.

2) Sử dụng C-0 C-M-k( 0tiền tố + sp-kill-sexp) để tiêu diệt nội dung trong sexp hiện tại hoặc C-k( sp-kill-hybrid-sexp). Cái sau chỉ hoạt động khi smartparens-strict-modeđược kích hoạt và hiện tại sexp phù hợp trong một dòng.

ref = open('specific|-file-name')
// C-M-u
ref = open(|'specific-file-name')
// C-k
ref = open(|)

Đánh dấu và xóa / giết / sao chép

1) Tìm đường đến điểm bắt đầu sexp (trong ví dụ C-M-u sp-backward-up-sexpnày là đủ), đặt dấu C-SPCvà đi đến cuối sexp với sp-end-of-sexp.

2) Sau đó, bạn có thể làm bất cứ điều gì bạn muốn: C-wgiết khu vực, khu vực M-wkill-ring-save (sao chép), backspacexóa nó mà không làm lộn xộn vòng giết (chỉ với delete-selection-mode)

ref = open('specific|-file-name')
// C-M-u
ref = open(|'specific-file-name')
// C-SPC - mark is now active
ref = open(|'specific-file-name')
// sp-end-of-sexp (my binding: M-e)
ref = open(<'specific-file-name'|)
// backspace
ref = open(|)

Chức năng đánh dấu bên trong sexp

smartparensgói có sp-mark-sexpchức năng đánh dấu toàn bộ sexp tiếp theo, tức là dấu phân cách và các thứ giữa chúng.

Bạn có thể sử dụng một hàm như thế này để loại bỏ các dấu phân cách ra khỏi vùng chọn:

(defun mark-inside-sexp-using-sp ()
  (interactive)
  (sp-mark-sexp)
  (exchange-point-and-mark) (backward-char)
  (exchange-point-and-mark) (forward-char)
  (message "MARK INSIDE SEXP (using sp)"))

(global-set-key (kbd "s-SPC") 'mark-inside-sexp-using-sp)
;; this is "super" modifier (win key) with space

Thoát khỏi sexp của bạn bằng cách sử dụng C-M-unhiều lần và bắn mark-Inside-sexp-used-sp và sau đó quyết định làm gì với vùng hoạt động.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.