@@ -1614,6 +1614,95 @@ export function setupJsonEditorLanguageSupport(
16141614 schemas : [ ] ,
16151615 } ) ;
16161616
1617+ const hoverDisposable = monaco . languages . registerHoverProvider ( 'json' , {
1618+ provideHover ( model , position ) {
1619+ if ( model . uri . toString ( ) !== context . modelUri ) return null ;
1620+ if ( ! context . schema ) return null ;
1621+
1622+ const text = model . getValue ( ) ;
1623+ const offset = model . getOffsetAt ( position ) ;
1624+ const tree = parseTree ( text ) ;
1625+ const location = getLocation ( text , offset ) ;
1626+ if ( ! location . path . length ) return null ;
1627+
1628+ const rootSchema = asSchema ( context . schema ) ;
1629+ const activeEvaluator = resolveActiveEvaluator (
1630+ context ,
1631+ tree ,
1632+ location . path
1633+ ) ;
1634+ const cursor = resolveSchemaAtJsonPath (
1635+ context ,
1636+ activeEvaluator ,
1637+ location . isAtPropertyKey ? location . path . slice ( 0 , - 1 ) : location . path
1638+ ) ;
1639+
1640+ // For property keys, show the property's schema description
1641+ if ( location . isAtPropertyKey ) {
1642+ const propName = location . path [ location . path . length - 1 ] ;
1643+ if ( typeof propName !== 'string' || ! cursor . schema ) return null ;
1644+ const propSchema = getSchemaAtProperty (
1645+ cursor . schema ,
1646+ propName ,
1647+ cursor . rootSchema
1648+ ) ;
1649+ const desc = getSchemaDescription ( propSchema ) ;
1650+ const title = getSchemaTitle ( propSchema ) ;
1651+ if ( ! desc && ! title ) return null ;
1652+
1653+ const word = model . getWordAtPosition ( position ) ;
1654+ const range = word
1655+ ? new monaco . Range (
1656+ position . lineNumber ,
1657+ word . startColumn ,
1658+ position . lineNumber ,
1659+ word . endColumn
1660+ )
1661+ : undefined ;
1662+
1663+ return {
1664+ range,
1665+ contents : [
1666+ {
1667+ value : `**${ title ?? propName } **${ desc ? '\n\n' + desc : '' } ` ,
1668+ } ,
1669+ ] ,
1670+ } ;
1671+ }
1672+
1673+ // For values, show the value's schema info
1674+ if ( cursor . schema ) {
1675+ const desc = getSchemaDescription ( cursor . schema ) ;
1676+ const title = getSchemaTitle ( cursor . schema ) ;
1677+ const enumVals = getSchemaEnumValues ( cursor . schema ) ;
1678+ if ( ! desc && ! title && enumVals . length === 0 ) return null ;
1679+
1680+ const parts : string [ ] = [ ] ;
1681+ if ( title ) parts . push ( `**${ title } **` ) ;
1682+ if ( desc ) parts . push ( desc ) ;
1683+ if ( enumVals . length > 0 )
1684+ parts . push ( `Values: \`${ enumVals . join ( '` | `' ) } \`` ) ;
1685+
1686+ const word = model . getWordAtPosition ( position ) ;
1687+ const range = word
1688+ ? new monaco . Range (
1689+ position . lineNumber ,
1690+ word . startColumn ,
1691+ position . lineNumber ,
1692+ word . endColumn
1693+ )
1694+ : undefined ;
1695+
1696+ return {
1697+ range,
1698+ contents : [ { value : parts . join ( '\n\n' ) } ] ,
1699+ } ;
1700+ }
1701+
1702+ return null ;
1703+ } ,
1704+ } ) ;
1705+
16171706 const disposable = monaco . languages . registerCompletionItemProvider ( 'json' , {
16181707 triggerCharacters : COMPLETION_TRIGGER_CHARACTERS ,
16191708 provideCompletionItems ( model , position ) {
@@ -1635,6 +1724,7 @@ export function setupJsonEditorLanguageSupport(
16351724 const codeActionDisposable = registerConditionCodeActions ( monaco , context ) ;
16361725
16371726 return ( ) => {
1727+ hoverDisposable . dispose ( ) ;
16381728 disposable . dispose ( ) ;
16391729 codeActionDisposable . dispose ( ) ;
16401730 } ;
0 commit comments