จะบรรลุเอฟเฟกต์การพับโค้ดใน Emacs ได้อย่างไร


123

อะไรคือวิธีที่ดีที่สุดในการบรรลุบางอย่างเช่นการพับโค้ดหรือประเภทของการขี่จักรยานที่โหมดองค์กรใช้ อะไรคือทางออกที่ดีที่สุดในการสร้างพฤติกรรมประเภทนี้

แก้ไข: ฉันขอโทษที่ฉันไม่ชัดเจน ฉันต้องการตั้งโปรแกรมบางอย่างใน elisp ที่ทำสิ่งต่างๆคล้ายกับการพับโค้ดหรือจริงๆแล้วส่วนใหญ่เหมือนกับโหมดองค์กรที่มีลำดับชั้นที่สามารถขยายได้ ฉันสงสัยว่าวิธีที่ดีที่สุดในการบรรลุผลนี้ ฉันคิดว่าฉันเคยได้ยินการซ้อนทับ emacs เป็นทางออกที่ดี แต่ฉันไม่รู้

เท่าที่พับได้ฉันก็ใช้ set-selective-display ในตัว

แก้ไขหมายเลข 2:

ขอบคุณสำหรับคำตอบ แต่ฉันคิดว่าฉันกำลังถามคำถามผิดดังนั้นขอให้ฉันพยายามให้ชัดเจนมากขึ้นว่าฉันกำลังพยายามทำอะไร ฉันต้องการสร้างสิ่งต่อไปนี้

เมื่อคุณใส่จุดของคุณบนฟังก์ชันและเรียกใช้ฟังก์ชัน elisp นี้มันจะวางนิยามฟังก์ชันจากที่ใดก็ตาม (ฉันคิดว่าจะใช้ find-tag สำหรับสิ่งนี้) และคลี่ออกในบัฟเฟอร์ปัจจุบัน แนวคิดคือถ้าคุณต้องข้ามไปยังบัฟเฟอร์อื่นเพื่ออ่านนิยามฟังก์ชันฉันรู้สึกว่ามันเปลี่ยนบริบทไปยังไฟล์อื่น ดังนั้นฉันต้องการให้มันทำงานเหมือนการพับโค้ดเพียง แต่ดึงโค้ดภายนอกจากบัฟเฟอร์เท่านั้น สิ่งนี้นำเสนอปัญหาบางประการเนื่องจากไม่สามารถวางรหัสลงในบัฟเฟอร์ได้อย่างเฉียบพลันหรือหากมีผู้บันทึกไว้ระบบจะบันทึกรหัสที่ดึงเข้ามา ดังนั้นฉันจึงสงสัยว่ามีวิธีสร้างพื้นที่ภายในบัฟเฟอร์ที่ไม่ได้เป็นส่วนหนึ่งของบัฟเฟอร์ด้วยหรือไม่ ผมคิดว่าเข้าท่า


คุณกำลังมองหาบางสิ่งที่เมื่อคุณเรียกมันด้วยจุดในฟังก์ชันเรียกมันข้ามไปที่นิยามฟังก์ชันหรือไม่? เช่นการขอความช่วยเหลือเกี่ยวกับฟังก์ชัน elisp จะช่วยให้คุณข้ามไปที่รหัส elisp ได้หรือไม่ ฉันไม่คิดว่าคุณจะทำสิ่งนี้ได้หากไม่มีแนวคิดบางอย่างเกี่ยวกับ "โครงการ" เช่นคุณจะรู้ได้อย่างไรว่าฟังก์ชัน "สลับ" ที่คุณต้องการข้ามไปยัง?
Brian Postow

1
ดูเพิ่มเติมที่: stackoverflow.com/questions/382781/…ซึ่งการแสดงผลแบบเลือกได้รับการปรับแต่งเล็กน้อยสำหรับเอฟเฟกต์ที่เหมือนการพับ
Michael Paulukonis

ฉันขอแนะนำให้คุณลบของคุณEDIT NB 2และตั้งคำถามใหม่
Stefan

คำตอบ:


151

โดยทั่วไปแล้วการพับนั้นไม่จำเป็นสำหรับ emac เนื่องจากมีเครื่องมือที่ใช้การกระทำที่ผู้คนทำด้วยตนเองอย่างชัดเจนเมื่อพับโค้ด

