diff options
Diffstat (limited to 'Lib/idlelib/EditorWindow.py')
| -rw-r--r-- | Lib/idlelib/EditorWindow.py | 210 |
1 files changed, 133 insertions, 77 deletions
diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py index 259c7f3..7cc69cb 100644 --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -6,22 +6,32 @@ from itertools import count from Tkinter import * import tkSimpleDialog import tkMessageBox -from MultiCall import MultiCallCreator - import webbrowser -import idlever -import WindowList -import SearchDialog -import GrepDialog -import ReplaceDialog -import PyParse -from configHandler import idleConf -import aboutDialog, textView, configDialog -import macosxSupport + +from idlelib.MultiCall import MultiCallCreator +from idlelib import idlever +from idlelib import WindowList +from idlelib import SearchDialog +from idlelib import GrepDialog +from idlelib import ReplaceDialog +from idlelib import PyParse +from idlelib.configHandler import idleConf +from idlelib import aboutDialog, textView, configDialog +from idlelib import macosxSupport # The default tab setting for a Text widget, in average-width characters. TK_TABWIDTH_DEFAULT = 8 +def _sphinx_version(): + "Format sys.version_info to produce the Sphinx version string used to install the chm docs" + major, minor, micro, level, serial = sys.version_info + release = '%s%s' % (major, minor) + if micro: + release += '%s' % micro + if level != 'final': + release += '%s%s' % (level[0], serial) + return release + def _find_module(fullname, path=None): """Version of imp.find_module() that handles hierarchical module names""" @@ -40,13 +50,13 @@ def _find_module(fullname, path=None): return file, filename, descr class EditorWindow(object): - from Percolator import Percolator - from ColorDelegator import ColorDelegator - from UndoDelegator import UndoDelegator - from IOBinding import IOBinding, filesystemencoding, encoding - import Bindings + from idlelib.Percolator import Percolator + from idlelib.ColorDelegator import ColorDelegator + from idlelib.UndoDelegator import UndoDelegator + from idlelib.IOBinding import IOBinding, filesystemencoding, encoding + from idlelib import Bindings from Tkinter import Toplevel - from MultiStatusBar import MultiStatusBar + from idlelib.MultiStatusBar import MultiStatusBar help_url = None @@ -64,15 +74,13 @@ class EditorWindow(object): 'Doc', 'index.html') elif sys.platform[:3] == 'win': chmfile = os.path.join(sys.prefix, 'Doc', - 'Python%d%d.chm' % sys.version_info[:2]) + 'Python%s.chm' % _sphinx_version()) if os.path.isfile(chmfile): dochome = chmfile - elif macosxSupport.runningAsOSXApp(): # documentation is stored inside the python framework dochome = os.path.join(sys.prefix, 'Resources/English.lproj/Documentation/index.html') - dochome = os.path.normpath(dochome) if os.path.isfile(dochome): EditorWindow.help_url = dochome @@ -80,7 +88,7 @@ class EditorWindow(object): # Safari requires real file:-URLs EditorWindow.help_url = 'file://' + EditorWindow.help_url else: - EditorWindow.help_url = "http://www.python.org/doc/current" + EditorWindow.help_url = "http://docs.python.org/%d.%d" % sys.version_info[:2] currentTheme=idleConf.CurrentTheme() self.flist = flist root = root or flist.root @@ -102,23 +110,21 @@ class EditorWindow(object): self.top.instance_dict = {} self.recent_files_path = os.path.join(idleConf.GetUserCfgDir(), 'recent-files.lst') - self.vbar = vbar = Scrollbar(top, name='vbar') self.text_frame = text_frame = Frame(top) + self.vbar = vbar = Scrollbar(text_frame, name='vbar') self.width = idleConf.GetOption('main','EditorWindow','width') - self.text = text = MultiCallCreator(Text)( - text_frame, name='text', padx=5, wrap='none', - foreground=idleConf.GetHighlight(currentTheme, - 'normal',fgBg='fg'), - background=idleConf.GetHighlight(currentTheme, - 'normal',fgBg='bg'), - highlightcolor=idleConf.GetHighlight(currentTheme, - 'hilite',fgBg='fg'), - highlightbackground=idleConf.GetHighlight(currentTheme, - 'hilite',fgBg='bg'), - insertbackground=idleConf.GetHighlight(currentTheme, - 'cursor',fgBg='fg'), - width=self.width, - height=idleConf.GetOption('main','EditorWindow','height') ) + text_options = { + 'name': 'text', + 'padx': 5, + 'wrap': 'none', + 'width': self.width, + 'height': idleConf.GetOption('main', 'EditorWindow', 'height')} + if TkVersion >= 8.5: + # Starting with tk 8.5 we have to set the new tabstyle option + # to 'wordprocessor' to achieve the same display of tabs as in + # older tk versions. + text_options['tabstyle'] = 'wordprocessor' + self.text = text = MultiCallCreator(Text)(text_frame, **text_options) self.top.focused_widget = self.text self.createmenubar() @@ -163,6 +169,7 @@ class EditorWindow(object): text.bind("<Right>", self.move_at_edge_if_selection(1)) text.bind("<<del-word-left>>", self.del_word_left) text.bind("<<del-word-right>>", self.del_word_right) + text.bind("<<beginning-of-line>>", self.home_callback) if flist: flist.inversedict[self] = key @@ -224,11 +231,6 @@ class EditorWindow(object): self.num_context_lines = 50, 500, 5000000 self.per = per = self.Percolator(text) - if self.ispythonsource(filename): - self.color = color = self.ColorDelegator() - per.insertfilter(color) - else: - self.color = None self.undo = undo = self.UndoDelegator() per.insertfilter(undo) @@ -247,11 +249,13 @@ class EditorWindow(object): menu=self.recent_files_menu) self.update_recent_files_list() + self.color = None # initialized below in self.ResetColorizer if filename: if os.path.exists(filename) and not os.path.isdir(filename): io.loadfile(filename) else: io.set_filename(filename) + self.ResetColorizer() self.saved_change_hook() self.set_indentation_params(self.ispythonsource(filename)) @@ -294,6 +298,50 @@ class EditorWindow(object): self.flist.new(dirname) return "break" + def home_callback(self, event): + if (event.state & 12) != 0 and event.keysym == "Home": + # state&1==shift, state&4==control, state&8==alt + return # <Modifier-Home>; fall back to class binding + + if self.text.index("iomark") and \ + self.text.compare("iomark", "<=", "insert lineend") and \ + self.text.compare("insert linestart", "<=", "iomark"): + insertpt = int(self.text.index("iomark").split(".")[1]) + else: + line = self.text.get("insert linestart", "insert lineend") + for insertpt in xrange(len(line)): + if line[insertpt] not in (' ','\t'): + break + else: + insertpt=len(line) + + lineat = int(self.text.index("insert").split('.')[1]) + + if insertpt == lineat: + insertpt = 0 + + dest = "insert linestart+"+str(insertpt)+"c" + + if (event.state&1) == 0: + # shift not pressed + self.text.tag_remove("sel", "1.0", "end") + else: + if not self.text.index("sel.first"): + self.text.mark_set("anchor","insert") + + first = self.text.index(dest) + last = self.text.index("anchor") + + if self.text.compare(first,">",last): + first,last = last,first + + self.text.tag_remove("sel", "1.0", "end") + self.text.tag_add("sel", first, last) + + self.text.mark_set("insert", dest) + self.text.see("insert") + return "break" + def set_status_bar(self): self.status_bar = self.MultiStatusBar(self.top) if macosxSupport.runningAsOSXApp(): @@ -336,7 +384,7 @@ class EditorWindow(object): menudict[name] = menu = Menu(mbar, name=name) mbar.add_cascade(label=label, menu=menu, underline=underline) - if sys.platform == 'darwin' and '.framework' in sys.executable: + if macosxSupport.runningAsOSXApp(): # Insert the application menu menudict['application'] = menu = Menu(mbar, name='apple') mbar.add_cascade(label='IDLE', menu=menu) @@ -392,7 +440,7 @@ class EditorWindow(object): def help_dialog(self, event=None): fn=os.path.join(os.path.abspath(os.path.dirname(__file__)),'help.txt') - textView.TextViewer(self.top,'Help',fn) + textView.view_file(self.top,'Help',fn) def python_docs(self, event=None): if sys.platform[:3] == 'win': @@ -414,6 +462,7 @@ class EditorWindow(object): def paste(self,event): self.text.event_generate("<<Paste>>") + self.text.see("insert") return "break" def select_all(self, event=None): @@ -530,11 +579,11 @@ class EditorWindow(object): return None head, tail = os.path.split(filename) base, ext = os.path.splitext(tail) - import ClassBrowser + from idlelib import ClassBrowser ClassBrowser.ClassBrowser(self.flist, base, [head]) def open_path_browser(self, event=None): - import PathBrowser + from idlelib import PathBrowser PathBrowser.PathBrowser(self.flist) def gotoline(self, lineno): @@ -560,7 +609,8 @@ class EditorWindow(object): def close_hook(self): if self.flist: - self.flist.close_edit(self) + self.flist.unregister_maybe_terminate(self) + self.flist = None def set_close_hook(self, close_hook): self.close_hook = close_hook @@ -570,36 +620,42 @@ class EditorWindow(object): self.flist.filename_changed_edit(self) self.saved_change_hook() self.top.update_windowlist_registry(self) - if self.ispythonsource(self.io.filename): - self.addcolorizer() - else: - self.rmcolorizer() + self.ResetColorizer() - def addcolorizer(self): + def _addcolorizer(self): if self.color: return - self.per.removefilter(self.undo) - self.color = self.ColorDelegator() - self.per.insertfilter(self.color) - self.per.insertfilter(self.undo) + if self.ispythonsource(self.io.filename): + self.color = self.ColorDelegator() + # can add more colorizers here... + if self.color: + self.per.removefilter(self.undo) + self.per.insertfilter(self.color) + self.per.insertfilter(self.undo) - def rmcolorizer(self): + def _rmcolorizer(self): if not self.color: return self.color.removecolors() - self.per.removefilter(self.undo) self.per.removefilter(self.color) self.color = None - self.per.insertfilter(self.undo) def ResetColorizer(self): - "Update the colour theme if it is changed" - # Called from configDialog.py - if self.color: - self.color = self.ColorDelegator() - self.per.insertfilter(self.color) + "Update the colour theme" + # Called from self.filename_change_hook and from configDialog.py + self._rmcolorizer() + self._addcolorizer() theme = idleConf.GetOption('main','Theme','name') - self.text.config(idleConf.GetHighlight(theme, "normal")) + normal_colors = idleConf.GetHighlight(theme, 'normal') + cursor_color = idleConf.GetHighlight(theme, 'cursor', fgBg='fg') + select_colors = idleConf.GetHighlight(theme, 'hilite') + self.text.config( + foreground=normal_colors['foreground'], + background=normal_colors['background'], + insertbackground=cursor_color, + selectforeground=select_colors['foreground'], + selectbackground=select_colors['background'], + ) def ResetFont(self): "Update the text widgets' font if it is changed" @@ -827,22 +883,21 @@ class EditorWindow(object): if self.io.filename: self.update_recent_files_list(new_file=self.io.filename) WindowList.unregister_callback(self.postwindowsmenu) - if self.close_hook: - self.close_hook() - self.flist = None - colorizing = 0 self.unload_extensions() - self.io.close(); self.io = None - self.undo = None # XXX + self.io.close() + self.io = None + self.undo = None if self.color: - colorizing = self.color.colorizing - doh = colorizing and self.top - self.color.close(doh) # Cancel colorization + self.color.close(False) + self.color = None self.text = None self.tkinter_vars = None - self.per.close(); self.per = None - if not colorizing: - self.top.destroy() + self.per.close() + self.per = None + self.top.destroy() + if self.close_hook: + # unless override: unregister from flist, terminate if last window + self.close_hook() def load_extensions(self): self.extensions = {} @@ -1138,7 +1193,7 @@ class EditorWindow(object): if not self.context_use_ps1: for context in self.num_context_lines: startat = max(lno - context, 1) - startatindex = `startat` + ".0" + startatindex = repr(startat) + ".0" rawtext = text.get(startatindex, "insert") y.set_str(rawtext) bod = y.find_good_parse_start( @@ -1504,6 +1559,7 @@ def test(): filename = None edit = EditorWindow(root=root, filename=filename) edit.set_close_hook(root.quit) + edit.text.bind("<<close-all-windows>>", edit.close_event) root.mainloop() root.destroy() |
