Tim Peters smart.patch:

EditorWindow.py:

+ Added get_tabwidth & set_tabwidth "virtual text" methods, that get/set the
widget's view of what a tab means.

+ Moved TK_TABWIDTH_DEFAULT here from AutoIndent.

+ Renamed Mark's get_selection_index to get_selection_indices (sorry, Mark,
but the name was plain wrong <wink>).

FormatParagraph.py:  renamed use of get_selection_index.

AutoIndent.py:

+ Moved TK_TABWIDTH_DEFAULT to EditorWindow.

+ Rewrote set_indentation_params to use new VTW get/set_tabwidth methods.

+ Changed smart_backspace_event to delete whitespace back to closest
preceding virtual tab stop or real character (note that this may require
inserting characters if backspacing over a tab!).

+ Nuked almost references to the selection tag, in favor of using
get_selection_indices.  The sole exception is in set_region, for which no
"set_selection" abstraction has yet been agreed upon.

+ Had too much fun using the spiffy new features of the format-paragraph
cmd.
diff --git a/Tools/idle/EditorWindow.py b/Tools/idle/EditorWindow.py
index bc4edde..0f23b15 100644
--- a/Tools/idle/EditorWindow.py
+++ b/Tools/idle/EditorWindow.py
@@ -9,6 +9,9 @@
 import idlever
 import WindowList
 
+# The default tab setting for a Text widget, in average-width characters.
+TK_TABWIDTH_DEFAULT = 8
+
 # File menu
 
 #$ event <<open-module>>
@@ -599,7 +602,7 @@
 
     # If a selection is defined in the text widget, return (start,
     # end) as Tkinter text indices, otherwise return (None, None)
-    def get_selection_index(self):
+    def get_selection_indices(self):
         try:
             first = self.text.index("sel.first")
             last = self.text.index("sel.last")
@@ -607,6 +610,23 @@
         except TclError:
             return None, None
 
+    # Return the text widget's current view of what a tab stop means
+    # (equivalent width in spaces).
+
+    def get_tabwidth(self):
+        current = self.text['tabs'] or TK_TABWIDTH_DEFAULT
+        return int(current)
+
+    # Set the text widget's current view of what a tab stop means.
+
+    def set_tabwidth(self, newtabwidth):
+        text = self.text
+        if self.get_tabwidth() != newtabwidth:
+            pixels = text.tk.call("font", "measure", text["font"],
+                                  "-displayof", text.master,
+                                  "n" * newtabwith)
+            text.configure(tabs=pixels)
+
 def prepstr(s):
     # Helper to extract the underscore from a string, e.g.
     # prepstr("Co_py") returns (2, "Copy").