'use strict' ; import * as fs from 'fs' ; import * as path from 'path' ; import { extensions , Uri , workspace , WorkspaceConfiguration , WorkspaceFolder } from 'vscode' ; import { getConfig } from './config' ; import { Constants } from './constants' ; export class Configuration { public static getConflictingExtensions ( resource = null ) { return Configuration . loadAnySetting < string [ ] > ( 'conflictingExtensions' , null , resource ) ; } public static getDocutilsWriter ( resource = null ) { return Configuration . loadSetting ( 'docutilsWriter' , 'html' , resource ) ; } public static getDocutilsWriterPart ( resource = null ) { return Configuration . loadSetting ( 'docutilsWriterPart' , 'html_body' , resource ) ; } public static getSphinxPath ( resource = null ) { return Configuration . loadSetting ( 'sphinxBuildPath' , null , resource ) ; } public static getConfPath ( resource = null ) { return Configuration . loadSetting ( 'confPath' , null , resource ) ; } public static getOutputFolder ( resource = null ) { return Configuration . loadSetting ( 'builtDocumentationPath' , null , resource ) ; } public static getPreviewName ( resource = null ) { return Configuration . loadSetting ( 'preview.name' , 'sphinx' , resource ) ; } public static getLinterName ( resource = null ) { return Configuration . loadSetting ( 'linter.name' , 'rstcheck' , resource ) ; } public static getLinterPath ( resource = null ) { return Configuration . loadSetting ( 'linter.executablePath' , null , resource ) ; } public static getSnootySourceFolder ( resource = null ) { return this . getConfiguration ( 'snooty' , resource ) . get < string > ( 'sourceFolder' ) ; } public static getSnootyDebugLaunch ( resource = null ) { return this . getConfiguration ( 'snooty' , resource ) . get < boolean > ( 'debugLaunch' , false ) ; } public static getTelemetryDisabled ( resource = null ) { return Configuration . loadAnySetting ( 'telemetry.disabled' , false , resource ) ; } public static getExtraArgs ( resource = null ) { return Configuration . loadAnySetting < string [ ] > ( 'linter.extraArgs' , null , resource ) ; } public static getRunType ( resource = null ) { return Configuration . loadAnySetting ( 'linter.run' , 'onType' , resource ) ; } public static async getPythonPath ( resource = null ) { try { const extension = extensions . getExtension ( 'ms-python.python' ) ; if ( ! extension ) { return Constants . python ; } const usingNewInterpreterStorage = extension . packageJSON ?. featureFlags ?. usingNewInterpreterStorage ; if ( usingNewInterpreterStorage ) { if ( ! extension . isActive ) { await extension . activate ( ) ; } const pythonPath = extension . exports . settings . getExecutionDetails ( resource ) . execCommand [ 0 ] ; return pythonPath ; } else { return this . getConfiguration ( 'python' , resource ) . get < string > ( 'pythonPath' ) ; } } catch ( error ) { return Constants . python ; } } public static getConfiguration ( section ? , resource = null ) { if ( resource ) { return workspace . getConfiguration ( section , resource ) ; } else { return workspace . getConfiguration ( section ) ; } } public static getPythonPath2 ( resource = null ) { const primary = Configuration . loadSetting ( 'pythonPath' , 'python3' , resource , true , 'python' ) ; if ( primary ) { const workspaceRoot = Configuration . GetRootPath ( resource ) ; if ( workspaceRoot ) { const optional = path . join ( workspaceRoot , primary ) ; if ( fs . existsSync ( optional ) ) { return optional ; } } } return primary ; } public static getLinterDisabled ( resource = null ) { return Configuration . loadAnySetting ( 'linter.disabled' , true , resource ) ; } public static getSphinxDisabled ( resource = null ) { return Configuration . loadAnySetting ( 'preview.sphinx.disabled' , false , resource ) ; } public static getDocUtilDisabled ( resource = null ) { return Configuration . loadAnySetting ( 'preview.docutils.disabled' , true , resource ) ; } public static getLanguageServerDisabled ( resource = null ) { return Configuration . loadAnySetting ( 'languageServer.disabled' , true , resource ) ; } public static getUpdateDelay ( resource = null ) { return Configuration . loadAnySetting < number > ( 'updateDelay' , 3000 , resource ) ; } public static getSyntaxHighlightingDisabled ( resource = null ) { return Configuration . loadAnySetting ( 'syntaxHighlighting.disabled' , false , resource ) ; } public static getTableEditorDisabled ( resource = null ) { return Configuration . loadAnySetting ( 'editor.tableEditor.disabled' , false , resource ) ; } public static getAdornments ( resource = null ) { return Configuration . loadAnySetting ( 'editor.sectionEditor.adornments' , "#*=-^\"'`:.~_+" , resource ) ; } public static getPythonRecommendationDisabled ( resource = null ) { return Configuration . loadAnySetting ( 'pythonRecommendation.disabled' , false , resource ) ; } public static async setPythonRecommendationDisabled ( resource = null ) { await Configuration . saveAnySetting ( 'pythonRecommendation.disabled' , true , resource ) ; } public static async setConfPath ( value , resource = null , insertMacro ) { return await Configuration . saveSetting ( 'confPath' , value , resource , insertMacro ) ; } public static async setLanguageServerDisabled ( resource = null ) { await Configuration . saveAnySetting ( 'languageServer.disabled' , true , resource ) ; } public static async setLinterDisabled ( resource = null ) { await Configuration . saveAnySetting ( 'linter.disabled' , true , resource ) ; } public static async setSphinxDisabled ( resource = null ) { await Configuration . saveAnySetting ( 'preview.sphinx.disabled' , true , resource ) ; } public static async setDocUtilDisabled ( resource = null ) { await Configuration . saveAnySetting ( 'preview.docutils.disabled' , true , resource ) ; } public static async setSyntaxHighlightingDisabled ( resource = null ) { await Configuration . saveAnySetting ( 'syntaxHighlighting.disabled' , true , resource ) ; } private static loadAnySetting < T > ( configSection , defaultValue , resource , header = 'restructuredtext' ) { return getConfig ( header , resource ) . get ( configSection , defaultValue ) ; } private static async saveAnySetting < T > ( configSection , value , resource , header = 'restructuredtext' ) { await getConfig ( header , resource ) . update ( configSection , value ) ; return value ; } private static loadSetting ( configSection , defaultValue , resource , expand = true , header = 'restructuredtext' ) { const result = this . loadAnySetting < string > ( configSection , defaultValue , resource , header ) ; if ( expand && result != null ) { return this . expandMacro ( result , resource ) ; } return result ; } private static async saveSetting ( configSection , value , resource , insertMacro = false , header = 'restructuredtext' ) { if ( insertMacro ) { value = this . insertMacro ( value , resource ) ; } return await this . saveAnySetting < string > ( configSection , value , resource , header ) ; } private static insertMacro ( input , resource ) { if ( resource == null ) { return input ; } let path ; if ( ! workspace . workspaceFolders ) { path = workspace . rootPath ; } else { let root ; if ( workspace . workspaceFolders . length === 1 ) { root = workspace . workspaceFolders [ 0 ] ; } else { root = workspace . getWorkspaceFolder ( resource ) ; } path = root . uri . fsPath ; } if ( input . startsWith ( path ) ) { return input . replace ( path , '${workspaceFolder}' ) ; } return input ; } public static expandMacro ( input , resource ) { if ( input . indexOf ( '${' ) === - 1 ) { return input ; } let expanded ; if ( input . indexOf ( '${env:' ) > - 1 ) { expanded = input . replace ( /\$\{env\:(.+)\}/ , ( match , p1 ) => { const variable = process . env [ p1 ] ; return variable == null ? '' : variable ; } ) ; } else { expanded = input ; } if ( expanded . indexOf ( '${' ) > - 1 ) { const path = this . GetRootPath ( resource ) ; if ( path ) { return expanded . replace ( '${workspaceRoot}' , path ) . replace ( '${workspaceFolder}' , path ) ; } } return expanded ; } public static GetRootPath ( resource ) { if ( ! workspace . workspaceFolders ) { return workspace . rootPath ?? path . dirname ( resource . fsPath ) ; } let root ; if ( workspace . workspaceFolders . length === 1 ) { root = workspace . workspaceFolders [ 0 ] ; } else { if ( resource == null ) { return undefined ; } root = workspace . getWorkspaceFolder ( resource ) ; } if ( root ) { return root . uri . fsPath ; } return undefined ; } }