提交 fecb0833 编写于 作者: M Martin Aeschlimann

Merge branch 'master' into aeschli/productIconsTheme

......@@ -69,5 +69,8 @@
"msjsdiag.debugger-for-chrome": "workspace"
},
"gulp.autoDetect": "off",
"files.insertFinalNewline": true
"files.insertFinalNewline": true,
"[typescript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
}
}
......@@ -445,7 +445,8 @@
"devDependencies": {
"@types/node": "^12.11.7",
"mocha-junit-reporter": "^1.17.0",
"mocha-multi-reporters": "^1.1.7"
"mocha-multi-reporters": "^1.1.7",
"vscode": "1.0.1"
},
"dependencies": {
"@emmetio/css-parser": "ramya-rao-a/css-parser#vscode",
......
......@@ -3,68 +3,28 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as Mocha from 'mocha';
import * as glob from 'glob';
const path = require('path');
const testRunner = require('vscode/lib/testrunner');
const suite = 'Integration Emmet Tests';
export function run(): Promise<void> {
// Create the mocha test
const options: {
ui?: string;
timeout?: number;
reporter?: string;
reporterOptions?: any;
} = {
ui: 'tdd',
timeout: 60000,
reporter: undefined,
reporterOptions: undefined
const options: any = {
ui: 'tdd',
useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'),
timeout: 60000
};
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
}
};
}
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(
process.env.BUILD_ARTIFACTSTAGINGDIRECTORY,
`test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`
)
}
};
}
const mocha = new Mocha(options);
if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') {
mocha.useColors(true);
}
const testsRoot = path.resolve(__dirname, '..');
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
testRunner.configure(options);
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
e(err);
}
});
});
}
export = testRunner;
此差异已折叠。
......@@ -1879,6 +1879,7 @@
"@types/which": "^1.0.28",
"mocha": "^3.2.0",
"mocha-junit-reporter": "^1.23.3",
"mocha-multi-reporters": "^1.1.7"
"mocha-multi-reporters": "^1.1.7",
"vscode": "^1.1.36"
}
}
......@@ -3,68 +3,28 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as Mocha from 'mocha';
import * as glob from 'glob';
const path = require('path');
const testRunner = require('vscode/lib/testrunner');
const suite = 'Integration Git Tests';
export function run(): Promise<void> {
// Create the mocha test
const options: {
ui?: string;
timeout?: number;
reporter?: string;
reporterOptions?: any;
} = {
ui: 'tdd',
timeout: 60000,
reporter: undefined,
reporterOptions: undefined
const options: any = {
ui: 'tdd',
useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'),
timeout: 60000
};
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
}
};
}
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(
process.env.BUILD_ARTIFACTSTAGINGDIRECTORY,
`test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`
)
}
};
}
const mocha = new Mocha(options);
if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') {
mocha.useColors(true);
}
const testsRoot = path.resolve(__dirname, '..');
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
testRunner.configure(options);
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
e(err);
}
});
});
}
export = testRunner;
此差异已折叠。
......@@ -346,6 +346,7 @@
"mocha-multi-reporters": "^1.1.7",
"ts-loader": "^6.2.1",
"typescript": "^3.7.3",
"vscode": "^1.1.10",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.0"
}
......
......@@ -3,68 +3,28 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as Mocha from 'mocha';
import * as glob from 'glob';
const path = require('path');
const testRunner = require('vscode/lib/testrunner');
const suite = 'Integration Markdown Tests';
export function run(): Promise<void> {
// Create the mocha test
const options: {
ui?: string;
timeout?: number;
reporter?: string;
reporterOptions?: any;
} = {
ui: 'tdd',
timeout: 60000,
reporter: undefined,
reporterOptions: undefined
const options: any = {
ui: 'tdd',
useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'),
timeout: 60000
};
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
}
};
}
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(
process.env.BUILD_ARTIFACTSTAGINGDIRECTORY,
`test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`
)
}
};
}
const mocha = new Mocha(options);
if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') {
mocha.useColors(true);
}
const testsRoot = path.resolve(__dirname, '..');
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
testRunner.configure(options);
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
e(err);
}
});
});
}
export = testRunner;
......@@ -26,7 +26,8 @@
"devDependencies": {
"@types/node": "^12.11.7",
"@types/rimraf": "2.0.2",
"@types/semver": "^5.5.0"
"@types/semver": "^5.5.0",
"vscode": "^1.1.36"
},
"scripts": {
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:typescript ./tsconfig.json"
......
......@@ -44,7 +44,8 @@ class TypeScriptWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvide
const args: Proto.NavtoRequestArgs = {
file: filepath,
searchValue: search
searchValue: search,
maxResultCount: 256,
};
const response = await this.client.execute('navto', args, token);
......@@ -52,18 +53,12 @@ class TypeScriptWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvide
return [];
}
const result: vscode.SymbolInformation[] = [];
for (const item of response.body) {
if (!item.containerName && item.kind === 'alias') {
continue;
}
const label = TypeScriptWorkspaceSymbolProvider.getLabel(item);
result.push(new vscode.SymbolInformation(label, getSymbolKind(item), item.containerName || '',
typeConverters.Location.fromTextSpan(this.client.toResource(item.file), item)));
}
return result;
return response.body
.filter(item => item.containerName && item.kind !== 'alias')
.map(item => this.toSymbolInformation(item));
}
private async toOpenedFiledPath(document: vscode.TextDocument) {
if (document.uri.scheme === fileSchemes.git) {
try {
......@@ -79,6 +74,15 @@ class TypeScriptWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvide
return this.client.toOpenedFilePath(document);
}
private toSymbolInformation(item: Proto.NavtoItem) {
const label = TypeScriptWorkspaceSymbolProvider.getLabel(item);
return new vscode.SymbolInformation(
label,
getSymbolKind(item),
item.containerName || '',
typeConverters.Location.fromTextSpan(this.client.toResource(item.file), item));
}
private static getLabel(item: Proto.NavtoItem) {
const label = item.name;
if (item.kind === 'method' || item.kind === 'function') {
......
......@@ -3,48 +3,26 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as Mocha from 'mocha';
import * as glob from 'glob';
//
// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING
//
// This file is providing the test runner to use when running extension tests.
// By default the test runner in use is Mocha based.
//
// You can provide your own test runner if you want to override it by exporting
// a function run(testRoot: string, clb: (error:Error) => void) that the extension
// host can call to run the tests. The test runner is expected to use console.log
// to report the results back to the caller. When the tests are finished, return
// a possible error to the callback or null if none.
export function run(): Promise<void> {
// Create the mocha test
const options: {
ui?: string;
timeout?: number;
} = {
ui: 'tdd',
timeout: 60000
};
const testRunner = require('vscode/lib/testrunner');
const mocha = new Mocha(options);
if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') {
mocha.useColors(true);
}
// You can directly control Mocha options by uncommenting the following lines
// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info
testRunner.configure({
ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.)
useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'), // colored output from test results (only windows cannot handle)
timeout: 60000,
});
const testsRoot = path.resolve(__dirname, '..');
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
e(err);
}
});
});
}
export = testRunner;
......@@ -76,6 +76,7 @@
"languages": [
"markdown"
],
"configurationAttributes": {
"launch": {
"required": [
......@@ -120,6 +121,7 @@
"@types/node": "^12.11.7",
"mocha-junit-reporter": "^1.17.0",
"mocha-multi-reporters": "^1.1.7",
"typescript": "^1.6.2"
"typescript": "^1.6.2",
"vscode": "1.1.5"
}
}
......@@ -3,68 +3,28 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as Mocha from 'mocha';
import * as glob from 'glob';
const path = require('path');
const testRunner = require('vscode/lib/testrunner');
const suite = 'Integration Single Folder Tests';
export function run(): Promise<void> {
// Create the mocha test
const options: {
ui?: string;
timeout?: number;
reporter?: string;
reporterOptions?: any;
} = {
ui: 'tdd',
timeout: 60000,
reporter: undefined,
reporterOptions: undefined
const options: any = {
ui: 'tdd',
useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'),
timeout: 60000
};
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
}
};
}
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(
process.env.BUILD_ARTIFACTSTAGINGDIRECTORY,
`test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`
)
}
};
}
const mocha = new Mocha(options);
if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') {
mocha.useColors(true);
}
const testsRoot = path.resolve(__dirname, '.');
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
testRunner.configure(options);
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
e(err);
}
});
});
}
export = testRunner;
......@@ -3,68 +3,28 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as Mocha from 'mocha';
import * as glob from 'glob';
const path = require('path');
const testRunner = require('vscode/lib/testrunner');
const suite = 'Integration Workspace Tests';
export function run(): Promise<void> {
// Create the mocha test
const options: {
ui?: string;
timeout?: number;
reporter?: string;
reporterOptions?: any;
} = {
ui: 'tdd',
timeout: 60000,
reporter: undefined,
reporterOptions: undefined
const options: any = {
ui: 'tdd',
useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'),
timeout: 60000
};
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
}
};
}
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(
process.env.BUILD_ARTIFACTSTAGINGDIRECTORY,
`test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`
)
}
};
}
const mocha = new Mocha(options);
if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') {
mocha.useColors(true);
}
const testsRoot = path.resolve(__dirname, '.');
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
testRunner.configure(options);
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
e(err);
}
});
});
}
export = testRunner;
......@@ -22,7 +22,8 @@
"devDependencies": {
"@types/node": "^12.11.7",
"mocha-junit-reporter": "^1.17.0",
"mocha-multi-reporters": "^1.1.7"
"mocha-multi-reporters": "^1.1.7",
"vscode": "1.1.5"
},
"contributes": {
"semanticTokenTypes": [
......@@ -40,9 +41,7 @@
"semanticTokenStyleDefaults": [
{
"selector": "testToken",
"scope": [
"entity.name.function.special"
]
"scope": [ "entity.name.function.special" ]
},
{
"selector": "*.testModifier",
......
......@@ -3,68 +3,28 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as Mocha from 'mocha';
import * as glob from 'glob';
const path = require('path');
const testRunner = require('vscode/lib/testrunner');
const suite = 'Integration Colorize Tests';
export function run(): Promise<void> {
// Create the mocha test
const options: {
ui?: string;
timeout?: number;
reporter?: string;
reporterOptions?: any;
} = {
ui: 'tdd',
timeout: 60000,
reporter: undefined,
reporterOptions: undefined
const options: any = {
ui: 'tdd',
useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'),
timeout: 60000
};
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
}
};
}
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(
process.env.BUILD_ARTIFACTSTAGINGDIRECTORY,
`test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`
)
}
};
}
const mocha = new Mocha(options);
if (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32') {
mocha.useColors(true);
}
const testsRoot = path.resolve(__dirname, '..');
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot, ignore: '**/node_modules/**' }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
testRunner.configure(options);
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
e(err);
}
});
});
}
export = testRunner;
......@@ -8,9 +8,7 @@
"engines": {
"vscode": "^1.25.0"
},
"extensionKind": [
"ui"
],
"extensionKind": [ "ui" ],
"scripts": {
"compile": "node ./node_modules/vscode/bin/compile -watch -p ./",
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:vscode-test-resolver ./tsconfig.json"
......@@ -23,7 +21,8 @@
],
"main": "./out/extension",
"devDependencies": {
"@types/node": "^12.11.7"
"@types/node": "^12.11.7",
"vscode": "1.1.5"
},
"contributes": {
"resourceLabelFormatters": [
......@@ -89,4 +88,6 @@
}
}
}
}
......@@ -856,18 +856,13 @@ export namespace CoreNavigationCommands {
}
}));
export const CursorLineStart: CoreEditorCommand = registerEditorCommand(new class extends CoreEditorCommand {
constructor() {
super({
id: 'cursorLineStart',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 0,
mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_A }
}
});
class LineStartCommand extends CoreEditorCommand {
private readonly _inSelectionMode: boolean;
constructor(opts: ICommandOptions & { inSelectionMode: boolean; }) {
super(opts);
this._inSelectionMode = opts.inSelectionMode;
}
public runCoreEditorCommand(cursors: ICursors, args: any): void {
......@@ -885,11 +880,35 @@ export namespace CoreNavigationCommands {
for (let i = 0, len = cursors.length; i < len; i++) {
const cursor = cursors[i];
const lineNumber = cursor.modelState.position.lineNumber;
result[i] = CursorState.fromModelState(cursor.modelState.move(false, lineNumber, 1, 0));
result[i] = CursorState.fromModelState(cursor.modelState.move(this._inSelectionMode, lineNumber, 1, 0));
}
return result;
}
});
}
export const CursorLineStart: CoreEditorCommand = registerEditorCommand(new LineStartCommand({
inSelectionMode: false,
id: 'cursorLineStart',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 0,
mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_A }
}
}));
export const CursorLineStartSelect: CoreEditorCommand = registerEditorCommand(new LineStartCommand({
inSelectionMode: true,
id: 'cursorLineStartSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 0,
mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.KEY_A }
}
}));
class EndCommand extends CoreEditorCommand {
......@@ -935,18 +954,13 @@ export namespace CoreNavigationCommands {
}
}));
export const CursorLineEnd: CoreEditorCommand = registerEditorCommand(new class extends CoreEditorCommand {
constructor() {
super({
id: 'cursorLineEnd',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 0,
mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_E }
}
});
class LineEndCommand extends CoreEditorCommand {
private readonly _inSelectionMode: boolean;
constructor(opts: ICommandOptions & { inSelectionMode: boolean; }) {
super(opts);
this._inSelectionMode = opts.inSelectionMode;
}
public runCoreEditorCommand(cursors: ICursors, args: any): void {
......@@ -965,11 +979,35 @@ export namespace CoreNavigationCommands {
const cursor = cursors[i];
const lineNumber = cursor.modelState.position.lineNumber;
const maxColumn = context.model.getLineMaxColumn(lineNumber);
result[i] = CursorState.fromModelState(cursor.modelState.move(false, lineNumber, maxColumn, 0));
result[i] = CursorState.fromModelState(cursor.modelState.move(this._inSelectionMode, lineNumber, maxColumn, 0));
}
return result;
}
});
}
export const CursorLineEnd: CoreEditorCommand = registerEditorCommand(new LineEndCommand({
inSelectionMode: false,
id: 'cursorLineEnd',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 0,
mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_E }
}
}));
export const CursorLineEndSelect: CoreEditorCommand = registerEditorCommand(new LineEndCommand({
inSelectionMode: true,
id: 'cursorLineEndSelect',
precondition: undefined,
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: 0,
mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.KEY_E }
}
}));
class TopCommand extends CoreEditorCommand {
......
......@@ -252,9 +252,9 @@ export class TextAreaHandler extends ViewPart {
this._viewController.setSelection('keyboard', modelSelection);
}));
this._register(this._textAreaInput.onCompositionStart(() => {
this._register(this._textAreaInput.onCompositionStart((e) => {
const lineNumber = this._selections[0].startLineNumber;
const column = this._selections[0].startColumn;
const column = this._selections[0].startColumn - (e.moveOneCharacterLeft ? 1 : 0);
this._context.privateViewEventBus.emit(new viewEvents.ViewRevealRangeRequestEvent(
'keyboard',
......
......@@ -95,6 +95,10 @@ class InMemoryClipboardMetadataManager {
}
}
export interface ICompositionStartEvent {
moveOneCharacterLeft: boolean;
}
/**
* Writes screen reader content to the textarea and is able to analyze its input events to generate:
* - onCut
......@@ -126,8 +130,8 @@ export class TextAreaInput extends Disposable {
private _onType = this._register(new Emitter<ITypeData>());
public readonly onType: Event<ITypeData> = this._onType.event;
private _onCompositionStart = this._register(new Emitter<void>());
public readonly onCompositionStart: Event<void> = this._onCompositionStart.event;
private _onCompositionStart = this._register(new Emitter<ICompositionStartEvent>());
public readonly onCompositionStart: Event<ICompositionStartEvent> = this._onCompositionStart.event;
private _onCompositionUpdate = this._register(new Emitter<ICompositionData>());
public readonly onCompositionUpdate: Event<ICompositionData> = this._onCompositionUpdate.event;
......@@ -165,9 +169,11 @@ export class TextAreaInput extends Disposable {
this._isDoingComposition = false;
this._nextCommand = ReadFromTextArea.Type;
let lastKeyDown: IKeyboardEvent | null = null;
this._register(dom.addStandardDisposableListener(textArea.domNode, 'keydown', (e: IKeyboardEvent) => {
if (this._isDoingComposition &&
(e.keyCode === KeyCode.KEY_IN_COMPOSITION || e.keyCode === KeyCode.Backspace)) {
if (e.keyCode === KeyCode.KEY_IN_COMPOSITION
|| (this._isDoingComposition && e.keyCode === KeyCode.Backspace)) {
// Stop propagation for keyDown events if the IME is processing key input
e.stopPropagation();
}
......@@ -177,6 +183,8 @@ export class TextAreaInput extends Disposable {
// See https://msdn.microsoft.com/en-us/library/ie/ms536939(v=vs.85).aspx
e.preventDefault();
}
lastKeyDown = e;
this._onKeyDown.fire(e);
}));
......@@ -190,12 +198,35 @@ export class TextAreaInput extends Disposable {
}
this._isDoingComposition = true;
// In IE we cannot set .value when handling 'compositionstart' because the entire composition will get canceled.
if (!browser.isEdge) {
let moveOneCharacterLeft = false;
if (
platform.isMacintosh
&& lastKeyDown
&& lastKeyDown.equals(KeyCode.KEY_IN_COMPOSITION)
&& this._textAreaState.selectionStart === this._textAreaState.selectionEnd
&& this._textAreaState.selectionStart > 0
&& this._textAreaState.value.substr(this._textAreaState.selectionStart - 1, 1) === e.data
) {
// Handling long press case on macOS + arrow key => pretend the character was selected
if (lastKeyDown.code === 'ArrowRight' || lastKeyDown.code === 'ArrowLeft') {
moveOneCharacterLeft = true;
}
}
if (moveOneCharacterLeft) {
this._textAreaState = new TextAreaState(
this._textAreaState.value,
this._textAreaState.selectionStart - 1,
this._textAreaState.selectionEnd,
this._textAreaState.selectionStartPosition ? new Position(this._textAreaState.selectionStartPosition.lineNumber, this._textAreaState.selectionStartPosition.column - 1) : null,
this._textAreaState.selectionEndPosition
);
} else if (!browser.isEdge) {
// In IE we cannot set .value when handling 'compositionstart' because the entire composition will get canceled.
this._setAndWriteTextAreaState('compositionstart', TextAreaState.EMPTY);
}
this._onCompositionStart.fire();
this._onCompositionStart.fire({ moveOneCharacterLeft });
}));
/**
......
......@@ -13,66 +13,43 @@ export class MoveCaretCommand implements ICommand {
private readonly _selection: Selection;
private readonly _isMovingLeft: boolean;
private _cutStartIndex: number;
private _cutEndIndex: number;
private _moved: boolean;
private _selectionId: string | null;
constructor(selection: Selection, isMovingLeft: boolean) {
this._selection = selection;
this._isMovingLeft = isMovingLeft;
this._cutStartIndex = -1;
this._cutEndIndex = -1;
this._moved = false;
this._selectionId = null;
}
public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {
let s = this._selection;
this._selectionId = builder.trackSelection(s);
if (s.startLineNumber !== s.endLineNumber) {
if (this._selection.startLineNumber !== this._selection.endLineNumber || this._selection.isEmpty()) {
return;
}
if (this._isMovingLeft && s.startColumn === 0) {
const lineNumber = this._selection.startLineNumber;
const startColumn = this._selection.startColumn;
const endColumn = this._selection.endColumn;
if (this._isMovingLeft && startColumn === 1) {
return;
} else if (!this._isMovingLeft && s.endColumn === model.getLineMaxColumn(s.startLineNumber)) {
}
if (!this._isMovingLeft && endColumn === model.getLineMaxColumn(lineNumber)) {
return;
}
let lineNumber = s.selectionStartLineNumber;
let lineContent = model.getLineContent(lineNumber);
let left: string;
let middle: string;
let right: string;
if (this._isMovingLeft) {
left = lineContent.substring(0, s.startColumn - 2);
middle = lineContent.substring(s.startColumn - 1, s.endColumn - 1);
right = lineContent.substring(s.startColumn - 2, s.startColumn - 1) + lineContent.substring(s.endColumn - 1);
const rangeBefore = new Range(lineNumber, startColumn - 1, lineNumber, startColumn);
const charBefore = model.getValueInRange(rangeBefore);
builder.addEditOperation(rangeBefore, null);
builder.addEditOperation(new Range(lineNumber, endColumn, lineNumber, endColumn), charBefore);
} else {
left = lineContent.substring(0, s.startColumn - 1) + lineContent.substring(s.endColumn - 1, s.endColumn);
middle = lineContent.substring(s.startColumn - 1, s.endColumn - 1);
right = lineContent.substring(s.endColumn);
const rangeAfter = new Range(lineNumber, endColumn, lineNumber, endColumn + 1);
const charAfter = model.getValueInRange(rangeAfter);
builder.addEditOperation(rangeAfter, null);
builder.addEditOperation(new Range(lineNumber, startColumn, lineNumber, startColumn), charAfter);
}
let newLineContent = left + middle + right;
builder.addEditOperation(new Range(lineNumber, 1, lineNumber, model.getLineMaxColumn(lineNumber)), null);
builder.addEditOperation(new Range(lineNumber, 1, lineNumber, 1), newLineContent);
this._cutStartIndex = s.startColumn + (this._isMovingLeft ? -1 : 1);
this._cutEndIndex = this._cutStartIndex + s.endColumn - s.startColumn;
this._moved = true;
}
public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {
let result = helper.getTrackedSelection(this._selectionId!);
if (this._moved) {
result = result.setStartPosition(result.startLineNumber, this._cutStartIndex);
result = result.setEndPosition(result.startLineNumber, this._cutEndIndex);
if (this._isMovingLeft) {
return new Selection(this._selection.startLineNumber, this._selection.startColumn - 1, this._selection.endLineNumber, this._selection.endColumn - 1);
} else {
return new Selection(this._selection.startLineNumber, this._selection.startColumn + 1, this._selection.endLineNumber, this._selection.endColumn + 1);
}
return result;
}
}
......@@ -10,10 +10,7 @@ import { IEditorContribution } from 'vs/editor/common/editorCommon';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IQuickInputService, IQuickInputButton, IQuickPickItem, IQuickPick, IInputBox, IQuickNavigateConfiguration, IPickOptions, QuickPickInput, IInputOptions } from 'vs/platform/quickinput/common/quickInput';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
......@@ -28,15 +25,13 @@ export class EditorScopedQuickInputServiceImpl extends QuickInputService {
constructor(
editor: ICodeEditor,
@IConfigurationService configurationService: IConfigurationService,
@IInstantiationService instantiationService: IInstantiationService,
@IKeybindingService keybindingService: IKeybindingService,
@IContextKeyService contextKeyService: IContextKeyService,
@IThemeService themeService: IThemeService,
@IAccessibilityService accessibilityService: IAccessibilityService,
@ILayoutService layoutService: ILayoutService
) {
super({ args: Object.create(null) } as IEnvironmentService, configurationService, instantiationService, keybindingService, contextKeyService, themeService, accessibilityService, layoutService);
super(instantiationService, contextKeyService, themeService, accessibilityService, layoutService);
// Use the passed in code editor as host for the quick input widget
const contribution = QuickInputEditorContribution.get(editor);
......
......@@ -9,13 +9,10 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IThemeService, Themable } from 'vs/platform/theme/common/themeService';
import { inputBackground, inputForeground, inputBorder, inputValidationInfoBackground, inputValidationInfoForeground, inputValidationInfoBorder, inputValidationWarningBackground, inputValidationWarningForeground, inputValidationWarningBorder, inputValidationErrorBackground, inputValidationErrorForeground, inputValidationErrorBorder, badgeBackground, badgeForeground, contrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, progressBarBackground, widgetShadow, listFocusForeground, listFocusBackground, activeContrastBorder, pickerGroupBorder, pickerGroupForeground, quickInputForeground, quickInputBackground, quickInputTitleBackground } from 'vs/platform/theme/common/colorRegistry';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { computeStyles } from 'vs/platform/theme/common/styler';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { QuickInputController, IQuickInputStyles } from 'vs/base/parts/quickinput/browser/quickInput';
import { QuickInputController, IQuickInputStyles, IQuickInputOptions } from 'vs/base/parts/quickinput/browser/quickInput';
import { WorkbenchList } from 'vs/platform/list/browser/listService';
import { List, IListOptions } from 'vs/base/browser/ui/list/listWidget';
import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list';
......@@ -43,25 +40,22 @@ export class QuickInputService extends Themable implements IQuickInputService {
private readonly contexts = new Map<string, IContextKey<boolean>>();
constructor(
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IKeybindingService private readonly keybindingService: IKeybindingService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IThemeService themeService: IThemeService,
@IAccessibilityService private readonly accessibilityService: IAccessibilityService,
@ILayoutService private readonly layoutService: ILayoutService
@ILayoutService protected readonly layoutService: ILayoutService
) {
super(themeService);
}
protected createController(host: IQuickInputControllerHost = this.layoutService): QuickInputController {
const controller = this._register(new QuickInputController({
protected createController(host: IQuickInputControllerHost = this.layoutService, options?: Partial<IQuickInputOptions>): QuickInputController {
const defaultOptions: IQuickInputOptions = {
idPrefix: 'quickInput_', // Constant since there is still only one.
container: host.container,
ignoreFocusOut: () => this.environmentService.args['sticky-quickopen'] || !this.configurationService.getValue('workbench.quickOpen.closeOnFocusLost'),
ignoreFocusOut: () => false,
isScreenReaderOptimized: () => this.accessibilityService.isScreenReaderOptimized(),
backKeybindingLabel: () => this.keybindingService.lookupKeybinding('workbench.action.quickInputBack')?.getLabel() || undefined,
backKeybindingLabel: () => undefined,
setContextKey: (id?: string) => this.setContextKey(id),
returnFocus: () => host.focus(),
createList: <T>(
......@@ -72,6 +66,11 @@ export class QuickInputService extends Themable implements IQuickInputService {
options: IListOptions<T>,
) => this.instantiationService.createInstance(WorkbenchList, user, container, delegate, renderers, options) as List<T>,
styles: this.computeStyles()
};
const controller = this._register(new QuickInputController({
...defaultOptions,
...options
}));
controller.layout(host.dimension, host.offset?.top ?? 0);
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { QuickInputController } from 'vs/base/parts/quickinput/browser/quickInput';
import { QuickInputService as BaseQuickInputService } from 'vs/platform/quickinput/browser/quickInput';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
export class QuickInputService extends BaseQuickInputService {
constructor(
@IEnvironmentService private environmentService: IEnvironmentService,
@IConfigurationService private configurationService: IConfigurationService,
@IInstantiationService instantiationService: IInstantiationService,
@IKeybindingService private keybindingService: IKeybindingService,
@IContextKeyService contextKeyService: IContextKeyService,
@IThemeService themeService: IThemeService,
@IAccessibilityService accessibilityService: IAccessibilityService,
@ILayoutService protected layoutService: ILayoutService
) {
super(instantiationService, contextKeyService, themeService, accessibilityService, layoutService);
}
protected createController(): QuickInputController {
return super.createController(this.layoutService, {
ignoreFocusOut: () => this.environmentService.args['sticky-quickopen'] || !this.configurationService.getValue('workbench.quickOpen.closeOnFocusLost'),
backKeybindingLabel: () => this.keybindingService.lookupKeybinding('workbench.action.quickInputBack')?.getLabel() || undefined,
});
}
}
registerSingleton(IQuickInputService, QuickInputService, true);
......@@ -84,6 +84,7 @@ import 'vs/workbench/services/workingCopy/common/workingCopyService';
import 'vs/workbench/services/workingCopy/common/workingCopyFileService';
import 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import 'vs/workbench/services/views/browser/viewDescriptorService';
import 'vs/workbench/services/quickinput/browser/quickInputService';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
......@@ -112,8 +113,6 @@ import { OpenerService } from 'vs/editor/browser/services/openerService';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync';
import { UserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSyncEnablementService';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { QuickInputService } from 'vs/platform/quickinput/browser/quickInput';
registerSingleton(IUserDataSyncEnablementService, UserDataSyncEnablementService);
registerSingleton(IGlobalExtensionEnablementService, GlobalExtensionEnablementService);
......@@ -129,7 +128,6 @@ registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationSe
registerSingleton(IMenuService, MenuService, true);
registerSingleton(IDownloadService, DownloadService, true);
registerSingleton(IOpenerService, OpenerService, true);
registerSingleton(IQuickInputService, QuickInputService, true);
//#endregion
......
......@@ -208,20 +208,6 @@
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
"@types/events@*":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
"@types/glob@5.0.36":
version "5.0.36"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.36.tgz#0c80a9c8664fc7d19781de229f287077fd622cb2"
integrity sha512-KEzSKuP2+3oOjYYjujue6Z3Yqis5HKA1BsIC+jZ1v3lrRNdsqyNNtX0rQf6LSuI4DJJ2z5UV//zBZCcvM0xikg==
dependencies:
"@types/events" "*"
"@types/minimatch" "*"
"@types/node" "*"
"@types/graceful-fs@4.1.2":
version "4.1.2"
resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.2.tgz#fbc9575dbcc6d1d91dd768d30c5fc0c19f6c50bd"
......@@ -253,11 +239,6 @@
resolved "https://registry.yarnpkg.com/@types/keytar/-/keytar-4.4.0.tgz#ca24e6ee6d0df10c003aafe26e93113b8faf0d8e"
integrity sha512-cq/NkUUy6rpWD8n7PweNQQBpw2o0cf5v6fbkUVEpOB9VzzIvyPvSEId1/goIj+MciW2v1Lw5mRimKO01XgE9EA==
"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
"@types/mocha@2.2.39":
version "2.2.39"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.39.tgz#f68d63db8b69c38e9558b4073525cf96c4f7a829"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册