From 108ed70709d32ed1e4c0cd1143fb53f19d1262a0 Mon Sep 17 00:00:00 2001 From: Albert Graef <aggraef@gmail.com> Date: Mon, 15 Aug 2022 05:02:12 +0200 Subject: [PATCH] Cycle though all completions with Tab. The completion popup only shows the first few completion items, because of limited screen real estate. But there's no reason that Tab completion should have the same limitation. So we now keep track of the full list of completions internally and let Tab cycle through them all. --- pd/nw/pd_canvas.js | 12 ++++++++---- pd/nw/pdgui.js | 9 ++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/pd/nw/pd_canvas.js b/pd/nw/pd_canvas.js index 4232e1e12..ce268c464 100644 --- a/pd/nw/pd_canvas.js +++ b/pd/nw/pd_canvas.js @@ -50,6 +50,7 @@ var canvas_events = (function() { last_dropdown_menu_y, last_search_term = "", svg_view = document.getElementById("patchsvg").viewBox.baseVal, + last_results = [], // last completion results (autocomplete) last_completed = -1, // last Tab completion (autocomplete) last_yanked = "", // last yanked completion (to confirm deletion) textbox = function () { @@ -343,7 +344,7 @@ var canvas_events = (function() { if (obj_class === "obj") { // autocomplete only works for objects pdgui.create_autocomplete_dd(document, ac_dropdown(), textbox()); if (ac_dropdown().getAttribute("searched_text") !== textbox().innerText) { - pdgui.repopulate_autocomplete_dd(document, ac_dropdown, obj_class, textbox().innerText); + last_results = pdgui.repopulate_autocomplete_dd(document, ac_dropdown, obj_class, textbox().innerText); } } }, @@ -548,7 +549,7 @@ var canvas_events = (function() { }, text_mousedown: function(evt) { if (evt.target.parentNode === ac_dropdown()) { - last_completed = pdgui.select_result_autocomplete_dd(textbox(), ac_dropdown(), last_completed); + last_completed = pdgui.select_result_autocomplete_dd(textbox(), ac_dropdown(), last_completed, last_results); last_yanked = ""; // ag: Don't do the usual object instantiation thing if // we've clicked on the autocompletion dropdown. This @@ -604,7 +605,7 @@ var canvas_events = (function() { if(ac_dropdown() === null || ac_dropdown().getAttribute("selected_item") === "-1") { grow_svg_for_element(textbox()); } else { // else, if there is a selected item on autocompletion tool, the selected item is written on the box - last_completed = pdgui.select_result_autocomplete_dd(textbox(), ac_dropdown(), last_completed); + last_completed = pdgui.select_result_autocomplete_dd(textbox(), ac_dropdown(), last_completed, last_results); caret_end(); // No need to instantiate the object here, // presumably the user wants to go on editing. @@ -612,13 +613,14 @@ var canvas_events = (function() { last_yanked = ""; break; case 9: // tab - last_completed = pdgui.select_result_autocomplete_dd(textbox(), ac_dropdown(), last_completed); + last_completed = pdgui.select_result_autocomplete_dd(textbox(), ac_dropdown(), last_completed, last_results); last_yanked = ""; caret_end(); break; case 27: // esc pdgui.delete_autocomplete_dd(ac_dropdown()); last_completed = -1; + last_results = []; if (last_yanked != "") { pdgui.post("Operation aborted.") } @@ -632,6 +634,7 @@ var canvas_events = (function() { // which is to "yank" the current completion // (remove it from the completion index). last_completed = -1; + last_results = []; if (textbox().innerText === "") { pdgui.delete_autocomplete_dd(ac_dropdown()); last_yanked = ""; @@ -672,6 +675,7 @@ var canvas_events = (function() { || e.keyCode == 8 || e.keyCode == 46; } if (is_valid_key(evt)) { + last_results = []; last_completed = -1; last_yanked = ""; if (textbox().innerText === "") { diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js index aeebc88a4..ebeb39449 100644 --- a/pd/nw/pdgui.js +++ b/pd/nw/pdgui.js @@ -716,7 +716,7 @@ function update_autocomplete_dd_arrowup(ac_dropdown) { } } -function select_result_autocomplete_dd(textbox, ac_dropdown, last) { +function select_result_autocomplete_dd(textbox, ac_dropdown, last, res) { if (ac_dropdown !== null) { let sel = ac_dropdown.getAttribute("selected_item"); if (sel > -1) { @@ -724,9 +724,9 @@ function select_result_autocomplete_dd(textbox, ac_dropdown, last) { delete_autocomplete_dd(ac_dropdown); return sel; } else { // it only passes here when the user presses 'tab' and there is no option selected - var n = ac_dropdown.children.length; + var n = res.length; var next = (last+1) % n; - textbox.innerText = ac_dropdown.children.item(next).innerText; + textbox.innerText = res[next]; return next; } } else { @@ -800,6 +800,8 @@ function repopulate_autocomplete_dd(doc, ac_dropdown, obj_class, text) { results = results.map(a => a.item.title); } + // record the complete results, we need them for tab completion + let all_results = results; // GB TODO: ideally we should be able to show all the results in a limited window with a scroll bar let n = 8; // Maximum number of suggestions if (results.length > n) results = results.slice(0,n); @@ -823,6 +825,7 @@ function repopulate_autocomplete_dd(doc, ac_dropdown, obj_class, text) { } else { // if there is no suggestion candidate, the autocompletion dropdown should disappear delete_autocomplete_dd (ac_dropdown()); } + return all_results; } // GB: create autocomplete dropdown based on the properties of the textbox for new_obj_element -- GitLab