Hover elements

In addition to code completion we can provide hover information. We want to see the implementation of fragments when hovering of fragment usages. That way code inspection can be easier done.

We'll create FragmentHoverProvider which implements HoverProvider.

<<fragment hover provider>>=
export class FragmentHoverProvider implements vscode.HoverProvider {
  readonly fragmentRepository : FragmentRepository;
  constructor(repository : FragmentRepository)
  {
    this.fragmentRepository = repository;
  }
  <<hover provider method>>
}

The FragmentHoverProvider implements provideHover. This will create the Hover item if under the current cursor position there is a fragment, including its opening and closing double chevrons.

<<hover provider method>>=
public async provideHover(
  document : vscode.TextDocument,
  position : vscode.Position,
  _: vscode.CancellationToken
)
{
  <<get current line>>
  <<find workspace folder for hover detection>>
  <<create hover item for fragment>>
  return null;
}

We get the current line of text from the document. We are going to look only for tags that are on one line. In the future it would be nice to add support for cases where mentioning a fragment in explaining text is split over several lines due to word wrapping, but with the current implementation we'll look only at those that are on one line.

<<get current line>>=
const currentLine = document.lineAt(position.line);

Next we need to know the the workspace folder for the given document so that we can query the correct project for the fragments. If no workspace folder was determined return null, as there is no literate project associated with the given document.

<<find workspace folder for hover detection>>=
const workspaceFolder : vscode.WorkspaceFolder | undefined = determineWorkspaceFolder(document);
if(!workspaceFolder) { return null; }

Fragments are now available so we can see if we have a fragment under our cursor. If we do, and the fragment is not one that defines or appends to a fragment we know our cursor is over either fragment usage in a code fence or a fragment mention in explaining text. For this we can create a Hover with the code of the fragment as a MarkdownString in a code fence.

If that is not the case our provideHover implementation will return null.

<<create hover item for fragment>>=
let fragmentLocation = this.fragmentRepository.getFragmentTagLocation(document, currentLine, position);
if(fragmentLocation.fragment && !fragmentLocation.root)
{
  let fragment = fragmentLocation.fragment;
  let range = fragmentLocation.range;
  return new vscode.Hover(
    new vscode.MarkdownString(`~~~ ${fragment.lang}\n${fragment.code}\n~~~`, true),
    range
    );
}

With the workspace folder in hand we can ask the FragmentRepository for the fragment map that has been generated for the workspace folder.

<<get fragments for hover detection>>=
let fragments = this.fragmentRepository.getFragments(workspaceFolder).map;