Làm cách nào để phát hiện nếu ký tự hiện tại là ký tự nhận xét cho chế độ chính đó?


12

Tôi đang làm việc với chức năng nhỏ này kéo dòng tiếp theo lên dòng hiện tại. Tôi muốn thêm một chức năng để nếu dòng hiện tại là một nhận xét dòng và dòng tiếp theo cũng là một nhận xét dòng, thì các ký tự nhận xét sẽ bị xóa sau hành động "kéo lên".

Thí dụ:

Trước

;; comment 1▮
;; comment 2

Gọi điện thoại M-x modi/pull-up-line

Sau

;; comment 1▮comment 2

Lưu ý rằng các ;;ký tự được loại bỏ trước đó comment 2.

(defun modi/pull-up-line ()
  "Join the following line onto the current one (analogous to `C-e', `C-d') or
`C-u M-^' or `C-u M-x join-line'.

If the current line is a comment and the pulled-up line is also a comment,
remove the comment characters from that line."
  (interactive)
  (join-line -1)
  ;; If the current line is a comment
  (when (nth 4 (syntax-ppss))
    ;; Remove the comment prefix chars from the pulled-up line if present
    (save-excursion
      (forward-char)
      (while (looking-at "/\\|;\\|#")
        (delete-forward-char 1))
      (when (looking-at "\\s-")
        (delete-forward-char 1)))))

Hàm trên hoạt động nhưng hiện tại, bất kể chế độ chính, nó sẽ xem xét /hoặc ;hoặc #là một ký tự nhận xét : (looking-at "/\\|;\\|#").

Tôi muốn làm cho dòng này thông minh hơn; chế độ chính cụ thể.

Giải pháp

Nhờ giải pháp của @ericstokes, tôi tin rằng hiện tại bên dưới bao gồm tất cả các trường hợp sử dụng của tôi :)

(defun modi/pull-up-line ()
  "Join the following line onto the current one (analogous to `C-e', `C-d') or
`C-u M-^' or `C-u M-x join-line'.

If the current line is a comment and the pulled-up line is also a comment,
remove the comment characters from that line."
  (interactive)
  (join-line -1)
  ;; If the current line is a comment
  (when (nth 4 (syntax-ppss))
    ;; Remove the comment prefix chars from the pulled-up line if present
    (save-excursion
      (forward-char)
      ;; Delete all comment-start or space characters
      (while (looking-at (concat "\\s<" ; comment-start char as per syntax table
                                 "\\|" (substring comment-start 0 1) ; first char of `comment-start'
                                 "\\|" "\\s-")) ; extra spaces
        (delete-forward-char 1)))))

Bạn có muốn điều này đủ thông minh để xử lý các ký tự bắt đầu và kết thúc nhận xét khác nhau và nhận xét nhiều ký tự (ví dụ: C /* ... */) không?
erikstokes

Không, đó là tất cả những gì tôi cần. Cảm ơn!
Kaushal Modi

@erikstokes Vì tò mò, bạn sẽ xử lý các bình luận kiểu C như thế nào?
Pradhan

Giải pháp này hoạt động với các bình luận nhiều dòng ngay lập tức, không cần phải làm gì đặc biệt vì chúng tôi không cần xóa bất kỳ ký tự nào khi tham gia bình luận nhiều dòng.
Kaushal Modi

2
@Pradhan Có comment-startcomment-endchuỗi được đặt thành "/ *" và "* /" trong c-mode(nhưng không c++-mode). Và có c-comment-start-regexpphù hợp với cả hai phong cách. Bạn xóa các ký tự kết thúc sau đó bắt đầu sau khi tham gia. Nhưng tôi nghĩ rằng giải pháp của tôi sẽ được uncomment-region, join-linecác comment-regionvà để cho Emacs lo lắng về những gì bình luận nhân vật là gì.
erikstokes

Câu trả lời:


12

Bạn có thể kiểm tra xem ký tự hiện tại có phải là ký tự nhận xét hay không bằng cách sử dụng bảng cú pháp : (looking-at "\\s<"). Regrec \\s<sẽ khớp bất kỳ ký tự nào với cú pháp "bình luận bắt đầu"; \\s>sẽ khớp với những người có cú pháp "bình luận kết thúc".

Một tùy chọn khác là biến comment-start, đó là chuỗi được chèn bởi comment-dwimvà bạn bè. Nó thường được đặt thành ký tự bắt đầu bình luận cộng với một số khoảng trắng.


2

Có một giải pháp đơn giản hơn nhiều , vui lòng nghiên cứu mã của tôi tại https://github.com/redguardtoo/evil-nerd-commenter/blob/master/evil-nerd-commenter.el

Tôi sẽ không sao chép / dán tất cả các mã ở đây. nhưng đây là những điểm chính:

  • bình luận có mặt phông chữ riêng, tìm kiếm phông chữ khóa-bình luận-mặt và phông chữ khóa-bình luận-dấu phân cách-khuôn mặt trong mã của tôi

  • sử dụng API riêng của Emacs để bỏ dòng thứ hai, sau đó nối nó với dòng đầu tiên

Nó nên hoạt động trên bất kỳ chế độ chính hợp lý.

Thủ thuật này không phải do tôi phát minh ra. Đó thực sự là từ mã riêng của Emacs, (cụ thể hơn là flyspell). Vì vậy, giải pháp nên hỗ trợ mọi hỗ trợ flyspell ở chế độ chính


3
Để làm nổi bật một cái gì đó như bình luận, nó yêu cầu bảng cú pháp phải được thiết lập phù hợp, vì vậy tôi nghi ngờ điều này thông minh hơn so với cách nhìn vào cú pháp.
wasamasa

Tôi đã học được mẹo này bằng cách đọc mã riêng của Emacs (thực ra, đó là flyspell), như tôi đã ghi lại trong mã của mình.
chen bin

0

Nếu bạn đang tìm kiếm tính năng này cho mã lisp (Elisp, Clojure, Scheme và Common Lisp), thì bạn nên thử lispy , một hàm được gọi là lispy-fillloại điều này.

Nếu bạn đang tìm kiếm tính năng này cho ngôn ngữ khác, thì bạn nên rebox2 (đã xác minh cho CPython), một chức năng được gọi rebox-fillhoặc chức năng khác được gọi là rebox-dwimthực hiện loại điều này.

Cả hai đều là các gói tuyệt vời và chúng không xung đột với nhau vì chúng được sử dụng cho các chế độ chính khác nhau và cả hai ( lispy-fillrebox-dwim) bị ràng buộc M-q, khá gọn gà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.