import { Hover , MarkdownString } from 'vscode' ; import * as utils from '../Utils/Utils' ; import axios , { AxiosRequestConfig } from 'axios' ; import { ConfigManager } from '../Utils/ConfigManager' ; import { OH_CONFIG_PARAMETERS } from '../Utils/types' ; author Jerome Luckenbach - Initial contribution
  export class HoverProvider { /**
     * Only allow a single provider to exist at a time.
     */ private static _currentProvider : HoverProvider | undefined ; /**
     * Array of known Items from the openHAB environment
     */ private knownItems : String [ ] ; /**
     * Regex for Thread::sleep() expression
     */ public static THREAD_SLEEP_REGEX : RegExp = /(?<=sleep\()[0-9]{1,9}(?=\))/gm ; /**
     * Regex for all hover-relevant wordings
     */ public static HOVERED_WORD_REGEX : RegExp = /(?<=sleep\()[0-9]{1,9}(?=\)){1}|(\w+){1}/gm ; /**
     * Only allow the class to call the constructor
     */ public constructor ( ) { this . updateItems ( ) ; } param hoveredText returns public getHover ( hoveredText , hoveredLine ) { console . log ( `Checking if text can get a hover information.` ) ; console . debug ( `Checking if => ${ hoveredLine } <= includes a Thread::sleep()` ) ; const lineMatch = hoveredLine . match ( HoverProvider . THREAD_SLEEP_REGEX ) ; if ( lineMatch && lineMatch . length == 1 ) return this . getReadableThreadSleep ( hoveredLine ) ; console . debug ( `Checking if => ${ hoveredText } <= is a known Item now` ) ; if ( this . knownItems . includes ( hoveredText ) ) return this . getRestItemHover ( hoveredText ) ; console . log ( `Nothing to hover, waiting...` ) ; return null ; } param hoveredLine returns private getReadableThreadSleep ( hoveredLine ) { let match = parseInt ( hoveredLine . match ( HoverProvider . THREAD_SLEEP_REGEX ) [ 0 ] ) ; return new Promise ( ( resolve , reject ) => { let resultText = new MarkdownString ( ) ; resultText . appendCodeblock ( `${ this . humanReadableDuration ( match ) }` , 'openhab' ) ; resolve ( new Hover ( resultText ) ) ; } ) ; } param hoveredText returns private getRestItemHover ( hoveredText ) { return new Promise ( ( resolve , reject ) => { console . log ( `Requesting => ${ utils . getHost ( ) }/rest/items/${ hoveredText } <= now` ) ; let config = { url : utils . getHost ( ) + `/rest/items/${ hoveredText }` , headers : { } } ; if ( ConfigManager . tokenAuthAvailable ( ) ) { config . headers = { 'X-OPENHAB-TOKEN' : ConfigManager . get ( OH_CONFIG_PARAMETERS . connection . authToken ) } ; } axios ( config ) . then ( ( response ) => { let result = response . data ; if ( ! result . error ) { let resultText = new MarkdownString ( ) ; if ( result . type === "Group" ) { resultText . appendCodeblock ( `Item ${ result . name } | ${ result . state }` , 'openhab' ) ; resultText . appendMarkdown ( `##### Members:` ) ; result . members . forEach ( ( member , key , result ) => { resultText . appendCodeblock ( `Item ${ member . name } | ${ member . state }` , 'openhab' ) ; if ( ! Object . is ( result . length - 1 , key ) ) { resultText . appendText ( `\n` ) ; } } ) ; } else { resultText . appendCodeblock ( `${ result . state }` , 'openhab' ) ; } resolve ( new Hover ( resultText ) ) ; } } ) . catch ( ( ) => reject ( false ) ) ; } ) ; } param msDuration returns private humanReadableDuration ( msDuration ) { const h = Math . floor ( msDuration / 1000 / 60 / 60 ) ; const m = Math . floor ( ( msDuration / 1000 / 60 / 60 - h ) * 60 ) ; const s = Math . floor ( ( ( msDuration / 1000 / 60 / 60 - h ) * 60 - m ) * 60 ) ; const ms = msDuration - ( h * 3600 * 1000 ) - ( m * 60 * 1000 ) - ( s * 1000 ) ; return `${ h != 0 ? h + ' hours ' : '' }${ m != 0 ? m + ' minutes ' : '' }${ s != 0 ? s + ' seconds ' : '' }${ ms != 0 ? ms + ' milliseconds ' : '' }` ; } returns public updateItems ( ) { let config = { url : utils . getHost ( ) + '/rest/items' , headers : { } } ; if ( ConfigManager . tokenAuthAvailable ( ) ) { config . headers = { 'X-OPENHAB-TOKEN' : ConfigManager . get ( OH_CONFIG_PARAMETERS . connection . authToken ) } ; } axios ( config ) . then ( ( response ) => { this . knownItems = new Array < String > ( ) ; let result = response . data ; result . forEach ( item => { this . knownItems . push ( item . name ) ; } ) ; console . log ( `Updates Items for HoverProvider` ) ; return true ; } ) . catch ( ( error ) => { console . error ( `Failed to update Items for HoverProvider` , error ) ; utils . appendToOutput ( `Could not reload items for HoverProvider` ) ; utils . handleRequestError ( error ) ; return false ; } ) ; return false ; } }