| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 8e25e01 commit 8839681
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,6 +20,7 @@ | |||
| 20 | 20 | from pygments.formatters import TerminalFormatter | |
| 21 | 21 | ||
| 22 | 22 | from wcwidth import wcswidth | |
| 23 | + from math import ceil | ||
| 23 | 24 | ||
| 24 | 25 | import blessings | |
| 25 | 26 | ||
@@ -395,14 +396,22 @@ def __init__( | |||
| 395 | 396 | # current line of output - stdout and stdin go here | |
| 396 | 397 | self.current_stdouterr_line = "" | |
| 397 | 398 | ||
| 398 | - # lines separated whenever logical line | ||
| 399 | - # length goes over what the terminal width | ||
| 400 | - # was at the time of original output | ||
| 399 | + | ||
| 400 | + # this is every line that's been displayed (input and output) | ||
| 401 | + # as with formatting applied. Logical lines that exceeded the terminal width | ||
| 402 | + # at the time of output are split across multiple entries in this list. | ||
| 401 | 403 | self.display_lines = [] | |
| 402 | 404 | ||
| 403 | 405 | # this is every line that's been executed; it gets smaller on rewind | |
| 404 | 406 | self.history = [] | |
| 405 | 407 | ||
| 408 | + # This is every logical line that's been displayed, both input and output. | ||
| 409 | + # Like self.history, lines are unwrapped, uncolored, and without prompt. | ||
| 410 | + # Entries are tuples, where | ||
| 411 | + # the first element a string of the line | ||
| 412 | + # the second element is one of 2 strings: "input" or "output". | ||
| 413 | + self.all_logical_lines = [] | ||
| 414 | + | ||
| 406 | 415 | # formatted version of lines in the buffer kept around so we can | |
| 407 | 416 | # unhighlight parens using self.reprint_line as called by bpython.Repl | |
| 408 | 417 | self.display_buffer = [] | |
@@ -411,7 +420,7 @@ def __init__( | |||
| 411 | 420 | # because there wasn't room to display everything | |
| 412 | 421 | self.scroll_offset = 0 | |
| 413 | 422 | ||
| 414 | - # from the left, 0 means first char | ||
| 423 | + # cursor position relative to start of current_line, 0 is first char | ||
| 415 | 424 | self._cursor_offset = 0 | |
| 416 | 425 | ||
| 417 | 426 | self.orig_tcattrs = orig_tcattrs | |
@@ -872,8 +881,10 @@ def on_enter(self, new_code=True, reset_rl_history=True): | |||
| 872 | 881 | self.rl_history.reset() | |
| 873 | 882 | ||
| 874 | 883 | self.history.append(self.current_line) | |
| 884 | + self.all_logical_lines.append((self.current_line, "input")) | ||
| 875 | 885 | self.push(self.current_line, insert_into_history=new_code) | |
| 876 | 886 | ||
| 887 | + | ||
| 877 | 888 | def on_tab(self, back=False): | |
| 878 | 889 | """Do something on tab key | |
| 879 | 890 | taken from bpython.cli | |
@@ -982,6 +993,9 @@ def process_simple_keypress(self, e): | |||
| 982 | 993 | self.add_normal_character(e) | |
| 983 | 994 | ||
| 984 | 995 | def send_current_block_to_external_editor(self, filename=None): | |
| 996 | + """" | ||
| 997 | + Sends the current code block to external editor to be edited. Usually bound to C-x. | ||
| 998 | + """ | ||
| 985 | 999 | text = self.send_to_external_editor(self.get_current_block()) | |
| 986 | 1000 | lines = [line for line in text.split("\n")] | |
| 987 | 1001 | while lines and not lines[-1].split(): | |
@@ -994,15 +1008,20 @@ def send_current_block_to_external_editor(self, filename=None): | |||
| 994 | 1008 | self.cursor_offset = len(self.current_line) | |
| 995 | 1009 | ||
| 996 | 1010 | def send_session_to_external_editor(self, filename=None): | |
| 1011 | + """ | ||
| 1012 | + Sends entire bpython session to external editor to be edited. Usually bound to F7. | ||
| 1013 | + | ||
| 1014 | + Loops through self.all_logical_lines so that lines aren't wrapped in the editor. | ||
| 1015 | + | ||
| 1016 | + """ | ||
| 997 | 1017 | for_editor = EDIT_SESSION_HEADER | |
| 998 | 1018 | for_editor += "\n".join( | |
| 999 | - line[len(self.ps1) :] | ||
| 1000 | - if line.startswith(self.ps1) | ||
| 1001 | - else line[len(self.ps2) :] | ||
| 1002 | - if line.startswith(self.ps2) | ||
| 1003 | - else "### " + line | ||
| 1004 | - for line in self.getstdout().split("\n") | ||
| 1019 | + line[0] if line[1] == "input" | ||
| 1020 | + else "### " + line[0] | ||
| 1021 | + for line in self.all_logical_lines | ||
| 1005 | 1022 | ) | |
| 1023 | + for_editor += "\n" + "### " + self.current_line | ||
| 1024 | + | ||
| 1006 | 1025 | text = self.send_to_external_editor(for_editor) | |
| 1007 | 1026 | if text == for_editor: | |
| 1008 | 1027 | self.status_bar.message( | |
@@ -1170,7 +1189,9 @@ def push(self, line, insert_into_history=True): | |||
| 1170 | 1189 | if c: | |
| 1171 | 1190 | logger.debug("finished - buffer cleared") | |
| 1172 | 1191 | self.cursor_offset = 0 | |
| 1192 | + | ||
| 1173 | 1193 | self.display_lines.extend(self.display_buffer_lines) | |
| 1194 | + | ||
| 1174 | 1195 | self.display_buffer = [] | |
| 1175 | 1196 | self.buffer = [] | |
| 1176 | 1197 | ||
@@ -1237,13 +1258,17 @@ def clear_current_block(self, remove_from_history=True): | |||
| 1237 | 1258 | if remove_from_history: | |
| 1238 | 1259 | for unused in self.buffer: | |
| 1239 | 1260 | self.history.pop() | |
| 1261 | + self.all_logical_lines.pop() | ||
| 1240 | 1262 | self.buffer = [] | |
| 1241 | 1263 | self.cursor_offset = 0 | |
| 1242 | 1264 | self.saved_indent = 0 | |
| 1243 | 1265 | self.current_line = "" | |
| 1244 | 1266 | self.cursor_offset = len(self.current_line) | |
| 1245 | 1267 | ||
| 1246 | 1268 | def get_current_block(self): | |
| 1269 | + """ | ||
| 1270 | + Returns the current code block as string (without prompts) | ||
| 1271 | + """ | ||
| 1247 | 1272 | return "\n".join(self.buffer + [self.current_line]) | |
| 1248 | 1273 | ||
| 1249 | 1274 | def send_to_stdouterr(self, output): | |
@@ -1271,6 +1296,15 @@ def send_to_stdouterr(self, output): | |||
| 1271 | 1296 | [], | |
| 1272 | 1297 | ) | |
| 1273 | 1298 | ) | |
| 1299 | + | ||
| 1300 | + # These can be FmtStrs, but self.all_logical_lines only wants strings | ||
| 1301 | + for line in [self.current_stdouterr_line] + lines[1:-1]: | ||
| 1302 | + if isinstance(line, FmtStr): | ||
| 1303 | + self.all_logical_lines.append((line.s, "output")) | ||
| 1304 | + else: | ||
| 1305 | + self.all_logical_lines.append((line, "output")) | ||
| 1306 | + | ||
| 1307 | + | ||
| 1274 | 1308 | self.current_stdouterr_line = lines[-1] | |
| 1275 | 1309 | logger.debug("display_lines: %r", self.display_lines) | |
| 1276 | 1310 | ||
@@ -1804,11 +1838,15 @@ def take_back_buffer_line(self): | |||
| 1804 | 1838 | self.display_buffer.pop() | |
| 1805 | 1839 | self.buffer.pop() | |
| 1806 | 1840 | self.history.pop() | |
| 1841 | + self.all_logical_lines.pop() | ||
| 1807 | 1842 | ||
| 1808 | 1843 | def take_back_empty_line(self): | |
| 1809 | 1844 | assert self.history and not self.history[-1] | |
| 1810 | 1845 | self.history.pop() | |
| 1811 | 1846 | self.display_lines.pop() | |
| 1847 | + self.all_logical_lines.pop() | ||
| 1848 | + | ||
| 1849 | + | ||
| 1812 | 1850 | ||
| 1813 | 1851 | def prompt_undo(self): | |
| 1814 | 1852 | if self.buffer: | |
@@ -1826,8 +1864,9 @@ def prompt_for_undo(): | |||
| 1826 | 1864 | def redo(self): | |
| 1827 | 1865 | if (self.redo_stack): | |
| 1828 | 1866 | temp = self.redo_stack.pop() | |
| 1829 | - self.push(temp) | ||
| 1830 | 1867 | self.history.append(temp) | |
| 1868 | + self.all_logical_lines.append((temp, "input")) | ||
| 1869 | + self.push(temp) | ||
| 1831 | 1870 | else: | |
| 1832 | 1871 | self.status_bar.message("Nothing to redo.") | |
| 1833 | 1872 | ||
@@ -1839,6 +1878,7 @@ def reevaluate(self, new_code=False): | |||
| 1839 | 1878 | old_display_lines = self.display_lines | |
| 1840 | 1879 | self.history = [] | |
| 1841 | 1880 | self.display_lines = [] | |
| 1881 | + self.all_logical_lines = [] | ||
| 1842 | 1882 | ||
| 1843 | 1883 | if not self.weak_rewind: | |
| 1844 | 1884 | self.interp = self.interp.__class__() | |
@@ -1903,6 +1943,9 @@ def initialize_interp(self): | |||
| 1903 | 1943 | del self.coderunner.interp.locals["_Helper"] | |
| 1904 | 1944 | ||
| 1905 | 1945 | def getstdout(self): | |
| 1946 | + """ | ||
| 1947 | + Returns a string of the current bpython session, formatted and wrapped. | ||
| 1948 | + """ | ||
| 1906 | 1949 | lines = self.lines_for_display + [self.current_line_formatted] | |
| 1907 | 1950 | s = ( | |
| 1908 | 1951 | "\n".join(x.s if isinstance(x, FmtStr) else x for x in lines) | |
@@ -1911,6 +1954,7 @@ def getstdout(self): | |||
| 1911 | 1954 | ) | |
| 1912 | 1955 | return s | |
| 1913 | 1956 | ||
| 1957 | + | ||
| 1914 | 1958 | def focus_on_subprocess(self, args): | |
| 1915 | 1959 | prev_sigwinch_handler = signal.getsignal(signal.SIGWINCH) | |
| 1916 | 1960 | try: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -78,6 +78,8 @@ def test_external_communication(self): | |||
| 78 | 78 | def test_external_communication_encoding(self): | |
| 79 | 79 | with captured_output(): | |
| 80 | 80 | self.repl.display_lines.append('>>> "åß∂ƒ"') | |
| 81 | + self.repl.history.append('"åß∂ƒ"') | ||
| 82 | + self.repl.all_logical_lines.append(('"åß∂ƒ"',"input")) | ||
| 81 | 83 | self.repl.send_session_to_external_editor() | |
| 82 | 84 | ||
| 83 | 85 | def test_get_last_word(self): | |
| Back | FazBrowse Home | New Git URL |
0 commit comments