คนส่วนใหญ่ประสบความสำเร็จด้วยการค้นหาที่เพิ่มขึ้นง่ายๆ เห็น "foo" ที่กล่าวถึงบ้างไหม พิมพ์C-sfooค้นหาคำจำกัดความกด Enter อ่านแล้วกดC-x C-xเพื่อย้อนกลับไปยังจุดที่คุณอยู่ ง่ายและมีประโยชน์มาก

โหมดส่วนใหญ่สนับสนุนimenu M-ximenuจะให้คุณข้ามไปยังนิยามฟังก์ชัน (ฯลฯ ) ตามชื่อ คุณยังสามารถผูกเข้ากับการคลิกเมาส์เพื่อรับเมนูฟังก์ชัน (หรือเพิ่มลงในแถบเมนูดูรายละเอียดเพิ่มเติมในหน้าข้อมูล) ให้ข้อมูลสำหรับโหมดฟังก์ชันใดซึ่งจะช่วยให้คุณเห็นว่าฟังก์ชันใดที่คุณอยู่ในโมเดลซีน (ทำไมฟังก์ชั่นของคุณถึงนานขนาดนี้?)

นอกจากนี้ยังมีSpeedbarซึ่งแสดงข้อมูล imenu (และสิ่งอื่น ๆ ) กราฟิก

