Nguyên tắc cơ bản của nhiều con trỏ


55

Gần đây tôi đã tìm hiểu về multiple-cursorsnó, và nó trông giống như một gói rất hữu ích. Tôi đã xem qua các tài liệu về repo ban đầu , nhưng các lệnh vẫn có vẻ hơi mơ hồ đối với tôi.

Sau đó tôi đã xem video trong Emacs Rocks!, Và video rất hay, nhưng nó tập trung chủ yếu vào những gì multiple-cursorscó khả năng làm, hơn là làm thế nào để làm điều đó.

Có bất kỳ hướng dẫn, hướng dẫn hoặc ví dụ nào minh họa chức năng cơ bản nhất của nó không?


4
Tôi đã có thể đứng dậy và chạy multiple-cursorsrất nhanh chỉ bằng cách đọc tệp README. Đề nghị của tôi là chỉ học mc/mark-next-like-this. Hãy thử nó, và làm quen với những gì nó làm. Từ đó, hãy quay trở lại README bất cứ khi nào bạn có câu hỏi bắt đầu bằng "Tôi tự hỏi liệu nhiều con trỏ có thể làm được không ..." Tất cả những điều đó đã nói, tôi nghĩ rằng một lời giới thiệu cơ bản hơn Đá Emacs! video sẽ hữu ích cho người mới bắt đầu.
nispio

Hoàn toàn đồng ý! Hoàn toàn không rõ làm thế nào để sử dụng nó. Tôi chỉ che dấu các dòng sau đó thực hiện mc / chỉnh sửa dòng với KBD được liên kết (không thông qua Mx như đã lưu ý trên Github) Sau đó, tôi thấy nhiều con trỏ nhưng chúng chỉ biến mất sau bất kỳ kiểu nhập văn bản nào
Dima Fomin

Câu trả lời:


19

Ngoài việc sử dụng @bastibe mô tả, tôi sử dụng nhiều con trỏ để thêm hoặc xóa văn bản từ đầu / cuối của một nhóm dòng:

  1. Di chuyển điểm đến đầu hoặc cuối của khu vực quan tâm
  2. gọi set-rectangular-region-anchor(ràng buộc với bất kỳ phím nào bạn thích, tôi nghĩ đề xuất từ ​​Magnars là H-space, nếu bạn có một phím siêu tốc)
  3. Di chuyển điểm tiến hoặc lùi theo dòng ( C-nC-p) cho đến khi bạn có một con trỏ trên mỗi dòng bạn muốn chỉnh sửa
  4. Chèn hoặc xóa văn bản khi cần thiết, tùy ý di chuyển đến cuối dòng ( C-e) để thực hiện thay đổi ở đó.

Bạn có thể sử dụng forward-word, forward sentencevv để di chuyển qua lại dọc theo các dòng, cho phép bạn chỉnh sửa từ thứ tư trong mỗi dòng, ngay cả khi văn bản trên mỗi dòng không giống nhau.

Ví dụ, tôi làm công việc này mọi lúc:

  • C-u M-!ls / test-dat / pp5 / * fsaRETURN

    Điều này sẽ chèn các contens của thư mục pp5 vào bộ đệm. Tôi đặt điểm !khi bắt đầu danh sách:

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa
/test-dat/pp5/QCJB-22-5_Frag#90.fsa
/test-dat/pp5/ONGL-1-5_Frag#102.fsa
/test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • Thêm con trỏ vào mỗi dòng với H-space, C-nx 4
  • nhân đôi mỗi dòng với C-k C-y space C-y C-a

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa /test-dat/pp5/ONAB-6-5_Frag#89.fsa
!/test-dat/pp5/QCJB-22-5_Frag#90.fsa /test-dat/pp5/QCJB-22-5_Frag#90.fsa
!/test-dat/pp5/ONGL-1-5_Frag#102.fsa /test-dat/pp5/ONGL-1-5_Frag#102.fsa
!/test-dat/pp5/ONGL-1-5_Frag#78.fsa /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • cắt phần đầu tiên thành tên biến với M-dx 3 C-d C-fx3 M-dx3 <-

