在Visual Studio解决方案中“制表符化”所有文件?

36

在编辑器中有一个“tabify”命令:

编辑 > 高级 > Tabify选定行

(而且Power Tools 2010也提供了每个文件的此功能),但是是否有办法对解决方案中的所有代码文件执行此操作?

ReSharper中有一个“清理代码”命令,但我在那里找到的唯一半适合的选项是运行格式化程序以应用于所有文件,这比我想要的要多(我不想运行完整的格式化,只想进行制表符调整)。


1
嘿,关于这个问题有什么新的消息吗? - brokenisfixed
有一个基于正则表达式的好方法:https://dev59.com/z2gt5IYBdhLWcg3wvgBu - Al Kepp
可能是整个解决方案中取消制表符的方法的重复问题。 - Al Kepp
这个答案对我帮助很大: https://dev59.com/YI_ea4cB1Zd3GeqPUupU - Andrii Viazovskyi
6个回答

16

如果你已经添加了Microsoft Productivity Power tools扩展程序(如果还没有,我建议你这样做),它会增加一个选项来将文件标签化。这不适用于解决方案中的所有文件,而是在每个文件上编辑时针对每个文件提示。虽然不完全符合你的要求,但是有所帮助。

此外,你可以尝试将IDE编辑器设置为使用制表符,然后进行菜单-编辑-高级格式化文档(CTRL+E,D)。这将用制表符替换一组制表符长度的空格,并且这应该可以通过宏脚本应用于解决方案中的所有文件。


请问您能否详细说明如何在VS2013中使用Microsoft Productivity Power Tools进行Tabify操作?谢谢。 - leoly
当编辑窗口检测到混合制表符和空格时,它会在顶部提供一个“提示栏”,并提供将文件转换为制表符或空格的选项。如果我没记错的话,这会在加载和保存时发生,我不认为还有其他方法来强制执行文件操作。如果您只想要制表符/空格修复,此扩展程序可以实现:https://visualstudiogallery.msdn.microsoft.com/91a3f8ae-3152-438a-b5fc-fb37878dd007 - Pete Stensønes
1
是的,我已经找到了提示栏。然而,似乎没有办法将整个解决方案的文件进行分页。无论如何,再次感谢。 - leoly
我不明白为什么Power Tools一直要求我在同一个文件中进行制表符处理。 - Carlos ABS

5
该请求包含指向IDE宏的链接,可完成以下工作:
http://blogs.msdn.com/b/kevinpilchbisson/archive/2004/05/17/133371.aspx
http://web.archive.org/web/20090217094033/http://chriseargle.com/post/Format-Solution.aspx

这里是一个Visual Studio宏的示例代码,可以自动格式化打开解决方案中所有*.cs、*.h、*.cpp和*.hpp文件,其中包括将空格转换为制表符(具体取决于您在“工具”>“选项”>“文本编辑器”>特定语言或“所有语言”>标签中的Tab设置):

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics

Public Module ConvertTabsToSpaces

    Public Sub FormatSolution()
        Dim sol As Solution = DTE.Solution
        For i As Integer = 1 To sol.Projects.Count
            FormatProject(sol.Projects.Item(i))
        Next
    End Sub

    Private Sub FormatProject(ByVal proj As Project)
        If Not proj.ProjectItems Is Nothing Then
            For i As Integer = 1 To proj.ProjectItems.Count
                FormatProjectItem(proj.ProjectItems.Item(i))
            Next
        End If
    End Sub

    Private Sub FormatProjectItem(ByVal projectItem As ProjectItem)
        If projectItem.Kind = Constants.vsProjectItemKindPhysicalFile Then
            If projectItem.Name.LastIndexOf(".cs") = projectItem.Name.Length - 3 Then
                Dim window As Window = projectItem.Open(Constants.vsViewKindCode)
                window.Activate()
                projectItem.Document.DTE.ExecuteCommand("Edit.FormatDocument")
                window.Close(vsSaveChanges.vsSaveChangesYes)
            ElseIf ((projectItem.Name.LastIndexOf(".cpp") = projectItem.Name.Length - 4) OrElse (projectItem.Name.LastIndexOf(".hpp") = projectItem.Name.Length - 4) OrElse (projectItem.Name.LastIndexOf(".h") = projectItem.Name.Length - 2)) Then
                Dim window As Window = projectItem.Open(Constants.vsViewKindCode)
                window.Activate()
                projectItem.Document.DTE.ExecuteCommand("Edit.SelectAll")
                projectItem.Document.DTE.ExecuteCommand("Edit.FormatSelection")
                window.Close(vsSaveChanges.vsSaveChangesYes)
            End If
        End If

        'Be sure to format all of the ProjectItems.
        If Not projectItem.ProjectItems Is Nothing Then
            For i As Integer = 1 To projectItem.ProjectItems.Count
                FormatProjectItem(projectItem.ProjectItems.Item(i))
            Next
        End If

        'Format the SubProject if it exists.
        If Not projectItem.SubProject Is Nothing Then
            FormatProject(projectItem.SubProject)
        End If
    End Sub

End Module

操作步骤(适用于Visual Studio 2005,新版本类似):

  1. 打开Visual Studio
  2. 选择"工具" > "宏" > "宏IDE..."
  3. 右键点击"MyMacros" > "添加" > "添加新项..."
  4. 选择"模块"
  5. 在名称字段中输入"ConvertSpacesToTabs"(不带引号)
  6. 单击"添加"
  7. 将新模块的内容替换为上述代码
  8. 单击"保存"
  9. 关闭宏IDE
  10. 选择"工具" > "宏" > "宏浏览器"
  11. 展开"MyMacros" > "ConvertSpacesToTabs"
  12. 双击"FormatSolution"
  13. 等待宏执行完毕

