如何在JavaScript中实现区域/代码折叠

157

如何在Visual Studio中为JavaScript实现区域(即代码折叠)?

如果JavaScript有数百行代码,使用类似于VB / C#中的代码折叠区域将更易于理解。

#region My Code

#endregion

1
没有任何一个解决方案像这个一样适合我。https://dev59.com/gVYO5IYBdhLWcg3wI-Zw#46268008 - Michael Drum
18个回答

84

1
@William 有一天人们肯定会需要这个的 ;) - Kaushik Thanki
2
随着时间的推移,这将成为事实上被接受的答案。 - Hakan Fıstık
截至2019年6月10日,与最新版本的VSCode - Typescript完美配合。 - Eddy Howard
这也适用于VS2019,而且我没有安装Web Essentials。 - Luke Vo
2
@LukeVo 然后似乎VS2019内置支持这个。 - Kaushik Thanki
永远不要使用Web Essentials,注意它会让你陷入循环安装相同的东西,每次打开vs2015都是如此。此外,您的JS折叠功能也将无法正常工作。完全没用。 - Devmyselz

52

微软现在推出了一个适用于VS 2010的扩展,该扩展提供了以下功能:

JScript编辑器扩展


太棒了!我希望他们能在下一个VS更新中包含这个功能。感谢分享! - William Niu
真是一个非常棒的扩展,甚至比第三方的大纲扩展还要好。 - Hovis Biddle
2
这种情况是否发生在VS 2012和2013中? - Jacques
1
太好了!有没有适用于VS 2012或2013的版本? - Axel

44

这很简单!

标记您想要折叠的部分,然后

Ctrl+M+H

要展开,请在其左侧使用“+”标记。


4
成功了!它让我的代码看起来更简洁,因为我有很多的ajax调用在一个单一的ajax调用下。 - Sorangwala Abbasali
4
这只是一个临时解决办法。如果您关闭并重新打开文件,选定的区域会消失。 - oneNiceFriend

32

对于即将使用Visual Studio 2012的用户,可以使用Web Essentials 2012

对于即将使用Visual Studio 2015的用户,可以使用Web Essentials 2015.3

使用方法与@prasad提问的完全一样


4
+1 - 这应该是答案,因为现在大多数人都在使用2012/2013!(它也适用于2013) - Peter Albert

26

这篇博客文章解释了它,以及MSDN问题

您必须使用Visual Studio 2003/2005/2008宏。

为了保持一致性,请从博客文章中复制+粘贴以下内容:

  1. 打开宏资源管理器
  2. 创建一个新的宏
  3. 将其命名为OutlineRegions
  4. 单击“编辑宏”并粘贴以下VB代码:
Option Strict Off
Option Explicit Off

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics
Imports System.Collections

Public Module JsMacros

    Sub OutlineRegions()
        Dim selection As EnvDTE.TextSelection = DTE.ActiveDocument.Selection

        Const REGION_START As String = "//#region"
        Const REGION_END As String = "//#endregion"

        selection.SelectAll()
        Dim text As String = selection.Text
        selection.StartOfDocument(True)

        Dim startIndex As Integer
        Dim endIndex As Integer
        Dim lastIndex As Integer = 0
        Dim startRegions As Stack = New Stack()

        Do
            startIndex = text.IndexOf(REGION_START, lastIndex)
            endIndex = text.IndexOf(REGION_END, lastIndex)

            If startIndex = -1 AndAlso endIndex = -1 Then
                Exit Do
            End If

            If startIndex <> -1 AndAlso startIndex < endIndex Then
                startRegions.Push(startIndex)
                lastIndex = startIndex + 1
            Else
                ' Outline region ...
                selection.MoveToLineAndOffset(CalcLineNumber(text, CInt(startRegions.Pop())), 1)
                selection.MoveToLineAndOffset(CalcLineNumber(text, endIndex) + 1, 1, True)
                selection.OutlineSection()

                lastIndex = endIndex + 1
            End If
        Loop

        selection.StartOfDocument()
    End Sub

    Private Function CalcLineNumber(ByVal text As String, ByVal index As Integer)
        Dim lineNumber As Integer = 1
        Dim i As Integer = 0

        While i < index
            If text.Chars(i) = vbCr Then
                lineNumber += 1
                i += 1
            End If

            i += 1
        End While

        Return lineNumber
    End Function

End Module
  1. 保存宏并关闭编辑器。
  2. 现在,让我们为宏分配快捷键。转到“工具”->“选项”->“环境”->“键盘”,并在“显示包含命令”的文本框中搜索您的宏。
  3. 现在,在“按快捷键”下方的文本框中,可以输入所需的快捷键。我使用Ctrl+M+E这个组合键。我不知道为什么 - 我第一次输入后就一直使用它 :)

这个很有用,从网站评论中需要注意的重要一点是:“您必须检查上面代码中模块的名称与您的新宏的名称是否匹配!两个名称必须相同!” - Prasad
@Mr. Flibble:不确定...我只有VS2005。 - user195488
微软现在为VS2010提供了一个扩展程序,可以提供这个功能(请参见下面我的回答中的链接)。 - BrianFinkel
非常好,但请问有没有一种方法可以在突出显示 JavaScript 代码的同时,通过快捷方式在开头放置 #region,而在结尾放置 #endregion,以使它变得更加容易? :) 我认为这将是一件非常有帮助的事情。 - Marwan
@Marwan:如果你有问题,请提出另一个问题。不要在这个答案下发表评论。 - user195488
显示剩余3条评论

