diff options
author | Guido van Rossum <guido@python.org> | 1999-04-19 16:23:15 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1999-04-19 16:23:15 (GMT) |
commit | 17c516eacb2051ff7f549bea077ebb9666ffab69 (patch) | |
tree | 4205b3c6b779871bd5e76e9d9e2cfaa8e7f1b361 /Tools | |
parent | e9af64c373c198f02be7de46527a4b444111bfdf (diff) | |
download | cpython-17c516eacb2051ff7f549bea077ebb9666ffab69.zip cpython-17c516eacb2051ff7f549bea077ebb9666ffab69.tar.gz cpython-17c516eacb2051ff7f549bea077ebb9666ffab69.tar.bz2 |
Tim Peters implements some of my wishes:
o Makes the tab key intelligently insert spaces when appropriate (see Help
list banter twixt David Ascher and me; idea stolen from every other editor
on earth <wink>).
o newline_and_indent_event trims trailing whitespace on the old line (pymode
and Codewright).
o newline_and_indent_event no longer fooled by trailing whitespace or
comment after ":" (pymode, PTUI).
o newline_and_indent_event now reduces the new line's indentation after
return, break, continue, raise and pass stmts (pymode).
The last two are easy to fool in the presence of strings & continuations,
but pymode requires Emacs's high-powered C parsing functions to avoid that
in finite time.
Diffstat (limited to 'Tools')
-rw-r--r-- | Tools/idle/AutoIndent.py | 71 |
1 files changed, 60 insertions, 11 deletions
diff --git a/Tools/idle/AutoIndent.py b/Tools/idle/AutoIndent.py index 3f1dfe1..4de7ad0 100644 --- a/Tools/idle/AutoIndent.py +++ b/Tools/idle/AutoIndent.py @@ -33,6 +33,20 @@ from Tkinter import TclError ###$ win <Alt-Key-6> ###$ unix <Alt-Key-6> +import re +_is_block_opener = re.compile(r":\s*(#.*)?$").search +_is_block_closer = re.compile(r""" + \s* + ( return + | break + | continue + | raise + | pass + ) + \b +""", re.VERBOSE).match +del re + class AutoIndent: menudefs = [ @@ -50,6 +64,7 @@ class AutoIndent: keydefs = { '<<smart-backspace>>': ['<Key-BackSpace>'], '<<newline-and-indent>>': ['<Key-Return>', '<KP_Enter>'], + '<<smart-indent>>': ['<Key-Tab>'] } windows_keydefs = { @@ -112,6 +127,36 @@ class AutoIndent: text.delete("insert - %d chars" % ndelete, "insert") return "break" + def smart_indent_event(self, event): + # if intraline selection: + # delete it + # elif multiline selection: + # do indent-region & return + # if tabs preferred: + # insert a tab + # else: + # insert spaces up to next higher multiple of indent level + text = self.text + try: + first = text.index("sel.first") + last = text.index("sel.last") + except TclError: + first = last = None + if first and last: + if index2line(first) != index2line(last): + return self.indent_region_event(event) + text.delete(first, last) + text.mark_set("insert", first) + if self.prefertabs: + pad = '\t' + else: + n = len(self.spaceindent) + prefix = text.get("insert linestart", "insert") + pad = ' ' * (n - len(prefix) % n) + text.insert("insert", pad) + text.see("insert") + return "break" + def newline_and_indent_event(self, event): text = self.text try: @@ -127,18 +172,18 @@ class AutoIndent: while i < n and line[i] in " \t": i = i+1 indent = line[:i] - lastchar = text.get("insert -1c") - if lastchar == ":": - if not indent: - if self.prefertabs: - indent = "\t" - else: - indent = self.spaceindent - elif indent[-1] == "\t": - indent = indent + "\t" - else: - indent = indent + self.spaceindent + # strip trailing whitespace + i = 0 + while line and line[-1] in " \t": + line = line[:-1] + i = i + 1 + if i: + text.delete("insert - %d chars" % i, "insert") text.insert("insert", "\n" + indent) + if _is_block_opener(line): + self.smart_indent_event(event) + elif indent and _is_block_closer(line) and line[-1:] != "\\": + self.smart_backspace_event(event) text.see("insert") return "break" @@ -242,3 +287,7 @@ def tabify(line, tabsize=8): else: i = len(line) return '\t' * (i/tabsize) + line[i:] + +# "line.col" -> line, as an int +def index2line(index): + return int(float(index)) |