Thay đổi thứ tự các ký hiệu cho «dòng sắp xếp»


7

Tôi đang sử dụng «sort-lines» để sắp xếp bao gồm s trong các tệp C / C ++ trước khi lưu. Vấn đề phát sinh là một tiêu đề có "biểu tượng được sắp xếp cao hơn so với tiêu đề có biểu <tượng. Nhưng tôi muốn điều ngược lại.

Làm thế nào để tôi thay đổi thứ tự như vậy, để <nhân vật có quyền ưu tiên cao hơn "biểu tượng?


2
Bạn có thể cần phải viết chức năng vị ngữ của riêng bạn và gọi sort-subrtrực tiếp. Hoặc .. là một hack, bạn có thể khuyên sort-linesrằng trước khi sắp xếp bạn trao đổi "<ký tự và sau khi sắp xếp bạn trao đổi chúng trở lại. :-)
glucas

Câu trả lời:


2

Bạn có thể sử dụng sort-regexp-fields. Đánh dấu khu vực và làm:

M-x sort-regexp-fields RET #include .\(.*\) RET \1 RET

Nhóm biểu thức chính quy sẽ nắm bắt mọi thứ sau #include "hoặc #include <và sắp xếp trên đó thay vì toàn bộ dòng.

FYI, tôi tin rằng lý do sắp xếp bạn đang thấy là vì "cao hơn so với <ASCII.


1
Cảm ơn bạn, tôi đã nghĩ đến việc sắp xếp theo tên của một tiêu đề và bỏ qua việc mở cửa <, "các biểu tượng. Nhưng tôi đã đi đến kết luận rằng các tiêu đề được sắp xếp cùng nhau theo cách này có vẻ hơi lộn xộn, đó là lý do tại sao tôi muốn thay đổi thứ tự của các nhân vật.
Hi-Angel

2

Trong khi đó tôi đã viết một mã để thực hiện hack mà @glucas đã đề cập. Nó có lẽ chỉ phù hợp với mục đích sắp xếp các tiêu đề trong C, nhưng tôi hy vọng ai đó thấy nó hữu ích.

(defun replace-char-after (character-number replacement)
  "Replaces char in the buffer after the `character-number' with `replacement'"
  (save-excursion
    (goto-char character-number)
    (delete-char 1)
    (insert-char replacement)))

(defun replace-delimiters (old-closing-char new-opening-char new-closing-char opening-point end-point)
  "Replaces delimiters between `opening-point' and the
`end-point'. Note, that the `opening-point' should point to the
opening symbol, thus the function seeks only the closing"
  (block replace-delimiters
    (let ((closing-point opening-point))
      (setq closing-point (+ 1 opening-point))
      (while (< closing-point end-point)
        (if (eq (char-after closing-point) ?\n) ;;no closing delimiter
            (progn
              (print "Err: no closing delimiter")
              (return-from replace-delimiters nil))
          (when (eq (char-after closing-point) old-closing-char)
            (progn
              (replace-char-after opening-point new-opening-char);;opening delimiter
              (replace-char-after closing-point new-closing-char);;closing delimiter
              (return-from replace-delimiters (+ 1 closing-point)))))
        (setq closing-point (+ closing-point 1))))))

(defun swap-<-and-quote-includes (beg end)
    "Swaps in the text between `beg' and `end' the matching «<» and
  «>» character to the \" quote, and vice versa. Mainly used
  before sorting to swap the order of these characters, next
  after the sort to restore the text."
  (block swap-<-and-quote-includes
    (let ((curr-point beg))
      (while (< curr-point end)
        (setq curr-point (+ curr-point 1))
        ;;first check «"»
        (if (eq (char-after curr-point) ?\")
            (progn
              (setq curr-point (replace-delimiters ?\" ?< ?> curr-point end))
              (if (eq curr-point nil)
                  (return-from swap-<-and-quote-includes t)))
          ;;else if «<»
          (if (eq (char-after curr-point) ?<)
              (progn
                (setq curr-point (replace-delimiters ?\> ?\" ?\" curr-point end))
                (if (eq curr-point nil)
                    (return-from swap-<-and-quote-includes t)))))))))

Chức năng swap-<-and-quote-includesbiến đổi mỗi văn bản như <foo>đến "foo", và mỗi "foo"để <foo>trong phạm vi được cầu xin , cuối .

Và đây là mã để tìm và sắp xếp các tiêu đề:

(defun sort-lines-nocase (reverse beg end)
  (let ((sort-fold-case t))
    (sort-lines reverse beg end)))

(defun c-sort-includes ()
  "Sorts #include statements"
  (interactive)
  (save-excursion
    (let (beg end orig-content sorted-content)
      (goto-char (point-min))
      (while (and (not (looking-at "#include "));;look for includes, if no then
                  (eq (forward-line 1) 0) ;;go one line down (if not EOF).
                  ))
      (setq beg (point))
      (while (and (looking-at "#include ")
                  (eq (forward-line 1) 0)));;to not hang cuz of EOF
      (setq end (point))
      (setq orig-content (buffer-substring-no-properties beg end))
      (setq sorted-content (with-temp-buffer
                             (insert orig-content)
                             (swap-<-and-quote-includes (point-min) (point-max)) ;;swap characters < and > in includes
                             (sort-lines-nocase (point-min) (point-max)) ;;sort
                             (swap-<-and-quote-includes (point-min) (point-max)) ;;swap the characters  back
                             (buffer-string)))
      (when (not (string= orig-content sorted-content))
        (kill-region beg end)
        (insert sorted-content))
      )))

Hàm c-sort-includestìm kiếm đoạn đầu tiên của «#include» s và sắp xếp nó. Tôi đã thêm nó vào before-save-hookvới một mã để chỉ chạy nó cho chế độ C và C ++. Nhược điểm đã biết: α) chỉ đoạn đầu tiên có bao gồm sẽ được sắp xếp. Đó là bởi vì tìm kiếm cho đến cuối tập tin có thể tốn kém - ví dụ như trong công việc của tôi, gần đây tôi đã tìm thấy một .ctập tin với - bạn có thể tưởng tượng được không?! - 00016000 dòng! Giải pháp chính xác sẽ là một chế độ nhỏ, theo dõi các khối tiêu đề trong tệp nằm ở đâu. ) Trong các Emac cũ hơn, từ năm 2015, chức năng có thể bị treo - đó là một lỗi mà sau đó đã được sửa.

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.