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
.
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.
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.
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.
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
.
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.
let fragments = this.fragmentRepository.getFragments(workspaceFolder).map;