Mercurial > cpython-lru_cache-weakref
annotate Lib/idlelib/ReplaceDialog.py @ 79675:c0a2294de787 2.7
Issue #16199: Backport 2to3 typo fix from 3.2.
| author | Chris Jerdonek <chris.jerdonek@gmail.com> |
|---|---|
| date | Thu, 11 Oct 2012 16:15:46 -0700 |
| parents | 44c00de723b3 |
| children | edcfd18840cc |
| rev | line source |
|---|---|
|
47183
b53604fad54b
Tkinter rename reversal: remove tkinter package, adapt imports and docs.
Georg Brandl <georg@python.org>
parents:
47101
diff
changeset
|
1 from Tkinter import * |
|
60144
eab361617f6a
#7092: Fix additional "-3" warnings in the idlelib package, and convert to absolute imports.
Florent Xicluna <florent.xicluna@gmail.com>
parents:
47183
diff
changeset
|
2 |
|
eab361617f6a
#7092: Fix additional "-3" warnings in the idlelib package, and convert to absolute imports.
Florent Xicluna <florent.xicluna@gmail.com>
parents:
47183
diff
changeset
|
3 from idlelib import SearchEngine |
|
eab361617f6a
#7092: Fix additional "-3" warnings in the idlelib package, and convert to absolute imports.
Florent Xicluna <florent.xicluna@gmail.com>
parents:
47183
diff
changeset
|
4 from idlelib.SearchDialogBase import SearchDialogBase |
|
78417
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
5 import re |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
6 |
| 13975 | 7 |
| 8 def replace(text): | |
| 9 root = text._root() | |
| 10 engine = SearchEngine.get(root) | |
| 11 if not hasattr(engine, "_replacedialog"): | |
| 12 engine._replacedialog = ReplaceDialog(root, engine) | |
| 13 dialog = engine._replacedialog | |
| 14 dialog.open(text) | |
| 15 | |
|
78417
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
16 |
| 13975 | 17 class ReplaceDialog(SearchDialogBase): |
| 18 | |
| 19 title = "Replace Dialog" | |
| 20 icon = "Replace" | |
| 21 | |
| 22 def __init__(self, root, engine): | |
| 23 SearchDialogBase.__init__(self, root, engine) | |
| 24 self.replvar = StringVar(root) | |
| 25 | |
| 26 def open(self, text): | |
| 27 SearchDialogBase.open(self, text) | |
| 28 try: | |
| 29 first = text.index("sel.first") | |
| 30 except TclError: | |
| 31 first = None | |
| 32 try: | |
| 33 last = text.index("sel.last") | |
| 34 except TclError: | |
| 35 last = None | |
| 36 first = first or text.index("insert") | |
| 37 last = last or first | |
| 38 self.show_hit(first, last) | |
| 39 self.ok = 1 | |
| 40 | |
| 41 def create_entries(self): | |
| 42 SearchDialogBase.create_entries(self) | |
| 43 self.replent = self.make_entry("Replace with:", self.replvar) | |
| 44 | |
| 45 def create_command_buttons(self): | |
| 46 SearchDialogBase.create_command_buttons(self) | |
| 47 self.make_button("Find", self.find_it) | |
| 48 self.make_button("Replace", self.replace_it) | |
| 49 self.make_button("Replace+Find", self.default_command, 1) | |
| 50 self.make_button("Replace All", self.replace_all) | |
| 51 | |
| 52 def find_it(self, event=None): | |
| 53 self.do_find(0) | |
| 54 | |
| 55 def replace_it(self, event=None): | |
| 56 if self.do_find(self.ok): | |
| 57 self.do_replace() | |
| 58 | |
| 59 def default_command(self, event=None): | |
| 60 if self.do_find(self.ok): | |
|
78417
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
61 if self.do_replace(): # Only find next match if replace succeeded. |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
62 # A bad re can cause a it to fail. |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
63 self.do_find(0) |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
64 |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
65 def _replace_expand(self, m, repl): |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
66 """ Helper function for expanding a regular expression |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
67 in the replace field, if needed. """ |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
68 if self.engine.isre(): |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
69 try: |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
70 new = m.expand(repl) |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
71 except re.error: |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
72 self.engine.report_error(repl, 'Invalid Replace Expression') |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
73 new = None |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
74 else: |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
75 new = repl |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
76 return new |
| 13975 | 77 |
| 78 def replace_all(self, event=None): | |
| 79 prog = self.engine.getprog() | |
| 80 if not prog: | |
| 81 return | |
| 82 repl = self.replvar.get() | |
| 83 text = self.text | |
| 84 res = self.engine.search_text(text, prog) | |
| 85 if not res: | |
| 86 text.bell() | |
| 87 return | |
| 88 text.tag_remove("sel", "1.0", "end") | |
| 89 text.tag_remove("hit", "1.0", "end") | |
| 90 line = res[0] | |
| 91 col = res[1].start() | |
| 92 if self.engine.iswrap(): | |
| 93 line = 1 | |
| 94 col = 0 | |
| 95 ok = 1 | |
| 96 first = last = None | |
| 97 # XXX ought to replace circular instead of top-to-bottom when wrapping | |
| 98 text.undo_block_start() | |
| 99 while 1: | |
| 100 res = self.engine.search_forward(text, prog, line, col, 0, ok) | |
| 101 if not res: | |
| 102 break | |
| 103 line, m = res | |
| 104 chars = text.get("%d.0" % line, "%d.0" % (line+1)) | |
| 105 orig = m.group() | |
|
78417
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
106 new = self._replace_expand(m, repl) |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
107 if new is None: |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
108 break |
| 13975 | 109 i, j = m.span() |
| 110 first = "%d.%d" % (line, i) | |
| 111 last = "%d.%d" % (line, j) | |
| 112 if new == orig: | |
| 113 text.mark_set("insert", last) | |
| 114 else: | |
| 115 text.mark_set("insert", first) | |
| 116 if first != last: | |
| 117 text.delete(first, last) | |
| 118 if new: | |
| 119 text.insert(first, new) | |
| 120 col = i + len(new) | |
| 121 ok = 0 | |
| 122 text.undo_block_stop() | |
| 123 if first and last: | |
| 124 self.show_hit(first, last) | |
| 125 | |
| 126 def do_find(self, ok=0): | |
| 127 if not self.engine.getprog(): | |
| 25311 | 128 return False |
| 13975 | 129 text = self.text |
| 130 res = self.engine.search_text(text, None, ok) | |
| 131 if not res: | |
| 132 text.bell() | |
| 25311 | 133 return False |
| 13975 | 134 line, m = res |
| 135 i, j = m.span() | |
| 136 first = "%d.%d" % (line, i) | |
| 137 last = "%d.%d" % (line, j) | |
| 138 self.show_hit(first, last) | |
| 139 self.ok = 1 | |
| 25311 | 140 return True |
| 13975 | 141 |
| 142 def do_replace(self): | |
| 143 prog = self.engine.getprog() | |
| 144 if not prog: | |
| 25311 | 145 return False |
| 13975 | 146 text = self.text |
| 147 try: | |
| 148 first = pos = text.index("sel.first") | |
| 149 last = text.index("sel.last") | |
| 150 except TclError: | |
| 151 pos = None | |
| 152 if not pos: | |
| 153 first = last = pos = text.index("insert") | |
| 154 line, col = SearchEngine.get_line_col(pos) | |
| 155 chars = text.get("%d.0" % line, "%d.0" % (line+1)) | |
| 156 m = prog.match(chars, col) | |
| 157 if not prog: | |
| 25311 | 158 return False |
|
78417
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
159 new = self._replace_expand(m, self.replvar.get()) |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
160 if new is None: |
|
44c00de723b3
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents:
60144
diff
changeset
|
161 return False |
| 13975 | 162 text.mark_set("insert", first) |
| 163 text.undo_block_start() | |
| 164 if m.group(): | |
| 165 text.delete(first, last) | |
| 166 if new: | |
| 167 text.insert(first, new) | |
| 168 text.undo_block_stop() | |
| 169 self.show_hit(first, text.index("insert")) | |
| 170 self.ok = 0 | |
| 25311 | 171 return True |
| 13975 | 172 |
| 173 def show_hit(self, first, last): | |
| 174 text = self.text | |
| 175 text.mark_set("insert", first) | |
| 176 text.tag_remove("sel", "1.0", "end") | |
| 177 text.tag_add("sel", first, last) | |
| 178 text.tag_remove("hit", "1.0", "end") | |
| 179 if first == last: | |
| 180 text.tag_add("hit", first) | |
| 181 else: | |
| 182 text.tag_add("hit", first, last) | |
| 183 text.see("insert") | |
| 184 text.update_idletasks() | |
| 185 | |
| 186 def close(self, event=None): | |
| 187 SearchDialogBase.close(self, event) | |
| 188 self.text.tag_remove("hit", "1.0", "end") |
