Temporary change of tab



  • Is there a way to temporarily change the tab size in just the current document? Four space tabs is fine but sometimes log files (in a variety of extensions) are in 8 space tabs so I just want to change for that document whilst it’s open.



  • @Rob-Nicholson-1

    Is there a way to temporarily change the tab size in just the current document?

    The general answer would be NO, as this setting is bound to the scintilla
    instance and therefore affects all documents within the same instance.
    But there is a way to “fake” it but that involves a scripting language plugin.
    If you want to/can go this way let us know.



  • @Rob-Nicholson-1 ,

    sometimes log files (in a variety of extensions) are in 8 space tabs

    If all of the 8-space logs were all part of the same builtin syntax-highlighting lexer (entry in the Language menu), then it wouldn’t matter if there were many extensions or just one. However, there isn’t really a logfile builtin lexer, and even if you created a UDL, the UDL don’t have their own tab settings – they just use the default.

    Thus, the only way I know to accomplish your task is with a scripting language.

    If you want a manual toggle, you could do it by sending the SCI_SETTABWIDTH message to the active scintilla editor component. But you’d have to be willing to install either the NppExec or PythonScript or LuaScript plugin (from Plugins Admin), or externally through Perl’s Win32::Mechanize::NotepadPlusPlus module.

    As a brief intro,

    • in NppExec (which is a Notepad+±specific “shell” or “batch” language), you would define two scripts, one would be named SetTab8 and run sci_sendmsg SCI_SETTABWIDTH 8; the other would be named SetTab4 or similar, and would run sci_sendmsg SCI_SETTABWIDTH 4
    • in PythonScript, you could do it with two scripts, named similarly, using the syntax editor.setTabWidth(n) where n is either 4 or 8. Or you could get a little fancier and do something like n = 12 - editor.getTabWidth(); editor.setTabWidth(n); which would allow one script to toggle between 4 and 8. Or even fancier, and have it look at the active file’s type or extension to decide whether to set it to 4 or 8 or leave it unchanged.
    • I don’t use LuaScript, but the syntax would be similar
    • In Perl, it would use nearly the same syntax as PythonScript, except using -> instead of .

    I see that @Ekopalypse chimed in with the short version of this while I was typing. :-) That’s what I get for being “the wordy one”. ;-)

    Anyway, if you want to do it with a scripting language, let us know. If you tell us which language you’d prefer to use, we can help you through the steps of installing the plugin, adding the script(s), and getting them assigned to keyboard shortcuts.



  • This thread is semi-related: https://community.notepad-plus-plus.org/topic/17484/macro-to-switch-indentation

    I have some older Pythonscript code (at least I think it is mine and not copied from someone else here on the forum – also important is that it seems to still work!) that will allow tab/space settings to be altered for only the active file it is run upon.

    It is called TabKeyInsertsTabCharsOrSpacesForCurrentFileTab.py and that is perhaps the longest script name I’ve ever used. A habit I picked up from people on the forum is to name some of the variables with the capital letters in the script name, thus the crazy looking vars with TKITCOSFCFT in them.

    Here’s the script:

    # -*- coding: utf-8 -*-
    
    from Npp import editor, notepad
    
    def TKITCOSFCFT__buffer_was_activated(args):
        # need to .setUseTabs() and .setTabWidth() whenever tab is switched because when a tab is switched,
        #  N++ will internally reset to configured settings for the type of file the activated buffer is
        cfn = notepad.getCurrentFilename()
        if cfn in TKITCOSFCFT__dict:
            (use_tabs, tab_width) = TKITCOSFCFT__dict[cfn]
            editor.setUseTabs(use_tabs)
            editor.setTabWidth(tab_width)
    
    try:
        TKITCOSFCFT__dict
    except NameError:
        TKITCOSFCFT__dict = {}
        def TKITCOSFCFT__callback_npp_BUFFERACTIVATED(args): TKITCOSFCFT__buffer_was_activated(args)
        notepad.callback(TKITCOSFCFT__callback_npp_BUFFERACTIVATED, [NOTIFICATION.BUFFERACTIVATED])
    
    def TKITCOSFCFT__main():
        cfn = notepad.getCurrentFilename()
        if cfn in TKITCOSFCFT__dict:
            (use_tabs, tab_width) = TKITCOSFCFT__dict[cfn]
        else:
            use_tabs = editor.getUseTabs()
            tab_width = editor.getTabWidth()
        if use_tabs:
            msg = 'Insert TAB character with Tab key hit.\r\nDisplay equivalent for 1 tab is {tw} spaces.'.format(tw=tab_width)
        else:
            msg = 'Insert {tw} SPACE characters per Tab key hit.'.format(tw=tab_width)
        if notepad.messageBox('Current setting for this file:\r\n\r\n' + msg + '\r\n\r\nChange this setting?', '', MESSAGEBOXFLAGS.YESNO) == MESSAGEBOXFLAGS.RESULTYES:
            use_tabs = False
            if notepad.messageBox('Insert actual TAB characters when Tab key hit?', '', MESSAGEBOXFLAGS.YESNO) == MESSAGEBOXFLAGS.RESULTYES:
                use_tabs = True
            while True:
                user_input = notepad.prompt('How many spaces should one Tab key represent?', '', str(tab_width))
                try:
                    user_input = int(user_input)
                except:
                    continue
                if user_input > 0:
                    tab_width = user_input
                    editor.setUseTabs(use_tabs)
                    editor.setTabWidth(tab_width)
                    TKITCOSFCFT__dict[cfn] = (use_tabs, tab_width)
                    break
    
    TKITCOSFCFT__main()
    


  • @Alan-Kilborn said in Temporary change of tab:

    A habit I picked up from people on the forum

    To be honest, I’ve never understood the creation of such variable names.
    It makes, at least for me, it more difficult to read/understand.

    To quote from “Zen of python”: Readability counts

    Why do you think this is a good way of doing it this way?
    There must be a goal behind it, right?



  • @Ekopalypse said in Temporary change of tab:

    Why do you think this is a good way of doing it this way?
    There must be a goal behind it, right?

    In “normal” Python, one runs a program, via command line “python foo.py”. That program ends; poof, variables gone. Even if that program stays running and one does a “python bar.py” in a different command window, “foo” and “bar” can’t (usually) know each other’s variables.

    In Notepad++ Pythonscript Python, since it doesn’t end until Notepad++ is closed, things from previously run scripts “hang around”. So there’s a possibility (perhaps slight) of a later-run script using something leftover from an earlier script, leading to odd results. I know this has happened to me a few times; again, fairly rare.

    So if you notice, I just do this special prefixing for things that would remain known, not everything. And like I said, this is “old” code; my newer way of doing things is by putting most everything into a “class” so a lot of this type of prefixing becomes unnecessary. When using a class, it needs to be given a name, so I do a similar method I guess to keep it short when the name otherwise doesn’t mean much.

    Probably my scripting framework for the “class” based approach isn’t ideal, either. Feel free when you see it to comment on what is awkward or could be better. So far it seems to be working okay for me for these little Pythonscripts.



  • @Alan-Kilborn said in Temporary change of tab:

    In Notepad++ Pythonscript Python, since it doesn’t end until Notepad++ is closed, things from previously run scripts “hang around”.

    I knew there is an idea behind

    my newer way of doing things is by putting most everything into a “class”

    Yes, also my preferred way to keep the scope of the script tight.

    So far it seems to be working okay for me

    and this is what counts.


Log in to reply