6

I normally write code with tabs but many python libraries use spaces. Is there any way for Notepad++ to automatically detect how the file is formatted and have it automatically switch to using spaces when the file is already formatted that way?

BTW, I know there was already an SO question on how to change Notepad++'s tab format. But it would be better if it automatically changed based on the current file's formatting.

Community
  • 1
  • 1
speedplane
  • 14,130
  • 14
  • 78
  • 128

3 Answers3

7

If you install the "Python Script" plugin for Notepad++, you can write code to automatically switch between tabs and spaces.

Here's how:

  1. In the menu: Plugins -> Python Script -> Configuration, and set Initialization to ATSTARTUP. When Notepad++ starts, the startup.py script will run.

  2. Find startup.py and edit it. On my PC its path is c:\Program Files\Notepad++\plugins\PythonScript\scripts\startup.py, add the following code to startup.py.

The function buffer_active() is called every time when you switch tab, and guess_tab() checks whether the text is using tab indent or not. You can show the Python console to debug the code.

def guess_tab(text):
    count = 0
    for line in text.split("\n"):
        indents = line[:len(line)-len(line.lstrip())]
        if "\t" in indents:
            count += 1
    if count > 5: 
        return True
    else:
        return False

def buffer_active(arg):
    editor.setBackSpaceUnIndents(True)
    use_tab = guess_tab(editor.getText())
    editor.setUseTabs(use_tab)
    sys.stderr.write( "setUseTabs %s\n" % use_tab )

notepad.clearCallbacks([NOTIFICATION.BUFFERACTIVATED])    
notepad.callback(buffer_active, [NOTIFICATION.BUFFERACTIVATED])

This is only an example, feel free to make guess_tab() better yourself, maybe use a global dict to cache the result and speedup the callback function.

speedplane
  • 14,130
  • 14
  • 78
  • 128
HYRY
  • 83,863
  • 22
  • 167
  • 176
  • Doesn't seem to be working. This may be a problem with PythonScript. I don't see anything printed in the console when I switch tabs. Shouldn't I see setUseTabs? – speedplane Apr 12 '12 at 05:13
  • I've just tried it, and it works perfectly! speedplane: change "if count > 5" to "if count > 0".. maybe you've tried it on files with less than 6 lines with tabs in front of it? @HYRY: why don't you post it over here? https://sourceforge.net/projects/npppythonscript/forums/forum/1199074 ... it's a very handy script! – ufo Jun 02 '12 at 13:49
  • Got it working! I had to re-install the Python Script plugin from the plugin manager. – speedplane Jun 18 '12 at 11:35
3

Here is an improved version based on HYRY's answer :

  • Works on the startup tab (when you launch notepad++ to open a file)
  • Doesn't need a minimal amount of rows to trigger indentation detection. Indentation guess is based on the first encountered indented line.
  • Keeps indentation defaults when indentation cannot be detected
  • Very efficient, doesn't slow down Notepad++ when opening big files (tested on a 220 MB file, indentation detection takes only < 300 ms)

Available for download here : https://gist.github.com/vincepare/8a204172d959defb2122

import re
import time

def indent_guess_tab(text):
    for line in text.split("\n"):
        pattern = re.compile("^( {4,}|\t)")
        match = pattern.match(line)
        if (match):
            return True if ("\t" in match.group(1)) else False

def indent_auto_detect(arg):
    start = time.clock()

    # Get text sample
    maxLen = 500000
    len = editor.getTextLength()
    len = len if len < maxLen else maxLen
    sample = editor.getTextRange(0, len)

    # Indent set
    current_use_tab = editor.getUseTabs()
    use_tab = indent_guess_tab(sample)

    if (use_tab != None and use_tab != current_use_tab):
        console.write("Indent use tab switch (%s => %s)\n" % (current_use_tab, use_tab))
        editor.setUseTabs(use_tab)

    end = time.clock()
    console.write("Indentation detection took %s ms\n" % (round((end-start)*1000, 3)))

notepad.clearCallbacks([NOTIFICATION.BUFFERACTIVATED, NOTIFICATION.READY])    
notepad.callback(indent_auto_detect, [NOTIFICATION.BUFFERACTIVATED])
notepad.callback(indent_auto_detect, [NOTIFICATION.READY])
console.write("Automatic indentation detection started\n")
indent_auto_detect(None)
Vince
  • 2,844
  • 1
  • 25
  • 26
  • 1
    And here's another one that also detects the number of spaces (and is much shorter): https://gist.github.com/patstew/8dc8a4c0b816e2f33204e3e15cd5497e – patstew Mar 08 '17 at 13:04
1

Nope!

You can always just change them (to tabs, of course) to suit your needs with Replace All (    , \t) in extended mode.

Ry-
  • 199,309
  • 51
  • 404
  • 420
  • 2
    Or **TextFX > TextFX Edit > Leading spaces to tabs or tabs to spaces**, but I question the efficacy of Notepad++ plugins sometimes. – BoltClock Apr 03 '12 at 02:06
  • @BoltClock: Ah, thanks. I'm usually afraid to touch the TextFX menu :) – Ry- Apr 03 '12 at 02:07