Làm thế nào để đạt được hiệu ứng gấp mã trong Emacs?


123

Cách tốt nhất để đạt được điều gì đó như gấp mã hoặc kiểu quay vòng mà chế độ tổ chức sử dụng. Giải pháp tốt nhất trong elisp để tạo ra loại hành vi này là gì?

CHỈNH SỬA: Tôi xin lỗi vì tôi không rõ ràng. Tôi muốn lập trình một cái gì đó trong elisp thực hiện những thứ rất giống với việc gấp mã hoặc thực sự giống như chế độ tổ chức nhất với hệ thống phân cấp có thể được mở rộng. Tôi đang tự hỏi cách tốt nhất để đạt được điều này ảnh hưởng. Tôi nghĩ rằng tôi đã nghe nói lớp phủ emacs là một giải pháp tốt, nhưng tôi không biết.

Theo như cách gấp, tôi chỉ sử dụng bộ hiển thị có chọn lọc nội bộ

CHỈNH SỬA SỐ 2:

Cảm ơn vì câu trả lời nhưng tôi nghĩ rằng tôi đang đặt câu hỏi sai, vì vậy hãy để tôi cố gắng nói rõ hơn về những gì tôi đang cố gắng làm. Tôi muốn tạo cái sau

Khi bạn đặt quan điểm của mình vào một hàm và gọi hàm elisp này, nó sẽ đặt định nghĩa hàm từ bất cứ đâu (tôi đang nghĩ đến việc chỉ sử dụng thẻ tìm kiếm cho việc này) và mở nó ra trong bộ đệm hiện tại. Ý tưởng là nếu bạn phải chuyển đến một vùng đệm khác để đọc định nghĩa hàm, tôi cảm thấy nó giống như một sự chuyển ngữ cảnh sang một tệp khác. Vì vậy, tôi muốn nó hoạt động giống như mã gấp chỉ nó kéo mã bên ngoài từ bộ đệm. Điều này gây ra một số vấn đề vì nó không thể dán mã vào bộ đệm một cách thành thạo hoặc nếu ai đó lưu nó, nó sẽ lưu mã được kéo vào. Vì vậy, tôi đang tự hỏi nếu có cách nào để tạo ra một khu vực bên trong một bộ đệm cũng không phải là một phần của bộ đệm. Tôi nghĩ nó có nghĩa.


Bạn đang tìm kiếm một cái gì đó mà khi bạn gọi nó bằng điểm trong một hàm CALL nó sẽ nhảy đến định nghĩa hàm? đại loại như nhận trợ giúp về một hàm elisp sẽ cho phép bạn chuyển đến mã elisp? Tôi không nghĩ bạn có thể làm điều này nếu không có một số khái niệm về "Dự án". Ví dụ, làm thế nào bạn biết được bạn muốn chuyển đến hàm "hoán đổi" nào?
Brian Postow,

1
Xem thêm: stackoverflow.com/questions/382781/… nơi hiển thị chọn lọc được tinh chỉnh một chút cho một số hiệu ứng giống như gấp.
Michael Paulukonis

Tôi khuyên bạn nên xóa của bạn EDIT NB 2và đặt một câu hỏi mới cho nó.
Stefan

Câu trả lời:


151

Gấp nói chung là không cần thiết với emac, vì nó có các công cụ triển khai rõ ràng các hành động mà mọi người thực hiện theo cách thủ công khi gấp mã.

Hầu hết mọi người đều thành công tốt đẹp với những tìm kiếm gia tăng đơn giản. Xem "foo" được đề cập ở đâu đó? Nhập C-sfoo, tìm định nghĩa, nhấn enter, đọc, sau đó nhấn C-x C-xđể quay lại vị trí của bạn. Đơn giản và rất hữu ích.