หากคุณต้องการดูภาพรวมของไฟล์ของคุณให้ลองใช้M-xoccur"เมื่อระบุ regex มันจะสร้างบัฟเฟอร์ใหม่สำหรับแต่ละรายการที่ตรงกันในบัฟเฟอร์ปัจจุบันคุณสามารถค้นหา" (defun "เพื่อดูภาพรวมของฟังก์ชันของไฟล์ปัจจุบัน การใช้งานการคลิกที่ผลลัพธ์จะย้ายคุณไปยังตำแหน่งนั้นในไฟล์

อย่างไรก็ตามลองนึกถึงสิ่งที่คุณต้องการบรรลุจริงๆและ Emacs อาจดำเนินการดังกล่าว อย่าต่อสู้กับเครื่องมือที่ไม่สมบูรณ์ซึ่งทำให้คุณพับและกางสิ่งต่างๆอยู่ตลอดเวลา


13
Vim ยังมีคุณสมบัติเหล่านี้ทั้งหมดในรูปแบบใดรูปแบบหนึ่ง แต่ฉันยังพบว่าสิ่งอำนวยความสะดวกพับรหัสมีค่า
สังหรณ์ใจ

115
ฉันลงคะแนนให้กับประโยคแรก ("โดยทั่วไปแล้วการพับไม่จำเป็นกับ emacs เนื่องจาก ... ") ฉันใช้การพับอย่างง่าย (ตามระดับการเยื้อง) อย่างต่อเนื่องเพื่อสแกนโครงสร้างของโค้ดที่ไม่คุ้นเคย
Simon Michael

4
Ms o เป็นทางลัดสำหรับ Mx เกิดขึ้น
Joshua Olson

3
ฉันโหวตให้เพราะทางลัดที่มีประโยชน์มากมายในคำตอบ แต่ยังโหวตด้วยความคิดเห็น @SimonMichael เพราะการพับ / คลี่ยังคงมีประโยชน์ในบางครั้ง!
Adrien Coquio

56
คำตอบได้รับการคิดอย่างดีและให้ข้อมูลมาก อย่างไรก็ตาม OP ถามวิธีการพับโค้ด OP ไม่ได้ถามว่าวิธีหลีกเลี่ยงการพับโค้ดของทุกคนเป็นอย่างไร โหวตลง
wkschwartz

104

โหมดซ่อนโชว์ ( hs-minor-mode) พร้อมการผูกแป้นเริ่มต้นC-c @ C-M-hเพื่อเรียกการพับ ( hs-hide-all)


12
นี้ใช้งานได้ดี และด้วยความชั่วร้ายโหมดนี้ถูกเรียกโดยคำสั่งที่เป็นกลุ่มปกติ: zR, zM, ,zo zc
Justin M. Keyes

39

อีกวิธีในการสกินแมว:

เมื่อเกิดขึ้นคุณไม่จำเป็นต้องมีแพ็คเกจหรือการกำหนดค่าเพิ่มเติมสำหรับสิ่งนั้น เพียงไปที่ไฟล์ต้นฉบับพิมพ์

M-1 Cx $และเวทมนตร์ก็เกิดขึ้น!

ตามปกติมันเป็นเวทมนตร์สีขาว: Cx $จะนำรหัสของคุณกลับมา

เราสามารถใช้ระบบช่วยเหลือของ Emacs เพื่อค้นหาสิ่งที่เกิดขึ้น: Ch k Cx $ บอกเราว่าคีย์ผสมข้างต้นเรียก set-selective-displayซึ่งเป็นฟังก์ชันที่รับอาร์กิวเมนต์ที่เป็นตัวเลขหนึ่งตัว (คำนำหน้า M-1 ส่งผ่าน 1 เป็นค่า ของอาร์กิวเมนต์นั้น) และไม่น่าแปลกใจที่ตั้งค่าตัวแปรที่เลือกแสดงเป็นค่าของอาร์กิวเมนต์นั้น

จาก บล็อกพ่อมด emacs เล็กน้อย

เพื่อความสมบูรณ์: M-3 Cx $จะแสดงโค้ดที่ซ้อนกันลึกขึ้นเรื่อย ๆ

FWIW วันนี้ฉันสร้างผู้ช่วยเล็ก ๆ ตาม smth พบที่นี่เพื่อให้ F5 สลับการพับโค้ดตามตำแหน่งเคอร์เซอร์ปัจจุบัน:

(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

ฉันใช้โหมดรองร่างเพื่อพับรหัสหลาม แทนที่จะต้องวาง {{{และ}}} เหมือนในโหมดพับจะใช้ตำแหน่งที่กำหนดบล็อก

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

ฉันค่อนข้างมั่นใจว่ามันมาพร้อมกับอีแมค จากนั้นฉันเพิ่มสิ่งนี้ใน. emac ของฉัน

;;======= 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
ดูเหมือนว่าoutline-modeรองรับ python out-of-the-box ใน emacs 24 - ไม่จำเป็นต้องใช้outline-levelฟังก์ชันที่กำหนดเอง นี่คือทั้งหมดที่ฉันต้องการเพิ่มในuser.el:(add-hook 'python-mode-hook 'outline-minor-mode)
scytale

1
โอ้และคุณต้องการแทนที่อย่างแน่นอนoutline-minor-mode-prefix(setq outline-minor-mode-prefix (kbd "C-;"))
เชื่อมโยงคีย์

13

คุณยังสามารถรับโค้ดพับได้โดยใช้ CEDET พร้อมรหัสต่อไปนี้ในไฟล์ init:

(global-semantic-folding-mode t)

หลังจากประเมินรหัสนี้แล้วสามเหลี่ยมเล็ก ๆ จะปรากฏในบริเวณขอบดังนั้นคุณจะสามารถพับและคลี่โค้ดโดยใช้มันได้ วิธีนี้มีความแม่นยำมากขึ้นเนื่องจากใช้ข้อมูลวากยสัมพันธ์ซึ่งดึงมาจากซอร์สโค้ด


1
หากพบข้อผิดพลาดลองดูคำถามนี้stackoverflow.com/questions/15307113/…
AdrieanKhisbe

9

hs-minor-mode ทำงานได้อย่างสวยงาม

มันทำงานได้สวยงามยิ่งขึ้นเมื่อจับคู่กับ fold-dwim (ทำในสิ่งที่ฉันหมายถึง) จากนั้นก็มี fold-dwim-org ซึ่งมีโหมดองค์กรเช่นการผูกคีย์สำหรับการพับโค้ด! ทั้งสองสามารถติดตั้งผ่าน marmalade (และฉันคิดว่า elpa)



5

vimish-fold ยังเป็นทางออกที่ดีและง่ายดาย

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

จากหน้าแรก:

นี่คือแพ็คเกจสำหรับทำการพับข้อความเหมือนใน Vim มีคุณสมบัติดังต่อไปนี้:

  • การพับพื้นที่ใช้งาน
  • ผลตอบรับที่ดี: เห็นได้ชัดว่าส่วนใดของข้อความถูกพับ
  • ความคงอยู่ตามค่าเริ่มต้น: เมื่อคุณปิดไฟล์การพับของคุณจะไม่หายไป
  • ความคงทนสามารถปรับขนาดได้ดีคุณสามารถทำงานกับไฟล์หลายร้อยไฟล์ที่มีการพับจำนวนมากโดยไม่มีผลเสีย
  • มันไม่ทำลายการเยื้องหรือบางสิ่งบางอย่าง
  • การพับสามารถสลับจากสถานะพับเป็นกางออกและกลับได้อย่างง่ายดาย
  • การนำทางอย่างรวดเร็วระหว่างการพับที่มีอยู่
  • คุณสามารถใช้เมาส์เพื่อคลี่พับ (เหมาะสำหรับผู้เริ่มต้นและไม่เพียง แต่สำหรับพวกเขาเท่านั้น)
  • สำหรับแฟน ๆ ของแพ็คเกจ avy: คุณสามารถใช้ avy เพื่อพับข้อความโดยใช้จำนวนจังหวะแป้นน้อยที่สุด!

ใช้สิ่งที่ยอดเยี่ยมuse-packageฉันติดตั้งและเปิดใช้งานโดยใช้ข้อมูลโค้ดนี้ใน config ของฉัน:

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

3

ฉันแปลกใจที่ไม่มีใครพูดถึงการทำให้แคบลง มันสุดยอดมากแถมมาพร้อมกับ emac ด้วย เพียงเลือกรหัสที่คุณต้องการที่จะมุ่งเน้นและกดเพื่อกลับไปยังโหมดมุมมองแบบเต็มเพียงแค่ทำC-x n n C-x n wฉันมักจะชอบใช้ฟังก์ชัน emacs ในตัวมากกว่าที่จะถ่วงพื้นที่ผู้ใช้ของฉันด้วยแพ็คเกจอื่น หาก emac สามารถทำได้ด้วยฟังก์ชั่นในตัวฉันจะชอบมากกว่าแพ็คเกจของบุคคลที่สาม แต่นั่นเป็นเพียงฉันไม่ได้หมายความหรือบ่งบอกถึงสิ่งอื่นใดนอกจากฉันชอบสิ่งที่เรียบง่ายมากกว่าการกำหนดค่าแบบยาวที่ซับซ้อน



2

ฉันเชื่อว่าการเปรียบเทียบ "โครงการ" ของคุณกับการพับนั้นไม่ดีนักเนื่องจากการพับเป็นการเปลี่ยนรูปลักษณ์ในขณะที่ทำให้เนื้อหาบัฟเฟอร์ยังคงอยู่ (ข้อความ) โครงการของคุณจะเกี่ยวข้องกับการแสดงข้อความเพิ่มเติมในขณะที่ทำให้เนื้อหาบัฟเฟอร์เหมือนเดิม AFAIU ดังนั้น. ไม่สามารถใช้งานได้เป็นองค์ประกอบของการแทรกข้อความและการพับ (จากนั้นเนื้อหาบัฟเฟอร์จะเปลี่ยนไป)

แต่บางทีมันเป็นจริงไปได้ด้วยกลไกการเช่นเดียวกับการพับจะทำด้วย - "ซ้อนทับ" ... พิจารณาและ "หลังสตริง" "ก่อนที่จะสาย" คุณสมบัติซ้อนทับ ; บางทีคุณอาจใส่นิยามฟังก์ชันลงในสตริงเหล่านี้ซึ่งเป็นของโอเวอร์เลย์ที่มีความยาวเป็นศูนย์ ณ จุดนั้น ดูฟังก์ชันoutline-flag-regionเพื่อดูว่ามีการใช้การวางซ้อนในโหมดเค้าร่างอย่างไร


2

หากคุณใช้hs-minor-modeอาจเป็นความคิดที่ดีที่จะตั้งค่าทางลัดที่สะดวกกว่าเช่น:

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

0

ด้วยแรงบันดาลใจจากคำตอบของ einSelbst :

(คำแนะนำ - เพิ่ม 'set-selective-display
            : filter-args (แลมบ์ดา (args)
                           (if (หรือ (car args) selective-display)
                               args
                             (รายการ (1+ (คอลัมน์ปัจจุบัน)))))
            '((ชื่อ. set-selective-display-from-cursor-column)))

Voila, C-x $ก็กลายเป็นประโยชน์ได้โดยไม่ต้องใด ๆC-uมิได้M-4ธุรกิจ


0

หากคุณใช้ JavaScript และใช้js2-mode.elงานอยู่คุณสามารถ:

C-c C-f: toggle hide / show all

C-c C-e: ซ่อนองค์ประกอบ

C-c C-s: แสดงองค์ประกอบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.