Emacs에서 코드 접기 효과를 얻는 방법은 무엇입니까?


123

코드 폴딩이나 조직 모드에서 사용하는 순환 유형과 같은 것을 달성하는 가장 좋은 방법은 무엇입니까? 이러한 유형의 동작을 생성하기 위해 elisp에서 가장 좋은 솔루션은 무엇입니까?

편집 : 명확하지 않아서 죄송합니다. 코드 접기와 매우 유사한 작업을 수행하거나 실제로 확장 할 수있는 계층 구조가있는 조직 모드와 가장 유사한 것을 elisp에서 프로그래밍하고 싶습니다. 이 효과를 얻을 수있는 가장 좋은 방법이 궁금합니다. emacs 오버레이가 좋은 솔루션이라고 들었지만 모르겠습니다.

폴딩에 관해서는 내장 된 세트 선택적 디스플레이를 사용합니다.

번호 2 수정 :

답 해주셔서 감사 합니다만 제가 잘못된 질문을하고있는 것 같아서 제가하려는 일에 대해 좀 더 명확하게하겠습니다. 다음을 만들고 싶습니다

당신이 당신의 요점을 함수에 놓고이 elisp 함수를 호출하면 그것이 어디에 있든 (나는 이것을 위해 find-tag를 사용하려고 생각하고 있습니다) 함수 정의를 넣고 현재 버퍼에서 펼칩니다. 아이디어는 함수 정의를 읽기 위해 다른 버퍼로 이동해야하는 경우 다른 파일로의 컨텍스트 전환처럼 느껴집니다. 따라서 버퍼에서 외부 코드를 가져 오는 코드 접기처럼 작동하고 싶습니다. 이것은 코드를 버퍼에 직접 붙여 넣을 수 없거나 누군가 저장하면 풀인 코드를 저장하기 때문에 몇 가지 문제가 있습니다. 그래서 버퍼의 일부가 아닌 버퍼 내부에 영역을 만드는 방법이 있는지 궁금합니다. 그게 말이되는 것 같아요.


함수 CALL에서 포인트로 호출하면 함수 정의로 이동하는 것을 찾고 있습니까? elisp 함수에 대한 도움을받는 것과 비슷하게 elisp 코드로 이동할 수 있습니까? "프로젝트"라는 개념 없이는이 작업을 수행 할 수 없다고 생각합니다. 예를 들어, 어떤 "스왑"기능으로 이동 하려는지 어떻게 알 수 있습니까?
Brian Postow

1
참조 : stackoverflow.com/questions/382781/… 여기서 선택적 표시는 일부 접는 효과를 위해 약간 조정됩니다.
Michael Paulukonis

나는 당신을 제거 EDIT NB 2하고 그것에 대한 새로운 질문을 만드는 것이 좋습니다 .
Stefan

답변:


151

이맥스에서는 코드를 접을 때 사람들이 수동으로 수행하는 작업을 명시 적으로 구현하는 도구가 있으므로 접기는 일반적으로 불필요합니다.

대부분의 사람들은 간단한 증분 검색으로 성공했습니다. 어딘가에 언급 된 "foo"를 보십니까? 을 입력 C-sfoo하고 정의를 찾고 Enter 키를 누르고 읽은 다음을 눌러 C-x C-x이전 위치로 돌아갑니다. 간단하고 매우 유용합니다.

대부분의 모드는 imenu를 지원 합니다 . M-ximenu이름으로 함수 정의 (등)로 이동할 수 있습니다. 기능 메뉴를 가져 오기 위해 마우스 클릭에 바인딩 할 수도 있습니다 (또는 메뉴 막대에 추가합니다. 자세한 내용은 정보 페이지 참조). 어떤 기능 모드에 대한 데이터를 제공하여 현재 모델 라인에 어떤 기능이 있는지 확인할 수 있습니다. (그래도 당신의 기능은 왜 이렇게 긴가요?)

