Làm thế nào để bọc văn bản đã cho xung quanh khu vực


11

Tôi thường có một tình huống mà tôi cần phải áp dụng văn bản xung quanh một khu vực. Đối với HTML và các trường hợp đơn giản, đã có thư viện cho việc này. Nhưng những gì về trường hợp chung? Tôi muốn được hỏi những gì tôi sẽ chèn đầu và cuối khu vực.


Bạn có muốn sử dụng nó để chèn nội dung tùy ý một lần, hoặc một số ít các cặp, nhiều lần không? Trong trường hợp sau, các thư viện như smartparens có thể tỏ ra hữu ích và chúng có thể được mở rộng bằng các cặp tùy chỉnh. Ví dụ: bạn có thể thêm một cặp <?php... ?>, và sau đó, khi bạn chọn một khu vực và gõ <?php(hoặc một phím bấm), hãy gói nó trong cặp. Nhưng afaik không có cách dễ dàng để sử dụng các thư viện này nếu bạn có nhiều cặp one-shot.
T. Verron

@ T.Verron: Tôi biết rằng những người tồn tại. Nhưng đối với những thời điểm khi có nhu cầu duy nhất để duyệt mã và đánh dấu công cụ, một chức năng chung, có thể tái sử dụng phù hợp nhất
nperson325681

Câu trả lời:


6

Tôi đã đi vòng quanh và tìm thấy bài đăng này của John D. Cook . Ông trình bày cách xây dựng một chức năng tương tác đơn giản để có được các thẻ HTML / XML xung quanh khu vực một cách dễ dàng. Từ đó tôi sửa đổi hàm để hỏi hai lần.

(defun tag-word-or-region (text-begin text-end)
  "Surround current word or region with given text."
  (interactive "sStart tag: \nsEnd tag: ")
  (let (pos1 pos2 bds)
    (if (and transient-mark-mode mark-active)
        (progn
          (goto-char (region-end))
          (insert text-end)
          (goto-char (region-beginning))
          (insert text-begin))
      (progn
        (setq bds (bounds-of-thing-at-point 'symbol))
        (goto-char (cdr bds))
        (insert text-end)
        (goto-char (car bds))
        (insert text-begin)))))

Quan trọng hơn, chức năng này cũng có thể được sử dụng như một công cụ phụ trợ, ví dụ khi bạn muốn liên kết các khóa để ánh xạ một số bit cụ thể của văn bản.

(defun tag-php ()
  (interactive)
  (tag-word-or-region "<?php " "?>"))

Btw, cách này xử lý một số trường hợp ranh giới là không tối ưu; việc tìm kiếm bắt đầu đôi khi có thể thất bại và để lại cả hai thẻ ở cuối. Nó có thể là eviltôi sử dụng mà can thiệp ở đây. Có lẽ một chức năng của loại interactive "r" làm việc mạnh mẽ hơn?
nperson325681

4

Tôi sẽ đề nghị một cách tiếp cận khác. Khi có một khu vực, theo định nghĩa pointphải ở đầu (hoặc cuối) của khu vực, và marksẽ ở cuối (hoặc bắt đầu). Có nghĩa là bạn có thể nhập văn bản mà bạn muốn vào thời điểm, và sau đó sử dụng exchange-point-and-mark, ví dụ C-x C-x, để chuyển đến đầu kia của khu vực. Nhập nửa sau của trình bao bọc của bạn và bạn đã hoàn tất.

Bạn không được yêu cầu nhắc nhở rõ ràng về văn bản chèn, nhưng tôi không thể tưởng tượng được sẽ có cách nào để thực hiện điều tương tự với ít nỗ lực hơn.


Nếu văn bản bắt đầu và kết thúc giống nhau, tôi tự hỏi liệu một cái gì đó giống như multiple-cursorscó thể được điều chỉnh để chèn văn bản đồng thời ở đầu và cuối của khu vực hoạt động.
glucas

Nghe có vẻ giống như cách thủ công mà người dùng của các biên tập viên ít hơn buộc phải làm bằng mọi cách. Dù sao, tôi đọc việc sử dụng macro như một ẩn ý từ câu trả lời của bạn, phải nói. Tôi thích phong cách của bạn
nperson325681

1
@progo - Cảm ơn :) Nghe có vẻ như là một cách tiếp cận thủ công hơn, nhưng nó thực sự sử dụng ít tổ hợp phím hơn so với giải pháp thay thế của bạn. Với phương pháp này, ngoài văn bản gói, bạn chỉ cần C-x C-x. Với câu trả lời của bạn, bạn cần gọi hàm của bạn ( C-c something) và bạn cũng cần nhấn returnsau mỗi lần nhập. Vì vậy, bất kể bạn làm gì, bạn đã có thêm hai lần nhấn phím. Điều đó nói rằng, nó không có ích nếu bạn muốn một cái gì đó để gọi từ elisp.
Tyler

3

Chỉ vì lợi ích của sự đa dạng:

Một cách khác để làm điều này với một số văn bản bắt đầu và kết thúc tùy ý sẽ là sử dụng replace-regexptrên vùng: khớp .+và thay thế bằng before \& after, hoặc bất kỳ văn bản nào bạn muốn sử dụng cho beforeafter.

Bạn có thể viết một lệnh để làm điều này, nhưng tôi đang nghĩ về một trường hợp trong một tệp nhất định bạn muốn áp dụng cùng một văn bản bắt đầu / kết thúc ở nhiều nơi. Bạn có thể ghi lại một macro hoặc chỉ sử dụng lịch sử xe buýt nhỏ để lặp lại trên một khu vực khác.

Tất nhiên, nếu văn bản bạn muốn bọc có thể được biểu thị như một biểu thức thông thường thì bạn thậm chí sẽ không cần chọn một vùng và có thể thực hiện query-replace-regexptrên bộ đệm, nhưng có lẽ văn bản bạn muốn bọc không nhất quán.

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.