|
104 | 104 |
|
105 | 105 | # Help text for the jump-to dialog
|
106 | 106 | _JUMP_TO_HELP = """\
|
107 |
| -Type one or more strings/regexes and press Enter to list items that match all |
108 |
| -of them. Python's regex flavor is used (see the 're' module). Double-clicking |
109 |
| -an item will jump to it. Item values can be toggled directly within the dialog.\ |
| 107 | +Type to search - results update as you type. Supports multiple strings/regexes |
| 108 | +(space-separated) that must all match. Python's regex flavor is used (see 're' |
| 109 | +module). Double-click an item to jump to it. Values can be toggled within the dialog.\ |
110 | 110 | """
|
111 | 111 |
|
112 | 112 |
|
@@ -186,11 +186,13 @@ def menuconfig(kconf):
|
186 | 186 | global _jump_to_tree
|
187 | 187 | global _cur_menu
|
188 | 188 | global _tree_row_index
|
| 189 | + global _search_after_id |
189 | 190 |
|
190 | 191 | _kconf = kconf
|
191 | 192 |
|
192 | 193 | _jump_to_tree = None
|
193 | 194 | _tree_row_index = 0
|
| 195 | + _search_after_id = None |
194 | 196 |
|
195 | 197 | _create_id_to_node()
|
196 | 198 |
|
@@ -2061,18 +2063,35 @@ def _try_load(filename):
|
2061 | 2063 | def _jump_to_dialog(_=None):
|
2062 | 2064 | # Pops up a dialog for jumping directly to a particular node. Symbol values
|
2063 | 2065 | # can also be changed within the dialog.
|
2064 |
| - # |
2065 |
| - # Note: There's nothing preventing this from doing an incremental search |
2066 |
| - # like menuconfig.py does, but currently it's a bit jerky for large Kconfig |
2067 |
| - # trees, at least when inputting the beginning of the search string. We'd |
2068 |
| - # need to somehow only update the tree items that are shown in the Treeview |
2069 |
| - # to fix it. |
2070 | 2066 |
|
2071 | 2067 | global _jump_to_tree
|
| 2068 | + global _search_after_id |
| 2069 | + |
| 2070 | + _search_after_id = None |
2072 | 2071 |
|
2073 | 2072 | def search(_=None):
|
| 2073 | + # Clear "Searching..." message |
| 2074 | + if msglabel["text"] == "Searching...": |
| 2075 | + msglabel["text"] = "" |
2074 | 2076 | _update_jump_to_matches(msglabel, entry.get())
|
2075 | 2077 |
|
| 2078 | + def interactive_search(_=None): |
| 2079 | + # Performs incremental search with debouncing to avoid excessive updates |
| 2080 | + global _search_after_id |
| 2081 | + |
| 2082 | + # Cancel any pending search |
| 2083 | + if _search_after_id: |
| 2084 | + dialog.after_cancel(_search_after_id) |
| 2085 | + |
| 2086 | + # Show searching indicator for non-empty queries |
| 2087 | + search_text = entry.get() |
| 2088 | + if search_text: |
| 2089 | + msglabel["text"] = "Searching..." |
| 2090 | + |
| 2091 | + # Schedule a new search after a short delay (150ms) |
| 2092 | + # This provides responsive feedback while avoiding excessive updates |
| 2093 | + _search_after_id = dialog.after(150, lambda: search()) |
| 2094 | + |
2076 | 2095 | def jump_to_selected(event=None):
|
2077 | 2096 | # Jumps to the selected node and closes the dialog
|
2078 | 2097 |
|
@@ -2115,6 +2134,9 @@ def tree_select(_):
|
2115 | 2134 | entry.grid(column=0, row=1, sticky="ew", padx=".1c", pady=".1c")
|
2116 | 2135 | entry.focus_set()
|
2117 | 2136 |
|
| 2137 | + # Bind KeyRelease for interactive search |
| 2138 | + entry.bind("<KeyRelease>", interactive_search) |
| 2139 | + # Still allow immediate search with Enter |
2118 | 2140 | entry.bind("<Return>", search)
|
2119 | 2141 | entry.bind("<KP_Enter>", search)
|
2120 | 2142 |
|
@@ -2156,7 +2178,15 @@ def tree_select(_):
|
2156 | 2178 | # add=True to avoid overriding the description text update
|
2157 | 2179 | tree.bind("<<TreeviewSelect>>", tree_select, add=True)
|
2158 | 2180 |
|
| 2181 | + def on_dialog_destroy(): |
| 2182 | + # Clean up any pending search callbacks |
| 2183 | + global _search_after_id |
| 2184 | + if _search_after_id: |
| 2185 | + dialog.after_cancel(_search_after_id) |
| 2186 | + _search_after_id = None |
| 2187 | + |
2159 | 2188 | dialog.bind("<Escape>", lambda _: dialog.destroy())
|
| 2189 | + dialog.protocol("WM_DELETE_WINDOW", lambda: (on_dialog_destroy(), dialog.destroy())) |
2160 | 2190 |
|
2161 | 2191 | # Wait for the user to be done with the dialog
|
2162 | 2192 | _root.wait_window(dialog)
|
|
0 commit comments