Hầu hết các chế độ đều hỗ trợ imenu . M-ximenusẽ cho phép bạn chuyển đến định nghĩa hàm (v.v.) theo tên. Bạn cũng có thể liên kết nó với một cú nhấp chuột để nhận menu các chức năng (hoặc thêm nó vào thanh menu; xem trang Thông tin để biết thêm chi tiết). Nó cung cấp dữ liệu cho chế độ-chức năng nào, cho phép bạn biết bạn hiện đang ở trong chức năng nào trong mô hình. (Tại sao các chức năng của bạn lại dài như vậy?)

Ngoài ra còn có speedbar , hiển thị thông tin imenu (và những thứ khác) đồ họa.

Nếu bạn muốn xem tổng quan về tệp của mình, hãy thử M-xoccur". Với một regex, nó sẽ tạo một bộ đệm mới với mỗi kết quả khớp trong bộ đệm hiện tại. Bạn có thể tìm kiếm" (defun "để biết tổng quan về các chức năng của tệp hiện tại. Thực hiện. Nhấp vào kết quả sẽ chuyển bạn đến vị trí đó trong tệp.

Vì vậy, dù sao đi nữa, hãy nghĩ về những gì bạn thực sự muốn đạt được và Emacs có thể thực hiện điều đó. Đừng chiến đấu với những công cụ không hoàn hảo khiến bạn gấp và mở mọi thứ liên tục.


13
Vim cũng cung cấp tất cả các tính năng này dưới dạng này hay dạng khác nhưng tôi vẫn thấy tiện ích gấp mã của nó là vô giá.
trực giác

115
Tôi đã bỏ phiếu cho câu đầu tiên ("Nói chung là không cần gấp với emacs, như ..."). Tôi sử dụng cách gấp đơn giản (dựa trên mức độ thụt lề) liên tục để quét cấu trúc của mã không quen thuộc.
Simon Michael

4
Bà o là các phím tắt cho Mx xảy ra
Joshua Olson

3
Tôi đã bỏ phiếu vì nhiều phím tắt hữu ích trong câu trả lời nhưng cũng có nhận xét @SimonMichael được bầu chọn bởi vì đôi khi gập / mở ra vẫn có thể hữu ích!
Adrien Coquio 14/02/13

56
Câu trả lời đã được nghĩ ra và rất nhiều thông tin. Tuy nhiên, OP đã hỏi làm thế nào để thực hiện việc gấp mã. OP đã không hỏi cách yêu thích của mọi người để tránh việc gấp mã là gì. Xuống bình chọn.
wkschwartz

104

chế độ ẩn hiện ( hs-minor-mode) với bàn phím mặc định C-c @ C-M-hđể kích hoạt việc gấp ( hs-hide-all)


12
Điều này hoạt động tốt. Và với cái ác chế độ, điều này được kích hoạt bởi các lệnh vim bình thường: zR, zM, zo, zc.
Justin M. Keyes

39

Một cách khác để lột da mèo:

Khi nó xảy ra, bạn không cần bất kỳ gói hoặc cấu hình bổ sung nào cho việc đó. Chỉ cần truy cập bất kỳ tệp nguồn nào, nhập

M-1 Cx $ và điều kỳ diệu sẽ xảy ra!

Như thường lệ, đó là phép màu trắng: Cx $ sẽ đưa mã của bạn trở lại.

Chúng ta có thể sử dụng hệ thống trợ giúp của Emacs để khám phá điều gì đang xảy ra: Ch k Cx $ cho chúng ta biết rằng tổ hợp phím ở trên đang gọi set-select-display , một hàm nhận một đối số số (tiền tố M-1 chuyển 1 làm giá trị của đối số đó) và không có gì ngạc nhiên khi đặt biến hiển thị có chọn lọc thành giá trị của đối số đó.

từ blog wizardry emacs nhỏ

Chỉ để hoàn thiện: M-3 Cx $ sẽ hiển thị mã lồng nhau sâu hơn, v.v.

FWIW Hôm nay tôi đã tạo một người trợ giúp nhỏ dựa trên smth. được tìm thấy ở đây để F5 chuyển đổi chế độ gấp mã dựa trên vị trí con trỏ hiện tại:

(global-set-key (kbd "<f5>") 'set-selective-display-dlw)

(defun set-selective-display-dlw (&optional level)
"Fold text indented same of more than the cursor.
If level is set, set the indent level to LEVEL.
If 'selective-display' is already set to LEVEL, clicking
F5 again will unset 'selective-display' by setting it to 0."
  (interactive "P")
  (if (eq selective-display (1+ (current-column)))
      (set-selective-display 0)
    (set-selective-display (or level (1+ (current-column))))))

22

Tôi sử dụng chế độ phác thảo nhỏ để gấp mã python của mình. Thay vì cần đặt {{{và}}} như ở chế độ gấp, nó sử dụng vị trí khối được xác định.

http://www.gnu.org/software/emacs/manual/html_node/emacs/Outline-Mode.html http://www.emacswiki.org/emacs/OutlineMinorMode

Tôi khá chắc chắn rằng nó đi kèm với emacs. Sau đó, tôi thêm điều này vào .emac của tôi

;;======= Code folding =======
(add-hook 'python-mode-hook 'my-python-outline-hook)
; this gets called by outline to deteremine the level. Just use the length of the whitespace
(defun py-outline-level ()
  (let (buffer-invisibility-spec)
    (save-excursion
      (skip-chars-forward "    ")
      (current-column))))
; this get called after python mode is enabled
(defun my-python-outline-hook ()
  ; outline uses this regexp to find headers. I match lines with no indent and indented "class"
  ; and "def" lines.
  (setq outline-regexp "[^ \t]\\|[ \t]*\\(def\\|class\\) ")
  ; enable our level computation
  (setq outline-level 'py-outline-level)
  ; do not use their \C-c@ prefix, too hard to type. Note this overides some bindings.
  (setq outline-minor-mode-prefix "\C-t")
  ; turn on outline mode
  (outline-minor-mode t)
  ; initially hide all but the headers
  ;(hide-body)
  ; make paren matches visible
  (show-paren-mode 1)
)

8
có vẻ như outline-modehỗ trợ python out-of-the-box trong emacs 24 - không cần các outline-levelchức năng tùy chỉnh . Đây là tất cả những gì tôi cần để thêm vào user.el:(add-hook 'python-mode-hook 'outline-minor-mode)
scytale

1
ồ và bạn chắc chắn muốn ghi đè outline-minor-mode-prefix- các liên kết phím mặc định thật tệ - tôi sử dụng(setq outline-minor-mode-prefix (kbd "C-;"))
scytale

13

Bạn cũng có thể nhận mã gấp bằng cách sử dụng CEDET với mã sau trong tệp init:

(global-semantic-folding-mode t)

Sau khi đánh giá mã này, hình tam giác nhỏ sẽ xuất hiện ở vùng rìa, vì vậy bạn có thể gấp và mở mã bằng cách sử dụng nó. Phương pháp này chính xác hơn, vì nó sử dụng thông tin cú pháp, được trích xuất từ ​​mã nguồn


1
nếu phải đối mặt với một số lỗi, có một cái nhìn về câu hỏi này: stackoverflow.com/questions/15307113/...
AdrieanKhisbe

9

hs-tiểu-chế độ hoạt động đẹp.

Nó thậm chí còn hoạt động đẹp hơn khi được ghép nối với fold-dwim (ý tôi là). Sau đó, có gấp-dwim-org, cung cấp chế độ tổ chức giống như các liên kết khóa để gấp mã! Cả hai đều có thể được cài đặt thông qua mứt cam (và tôi nghĩ là elpa).



5

vimish-fold cũng là một giải pháp tốt và dễ dàng.

https://github.com/mrkkrp/vimish-fold .

Từ trang chủ:

Đây là gói thực hiện thao tác gấp văn bản giống như trong Vim. Nó có các tính năng sau:

  • sự gấp khúc của các vùng hoạt động;
  • phản hồi trực quan tốt: rõ ràng phần nào của văn bản được gấp lại;
  • theo mặc định: khi bạn đóng tệp, các nếp gấp của bạn không biến mất;
  • tính bền bỉ có quy mô tốt, bạn có thể làm việc trên hàng trăm tệp với nhiều nếp gấp mà không có tác dụng phụ;
  • nó không bị gãy thụt lề hay gì đó;
  • các nếp gấp có thể được chuyển đổi từ trạng thái gấp sang mở ra và quay lại rất dễ dàng;
  • điều hướng nhanh giữa các nếp gấp hiện có;
  • bạn có thể sử dụng chuột để mở ra các nếp gấp (tốt cho người mới bắt đầu và không chỉ cho họ);
  • dành cho người hâm mộ gói avy: bạn có thể sử dụng avy để gấp văn bản với số lượng nét phím tối thiểu!

Sử dụng tuyệt vời, use-packagetôi cài đặt và kích hoạt nó bằng đoạn mã này trong cấu hình của tôi:

(use-package vimish-fold
  :ensure t
  :config (vimish-fold-global-mode t))

3

Tôi ngạc nhiên rằng không ai đề cập đến việc thu hẹp-mở rộng. Nó siêu tuyệt vời, nó cũng đi kèm với emacs. Đơn giản chỉ cần chọn mã bạn muốn lấy tiêu điểm và nhấn C-x n n, để quay lại chế độ xem đầy đủ chỉ cần làm C-x n w. Tôi luôn thích sử dụng chức năng emacs tích hợp sẵn hơn là làm lộn xộn không gian người dùng của tôi với một gói khác. Nếu emacs có thể làm điều đó với chức năng tích hợp thì tôi sẽ thích điều đó hơn một số gói của bên thứ ba, nhưng đó chỉ là tôi, không có ý nghĩa hoặc ngụ ý gì khác ngoài việc tôi thích những thứ đơn giản hơn cấu hình dài phức tạp.



2

Tôi tin rằng việc bạn so sánh "dự án" của bạn với việc gấp là không hoàn toàn tốt, bởi vì gấp là việc thay đổi diện mạo trong khi vẫn giữ nguyên nội dung đệm (văn bản). Dự án của bạn sẽ liên quan đến việc hiển thị thêm văn bản trong khi vẫn giữ nguyên nội dung đệm, AFAIU. Vì thế. nó không thể thực hiện được như một thành phần của chèn và gấp văn bản (sau đó, nội dung bộ đệm sẽ bị thay đổi).

Nhưng có lẽ, nó thực sự có thể xảy ra với cùng một cơ chế như việc gấp được thực hiện với - "lớp phủ" ... Hãy xem xét các thuộc tính lớp phủ "trước chuỗi" và "sau chuỗi" ; có lẽ, bạn có thể đặt các định nghĩa hàm của mình vào các chuỗi này thuộc lớp phủ có độ dài bằng 0 tại điểm. Nhìn vào chức năng phác thảo-cờ-vùng để xem cách lớp phủ được sử dụng trong chế độ phác thảo.


2

Nếu bạn sử dụng hs-minor-mode, bạn cũng nên đặt một phím tắt thuận tiện hơn, ví dụ:

(eval-after-load 'hideshow
 '(progn
   (global-set-key (kbd "C-+") 'hs-toggle-hiding)))

0

Với cảm hứng từ câu trả lời của einSelbst :

(lời khuyên-thêm 'set-select-display
            : filter-args (lambda (args)
                           (if (hoặc (car args) select-display)
                               args
                             (danh sách (1+ (cột hiện tại)))))
            '((tên. set-select-display-from-con trỏ-cột)))

Thì đấy, C-x $đột nhiên trở nên hữu ích ngay cả khi không có bất kỳ C-uhoặc M-4kinh doanh.


0

Nếu bạn đang thực hiện một số JavaScript và sử dụng js2-mode.el, bạn có thể:

C-c C-f: chuyển đổi ẩn / hiện tất cả

C-c C-e: ẩn phần tử

C-c C-s: hiển thị phần tử

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.