Repository navigation
gh-152942: Add an AST browser to IDLE - #152947
serhiy-storchaka wants to merge 7 commits into
Conversation
Documentation build overview
179 files changed ·
|
terryjreedy
left a comment
There was a problem hiding this comment.
Using the extension mechanism is handy for developing mulltiple features whose patches would confIict, but I really do not want to merge this way. I added comments about integrating features into normal code. (Not sure if complete.)
| # A browser for the Python tokens of the editor, opened from the Tools menu. | ||
| [TokenBrowser] | ||
| enable= 1 | ||
| [TokenBrowser_cfgBindings] |
There was a problem hiding this comment.
These extension def entries do nothing.
|
|
||
| extfiles = { # Map built-in config-extension section names to file names. | ||
| 'TokenBrowser': 'tokenbrowser', | ||
| 'ASTBrowser': 'astbrowser', |
There was a problem hiding this comment.
Please no. Just import files in code in the appropriate place. (See next comment.)
| ('tools', [ | ||
| ]), |
There was a problem hiding this comment.
Menu entries defining tool menu entries and virtual events should be added here. Each browser patch will have have to be finalized by basing it on the code as modified by the previous browser patch. Currently, corresponding objects are imported in editor.Editor and bound to events in init. (Yes, refactoring is needed.)
| ========================= | ||
|
|
||
|
|
||
| gh-152942: Add an AST Browser to IDLE, opened from the Tools menu. It |
There was a problem hiding this comment.
News3 items have to be added just before merging. I believe that this will be a merge conflict as soon as something else is added.
|
When you're done making the requested changes, leave the comment: And if you don't make the requested changes, you will be put in the comfy chair! |
d842aca to
eacd68e
Compare
|
Done — reworked all four from extensions to integrated features, like the Module and Path browsers. The three code browsers go on a new Browse menu (your name), stacked token → AST → disassembly. The Character Browser stays on Edit for now so its separate PR doesn't conflict; it can move later. I kept the News3 entries — resolving the conflict or adding them just before merge is the same edit either way. Folding the existing Path/Module browsers into Browse is a good follow-up. |
| first, scope = "1.0", "text" | ||
| self.base = tuple(int(i) for i in first.split(".")) | ||
| source = text.get(first, last) | ||
| self.source_lines = source.splitlines() |
There was a problem hiding this comment.
str.splitlines() breaks on several characters that the parser and the Text widget do not treat as line boundaries: form feed \f, vertical tab \v, \x1c-\x1e, \x85, and \u2028/\u2029. When the source contains one of them, source_lines gains an extra entry, and editor_index (which indexes source_lines[lineno - 1] to turn a byte column into a character column) reads the wrong line. Form feed is the realistic trigger, since it is a legal page separator in Python source.
>>> src = "x = 1\f\ny = 22\n" # a form feed ends the first line
>>> src.splitlines() # three entries for two real lines
['x = 1', '', 'y = 22']
>>> ast.parse(src).body[1].lineno # the y = 22 statement
2y = 22 is line 2 to the parser, but source_lines[1] is now '', so editor_index(2, 4) and editor_index(2, 6) both collapse to column 0 and node_range returns a zero-width ('2.0', '2.0'). show_highlight skips zero-width ranges (rng[0] != rng[1]), so that node highlights nothing; and because the extra source_lines entry shifts every line after the form feed, later nodes have their byte columns converted against the wrong line and highlight or navigate to the wrong place. Restricting the split to the parser's line endings keeps source_lines aligned.
There was a problem hiding this comment.
Good catch, thank you. Fixed by splitting on "\n" only, in both the AST and disassembly browsers, each with a form-feed regression test. (A lone \r is a separate parser-vs-Text case I'll handle later.)
Add an empty Browse menu, between Debug and Options, for the browser windows that open on the Shell and the editor. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A window opened from the Browse menu registers itself in the editor's list of browsers. ResetColorizer and ResetFont, which the configuration dialog calls on every window, ask each open browser to restyle itself, so that a theme or font change reaches it without reopening. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add an AST Browser command to the Browse menu (Shell and editor). It opens a window showing the abstract syntax tree of the editor content (or, in the Shell, the current input), or of the selection if there is one. Selecting a node highlights the matching region in the editor and, while the browser has focus, moves the editor cursor there; selecting text or moving the cursor in the editor selects the innermost enclosing node. Double-clicking a node (or pressing Escape) hides the browser, revealing the editor at the node. It shares the window skeleton and editor-sync mechanism with the token browser. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
str.splitlines() also breaks at form feed and similar characters that the parser and the Text widget keep within the line, which misaligned the column mapping for the following lines. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Title the browser window with the name of the browsed file, as the module browser does. Take the tree's colors, font and row height from the current theme and font settings, and restyle open browsers when the configuration changes. Open the window beside the editor rather than over the text. Leave a double-click to the Treeview, which expands or collapses a node, instead of hiding the browser; Escape still hides it. Show the editor's cursor while the browser has the focus, so that it marks the start of the selected node. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Up and Down selected nothing until a row was clicked, because the window, not the tree, took the focus when the browser was opened, and refresh() gave the focus back to the window every time the command was invoked again. Tk remembers the focused widget of each window, so focusing the tree once is enough to keep it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Selecting the browser from the taskbar now deiconifies the editor window and raises it, then raises the browser again so that it stays on top of the editor it belongs to. A window manager may refuse to raise a window above the window of another application; the editor is then only marked as needing attention. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
45e0b82 to
251145a
Compare
Add an AST Browser to IDLE's new Browse menu (Shell and editor). It shows the abstract syntax tree of the editor content, the Shell input, or the selection, as a tree whose rows name the field, the node type, and its simple fields inlined.
Selecting a node highlights the matching source in the editor and, while the browser has the focus, moves the cursor there; selecting text or moving the cursor in the editor selects the innermost node that encloses it. Double-clicking a node expands or collapses it, and Escape hides the browser.
Node columns are UTF-8 byte offsets, converted to editor columns against the source lines; the second commit splits those lines at newlines only, so that a form feed does not shift every following line.
There is one browser per editor, and invoking the command again refreshes it. A selection that does not parse on its own is reported in the status bar, since
ast.parseis all or nothing.The window follows the configuration: its title names the browsed file, the tree takes the current theme's colors and the editor's font with a row height to match, and open browsers are restyled when the configuration changes. It opens beside the editor, its tree takes the focus so that Up and Down work at once, and selecting it from the taskbar reveals its editor.
The first two commits add the Browse menu and the restyle hook that this PR shares with the token (#152946), bytecode (#152974) and character (#152945) browsers; whichever of the four lands first brings them in, and the others drop them on rebase.
🤖 Generated with Claude Code