This is an archive of the discontinued LLVM Phabricator instance.

[LLDB][GUI] Add initial searcher support
ClosedPublic

Authored by OmarEmaraDev on Aug 23 2021, 5:11 AM.

Details

Summary

This patch adds a new type of reusable UI components. Searcher Windows
contain a text field to enter a search keyword and a list of scrollable
matches are presented. The target match can be selected and executed
which invokes a user callback to do something with the match.

This patch also adds one searcher delegate, which wraps the common
command completion searchers for simple use cases.

Diff Detail

Event Timeline

OmarEmaraDev created this revision.Aug 23 2021, 5:11 AM
OmarEmaraDev requested review of this revision.Aug 23 2021, 5:11 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 23 2021, 5:11 AM

An example searcher window for source files:

I like the look of this. It seems we would want this kind of auto complete in many fields that we already have, like the file or directory dialogs to start with.

My main question is do we need a full window for this, or can be paint a window that is just the search results? My thinking is that the right arrow key could be used to auto complete a text field if we are at the end of the input. If we have a file dialog and you type "~/" and then RIGHT arrow, it would be great if this window could appear right at the correct location and not look like a complete new window, but just a popup window that augments an existing Field (not necessarily a text field!) right below with minimal bordering so that it blends into the current form. You can select things using the up and down arrows, press enter to update the text, or keep typing to filter more.

Maybe we can:

  • Maybe we add a "SearcherWindowDelegate *m_search_window;" member to FormDelegate so that this helper UI can appear when needed for any FieldDelegate that requests/needs it
    • "m_search_window" can be set to a non NULL value when one of the FieldDelegates in the FormDelegate asks for auto completion and provides a SearcherDelegate to use and a pointer to the FieldDelegate itself so that the SearcherWindowDelegate can be positioned correctly
    • If "m_search_window" is NULL, then never show this UI
    • If "m_search_window" is not NULL, then some keys get sent to the searcher delegate before or after the field gets them so it can do the choices UI
      • if the user hits ENTER, then the Field is asked to update its value via some API in FieldDelegate, and the GUI for the matches disappears and m_search_window is freed and set to NULL again

We should hook up at least one of the FieldDelegate objects so that it uses this functionality so we can play with it in this patch to make sure it works.

Let me know if you had other plans for this window and how it would be used.

lldb/source/Core/IOHandlerCursesGUI.cpp
3675

Should we be doing just like any other dialog that we have created and be constructing these items on the fly?

m_text_field = AddTextField("Search", "", true);

It seems the matches could use a modified ChoicesField for the matches? Are you currently drawing the choices (matches) manually?

3718

Seems like this could be done using a ChoicesField no instead of drawing manually?

3814

Is this a new text field itself, or designed to be a reference to an existing text field?

@clayborg I was planning on getting to field completion later as part of a global "context window" feature. There are reasons why I need this as a full separate window for now. Imminently, I am creating an operator that changes the file in the sources window so that breakpoints can be inserted manually. So once the user press Ctrl+F, a search window will appear where the user can choose a source file to navigate to. This will require a custom searcher, and not the common searcher implemented above, which I will add in a following patch. What do you think?

lldb/source/Core/IOHandlerCursesGUI.cpp
3675

AddTextField is part of form delegates, I don't think implementing this as a form is a good idea as they are functionally distinct.

I am drawing choices manually because the duplicated code is not really a lot and I like to be able to control the style of the drawing. But I guess we can reimplemented that using a choices field.

3814

A new instance of a text field.

OmarEmaraDev added inline comments.Aug 24 2021, 9:06 AM
lldb/source/Core/IOHandlerCursesGUI.cpp
3675

One thing to note is that text representation of matches are lazily computed in this window but not in the choices field, which gives an advantage. We can probably add support for lazy computation in the choice field, but it may not be worth it at the moment.

@clayborg I was planning on getting to field completion later as part of a global "context window" feature. There are reasons why I need this as a full separate window for now. Imminently, I am creating an operator that changes the file in the sources window so that breakpoints can be inserted manually. So once the user press Ctrl+F, a search window will appear where the user can choose a source file to navigate to.

Pressing CTRL+F can and should bring up a dialog window right? The user will search for something, and finalize with some action. So this seems like perfect use for dialog windows and the fields and forms you have already created.

This will require a custom searcher, and not the common searcher implemented above, which I will add in a following patch. What do you think?

See comments above, but I do think this is a perfect usage for dialog windows:

  • user presses CTRL+F and dialog comes up
    • user selects a file and presses OPT+ENTER to finalize the action and source view updates
    • user presses escape and dismisses the dialog
lldb/source/Core/IOHandlerCursesGUI.cpp
3675

But this does seem like the perfect use for a dialog window: user presses CTRL+F, dialog shows up and allows user to select something, and then press OPT+ENTER to update the source view. Is there a reason you think this should be a window and not a dialog?

If we re-use the ChoicesField, you can just update the choices with a delegate any time the choices should change and repaint the windows right?

3814

Yeah, the main questions is if this should be a FormDelegate or not. See other comments.

@clayborg I see a number of issues with using forms directly:

  • The user will have to bother with form navigation. If we have a text field and a choice field, the user will have to switch between them using Tab and Shift+Tab in order to explore, rectify, and select a match. This is significantly more work then just typing without worry, selecting using arrow keys, and executing using enter.
  • Not all users will use the OPT+Enter keys, it is likely that once the user sees a button that says "Select", the user will try to navigate to that button ignoring the tip in the windows border. Which is more work than just pressing enter.
  • Updating the choices will require that we materialize all choices into text, this can work for the common completion searcher, but other searchers will require actual processing that might slow down the update process. The searcher window only materialize the match that it draws, so it can draw things much faster. We could update the choices field to accept a callback to compute its contents, but this will complicate the code, so it is worth considering if this is really needed.
  • Practically all search dialogs work in a manner similar to the searcher window, like browser search bar, editor search dialogs, and the like. I don't recall seeing a search dialog that is implemented as a form.
  • We want the ability to do custom styling. One thing I was considering is coloring the matched substring a different color, if we use a choice field, then we give up on custom styling.
clayborg accepted this revision.Aug 25 2021, 1:53 PM

Ok, sounds like you have thought this through.

This revision is now accepted and ready to land.Aug 25 2021, 1:53 PM
This revision was landed with ongoing or failed builds.Aug 25 2021, 1:55 PM
This revision was automatically updated to reflect the committed changes.