summaryrefslogtreecommitdiffstats
path: root/Tools/idle
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1999-04-19 16:23:15 (GMT)
committerGuido van Rossum <guido@python.org>1999-04-19 16:23:15 (GMT)
commit17c516eacb2051ff7f549bea077ebb9666ffab69 (patch)
tree4205b3c6b779871bd5e76e9d9e2cfaa8e7f1b361 /Tools/idle
parente9af64c373c198f02be7de46527a4b444111bfdf (diff)
downloadcpython-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/idle')
-rw-r--r--Tools/idle/AutoIndent.py71
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))