Search code examples
sublimetext3sublimetext2sublimetextsublime-text-plugin

Indentation defined via preferences and via GUI


I'm trying to understand how ST's indentation defined via "transtate_tabs_to_spaces" is different from indentation defined via GUI (bottom right corner of the window).

Step 1. Add this preferences:

"draw_white_space": "all",
"translate_tabs_to_spaces": true,

Step 2. Ensure you have this:

enter image description here

And not this:

enter image description here

Step 3. Create new file inside ST with single line and press Ctrl-] (on Windows). It will be indented with 4 spaces - exactly as the user expected:

enter image description here

Step 4. Now, turn off the check mark in front of Indent Using Spaces in the GUI:

enter image description here

And then, reproduce step 3. You will see, that text was indented with a tab, instead of spaces, despite you still have "translate_tabs_to_spaces": true in your preferences.

enter image description here

So, it looks that ST have 2 ways to control indentation - via translate_tabs_to_spaces setting and via GUI, and GUI have precedence.

  • Is everything correct in my description?

  • And is there a way to reliably enforce spaces, which will not be overwritten by GUI? (For example, it could be used expand_tabs command on save, but probably there exists another ways to handle this issue?)


Solution

  • Your premise is essentially correct, but there is something happening behind the scenes that you may not be expecting.

    The setting translate_tabs_to_spaces tells Sublime that whenever anything tries to insert a literal tab character, it should expand the tab to some number of spaces instead, with the number of spaces coming from the tab_size setting.

    There is only one setting that controls this, but the menu item that you see in the indentation menu (either from the button in the status line or in View > Indentation in the main men) uses the toggle_setting command.

    For example if you use View Package File from the command palette to view Default/Indentation.sublime-menu (the definition for the menu that pops up in the status bar), the first entry in the menu item is this one (reformatted here to not be one long line):

    { 
        "command": "toggle_setting", 
        "args": {"setting": "translate_tabs_to_spaces"}, 
        "caption": "Indent Using Spaces", 
        "checkbox": true 
    },
    

    The toggle_setting command changes the setting in a view specific way; that is, it modifies the setting in the buffer that you're currently editing, but not in your actual preferences file.

    If you consult the documentation on settings, you can see that buffer specific settings are the last item in the list of potential places for settings to come from, which makes them take precedence over everything else. A buffer specific setting only persists while you have the file open; if you close the file and re-open it, the original preference will re-assert itself.

    You can verify this in both of your cases above by opening the Sublime console with Ctrl+` or View > Show Console and entering the following python command while you have each of the two files focused:

    view.settings().get("translate_tabs_to_spaces")
    

    If you do this, you'll see that it returns True when the checkbox is checked and False when it's not.

    Generally speaking the biggest vector for problems when it comes to the translate_tabs_to_spaces setting is the detect_indentation setting, which defaults to true unless you turn it off.

    When that setting is turned on, every time a file is loaded Sublime automatically runs the command associated with the Guess Settings From Buffer command in the indentation menu. That can cause the indent settings you've chosen to change from what you expected them to be.

    Realistically, with the appropriate settings set it should work the way you want as long as you don't purposefully change the setting by using the menu item.

    In theory a simple plugin could be employed to alter what that menu item does so that it would toggle the setting globally instead of in the current buffer only, but in that case every other file you have loaded would suddenly have it's setting changed, which is arguably much worse.