mirror of
https://github.com/Microsoft/vscode
synced 2024-09-18 01:58:27 +00:00
Merge branch 'main' into mlively/pasteRefactor
This commit is contained in:
commit
6273efd6b6
|
@ -152,6 +152,7 @@ exports.config = {
|
|||
'F# script': ['fsx', 'fsscript'],
|
||||
'SVG document': ['svg', 'svgz'],
|
||||
'TOML document': 'toml',
|
||||
'Swift source code': 'swift',
|
||||
}, 'default'),
|
||||
// Default icon with default name
|
||||
darwinBundleDocumentType([
|
||||
|
|
|
@ -167,6 +167,7 @@ export const config = {
|
|||
'F# script': ['fsx', 'fsscript'],
|
||||
'SVG document': ['svg', 'svgz'],
|
||||
'TOML document': 'toml',
|
||||
'Swift source code': 'swift',
|
||||
}, 'default'),
|
||||
// Default icon with default name
|
||||
darwinBundleDocumentType([
|
||||
|
|
|
@ -13,6 +13,7 @@ const Parser = require("tree-sitter");
|
|||
const node_fetch_1 = require("node-fetch");
|
||||
const { typescript } = require('tree-sitter-typescript');
|
||||
const product = require('../../product.json');
|
||||
const packageJson = require('../../package.json');
|
||||
function isNlsString(value) {
|
||||
return value ? typeof value !== 'string' : false;
|
||||
}
|
||||
|
@ -408,16 +409,11 @@ const Languages = {
|
|||
'tr': 'tr-tr',
|
||||
'pl': 'pl-pl',
|
||||
};
|
||||
async function getLatestStableVersion(updateUrl) {
|
||||
const res = await (0, node_fetch_1.default)(`${updateUrl}/api/update/darwin/stable/latest`);
|
||||
const { name: version } = await res.json();
|
||||
return version;
|
||||
}
|
||||
async function getSpecificNLS(resourceUrlTemplate, languageId, version) {
|
||||
const resource = {
|
||||
publisher: 'ms-ceintl',
|
||||
name: `vscode-language-pack-${languageId}`,
|
||||
version,
|
||||
version: `${version[0]}.${version[1]}.${version[2]}`,
|
||||
path: 'extension/translations/main.i18n.json'
|
||||
};
|
||||
const url = resourceUrlTemplate.replace(/\{([^}]+)\}/g, (_, key) => resource[key]);
|
||||
|
@ -428,35 +424,47 @@ async function getSpecificNLS(resourceUrlTemplate, languageId, version) {
|
|||
const { contents: result } = await res.json();
|
||||
return result;
|
||||
}
|
||||
function previousVersion(version) {
|
||||
const [, major, minor, patch] = /^(\d+)\.(\d+)\.(\d+)$/.exec(version);
|
||||
return `${major}.${parseInt(minor) - 1}.${patch}`;
|
||||
function parseVersion(version) {
|
||||
const [, major, minor, patch] = /^(\d+)\.(\d+)\.(\d+)/.exec(version);
|
||||
return [parseInt(major), parseInt(minor), parseInt(patch)];
|
||||
}
|
||||
async function getNLS(resourceUrlTemplate, languageId, version) {
|
||||
try {
|
||||
return await getSpecificNLS(resourceUrlTemplate, languageId, version);
|
||||
function compareVersions(a, b) {
|
||||
if (a[0] !== b[0]) {
|
||||
return a[0] - b[0];
|
||||
}
|
||||
catch (err) {
|
||||
if (/\[404\]/.test(err.message)) {
|
||||
const thePreviousVersion = previousVersion(version);
|
||||
console.warn(`Language pack ${languageId}@${version} is missing. Downloading previous version ${thePreviousVersion}...`);
|
||||
try {
|
||||
return await getSpecificNLS(resourceUrlTemplate, languageId, thePreviousVersion);
|
||||
if (a[1] !== b[1]) {
|
||||
return a[1] - b[1];
|
||||
}
|
||||
catch (err) {
|
||||
if (/\[404\]/.test(err.message)) {
|
||||
console.warn(`Language pack ${languageId}@${thePreviousVersion} is missing. Downloading previous version...`);
|
||||
return await getSpecificNLS(resourceUrlTemplate, languageId, previousVersion(thePreviousVersion));
|
||||
return a[2] - b[2];
|
||||
}
|
||||
else {
|
||||
throw err;
|
||||
async function queryVersions(serviceUrl, languageId) {
|
||||
const res = await (0, node_fetch_1.default)(`${serviceUrl}/extensionquery`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json;api-version=3.0-preview.1',
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'VS Code Build',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
filters: [{ criteria: [{ filterType: 7, value: `ms-ceintl.vscode-language-pack-${languageId}` }] }],
|
||||
flags: 0x1
|
||||
})
|
||||
});
|
||||
if (res.status !== 200) {
|
||||
throw new Error(`[${res.status}] Error querying for extension: ${languageId}`);
|
||||
}
|
||||
const result = await res.json();
|
||||
return result.results[0].extensions[0].versions.map(v => parseVersion(v.version)).sort(compareVersions);
|
||||
}
|
||||
async function getNLS(extensionGalleryServiceUrl, resourceUrlTemplate, languageId, version) {
|
||||
const versions = await queryVersions(extensionGalleryServiceUrl, languageId);
|
||||
const nextMinor = [version[0], version[1] + 1, 0];
|
||||
const compatibleVersions = versions.filter(v => compareVersions(v, nextMinor) < 0);
|
||||
const latestCompatibleVersion = compatibleVersions.at(-1); // order is newest to oldest
|
||||
if (!latestCompatibleVersion) {
|
||||
throw new Error(`No compatible language pack found for ${languageId} for version ${version}`);
|
||||
}
|
||||
else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
return await getSpecificNLS(resourceUrlTemplate, languageId, latestCompatibleVersion);
|
||||
}
|
||||
async function parsePolicies() {
|
||||
const parser = new Parser();
|
||||
|
@ -473,9 +481,9 @@ async function parsePolicies() {
|
|||
return policies;
|
||||
}
|
||||
async function getTranslations() {
|
||||
const updateUrl = product.updateUrl;
|
||||
if (!updateUrl) {
|
||||
console.warn(`Skipping policy localization: No 'updateUrl' found in 'product.json'.`);
|
||||
const extensionGalleryServiceUrl = product.extensionsGallery?.serviceUrl;
|
||||
if (!extensionGalleryServiceUrl) {
|
||||
console.warn(`Skipping policy localization: No 'extensionGallery.serviceUrl' found in 'product.json'.`);
|
||||
return [];
|
||||
}
|
||||
const resourceUrlTemplate = product.extensionsGallery?.resourceUrlTemplate;
|
||||
|
@ -483,9 +491,9 @@ async function getTranslations() {
|
|||
console.warn(`Skipping policy localization: No 'resourceUrlTemplate' found in 'product.json'.`);
|
||||
return [];
|
||||
}
|
||||
const version = await getLatestStableVersion(updateUrl);
|
||||
const version = parseVersion(packageJson.version);
|
||||
const languageIds = Object.keys(Languages);
|
||||
return await Promise.all(languageIds.map(languageId => getNLS(resourceUrlTemplate, languageId, version)
|
||||
return await Promise.all(languageIds.map(languageId => getNLS(extensionGalleryServiceUrl, resourceUrlTemplate, languageId, version)
|
||||
.then(languageTranslations => ({ languageId, languageTranslations }))));
|
||||
}
|
||||
async function main() {
|
||||
|
|
|
@ -12,6 +12,7 @@ import * as Parser from 'tree-sitter';
|
|||
import fetch from 'node-fetch';
|
||||
const { typescript } = require('tree-sitter-typescript');
|
||||
const product = require('../../product.json');
|
||||
const packageJson = require('../../package.json');
|
||||
|
||||
type NlsString = { value: string; nlsKey: string };
|
||||
|
||||
|
@ -587,17 +588,13 @@ const Languages = {
|
|||
type LanguageTranslations = { [moduleName: string]: { [nlsKey: string]: string } };
|
||||
type Translations = { languageId: string; languageTranslations: LanguageTranslations }[];
|
||||
|
||||
async function getLatestStableVersion(updateUrl: string) {
|
||||
const res = await fetch(`${updateUrl}/api/update/darwin/stable/latest`);
|
||||
const { name: version } = await res.json() as { name: string };
|
||||
return version;
|
||||
}
|
||||
type Version = [number, number, number];
|
||||
|
||||
async function getSpecificNLS(resourceUrlTemplate: string, languageId: string, version: string) {
|
||||
async function getSpecificNLS(resourceUrlTemplate: string, languageId: string, version: Version) {
|
||||
const resource = {
|
||||
publisher: 'ms-ceintl',
|
||||
name: `vscode-language-pack-${languageId}`,
|
||||
version,
|
||||
version: `${version[0]}.${version[1]}.${version[2]}`,
|
||||
path: 'extension/translations/main.i18n.json'
|
||||
};
|
||||
|
||||
|
@ -612,32 +609,50 @@ async function getSpecificNLS(resourceUrlTemplate: string, languageId: string, v
|
|||
return result;
|
||||
}
|
||||
|
||||
function previousVersion(version: string): string {
|
||||
const [, major, minor, patch] = /^(\d+)\.(\d+)\.(\d+)$/.exec(version)!;
|
||||
return `${major}.${parseInt(minor) - 1}.${patch}`;
|
||||
function parseVersion(version: string): Version {
|
||||
const [, major, minor, patch] = /^(\d+)\.(\d+)\.(\d+)/.exec(version)!;
|
||||
return [parseInt(major), parseInt(minor), parseInt(patch)];
|
||||
}
|
||||
|
||||
async function getNLS(resourceUrlTemplate: string, languageId: string, version: string) {
|
||||
try {
|
||||
return await getSpecificNLS(resourceUrlTemplate, languageId, version);
|
||||
} catch (err) {
|
||||
if (/\[404\]/.test(err.message)) {
|
||||
const thePreviousVersion = previousVersion(version);
|
||||
console.warn(`Language pack ${languageId}@${version} is missing. Downloading previous version ${thePreviousVersion}...`);
|
||||
try {
|
||||
return await getSpecificNLS(resourceUrlTemplate, languageId, thePreviousVersion);
|
||||
} catch (err) {
|
||||
if (/\[404\]/.test(err.message)) {
|
||||
console.warn(`Language pack ${languageId}@${thePreviousVersion} is missing. Downloading previous version...`);
|
||||
return await getSpecificNLS(resourceUrlTemplate, languageId, previousVersion(thePreviousVersion));
|
||||
} else {
|
||||
throw err;
|
||||
function compareVersions(a: Version, b: Version): number {
|
||||
if (a[0] !== b[0]) { return a[0] - b[0]; }
|
||||
if (a[1] !== b[1]) { return a[1] - b[1]; }
|
||||
return a[2] - b[2];
|
||||
}
|
||||
|
||||
async function queryVersions(serviceUrl: string, languageId: string): Promise<Version[]> {
|
||||
const res = await fetch(`${serviceUrl}/extensionquery`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json;api-version=3.0-preview.1',
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'VS Code Build',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
filters: [{ criteria: [{ filterType: 7, value: `ms-ceintl.vscode-language-pack-${languageId}` }] }],
|
||||
flags: 0x1
|
||||
})
|
||||
});
|
||||
|
||||
if (res.status !== 200) {
|
||||
throw new Error(`[${res.status}] Error querying for extension: ${languageId}`);
|
||||
}
|
||||
} else {
|
||||
throw err;
|
||||
|
||||
const result = await res.json() as { results: [{ extensions: { versions: { version: string }[] }[] }] };
|
||||
return result.results[0].extensions[0].versions.map(v => parseVersion(v.version)).sort(compareVersions);
|
||||
}
|
||||
|
||||
async function getNLS(extensionGalleryServiceUrl: string, resourceUrlTemplate: string, languageId: string, version: Version) {
|
||||
const versions = await queryVersions(extensionGalleryServiceUrl, languageId);
|
||||
const nextMinor: Version = [version[0], version[1] + 1, 0];
|
||||
const compatibleVersions = versions.filter(v => compareVersions(v, nextMinor) < 0);
|
||||
const latestCompatibleVersion = compatibleVersions.at(-1)!; // order is newest to oldest
|
||||
|
||||
if (!latestCompatibleVersion) {
|
||||
throw new Error(`No compatible language pack found for ${languageId} for version ${version}`);
|
||||
}
|
||||
|
||||
return await getSpecificNLS(resourceUrlTemplate, languageId, latestCompatibleVersion);
|
||||
}
|
||||
|
||||
async function parsePolicies(): Promise<Policy[]> {
|
||||
|
@ -659,10 +674,10 @@ async function parsePolicies(): Promise<Policy[]> {
|
|||
}
|
||||
|
||||
async function getTranslations(): Promise<Translations> {
|
||||
const updateUrl = product.updateUrl;
|
||||
const extensionGalleryServiceUrl = product.extensionsGallery?.serviceUrl;
|
||||
|
||||
if (!updateUrl) {
|
||||
console.warn(`Skipping policy localization: No 'updateUrl' found in 'product.json'.`);
|
||||
if (!extensionGalleryServiceUrl) {
|
||||
console.warn(`Skipping policy localization: No 'extensionGallery.serviceUrl' found in 'product.json'.`);
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -673,11 +688,11 @@ async function getTranslations(): Promise<Translations> {
|
|||
return [];
|
||||
}
|
||||
|
||||
const version = await getLatestStableVersion(updateUrl);
|
||||
const version = parseVersion(packageJson.version);
|
||||
const languageIds = Object.keys(Languages);
|
||||
|
||||
return await Promise.all(languageIds.map(
|
||||
languageId => getNLS(resourceUrlTemplate, languageId, version)
|
||||
languageId => getNLS(extensionGalleryServiceUrl, resourceUrlTemplate, languageId, version)
|
||||
.then(languageTranslations => ({ languageId, languageTranslations }))
|
||||
));
|
||||
}
|
||||
|
|
538
cgmanifest.json
538
cgmanifest.json
|
@ -55,135 +55,433 @@
|
|||
"license": "LGPL-2.1+",
|
||||
"version": "4.4.git",
|
||||
"licenseDetail": [
|
||||
"# License",
|
||||
" GNU LESSER GENERAL PUBLIC LICENSE",
|
||||
" Version 2.1, February 1999",
|
||||
" Copyright (C) 1991, 1999 Free Software Foundation, Inc.",
|
||||
" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA",
|
||||
" Everyone is permitted to copy and distribute verbatim copies",
|
||||
" of this license document, but changing it is not allowed.",
|
||||
"[This is the first released version of the Lesser GPL. It also counts",
|
||||
" as the successor of the GNU Library Public License, version 2, hence",
|
||||
" the version number 2.1.]",
|
||||
" Preamble",
|
||||
" The licenses for most software are designed to take away your",
|
||||
"freedom to share and change it. By contrast, the GNU General Public",
|
||||
"Licenses are intended to guarantee your freedom to share and change",
|
||||
"free software--to make sure the software is free for all its users.",
|
||||
" This license, the Lesser General Public License, applies to some",
|
||||
"specially designated software packages--typically libraries--of the",
|
||||
"Free Software Foundation and other authors who decide to use it. You",
|
||||
"can use it too, but we suggest you first think carefully about whether",
|
||||
"this license or the ordinary General Public License is the better",
|
||||
"strategy to use in any particular case, based on the explanations below.",
|
||||
" When we speak of free software, we are referring to freedom of use,",
|
||||
"not price. Our General Public Licenses are designed to make sure that",
|
||||
"you have the freedom to distribute copies of free software (and charge",
|
||||
"for this service if you wish); that you receive source code or can get",
|
||||
"it if you want it; that you can change the software and use pieces of",
|
||||
"it in new free programs; and that you are informed that you can do",
|
||||
"these things.",
|
||||
" To protect your rights, we need to make restrictions that forbid",
|
||||
"distributors to deny you these rights or to ask you to surrender these",
|
||||
"rights. These restrictions translate to certain responsibilities for",
|
||||
"you if you distribute copies of the library or if you modify it.",
|
||||
" For example, if you distribute copies of the library, whether gratis",
|
||||
"or for a fee, you must give the recipients all the rights that we gave",
|
||||
"you. You must make sure that they, too, receive or can get the source",
|
||||
"code. If you link other code with the library, you must provide",
|
||||
"complete object files to the recipients, so that they can relink them",
|
||||
"with the library after making changes to the library and recompiling",
|
||||
"it. And you must show them these terms so they know their rights.",
|
||||
" We protect your rights with a two-step method: (1) we copyright the",
|
||||
"library, and (2) we offer you this license, which gives you legal",
|
||||
"permission to copy, distribute and/or modify the library.",
|
||||
" To protect each distributor, we want to make it very clear that",
|
||||
"there is no warranty for the free library. Also, if the library is",
|
||||
"modified by someone else and passed on, the recipients should know",
|
||||
"that what they have is not the original version, so that the original",
|
||||
"author's reputation will not be affected by problems that might be",
|
||||
"introduced by others.",
|
||||
"",
|
||||
"Most files in FFmpeg are under the GNU Lesser General Public License version 2.1",
|
||||
"or later (LGPL v2.1+). Read the file `COPYING.LGPLv2.1` for details. Some other",
|
||||
"files have MIT/X11/BSD-style licenses. In combination the LGPL v2.1+ applies to",
|
||||
"FFmpeg.",
|
||||
" Finally, software patents pose a constant threat to the existence of",
|
||||
"any free program. We wish to make sure that a company cannot",
|
||||
"effectively restrict the users of a free program by obtaining a",
|
||||
"restrictive license from a patent holder. Therefore, we insist that",
|
||||
"any patent license obtained for a version of the library must be",
|
||||
"consistent with the full freedom of use specified in this license.",
|
||||
" Most GNU software, including some libraries, is covered by the",
|
||||
"ordinary GNU General Public License. This license, the GNU Lesser",
|
||||
"General Public License, applies to certain designated libraries, and",
|
||||
"is quite different from the ordinary General Public License. We use",
|
||||
"this license for certain libraries in order to permit linking those",
|
||||
"libraries into non-free programs.",
|
||||
" When a program is linked with a library, whether statically or using",
|
||||
"a shared library, the combination of the two is legally speaking a",
|
||||
"combined work, a derivative of the original library. The ordinary",
|
||||
"General Public License therefore permits such linking only if the",
|
||||
"entire combination fits its criteria of freedom. The Lesser General",
|
||||
"Public License permits more lax criteria for linking other code with",
|
||||
"the library.",
|
||||
" We call this license the \"Lesser\" General Public License because it",
|
||||
"does Less to protect the user's freedom than the ordinary General",
|
||||
"Public License. It also provides other free software developers Less",
|
||||
"of an advantage over competing non-free programs. These disadvantages",
|
||||
"are the reason we use the ordinary General Public License for many",
|
||||
"libraries. However, the Lesser license provides advantages in certain",
|
||||
"special circumstances.",
|
||||
" For example, on rare occasions, there may be a special need to",
|
||||
"encourage the widest possible use of a certain library, so that it becomes",
|
||||
"a de-facto standard. To achieve this, non-free programs must be",
|
||||
"allowed to use the library. A more frequent case is that a free",
|
||||
"library does the same job as widely used non-free libraries. In this",
|
||||
"case, there is little to gain by limiting the free library to free",
|
||||
"software only, so we use the Lesser General Public License.",
|
||||
" In other cases, permission to use a particular library in non-free",
|
||||
"programs enables a greater number of people to use a large body of",
|
||||
"free software. For example, permission to use the GNU C Library in",
|
||||
"non-free programs enables many more people to use the whole GNU",
|
||||
"operating system, as well as its variant, the GNU/Linux operating",
|
||||
"system.",
|
||||
" Although the Lesser General Public License is Less protective of the",
|
||||
"users' freedom, it does ensure that the user of a program that is",
|
||||
"linked with the Library has the freedom and the wherewithal to run",
|
||||
"that program using a modified version of the Library.",
|
||||
" The precise terms and conditions for copying, distribution and",
|
||||
"modification follow. Pay close attention to the difference between a",
|
||||
"\"work based on the library\" and a \"work that uses the library\". The",
|
||||
"former contains code derived from the library, whereas the latter must",
|
||||
"be combined with the library in order to run.",
|
||||
"",
|
||||
"Some optional parts of FFmpeg are licensed under the GNU General Public License",
|
||||
"version 2 or later (GPL v2+). See the file `COPYING.GPLv2` for details. None of",
|
||||
"these parts are used by default, you have to explicitly pass `--enable-gpl` to",
|
||||
"configure to activate them. In this case, FFmpeg's license changes to GPL v2+.",
|
||||
" GNU LESSER GENERAL PUBLIC LICENSE",
|
||||
" TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION",
|
||||
" 0. This License Agreement applies to any software library or other",
|
||||
"program which contains a notice placed by the copyright holder or",
|
||||
"other authorized party saying it may be distributed under the terms of",
|
||||
"this Lesser General Public License (also called \"this License\").",
|
||||
"Each licensee is addressed as \"you\".",
|
||||
" A \"library\" means a collection of software functions and/or data",
|
||||
"prepared so as to be conveniently linked with application programs",
|
||||
"(which use some of those functions and data) to form executables.",
|
||||
" The \"Library\", below, refers to any such software library or work",
|
||||
"which has been distributed under these terms. A \"work based on the",
|
||||
"Library\" means either the Library or any derivative work under",
|
||||
"copyright law: that is to say, a work containing the Library or a",
|
||||
"portion of it, either verbatim or with modifications and/or translated",
|
||||
"straightforwardly into another language. (Hereinafter, translation is",
|
||||
"included without limitation in the term \"modification\".)",
|
||||
" \"Source code\" for a work means the preferred form of the work for",
|
||||
"making modifications to it. For a library, complete source code means",
|
||||
"all the source code for all modules it contains, plus any associated",
|
||||
"interface definition files, plus the scripts used to control compilation",
|
||||
"and installation of the library.",
|
||||
" Activities other than copying, distribution and modification are not",
|
||||
"covered by this License; they are outside its scope. The act of",
|
||||
"running a program using the Library is not restricted, and output from",
|
||||
"such a program is covered only if its contents constitute a work based",
|
||||
"on the Library (independent of the use of the Library in a tool for",
|
||||
"writing it). Whether that is true depends on what the Library does",
|
||||
"and what the program that uses the Library does.",
|
||||
" 1. You may copy and distribute verbatim copies of the Library's",
|
||||
"complete source code as you receive it, in any medium, provided that",
|
||||
"you conspicuously and appropriately publish on each copy an",
|
||||
"appropriate copyright notice and disclaimer of warranty; keep intact",
|
||||
"all the notices that refer to this License and to the absence of any",
|
||||
"warranty; and distribute a copy of this License along with the",
|
||||
"Library.",
|
||||
" You may charge a fee for the physical act of transferring a copy,",
|
||||
"and you may at your option offer warranty protection in exchange for a",
|
||||
"fee.",
|
||||
"",
|
||||
"Specifically, the GPL parts of FFmpeg are:",
|
||||
" 2. You may modify your copy or copies of the Library or any portion",
|
||||
"of it, thus forming a work based on the Library, and copy and",
|
||||
"distribute such modifications or work under the terms of Section 1",
|
||||
"above, provided that you also meet all of these conditions:",
|
||||
" a) The modified work must itself be a software library.",
|
||||
" b) You must cause the files modified to carry prominent notices",
|
||||
" stating that you changed the files and the date of any change.",
|
||||
" c) You must cause the whole of the work to be licensed at no",
|
||||
" charge to all third parties under the terms of this License.",
|
||||
" d) If a facility in the modified Library refers to a function or a",
|
||||
" table of data to be supplied by an application program that uses",
|
||||
" the facility, other than as an argument passed when the facility",
|
||||
" is invoked, then you must make a good faith effort to ensure that,",
|
||||
" in the event an application does not supply such function or",
|
||||
" table, the facility still operates, and performs whatever part of",
|
||||
" its purpose remains meaningful.",
|
||||
" (For example, a function in a library to compute square roots has",
|
||||
" a purpose that is entirely well-defined independent of the",
|
||||
" application. Therefore, Subsection 2d requires that any",
|
||||
" application-supplied function or table used by this function must",
|
||||
" be optional: if the application does not supply it, the square",
|
||||
" root function must still compute square roots.)",
|
||||
"These requirements apply to the modified work as a whole. If",
|
||||
"identifiable sections of that work are not derived from the Library,",
|
||||
"and can be reasonably considered independent and separate works in",
|
||||
"themselves, then this License, and its terms, do not apply to those",
|
||||
"sections when you distribute them as separate works. But when you",
|
||||
"distribute the same sections as part of a whole which is a work based",
|
||||
"on the Library, the distribution of the whole must be on the terms of",
|
||||
"this License, whose permissions for other licensees extend to the",
|
||||
"entire whole, and thus to each and every part regardless of who wrote",
|
||||
"it.",
|
||||
"Thus, it is not the intent of this section to claim rights or contest",
|
||||
"your rights to work written entirely by you; rather, the intent is to",
|
||||
"exercise the right to control the distribution of derivative or",
|
||||
"collective works based on the Library.",
|
||||
"In addition, mere aggregation of another work not based on the Library",
|
||||
"with the Library (or with a work based on the Library) on a volume of",
|
||||
"a storage or distribution medium does not bring the other work under",
|
||||
"the scope of this License.",
|
||||
" 3. You may opt to apply the terms of the ordinary GNU General Public",
|
||||
"License instead of this License to a given copy of the Library. To do",
|
||||
"this, you must alter all the notices that refer to this License, so",
|
||||
"that they refer to the ordinary GNU General Public License, version 2,",
|
||||
"instead of to this License. (If a newer version than version 2 of the",
|
||||
"ordinary GNU General Public License has appeared, then you can specify",
|
||||
"that version instead if you wish.) Do not make any other change in",
|
||||
"these notices.",
|
||||
"",
|
||||
"- libpostproc",
|
||||
"- optional x86 optimization in the files",
|
||||
" - `libavcodec/x86/flac_dsp_gpl.asm`",
|
||||
" - `libavcodec/x86/idct_mmx.c`",
|
||||
" - `libavfilter/x86/vf_removegrain.asm`",
|
||||
"- the following building and testing tools",
|
||||
" - `compat/solaris/make_sunver.pl`",
|
||||
" - `doc/t2h.pm`",
|
||||
" - `doc/texi2pod.pl`",
|
||||
" - `libswresample/tests/swresample.c`",
|
||||
" - `tests/checkasm/*`",
|
||||
" - `tests/tiny_ssim.c`",
|
||||
"- the following filters in libavfilter:",
|
||||
" - `signature_lookup.c`",
|
||||
" - `vf_blackframe.c`",
|
||||
" - `vf_boxblur.c`",
|
||||
" - `vf_colormatrix.c`",
|
||||
" - `vf_cover_rect.c`",
|
||||
" - `vf_cropdetect.c`",
|
||||
" - `vf_delogo.c`",
|
||||
" - `vf_eq.c`",
|
||||
" - `vf_find_rect.c`",
|
||||
" - `vf_fspp.c`",
|
||||
" - `vf_histeq.c`",
|
||||
" - `vf_hqdn3d.c`",
|
||||
" - `vf_kerndeint.c`",
|
||||
" - `vf_lensfun.c` (GPL version 3 or later)",
|
||||
" - `vf_mcdeint.c`",
|
||||
" - `vf_mpdecimate.c`",
|
||||
" - `vf_nnedi.c`",
|
||||
" - `vf_owdenoise.c`",
|
||||
" - `vf_perspective.c`",
|
||||
" - `vf_phase.c`",
|
||||
" - `vf_pp.c`",
|
||||
" - `vf_pp7.c`",
|
||||
" - `vf_pullup.c`",
|
||||
" - `vf_repeatfields.c`",
|
||||
" - `vf_sab.c`",
|
||||
" - `vf_signature.c`",
|
||||
" - `vf_smartblur.c`",
|
||||
" - `vf_spp.c`",
|
||||
" - `vf_stereo3d.c`",
|
||||
" - `vf_super2xsai.c`",
|
||||
" - `vf_tinterlace.c`",
|
||||
" - `vf_uspp.c`",
|
||||
" - `vf_vaguedenoiser.c`",
|
||||
" - `vsrc_mptestsrc.c`",
|
||||
" Once this change is made in a given copy, it is irreversible for",
|
||||
"that copy, so the ordinary GNU General Public License applies to all",
|
||||
"subsequent copies and derivative works made from that copy.",
|
||||
" This option is useful when you wish to copy part of the code of",
|
||||
"the Library into a program that is not a library.",
|
||||
" 4. You may copy and distribute the Library (or a portion or",
|
||||
"derivative of it, under Section 2) in object code or executable form",
|
||||
"under the terms of Sections 1 and 2 above provided that you accompany",
|
||||
"it with the complete corresponding machine-readable source code, which",
|
||||
"must be distributed under the terms of Sections 1 and 2 above on a",
|
||||
"medium customarily used for software interchange.",
|
||||
" If distribution of object code is made by offering access to copy",
|
||||
"from a designated place, then offering equivalent access to copy the",
|
||||
"source code from the same place satisfies the requirement to",
|
||||
"distribute the source code, even though third parties are not",
|
||||
"compelled to copy the source along with the object code.",
|
||||
" 5. A program that contains no derivative of any portion of the",
|
||||
"Library, but is designed to work with the Library by being compiled or",
|
||||
"linked with it, is called a \"work that uses the Library\". Such a",
|
||||
"work, in isolation, is not a derivative work of the Library, and",
|
||||
"therefore falls outside the scope of this License.",
|
||||
" However, linking a \"work that uses the Library\" with the Library",
|
||||
"creates an executable that is a derivative of the Library (because it",
|
||||
"contains portions of the Library), rather than a \"work that uses the",
|
||||
"library\". The executable is therefore covered by this License.",
|
||||
"Section 6 states terms for distribution of such executables.",
|
||||
" When a \"work that uses the Library\" uses material from a header file",
|
||||
"that is part of the Library, the object code for the work may be a",
|
||||
"derivative work of the Library even though the source code is not.",
|
||||
"Whether this is true is especially significant if the work can be",
|
||||
"linked without the Library, or if the work is itself a library. The",
|
||||
"threshold for this to be true is not precisely defined by law.",
|
||||
" If such an object file uses only numerical parameters, data",
|
||||
"structure layouts and accessors, and small macros and small inline",
|
||||
"functions (ten lines or less in length), then the use of the object",
|
||||
"file is unrestricted, regardless of whether it is legally a derivative",
|
||||
"work. (Executables containing this object code plus portions of the",
|
||||
"Library will still fall under Section 6.)",
|
||||
" Otherwise, if the work is a derivative of the Library, you may",
|
||||
"distribute the object code for the work under the terms of Section 6.",
|
||||
"Any executables containing that work also fall under Section 6,",
|
||||
"whether or not they are linked directly with the Library itself.",
|
||||
"",
|
||||
"Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then",
|
||||
"the configure parameter `--enable-version3` will activate this licensing option",
|
||||
"for you. Read the file `COPYING.LGPLv3` or, if you have enabled GPL parts,",
|
||||
"`COPYING.GPLv3` to learn the exact legal terms that apply in this case.",
|
||||
" 6. As an exception to the Sections above, you may also combine or",
|
||||
"link a \"work that uses the Library\" with the Library to produce a",
|
||||
"work containing portions of the Library, and distribute that work",
|
||||
"under terms of your choice, provided that the terms permit",
|
||||
"modification of the work for the customer's own use and reverse",
|
||||
"engineering for debugging such modifications.",
|
||||
" You must give prominent notice with each copy of the work that the",
|
||||
"Library is used in it and that the Library and its use are covered by",
|
||||
"this License. You must supply a copy of this License. If the work",
|
||||
"during execution displays copyright notices, you must include the",
|
||||
"copyright notice for the Library among them, as well as a reference",
|
||||
"directing the user to the copy of this License. Also, you must do one",
|
||||
"of these things:",
|
||||
" a) Accompany the work with the complete corresponding",
|
||||
" machine-readable source code for the Library including whatever",
|
||||
" changes were used in the work (which must be distributed under",
|
||||
" Sections 1 and 2 above); and, if the work is an executable linked",
|
||||
" with the Library, with the complete machine-readable \"work that",
|
||||
" uses the Library\", as object code and/or source code, so that the",
|
||||
" user can modify the Library and then relink to produce a modified",
|
||||
" executable containing the modified Library. (It is understood",
|
||||
" that the user who changes the contents of definitions files in the",
|
||||
" Library will not necessarily be able to recompile the application",
|
||||
" to use the modified definitions.)",
|
||||
" b) Use a suitable shared library mechanism for linking with the",
|
||||
" Library. A suitable mechanism is one that (1) uses at run time a",
|
||||
" copy of the library already present on the user's computer system,",
|
||||
" rather than copying library functions into the executable, and (2)",
|
||||
" will operate properly with a modified version of the library, if",
|
||||
" the user installs one, as long as the modified version is",
|
||||
" interface-compatible with the version that the work was made with.",
|
||||
" c) Accompany the work with a written offer, valid for at",
|
||||
" least three years, to give the same user the materials",
|
||||
" specified in Subsection 6a, above, for a charge no more",
|
||||
" than the cost of performing this distribution.",
|
||||
" d) If distribution of the work is made by offering access to copy",
|
||||
" from a designated place, offer equivalent access to copy the above",
|
||||
" specified materials from the same place.",
|
||||
" e) Verify that the user has already received a copy of these",
|
||||
" materials or that you have already sent this user a copy.",
|
||||
" For an executable, the required form of the \"work that uses the",
|
||||
"Library\" must include any data and utility programs needed for",
|
||||
"reproducing the executable from it. However, as a special exception,",
|
||||
"the materials to be distributed need not include anything that is",
|
||||
"normally distributed (in either source or binary form) with the major",
|
||||
"components (compiler, kernel, and so on) of the operating system on",
|
||||
"which the executable runs, unless that component itself accompanies",
|
||||
"the executable.",
|
||||
" It may happen that this requirement contradicts the license",
|
||||
"restrictions of other proprietary libraries that do not normally",
|
||||
"accompany the operating system. Such a contradiction means you cannot",
|
||||
"use both them and the Library together in an executable that you",
|
||||
"distribute.",
|
||||
"",
|
||||
"There are a handful of files under other licensing terms, namely:",
|
||||
" 7. You may place library facilities that are a work based on the",
|
||||
"Library side-by-side in a single library together with other library",
|
||||
"facilities not covered by this License, and distribute such a combined",
|
||||
"library, provided that the separate distribution of the work based on",
|
||||
"the Library and of the other library facilities is otherwise",
|
||||
"permitted, and provided that you do these two things:",
|
||||
" a) Accompany the combined library with a copy of the same work",
|
||||
" based on the Library, uncombined with any other library",
|
||||
" facilities. This must be distributed under the terms of the",
|
||||
" Sections above.",
|
||||
" b) Give prominent notice with the combined library of the fact",
|
||||
" that part of it is a work based on the Library, and explaining",
|
||||
" where to find the accompanying uncombined form of the same work.",
|
||||
" 8. You may not copy, modify, sublicense, link with, or distribute",
|
||||
"the Library except as expressly provided under this License. Any",
|
||||
"attempt otherwise to copy, modify, sublicense, link with, or",
|
||||
"distribute the Library is void, and will automatically terminate your",
|
||||
"rights under this License. However, parties who have received copies,",
|
||||
"or rights, from you under this License will not have their licenses",
|
||||
"terminated so long as such parties remain in full compliance.",
|
||||
" 9. You are not required to accept this License, since you have not",
|
||||
"signed it. However, nothing else grants you permission to modify or",
|
||||
"distribute the Library or its derivative works. These actions are",
|
||||
"prohibited by law if you do not accept this License. Therefore, by",
|
||||
"modifying or distributing the Library (or any work based on the",
|
||||
"Library), you indicate your acceptance of this License to do so, and",
|
||||
"all its terms and conditions for copying, distributing or modifying",
|
||||
"the Library or works based on it.",
|
||||
" 10. Each time you redistribute the Library (or any work based on the",
|
||||
"Library), the recipient automatically receives a license from the",
|
||||
"original licensor to copy, distribute, link with or modify the Library",
|
||||
"subject to these terms and conditions. You may not impose any further",
|
||||
"restrictions on the recipients' exercise of the rights granted herein.",
|
||||
"You are not responsible for enforcing compliance by third parties with",
|
||||
"this License.",
|
||||
"",
|
||||
"* The files `libavcodec/jfdctfst.c`, `libavcodec/jfdctint_template.c` and",
|
||||
" `libavcodec/jrevdct.c` are taken from libjpeg, see the top of the files for",
|
||||
" licensing details. Specifically note that you must credit the IJG in the",
|
||||
" documentation accompanying your program if you only distribute executables.",
|
||||
" You must also indicate any changes including additions and deletions to",
|
||||
" those three files in the documentation.",
|
||||
"* `tests/reference.pnm` is under the expat license.",
|
||||
" 11. If, as a consequence of a court judgment or allegation of patent",
|
||||
"infringement or for any other reason (not limited to patent issues),",
|
||||
"conditions are imposed on you (whether by court order, agreement or",
|
||||
"otherwise) that contradict the conditions of this License, they do not",
|
||||
"excuse you from the conditions of this License. If you cannot",
|
||||
"distribute so as to satisfy simultaneously your obligations under this",
|
||||
"License and any other pertinent obligations, then as a consequence you",
|
||||
"may not distribute the Library at all. For example, if a patent",
|
||||
"license would not permit royalty-free redistribution of the Library by",
|
||||
"all those who receive copies directly or indirectly through you, then",
|
||||
"the only way you could satisfy both it and this License would be to",
|
||||
"refrain entirely from distribution of the Library.",
|
||||
"If any portion of this section is held invalid or unenforceable under any",
|
||||
"particular circumstance, the balance of the section is intended to apply,",
|
||||
"and the section as a whole is intended to apply in other circumstances.",
|
||||
"It is not the purpose of this section to induce you to infringe any",
|
||||
"patents or other property right claims or to contest validity of any",
|
||||
"such claims; this section has the sole purpose of protecting the",
|
||||
"integrity of the free software distribution system which is",
|
||||
"implemented by public license practices. Many people have made",
|
||||
"generous contributions to the wide range of software distributed",
|
||||
"through that system in reliance on consistent application of that",
|
||||
"system; it is up to the author/donor to decide if he or she is willing",
|
||||
"to distribute software through any other system and a licensee cannot",
|
||||
"impose that choice.",
|
||||
"This section is intended to make thoroughly clear what is believed to",
|
||||
"be a consequence of the rest of this License.",
|
||||
" 12. If the distribution and/or use of the Library is restricted in",
|
||||
"certain countries either by patents or by copyrighted interfaces, the",
|
||||
"original copyright holder who places the Library under this License may add",
|
||||
"an explicit geographical distribution limitation excluding those countries,",
|
||||
"so that distribution is permitted only in or among countries not thus",
|
||||
"excluded. In such case, this License incorporates the limitation as if",
|
||||
"written in the body of this License.",
|
||||
" 13. The Free Software Foundation may publish revised and/or new",
|
||||
"versions of the Lesser General Public License from time to time.",
|
||||
"Such new versions will be similar in spirit to the present version,",
|
||||
"but may differ in detail to address new problems or concerns.",
|
||||
"Each version is given a distinguishing version number. If the Library",
|
||||
"specifies a version number of this License which applies to it and",
|
||||
"\"any later version\", you have the option of following the terms and",
|
||||
"conditions either of that version or of any later version published by",
|
||||
"the Free Software Foundation. If the Library does not specify a",
|
||||
"license version number, you may choose any version ever published by",
|
||||
"the Free Software Foundation.",
|
||||
"",
|
||||
" 14. If you wish to incorporate parts of the Library into other free",
|
||||
"programs whose distribution conditions are incompatible with these,",
|
||||
"write to the author to ask for permission. For software which is",
|
||||
"copyrighted by the Free Software Foundation, write to the Free",
|
||||
"Software Foundation; we sometimes make exceptions for this. Our",
|
||||
"decision will be guided by the two goals of preserving the free status",
|
||||
"of all derivatives of our free software and of promoting the sharing",
|
||||
"and reuse of software generally.",
|
||||
" NO WARRANTY",
|
||||
" 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO",
|
||||
"WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.",
|
||||
"EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR",
|
||||
"OTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY",
|
||||
"KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE",
|
||||
"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR",
|
||||
"PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE",
|
||||
"LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME",
|
||||
"THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.",
|
||||
" 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN",
|
||||
"WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY",
|
||||
"AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU",
|
||||
"FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR",
|
||||
"CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE",
|
||||
"LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING",
|
||||
"RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A",
|
||||
"FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF",
|
||||
"SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH",
|
||||
"DAMAGES.",
|
||||
" END OF TERMS AND CONDITIONS",
|
||||
"",
|
||||
"## External libraries",
|
||||
"",
|
||||
"FFmpeg can be combined with a number of external libraries, which sometimes",
|
||||
"affect the licensing of binaries resulting from the combination.",
|
||||
"",
|
||||
"### Compatible libraries",
|
||||
"",
|
||||
"The following libraries are under GPL version 2:",
|
||||
"- avisynth",
|
||||
"- frei0r",
|
||||
"- libcdio",
|
||||
"- libdavs2",
|
||||
"- librubberband",
|
||||
"- libvidstab",
|
||||
"- libx264",
|
||||
"- libx265",
|
||||
"- libxavs",
|
||||
"- libxavs2",
|
||||
"- libxvid",
|
||||
"",
|
||||
"When combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by",
|
||||
"passing `--enable-gpl` to configure.",
|
||||
"",
|
||||
"The following libraries are under LGPL version 3:",
|
||||
"- gmp",
|
||||
"- libaribb24",
|
||||
"- liblensfun",
|
||||
"",
|
||||
"When combining them with FFmpeg, use the configure option `--enable-version3` to",
|
||||
"upgrade FFmpeg to the LGPL v3.",
|
||||
"",
|
||||
"The VMAF, mbedTLS, RK MPI, OpenCORE and VisualOn libraries are under the Apache License",
|
||||
"2.0. That license is incompatible with the LGPL v2.1 and the GPL v2, but not with",
|
||||
"version 3 of those licenses. So to combine these libraries with FFmpeg, the",
|
||||
"license version needs to be upgraded by passing `--enable-version3` to configure.",
|
||||
"",
|
||||
"The smbclient library is under the GPL v3, to combine it with FFmpeg,",
|
||||
"the options `--enable-gpl` and `--enable-version3` have to be passed to",
|
||||
"configure to upgrade FFmpeg to the GPL v3.",
|
||||
"",
|
||||
"### Incompatible libraries",
|
||||
"",
|
||||
"There are certain libraries you can combine with FFmpeg whose licenses are not",
|
||||
"compatible with the GPL and/or the LGPL. If you wish to enable these",
|
||||
"libraries, even in circumstances that their license may be incompatible, pass",
|
||||
"`--enable-nonfree` to configure. This will cause the resulting binary to be",
|
||||
"unredistributable.",
|
||||
"",
|
||||
"The Fraunhofer FDK AAC and OpenSSL libraries are under licenses which are",
|
||||
"incompatible with the GPLv2 and v3. To the best of our knowledge, they are",
|
||||
"compatible with the LGPL."
|
||||
" How to Apply These Terms to Your New Libraries",
|
||||
" If you develop a new library, and you want it to be of the greatest",
|
||||
"possible use to the public, we recommend making it free software that",
|
||||
"everyone can redistribute and change. You can do so by permitting",
|
||||
"redistribution under these terms (or, alternatively, under the terms of the",
|
||||
"ordinary General Public License).",
|
||||
" To apply these terms, attach the following notices to the library. It is",
|
||||
"safest to attach them to the start of each source file to most effectively",
|
||||
"convey the exclusion of warranty; and each file should have at least the",
|
||||
"\"copyright\" line and a pointer to where the full notice is found.",
|
||||
" <one line to give the library's name and a brief idea of what it does.>",
|
||||
" Copyright (C) <year> <name of author>",
|
||||
" This library is free software; you can redistribute it and/or",
|
||||
" modify it under the terms of the GNU Lesser General Public",
|
||||
" License as published by the Free Software Foundation; either",
|
||||
" version 2.1 of the License, or (at your option) any later version.",
|
||||
" This library is distributed in the hope that it will be useful,",
|
||||
" but WITHOUT ANY WARRANTY; without even the implied warranty of",
|
||||
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU",
|
||||
" Lesser General Public License for more details.",
|
||||
" You should have received a copy of the GNU Lesser General Public",
|
||||
" License along with this library; if not, write to the Free Software",
|
||||
" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA",
|
||||
"Also add information on how to contact you by electronic and paper mail.",
|
||||
"You should also get your employer (if you work as a programmer) or your",
|
||||
"school, if any, to sign a \"copyright disclaimer\" for the library, if",
|
||||
"necessary. Here is a sample; alter the names:",
|
||||
" Yoyodyne, Inc., hereby disclaims all copyright interest in the",
|
||||
" library `Frob' (a library for tweaking knobs) written by James Random Hacker.",
|
||||
" <signature of Ty Coon>, 1 April 1990",
|
||||
" Ty Coon, President of Vice",
|
||||
"That's all there is to it!"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import * as path from 'path';
|
||||
import * as picomatch from 'picomatch';
|
||||
import * as vscode from 'vscode';
|
||||
import { BaseLanguageClient } from 'vscode-languageclient';
|
||||
import { BaseLanguageClient, TextDocumentEdit } from 'vscode-languageclient';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { getEditForFileRenames } from '../protocol';
|
||||
import { Delayer } from '../util/async';
|
||||
|
@ -206,13 +206,13 @@ class UpdateLinksOnFileRenameHandler extends Disposable {
|
|||
token: vscode.CancellationToken,
|
||||
): Promise<boolean> {
|
||||
const edit = await this.client.sendRequest(getEditForFileRenames, [{ oldUri: oldUri.toString(), newUri: newUri.toString() }], token);
|
||||
if (!edit.changes) {
|
||||
if (!edit.documentChanges?.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const [path, edits] of Object.entries(edit.changes)) {
|
||||
const uri = vscode.Uri.parse(path);
|
||||
for (const edit of edits) {
|
||||
for (const change of edit.documentChanges as TextDocumentEdit[]) {
|
||||
const uri = vscode.Uri.parse(change.textDocument.uri);
|
||||
for (const edit of change.edits) {
|
||||
workspaceEdit.replace(uri, convertRange(edit.range), edit.newText);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -569,7 +569,7 @@ registerEditorCommand(new CodeActionContribution({
|
|||
kbOpts: {
|
||||
weight: weight + 100000,
|
||||
primary: KeyCode.Enter,
|
||||
secondary: [KeyMod.Shift | KeyCode.Tab],
|
||||
secondary: [KeyMod.CtrlCmd | KeyCode.Period],
|
||||
}
|
||||
}));
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ export abstract class SymbolNavigationAction extends EditorAction {
|
|||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
run(accessor: ServicesAccessor, editor: ICodeEditor, arg?: SymbolNavigationAnchor | unknown): Promise<void> {
|
||||
run(accessor: ServicesAccessor, editor: ICodeEditor, arg?: SymbolNavigationAnchor | unknown, range?: Range): Promise<void> {
|
||||
if (!editor.hasModel()) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ export abstract class SymbolNavigationAction extends EditorAction {
|
|||
|
||||
} else {
|
||||
// normal results handling
|
||||
return this._onResult(editorService, symbolNavService, editor, references);
|
||||
return this._onResult(editorService, symbolNavService, editor, references, range);
|
||||
}
|
||||
|
||||
}, (err) => {
|
||||
|
@ -165,18 +165,18 @@ export abstract class SymbolNavigationAction extends EditorAction {
|
|||
|
||||
protected abstract _getGoToPreference(editor: IActiveCodeEditor): GoToLocationValues;
|
||||
|
||||
private async _onResult(editorService: ICodeEditorService, symbolNavService: ISymbolNavigationService, editor: IActiveCodeEditor, model: ReferencesModel): Promise<void> {
|
||||
private async _onResult(editorService: ICodeEditorService, symbolNavService: ISymbolNavigationService, editor: IActiveCodeEditor, model: ReferencesModel, range?: Range): Promise<void> {
|
||||
|
||||
const gotoLocation = this._getGoToPreference(editor);
|
||||
if (!(editor instanceof EmbeddedCodeEditorWidget) && (this.configuration.openInPeek || (gotoLocation === 'peek' && model.references.length > 1))) {
|
||||
this._openInPeek(editor, model);
|
||||
this._openInPeek(editor, model, range);
|
||||
|
||||
} else {
|
||||
const next = model.firstReference()!;
|
||||
const peek = model.references.length > 1 && gotoLocation === 'gotoAndPeek';
|
||||
const targetEditor = await this._openReference(editor, editorService, next, this.configuration.openToSide, !peek);
|
||||
if (peek && targetEditor) {
|
||||
this._openInPeek(targetEditor, model);
|
||||
this._openInPeek(targetEditor, model, range);
|
||||
} else {
|
||||
model.dispose();
|
||||
}
|
||||
|
@ -229,10 +229,10 @@ export abstract class SymbolNavigationAction extends EditorAction {
|
|||
return targetEditor;
|
||||
}
|
||||
|
||||
private _openInPeek(target: ICodeEditor, model: ReferencesModel) {
|
||||
private _openInPeek(target: ICodeEditor, model: ReferencesModel, range?: Range) {
|
||||
const controller = ReferencesController.get(target);
|
||||
if (controller && target.hasModel()) {
|
||||
controller.toggleWidget(target.getSelection(), createCancelablePromise(_ => Promise.resolve(model)), this.configuration.openInPeek);
|
||||
controller.toggleWidget(range ?? target.getSelection(), createCancelablePromise(_ => Promise.resolve(model)), this.configuration.openInPeek);
|
||||
} else {
|
||||
model.dispose();
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ export async function goToDefinitionWithLocation(accessor: ServicesAccessor, eve
|
|||
const canPeek = !openToSide && editor.getOption(EditorOption.definitionLinkOpensInPeek) && !isInPeek;
|
||||
|
||||
const action = new DefinitionAction({ openToSide, openInPeek: canPeek, muteMessage: true }, { alias: '', label: '', id: '', precondition: undefined });
|
||||
return action.run(accessor, editor, { model: ref.object.textEditorModel, position: Range.getStartPosition(location.range) });
|
||||
return action.run(accessor, editor, { model: ref.object.textEditorModel, position: Range.getStartPosition(location.range) }, Range.lift(location.range));
|
||||
});
|
||||
|
||||
ref.dispose();
|
||||
|
|
|
@ -12,6 +12,7 @@ import { EditorOption } from 'vs/editor/common/config/editorOptions';
|
|||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { binarySearch } from 'vs/base/common/arrays';
|
||||
|
||||
export class StickyRange {
|
||||
constructor(
|
||||
|
@ -96,9 +97,34 @@ export class StickyLineCandidateProvider extends Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
private updateIndex(index: number) {
|
||||
if (index === -1) {
|
||||
index = 0;
|
||||
} else if (index < 0) {
|
||||
index = -index - 2;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public getCandidateStickyLinesIntersectingFromOutline(range: StickyRange, outlineModel: StickyOutlineElement, result: StickyLineCandidate[], depth: number, lastStartLineNumber: number): void {
|
||||
if (outlineModel.children.length === 0) {
|
||||
return;
|
||||
}
|
||||
let lastLine = lastStartLineNumber;
|
||||
for (const child of outlineModel.children) {
|
||||
const childrenStartLines: number[] = [];
|
||||
for (let i = 0; i < outlineModel.children.length; i++) {
|
||||
const child = outlineModel.children[i];
|
||||
if (child.range) {
|
||||
childrenStartLines.push(child.range.startLineNumber);
|
||||
}
|
||||
}
|
||||
const lowerBound = this.updateIndex(binarySearch(childrenStartLines, range.startLineNumber, (a: number, b: number) => { return a - b; }));
|
||||
const upperBound = this.updateIndex(binarySearch(childrenStartLines, range.startLineNumber + depth, (a: number, b: number) => { return a - b; }));
|
||||
for (let i = lowerBound; i <= upperBound; i++) {
|
||||
const child = outlineModel.children[i];
|
||||
if (!child) {
|
||||
return;
|
||||
}
|
||||
if (child.range) {
|
||||
const childStartLine = child.range.startLineNumber;
|
||||
const childEndLine = child.range.endLineNumber;
|
||||
|
@ -133,9 +159,13 @@ export class StickyLineCandidateProvider extends Disposable {
|
|||
|
||||
class StickyOutlineElement {
|
||||
public static fromOutlineModel(outlineModel: OutlineModel | OutlineElement | OutlineGroup): StickyOutlineElement {
|
||||
const children = [...outlineModel.children.values()].map(child =>
|
||||
StickyOutlineElement.fromOutlineModel(child)
|
||||
);
|
||||
|
||||
const children: StickyOutlineElement[] = [];
|
||||
for (const child of outlineModel.children.values()) {
|
||||
if (child instanceof OutlineElement && child.symbol.selectionRange.startLineNumber !== child.symbol.range.endLineNumber || child instanceof OutlineGroup || child instanceof OutlineModel) {
|
||||
children.push(StickyOutlineElement.fromOutlineModel(child));
|
||||
}
|
||||
}
|
||||
children.sort((child1, child2) => {
|
||||
if (!child1.range || !child2.range) {
|
||||
return 1;
|
||||
|
|
|
@ -160,7 +160,6 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
|
|||
return linkGestureStore;
|
||||
}
|
||||
|
||||
|
||||
public get lineNumbers(): number[] {
|
||||
return this._lineNumbers;
|
||||
}
|
||||
|
|
|
@ -105,12 +105,10 @@ suite('Sticky Scroll Tests', () => {
|
|||
const languageService = instantiationService.get(ILanguageFeaturesService);
|
||||
languageService.documentSymbolProvider.register('*', documentSymbolProviderForTestModel());
|
||||
const provider: StickyLineCandidateProvider = new StickyLineCandidateProvider(editor, languageService);
|
||||
|
||||
await provider.update();
|
||||
|
||||
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 1, endLineNumber: 4 }), [new StickyLineCandidate(1, 2, 1)]);
|
||||
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 1, endLineNumber: 10 }), [new StickyLineCandidate(1, 2, 1), new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3)]);
|
||||
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 1, endLineNumber: 13 }), [new StickyLineCandidate(1, 2, 1), new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3), new StickyLineCandidate(13, 13, 1)]);
|
||||
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 8, endLineNumber: 10 }), [new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3)]);
|
||||
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 10, endLineNumber: 13 }), [new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3)]);
|
||||
|
||||
provider.dispose();
|
||||
model.dispose();
|
||||
|
|
|
@ -9,6 +9,7 @@ import { URI } from 'vs/base/common/uri';
|
|||
import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService';
|
||||
import { IExtensionsScannerService } from 'vs/platform/extensionManagement/common/extensionsScannerService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { EXTENSIONS_RESOURCE_NAME } from 'vs/platform/userDataProfile/common/userDataProfile';
|
||||
import { IUserDataProfilesMainService } from 'vs/platform/userDataProfile/electron-main/userDataProfile';
|
||||
|
||||
|
@ -18,8 +19,10 @@ export class DefaultExtensionsProfileInitHandler extends Disposable {
|
|||
@IFileService private readonly fileService: IFileService,
|
||||
@IExtensionsScannerService private readonly extensionsScannerService: IExtensionsScannerService,
|
||||
@IExtensionsProfileScannerService private readonly extensionsProfileScannerService: IExtensionsProfileScannerService,
|
||||
@ILogService logService: ILogService,
|
||||
) {
|
||||
super();
|
||||
if (userDataProfilesService.isEnabled()) {
|
||||
this._register(userDataProfilesService.onWillCreateProfile(e => {
|
||||
if (userDataProfilesService.profiles.length === 1) {
|
||||
e.join(this.initialize());
|
||||
|
@ -30,6 +33,9 @@ export class DefaultExtensionsProfileInitHandler extends Disposable {
|
|||
this.uninitialize();
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
this.uninitialize().then(null, e => logService.error(e));
|
||||
}
|
||||
}
|
||||
|
||||
private async initialize(): Promise<void> {
|
||||
|
|
|
@ -39,6 +39,15 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme
|
|||
super(stateMainService, uriIdentityService, environmentService, fileService, logService);
|
||||
}
|
||||
|
||||
override setEnablement(enabled: boolean): void {
|
||||
super.setEnablement(enabled);
|
||||
if (!this.enabled) {
|
||||
// reset
|
||||
this.saveStoredProfiles([]);
|
||||
this.saveStoredProfileAssociations({});
|
||||
}
|
||||
}
|
||||
|
||||
isEnabled(): boolean {
|
||||
return this.enabled;
|
||||
}
|
||||
|
@ -69,11 +78,19 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme
|
|||
}
|
||||
|
||||
protected override saveStoredProfiles(storedProfiles: StoredUserDataProfile[]): void {
|
||||
if (storedProfiles.length) {
|
||||
this.stateMainService.setItem(UserDataProfilesMainService.PROFILES_KEY, storedProfiles);
|
||||
} else {
|
||||
this.stateMainService.removeItem(UserDataProfilesMainService.PROFILES_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
protected override saveStoredProfileAssociations(storedProfileAssociations: StoredProfileAssociations): void {
|
||||
if (storedProfileAssociations.emptyWindow || storedProfileAssociations.workspaces) {
|
||||
this.stateMainService.setItem(UserDataProfilesMainService.PROFILE_ASSOCIATIONS_KEY, storedProfileAssociations);
|
||||
} else {
|
||||
this.stateMainService.removeItem(UserDataProfilesMainService.PROFILE_ASSOCIATIONS_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
protected override getStoredProfileAssociations(): StoredProfileAssociations {
|
||||
|
|
|
@ -168,6 +168,7 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
|
|||
this._register(treeView.onDidExpandItem(item => this._proxy.$setExpanded(treeViewId, item.handle, true)));
|
||||
this._register(treeView.onDidCollapseItem(item => this._proxy.$setExpanded(treeViewId, item.handle, false)));
|
||||
this._register(treeView.onDidChangeSelection(items => this._proxy.$setSelection(treeViewId, items.map(({ handle }) => handle))));
|
||||
this._register(treeView.onDidChangeFocus(item => this._proxy.$setFocus(treeViewId, item.handle)));
|
||||
this._register(treeView.onDidChangeVisibility(isVisible => this._proxy.$setVisible(treeViewId, isVisible)));
|
||||
}
|
||||
|
||||
|
|
|
@ -1406,6 +1406,7 @@ export interface ExtHostTreeViewsShape {
|
|||
$handleDrag(sourceViewId: string, sourceTreeItemHandles: string[], operationUuid: string, token: CancellationToken): Promise<DataTransferDTO | undefined>;
|
||||
$setExpanded(treeViewId: string, treeItemHandle: string, expanded: boolean): void;
|
||||
$setSelection(treeViewId: string, treeItemHandles: string[]): void;
|
||||
$setFocus(treeViewId: string, treeItemHandle: string): void;
|
||||
$setVisible(treeViewId: string, visible: boolean): void;
|
||||
$hasResolve(treeViewId: string): Promise<boolean>;
|
||||
$resolve(treeViewId: string, treeItemHandle: string, token: CancellationToken): Promise<ITreeItem | undefined>;
|
||||
|
|
|
@ -59,7 +59,7 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
|
|||
) {
|
||||
|
||||
function isTreeViewConvertableItem(arg: any): boolean {
|
||||
return arg && arg.$treeViewId && (arg.$treeItemHandle || arg.$selectedTreeItems);
|
||||
return arg && arg.$treeViewId && (arg.$treeItemHandle || arg.$selectedTreeItems || arg.$focusedTreeItem);
|
||||
}
|
||||
commands.registerArgumentProcessor({
|
||||
processArgument: arg => {
|
||||
|
@ -221,6 +221,14 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
|
|||
treeView.setSelection(treeItemHandles);
|
||||
}
|
||||
|
||||
$setFocus(treeViewId: string, treeItemHandles: string) {
|
||||
const treeView = this.treeViews.get(treeViewId);
|
||||
if (!treeView) {
|
||||
throw new Error(localize('treeView.notRegistered', 'No tree view with id \'{0}\' registered.', treeViewId));
|
||||
}
|
||||
treeView.setFocus(treeItemHandles);
|
||||
}
|
||||
|
||||
$setVisible(treeViewId: string, isVisible: boolean): void {
|
||||
const treeView = this.treeViews.get(treeViewId);
|
||||
if (!treeView) {
|
||||
|
@ -240,8 +248,8 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
|
|||
if (treeView && '$treeItemHandle' in arg) {
|
||||
return treeView.getExtensionElement(arg.$treeItemHandle);
|
||||
}
|
||||
if (treeView && '$selectedTreeItems' in arg && arg.$selectedTreeItems) {
|
||||
return { selectedTreeItems: treeView.selectedElements };
|
||||
if (treeView && '$focusedTreeItem' in arg && arg.$focusedTreeItem) {
|
||||
return treeView.focusedElement;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -276,6 +284,9 @@ class ExtHostTreeView<T> extends Disposable {
|
|||
private _selectedHandles: TreeItemHandle[] = [];
|
||||
get selectedElements(): T[] { return <T[]>this._selectedHandles.map(handle => this.getExtensionElement(handle)).filter(element => !isUndefinedOrNull(element)); }
|
||||
|
||||
private _focusedHandle: TreeItemHandle | undefined = undefined;
|
||||
get focusedElement(): T | undefined { return <T | undefined>(this._focusedHandle ? this.getExtensionElement(this._focusedHandle) : undefined); }
|
||||
|
||||
private _onDidExpandElement: Emitter<vscode.TreeViewExpansionEvent<T>> = this._register(new Emitter<vscode.TreeViewExpansionEvent<T>>());
|
||||
readonly onDidExpandElement: Event<vscode.TreeViewExpansionEvent<T>> = this._onDidExpandElement.event;
|
||||
|
||||
|
@ -455,6 +466,10 @@ class ExtHostTreeView<T> extends Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
setFocus(treeItemHandle: TreeItemHandle) {
|
||||
this._focusedHandle = treeItemHandle;
|
||||
}
|
||||
|
||||
setVisible(visible: boolean): void {
|
||||
if (visible !== this._visible) {
|
||||
this._visible = visible;
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item>.custom-view-tree-node-item-icon.disabled {
|
||||
opacity: 60%;
|
||||
opacity: 0.6;
|
||||
}
|
||||
/* makes spinning icons square */
|
||||
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item > .custom-view-tree-node-item-icon.codicon.codicon-modifier-spin {
|
||||
|
|
|
@ -71,6 +71,7 @@ export class TreeViewPane extends ViewPane {
|
|||
|
||||
protected readonly treeView: ITreeView;
|
||||
private _container: HTMLElement | undefined;
|
||||
private _actionRunner: MultipleSelectionActionRunner;
|
||||
|
||||
constructor(
|
||||
options: IViewletViewOptions,
|
||||
|
@ -83,6 +84,7 @@ export class TreeViewPane extends ViewPane {
|
|||
@IOpenerService openerService: IOpenerService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@INotificationService notificationService: INotificationService
|
||||
) {
|
||||
super({ ...(options as IViewPaneOptions), titleMenuId: MenuId.ViewTitle, donotForwardArgs: false }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService);
|
||||
const { treeView } = (<ITreeViewDescriptor>Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).getView(options.id));
|
||||
|
@ -103,6 +105,7 @@ export class TreeViewPane extends ViewPane {
|
|||
if (options.titleDescription !== this.treeView.description) {
|
||||
this.updateTitleDescription(this.treeView.description);
|
||||
}
|
||||
this._actionRunner = new MultipleSelectionActionRunner(notificationService, () => this.treeView.getSelection());
|
||||
|
||||
this.updateTreeVisibility();
|
||||
}
|
||||
|
@ -143,11 +146,12 @@ export class TreeViewPane extends ViewPane {
|
|||
this.treeView.setVisibility(this.isBodyVisible());
|
||||
}
|
||||
|
||||
override getActionRunner() {
|
||||
return this._actionRunner;
|
||||
}
|
||||
|
||||
override getActionsContext(): TreeViewPaneHandleArg {
|
||||
return {
|
||||
$selectedTreeItems: true,
|
||||
$treeViewId: this.id
|
||||
};
|
||||
return { $treeViewId: this.id, $focusedTreeItem: true, $selectedTreeItems: true };
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -214,6 +218,9 @@ abstract class AbstractTreeView extends Disposable implements ITreeView {
|
|||
private _onDidChangeSelection: Emitter<ITreeItem[]> = this._register(new Emitter<ITreeItem[]>());
|
||||
readonly onDidChangeSelection: Event<ITreeItem[]> = this._onDidChangeSelection.event;
|
||||
|
||||
private _onDidChangeFocus: Emitter<ITreeItem> = this._register(new Emitter<ITreeItem>());
|
||||
readonly onDidChangeFocus: Event<ITreeItem> = this._onDidChangeFocus.event;
|
||||
|
||||
private readonly _onDidChangeVisibility: Emitter<boolean> = this._register(new Emitter<boolean>());
|
||||
readonly onDidChangeVisibility: Event<boolean> = this._onDidChangeVisibility.event;
|
||||
|
||||
|
@ -617,6 +624,11 @@ abstract class AbstractTreeView extends Disposable implements ITreeView {
|
|||
customTreeKey.set(true);
|
||||
this._register(this.tree.onContextMenu(e => this.onContextMenu(treeMenus, e, actionRunner)));
|
||||
this._register(this.tree.onDidChangeSelection(e => this._onDidChangeSelection.fire(e.elements)));
|
||||
this._register(this.tree.onDidChangeFocus(e => {
|
||||
if (e.elements.length) {
|
||||
this._onDidChangeFocus.fire(e.elements[0]);
|
||||
}
|
||||
}));
|
||||
this._register(this.tree.onDidChangeCollapseState(e => {
|
||||
if (!e.node.element) {
|
||||
return;
|
||||
|
@ -803,6 +815,10 @@ abstract class AbstractTreeView extends Disposable implements ITreeView {
|
|||
this.tree?.setSelection(items);
|
||||
}
|
||||
|
||||
getSelection(): ITreeItem[] {
|
||||
return this.tree?.getSelection() ?? [];
|
||||
}
|
||||
|
||||
setFocus(item: ITreeItem): void {
|
||||
if (this.tree) {
|
||||
this.focus(true, item);
|
||||
|
@ -1234,13 +1250,13 @@ class MultipleSelectionActionRunner extends ActionRunner {
|
|||
}));
|
||||
}
|
||||
|
||||
override async runAction(action: IAction, context: TreeViewItemHandleArg): Promise<void> {
|
||||
override async runAction(action: IAction, context: TreeViewItemHandleArg | TreeViewPaneHandleArg): Promise<void> {
|
||||
const selection = this.getSelectedResources();
|
||||
let selectionHandleArgs: TreeViewItemHandleArg[] | undefined = undefined;
|
||||
let actionInSelected: boolean = false;
|
||||
if (selection.length > 1) {
|
||||
selectionHandleArgs = selection.map(selected => {
|
||||
if (selected.handle === context.$treeItemHandle) {
|
||||
if ((selected.handle === (context as TreeViewItemHandleArg).$treeItemHandle) || (context as TreeViewPaneHandleArg).$selectedTreeItems) {
|
||||
actionInSelected = true;
|
||||
}
|
||||
return { $treeViewId: context.$treeViewId, $treeItemHandle: selected.handle };
|
||||
|
|
|
@ -11,7 +11,7 @@ import { attachButtonStyler, attachProgressBarStyler } from 'vs/platform/theme/c
|
|||
import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { after, append, $, trackFocus, EventType, addDisposableListener, createCSSRule, asCSSUrl } from 'vs/base/browser/dom';
|
||||
import { IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { IAction, IActionRunner } from 'vs/base/common/actions';
|
||||
import { ActionsOrientation, IActionViewItem, prepareActions } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
|
||||
|
@ -298,7 +298,8 @@ export abstract class ViewPane extends Pane implements IView {
|
|||
actionViewItemProvider: action => this.getActionViewItem(action),
|
||||
ariaLabel: nls.localize('viewToolbarAriaLabel', "{0} actions", this.title),
|
||||
getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id),
|
||||
renderDropdownAsChildElement: true
|
||||
renderDropdownAsChildElement: true,
|
||||
actionRunner: this.getActionRunner()
|
||||
});
|
||||
|
||||
this._register(this.toolbar);
|
||||
|
@ -519,6 +520,10 @@ export abstract class ViewPane extends Pane implements IView {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
getActionRunner(): IActionRunner | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getOptimalWidth(): number {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -663,6 +663,8 @@ export interface ITreeView extends IDisposable {
|
|||
|
||||
readonly onDidChangeSelection: Event<ITreeItem[]>;
|
||||
|
||||
readonly onDidChangeFocus: Event<ITreeItem>;
|
||||
|
||||
readonly onDidChangeVisibility: Event<boolean>;
|
||||
|
||||
readonly onDidChangeActions: Event<void>;
|
||||
|
@ -691,6 +693,8 @@ export interface ITreeView extends IDisposable {
|
|||
|
||||
setSelection(items: ITreeItem[]): void;
|
||||
|
||||
getSelection(): ITreeItem[];
|
||||
|
||||
setFocus(item: ITreeItem): void;
|
||||
|
||||
show(container: any): void;
|
||||
|
@ -712,7 +716,8 @@ export interface ITreeViewDescriptor extends IViewDescriptor {
|
|||
|
||||
export type TreeViewPaneHandleArg = {
|
||||
$treeViewId: string;
|
||||
$selectedTreeItems: boolean;
|
||||
$selectedTreeItems?: boolean;
|
||||
$focusedTreeItem?: boolean;
|
||||
};
|
||||
|
||||
export type TreeViewItemHandleArg = {
|
||||
|
|
|
@ -51,6 +51,8 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
|||
import { equals } from 'vs/base/common/objects';
|
||||
import { IEditSessionIdentityService } from 'vs/platform/workspace/common/editSessions';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { IOutputService } from 'vs/workbench/services/output/common/output';
|
||||
import * as Constants from 'vs/workbench/contrib/logs/common/logConstants';
|
||||
|
||||
registerSingleton(IEditSessionsLogService, EditSessionsLogService);
|
||||
registerSingleton(IEditSessionsStorageService, EditSessionsWorkbenchService);
|
||||
|
@ -68,6 +70,16 @@ const openLocalFolderCommand: IAction2Options = {
|
|||
category: EDIT_SESSION_SYNC_CATEGORY,
|
||||
precondition: IsWebContext
|
||||
};
|
||||
const showOutputChannelCommand: IAction2Options = {
|
||||
id: 'workbench.experimental.editSessions.actions.showOutputChannel',
|
||||
title: { value: localize('show log', 'Show Log'), original: 'Show Log' },
|
||||
category: EDIT_SESSION_SYNC_CATEGORY
|
||||
};
|
||||
const resumingProgressOptions = {
|
||||
location: ProgressLocation.Window,
|
||||
type: 'syncing',
|
||||
title: `[${localize('resuming edit session window', 'Resuming edit session...')}](command:${showOutputChannelCommand.id})`
|
||||
};
|
||||
const queryParamName = 'editSessionId';
|
||||
const experimentalSettingName = 'workbench.experimental.editSessions.enabled';
|
||||
|
||||
|
@ -120,11 +132,8 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
|
|||
this.lifecycleService.onWillShutdown((e) => e.join(this.autoStoreEditSession(), { id: 'autoStoreEditSession', label: localize('autoStoreEditSession', 'Storing current edit session...') }));
|
||||
}
|
||||
|
||||
private async autoResumeEditSession() {
|
||||
if (this.environmentService.editSessionId !== undefined) {
|
||||
// In web, resume edit session based on an edit session GUID that
|
||||
// was explicitly passed into the workbench construction options
|
||||
void this.progressService.withProgress({ location: ProgressLocation.Window, type: 'syncing', title: localize('resuming edit session dialog', 'Resuming your latest edit session...') }, async () => {
|
||||
private autoResumeEditSession() {
|
||||
void this.progressService.withProgress(resumingProgressOptions, async () => {
|
||||
performance.mark('code/willResumeEditSessionFromIdentifier');
|
||||
|
||||
type ResumeEvent = {};
|
||||
|
@ -133,18 +142,17 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
|
|||
};
|
||||
this.telemetryService.publicLog2<ResumeEvent, ResumeClassification>('editSessions.continue.resume');
|
||||
|
||||
if (this.environmentService.editSessionId !== undefined) {
|
||||
await this.resumeEditSession(this.environmentService.editSessionId).finally(() => this.environmentService.editSessionId = undefined);
|
||||
|
||||
performance.mark('code/didResumeEditSessionFromIdentifier');
|
||||
});
|
||||
} else if (this.configurationService.getValue('workbench.experimental.editSessions.autoResume') === 'onReload' && this.editSessionsStorageService.isSignedIn) {
|
||||
// Attempt to resume edit session based on edit workspace identifier
|
||||
// Note: at this point if the user is not signed into edit sessions,
|
||||
// we don't want them to be prompted to sign in and should just return early
|
||||
void this.progressService.withProgress({ location: ProgressLocation.Window, type: 'syncing', title: localize('resuming edit session window', 'Resuming edit session...') }, async () => {
|
||||
await this.resumeEditSession(undefined, true);
|
||||
});
|
||||
}
|
||||
|
||||
performance.mark('code/didResumeEditSessionFromIdentifier');
|
||||
});
|
||||
}
|
||||
|
||||
private async autoStoreEditSession() {
|
||||
|
@ -187,10 +195,24 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
|
|||
this.registerContinueInLocalFolderAction();
|
||||
|
||||
this.registerShowEditSessionViewAction();
|
||||
this.registerShowEditSessionOutputChannelAction();
|
||||
|
||||
this.registered = true;
|
||||
}
|
||||
|
||||
private registerShowEditSessionOutputChannelAction() {
|
||||
this._register(registerAction2(class ShowEditSessionOutput extends Action2 {
|
||||
constructor() {
|
||||
super(showOutputChannelCommand);
|
||||
}
|
||||
|
||||
run(accessor: ServicesAccessor, ...args: any[]) {
|
||||
const outputChannel = accessor.get(IOutputService);
|
||||
void outputChannel.showChannel(Constants.editSessionsLogChannelId);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private registerShowEditSessionViewAction() {
|
||||
const that = this;
|
||||
this._register(registerAction2(class ShowEditSessionView extends Action2 {
|
||||
|
@ -262,10 +284,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
|
|||
}
|
||||
|
||||
async run(accessor: ServicesAccessor, editSessionId?: string): Promise<void> {
|
||||
await that.progressService.withProgress({
|
||||
location: ProgressLocation.Notification,
|
||||
title: localize('resuming edit session', 'Resuming edit session...')
|
||||
}, async () => {
|
||||
await that.progressService.withProgress(resumingProgressOptions, async () => {
|
||||
type ResumeEvent = {};
|
||||
type ResumeClassification = {
|
||||
owner: 'joyceerhl'; comment: 'Reporting when the resume edit session action is invoked.';
|
||||
|
|
|
@ -14,7 +14,7 @@ import { IProductService } from 'vs/platform/product/common/productService';
|
|||
import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
import { IStorageService, IStorageValueChangeEvent, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { createSyncHeaders, IAuthenticationProvider, IResourceRefHandle, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { createSyncHeaders, IAuthenticationProvider, IResourceRefHandle } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { UserDataSyncStoreClient } from 'vs/platform/userDataSync/common/userDataSyncStoreService';
|
||||
import { AuthenticationSession, AuthenticationSessionsChangeEvent, IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
|
@ -23,6 +23,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
|||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { ICredentialsService } from 'vs/platform/credentials/common/credentials';
|
||||
import { getCurrentAuthenticationSessionInfo } from 'vs/workbench/services/authentication/browser/authenticationService';
|
||||
import { isWeb } from 'vs/base/common/platform';
|
||||
|
||||
type ExistingSession = IQuickPickItem & { session: AuthenticationSession & { providerId: string } };
|
||||
type AuthenticationProviderOption = IQuickPickItem & { provider: IAuthenticationProvider };
|
||||
|
@ -57,7 +58,6 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
|||
@IRequestService private readonly requestService: IRequestService,
|
||||
@IDialogService private readonly dialogService: IDialogService,
|
||||
@ICredentialsService private readonly credentialsService: ICredentialsService,
|
||||
@IUserDataSyncEnablementService private readonly userDataSyncEnablementService: IUserDataSyncEnablementService,
|
||||
) {
|
||||
super();
|
||||
|
||||
|
@ -202,7 +202,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
|||
}
|
||||
|
||||
// If settings sync is already enabled, avoid asking again to authenticate
|
||||
if (this.userDataSyncEnablementService.isEnabled()) {
|
||||
if (this.shouldAttemptEditSessionInit()) {
|
||||
this.logService.info(`Reusing user data sync enablement`);
|
||||
const authenticationSessionInfo = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.productService);
|
||||
if (authenticationSessionInfo !== undefined) {
|
||||
|
@ -222,6 +222,10 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
|||
return undefined;
|
||||
}
|
||||
|
||||
private shouldAttemptEditSessionInit(): boolean {
|
||||
return isWeb && this.storageService.isNew(StorageScope.APPLICATION) && this.storageService.isNew(StorageScope.WORKSPACE);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Prompts the user to pick an authentication option for storing and getting edit sessions.
|
||||
|
|
|
@ -8,10 +8,9 @@ import { URI, UriComponents } from 'vs/base/common/uri';
|
|||
import { localize } from 'vs/nls';
|
||||
import { ILocalizedString } from 'vs/platform/action/common/action';
|
||||
import { Action2, IAction2Options, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { API_OPEN_DIFF_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands';
|
||||
import { IResourceMergeEditorInput } from 'vs/workbench/common/editor';
|
||||
import { MergeEditorInputData } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput';
|
||||
import { MergeEditor } from 'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor';
|
||||
|
@ -213,14 +212,14 @@ export class OpenResultResource extends MergeEditorAction {
|
|||
}
|
||||
}
|
||||
|
||||
export class GoToNextConflict extends MergeEditorAction {
|
||||
export class GoToNextUnhandledConflict extends MergeEditorAction {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'merge.goToNextConflict',
|
||||
id: 'merge.goToNextUnhandledConflict',
|
||||
category: mergeEditorCategory,
|
||||
title: {
|
||||
value: localize('merge.goToNextConflict', 'Go to Next Conflict'),
|
||||
original: 'Go to Next Conflict',
|
||||
value: localize('merge.goToNextUnhandledConflict', 'Go to Next Unhandled Conflict'),
|
||||
original: 'Go to Next Unhandled Conflict',
|
||||
},
|
||||
icon: Codicon.arrowDown,
|
||||
menu: [
|
||||
|
@ -237,21 +236,21 @@ export class GoToNextConflict extends MergeEditorAction {
|
|||
}
|
||||
|
||||
override runWithViewModel(viewModel: MergeEditorViewModel): void {
|
||||
viewModel.goToNextModifiedBaseRange(true);
|
||||
viewModel.goToNextModifiedBaseRange(r => !viewModel.model.isHandled(r).get());
|
||||
}
|
||||
}
|
||||
|
||||
export class GoToPreviousConflict extends MergeEditorAction {
|
||||
export class GoToPreviousUnhandledConflict extends MergeEditorAction {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'merge.goToPreviousConflict',
|
||||
id: 'merge.goToPreviousUnhandledConflict',
|
||||
category: mergeEditorCategory,
|
||||
title: {
|
||||
value: localize(
|
||||
'merge.goToPreviousConflict',
|
||||
'Go to Previous Conflict'
|
||||
'merge.goToPreviousUnhandledConflict',
|
||||
'Go to Previous Unhandled Conflict'
|
||||
),
|
||||
original: 'Go to Previous Conflict',
|
||||
original: 'Go to Previous Unhandled Conflict',
|
||||
},
|
||||
icon: Codicon.arrowUp,
|
||||
menu: [
|
||||
|
@ -268,7 +267,7 @@ export class GoToPreviousConflict extends MergeEditorAction {
|
|||
}
|
||||
|
||||
override runWithViewModel(viewModel: MergeEditorViewModel): void {
|
||||
viewModel.goToPreviousModifiedBaseRange(true);
|
||||
viewModel.goToPreviousModifiedBaseRange(r => !viewModel.model.isHandled(r).get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,8 +335,8 @@ export class CompareInput1WithBaseCommand extends MergeEditorAction {
|
|||
}
|
||||
|
||||
override runWithViewModel(viewModel: MergeEditorViewModel, accessor: ServicesAccessor): void {
|
||||
const commandService = accessor.get(ICommandService);
|
||||
mergeEditorCompare(viewModel, commandService, 1);
|
||||
const editorService = accessor.get(IEditorService);
|
||||
mergeEditorCompare(viewModel, editorService, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -361,20 +360,29 @@ export class CompareInput2WithBaseCommand extends MergeEditorAction {
|
|||
}
|
||||
|
||||
override runWithViewModel(viewModel: MergeEditorViewModel, accessor: ServicesAccessor): void {
|
||||
const commandService = accessor.get(ICommandService);
|
||||
mergeEditorCompare(viewModel, commandService, 2);
|
||||
const editorService = accessor.get(IEditorService);
|
||||
mergeEditorCompare(viewModel, editorService, 2);
|
||||
}
|
||||
}
|
||||
|
||||
function mergeEditorCompare(viewModel: MergeEditorViewModel, commandService: ICommandService, inputNumber: 1 | 2) {
|
||||
async function mergeEditorCompare(viewModel: MergeEditorViewModel, editorService: IEditorService, inputNumber: 1 | 2) {
|
||||
const model = viewModel.model;
|
||||
const base = model.base.uri;
|
||||
const input = inputNumber === 1 ? model.input1.textModel.uri : model.input2.textModel.uri;
|
||||
openDiffEditor(commandService, base, input);
|
||||
}
|
||||
const base = model.base;
|
||||
const input = inputNumber === 1 ? viewModel.inputCodeEditorView1.editor : viewModel.inputCodeEditorView2.editor;
|
||||
|
||||
function openDiffEditor(commandService: ICommandService, left: URI, right: URI, label?: string) {
|
||||
commandService.executeCommand(API_OPEN_DIFF_EDITOR_COMMAND_ID, left, right, label);
|
||||
const lineNumber = input.getPosition()!.lineNumber;
|
||||
await editorService.openEditor({
|
||||
original: { resource: base.uri },
|
||||
modified: { resource: input.getModel()!.uri },
|
||||
options: {
|
||||
selection: {
|
||||
startLineNumber: lineNumber,
|
||||
startColumn: 1,
|
||||
},
|
||||
revealIfOpened: true,
|
||||
revealIfVisible: true,
|
||||
} as ITextEditorOptions
|
||||
});
|
||||
}
|
||||
|
||||
export class OpenBaseFile extends MergeEditorAction {
|
||||
|
|
|
@ -11,7 +11,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
|||
import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor';
|
||||
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
|
||||
import { EditorExtensions, IEditorFactoryRegistry } from 'vs/workbench/common/editor';
|
||||
import { AcceptAllInput1, AcceptAllInput2, CompareInput1WithBaseCommand, CompareInput2WithBaseCommand, GoToNextConflict, GoToPreviousConflict, OpenBaseFile, OpenMergeEditor, OpenResultResource, SetColumnLayout, SetMixedLayout, ToggleActiveConflictInput1, ToggleActiveConflictInput2 } from 'vs/workbench/contrib/mergeEditor/browser/commands/commands';
|
||||
import { AcceptAllInput1, AcceptAllInput2, CompareInput1WithBaseCommand, CompareInput2WithBaseCommand, GoToNextUnhandledConflict, GoToPreviousUnhandledConflict, OpenBaseFile, OpenMergeEditor, OpenResultResource, SetColumnLayout, SetMixedLayout, ToggleActiveConflictInput1, ToggleActiveConflictInput2 } from 'vs/workbench/contrib/mergeEditor/browser/commands/commands';
|
||||
import { MergeEditorInput } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput';
|
||||
import { MergeEditor, MergeEditorResolverContribution, MergeEditorOpenHandlerContribution } from 'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor';
|
||||
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
|
@ -53,8 +53,8 @@ registerAction2(SetColumnLayout);
|
|||
registerAction2(OpenMergeEditor);
|
||||
registerAction2(OpenBaseFile);
|
||||
|
||||
registerAction2(GoToNextConflict);
|
||||
registerAction2(GoToPreviousConflict);
|
||||
registerAction2(GoToNextUnhandledConflict);
|
||||
registerAction2(GoToPreviousUnhandledConflict);
|
||||
|
||||
registerAction2(ToggleActiveConflictInput1);
|
||||
registerAction2(ToggleActiveConflictInput2);
|
||||
|
|
|
@ -265,7 +265,7 @@ class MergeEditorCloseHandler implements IEditorCloseHandler {
|
|||
|
||||
const actions: string[] = [
|
||||
localize('saveWithConflict', "Save with Conflicts"),
|
||||
localize('discard', "Don't save"),
|
||||
localize('discard', "Don't Save"),
|
||||
localize('cancel', "Cancel"),
|
||||
];
|
||||
|
||||
|
|
|
@ -54,12 +54,18 @@ export class MergeMarkersController extends Disposable {
|
|||
const startLine = model!.getLineContent(b.lineRange.startLineNumber).substring(0, 20);
|
||||
const endLine = model!.getLineContent(b.lineRange.endLineNumberExclusive - 1).substring(0, 20);
|
||||
|
||||
const conflictingLinesCount = b.lineRange.lineCount - 2;
|
||||
|
||||
const domNode = h('div', [
|
||||
h('div.conflict-zone-root', [
|
||||
h('pre', [startLine]),
|
||||
h('span.dots', ['...']),
|
||||
h('pre', [endLine]),
|
||||
h('span.text', [nls.localize('conflictingLines', "Conflicting Lines")]),
|
||||
h('span.text', [
|
||||
conflictingLinesCount === 1
|
||||
? nls.localize('conflictingLine', "1 Conflicting Line")
|
||||
: nls.localize('conflictingLines', "{0} Conflicting Lines", conflictingLinesCount)
|
||||
]),
|
||||
]),
|
||||
]).root;
|
||||
this.viewZoneIds.push(c.addZone({
|
||||
|
|
|
@ -42,6 +42,7 @@ export class LineEdits {
|
|||
constructor(public readonly edits: readonly LineRangeEdit[]) { }
|
||||
|
||||
public apply(model: ITextModel): void {
|
||||
model.pushStackElement();
|
||||
model.pushEditOperations(
|
||||
null,
|
||||
this.edits.map((e) => {
|
||||
|
|
|
@ -317,7 +317,11 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt
|
|||
|
||||
this.item = observableValue('item', item);
|
||||
|
||||
const checkBox = new Toggle({ isChecked: false, title: localize('accept', "Accept"), icon: Codicon.check });
|
||||
const checkBox = new Toggle({
|
||||
isChecked: false,
|
||||
title: '',
|
||||
icon: Codicon.check
|
||||
});
|
||||
|
||||
this._register(attachToggleStyler(checkBox, themeService));
|
||||
|
||||
|
@ -351,14 +355,16 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt
|
|||
autorun('Update Checkbox', (reader) => {
|
||||
const item = this.item.read(reader)!;
|
||||
const value = item.toggleState.read(reader);
|
||||
const iconMap: Record<InputState, { icon: Codicon | undefined; checked: boolean }> = {
|
||||
[InputState.excluded]: { icon: undefined, checked: false },
|
||||
[InputState.conflicting]: { icon: Codicon.circleFilled, checked: false },
|
||||
[InputState.first]: { icon: Codicon.check, checked: true },
|
||||
[InputState.second]: { icon: Codicon.checkAll, checked: true },
|
||||
const iconMap: Record<InputState, { icon: Codicon | undefined; checked: boolean; title: string }> = {
|
||||
[InputState.excluded]: { icon: undefined, checked: false, title: localize('accept.excluded', "Accept") },
|
||||
[InputState.conflicting]: { icon: Codicon.circleFilled, checked: false, title: localize('accept.conflicting', "Accept (result is dirty)") },
|
||||
[InputState.first]: { icon: Codicon.check, checked: true, title: localize('accept.first', "Undo accept") },
|
||||
[InputState.second]: { icon: Codicon.checkAll, checked: true, title: localize('accept.second', "Undo accept (currently second)") },
|
||||
};
|
||||
checkBox.setIcon(iconMap[value].icon);
|
||||
checkBox.checked = iconMap[value].checked;
|
||||
const state = iconMap[value];
|
||||
checkBox.setIcon(state.icon);
|
||||
checkBox.checked = state.checked;
|
||||
checkBox.setTitle(state.title);
|
||||
|
||||
if (!item.enabled.read(reader)) {
|
||||
checkBox.disable();
|
||||
|
@ -393,7 +399,6 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt
|
|||
}
|
||||
|
||||
layout(top: number, height: number, viewTop: number, viewHeight: number): void {
|
||||
|
||||
const checkboxHeight = this.checkboxDiv.clientHeight;
|
||||
const middleHeight = height / 2 - checkboxHeight / 2;
|
||||
|
||||
|
@ -413,7 +418,7 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt
|
|||
|
||||
if (preferredParentRange[0] < preferredParentRange[1]) {
|
||||
effectiveCheckboxTop = clamp(effectiveCheckboxTop, preferredViewPortRange[0], preferredViewPortRange[1]);
|
||||
effectiveCheckboxTop = clampIfIntervalIsNonEmpty(effectiveCheckboxTop, preferredParentRange[0], preferredParentRange[1]);
|
||||
effectiveCheckboxTop = clamp(effectiveCheckboxTop, preferredParentRange[0], preferredParentRange[1]);
|
||||
}
|
||||
|
||||
this.checkboxDiv.style.top = `${effectiveCheckboxTop - top}px`;
|
||||
|
@ -431,10 +436,3 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
function clampIfIntervalIsNonEmpty(value: number, min: number, max: number): number {
|
||||
if (min >= max) {
|
||||
return value;
|
||||
}
|
||||
return Math.min(Math.max(value, min), max);
|
||||
}
|
||||
|
|
|
@ -69,9 +69,9 @@ export class MergeEditorViewModel {
|
|||
|
||||
constructor(
|
||||
public readonly model: MergeEditorModel,
|
||||
private readonly inputCodeEditorView1: InputCodeEditorView,
|
||||
private readonly inputCodeEditorView2: InputCodeEditorView,
|
||||
private readonly resultCodeEditorView: ResultCodeEditorView
|
||||
public readonly inputCodeEditorView1: InputCodeEditorView,
|
||||
public readonly inputCodeEditorView2: InputCodeEditorView,
|
||||
public readonly resultCodeEditorView: ResultCodeEditorView
|
||||
) { }
|
||||
|
||||
public setState(
|
||||
|
@ -104,34 +104,34 @@ export class MergeEditorViewModel {
|
|||
}
|
||||
}
|
||||
|
||||
public goToNextModifiedBaseRange(onlyConflicting: boolean): void {
|
||||
public goToNextModifiedBaseRange(predicate: (m: ModifiedBaseRange) => boolean): void {
|
||||
this.goToConflict(
|
||||
(e, l) =>
|
||||
this.model.modifiedBaseRanges
|
||||
.get()
|
||||
.find(
|
||||
(r) =>
|
||||
(!onlyConflicting || r.isConflicting) &&
|
||||
predicate(r) &&
|
||||
this.getRange(e, r, undefined).startLineNumber > l
|
||||
) ||
|
||||
this.model.modifiedBaseRanges
|
||||
.get()
|
||||
.find((r) => !onlyConflicting || r.isConflicting)
|
||||
.find((r) => predicate(r))
|
||||
);
|
||||
}
|
||||
|
||||
public goToPreviousModifiedBaseRange(onlyConflicting: boolean): void {
|
||||
public goToPreviousModifiedBaseRange(predicate: (m: ModifiedBaseRange) => boolean): void {
|
||||
this.goToConflict(
|
||||
(e, l) =>
|
||||
findLast(
|
||||
this.model.modifiedBaseRanges.get(),
|
||||
(r) =>
|
||||
(!onlyConflicting || r.isConflicting) &&
|
||||
predicate(r) &&
|
||||
this.getRange(e, r, undefined).endLineNumberExclusive < l
|
||||
) ||
|
||||
findLast(
|
||||
this.model.modifiedBaseRanges.get(),
|
||||
(r) => !onlyConflicting || r.isConflicting
|
||||
(r) => predicate(r)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -94,4 +94,4 @@ export class OfflineStatusBarController implements IWorkbenchContribution {
|
|||
}
|
||||
|
||||
Registry.as<IWorkbenchContributionsRegistry>(Extensions.Workbench)
|
||||
.registerWorkbenchContribution(OfflineStatusBarController, LifecyclePhase.Starting);
|
||||
.registerWorkbenchContribution(OfflineStatusBarController, LifecyclePhase.Restored);
|
||||
|
|
|
@ -607,7 +607,7 @@ export class WorkspaceTagsService implements IWorkspaceTagsService {
|
|||
tags['workspace.bower'] = nameSet.has('bower.json') || nameSet.has('bower_components');
|
||||
|
||||
tags['workspace.java.pom'] = nameSet.has('pom.xml');
|
||||
tags['workspace.java.gradle'] = nameSet.has('build.gradle') || nameSet.has('settings.gradle');
|
||||
tags['workspace.java.gradle'] = nameSet.has('build.gradle') || nameSet.has('settings.gradle') || nameSet.has('build.gradle.kts') || nameSet.has('settings.gradle.kts') || nameSet.has('gradlew') || nameSet.has('gradlew.bat');
|
||||
|
||||
tags['workspace.yeoman.code.ext'] = nameSet.has('vsc-extension-quickstart.md');
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
|||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { FloatingClickWidget } from 'vs/workbench/browser/codeeditor';
|
||||
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import { Severity } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor';
|
||||
|
||||
|
@ -66,8 +66,9 @@ export class UserDataSyncMergesViewPane extends TreeViewPane {
|
|||
@IOpenerService openerService: IOpenerService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@INotificationService notificationService: INotificationService
|
||||
) {
|
||||
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService);
|
||||
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService, notificationService);
|
||||
this.userDataSyncPreview = userDataSyncWorkbenchService.userDataSyncPreview;
|
||||
|
||||
this._register(this.userDataSyncPreview.onDidChangeResources(() => this.updateSyncButtonEnablement()));
|
||||
|
|
|
@ -7,7 +7,8 @@ import { isEqual } from 'vs/base/common/resources';
|
|||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { EditorActivation } from 'vs/platform/editor/common/editor';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { EditorResourceAccessor, EditorInputWithOptions, isEditorInputWithOptions, IUntypedEditorInput, isEditorInput, EditorInputCapabilities } from 'vs/workbench/common/editor';
|
||||
import { EditorResourceAccessor, EditorInputWithOptions, isEditorInputWithOptions, IUntypedEditorInput, isEditorInput, EditorInputCapabilities, isResourceDiffEditorInput } from 'vs/workbench/common/editor';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { IEditorGroup, GroupsOrder, preferredSideBySideGroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { PreferredGroup, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
@ -205,6 +206,9 @@ function matchesEditor(typedEditor: EditorInput, editor: EditorInput | IUntypedE
|
|||
// editors that have no `override` defined.
|
||||
//
|
||||
// TODO@lramos15 https://github.com/microsoft/vscode/issues/131619
|
||||
if (typedEditor instanceof DiffEditorInput && isResourceDiffEditorInput(editor)) {
|
||||
return matchesEditor(typedEditor.primary, editor.modified) && matchesEditor(typedEditor.secondary, editor.original);
|
||||
}
|
||||
if (typedEditor.resource) {
|
||||
return isEqual(typedEditor.resource, EditorResourceAccessor.getCanonicalUri(editor));
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ const optimist = require('optimist')
|
|||
.describe('runGlob', 'only run tests matching <file_pattern>').alias('runGlob', 'glob').alias('runGlob', 'runGrep').string('runGlob')
|
||||
.describe('build', 'run with build output (out-build)').boolean('build')
|
||||
.describe('coverage', 'generate coverage report').boolean('coverage')
|
||||
.describe('debug', 'open dev tools, keep window open, reuse app data').string('debug')
|
||||
.describe('dev', 'open dev tools, keep window open, reuse app data').alias('dev', ['dev-tools', 'devTools']).string('dev')
|
||||
.describe('reporter', 'the mocha reporter').string('reporter').default('reporter', 'spec')
|
||||
.describe('reporter-options', 'the mocha reporter options').string('reporter-options').default('reporter-options', '')
|
||||
.describe('wait-server', 'port to connect to and wait before running tests')
|
||||
|
@ -73,7 +73,7 @@ if (crashReporterDirectory) {
|
|||
});
|
||||
}
|
||||
|
||||
if (!argv.debug) {
|
||||
if (!argv.dev) {
|
||||
app.setPath('userData', path.join(tmpdir(), `vscode-tests-${Date.now()}`));
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,7 @@ class IPCRunner extends events.EventEmitter {
|
|||
app.on('ready', () => {
|
||||
|
||||
ipcMain.on('error', (_, err) => {
|
||||
if (!argv.debug) {
|
||||
if (!argv.dev) {
|
||||
console.error(err);
|
||||
app.exit(1);
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ app.on('ready', () => {
|
|||
});
|
||||
|
||||
win.webContents.on('did-finish-load', () => {
|
||||
if (argv.debug) {
|
||||
if (argv.dev) {
|
||||
win.show();
|
||||
win.webContents.openDevTools();
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ app.on('ready', () => {
|
|||
applyReporter(runner, argv);
|
||||
}
|
||||
|
||||
if (!argv.debug) {
|
||||
if (!argv.dev) {
|
||||
ipcMain.on('all done', () => app.exit(runner.didFail ? 1 : 0));
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue