import { Hover , MarkupContent , MarkupKind } from 'vscode-languageserver' ; import { Position , TextDocument } from 'vscode-languageserver-textdocument' ; import { Scalar } from 'yaml/types' ; import { DocsLibrary } from '../services/docsLibrary' ; import { blockKeywords , isTaskKeyword , playKeywords , roleKeywords , taskKeywords , } from '../utils/ansible' ; import { formatModule , formatOption , formatTombstone , } from '../utils/docsFormatter' ; import { toLspRange } from '../utils/misc' ; import { AncestryBuilder , getOrigRange , getPathAt , getPossibleOptionsForPath , isBlockParam , isPlayParam , isRoleParam , isTaskParam , parseAllDocuments , } from '../utils/yaml' ; export async function doHover ( document , position , docsLibrary ) { const yamlDocs = parseAllDocuments ( document . getText ( ) ) ; const path = getPathAt ( document , position , yamlDocs ) ; if ( path ) { const node = path [ path . length - 1 ] ; if ( node instanceof Scalar && new AncestryBuilder ( path ) . parentOfKey ( ) . get ( ) ) { if ( isPlayParam ( path ) ) { return getKeywordHover ( document , node , playKeywords ) ; } if ( isBlockParam ( path ) ) { return getKeywordHover ( document , node , blockKeywords ) ; } if ( isRoleParam ( path ) ) { return getKeywordHover ( document , node , roleKeywords ) ; } if ( isTaskParam ( path ) ) { if ( isTaskKeyword ( node . value ) ) { return getKeywordHover ( document , node , taskKeywords ) ; } else { const [ module , hitFqcn ] = await docsLibrary . findModule ( node . value , path , document . uri ) ; const range = getOrigRange ( node ) ; if ( module && module . documentation ) { return { contents : formatModule ( module . documentation , docsLibrary . getModuleRoute ( hitFqcn || node . value ) ) , range : range ? toLspRange ( range , document ) : undefined , } ; } else if ( hitFqcn ) { const route = docsLibrary . getModuleRoute ( hitFqcn ) ; if ( route ) { return { contents : formatTombstone ( route ) , range : range ? toLspRange ( range , document ) : undefined , } ; } } } } const options = await getPossibleOptionsForPath ( path , document , docsLibrary ) ; if ( options ) { const option = options . get ( node . value ) ; if ( option ) { return { contents : formatOption ( option , true ) , } ; } } } } return null ; } function getKeywordHover ( document , node , keywords ) { const keywordDocumentation = keywords . get ( node . value ) ; const markupDoc = typeof keywordDocumentation === 'string' ? { kind : MarkupKind . Markdown , value : keywordDocumentation , } : keywordDocumentation ; if ( markupDoc ) { const range = getOrigRange ( node ) ; return { contents : markupDoc , range : range ? toLspRange ( range , document ) : undefined , } ; } else return null ; }