如何在Emacs中实现代码折叠效果?
什么是实现类似代码折叠的最佳方式,或者组织模式使用的循环types。 在elisp中创build这种types的行为最好的解决scheme是什么?
编辑:对不起,我不清楚。 我想在elisp中编写一些与代码折叠非常相似的东西,或者实际上最类似于可以扩展的层次结构的org模式。 我想知道达到这个效果的最好方法。 我想我听说emacs覆盖是一个很好的解决scheme,但我不知道。
至于折叠我只是使用内置的集select显示
编辑号码2:
感谢您的答案,但我想我问的是错误的问题,所以让我试着更清楚我在做什么。 我想创build以下
当你把你的观点放在一个函数上,并调用这个elisp函数时,它将把函数定义放在任何地方(我正在考虑只使用find-tag)并将其展开到当前缓冲区中。 这个想法是,如果你不得不跳转到不同的缓冲区来读取函数定义,我觉得它的上下文切换到另一个文件。 所以我希望它的行为就像代码折叠,只是从缓冲区拉外部代码。 这提出了一些问题,因为它不能将代码粘贴到缓冲区,或者如果有人保存它将保存拉入的代码。 所以我想知道是否有一种方法来创build一个缓冲区内也不是缓冲区的一部分。 我认为这是有道理的。
对于emacs来说,折叠通常是不必要的,因为它具有明确实现人们在折叠代码时手动执行的操作的工具。
大多数人通过简单的增量search取得了很好的成功 看到“富”提到的地方? 键入Cs foo
,find定义,按回车,读取它,然后按Cx Cx返回到您所在的位置。 简单而且非常有用。
大多数模式支持imenu 。 Mx imenu
会让你跳转到一个函数定义(等)名称。 您也可以将其绑定到鼠标单击以获取function菜单(或将其添加到菜单栏;有关更多详细信息,请参阅“信息”页面)。 它提供了哪些函数模式的数据,这可以让你看到你现在在模式行中的哪个函数。 (为什么你的function这么长,虽然?)
还有speedbar ,以graphics方式显示imenu信息(和其他东西)。
如果你想得到你的文件的概述,尝试Mx occur
“。给定一个正则expression式,它将创build一个新的缓冲区与每个匹配在当前的缓冲区。您可以search”(defun“以获得function的概述当前文件实现,点击结果会将你移动到文件中的那个位置。
所以无论如何,想想你真正想要达到的目标,Emacs可能会实现这个目标。 不要与不完善的工具,使你不断折叠和展开的事情。
隐藏显示模式( hs-minor-mode
)与默认的键合Cc @ Cc
触发折叠。
我使用大纲次要模式来折叠我的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 \Cc@ prefix, too hard to type. Note this overides some bindings. (setq outline-minor-mode-prefix "\Ct") ; turn on outline mode (outline-minor-mode t) ; initially hide all but the headers ;(hide-body) ; make paren matches visible (show-paren-mode 1) )
另一种方法来剥皮猫:
碰巧,你不需要任何包或者额外的configuration。 只要去任何源文件,input
M-1 Cx $和魔法发生!
像往常一样,它是白色的魔法: Cx $将带回你的代码。
我们可以使用Emacs的帮助系统来发现发生了什么事情:Ch k Cx $告诉我们,上面的组合键是调用set-selective-display ,一个带有一个数字参数的函数(M-1前缀作为值),毫不奇怪,将variablesselect性显示设置为该参数的值。
从小emacs巫术博客
只是为了完整: M-3 Cx $会显示更深的嵌套代码等等。
FWIW今天,我根据smth做了一个小助手。 在这里find,以便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))))))
您也可以通过在init文件中使用CEDET和以下代码来获得代码折叠:
(global-semantic-folding-mode t)
在对这个代码进行评估之后,这个小三angular形将出现在fringle区域,所以你可以使用它来展开和展开代码。 这种方法更精确,因为它使用从源代码中提取的语法信息
hs-minor-mode的作品非常漂亮。
它与fold-dwim配对(做我的意思)更加美妙。 然后是fold-dwim-org,它为代码折叠提供组织模式,如键绑定。 两者都可以通过橘子酱安装(我认为elpa)。
显然没有完美的解决scheme,但我认为最好的是这样的:
emacs带有hs-minor-mode,用于平衡expression式之间的代码折叠http://www.emacswiki.org/emacs/HideShow
我相信你的“项目”与折叠的比较不是很好,因为折叠是关于改变外观,同时保持缓冲区内容完整(文本)。 您的项目将涉及显示额外的文本,同时保持缓冲区内容完整,AFAIU。 所以。 它不能作为文本插入和折叠的组合来实现(然后,缓冲区内容将被改变)。
但也许,这是确实可能的相同的机制,因为折叠是用“覆盖”完成的…考虑“之前string”和“后string” 覆盖属性 ; 也许,你可以把你的函数定义放到属于这个零长度覆盖的string中。 查看outline-flag-region函数以查看在大纲模式中如何使用叠加层。
vimish-fold
也是一个不错的和容易的解决scheme。
https://github.com/mrkkrp/vimish-fold 。
从主页:
这是一个在Vim中执行文本折叠的包。 它具有以下特点:
- 活动区域的折叠;
- 良好的视觉反馈:很明显文本的哪一部分是折叠的;
- 持久性默认情况下:当你closures文件你的褶皱不消失;
- 持久性能够很好地扩展,可以处理数百个有很多折叠的文件而没有不利影响;
- 它不会打破缩进或什么;
- 折叠可以从折叠状态翻转到非常容易地展开和返回;
- 现有褶皱之间的快速导航;
- 你可以用鼠标来展开褶皱(对于初学者而言不仅适用于它们)。
- 对于avy包的粉丝:您可以使用avy以最less的击键次数来折叠文本!
使用优秀的use-package
我使用这个片段在我的configuration中安装并激活它:
(use-package vimish-fold :ensure t :config (vimish-fold-global-mode t))
如果你使用hs-minor-mode
,也可以设置一个更方便的快捷方式,例如:
(eval-after-load 'hideshow '(progn (global-set-key (kbd "C-+") 'hs-toggle-hiding)))