Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workspace Search #943

Open
2 of 4 tasks
glennsl opened this issue Nov 18, 2019 · 11 comments
Open
2 of 4 tasks

Workspace Search #943

glennsl opened this issue Nov 18, 2019 · 11 comments
Labels
A-search Area: Workspace search enhancement New feature or request meta A big-picture issue, often collecting a number of other issues for discussing overarching solutions

Comments

@glennsl
Copy link
Member

glennsl commented Nov 18, 2019

We 'bout to get search! But how?

Here's a rough outline of the (current) plan:

  • Start with a basic UI similar in style to the search panel in vscode
  • Add first-class keyboard navigation
  • Implement all the bells and whistles vscode has
  • Somehow make the the search, or search results, open in an ordinary buffer to be positioned and moved around in the layout as desired.

Copying vscode is relatively straight-forward, so while other feedback is of course also welcome, my only questions right now are:

  • How should the keyboard navigation work? Also consider how this will work if there are multiple search buffers open, for example. I understand vim sets some precedence here and that @bryphe has some ideas as well.
  • How should the "search buffer" work? Should there just be a Ctrl+P command to open the buffer, and then have the entire search UI in the buffer? Or should the UI basically be in the command palette, with the buffer only displaying the results? Or should it hijack/extend one or more vim commands?

Progress will be tracked in https://github.com/onivim/oni2/projects/9

@glennsl glennsl added enhancement New feature or request A-search Area: Workspace search meta A big-picture issue, often collecting a number of other issues for discussing overarching solutions labels Nov 18, 2019
@bryphe
Copy link
Member

bryphe commented Nov 19, 2019

So excited for this! It's a huge gap today 😄 I'll be very happy when I no longer need to leave Onivim 2 to git grep 🎉 Thank you for thinking about this @glennsl !

How should the keyboard navigation work? Also consider how this will work if there are multiple search buffers open, for example. I understand vim sets some precedence here and that @bryphe has some ideas as well.

I've been thinking a bit about this - there are two pieces we need:

Piece 1: The ability to focus the 'sidebar' or other panes. Ideally, we could use the <C-w>h shortcut to move window-left into the sidebar, and give the sidebar focus. Our current window manager only knows about focusing editors - so we'll need to augment it to know about giving focus to the sidebar.

IE, this moveCore method in WindowManager:

