diff --git a/CHANGELOG.md b/CHANGELOG.md index be7b32083..32fad5c15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Change Log -## 0.38.0 (January 30th, 2019) +## 0.38.0 (January 31st, 2019) +* enhancement - new dialog asking to hide java project settings files on startup. See [#776](https://github.com/redhat-developer/vscode-java/pull/776). * bug fix - pick up gradle properties updates when doing full build. See [#758](https://github.com/redhat-developer/vscode-java/issues/758). * bug fix - fixed inactive autocompletion after inserting a snippet in some cases. See [#768](https://github.com/redhat-developer/vscode-java/issues/768). diff --git a/README.md b/README.md index a8dd5866b..a4d28af5b 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ The following settings are supported: * `java.import.gradle.enabled` : Enable/disable the Gradle importer. * `java.import.maven.enabled` : Enable/disable the Maven importer. * `java.autobuild.enabled` : Enable/disable the 'auto build'. +* `java.maxConcurrentBuilds`: Set max simultaneous project builds. * `java.completion.favoriteStaticMembers` : Defines a list of static members or types with static members. * `java.completion.importOrder` : Defines the sorting order of import statements. * `java.progressReports.enabled` : [Experimental] Enable/disable progress reports from background processes on the server. @@ -91,8 +92,8 @@ The following settings are supported: * `java.completion.guessMethodArguments` : When set to true, method arguments are guessed when a method is selected from as list of code assist proposals. * `java.completion.enabled` : Enable/disable code completion support. -*New in 0.36.0:* -* `java.maxConcurrentBuilds`: Set max simultaneous project builds. +*New in 0.38.0:* +* `java.configuration.checkProjectSettingsExclusions`: Checks if the extension-generated project settings files (`.project`, `.classpath`, `.factorypath`, `.settings/`) should be excluded from the file explorer. Defaults to `true`. Troubleshooting diff --git a/package-lock.json b/package-lock.json index bd37d6ff8..ba19ca751 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1520,7 +1520,7 @@ }, "deep-assign": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=", "dev": true, "requires": { @@ -1647,7 +1647,7 @@ }, "duplexer": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, @@ -1866,7 +1866,7 @@ }, "event-stream": { "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", "dev": true, "requires": { @@ -1881,7 +1881,7 @@ "dependencies": { "map-stream": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "resolved": "http://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", "dev": true } @@ -2428,12 +2428,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2448,17 +2450,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -2575,7 +2580,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -2587,6 +2593,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2601,6 +2608,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2608,12 +2616,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -2632,6 +2642,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -2712,7 +2723,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -2724,6 +2736,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2845,6 +2858,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3323,7 +3337,7 @@ }, "kind-of": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", "dev": true }, @@ -3372,7 +3386,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -3384,13 +3398,13 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "through2": { "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { @@ -4327,7 +4341,7 @@ }, "is-obj": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, @@ -5641,7 +5655,7 @@ }, "pause-stream": { "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "requires": { @@ -6491,7 +6505,7 @@ }, "split": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "resolved": "http://registry.npmjs.org/split/-/split-0.3.3.tgz", "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", "dev": true, "requires": { @@ -6584,7 +6598,7 @@ }, "stream-combiner": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", "dev": true, "requires": { @@ -6728,7 +6742,7 @@ }, "tar": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "dev": true, "requires": { diff --git a/package.json b/package.json index dd29f2668..99393335d 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,12 @@ "description": "Specifies the severity of the message when the classpath is incomplete for a Java file", "scope": "window" }, + "java.configuration.checkProjectSettingsExclusions": { + "type": "boolean", + "default": true, + "description": "Checks if the extension-generated project settings files (.project, .classpath, .factorypath, .settings/) should be excluded from the file explorer.", + "scope": "window" + }, "java.configuration.updateBuildConfiguration": { "type": [ "string" diff --git a/src/extension.ts b/src/extension.ts index 6711be092..f923e6fde 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -14,8 +14,9 @@ SourceAttachmentRequest, SourceAttachmentResult, SourceAttachmentAttribute } fro import { ExtensionAPI } from './extension.api'; import * as buildpath from './buildpath'; import * as net from 'net'; +import { getJavaConfiguration } from './utils'; +import { onConfigurationChange, excludeProjectSettingsFiles } from './settings'; -let oldConfig; let lastStatus; let languageClient: LanguageClient; let jdtEventEmitter = new EventEmitter(); @@ -83,7 +84,6 @@ export function activate(context: ExtensionContext): Promise { item.command = Commands.OPEN_OUTPUT; let progressBar = window.createStatusBarItem(StatusBarAlignment.Left, Number.MIN_VALUE+1); - oldConfig = getJavaConfiguration(); let serverOptions; let port = process.env['SERVER_PORT']; if (!port) { @@ -300,6 +300,7 @@ export function activate(context: ExtensionContext): Promise { } }; workspace.registerTextDocumentContentProvider('jdt', provider); + excludeProjectSettingsFiles(); }); let cleanWorkspaceExists = fs.existsSync( path.join(workspacePath, cleanWorkspaceFileName)); @@ -434,34 +435,6 @@ function isJavaConfigFile(path: String) { return path.endsWith('pom.xml') || path.endsWith('.gradle'); } -function onConfigurationChange() { - return workspace.onDidChangeConfiguration(params => { - let newConfig = getJavaConfiguration(); - if (hasJavaConfigChanged(oldConfig, newConfig)) { - let msg = 'Java Language Server configuration changed, please restart VS Code.'; - let action = 'Restart Now'; - let restartId = Commands.RELOAD_WINDOW; - oldConfig = newConfig; - window.showWarningMessage(msg, action).then((selection) => { - if (action === selection) { - commands.executeCommand(restartId); - } - }); - } - }); -} - -function hasJavaConfigChanged(oldConfig, newConfig) { - return hasConfigKeyChanged('home', oldConfig, newConfig) - || hasConfigKeyChanged('jdt.ls.vmargs', oldConfig, newConfig) - || hasConfigKeyChanged('progressReports.enabled', oldConfig, newConfig); -} - -function hasConfigKeyChanged(key, oldConfig, newConfig) { - return oldConfig.get(key) !== newConfig.get(key); -} - - function getTempWorkspace() { return path.resolve(os.tmpdir(), 'vscodesws_' + makeRandomHexString(5)); } @@ -476,9 +449,6 @@ function makeRandomHexString(length) { return result; } -function getJavaConfiguration(): WorkspaceConfiguration { - return workspace.getConfiguration('java'); -} async function cleanWorkspace(workspacePath) { const doIt = 'Restart and delete'; @@ -745,4 +715,4 @@ function isPrefix(parentPath: string, childPath: string): boolean { } const relative = path.relative(parentPath, childPath); return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative); -} \ No newline at end of file +} diff --git a/src/settings.ts b/src/settings.ts new file mode 100644 index 000000000..2f2351489 --- /dev/null +++ b/src/settings.ts @@ -0,0 +1,104 @@ +'use strict'; + +import { window, Uri, workspace, WorkspaceConfiguration, commands, ConfigurationTarget } from 'vscode'; +import { LanguageClient } from 'vscode-languageclient'; +import { Commands } from './commands'; +import { getJavaConfiguration } from './utils'; + + +const DEFAULT_HIDDEN_FILES: string[] = ['**/.classpath', '**/.project', '**/.settings', '**/.factorypath']; + +const changeItem = { + global: 'Exclude globally', + workspace: 'Exclude in workspace', + never: 'Never' +}; + +const EXCLUDE_FILE_CONFIG = 'configuration.checkProjectSettingsExclusions'; + +let oldConfig: WorkspaceConfiguration = getJavaConfiguration(); + +export function onConfigurationChange() { + return workspace.onDidChangeConfiguration(params => { + if (!params.affectsConfiguration('java')) { + return; + } + let newConfig = getJavaConfiguration(); + if (newConfig.get(EXCLUDE_FILE_CONFIG)) { + excludeProjectSettingsFiles(); + } + if (hasJavaConfigChanged(oldConfig, newConfig)) { + let msg = 'Java Language Server configuration changed, please restart VS Code.'; + let action = 'Restart Now'; + let restartId = Commands.RELOAD_WINDOW; + oldConfig = newConfig; + window.showWarningMessage(msg, action).then((selection) => { + if (action === selection) { + commands.executeCommand(restartId); + } + }); + } + }); +} + +export function excludeProjectSettingsFiles() { + if (workspace.workspaceFolders && workspace.workspaceFolders.length) { + workspace.workspaceFolders.forEach((folder) => { + excludeProjectSettingsFilesForWorkspace(folder.uri); + }); + } +} + +function excludeProjectSettingsFilesForWorkspace(workspaceUri: Uri) { + const excudedConfig = getJavaConfiguration().get(EXCLUDE_FILE_CONFIG); + if (excudedConfig) { + const config = workspace.getConfiguration('files', workspaceUri); + const excludedValue: Object = config.get('exclude'); + const needExcludeFiles: string[] = []; + + let needUpdate = false; + for (const hiddenFile of DEFAULT_HIDDEN_FILES) { + if (!excludedValue.hasOwnProperty(hiddenFile)) { + needExcludeFiles.push(hiddenFile); + needUpdate = true; + } + } + if (needUpdate) { + const excludedInspectedValue = config.inspect('exclude'); + const items = [changeItem.workspace, changeItem.never]; + // Workspace file.exclude is undefined + if (!excludedInspectedValue.workspaceValue) { + items.unshift(changeItem.global); + } + + window.showInformationMessage('Do you want to exclude the VS Code Java project settings files (.classpath, .project. .settings, .factorypath) from the file explorer?', ...items).then((result) => { + if (result === changeItem.global) { + excludedInspectedValue.globalValue = excludedInspectedValue.globalValue || {}; + for (const hiddenFile of needExcludeFiles) { + excludedInspectedValue.globalValue[hiddenFile] = true; + } + config.update('exclude', excludedInspectedValue.globalValue, ConfigurationTarget.Global); + } if (result === changeItem.workspace) { + excludedInspectedValue.workspaceValue = excludedInspectedValue.workspaceValue || {}; + for (const hiddenFile of needExcludeFiles) { + excludedInspectedValue.workspaceValue[hiddenFile] = true; + } + config.update('exclude', excludedInspectedValue.workspaceValue, ConfigurationTarget.Workspace); + } else if (result === changeItem.never) { + const storeInWorkspace = getJavaConfiguration().inspect(EXCLUDE_FILE_CONFIG).workspaceValue; + getJavaConfiguration().update(EXCLUDE_FILE_CONFIG, false, storeInWorkspace?ConfigurationTarget.Workspace:ConfigurationTarget.Global); + } + }); + } + } +} + +function hasJavaConfigChanged(oldConfig: WorkspaceConfiguration, newConfig: WorkspaceConfiguration) { + return hasConfigKeyChanged('home', oldConfig, newConfig) + || hasConfigKeyChanged('jdt.ls.vmargs', oldConfig, newConfig) + || hasConfigKeyChanged('progressReports.enabled', oldConfig, newConfig); +} + +function hasConfigKeyChanged(key, oldConfig, newConfig) { + return oldConfig.get(key) !== newConfig.get(key); +} diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 000000000..9e53cb116 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,7 @@ +'use strict'; + +import { workspace, WorkspaceConfiguration } from 'vscode'; + +export function getJavaConfiguration(): WorkspaceConfiguration { + return workspace.getConfiguration('java'); +}