rubberduck-vba / Rubberduck

Every programmer needs a rubberduck. COM add-in for the VBA & VB6 IDE (VBE).
https://rubberduckvba.com
GNU General Public License v3.0
1.92k stars 302 forks source link

VB6 SmartIndenter ignores VBE's `Tab Width` Option #1290

Closed ThunderFrame closed 8 years ago

ThunderFrame commented 8 years ago

VB6 SmartIndenter indents code in 4-space blocks, and 8-space blocks when indenting continued lines and Align continued strings and parameters setting set to Unchecked, regardless of the VBE's Tab Width setting.

I like to use 2-space tabs, but SmartIndenter ignores my setting, and reformats:

Option Explicit

Sub MySub1()
'VBE Tab width = 2
'With `Align continued strings and parameters` setting set to `Unchecked`
    Dim x1 As _
            Integer: _
            Dim x2 As _
            Integer
    ReDim x3(0) As _
            Integer
End Sub

Sub MySub2()
'VBE Tab width = 2
'With `Align continued strings and parameters` setting set to `Checked`
    Dim x1 As _
        Integer: _
        Dim x2 As _
            Integer
    ReDim x3(0) As _
          Integer
End Sub
retailcoder commented 8 years ago

"I like to use 2-space tabs"

Yeah, right! ...lol

That's rather surprising actually, especially given this code

This code fetches the value being used:

'
' Read the user's tab width from the registry
'
Function GetTabWidth() As Integer
Attribute GetTabWidth.VB_UserMemId = 1610612745

    Dim sKey As String, i As Integer

    On Error Resume Next

    'Are we in the Office or VB IDE?
    If IsOfficeVBE Then
        If Left(poVBE.Version, 1) = "6" Then
            'Excel 97
            sKey = "\Software\Microsoft\VBA\6.0\Common\"
        Else
            'Office 2000
            sKey = "\Software\Microsoft\VBA\7.0\Common\"
        End If
    Else
        'VB
        sKey = "\Software\Microsoft\VBA\Microsoft Visual Basic\"
    End If

    'Default to 4 spaces
    i = Val("&H" & Mid(funGetRegValue(HKEY_CURRENT_USER, sKey, "TabWidth", "0x000004"), 3))
    If i = 0 Then i = 4

    GetTabWidth = i

End Function

Can you confirm your TabWidth registry value reads a 2 there?

comintern commented 8 years ago

Looks like it. I don't have that registry key set in Excel 14. It should be triggering the On Error Resume Next and defaulting to 4.

ThunderFrame commented 8 years ago

It never gets the correct setting because IsOfficeVBE is trying to use poVBE.FullName which would seem to be a deprecated property of the VBE, so it tries to get the VB registry entry.

ThunderFrame commented 8 years ago

@retailcoder No, seriously, I do use 2-space tabs - I demonstrate code on a 4:3 projector, so 2-space tabs are more accommodating.

comintern commented 8 years ago

OK, so I added code in 89be80e that pulls the VBE registry setting if it's building a default IIndenterSettings. The issue is that IndentSpaces is also stored in rubberduck.config, and that setting will be used by the Indenter if rubberduck.config is present. Is it worthwhile to try keeping them in sync? Note that this would either require writing it back to the registry or not store the value in rubberduck.config.

Thoughts?

retailcoder commented 8 years ago

@comintern good point. The easiest would be to drop the setting and just use the VBE's config... but it wouldn't be very user-friendly. Best would be to keep them in sync, by writing the value to the registry when we save the settings, and then ...and then things get wild and messy when the setting is changed from the VBE options... I... I'm not sure what the best solution is.

retailcoder commented 8 years ago

One option could be to just ignore the registry value and only use it when figuring out the defaults.

comintern commented 8 years ago

@retailcoder that's basically what it does now. I would imagine that if the VBE setting had changed, it would have been done on purpose. I'm guessing it would take exactly one run of the indenter for a user to realize what happened because the Tab key wouldn't match how the code was now indented.

I'm kind of up in the air on this, but on the other hand, I would guess that not many people mess with the VBE setting much. One compromise would be to check the registry setting on loading and warn the user if they don't match.

ThunderFrame commented 8 years ago

VB6 Smart Indenter has a similar problem... If 2/or more developers have different SmartIndenter settings, and/or VBE settings, then re-indenting a code block will result in source control changes. Ideally, all users have identical settings for SmartIndenter and VBE, or, the indenting settings are saved with the project or module.

Vogel612 commented 8 years ago

@ThunderFrame usually I'd expect a configuration for Indentation (and other linting) settings to be versioned with the codebase or follow a company-wide standard.

This would mean that we should allow to export the SmartIndenter settings into a separate file.

ThunderFrame commented 8 years ago

@Vogel612 Agreed. It's the rarer situations where code is forked across multiple companies, or across departments that have different standards.

RubberDuck is undoubtedly going to increase the number of VBA projects on GitHub, so forks will increasingly end up in environments where the settings differ.

ThunderFrame commented 8 years ago

Just a thought, but most SmartIndenter settings are boolean values, so in theory you could store most of the settings as bit flags in a 32-bit annotation in the project/module VBA, or even in a VB attribute.

Eg.

'@SmartIndenter 32801