또한이 스피드 그래픽 IMENU 정보 (그리고 다른 것들)을 표시한다.

파일의 개요를 보려면 M-xoccur"를 시도하십시오 . 정규식이 주어지면 현재 버퍼의 각 일치 항목과 함께 새 버퍼가 생성됩니다."(defun "을 검색하여 현재 파일의 기능에 대한 개요를 볼 수 있습니다. 결과를 클릭하면 파일의 해당 위치로 이동합니다.

어쨌든, 당신이 정말로 달성하고 싶은 것이 무엇인지 생각해보십시오. 그러면 Emacs는 아마도 그것을 구현할 것입니다. 끊임없이 물건을 접고 펼칠 수있는 불완전한 도구로 싸우지 마십시오.


13
Vim은 이러한 모든 기능을 한 가지 또는 다른 형태로 제공하지만 여전히 코드 폴딩 기능이 매우 중요합니다.
2011 년

115
나는 첫 번째 문장에 대해 반대표를 던졌다 ( "폴딩은 일반적으로 emacs에서는 불필요하다."). 익숙하지 않은 코드의 구조를 스캔하기 위해 지속적으로 간단한 접기 (들여 쓰기 수준에 따라)를 사용합니다.
Simon Michael

4
리 오가 발생할 MX의 바로 가기입니다
여호수아 올슨

3
나는 대답에 유용한 단축키가 많기 때문에 찬성했지만 fold / unfold는 여전히 유용 할 수 있기 때문에 @SimonMichael 댓글에 찬성 투표했습니다!
Adrien Coquio

56
대답은 잘 생각되었고 매우 유익했습니다. 그러나 OP는 코드 접기를 수행하는 방법을 물었습니다. OP는 코드 접기를 피하는 모든 사람이 좋아하는 방법이 무엇인지 묻지 않았습니다. 아래로 투표했습니다.
wkschwartz


39

고양이 가죽을 벗기는 또 다른 방법 :

이 경우 패키지 나 추가 구성이 필요하지 않습니다. 소스 파일로 이동하여

M-1 Cx $ 와 마법이 일어난다!

늘 그렇듯이, 그것은 백마법입니다. Cx $ 는 코드를 다시 가져올 것입니다.

Emacs의 도움말 시스템을 사용하여 무슨 일이 일어나고 있는지 알아낼 수 있습니다. Ch k Cx $는 위의 키 조합이 하나의 숫자 인수를 취하는 함수 인 set-selective-display를 호출하고 있음을 알려줍니다 (M-1 접두사는 값으로 1을 전달합니다 당연히 변수 선택 표시를 해당 인수의 값으로 설정합니다.

에서 작은 이맥스 마법의 블로그

완전성을 위해 : 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

개요 부 모드를 사용하여 파이썬 코드를 접습니다. 접기 모드 에서처럼 {{{and}}}를 배치 할 필요없이 블록이 정의 된 위치를 사용합니다.

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

나는 그것이 emacs와 함께 제공된다는 것을 확신합니다. 그런 다음 내 .emacs에 추가합니다.

;;======= 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-modeemacs 24에서 기본적으로 Python을 지원하는 것처럼 보입니다 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를 사용하여 코드 접기를 가져올 수도 있습니다.

(global-semantic-folding-mode t)

이 코드를 평가하면 작은 삼각형이 가장자리 영역에 나타나므로이를 사용하여 코드를 접고 펼칠 수 있습니다. 이 방법은 소스 코드에서 추출한 구문 정보를 사용하므로 더 정확합니다.


1
일부 버그에 직면하는 경우,이 질문에 봐 : stackoverflow.com/questions/15307113/...
AdrieanKhisbe

9

hs-minor-mode는 아름답게 작동합니다.

fold-dwim과 함께 사용하면 더욱 아름답게 작동합니다. 그런 다음 코드 폴딩을위한 키 바인딩과 같은 조직 모드를 제공하는 fold-dwim-org가 있습니다! 둘 다 마멀레이드를 통해 설치할 수 있습니다 (그리고 엘파라고 생각합니다).



5

vimish-fold 또한 훌륭하고 쉬운 솔루션입니다.

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

홈페이지에서 :

Vim 에서처럼 텍스트 접기를 수행하는 패키지입니다. 다음과 같은 기능이 있습니다.

  • 활성 영역의 접힘;
  • 좋은 시각적 피드백 : 텍스트의 어느 부분이 접혀 있는지 분명합니다.
  • 기본적으로 지속성 : 파일을 닫을 때 접기가 사라지지 않습니다.
  • 지속성은 잘 확장되므로 악영향없이 접을 수있는 수백 개의 파일에서 작업 할 수 있습니다.
  • 들여 쓰기 등을 깨뜨리지 않습니다.
  • 접기는 접힌 상태에서 펼쳐진 상태로 매우 쉽게 전환 할 수 있습니다.
  • 기존 접기 사이의 빠른 탐색;
  • 마우스를 사용하여 접을 수 있습니다 (초보자뿐만 아니라 초보자에게도 좋습니다).
  • avy 패키지의 팬 : avy를 사용하여 최소한의 키 입력으로 텍스트를 접을 수 있습니다!

우수한 use-package기능을 사용하여 내 구성에서 다음 코드 조각을 사용하여 설치하고 활성화합니다.

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

3

축소 확대를 언급 한 사람이 없다는 사실에 놀랐습니다. 정말 대단합니다. emacs도 번들로 제공됩니다. 집중할 코드를 선택하고를 누르면 C-x n n전체보기 모드로 돌아갑니다 C-x n w. 나는 항상 다른 패키지로 사용자 공간을 복잡하게 만드는 것보다 내장 된 emacs 기능을 사용하는 것을 선호합니다. emacs가 내장 기능으로 할 수 있다면 써드 파티 패키지보다 그것을 선호 할 것입니다. 그러나 그것은 나뿐입니다. 복잡한 긴 구성보다 단순한 것을 좋아한다는 것 외에 다른 것을 의미하거나 암시하지는 않습니다.



2

접기는 버퍼 내용 (텍스트)을 그대로 유지하면서 모양을 변경하는 것이기 때문에 "프로젝트"를 접기와 비교하는 것이 좋지 않다고 생각합니다. 프로젝트는 AFAIU라는 버퍼 내용을 그대로 유지하면서 추가 텍스트를 표시하는 것을 포함합니다. 그래서. 텍스트 삽입 및 접기의 구성으로 구현할 수 없습니다 (그러면 버퍼 내용이 변경됨).

그러나 아마도 이것은 폴딩이 다음으로 수행되는 것과 동일한 메커니즘으로 가능할 것입니다.- "overlays"... "before-string"및 "after-string" 오버레이 속성을 고려하십시오 . 아마도 함수 정의를 지점에서 길이가 0 인 오버레이에 속하는 이러한 문자열에 넣을 수 있습니다. 봐 개요 - 깃발 지역 오버레이가 아웃 라인 모드에서 사용하는 방법을 보려면 기능.


2

을 사용 hs-minor-mode하는 경우 더 편리한 바로 가기를 설정하는 것이 좋습니다. 예 :

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

0

einSelbst의 답변 에서 영감을 얻어 .

(advice-add 'set-selective-display
            : filter-args (람다 (args)
                           (또는 (자동차 인수) 선택적 표시)
                               args
                             (목록 (1+ (현재 열)))))
            '((name. set-selective-display-from-cursor-column)))

짜잔, C-x $갑자기 심지어 어떤없이 유용되었다 C-u이나 M-4사업.


0

JavaScript를 사용하고을 사용하는 경우 다음을 수행 js2-mode.el할 수 있습니다.

C-c C-f: 모두 숨기기 / 표시 전환

C-c C-e: 요소 숨기기

C-c C-s: 요소 표시

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.