auto-indent Python code

Discussion Forums discussion auto-indent Python code

This topic contains 0 voices and has 13 replies.

Viewing 14 posts - 1 through 14 (of 14 total)
Author Posts
Author Posts
September 1, 2011 at 6:44 pm #5482

bhengh
Member

I would like to use Programmer’s Notepad to write Python apps. Is there anyway to get Programmer’s Notepad to auto-indent after a block statement?

September 1, 2011 at 7:14 pm #18053

CoDEmanX
Member

There is:

http://pnotepad.org/docs/howto/automatic_indentation

September 5, 2011 at 12:34 pm #18054

simon
Key Master

Indeed, and PyPN already comes with auto-indent support for Python, so you don’t need to write your own indenter.

September 5, 2011 at 1:27 pm #18055

CoDEmanX
Member

Here is the code:

PN_dirini.py

@indenter("python")
def python_indent(c, doc):
sci = scintilla.Scintilla(doc)
if c == 'n' or c == 'r':
pos = sci.CurrentPos
line = sci.LineFromPosition( pos )

lc = findPrevLineLastChar( pos, sci )

# If the previous line ended with a colon, then indent
if lc == ':':
indent = sci.GetLineIndentation( line )

# The DumbIndent system may already have indented this line...
previndent = sci.GetLineIndentation( line - 1 )
if indent == previndent or indent == 0:
indent += 4
sci.IndentLine( line, indent )

Next stable release should contain indenters for the most used languages out of the box, that’d be awesome!

September 7, 2011 at 10:20 am #18056

CoDEmanX
Member

Just came to my mind:

Python indent won’t work if you enter a comment after a colon!

Example:

if condition < 1: # check something
no auto-indent, as previous line's last character isn't a colon

On the other hand, it may indent for no reason, if a comment ends with a colon

call_function() # smiley (:
stupid auto-indent

September 7, 2011 at 1:45 pm #18057

simon
Key Master

Yes, there are a couple of bugs in the python indenter. Comments is one, and the other is it will keep indenting if you add extra lines below the indent point. i.e. this:

type: def monkey():

type: [enter]

type: [enter]

Would be happy to accept patches for any of these issues or other indenters!

September 7, 2011 at 3:43 pm #18058

CoDEmanX
Member

Lol, it bet it indents more and more ’cause it ignores whitespace in the findPrevLineLastChar function:

def findPrevLineLastChar(p, sci):
while p > 0:
p = p - 1
c = chr( sci.GetCharAt(p) )

# Look for a non-whitespace character ending the previous line.
if not c in ['n','r','t',' ']:
return c
return None

But simply removing the white-space check won’t work, nor dropping just the ‘t’. It should check whether the whole previous line is white-space or comment and go back further until it fetches the right character.

Or perhaps do a completely new algorithm. I made an indentation script for C++, which went all over the file and increased indentation on the next line after { (it kept track of the opening and closing braces). Dunno if this would work for Python, as there are no closing brackets or end-keyword…

February 5, 2012 at 7:09 am #18062

fongandrew
Member

In case anyone is stumbling on this via Google, here’s a fix for the comment and multiple indentation bugs. Edit PN_dirinit.py and change the python_indent function as follows:

import re

# Indention regex - look for colon, then optional spaces and comment
PY_INDENT_RE = re.compile(r':s*(#.*)?$')

@indenter("python")
def python_indent(c, doc):
sci = scintilla.Scintilla(doc)
if c == 'n' or c == 'r':
pos = sci.CurrentPos
line = sci.LineFromPosition( pos )
prev_line = sci.GetLine(line - 1)

# If the previous line matches regular expression above, then indent
if PY_INDENT_RE.search(prev_line):
indent = sci.GetLineIndentation( line )

# The DumbIndent system may already have indented this line...
previndent = sci.GetLineIndentation( line - 1 )
if indent == previndent or indent == 0:
indent += 4
sci.IndentLine( line, indent )

February 18, 2012 at 3:58 am #18064

CoDEmanX
Member

i just tried your code but it doesn’t seem to change anything, still indenting everything without exception if previous line ends with a colon.

Do i have to delete a cached version of the init.py script somehow? But where would it be located at?

February 20, 2012 at 10:41 am #18065

simon
Key Master

If you have PN installed (rather than portable) then you might need to edit the script using PN running as administrator. Otherwise Windows Vista/7 will redirect your save to a “special” folder where PN won’t see it when compiling scripts.

February 22, 2012 at 3:23 am #18066

CoDEmanX
Member

Did that already, i guess the regex just doesn’t work as it should. With PN regex search, it still matches colons in comments if it’s the last character or if it’s followed by white-space only.

February 23, 2012 at 12:18 am #18067

NickDMax
Member

try: PY_INDENT_RE = re.compile(r'^[^#:]*:[^"']*$')

the basic logic is: find a colon that is not in a comment, and then ensure it is not in a string or doc comment.

February 23, 2012 at 4:34 am #18068

CoDEmanX
Member

great! it’s doing indentation for code-colons and nothing for comment-colons even if it’s at the very end

however, it indents code-colons in “”" comments “”", but that’s not much of a problem as i’m mostly using single line #comments!

"""
for x in y:
indented!

exec() # foo: bar
not indented!
"""

February 27, 2012 at 2:48 pm #18069

simon
Key Master

Unfortunately python’s regexs aren’t guaranteed to match the ones PN uses. Test them with python itself to be sure of the one you’re using.

Viewing 14 posts - 1 through 14 (of 14 total)

You must be logged in to reply to this topic.