ONAB-6-5 <-! /test-dat/pp5/ONAB-6-5_Frag#89.fsa
QCJB-22-5 <-! /test-dat/pp5/QCJB-22-5_Frag#90.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#102.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • sau đó bọc tên tệp thực tế trong hàm để tải nó: read.file ( C-d" C-e")RETURN

ONAB-6-5 <- read.file("/test-dat/pp5/ONAB-6-5_Frag#89.fsa")
QCJB-22-5 <- read.file("/test-dat/pp5/QCJB-22-5_Frag#90.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#102.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#78.fsa")

Và voila, bạn đã chuyển đổi một danh sách tập tin thành mã để đọc danh sách đó. Nó thực sự khó mô tả hơn nhiều so với thực tế!


3
Nếu bạn làm điều này thường xuyên, bạn có thể gói nó trong một macro bàn phím. Macro bàn phím và multiple-cursorscó thể tạo ra một sự kết hợp thực sự mạnh mẽ.
nispio

@nispio đồng ý! Đôi khi tôi đang lặp lại quá trình tương tự và một macro sẽ hữu ích. Tuy nhiên, thông thường, có một số khác biệt nhỏ ở giữa dòng công việc đòi hỏi những thay đổi nhỏ sẽ 'phá vỡ' một macro.
Tyler

1
Bạn thường có thể mô tả chính xác vị trí bạn muốn con trỏ chuyển sang sử dụng biểu thức chính quy. Trong các trường hợp như vậy, việc sử dụng phi-searchcó thể mạnh mẽ hơn so với điều hướng bằng các lệnh nhưM-f (x3)
nispio

@nispio chắc chắn, nó phụ thuộc vào tình hình. Với tên cấu trúc nhất quán, nó dễ dàng di chuyển bằng từ. Tôi đã không sử dụng tìm kiếm trong nhiều con trỏ vì các lệnh tìm kiếm emacs tích hợp dễ vỡ với mc. Tôi không biết phi-search, điều đó thật tuyệt!
Tyler

22

Tôi về cơ bản có hai trường hợp sử dụng thường xuyên cho multiple-cursors:

  • Thay thế một số chuỗi. Đánh dấu một thể hiện của chuỗi, sau đó sử dụng mc/mark-next-like-thismc/mark-previous-like-thisđánh dấu thêm phiên bản của chuỗi. Sau đó tôi ngay lập tức nhấn C-wđể xóa mọi trường hợp và thay vào đó viết một chuỗi mới. Tôi sử dụng điều này thường xuyên để đổi tên một biến trong mã.
  • Chỉnh sửa nhiều nơi cùng một lúc. Đánh dấu một số trường hợp của một chuỗi như trước đó, nhưng hủy bỏ lựa chọn (nhưng không phải là con trỏ) ngay lập tức bằng cách sử dụng C-g, hoặc đặt dấu và điểm vào cùng một cột của các dòng khác nhau và sử dụng mc/edit-linesđể lấy một con trỏ trên mỗi dòng. Bây giờ bạn có thể sử dụng các lệnh chỉnh sửa thông thường hoạt động trên mỗi một con trỏ này.

Trường hợp sử dụng đầu tiên đặc biệt hữu ích với expand-region. Tôi đã er/expand-regionbị ràng buộc vào C-j, và mc/mark-next-like-thismc/mark-previous-like-thisđến C->C-<. Cùng với đó, tôi có thể dễ dàng chọn điểm từ đang bật và đánh dấu lần xuất hiện tiếp theo / trước của từ đó ngay lập tức.

Trường hợp sử dụng thứ hai thay thế hầu hết việc sử dụng macro cho tôi. Thay vì ghi một macro, và sau đó áp dụng nó ở một vài nơi, tôi sẽ đặt một con trỏ ở mọi nơi và chỉ thực hiện thao tác ở tất cả các vị trí cùng một lúc.


Cảm ơn @bastibe. Bất kỳ ràng buộc cụ thể nào mà bạn hoặc multiple-cursors đề nghị cho ví dụ mark-next-like-this& mark-previous-like-this?
Amelio Vazquez-Reina

@ user815423426 như được nêu trong bài đăng, tôi sử dụng C->C-<cho mark-next-like-thismark-previous-like-this.
bastibe

Tại sao không sử dụng standart M-% để tìm kiếm và thay thế ?
Dima Fomin

6