编辑
我更新了代码,使用Siegmund Frenzel的代码来支持*.h、*.cpp和*.hpp文件,请参见以下链接: https://dev59.com/v1HTa4cB1Zd3GeqPPCrN#14766393


+1 给 Chris Eargle 的链接。他的宏做了 OP 所要求的事情。 - Adam Caviness
Chris Eargle 的链接现在已经失效了。 - William
@William,我添加了一个页面存档的链接。谢谢。 - Rami A.
1
@AndrewArnold,我更新了答案,包括源代码和说明。 - Rami A.
用户不是要求将空格转换为制表符吗,而不是将制表符转换为空格(“tabify”而不是“untabify”)? - thecoolmacdude
显示剩余2条评论

2
据我所知,“Tabify”的作用是将“ ”(4个空格)替换为制表符,它不会改变格式或其他任何内容。
虽然我建议使用文档格式化,但“tabification”可以通过自定义应用程序轻松完成,该应用程序将在您想要的所有文件上模仿相同的操作。
希望这可以帮助您!

1
您可以在解决方案的所有源代码上运行以下代码 Regex.Replace (sInput, "4_spaces", "\t");,它将以 Power Tools 相同的方式制表符化源代码。请将代码中的 "4_spaces" 更改为实际空格,因为 StackOverflow 会删除多个空格。 - brokenisfixed
1
需要检查一下,但可能存在一些边缘情况,比如自定义缩进可能需要特殊处理,全局搜索和替换可能无法正常工作。但还是感谢您的提示。 - Borek Bernard

2

有一个使用dotnet CLI的新方法:

  1. 通过运行以下命令安装dotnet format
    dotnet tool install -g dotnet-format
  2. 用以下命令行运行它,将SolutionFile.sln替换为您的解决方案文件的路径:
    dotnet format SolutionFile.sln

.editorconfigindent_style将用于确定代码是否使用制表符或空格。


1

对于vs2010,您可以使用以下查找和替换(此示例用于将制表符替换为4个空格)。

在查找框中输入:^{ *}^{空格*} 制表符)

在替换框中输入 \1\1 空格空格空格空格)

选中条件框并设置为正则表达式。 较新版本的vs使用不同的正则表达式语法,但应该可以做到相同效果。

更新 对于vb文件,执行一次即可成功,但对于resx文件需要多次执行,因此,根据文件类型的不同,您可能需要执行多次操作...


0

从Visual Studio 2013开始,宏已被移除(新版本的宏使用JavaScript而不是VBScript),因此要使Rami A.的答案在Visual Studio 2019中工作:

  1. 下载并安装Visual Commander扩展程序
  2. 扩展程序 > VCmd > 编辑宏
  3. 命名它
  4. 粘贴以下代码。我不得不对其进行一些更改,以使代码与Visual Commander配合工作。我还更改了它制表符的文件扩展名为.cs.aspx.ascx,因此如果需要C++/其他文件扩展名,请更改这些内容。
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics
Imports Microsoft.VisualStudio.Shell
Imports VisualCommanderExt

Public Class ConvertTabsToSpaces
    Implements ICommand
    Sub Run(DTE As DTE2, package As Package) Implements ICommand.Run
        Dim sol As Solution = dte.Solution
        For i As Integer = 1 To sol.Projects.Count
            FormatProject(sol.Projects.Item(i))
        Next
    End Sub

    Private Sub FormatProject(ByVal proj As Project)
        If Not proj.ProjectItems Is Nothing Then
            For i As Integer = 1 To proj.ProjectItems.Count
                FormatProjectItem(proj.ProjectItems.Item(i))
            Next
        End If
    End Sub

    Private Sub FormatProjectItem(ByVal projectItem As ProjectItem)
        If projectItem.Kind = Constants.vsProjectItemKindPhysicalFile Then
            If (projectItem.Name.LastIndexOf(".cs") = projectItem.Name.Length - 3 OrElse (projectItem.Name.LastIndexOf(".aspx") = projectItem.Name.Length - 5 OrElse (projectItem.Name.LastIndexOf(".ascx") = projectItem.Name.Length - 5))) Then
                Dim window As Window = projectItem.Open(Constants.vsViewKindCode)
                window.Activate()

                Try
                    projectItem.Document.DTE.ExecuteCommand("Edit.RemoveAndSort")
                Catch
                    ' Do nothing
                End Try

                Try
                    projectItem.Document.DTE.ExecuteCommand("Edit.SelectAll")
                    projectItem.Document.DTE.ExecuteCommand("Edit.FormatSelection")
                Catch
                    ' Do nothing
                End Try

                window.Close(vsSaveChanges.vsSaveChangesYes)
            End If
        End If

        'Be sure to format all of the ProjectItems
        If Not projectItem.ProjectItems Is Nothing Then
            For i As Integer = 1 To projectItem.ProjectItems.Count
                FormatProjectItem(projectItem.ProjectItems.Item(i))
            Next
        End If

        'Format the SubProject if it exists
        If Not projectItem.SubProject Is Nothing Then
            FormatProject(projectItem.SubProject)
        End If
    End Sub

End Class
  1. 保存
  2. 运行
  3. 为了将来使用而保存:扩展 > VCmd > 另存宏命令 > 命名 > 保存

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