26

通过标记代码片段 (不考虑任何逻辑块) 并按下 CTRL + M + H,您将定义所选内容为可折叠和展开的区域。


谢谢!如果我不小心创建了一个我想要删除或更改的区域,你能告诉我如何撤消它吗? - Tingo
3
您可以使用CTRL + M + U来撤销- 更多快捷键请参见:https://msdn.microsoft.com/en-us/library/td6a5x4s.aspx。 - laurian

20

Visual Studio的JSEnhancements插件能很好地解决这个问题。


这正是我正在寻找的。谢谢。 - Axel

17

对于那些来到这里寻找Visual Studio Code的人,相同的语法也适用。

// #region MongoDB Client
const MongoClient = require('mongodb').MongoClient;
const url = constants.credentials["uat"].mongo.url
MongoClient.connect(url, { useUnifiedTopology: true }, function (err, client) {
    if (err) {
        console.log(err);
    }
    else {
        docDB = client.db("middlewareDB");
    }
});
// #endregion

折叠时,它看起来像下面这样

输入图像描述


9

感谢0A0D提供的出色答案。我已经用它获得了好运气。Darin Dimitrov也提出了限制JS文件复杂性的好观点。然而,我确实发现折叠函数到其定义中使浏览文件变得更加容易的情况。

关于#region总体而言,这个SO问题解释得很好。

我对宏进行了一些修改,以支持更高级的代码折叠。这种方法允许您在//#region关键字之后放置描述,类似于C#,并将其显示在代码中,如下所示:

示例代码:

//#region InputHandler
var InputHandler = {
    inputMode: 'simple', //simple or advanced

    //#region filterKeys
    filterKeys: function(e) {
        var doSomething = true;
        if (doSomething) {
            alert('something');
        }
    },
    //#endregion filterKeys

    //#region handleInput
    handleInput: function(input, specialKeys) {
        //blah blah blah
    }
    //#endregion handleInput

};
//#endregion InputHandler

更新的宏:

Option Explicit On
Option Strict On

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Imports System.Collections.Generic

Public Module JsMacros


    Sub OutlineRegions()
        Dim selection As EnvDTE.TextSelection = CType(DTE.ActiveDocument.Selection, EnvDTE.TextSelection)

        Const REGION_START As String = "//#region"
        Const REGION_END As String = "//#endregion"

        selection.SelectAll()
        Dim text As String = selection.Text
        selection.StartOfDocument(True)

        Dim startIndex As Integer
        Dim endIndex As Integer
        Dim lastIndex As Integer = 0
        Dim startRegions As New Stack(Of Integer)

        Do
            startIndex = text.IndexOf(REGION_START, lastIndex)
            endIndex = text.IndexOf(REGION_END, lastIndex)

            If startIndex = -1 AndAlso endIndex = -1 Then
                Exit Do
            End If

            If startIndex <> -1 AndAlso startIndex < endIndex Then
                startRegions.Push(startIndex)
                lastIndex = startIndex + 1
            Else
                ' Outline region ...
                Dim tempStartIndex As Integer = CInt(startRegions.Pop())
                selection.MoveToLineAndOffset(CalcLineNumber(text, tempStartIndex), CalcLineOffset(text, tempStartIndex))
                selection.MoveToLineAndOffset(CalcLineNumber(text, endIndex) + 1, 1, True)
                selection.OutlineSection()

                lastIndex = endIndex + 1
            End If
        Loop

        selection.StartOfDocument()
    End Sub

    Private Function CalcLineNumber(ByVal text As String, ByVal index As Integer) As Integer
        Dim lineNumber As Integer = 1
        Dim i As Integer = 0

        While i < index
            If text.Chars(i) = vbLf Then
                lineNumber += 1
                i += 1
            End If

            If text.Chars(i) = vbCr Then
                lineNumber += 1
                i += 1
                If text.Chars(i) = vbLf Then
                    i += 1 'Swallow the next vbLf
                End If
            End If

            i += 1
        End While

        Return lineNumber
    End Function

    Private Function CalcLineOffset(ByVal text As String, ByVal index As Integer) As Integer
        Dim offset As Integer = 1
        Dim i As Integer = index - 1

        'Count backwards from //#region to the previous line counting the white spaces
        Dim whiteSpaces = 1
        While i >= 0
            Dim chr As Char = text.Chars(i)
            If chr = vbCr Or chr = vbLf Then
                whiteSpaces = offset
                Exit While
            End If
            i -= 1
            offset += 1
        End While

        'Count forwards from //#region to the end of the region line
        i = index
        offset = 0
        Do
            Dim chr As Char = text.Chars(i)
            If chr = vbCr Or chr = vbLf Then
                Return whiteSpaces + offset
            End If
            offset += 1
            i += 1
        Loop

        Return whiteSpaces
    End Function

End Module

6
VS 2010更新了扩展框架,有人很友好地创建了一个名为“Visual Studio 2010 JavaScript Outlining”的代码折叠插件,位于此处:http://jsoutlining.codeplex.com/。 - Michael La Voie
2
我们能否使用C#编写宏而不是VB? - Second Person Shooter

7

这个功能现在已经内置于VS2017中:

//#region fold this up

//#endregion

// 和 # 之间的空格不影响代码。

我不知道这个功能是在哪个版本添加的,因为在版本更改日志中没有找到任何提及。但我能在 v15.7.3 版本中使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接