import * as Color from 'color' ; import * as fs from 'fs' ; import { ExtensionContext , workspace , WorkspaceFolder } from 'vscode' ; interface ColorsInterface { sideBarColor_dark : Color ; titleBarTextColor_dark : Color ; titleBarColor_dark : Color ; sideBarColor_light : Color ; titleBarTextColor_light : Color ; titleBarColor_light : Color ; } export class SettingsFileDeleter { constructor ( private workspaceRoot , private colors ) { } /**
     * Deletes .vscode/settings.json if colors all match either the default light or dark Windows Colors and if no other settings exist.
     *
     * Deletes .vscode if no other files exist.
     */ public dispose ( ) { const settingsfile = this . workspaceRoot + '/.vscode/settings.json' ; const vscodeSettingsDir = this . workspaceRoot + '/.vscode' ; const settingsFileJson = JSON . parse ( ( fs . readFileSync ( settingsfile , "utf8" ) ) ) ; const cc = JSON . parse ( JSON . stringify ( workspace . getConfiguration ( 'workbench' ) . get ( 'colorCustomizations' ) ) ) ; const deleteSettingsFileUponExit = JSON . parse ( JSON . stringify ( workspace . getConfiguration ( 'windowColors' ) . get < string > ( '🌈 DeleteSettingsFileUponExit' ) ) ) ; if ( deleteSettingsFileUponExit ) { fs . unlinkSync ( settingsfile ) ; fs . rmdirSync ( vscodeSettingsDir ) ; } else if ( Object . keys ( settingsFileJson ) . length === 1 && Object . keys ( cc ) . length === 3 ) { const aColorWasModified = ( cc [ 'activityBar.background' ] !== this . colors . sideBarColor_dark . hex ( ) && cc [ 'activityBar.background' ] !== this . colors . sideBarColor_light . hex ( ) ) || ( cc [ 'titleBar.activeBackground' ] !== this . colors . titleBarColor_dark . hex ( ) && cc [ 'titleBar.activeBackground' ] !== this . colors . titleBarColor_light . hex ( ) ) || ( cc [ 'titleBar.activeForeground' ] !== this . colors . titleBarTextColor_dark . hex ( ) && cc [ 'titleBar.activeForeground' ] !== this . colors . titleBarTextColor_light . hex ( ) ) ; if ( ! aColorWasModified ) { fs . unlinkSync ( settingsfile ) ; fs . rmdirSync ( vscodeSettingsDir ) ; } } } } export function activate ( context ) { if ( ! workspace . workspaceFolders ) { return ; } let workspaceRoot = getWorkspaceFolder ( workspace . workspaceFolders ) ; const extensionTheme = workspace . getConfiguration ( 'windowColors' ) . get < string > ( '🌈 Theme' ) ; let baseColor = workspace . getConfiguration ( 'windowColors' ) . get < string > ( '🌈 BaseColor' ) ; if ( baseColor ) { baseColor = baseColor . toLowerCase ( ) . trim ( ) ; } /** retain initial unrelated colorCustomizations*/ const cc = JSON . parse ( JSON . stringify ( workspace . getConfiguration ( 'workbench' ) . get ( 'colorCustomizations' ) ) ) ; let sideBarColor = Color ( '#' + stringToARGB ( workspaceRoot ) ) ; let titleBarTextColor = Color ( '#ffffff' ) ; let titleBarColor = Color ( '#ffffff' ) ; const sideBarColor_dark = getColorWithLuminosity ( sideBarColor , .02 , .027 ) ; const titleBarTextColor_dark = getColorWithLuminosity ( sideBarColor_dark , 0.95 , 1 ) ; const titleBarColor_dark = sideBarColor_dark . lighten ( 0.4 ) ; const sideBarColor_light = getColorWithLuminosity ( sideBarColor , 0.45 , 0.55 ) ; const titleBarTextColor_light = getColorWithLuminosity ( sideBarColor_light , 0 , 0.01 ) ; const titleBarColor_light = sideBarColor_light . lighten ( 0.1 ) ; if ( extensionTheme === 'dark' ) { sideBarColor = sideBarColor_dark ; titleBarTextColor = titleBarTextColor_dark ; titleBarColor = titleBarColor_dark ; } else if ( extensionTheme === 'light' ) { sideBarColor = sideBarColor_light ; titleBarTextColor = titleBarTextColor_light ; titleBarColor = titleBarColor_light ; } if ( baseColor ) { sideBarColor = Color ( baseColor ) ; titleBarColor = sideBarColor . lighten ( 0.3 ) ; if ( titleBarColor . luminosity ( ) > 0.5 ) { titleBarTextColor = getColorWithLuminosity ( sideBarColor , 0 , 0.01 ) ; } else { titleBarTextColor = getColorWithLuminosity ( sideBarColor , 0.95 , 1 ) ; } } const doRemoveColors = extensionTheme === 'remove' ; let doUpdateColors = true ; if ( cc && ( cc [ 'activityBar.background' ] || cc [ 'titleBar.activeBackground' ] || cc [ 'titleBar.activeForeground' ] ) ) { doUpdateColors = false ; } if ( baseColor ) { doUpdateColors = true ; } if ( doUpdateColors || doRemoveColors ) { const newColors = { "activityBar.background" : doRemoveColors ? undefined : sideBarColor . hex ( ) , "titleBar.activeBackground" : doRemoveColors ? undefined : titleBarColor . hex ( ) , "titleBar.activeForeground" : doRemoveColors ? undefined : titleBarTextColor . hex ( ) , } ; workspace . getConfiguration ( 'workbench' ) . update ( 'colorCustomizations' , { ... cc , ... newColors } , false ) ; } const settingsFileDeleter = new SettingsFileDeleter ( workspaceRoot , { sideBarColor_dark , titleBarTextColor_dark , titleBarColor_dark , sideBarColor_light , titleBarTextColor_light , titleBarColor_light } ) ; context . subscriptions . push ( settingsFileDeleter ) ; } const getColorWithLuminosity = ( color , min , max ) : Color => { let c = Color ( color . hex ( ) ) ; while ( c . luminosity ( ) > max ) { c = c . darken ( 0.01 ) ; } while ( c . luminosity ( ) < min ) { c = c . lighten ( 0.01 ) ; } return c ; } ; export const getWorkspaceFolder = ( folders ) : string => { if ( ! folders ) { return '' ; } const folder = folders [ 0 ] || { } ; const uri = folder . uri ; return uri . fsPath ; } ; function stringToARGB ( str ) { return intToARGB ( hashCode ( str ) ) ; } function hashCode ( str ) { var hash = 0 ; for ( var i = 0 ; i < str . length ; i ++ ) { hash = str . charCodeAt ( i ) + ( ( hash << 5 ) - hash ) ; } return hash ; } function intToARGB ( i ) { var hex = ( ( i >> 24 ) & 0xFF ) . toString ( 16 ) + ( ( i >> 16 ) & 0xFF ) . toString ( 16 ) + ( ( i >> 8 ) & 0xFF ) . toString ( 16 ) + ( i & 0xFF ) . toString ( 16 ) ; hex += '000000' ; return hex . substring ( 0 , 6 ) ; }