2013-07-29 35 views
6

tôi thường dán mặt hàng được phân cách bởi dòng mới hoặc dòng nguồn cấp dữ liệu vào một bộ đệm Emacs dẫn đến từng hạng mục nằm trên một dòng khác nhau như thế này:Emacs: chuyển đổi mục trên dòng riêng biệt vào một danh sách bằng dấu phẩy

one 
two 
three 
four 

Rất thường thì tôi thực sự muốn có một danh sách các giá trị được phân cách bằng dấu phẩy như sau:

"one", "two", "three", "four" 

Thật tuyệt vời khi có thể thực hiện chuyển đổi một chạm từ các dòng thành danh sách. Tôi tưởng tượng tôi có thể chuyển đổi điều này bằng cách sử dụng một regex, nhưng nó có vẻ giống như các loại hoạt động thường được sử dụng mà có thể đã có sẵn chức năng Emacs. Ai có thể đề nghị một?

Trả lời

4

M-q sẽ thay thế các dấu ngắt dòng bằng dấu cách (trong danh sách ngắn ngắn gọn hợp lý) nhưng sẽ không thêm dấu ngoặc kép và dấu phẩy. Hoặc, có thể M-^ nhiều lần, cho đến khi bạn có tất cả trên cùng một dòng. Khác hơn thế - không có gì được xây dựng trong tâm trí.

Rõ ràng, macro bàn phím là một ứng cử viên tốt cho việc này.

Nhưng một cách nhanh hơn, điều đó không tạo ra nhiều undo bước sẽ là một cái gì đó dọc theo những dòng:

(defun lines-to-cslist (start end &optional arg) 
    (interactive "r\nP") 
    (let ((insertion 
     (mapconcat 
      (lambda (x) (format "\"%s\"" x)) 
      (split-string (buffer-substring start end)) ", "))) 
    (delete-region start end) 
    (insert insertion) 
    (when arg (forward-char (length insertion))))) 
+0

Con trỏ phải được đặt ngay sau dòng cuối cùng trong danh sách để chức năng này hoạt động như mong đợi, nhưng đó có thể là vị trí tự nhiên cho con trỏ nếu bạn vừa dán thứ gì đó vào bộ đệm. Điều này làm việc cho tôi - cảm ơn. Chỉnh sửa: Và điều này, tình cờ, nếu tại sao tôi thích Emacs! – SlowLearner

+0

@SlowLearner Tôi đã thay đổi nó để sử dụng đối số phổ quát như một hướng dẫn để nhảy đến vị trí sau khi chèn, vì vậy nếu bạn gọi nó là 'M-x dòng-to-cslist', điểm sẽ di chuyển đến cuối chuỗi được chèn. –

4

Edit: tôi làm thấy bạn đang tìm kiếm một chức năng ... nhưng vì câu trả lời duy nhất chỉ đơn giản là viết riêng của bạn (ví dụ như không có sẵn), tôi nghĩ rằng tôi sẽ nói với những gì regex sẽ là, vì những người khác có thể vấp ngã điều này và đánh giá cao một cách khác để viết và đặt nó vào .emacs.


Đây là hai bước, nhưng chỉ bởi vì bạn muốn văn bản của bạn trích dẫn:

Như dán trong Emacs *scratch* đệm (thêm five six để hiển thị nó hoạt động với nhiều từ trên mỗi dòng, nếu đó là quan tâm):

one 
two 
three 
four 
five six 

Thứ nhất, thay thế cá nhân word với "word":

M-x replace-regexp RET \(.*\) RET "\1" RET sản xuất:

"one" 
"two" 
"three" 
"four" 
"five six" 

Bây giờ, thay thế từng trở về vận chuyển (trong Emacs, C-q C-j) với một ,:

M-x replace-regexp RET C-q C-j RET , RET sản xuất:

"one", "two", "three", "four", "five six" 
1

Tôi đã viết một giải pháp cho việc này tại nơi làm việc ngày hôm nay. Dưới đây là các hàm chuyển đổi từ các dòng thành csv và từ csv thành các dòng, với dấu phân tách người dùng có thể xác định. Hàm này hoạt động trên vùng được đánh dấu hiện tại.

(defun lines-to-csv (separator) 
    "Converts the current region lines to a single line, CSV value, separated by the provided separator string." 
    (interactive "sEnter separator character: ") 
    (setq current-region-string (buffer-substring-no-properties (region-beginning) (region-end))) 
    (insert 
    (mapconcat 'identity 
       (split-string current-region-string "\n") 
       separator))) 

(defun csv-to-lines (separator) 
    "Converts the current region line, as a csv string, to a set of independent lines, splitting the string based on the provided separator." 
    (interactive "sEnter separator character: ") 
    (setq current-region-string (buffer-substring-no-properties (region-beginning) (region-end))) 
    (insert 
    (mapconcat 'identity 
       (split-string current-region-string separator) 
       "\n"))) 

Để sử dụng, hãy đánh dấu vùng bạn muốn chỉnh sửa, sau đó thực hiện M-x và chỉ định dấu phân cách để sử dụng.

0

Tôi thường thực hiện các loại tác vụ này bằng macro. M-X kmacro-start-macroM-x kmacro-end-or-call-macro, sau đó bạn có thể thực hiện nhiều lần.

Các vấn đề liên quan