Tôi muốn thêm một số tính năng bổ sung mà đôi khi tôi sử dụng multiple-cursors.

Tôi đã tìm thấy những điều sau đây là hữu ích:

iy-go-to-char

Đôi khi, bạn thấy mình cần phải chuyển sang tiếp theo #hoặc tiếp theo ,hoặc một số phân định cụ thể. Điều này đặc biệt hữu ích khi bạn cần di chuyển qua số lượng từ khác nhau cho mỗi con trỏ. Nó cung cấp các chức năng iy-go-to-chariy-go-to-char-backward, mà bạn có thể liên kết và sử dụng độc đáo.

khu vực mở rộng

Điều này thực sự hữu ích vì lý do tương tự iy- khi bạn có các dòng hơi khác nhau dưới mỗi con trỏ và bạn có thể muốn chọn chuỗi được trích dẫn dưới điểm hoặc tương tự.

công cụ tùy chỉnh

Đây là những thứ chỉ là elisp trong cấu hình của tôi, nhưng tôi thấy hữu ích. Có lẽ không phải do tôi viết.

Nhắc nhở đầu vào
Tôi đã nhận được cái này từ Magnars để đáp ứng yêu cầu đặt một chuỗi khác nhau dưới mỗi con trỏ. Mã này đơn giản, nhưng ràng buộc nó với một cái gì đó và sử dụng cho nhiều con trỏ là một cách tiện dụng để chèn các thứ hơi khác nhau ở mỗi nơi.

(defun prompt-for-insert ()
  (interactive)
  (insert (read-string "Insert: ")))

Số tăng tại điểm
Điều này hoặc đến từ SO, hoặc emacswiki. Không chắc chắn mà. Bản thân nó khá hữu ích và cả khi được sử dụng kết hợp vớimc/insert-numbers

(defun my-increment-number-decimal (&optional arg)
  "Increment the number forward from point by 'arg'."
  (interactive "p*")
  (save-excursion
    (save-match-data
      (let (inc-by field-width answer)
        (setq inc-by (if arg arg 1))
        (skip-chars-backward "0123456789")
        (when (re-search-forward "[0-9]+" nil t)
          (setq field-width (- (match-end 0) (match-beginning 0)))
          (setq answer (+ (string-to-number (match-string 0) 10) inc-by))
          (when (< answer 0)
            (setq answer (+ (expt 10 field-width) answer)))
          (replace-match (format (concat "%0" (int-to-string field-width) "d")
                                 answer)))))))

eval-and-thay thế
Đây là siêu mạnh mẽ và cho phép một số phần thực sự hữu ích. Nó đánh giá bất cứ thứ gì sexp nằm sau con trỏ và chèn kết quả của việc đánh giá nó.
Kết hợp nó với multiple-cursors-numbersví dụ như chèn sức mạnh của hai hoặc một chuỗi đi 0 1 2 0 1 2 0 1 2qua mỗi dòng hoặc một cái gì đó. (Tôi đã thực hiện cả hai điều này một cách hữu ích) Hoặc sử dụng nó s.elđể viết ra những cấu hình java tẻ nhạt đó với những thứ mặc định. Bạn viết ra từng cái CONFIG_VALUE_VARIABLE, sau đó biến nó thành CONFIG_VALUE_VARIABLE = "configValueVariable"bằng cách chạy s-camel-case.

(defun eval-and-replace ()
  (interactive)
  (let ((value (eval (preceding-sexp))))
    (kill-sexp -1)
    (insert (format "%s" value))))

iy-go-to-char là siêu hữu ích. Chỉ cần những gì tôi đang tìm kiếm.
Heinrich Hartmann

1
  1. Đi đến cuối * của những gì bạn muốn chọn.
  2. Nhấn C-S-bhoặc M-S-bđể chọn lùi cho đến khi bạn nhận được một phần được chọn. Bạn có thể sử dụng dịch chuyển mũi tên trái là tốt.
  3. Sau đó nhấn C->(nhấn shift nếu phím >nằm trên phím bàn phím của bạn) cho đến khi bạn nhận được nhiều hơn một mục được chọn.

* Điều quan trọng là chọn lùi hoặc lựa chọn đầu tiên sẽ đặt con trỏ ở vị trí sai.

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.