let moveCore = (dirX, dirY, v: t) => {
only knows about moving between window splits, not the sidebar / activity bar (the docks).

Piece 2: For vim keybindings, I anticipate there are multiple places we will want vim keybindings to integrate into GUI actions - the file explorer being one, the search result being another, maybe output logs / notifications like in #849 .

I'd like to provide a special hook for this, like:

let%hook () = Hooks.vimKeyboardNavigation(
   ~active=true, // Set to `true` if we have focus, otherwise false
   ~onMoveUp=(count) => setFocused(state => state.focusedIndex - count),
   ~onMoveDown=(count) => setFocused(state => state.focusedIndex + count), 
   // others down the road, like:
   //~onMoveLeft=(count) => ...
  //~onMoveRight=(count) => ...
  //~onStartSearch=(...) => ...
);

to act as the 'bridge' from the GUI world to Vim-keybinding-compatibility.

Under-the-hood, this hook would integrate with libvim by switching to a 'capture' mode - when it switches to active=true, it will create a hidden, unlisted, readonly scratch buffer, and listen for movements (I'm adding a special 'capture' API for this - actually somewhat related to #163 ). This will have 1-1 parity with Vim keybindings. When active switches to false, we'd dispose of the capture.

Even without that fully implemented - we could implement the active state by listening to j/k to call into onMoveUp/onMoveDown, and then once we get the capture API, we could switch (the capture API would have the benefit of respecting noremap, handling counts, etc).

How should the "search buffer" work?

I can see a few options for this:

Option 1 - VSCode-style: - When the user initiates search, we show the search UI and the search results in the sidebar. This seems like it might be the simplest to implement - the only downside is the UX isn't great IMO (since search results are often much wider than the sidebar!). At the minimum, we'd need to implement a resize functionality for our sidebar alongside this.

image

Option 2 - Search buffer:
When the user initiates search, we show the results in a buffer - essentially a new editor / tab like "Find in Files". Atom has a somewhat similar experience:

image

We could consider, though, moving the search query into the 'find results' pane.

We could still show the magnifying-glass-search-icon in the activity bar, but what would be a bit awkward is clicking it would open this 'search buffer' instead of a sidebar.

Option 3 - Vim / Quickfix style results:

Vim has the concept of a 'quickfix' / 'loclist' window - which is a window you can toggle on / off at the bottom of the screen, that has a list of locations - often it is used to show search results:

image

We could consider an experience like this, as it is 'vim-like'. It also is a place where we could funnel output from plugins that use the quickfix / location list. For the search experience, like option 2, we could consider moving the search query into the 'find results' pane.

Should there just be a Ctrl+P command to open the buffer, and then have the entire search UI in the buffer?

It sounds like this would be like 'Option 2', except we include the search query in the buffer. Seems pretty reasonable to me!

Or should the UI basically be in the command palette, with the buffer only displaying the results?

In my opinion having the query UX separate would be a confusing (although I believe SublimeText does this...).

Or should it hijack/extend one or more vim commands?

Vim does have a :grep command, like :grep 'my pattern.*' /some/path - we could use that as an initial entry point while we're working out the UI (and it'd be great to have compatibility with this anyway!). I can help wire up the built-in command to some entry point from libvim.

Thinking about this, I don't have a strong opinion per-se, but Option 3 - showing a bottom-window - is the most appealing to me. Primarily because such a pane could also be used for notification / output, like in #849 , showing build errors, and it would be a natural place for compatibility with Vim's quickfix / location list concepts.

A quick mock-up of what I was thinking:
image

  • Clicking the 'search' icon in the activity bar would open the pane, and put focus in the search tab / find field.
  • Running :grep would open the pane, put focus in the search tab, and execute the query specified via arguments from :grep.
  • Pressing <C-w>j when in the bottom-most window will expand the pane, and set focus in whatever 'tab' was last in the bottom pane.
  • j/k will navigate lists vertically
  • h/l will navigate between tabs of this bottom pane?

Just some ideas - sorry for the stream-of-consciousness reply! Let me know if you have ideas / questions / or need clarifications.

@CrossR
Copy link
Member

CrossR commented Nov 19, 2019

I basically agree with what @bryphe has said, leaning into the vim side of things sounds like it could help both search and many other actions that use a QuickFix/Location list window. That way, we get a lot of benefit from adding a new component.

I can see the benefit of having a search buffer too, so it could be something to explore as well. There is an open issue that outlines a different search buffer UI/UX: #194, which might help add some ideas for that. Especially for anything interactive, which is where a quick fix UI (at least in the vim model) breaks down for me. For a workspace search and replace, a big buffer so I can see every change and apply more formatting sounds nicer.

@glennsl
Copy link
Member Author

glennsl commented Nov 21, 2019

I've just opened #971, which implements a rudimentary first attempt at a search UI. It's kind of a combination of vscode-style and vim-style, a drawer at the bottom which has the query UI on the left, roughly as wide and tall as in vscode, and the results on the right.

2019-11-22-001109_797x623_scrot

It's a little bit awkward to have the button to open it on the side, far away from where it actually appears, but I'm sure we can figure out how to solve that.

It would also be really easy to integrate a button, on the right side of the results header for example, to pop the results out into a buffer. We then have option 1, 2 and 3 all-in-one! (Kinda)

@glennsl glennsl mentioned this issue Nov 23, 2019
2 tasks
@yunti
Copy link

yunti commented Nov 23, 2019

For comparison intellij, webstorm, etc... have a unified search popover, which is pretty powerful (bit beyond the scope here though). But it's nicely laid out with minimal noise in the reults.
Result first then path is a good approach. And vertical with search bar on top and result underneath uses the space well, without the gaps left in the horizontal approach.
The popover is useful in that you can return to the state of your editor layout as it was after the search, however I'm definitely attracted to the 'everything is a buffer' approach which does give power to the user to how they lay things out.

image

This second one uses the index of an Ide so not as relevant, but another search window for comparison.
image

@glennsl
Copy link
Member Author

glennsl commented Nov 23, 2019

Oh, cool @yunti! I actually googled Intellij/Webstorm's search UI when looking for inspiration, but didn't get the impression from screenshots that it was a popover-style UI. It looked like just a cramped dialog to me.

This second one uses the index of an Ide so not as relevant...

Have you switched the images? The second seems more relevant as it shows file content being searched, while the first is more like an advanced QuickOpen menu with an understanding of the AST. Which is of course cool, but requires very good language support. Probably more than the LSP provides?

The second screenshot has a button labeled "Open in Find Window". Do you know what that is? What does that do that this doesn't?

Other questions/concerns:

  • How does it handle long paths? The window seems relatively narrow, so it won't be able to fit much of a path, it seems.
  • It also seems like it would be very easy to misclick and close the window, which would presumably lose the query, options and where you were.
  • I sometimes use search results to navigate between locations in different files, doing various ordinary operations over a larger span of time. This seems more tailored to doing one-off operations over many locations and then be done with it. Perhaps that's why there's a "Find Window" in addition.

The popover is useful in that you can return to the state of your editor layout as it was after the search

Definitely, I think that's the biggest benefit of this.

Coupled with he ability to select a "work set" of results to open in a more persistent location list, as @gitbugr mentioned over in #971, this could be a very powerful tool.

@gitbugr
Copy link

gitbugr commented Nov 23, 2019

reposting here from #971

--
@glennsl

In neovim, I use Ag (fzf.vim) in a floating window which is pretty nice to work with

Can you illustrate? I'm not familiar with it.

sure:
Screenshot 2019-11-23 at 11 31 45

also a note about the tab-selection aspect of this - when it opens the quickfix menu, this suffices as my search & replace tool, in fact, it's more powerful. I can create a macro which will jump between the files and do more than just replacing strings.

output

The only thing I don't have a solution for is explicitly excluding types of files.

@bogdan0083
Copy link

Thank you guys for being open to discuss such an important feature of code editors. I'm very excited for this stuff!

I've been looking for the best search experience in code editors for quite a long time. What @gitbugr described above is close to what I use (and want), but not quite. 😄

I will list all the stuff that I personally want from search. I also understand that some of the features might not be implemented or be an overkill, but I think search functionality is the most important feature for me, so I need at least to have my word.

Here's the list:

  1. The search should be in buffer, like quickfix list or vim-swoop, or atom-narrow (it opens search window on the right side but have an option to open at the bottom like quickfix window). I want to have a full editing experience inside the search buffer (copy results / change search query right inside the search buffer and run search again / quickly browse through results using a hotkey / etc).
  2. I want it to show me a preview right away in the main window as I browse through the results. Like vim-swoop, or atom-narrow do. When you get accustomed to the new codebase this is quite useful to get the full context of what's going on.
  3. It should be highly flexible and configurable. For example, I might want to see multiple lines of context like sublime text does and pass arbitrary arguments to the grep like fzf. Or change the font size of the search buffer to make it smaller and more compact. Or I want it to open search on the right side, not on the bottom. Or or or or...
  4. I want to search everything. I want to search for text, symbols, @TODO lines, usages, references, different git commands (git status, git log etc.). Would be also cool to define where I want to search. For example, I might want to search my previous projects for particular function (probably an overkill, but would be cool to have as an option).
  5. I want to be able to edit search buffer results, save it and it will update the edited lines in real files. vim-swoop, atom-narrow has such option. Fzf and vim-clap also have it but only by populating quickfix window . Again, what @gitbugr showed above is close, but editing search results right away is better! This feature combined with multiple cursors support can make the refactoring experience way better. It might be disabled by default and enabled only as an option.
  6. I want search buffer to have a syntax highlighting for search results like vscode-better-search does (although the highlighting is quite often broken). This feature is non-trivial and might be hard to implement, but cool to have as an option.

Generally speaking, I want oni2 to have a flexible and highly configurable generic search interface exposed through an API which in the future will allow plugin authors to build providers they want.

Most of what I wrote is probably out of scope for this issue, but maybe it will give you some thoughts and ideas on how we should handle this.

@gitbugr
Copy link

gitbugr commented Nov 24, 2019

@bogdan0083

I think search functionality is the most important feature for me

I second this. The search is the main reason why I haven't been able to switch to a vim-emulated experience in vscode/atom/itellij, and why oni2 is so exciting for me.

I want it to show me a preview right away in the main window as I browse through the results. Like vim-swoop, or atom-narrow do

I actually have vim-swoop but don't get to use it very often because it doesn't allow you to do project-wide search/replace, only the buffers you currently have open.
atom-narrow is new to me, but damn that's cool! I'd really love oni to favour a search interface like this.

I think it could achieve both what I want (with macros) and what you want (with vim-swoop-like editing, right in the buffer.)

@yunti
Copy link

yunti commented Nov 26, 2019

I think search functionality is the most important feature for me

Yup I agree it's definitely key, and worth the time to get right. And as @bogdan0083 mentioned mentioned, (ideally):

It should be highly flexible and configurable

Answering @glennsl 's questions

Have you switched the images?

Eh yes sorry I meant this one.

image

I think one of the main design choices is whether to use an in-plane search or an out-of-plane / popover one.
I think both are useful depending on the type of search (with eg a popover one potentially best where you just want to quickly check something and jump back in to where you left off).
Ultimately this should probably be configurable, but it's going to be easier to implement in-plane so I would go for that first.
Depending on whether you go for a popover or not affects what makes sense to have in there - with a search preview as well as the results useful in the popover, whereas it's probably easiest to just sync the editor to the results for the preview for in-plane search.

The second screenshot has a button labeled "Open in Find Window". Do you know what that is? What does that do that this doesn't?

It opens into this, which is basically in-plane search, but made really painful as to move the editor to the relevant result you have to double click each time, rather than single click (or hover).
The nested result structure is painful too instead of just a flat list of results with filepath on the right.

image

For layout of results, I would definitely go for result first, then filepath, (as you mentioned in the other thread @glennsl) as we are (generally) reading LtR so have the key item come first.

How does it handle long paths? The window seems relatively narrow, so it won't be able to fit much of a path, it seems.

Generally it just shows the filename, if unique and enough of the path to identify it if the filename isn't unique. This works great - creates less noise (there's probably an option to configure it, but I can't see it straightaway). You can also make the window any width too.

It also seems like it would be very easy to misclick and close the window, which would presumably lose the query, options and where you were

It keeps the query and the state, so if you click away it's just a keyboard shortcut to pull it back up as it was, so this isn't ever an issue.

I sometimes use search results to navigate between locations in different files, doing various ordinary operations over a larger span of time. This seems more tailored to doing one-off operations over many locations and then be done with it.

It works well for this too as it stores the query and state, so it's not an issue.

Generally I would say that search is one's of intellij's strengths vs vscode (although intellij lacks in plenty of other areas) and is definitely an example worth looking at.

However @bogdan0083 makes a great post and like most editors it definitely doesn't do point 5. That looks great and definitely looks like a great addition to search further down the line.

Thinking further down the line, when we have multiple tools in there that @bryphe has mentioned he would like to do, like the filetree, search, embedded terminal, debugger etc...., it makes sense to have these treated in a common way, which is often what many editors/Ide's don't get quite right, and it seems that this being vim, making everything a buffer in some way is going to give better consistency. (eg as was touched on in #734 )

@glennsl
Copy link
Member Author

glennsl commented Feb 9, 2020

VS Code Insiders Edition also has a "Search Editor" feature now: https://code.visualstudio.com/updates/v1_42#_search-editor

VS Code Search Editor

@DanielPower
Copy link

Just a minor UX suggestion, but if the search is going to remain in the bottom pane, the search icon should move to the status bar where Problems and Notifications are, since having it in the sidebar implies it's an openable sidebar pane.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-search Area: Workspace search enhancement New feature or request meta A big-picture issue, often collecting a number of other issues for discussing overarching solutions
Projects
None yet
Development

No branches or pull requests

7 participants