Emacsでコード折りたたみ効果を実現する方法は?


123

コードの折りたたみや、org-modeが使用する循環のタイプなどを実現する最良の方法は何ですか。このタイプの動作を作成するためのelispの最適なソリューションは何ですか?

編集:すみません、よくわかりませんでした。コードの折りたたみと非常によく似た機能をelispでプログラミングしたい、または実際には組織モードのように階層を拡張できるようにプログラムしたい。私はこの影響を達成するための最良の方法を考えています。emacsオーバーレイが良い解決策だと聞いたことがありますが、わかりません。

折りたたみに関しては、組み込みのset-selective-displayを使用するだけです。

編集番号2:

回答ありがとうございます。私は間違った質問をしていると思うので、私が何をしようとしているのかをより明確にするようにしましょう。以下を作成したい

関数にポイントを置き、このelisp関数を呼び出すと、どこからでも関数定義が配置され(私はこれにfind-tagを使用することを考えています)、現在のバッファーで展開します。アイデアは、関数定義を読み取るために別のバッファーにジャンプする必要がある場合、別のファイルへのコンテキスト切り替えのように感じます。だから私はそれがバッファの外部にあるコードを引っ張るだけのコード折りたたみのように振る舞いたいと思います。これは、コードをバッファに実際に貼り付けることができないか、誰かがそれを保存した場合、プルされたコードを保存するため、いくつかの問題を引き起こします。したがって、バッファの一部ではない領域をバッファ内に作成する方法があるかどうか疑問に思っています。それは理にかなっていると思います。


あなたは関数CALLのポイントでそれを呼び出すとそれが関数定義にジャンプする何かを探していますか?elisp関数についてのヘルプを得るようなもので、elispコードにジャンプできますか?「プロジェクト」の概念なしにこれを行うことはできないと思います。たとえば、ジャンプ先の「スワップ」関数をどのようにして知ることができますか?
Brian Postow、

1
次も参照してください:stackoverflow.com/questions/382781/…ここでは、いくつかの折りたたみのような効果のために、selective-displayが少し調整されています。
マイケルPaulukonis、2010

を削除EDIT NB 2して、新しい質問をすることをお勧めします。
Stefan

回答:


151

emacsでは、コードを折りたたむときに手動で行うアクションを明示的に実装するツールがあるため、折りたたみは一般に不要です。

ほとんどの人は単純なインクリメンタル検索で成功しています。どこかで言及されている「foo」を参照してください。と入力しC-sfooて定義を見つけ、Enter C-x C-xキーを押して読み、次にを押して元の場所に戻ります。シンプルでとても便利です。

ほとんどのモードでimenuがサポートされていますM-ximenu名前で関数定義などにジャンプできます。これをマウスクリックにバインドして、機能のメニューを取得することもできます(またはメニューバーに追加します。詳細については、[情報]ページを参照してください)。これは、関数モードのデータを提供します。これにより、モードラインの現在どの関数にいるかを確認できます。(しかし、関数がこれほど長いのはなぜですか?)

また、imenu情報(およびその他のもの)をグラフィカルに表示するspeedbarもあります。

ファイルの概要を取得したい場合は、M-xoccur「」を試してください。正規表現を指定すると、現在のバッファー内で一致するものごとに新しいバッファーが作成されます。「(defun」を検索すると、現在のファイルの機能の概要を取得できます結果をクリックすると、ファイル内のその位置に移動します。

とにかく、本当に達成したいことを考えてください。Emacsはおそらくそれを実装しています。常に物事を折りたたんだり展開したりする不完全なツールと戦わないでください。


13
Vimはこれらの機能のすべてを何らかの形で提供しますが、コード折りたたみ機能は非常に貴重です。
2011年

115
私は最初の文に反対票を投じました(「折り畳みは一般にemacsでは不要です...」)。(インデントレベルに基づいて)単純な折りたたみを常に使用して、見慣れないコードの構造をスキャンしています。
Simon Michael、

4
Ms oはMxのショートカットです
Joshua Olson 2013年

3
私は回答に多くの便利なショートカットがあるので賛成票を投じましたが、折りたたみ/展開がまだ役立つこともあるので@SimonMichaelコメントも賛成票を投じました!
Adrien Coquio 2013

56
答えはよく考えられており、非常に有益でした。しかし、OPはコードの折りたたみを行う方法を尋ねました。OPは、コードの折りたたみを回避するために誰もが好きな方法を尋ねませんでした。反対票。
wkschwartz 2013年

104

折りたたみをトリガーするhs-minor-modeデフォルトのキーバインドC-c @ C-M-hを使用した非表示モード()(hs-hide-all


12
これはうまくいきます。そして邪悪なモードで、これは通常のVimのコマンドによってトリガーされます:zRzMzozc
Justin M. Keyes

39

猫の皮をむく別の方法:

たまたま、そのためのパッケージや追加の構成は必要ありません。ソースファイルに移動し、次のように入力します。

M-1 Cx $と魔法が起こります!

いつものように、それは白い魔法です:Cx $はコードを元に戻します。

Emacsのヘルプシステムを使用して、何が起こっているのかを発見できます。Chk Cx $は、上記のキーの組み合わせがset-selective-displayを呼び出し ていることを示しています。そして、当然のことながら、変数selective-displayをその引数の値に設定します。

マイナー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

私はPythonのコードを折り畳むためにアウトラインマイナーモードを使用しています。折りたたみモードのように{{{および}}}を配置する必要はなく、ブロックが定義されている場所を使用します。

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)
スキュタレー

1
ああ、あなたは間違いなくオーバーライドしたいoutline-minor-mode-prefix-デフォルトのキーバインドはひどい-私が使う(setq outline-minor-mode-prefix (kbd "C-;"))
scytale

13

また、CEDETを使用して、initファイルの次のコードでコードの折りたたみを取得することもできます。

(global-semantic-folding-mode t)

このコードを評価すると、小さな三角形がそばに表示されるため、それを使用してコードを折りたたんだり展開したりできます。この方法は、ソースコードから抽出された構文情報を使用するため、より正確です。


1
いくつかのバグが直面している場合は、この質問の表情を持っている:stackoverflow.com/questions/15307113/...
AdrieanKhisbe

9

hs-minor-modeは美しく動作します。

fold-dwim(私が言っていることを行う)と組み合わせると、より美しく機能します。次に、fold-dwim-orgがあります。これは、コードの折りたたみのためのキーバインディングのようなorg-modeを提供します!どちらもマーマレード経由でインストールできます(私はelpaだと思います)。



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)。そう。テキストの挿入と折りたたみの構成としては実装できません(その場合、バッファーの内容が変更されます)。

しかし、たぶん、たぶん折り畳みが行われるのと同じメカニズムで実際に可能です-「オーバーレイ」...「before-string」および「after-string」オーバーレイプロパティを検討してください。おそらく、その時点で長さゼロのオーバーレイに属するこれらの文字列に関数定義を置くことができます。アウトラインモードでオーバーレイがどのように使用されるかを確認するには、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(lambda(args)
                           (if(または(car args)selective-display)
                               引数
                             (リスト(1+(現在の列)))))
            '((name。set-selective-display-from-cursor-column)))

Voilaは、ビジネスもビジネスC-x $もない状態でも、突然役に立ちました。C-uM-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.