Skip to content

codemirror file view: Enable hovercards in ref panel preview

Administrator requested to merge fkling/cm-ref-panel-hovercard into main

Created by: fkling

Based on #40232 (for click to jump to def)

This was tricky to investiage/solve. The reason why hovercard actions didn't work with CodeMirror wasn't because of the use of <MemoryRouter /> but because the blob view was passed a different history object (blobMemoryHistory) than the <MemoryRouter /> context was using.

Because the CodeMirror/React integration establishes a new Router context, the history context object for all Hovercard links was blobMemoryHistory, but updating this one didn't update the panel's history object:

ref-panel-router

I think this needs to be refactored overall to provide a clear flow of history changes, but for the time being I fixed it by "forwarding" history changes originating from withing the hovercard to the panel's history (by listining to changes of blobMemoryRouter).

But even with this fixed I noticed that sometimes the blob view would not select the line when clicking on another reference in the same file. The reason for this was the logic of useBlobIsLoading. That hook made the assumption that there is always a 1:1 relation between a URL location and a blob view information. But that is not the case when we are working on main/master. Long story short, in that case the blob view is switching between URLs that contain and do not contain the commit ID. To the CodeMirror blob view that looked like new blob data is loading (location pathname changed) and it waited for new blob data to arrive but that never happened.

The hook was originally introduced to prevent applying line selection decoration that are outside of the current document, which did happen when a new blob was loaded. However, regardless of the issues with the reference panel, a more robust implementation is to verify that the position from the URL is valid in the current document.


I think I was able to replicate the current behavior of the ref panel:

  • Clicking on any reference or definition in the list loads the preview and scrolls to the selected line.
  • Clicking on the "Go to definition"/"Find references" buttons reloads the ref panel.
  • Using "click to to go to definition" will keep the file open and jump to the correct position if the definition is in the same file.

Demo:

https://user-images.githubusercontent.com/179026/184118429-65b21a99-c7ad-43de-a58d-ebe7f3b12b4b.mp4

Test plan

  • Hover over a token a click "find references"
  • Inside the ref panel, select any reference. The blob view should appear.
  • Hover over a reference whose definition is in the same document. Click on it. The blob view should directly jump to the definition.
  • Clicking "Go to definition" or "Find References" inside a hover card should cause the ref panel to update with the corresponding data.
  • Picking various references/definitions in the same/different files should scroll the corresponding lines into view.

App preview:

Check out the client app preview documentation to learn more.

Merge request reports

Loading