如何在Emacs中实现代码折叠效果?

时间:2009-07-06 02:29:23

标签: emacs elisp code-folding

什么是实现代码折叠或org-mode使用的循环类型的最佳方式。在elisp中创建这种行为的最佳解决方案是什么?

编辑: 对不起,我不清楚。我想在elisp中编写一些与代码折叠非常相似的东西,或者实际上最像org-mode的层次结构可以扩展。我想知道实现这种影响的最佳方法。我想我听过emacs叠加是一个很好的解决方案,但我不知道。

就折叠而言,我只使用内置的set-selective-display

编辑编号2:

感谢您的回答,但我想我问的是错误的问题,所以让我试着更清楚一下我想要做什么。我想创建以下

当你把你的观点放在一个函数上并调用这个elisp函数时,它将把函数定义放在任何地方(我想只是使用find-tag)并在当前缓冲区展开它。我的想法是,如果你必须跳转到不同的缓冲区来读取函数定义,我觉得它的上下文切换到另一个文件。所以我希望它表现得像代码折叠只是它从缓冲区拉入外部代码。这会带来一些问题,因为它无法将代码实际粘贴到缓冲区中,或者如果有人保存它,它将保存拉入的代码。所以我想知道是否有办法在缓冲区内创建一个也不属于缓冲区的区域。我认为这是有道理的。

14 个答案:

答案 0 :(得分:147)

emacs通常不需要折叠,因为它具有明确实现人们在折叠代码时手动执行的操作的工具。

大多数人通过简单的增量搜索取得了很好的成功。看到某处提到的“foo”?键入 Cs foo,找到定义,按回车键,读取它,然后按 Cx Cx 返回到您的位置是。简单而且非常有用。

大多数模式支持 imenu M-x imenu将允许您按名称跳转到函数定义(等)。您还可以将其绑定到鼠标单击以获取功能菜单(或将其添加到菜单栏;有关详细信息,请参阅信息页面)。它为哪个功能模式提供数据,它可以让你看到你当前在模式行中的哪个功能。 (但为什么你的功能很长?)

还有 speedbar ,它以图形方式显示imenu信息(和其他内容)。

如果你想得到你的文件的概述,试试 Mx occur“。给定一个正则表达式,它将在当前缓冲区中创建一个新的缓冲区,每个匹配。你可以搜索“(defun”以获得当前文件实现的功能的概述。单击结果将移动到文件中的该位置。

所以无论如何,想想你真正想要实现的目标,而Emacs可能会实现这一目标。不要与不完美的工具作斗争,让你不断折叠和展开东西。

答案 1 :(得分:88)

隐藏显示模式(hs-minor-mode),使用默认键绑定C-c @ C-M-h来触发折叠(hs-hide-all

答案 2 :(得分:28)

皮肤猫的另一种方法:

  

碰巧,您不需要任何包或额外配置   那。只需转到任何源文件,键入

M-1 C-x $ ,魔法发生了!

像往常一样,它是白色魔法: C-x $ 会带回你的代码。

  

我们可以使用Emacs的帮助系统来发现正在发生的事情:C-h k C-x $   告诉我们上面的组合键是调用    set-selective-display ,一个带一个数字参数的函数   (M-1前缀将1作为该参数的值)和   不出所料,将变量selective-display设置为值   那个论点。

来自minor emacs wizardry blog

为了完整性: M-3 C-x $ 会显示更深层次的嵌套代码,等等。

FWIW我今天基于smth做了一个小帮手。找到here,以便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))))))

答案 3 :(得分:21)

我使用outline次模式来折叠我的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)
)

答案 4 :(得分:12)

您还可以使用CEDET和init文件中的以下代码来获取代码折叠:

(global-semantic-folding-mode t)

在评估此代码后,小三角形将出现在边缘区域,因此您可以折叠和放大。使用它展开代码。这种方法更精确,因为它使用从源代码中提取的句法信息

答案 5 :(得分:9)

hs-minor-mode工作得很漂亮。

与fold-dwim搭配时,它的效果更加出色(做我的意思)。然后是fold-dwim-org,它为代码折叠提供类似于键绑定的组织模式!两者都可以通过果酱安装(我认为是elpa)。

答案 6 :(得分:7)

显然没有完美的解决方案,但我认为最好的解决方案是:

http://www.emacswiki.org/emacs/FoldingMode

答案 7 :(得分:4)

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))

答案 8 :(得分:2)

emacs附带hs-minor-mode,它可以平衡平衡表达式之间的代码折叠 http://www.emacswiki.org/emacs/HideShow

答案 9 :(得分:2)

答案 10 :(得分:1)

如果您使用use Yii; use yii\helpers\Url; use yii\web\ServerErrorHttpException; class UploadImageForm extends \yii\base\Model { public $imageFile; public $documentPath = 'uploads/'; public function rules() { return [ [['imageFile'], 'required'], [['imageFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg', 'maxSize' => 4194304, 'tooBig' => 'File size limit is 4MB'], ]; } public function attributes() { return ['imageFile']; } public function upload() { if ($this->validate()) { $fileName = $this->imageFile->baseName . '.' . $this->imageFile->extension; $path = $this->documentPath . Yii::$app->user->id . '/'; if ($this->imageFile->saveAs($path.$fileName) === false) throw new ServerErrorHttpException('Failed for unknown reason. please try again'); return [ 'imagePath' => Url::to('@web', true) .'/'. $path.$fileName, ]; } return false; } } ,最好还设置一个更方便的快捷方式,例如:

hs-minor-mode

答案 11 :(得分:1)

我很惊讶没有人提到缩小范围。它很棒,它还与emacs捆绑在一起。只需选择您要关注的代码,然后按C-x n n,就可以返回全视图模式,只需执行C-x n w。我总是更喜欢使用内置的emacs功能,而不是使用另一个软件包来使我的用户空间混乱。如果emacs可以使用内置功能做到这一点,那么我会优先选择某些第三方软件包,但这只是我,除了我喜欢复杂的长配置中的简单内容之外,并不意味着或暗示任何其他事情。

答案 12 :(得分:0)

einSelbst's answer的启发:

(advice-add 'set-selective-display
            :filter-args (lambda (args)
                           (if (or (car args) selective-display)
                               args
                             (list (1+ (current-column)))))
            '((name . set-selective-display-from-cursor-column)))

Voila,C-x $突然变得有用,即使没有任何C-uM-4生意。

答案 13 :(得分:0)

如果您正在使用JavaScript并使用js2-mode.el,则可以:

C-c C-f:切换隐藏/全部显示

C-c C-e:隐藏元素

C-c C-s:显示元素