Merge branch 'master' of https://github.com/Microsoft/vscode
This commit is contained in:
commit
47bc908e39
|
@ -284,6 +284,6 @@ gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => {
|
|||
account: process.env.AZURE_STORAGE_ACCOUNT,
|
||||
key: process.env.AZURE_STORAGE_ACCESS_KEY,
|
||||
container: 'sourcemaps',
|
||||
prefix: commit + '/core/'
|
||||
prefix: commit + '/'
|
||||
}));
|
||||
});
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
import {window, workspace, DecorationOptions, DecorationRenderOptions, Disposable, Range, TextDocument, TextEditor} from 'vscode';
|
||||
|
||||
const MAX_DECORATORS = 500;
|
||||
|
||||
let decorationType: DecorationRenderOptions = {
|
||||
before: {
|
||||
contentText: ' ',
|
||||
|
@ -76,7 +78,7 @@ export function activateColorDecorations(decoratorProvider: (uri: string) => The
|
|||
let document = editor.document;
|
||||
if (supportedLanguages[document.languageId]) {
|
||||
decoratorProvider(document.uri.toString()).then(ranges => {
|
||||
let decorations = ranges.map(range => {
|
||||
let decorations = ranges.slice(0, MAX_DECORATORS).map(range => {
|
||||
let color = document.getText(range);
|
||||
return <DecorationOptions>{
|
||||
range: range,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"comments": {
|
||||
"lineComment": "//",
|
||||
"blockComment": [ "/*", "*/" ]
|
||||
"lineComment": "#",
|
||||
"blockComment": [ "#", " " ]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"comments": {
|
||||
"lineComment": "//",
|
||||
"blockComment": [ "/*", "*/" ]
|
||||
"lineComment": "#",
|
||||
"blockComment": [ "#", " " ]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
"mimetypes": ["text/html", "text/x-jshtm", "text/template", "text/ng-template", "application/xhtml+xml"]
|
||||
}],
|
||||
"grammars": [{
|
||||
/* "language": "html", not yet enabled*/
|
||||
"scopeName": "text.html.basic",
|
||||
"path": "./syntaxes/HTML.plist"
|
||||
}]
|
||||
|
|
|
@ -54,6 +54,35 @@ function invertColor(color) {
|
|||
return res;
|
||||
}
|
||||
|
||||
function getLanguageMappings() {
|
||||
var langToExt = {
|
||||
'csharp': ['cs', 'csx']
|
||||
};
|
||||
|
||||
var allExtensions = fs.readdirSync('..');
|
||||
for (var i= 0; i < allExtensions.length; i++) {
|
||||
let dirPath = path.join('..', allExtensions[i], 'package.json');
|
||||
if (!fs.lstatSync(path.join('..', allExtensions[i])).isDirectory() || !fs.lstatSync(dirPath).isFile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let content = fs.readFileSync(dirPath).toString();
|
||||
let jsonContent = JSON.parse(content);
|
||||
let languages = jsonContent.contributes && jsonContent.contributes.languages;
|
||||
if (Array.isArray(languages)) {
|
||||
for (var k = 0; k < languages.length; k++) {
|
||||
var extensions = languages[k].extensions;
|
||||
var languageId = languages[k].id;
|
||||
if (Array.isArray(extensions) && languageId) {
|
||||
langToExt[languageId] = extensions.map(function (e) { return e.substr(1); });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return langToExt;
|
||||
}
|
||||
|
||||
|
||||
exports.update = function () {
|
||||
var fontMappings = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/_fonts/seti.less';
|
||||
|
@ -63,6 +92,7 @@ exports.update = function () {
|
|||
var fileName2Def = {};
|
||||
var def2ColorId = {};
|
||||
var colorId2Value = {};
|
||||
var lang2Def = {};
|
||||
|
||||
function writeFileIconContent(info) {
|
||||
var iconDefinitions = {};
|
||||
|
@ -106,14 +136,16 @@ exports.update = function () {
|
|||
file: "_default",
|
||||
fileExtensions: ext2Def,
|
||||
fileNames: fileName2Def,
|
||||
languageIds: lang2Def,
|
||||
light: {
|
||||
file: "_default_light",
|
||||
fileExtensions: getInvertSet(ext2Def),
|
||||
languageIds: getInvertSet(lang2Def),
|
||||
fileNames: getInvertSet(fileName2Def)
|
||||
},
|
||||
version: 'https://github.com/jesseweed/seti-ui/commit/' + info.commitSha,
|
||||
};
|
||||
fs.writeFileSync('./icons/seti-icon-theme.json', JSON.stringify(res, null, '\t'));
|
||||
fs.writeFileSync('./icons/vs-seti-icon-theme.json', JSON.stringify(res, null, '\t'));
|
||||
|
||||
}
|
||||
|
||||
|
@ -140,6 +172,26 @@ exports.update = function () {
|
|||
}
|
||||
def2ColorId[def] = colorId;
|
||||
}
|
||||
// replace extensions for languageId
|
||||
var langToExt = getLanguageMappings();
|
||||
for (var lang in langToExt) {
|
||||
var exts = langToExt[lang];
|
||||
var preferredDef = null;
|
||||
// use the first file association for the preferred definition
|
||||
for (var i1 = 0; i1 < exts.length && !preferredDef; i1++) {
|
||||
preferredDef = ext2Def[exts[i1]];
|
||||
}
|
||||
if (preferredDef) {
|
||||
lang2Def[lang] = preferredDef;
|
||||
for (var i1 = 0; i1 < exts.length; i1++) {
|
||||
// remove the extention association, unless it is different from the preferred
|
||||
if (ext2Def[exts[i1]] === preferredDef) {
|
||||
delete ext2Def[exts[i1]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var colors = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/ui-variables.less';
|
||||
return download(colors).then(function (content) {
|
||||
var regex3 = /(@[\w-]+):\s*(#[0-9a-z]+)/g;
|
||||
|
@ -156,7 +208,7 @@ exports.update = function () {
|
|||
console.error(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}, console.error);
|
||||
}
|
||||
|
|
|
@ -701,16 +701,9 @@
|
|||
},
|
||||
"file": "_default",
|
||||
"fileExtensions": {
|
||||
"cpp": "_cpp",
|
||||
"c": "_c",
|
||||
"cs": "_c-sharp",
|
||||
"cc": "_cpp",
|
||||
"cfc": "_coldfusion",
|
||||
"cfm": "_coldfusion",
|
||||
"coffee": "_coffee",
|
||||
"config": "_config",
|
||||
"cson": "_json",
|
||||
"css": "_css",
|
||||
"css.map": "_css",
|
||||
"sss": "_css",
|
||||
"csv": "_csv",
|
||||
|
@ -719,14 +712,11 @@
|
|||
"elm": "_elm",
|
||||
"ico": "_favicon",
|
||||
"gitignore": "_github",
|
||||
"gitconfig": "_github",
|
||||
"gitkeep": "_github",
|
||||
"gitattributes": "_github",
|
||||
"go": "_go2",
|
||||
"slide": "_go",
|
||||
"article": "_go",
|
||||
"gradle": "_gradle",
|
||||
"groovy": "_grails",
|
||||
"gsp": "_grails",
|
||||
"hh": "_hacklang",
|
||||
"haml": "_haml",
|
||||
|
@ -735,57 +725,37 @@
|
|||
"hjs": "_mustache",
|
||||
"hs": "_haskell",
|
||||
"lhs": "_haskell",
|
||||
"html": "_html",
|
||||
"jade": "_jade",
|
||||
"java": "_java",
|
||||
"class": "_java",
|
||||
"classpath": "_java",
|
||||
"js": "_javascript",
|
||||
"js.map": "_javascript",
|
||||
"es": "_javascript",
|
||||
"es5": "_javascript",
|
||||
"es6": "_javascript",
|
||||
"es7": "_javascript",
|
||||
"json": "_json",
|
||||
"jl": "_julia",
|
||||
"less": "_less",
|
||||
"liquid": "_liquid",
|
||||
"ls": "_livescript",
|
||||
"lua": "_lua",
|
||||
"markdown": "_markdown",
|
||||
"md": "_markdown",
|
||||
"mustache": "_mustache",
|
||||
"stache": "_mustache",
|
||||
"npm-debug.log": "_npm",
|
||||
"npmignore": "_npm",
|
||||
"h": "_c",
|
||||
"m": "_c",
|
||||
"ml": "_ocaml",
|
||||
"mli": "_ocaml",
|
||||
"cmx": "_ocaml",
|
||||
"cmxa": "_ocaml",
|
||||
"pl": "_perl",
|
||||
"php": "_php",
|
||||
"php.inc": "_php",
|
||||
"pug": "_pug",
|
||||
"pp": "_puppet",
|
||||
"py": "_python",
|
||||
"jsx": "_react",
|
||||
"cjsx": "_react",
|
||||
"tsx": "_react",
|
||||
"rb": "_ruby",
|
||||
"erb": "_ruby",
|
||||
"erb.html": "_ruby",
|
||||
"html.erb": "_ruby",
|
||||
"rs": "_rust",
|
||||
"sass": "_sass",
|
||||
"scss": "_sass",
|
||||
"slim": "_slim",
|
||||
"smarty.tpl": "_smarty",
|
||||
"sbt": "_sbt",
|
||||
"scala": "_scala",
|
||||
"styl": "_stylus",
|
||||
"swift": "_swift",
|
||||
"tf": "_terraform",
|
||||
"tf.json": "_terraform",
|
||||
"tex": "_tex",
|
||||
|
@ -795,12 +765,9 @@
|
|||
"ins": "_tex",
|
||||
"txt": "_default",
|
||||
"twig": "_twig",
|
||||
"ts": "_typescript",
|
||||
"vala": "_vala",
|
||||
"vapi": "_vala",
|
||||
"xml": "_xml",
|
||||
"yml": "_yml",
|
||||
"yaml": "_yml",
|
||||
"ai": "_illustrator",
|
||||
"psd": "_photoshop",
|
||||
"pdf": "_pdf",
|
||||
|
@ -814,11 +781,7 @@
|
|||
"jpeg": "_image",
|
||||
"svg": "_svg",
|
||||
"svgx": "_image",
|
||||
"cmd": "_shell",
|
||||
"sh": "_shell",
|
||||
"zsh": "_shell",
|
||||
"fish": "_shell",
|
||||
"zshrc": "_shell",
|
||||
"mov": "_video",
|
||||
"ogv": "_video",
|
||||
"webm": "_video",
|
||||
|
@ -865,19 +828,45 @@
|
|||
"TODO": "_todo",
|
||||
"npm-debug.log": "_npm_ignored"
|
||||
},
|
||||
"languageIds": {
|
||||
"csharp": "_c-sharp",
|
||||
"bat": "_shell",
|
||||
"coffeescript": "_coffee",
|
||||
"c": "_c",
|
||||
"cpp": "_cpp",
|
||||
"css": "_css",
|
||||
"go": "_go2",
|
||||
"groovy": "_grails",
|
||||
"html": "_html",
|
||||
"ini": "_github",
|
||||
"jade": "_jade",
|
||||
"java": "_java",
|
||||
"javascriptreact": "_react",
|
||||
"javascript": "_javascript",
|
||||
"json": "_json",
|
||||
"less": "_less",
|
||||
"lua": "_lua",
|
||||
"markdown": "_markdown",
|
||||
"objective-c": "_c",
|
||||
"perl": "_perl",
|
||||
"php": "_php",
|
||||
"python": "_python",
|
||||
"ruby": "_ruby",
|
||||
"rust": "_rust",
|
||||
"scss": "_sass",
|
||||
"shellscript": "_shell",
|
||||
"swift": "_swift",
|
||||
"typescript": "_typescript",
|
||||
"typescriptreact": "_react",
|
||||
"xml": "_config",
|
||||
"yaml": "_yml"
|
||||
},
|
||||
"light": {
|
||||
"file": "_default_light",
|
||||
"fileExtensions": {
|
||||
"cpp": "_cpp_light",
|
||||
"c": "_c_light",
|
||||
"cs": "_c-sharp_light",
|
||||
"cc": "_cpp_light",
|
||||
"cfc": "_coldfusion_light",
|
||||
"cfm": "_coldfusion_light",
|
||||
"coffee": "_coffee_light",
|
||||
"config": "_config_light",
|
||||
"cson": "_json_light",
|
||||
"css": "_css_light",
|
||||
"css.map": "_css_light",
|
||||
"sss": "_css_light",
|
||||
"csv": "_csv_light",
|
||||
|
@ -886,14 +875,11 @@
|
|||
"elm": "_elm_light",
|
||||
"ico": "_favicon_light",
|
||||
"gitignore": "_github_light",
|
||||
"gitconfig": "_github_light",
|
||||
"gitkeep": "_github_light",
|
||||
"gitattributes": "_github_light",
|
||||
"go": "_go2_light",
|
||||
"slide": "_go_light",
|
||||
"article": "_go_light",
|
||||
"gradle": "_gradle_light",
|
||||
"groovy": "_grails_light",
|
||||
"gsp": "_grails_light",
|
||||
"hh": "_hacklang_light",
|
||||
"haml": "_haml_light",
|
||||
|
@ -902,57 +888,37 @@
|
|||
"hjs": "_mustache_light",
|
||||
"hs": "_haskell_light",
|
||||
"lhs": "_haskell_light",
|
||||
"html": "_html_light",
|
||||
"jade": "_jade_light",
|
||||
"java": "_java_light",
|
||||
"class": "_java_light",
|
||||
"classpath": "_java_light",
|
||||
"js": "_javascript_light",
|
||||
"js.map": "_javascript_light",
|
||||
"es": "_javascript_light",
|
||||
"es5": "_javascript_light",
|
||||
"es6": "_javascript_light",
|
||||
"es7": "_javascript_light",
|
||||
"json": "_json_light",
|
||||
"jl": "_julia_light",
|
||||
"less": "_less_light",
|
||||
"liquid": "_liquid_light",
|
||||
"ls": "_livescript_light",
|
||||
"lua": "_lua_light",
|
||||
"markdown": "_markdown_light",
|
||||
"md": "_markdown_light",
|
||||
"mustache": "_mustache_light",
|
||||
"stache": "_mustache_light",
|
||||
"npm-debug.log": "_npm_light",
|
||||
"npmignore": "_npm_light",
|
||||
"h": "_c_light",
|
||||
"m": "_c_light",
|
||||
"ml": "_ocaml_light",
|
||||
"mli": "_ocaml_light",
|
||||
"cmx": "_ocaml_light",
|
||||
"cmxa": "_ocaml_light",
|
||||
"pl": "_perl_light",
|
||||
"php": "_php_light",
|
||||
"php.inc": "_php_light",
|
||||
"pug": "_pug_light",
|
||||
"pp": "_puppet_light",
|
||||
"py": "_python_light",
|
||||
"jsx": "_react_light",
|
||||
"cjsx": "_react_light",
|
||||
"tsx": "_react_light",
|
||||
"rb": "_ruby_light",
|
||||
"erb": "_ruby_light",
|
||||
"erb.html": "_ruby_light",
|
||||
"html.erb": "_ruby_light",
|
||||
"rs": "_rust_light",
|
||||
"sass": "_sass_light",
|
||||
"scss": "_sass_light",
|
||||
"slim": "_slim_light",
|
||||
"smarty.tpl": "_smarty_light",
|
||||
"sbt": "_sbt_light",
|
||||
"scala": "_scala_light",
|
||||
"styl": "_stylus_light",
|
||||
"swift": "_swift_light",
|
||||
"tf": "_terraform_light",
|
||||
"tf.json": "_terraform_light",
|
||||
"tex": "_tex_light",
|
||||
|
@ -962,12 +928,9 @@
|
|||
"ins": "_tex_light",
|
||||
"txt": "_default_light",
|
||||
"twig": "_twig_light",
|
||||
"ts": "_typescript_light",
|
||||
"vala": "_vala_light",
|
||||
"vapi": "_vala_light",
|
||||
"xml": "_xml_light",
|
||||
"yml": "_yml_light",
|
||||
"yaml": "_yml_light",
|
||||
"ai": "_illustrator_light",
|
||||
"psd": "_photoshop_light",
|
||||
"pdf": "_pdf_light",
|
||||
|
@ -981,11 +944,7 @@
|
|||
"jpeg": "_image_light",
|
||||
"svg": "_svg_light",
|
||||
"svgx": "_image_light",
|
||||
"cmd": "_shell_light",
|
||||
"sh": "_shell_light",
|
||||
"zsh": "_shell_light",
|
||||
"fish": "_shell_light",
|
||||
"zshrc": "_shell_light",
|
||||
"mov": "_video_light",
|
||||
"ogv": "_video_light",
|
||||
"webm": "_video_light",
|
||||
|
@ -1006,6 +965,39 @@
|
|||
"tmp": "_clock_light",
|
||||
"DS_Store": "_ignored_light"
|
||||
},
|
||||
"languageIds": {
|
||||
"csharp": "_c-sharp_light",
|
||||
"bat": "_shell_light",
|
||||
"coffeescript": "_coffee_light",
|
||||
"c": "_c_light",
|
||||
"cpp": "_cpp_light",
|
||||
"css": "_css_light",
|
||||
"go": "_go2_light",
|
||||
"groovy": "_grails_light",
|
||||
"html": "_html_light",
|
||||
"ini": "_github_light",
|
||||
"jade": "_jade_light",
|
||||
"java": "_java_light",
|
||||
"javascriptreact": "_react_light",
|
||||
"javascript": "_javascript_light",
|
||||
"json": "_json_light",
|
||||
"less": "_less_light",
|
||||
"lua": "_lua_light",
|
||||
"markdown": "_markdown_light",
|
||||
"objective-c": "_c_light",
|
||||
"perl": "_perl_light",
|
||||
"php": "_php_light",
|
||||
"python": "_python_light",
|
||||
"ruby": "_ruby_light",
|
||||
"rust": "_rust_light",
|
||||
"scss": "_sass_light",
|
||||
"shellscript": "_shell_light",
|
||||
"swift": "_swift_light",
|
||||
"typescript": "_typescript_light",
|
||||
"typescriptreact": "_react_light",
|
||||
"xml": "_config_light",
|
||||
"yaml": "_yml_light"
|
||||
},
|
||||
"fileNames": {
|
||||
"karma.conf.js": "_karma_light",
|
||||
"karma.conf.coffee": "_karma_light",
|
||||
|
|
|
@ -100,9 +100,11 @@ class Main {
|
|||
const response = JSON.parse(err.responseText);
|
||||
return TPromise.wrapError(response.message);
|
||||
} catch (e) {
|
||||
return TPromise.wrapError(err);
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
return TPromise.wrapError(err);
|
||||
})
|
||||
.then(result => {
|
||||
const [extension] = result.firstPage;
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import {EventEmitter} from 'vs/base/common/eventEmitter';
|
||||
import {Schemas} from 'vs/base/common/network';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import {TPromise} from 'vs/base/common/winjs.base';
|
||||
|
@ -56,13 +55,18 @@ export class SimpleEditor implements IEditor {
|
|||
}
|
||||
}
|
||||
|
||||
export class SimpleModel extends EventEmitter implements ITextEditorModel {
|
||||
export class SimpleModel implements ITextEditorModel {
|
||||
|
||||
private model:editorCommon.IModel;
|
||||
private _onDispose: Emitter<void>;
|
||||
|
||||
constructor(model:editorCommon.IModel) {
|
||||
super();
|
||||
this.model = model;
|
||||
this._onDispose = new Emitter<void>();
|
||||
}
|
||||
|
||||
public get onDispose(): Event<void> {
|
||||
return this._onDispose.event;
|
||||
}
|
||||
|
||||
public load(): TPromise<SimpleModel> {
|
||||
|
@ -72,6 +76,10 @@ export class SimpleModel extends EventEmitter implements ITextEditorModel {
|
|||
public get textEditorModel():editorCommon.IModel {
|
||||
return this.model;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._onDispose.fire();
|
||||
}
|
||||
}
|
||||
|
||||
export interface IOpenEditorDelegate {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
'use strict';
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import {HistoryNavigator} from 'vs/base/common/history';
|
||||
import {KeyCode, KeyMod, KeyChord} from 'vs/base/common/keyCodes';
|
||||
import {Disposable} from 'vs/base/common/lifecycle';
|
||||
import {ContextKeyExpr, RawContextKey, IContextKey, IContextKeyService} from 'vs/platform/contextkey/common/contextkey';
|
||||
|
@ -16,7 +17,7 @@ import {editorAction, commonEditorContribution, ServicesAccessor, EditorAction,
|
|||
import {FIND_IDS, FindModelBoundToEditorModel} from 'vs/editor/contrib/find/common/findModel';
|
||||
import {FindReplaceState, FindReplaceStateChangedEvent, INewFindReplaceState} from 'vs/editor/contrib/find/common/findState';
|
||||
import {DocumentHighlightProviderRegistry} from 'vs/editor/common/modes';
|
||||
import {RunOnceScheduler} from 'vs/base/common/async';
|
||||
import {RunOnceScheduler, Delayer} from 'vs/base/common/async';
|
||||
|
||||
import EditorContextKeys = editorCommon.EditorContextKeys;
|
||||
|
||||
|
@ -27,10 +28,10 @@ export const enum FindStartFocusAction {
|
|||
}
|
||||
|
||||
export interface IFindStartOptions {
|
||||
forceRevealReplace:boolean;
|
||||
seedSearchStringFromSelection:boolean;
|
||||
shouldFocus:FindStartFocusAction;
|
||||
shouldAnimate:boolean;
|
||||
forceRevealReplace: boolean;
|
||||
seedSearchStringFromSelection: boolean;
|
||||
shouldFocus: FindStartFocusAction;
|
||||
shouldAnimate: boolean;
|
||||
}
|
||||
|
||||
export const CONTEXT_FIND_WIDGET_VISIBLE = new RawContextKey<boolean>('findWidgetVisible', false);
|
||||
|
@ -43,17 +44,21 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
|
|||
private _editor: editorCommon.ICommonCodeEditor;
|
||||
private _findWidgetVisible: IContextKey<boolean>;
|
||||
protected _state: FindReplaceState;
|
||||
private _currentHistoryNavigator: HistoryNavigator<string>;
|
||||
private _updateHistoryDelayer: Delayer<void>;
|
||||
private _model: FindModelBoundToEditorModel;
|
||||
|
||||
public static get(editor:editorCommon.ICommonCodeEditor): CommonFindController {
|
||||
public static get(editor: editorCommon.ICommonCodeEditor): CommonFindController {
|
||||
return editor.getContribution<CommonFindController>(CommonFindController.ID);
|
||||
}
|
||||
|
||||
constructor(editor:editorCommon.ICommonCodeEditor, @IContextKeyService contextKeyService: IContextKeyService) {
|
||||
constructor(editor: editorCommon.ICommonCodeEditor, @IContextKeyService contextKeyService: IContextKeyService) {
|
||||
super();
|
||||
this._editor = editor;
|
||||
this._findWidgetVisible = CONTEXT_FIND_WIDGET_VISIBLE.bindTo(contextKeyService);
|
||||
|
||||
this._updateHistoryDelayer = new Delayer<void>(500);
|
||||
this._currentHistoryNavigator = new HistoryNavigator<string>();
|
||||
this._state = this._register(new FindReplaceState());
|
||||
this._register(this._state.addChangeListener((e) => this._onStateChanged(e)));
|
||||
|
||||
|
@ -95,7 +100,10 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
|
|||
return CommonFindController.ID;
|
||||
}
|
||||
|
||||
private _onStateChanged(e:FindReplaceStateChangedEvent): void {
|
||||
private _onStateChanged(e: FindReplaceStateChangedEvent): void {
|
||||
if (e.updateHistory && e.searchString) {
|
||||
this._delayedUpdateHistory();
|
||||
}
|
||||
if (e.isRevealed) {
|
||||
if (this._state.isRevealed) {
|
||||
this._findWidgetVisible.set(true);
|
||||
|
@ -106,10 +114,24 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
|
|||
}
|
||||
}
|
||||
|
||||
protected _delayedUpdateHistory() {
|
||||
this._updateHistoryDelayer.trigger(this._updateHistory.bind(this));
|
||||
}
|
||||
|
||||
protected _updateHistory() {
|
||||
if (this._state.searchString) {
|
||||
this._currentHistoryNavigator.add(this._state.searchString);
|
||||
}
|
||||
}
|
||||
|
||||
public getState(): FindReplaceState {
|
||||
return this._state;
|
||||
}
|
||||
|
||||
public getHistory(): HistoryNavigator<string> {
|
||||
return this._currentHistoryNavigator;
|
||||
}
|
||||
|
||||
public closeFindWidget(): void {
|
||||
this._state.change({
|
||||
isRevealed: false,
|
||||
|
@ -130,7 +152,7 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
|
|||
this._state.change({ isRegex: !this._state.isRegex }, false);
|
||||
}
|
||||
|
||||
public setSearchString(searchString:string): void {
|
||||
public setSearchString(searchString: string): void {
|
||||
this._state.change({ searchString: searchString }, false);
|
||||
}
|
||||
|
||||
|
@ -151,7 +173,7 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
|
|||
return null;
|
||||
}
|
||||
|
||||
protected _start(opts:IFindStartOptions): void {
|
||||
protected _start(opts: IFindStartOptions): void {
|
||||
this.disposeModel();
|
||||
|
||||
if (!this._editor.getModel()) {
|
||||
|
@ -187,7 +209,7 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
|
|||
}
|
||||
}
|
||||
|
||||
public start(opts:IFindStartOptions): void {
|
||||
public start(opts: IFindStartOptions): void {
|
||||
this._start(opts);
|
||||
}
|
||||
|
||||
|
@ -231,6 +253,22 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public showPreviousFindTerm(): boolean {
|
||||
let previousTerm = this._currentHistoryNavigator.previous();
|
||||
if (previousTerm) {
|
||||
this._state.change({ searchString: previousTerm }, false, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public showNextFindTerm(): boolean {
|
||||
let nextTerm = this._currentHistoryNavigator.next();
|
||||
if (nextTerm) {
|
||||
this._state.change({ searchString: nextTerm }, false, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@editorAction
|
||||
|
@ -239,7 +277,7 @@ export class StartFindAction extends EditorAction {
|
|||
constructor() {
|
||||
super({
|
||||
id: FIND_IDS.StartFindAction,
|
||||
label: nls.localize('startFindAction',"Find"),
|
||||
label: nls.localize('startFindAction', "Find"),
|
||||
alias: 'Find',
|
||||
precondition: null,
|
||||
kbOpts: {
|
||||
|
@ -253,7 +291,7 @@ export class StartFindAction extends EditorAction {
|
|||
});
|
||||
}
|
||||
|
||||
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
|
||||
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
|
||||
let controller = CommonFindController.get(editor);
|
||||
if (controller) {
|
||||
controller.start({
|
||||
|
@ -267,7 +305,7 @@ export class StartFindAction extends EditorAction {
|
|||
}
|
||||
|
||||
export abstract class MatchFindAction extends EditorAction {
|
||||
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
|
||||
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
|
||||
let controller = CommonFindController.get(editor);
|
||||
if (controller && !this._run(controller)) {
|
||||
controller.start({
|
||||
|
@ -280,7 +318,7 @@ export abstract class MatchFindAction extends EditorAction {
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract _run(controller:CommonFindController): boolean;
|
||||
protected abstract _run(controller: CommonFindController): boolean;
|
||||
}
|
||||
|
||||
@editorAction
|
||||
|
@ -300,7 +338,7 @@ export class NextMatchFindAction extends MatchFindAction {
|
|||
});
|
||||
}
|
||||
|
||||
protected _run(controller:CommonFindController): boolean {
|
||||
protected _run(controller: CommonFindController): boolean {
|
||||
return controller.moveToNextMatch();
|
||||
}
|
||||
}
|
||||
|
@ -322,13 +360,13 @@ export class PreviousMatchFindAction extends MatchFindAction {
|
|||
});
|
||||
}
|
||||
|
||||
protected _run(controller:CommonFindController): boolean {
|
||||
protected _run(controller: CommonFindController): boolean {
|
||||
return controller.moveToPrevMatch();
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class SelectionMatchFindAction extends EditorAction {
|
||||
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
|
||||
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
|
||||
let controller = CommonFindController.get(editor);
|
||||
if (!controller) {
|
||||
return;
|
||||
|
@ -348,7 +386,7 @@ export abstract class SelectionMatchFindAction extends EditorAction {
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract _run(controller:CommonFindController): boolean;
|
||||
protected abstract _run(controller: CommonFindController): boolean;
|
||||
}
|
||||
|
||||
@editorAction
|
||||
|
@ -367,7 +405,7 @@ export class NextSelectionMatchFindAction extends SelectionMatchFindAction {
|
|||
});
|
||||
}
|
||||
|
||||
protected _run(controller:CommonFindController): boolean {
|
||||
protected _run(controller: CommonFindController): boolean {
|
||||
return controller.moveToNextMatch();
|
||||
}
|
||||
}
|
||||
|
@ -388,7 +426,7 @@ export class PreviousSelectionMatchFindAction extends SelectionMatchFindAction {
|
|||
});
|
||||
}
|
||||
|
||||
protected _run(controller:CommonFindController): boolean {
|
||||
protected _run(controller: CommonFindController): boolean {
|
||||
return controller.moveToPrevMatch();
|
||||
}
|
||||
}
|
||||
|
@ -410,7 +448,7 @@ export class StartFindReplaceAction extends EditorAction {
|
|||
});
|
||||
}
|
||||
|
||||
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
|
||||
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
|
||||
if (editor.getConfiguration().readOnly) {
|
||||
return;
|
||||
}
|
||||
|
@ -428,14 +466,14 @@ export class StartFindReplaceAction extends EditorAction {
|
|||
}
|
||||
|
||||
export interface IMultiCursorFindResult {
|
||||
searchText:string;
|
||||
matchCase:boolean;
|
||||
wholeWord:boolean;
|
||||
searchText: string;
|
||||
matchCase: boolean;
|
||||
wholeWord: boolean;
|
||||
|
||||
currentMatch: Selection;
|
||||
}
|
||||
|
||||
function multiCursorFind(editor:editorCommon.ICommonCodeEditor, changeFindSearchString:boolean): IMultiCursorFindResult {
|
||||
function multiCursorFind(editor: editorCommon.ICommonCodeEditor, changeFindSearchString: boolean): IMultiCursorFindResult {
|
||||
let controller = CommonFindController.get(editor);
|
||||
if (!controller) {
|
||||
return null;
|
||||
|
@ -489,7 +527,7 @@ function multiCursorFind(editor:editorCommon.ICommonCodeEditor, changeFindSearch
|
|||
}
|
||||
|
||||
export abstract class SelectNextFindMatchAction extends EditorAction {
|
||||
protected _getNextMatch(editor:editorCommon.ICommonCodeEditor): Selection {
|
||||
protected _getNextMatch(editor: editorCommon.ICommonCodeEditor): Selection {
|
||||
let r = multiCursorFind(editor, true);
|
||||
if (!r) {
|
||||
return null;
|
||||
|
@ -512,7 +550,7 @@ export abstract class SelectNextFindMatchAction extends EditorAction {
|
|||
}
|
||||
|
||||
export abstract class SelectPreviousFindMatchAction extends EditorAction {
|
||||
protected _getPreviousMatch(editor:editorCommon.ICommonCodeEditor): Selection {
|
||||
protected _getPreviousMatch(editor: editorCommon.ICommonCodeEditor): Selection {
|
||||
let r = multiCursorFind(editor, true);
|
||||
if (!r) {
|
||||
return null;
|
||||
|
@ -550,7 +588,7 @@ export class AddSelectionToNextFindMatchAction extends SelectNextFindMatchAction
|
|||
});
|
||||
}
|
||||
|
||||
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
|
||||
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
|
||||
let nextMatch = this._getNextMatch(editor);
|
||||
|
||||
if (!nextMatch) {
|
||||
|
@ -575,7 +613,7 @@ export class AddSelectionToPreviousFindMatchAction extends SelectPreviousFindMat
|
|||
});
|
||||
}
|
||||
|
||||
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
|
||||
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
|
||||
let previousMatch = this._getPreviousMatch(editor);
|
||||
|
||||
if (!previousMatch) {
|
||||
|
@ -604,7 +642,7 @@ export class MoveSelectionToNextFindMatchAction extends SelectNextFindMatchActio
|
|||
});
|
||||
}
|
||||
|
||||
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
|
||||
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
|
||||
let nextMatch = this._getNextMatch(editor);
|
||||
|
||||
if (!nextMatch) {
|
||||
|
@ -629,7 +667,7 @@ export class MoveSelectionToPreviousFindMatchAction extends SelectPreviousFindMa
|
|||
});
|
||||
}
|
||||
|
||||
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
|
||||
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
|
||||
let previousMatch = this._getPreviousMatch(editor);
|
||||
|
||||
if (!previousMatch) {
|
||||
|
@ -643,7 +681,7 @@ export class MoveSelectionToPreviousFindMatchAction extends SelectPreviousFindMa
|
|||
}
|
||||
|
||||
export abstract class AbstractSelectHighlightsAction extends EditorAction {
|
||||
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
|
||||
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
|
||||
let r = multiCursorFind(editor, true);
|
||||
if (!r) {
|
||||
return;
|
||||
|
@ -713,7 +751,7 @@ export class SelectionHighlighter extends Disposable implements editorCommon.IEd
|
|||
private updateSoon: RunOnceScheduler;
|
||||
private lastWordUnderCursor: Range;
|
||||
|
||||
constructor(editor:editorCommon.ICommonCodeEditor) {
|
||||
constructor(editor: editorCommon.ICommonCodeEditor) {
|
||||
super();
|
||||
this.editor = editor;
|
||||
this.decorations = [];
|
||||
|
@ -812,7 +850,7 @@ export class SelectionHighlighter extends Disposable implements editorCommon.IEd
|
|||
|
||||
// do not overlap with selection (issue #64 and #512)
|
||||
let matches: Range[] = [];
|
||||
for (let i = 0, j = 0, len = allMatches.length, lenJ = selections.length; i < len; ) {
|
||||
for (let i = 0, j = 0, len = allMatches.length, lenJ = selections.length; i < len;) {
|
||||
let match = allMatches[i];
|
||||
|
||||
if (j >= lenJ) {
|
||||
|
@ -943,3 +981,25 @@ CommonEditorRegistry.registerEditorCommand(new FindCommand({
|
|||
primary: KeyMod.Alt | KeyCode.Enter
|
||||
}
|
||||
}));
|
||||
|
||||
CommonEditorRegistry.registerEditorCommand(new FindCommand({
|
||||
id: FIND_IDS.ShowPreviousFindTermAction,
|
||||
precondition: CONTEXT_FIND_WIDGET_VISIBLE,
|
||||
handler: x => x.showPreviousFindTerm(),
|
||||
kbOpts: {
|
||||
weight: CommonEditorRegistry.commandWeight(5),
|
||||
kbExpr: EditorContextKeys.Focus,
|
||||
primary: KeyMod.Alt | KeyCode.UpArrow
|
||||
}
|
||||
}));
|
||||
|
||||
CommonEditorRegistry.registerEditorCommand(new FindCommand({
|
||||
id: FIND_IDS.ShowNextFindTermAction,
|
||||
precondition: CONTEXT_FIND_WIDGET_VISIBLE,
|
||||
handler: x => x.showNextFindTerm(),
|
||||
kbOpts: {
|
||||
weight: CommonEditorRegistry.commandWeight(5),
|
||||
kbExpr: EditorContextKeys.Focus,
|
||||
primary: KeyMod.Alt | KeyCode.DownArrow
|
||||
}
|
||||
}));
|
||||
|
|
|
@ -34,7 +34,9 @@ export const FIND_IDS = {
|
|||
ToggleRegexCommand: 'toggleFindRegex',
|
||||
ReplaceOneAction: 'editor.action.replaceOne',
|
||||
ReplaceAllAction: 'editor.action.replaceAll',
|
||||
SelectAllMatchesAction: 'editor.action.selectAllMatches'
|
||||
SelectAllMatchesAction: 'editor.action.selectAllMatches',
|
||||
ShowPreviousFindTermAction: 'find.history.showPrevious',
|
||||
ShowNextFindTermAction: 'find.history.showNext'
|
||||
};
|
||||
|
||||
export const MATCHES_LIMIT = 999;
|
||||
|
|
|
@ -10,6 +10,7 @@ import {Range} from 'vs/editor/common/core/range';
|
|||
|
||||
export interface FindReplaceStateChangedEvent {
|
||||
moveCursor: boolean;
|
||||
updateHistory: boolean;
|
||||
|
||||
searchString: boolean;
|
||||
replaceString: boolean;
|
||||
|
@ -90,6 +91,7 @@ export class FindReplaceState implements IDisposable {
|
|||
public changeMatchInfo(matchesPosition:number, matchesCount:number, currentMatch:Range): void {
|
||||
let changeEvent:FindReplaceStateChangedEvent = {
|
||||
moveCursor: false,
|
||||
updateHistory: false,
|
||||
searchString: false,
|
||||
replaceString: false,
|
||||
isRevealed: false,
|
||||
|
@ -135,9 +137,10 @@ export class FindReplaceState implements IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
public change(newState:INewFindReplaceState, moveCursor:boolean): void {
|
||||
public change(newState:INewFindReplaceState, moveCursor:boolean, updateHistory: boolean = true): void {
|
||||
let changeEvent:FindReplaceStateChangedEvent = {
|
||||
moveCursor: moveCursor,
|
||||
updateHistory: updateHistory,
|
||||
searchString: false,
|
||||
replaceString: false,
|
||||
isRevealed: false,
|
||||
|
|
|
@ -15,10 +15,12 @@ import {
|
|||
NextMatchFindAction, StartFindAction, SelectHighlightsAction
|
||||
} from 'vs/editor/contrib/find/common/findController';
|
||||
import {withMockCodeEditor} from 'vs/editor/test/common/mocks/mockCodeEditor';
|
||||
import {HistoryNavigator} from 'vs/base/common/history';
|
||||
|
||||
class TestFindController extends CommonFindController {
|
||||
|
||||
public hasFocus: boolean;
|
||||
public delayUpdateHistory: boolean = false;
|
||||
|
||||
protected _start(opts:IFindStartOptions): void {
|
||||
super._start(opts);
|
||||
|
@ -27,6 +29,14 @@ class TestFindController extends CommonFindController {
|
|||
this.hasFocus = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected _delayedUpdateHistory() {
|
||||
if (this.delayUpdateHistory) {
|
||||
super._delayedUpdateHistory();
|
||||
} else {
|
||||
this._updateHistory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suite('FindController', () => {
|
||||
|
@ -196,4 +206,125 @@ suite('FindController', () => {
|
|||
assert.equal(findController.getState().searchScope, null);
|
||||
});
|
||||
});
|
||||
|
||||
test('find term is added to history on state change', () => {
|
||||
withMockCodeEditor([
|
||||
'var x = (3 * 5)',
|
||||
'var y = (3 * 5)',
|
||||
'var z = (3 * 5)',
|
||||
], {}, (editor, cursor) => {
|
||||
|
||||
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
|
||||
findController.getState().change({ searchString: '1' }, false);
|
||||
findController.getState().change({ searchString: '2' }, false);
|
||||
findController.getState().change({ searchString: '3' }, false);
|
||||
|
||||
assert.deepEqual(['1', '2', '3'], toArray(findController.getHistory()));
|
||||
});
|
||||
});
|
||||
|
||||
test('find term is added with delay', (done) => {
|
||||
withMockCodeEditor([
|
||||
'var x = (3 * 5)',
|
||||
'var y = (3 * 5)',
|
||||
'var z = (3 * 5)',
|
||||
], {}, (editor, cursor) => {
|
||||
|
||||
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
|
||||
findController.delayUpdateHistory = true;
|
||||
findController.getState().change({ searchString: '1' }, false);
|
||||
findController.getState().change({ searchString: '2' }, false);
|
||||
findController.getState().change({ searchString: '3' }, false);
|
||||
|
||||
setTimeout(function() {
|
||||
assert.deepEqual(['3'], toArray(findController.getHistory()));
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
});
|
||||
|
||||
test('show previous find term', () => {
|
||||
withMockCodeEditor([
|
||||
'var x = (3 * 5)',
|
||||
'var y = (3 * 5)',
|
||||
'var z = (3 * 5)',
|
||||
], {}, (editor, cursor) => {
|
||||
|
||||
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
|
||||
findController.getState().change({ searchString: '1' }, false);
|
||||
findController.getState().change({ searchString: '2' }, false);
|
||||
findController.getState().change({ searchString: '3' }, false);
|
||||
|
||||
findController.showPreviousFindTerm();
|
||||
assert.deepEqual('2', findController.getState().searchString);
|
||||
});
|
||||
});
|
||||
|
||||
test('show previous find term do not update history', () => {
|
||||
withMockCodeEditor([
|
||||
'var x = (3 * 5)',
|
||||
'var y = (3 * 5)',
|
||||
'var z = (3 * 5)',
|
||||
], {}, (editor, cursor) => {
|
||||
|
||||
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
|
||||
findController.getState().change({ searchString: '1' }, false);
|
||||
findController.getState().change({ searchString: '2' }, false);
|
||||
findController.getState().change({ searchString: '3' }, false);
|
||||
|
||||
findController.showPreviousFindTerm();
|
||||
assert.deepEqual(['1', '2', '3'], toArray(findController.getHistory()));
|
||||
});
|
||||
});
|
||||
|
||||
test('show next find term', () => {
|
||||
withMockCodeEditor([
|
||||
'var x = (3 * 5)',
|
||||
'var y = (3 * 5)',
|
||||
'var z = (3 * 5)',
|
||||
], {}, (editor, cursor) => {
|
||||
|
||||
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
|
||||
findController.getState().change({ searchString: '1' }, false);
|
||||
findController.getState().change({ searchString: '2' }, false);
|
||||
findController.getState().change({ searchString: '3' }, false);
|
||||
findController.getState().change({ searchString: '4' }, false);
|
||||
|
||||
findController.showPreviousFindTerm();
|
||||
findController.showPreviousFindTerm();
|
||||
findController.showNextFindTerm();
|
||||
assert.deepEqual('3', findController.getState().searchString);
|
||||
});
|
||||
});
|
||||
|
||||
test('show next find term do not update history', () => {
|
||||
withMockCodeEditor([
|
||||
'var x = (3 * 5)',
|
||||
'var y = (3 * 5)',
|
||||
'var z = (3 * 5)',
|
||||
], {}, (editor, cursor) => {
|
||||
|
||||
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
|
||||
findController.getState().change({ searchString: '1' }, false);
|
||||
findController.getState().change({ searchString: '2' }, false);
|
||||
findController.getState().change({ searchString: '3' }, false);
|
||||
findController.getState().change({ searchString: '4' }, false);
|
||||
|
||||
findController.showPreviousFindTerm();
|
||||
findController.showPreviousFindTerm();
|
||||
findController.showNextFindTerm();
|
||||
assert.deepEqual(['1', '2', '3', '4'], toArray(findController.getHistory()));
|
||||
});
|
||||
});
|
||||
|
||||
function toArray(historyNavigator: HistoryNavigator<string>): string[] {
|
||||
let result = [];
|
||||
historyNavigator.first();
|
||||
if (historyNavigator.current()) {
|
||||
do {
|
||||
result.push(historyNavigator.current());
|
||||
} while (historyNavigator.next());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -28,6 +28,8 @@ export interface IEditorService {
|
|||
|
||||
export interface IEditorModel {
|
||||
|
||||
onDispose: Event<void>;
|
||||
|
||||
/**
|
||||
* Loads the model.
|
||||
*/
|
||||
|
|
|
@ -9,7 +9,7 @@ import URI from 'vs/base/common/uri';
|
|||
import {isUnspecific, guessMimeTypes, MIME_TEXT, suggestFilename} from 'vs/base/common/mime';
|
||||
import labels = require('vs/base/common/labels');
|
||||
import paths = require('vs/base/common/paths');
|
||||
import {UntitledEditorInput as AbstractUntitledEditorInput, EditorModel, EncodingMode, ConfirmResult} from 'vs/workbench/common/editor';
|
||||
import {UntitledEditorInput as AbstractUntitledEditorInput, EncodingMode, ConfirmResult} from 'vs/workbench/common/editor';
|
||||
import {UntitledEditorModel} from 'vs/workbench/common/editor/untitledEditorModel';
|
||||
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
|
||||
import {ILifecycleService} from 'vs/platform/lifecycle/common/lifecycle';
|
||||
|
@ -131,7 +131,7 @@ export class UntitledEditorInput extends AbstractUntitledEditorInput {
|
|||
}
|
||||
}
|
||||
|
||||
public resolve(refresh?: boolean): TPromise<EditorModel> {
|
||||
public resolve(refresh?: boolean): TPromise<UntitledEditorModel> {
|
||||
|
||||
// Use Cached Model
|
||||
if (this.cachedModel) {
|
||||
|
|
|
@ -14,7 +14,7 @@ import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/ex
|
|||
import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actionRegistry';
|
||||
import { ExtensionTipsService } from 'vs/workbench/parts/extensions/electron-browser/extensionTipsService';
|
||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||
import { ExtensionsWorkbenchExtension, StatusUpdater } from 'vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension';
|
||||
import { ExtensionsWorkbenchExtension } from 'vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension';
|
||||
import { IOutputChannelRegistry, Extensions as OutputExtensions } from 'vs/workbench/parts/output/common/output';
|
||||
import { EditorDescriptor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/common/editor';
|
||||
|
@ -25,6 +25,7 @@ import { OpenExtensionsViewletAction, InstallExtensionsAction, ShowOutdatedExten
|
|||
import { ExtensionsInput } from './extensionsInput';
|
||||
import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||
import { ExtensionEditor } from './extensionEditor';
|
||||
import { StatusUpdater } from './extensionsViewlet';
|
||||
import { IQuickOpenRegistry, Extensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import { localize } from 'vs/nls';
|
|||
import { ThrottledDelayer, always } from 'vs/base/common/async';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { isPromiseCanceledError, onUnexpectedError, create as createError } from 'vs/base/common/errors';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { Builder, Dimension } from 'vs/base/browser/builder';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
|
@ -28,7 +29,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
|||
import { PagedList } from 'vs/base/browser/ui/list/listPaging';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Delegate, Renderer } from './extensionsList';
|
||||
import { IExtensionsWorkbenchService, IExtension, IExtensionsViewlet, VIEWLET_ID } from './extensions';
|
||||
import { IExtensionsWorkbenchService, IExtension, IExtensionsViewlet, VIEWLET_ID, ExtensionState } from './extensions';
|
||||
import { ShowRecommendedExtensionsAction, ShowPopularExtensionsAction, ShowInstalledExtensionsAction, ShowOutdatedExtensionsAction, ClearExtensionsInputAction, ChangeSortAction, UpdateAllAction } from './extensionsActions';
|
||||
import { IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService, SortBy, SortOrder, IQueryOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionsInput } from './extensionsInput';
|
||||
|
@ -41,6 +42,7 @@ import { IMessageService, CloseAction } from 'vs/platform/message/common/message
|
|||
import Severity from 'vs/base/common/severity';
|
||||
import { IURLService } from 'vs/platform/url/common/url';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IActivityService, ProgressBadge, NumberBadge } from 'vs/workbench/services/activity/common/activityService';
|
||||
|
||||
interface SearchInputEvent extends Event {
|
||||
target: HTMLInputElement;
|
||||
|
@ -358,3 +360,39 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet {
|
|||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export class StatusUpdater implements IWorkbenchContribution {
|
||||
|
||||
private disposables: IDisposable[];
|
||||
|
||||
constructor(
|
||||
@IActivityService private activityService: IActivityService,
|
||||
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
|
||||
) {
|
||||
extensionsWorkbenchService.onChange(this.onServiceChange, this, this.disposables);
|
||||
}
|
||||
|
||||
getId(): string {
|
||||
return 'vs.extensions.statusupdater';
|
||||
}
|
||||
|
||||
private onServiceChange(): void {
|
||||
if (this.extensionsWorkbenchService.local.some(e => e.state === ExtensionState.Installing)) {
|
||||
this.activityService.showActivity(VIEWLET_ID, new ProgressBadge(() => localize('extensions', 'Extensions')), 'extensions-badge progress-badge');
|
||||
return;
|
||||
}
|
||||
|
||||
const outdated = this.extensionsWorkbenchService.local.reduce((r, e) => r + (e.outdated ? 1 : 0), 0);
|
||||
|
||||
if (outdated > 0) {
|
||||
const badge = new NumberBadge(outdated, n => localize('outdatedExtensions', '{0} Outdated Extensions', n));
|
||||
this.activityService.showActivity(VIEWLET_ID, badge, 'extensions-badge count-badge');
|
||||
} else {
|
||||
this.activityService.showActivity(VIEWLET_ID, null, 'extensions-badge');
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.disposables = dispose(this.disposables);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,16 +6,13 @@
|
|||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { localize } from 'vs/nls';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IMessageService } from 'vs/platform/message/common/message';
|
||||
import { IExtensionsWorkbenchService, ExtensionState, VIEWLET_ID } from './extensions';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { LegacyWorkspaceContextService } from 'vs/workbench/services/workspace/common/contextService';
|
||||
import { IActivityService, ProgressBadge, NumberBadge } from 'vs/workbench/services/activity/common/activityService';
|
||||
import { ReloadWindowAction } from 'vs/workbench/electron-browser/actions';
|
||||
import { ipcRenderer as ipc } from 'electron';
|
||||
|
||||
|
@ -70,40 +67,4 @@ export class ExtensionsWorkbenchExtension implements IWorkbenchContribution {
|
|||
public getId(): string {
|
||||
return 'vs.extensions.workbenchextension';
|
||||
}
|
||||
}
|
||||
|
||||
export class StatusUpdater implements IWorkbenchContribution {
|
||||
|
||||
private disposables: IDisposable[];
|
||||
|
||||
constructor(
|
||||
@IActivityService private activityService: IActivityService,
|
||||
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
|
||||
) {
|
||||
extensionsWorkbenchService.onChange(this.onServiceChange, this, this.disposables);
|
||||
}
|
||||
|
||||
getId(): string {
|
||||
return 'vs.extensions.statusupdater';
|
||||
}
|
||||
|
||||
private onServiceChange(): void {
|
||||
if (this.extensionsWorkbenchService.local.some(e => e.state === ExtensionState.Installing)) {
|
||||
this.activityService.showActivity(VIEWLET_ID, new ProgressBadge(() => localize('extensions', 'Extensions')), 'extensions-badge progress-badge');
|
||||
return;
|
||||
}
|
||||
|
||||
const outdated = this.extensionsWorkbenchService.local.reduce((r, e) => r + (e.outdated ? 1 : 0), 0);
|
||||
|
||||
if (outdated > 0) {
|
||||
const badge = new NumberBadge(outdated, n => localize('outdatedExtensions', '{0} Outdated Extensions', n));
|
||||
this.activityService.showActivity(VIEWLET_ID, badge, 'extensions-badge count-badge');
|
||||
} else {
|
||||
this.activityService.showActivity(VIEWLET_ID, null, 'extensions-badge');
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.disposables = dispose(this.disposables);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -467,7 +467,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
|
|||
|
||||
const message = err && err.message || '';
|
||||
|
||||
if (/getaddrinfo ENOTFOUND|getaddrinfo ENOENT|connect EACCES/.test(message)) {
|
||||
if (/getaddrinfo ENOTFOUND|getaddrinfo ENOENT|connect EACCES|connect ECONNREFUSED/.test(message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,9 @@ import {IEditorViewState} from 'vs/editor/common/editorCommon';
|
|||
import {Action} from 'vs/base/common/actions';
|
||||
import {Scope} from 'vs/workbench/common/memento';
|
||||
import {IEditorOptions} from 'vs/editor/common/editorCommon';
|
||||
import {VIEWLET_ID, TEXT_FILE_EDITOR_ID} from 'vs/workbench/parts/files/common/files';
|
||||
import {VIEWLET_ID, TEXT_FILE_EDITOR_ID, ITextFileEditorModel} from 'vs/workbench/parts/files/common/files';
|
||||
import {BaseTextEditor} from 'vs/workbench/browser/parts/editor/textEditor';
|
||||
import {EditorOptions, TextEditorOptions, EditorModel} from 'vs/workbench/common/editor';
|
||||
import {TextFileEditorModel} from 'vs/workbench/parts/files/common/editors/textFileEditorModel';
|
||||
import {EditorOptions, TextEditorOptions} from 'vs/workbench/common/editor';
|
||||
import {BinaryEditorModel} from 'vs/workbench/common/editor/binaryEditorModel';
|
||||
import {FileEditorInput} from 'vs/workbench/parts/files/common/editors/fileEditorInput';
|
||||
import {ExplorerViewlet} from 'vs/workbench/parts/files/browser/explorerViewlet';
|
||||
|
@ -117,7 +116,7 @@ export class TextFileEditor extends BaseTextEditor {
|
|||
}
|
||||
|
||||
// Different Input (Reload)
|
||||
return this.editorService.resolveEditorModel(input, true /* Reload */).then((resolvedModel: EditorModel) => {
|
||||
return this.editorService.resolveEditorModel(input, true /* Reload */).then(resolvedModel => {
|
||||
|
||||
// There is a special case where the text editor has to handle binary file editor input: if a file with application/unknown
|
||||
// mime has been resolved and cached before, it maybe an actual instance of BinaryEditorModel. In this case our text
|
||||
|
@ -126,13 +125,8 @@ export class TextFileEditor extends BaseTextEditor {
|
|||
return this.openAsBinary(input, options);
|
||||
}
|
||||
|
||||
// Assert Model interface
|
||||
if (!(resolvedModel instanceof TextFileEditorModel)) {
|
||||
return TPromise.wrapError<void>('Invalid editor input. Text file editor requires a model instance of TextFileEditorModel.');
|
||||
}
|
||||
|
||||
// Check Model state
|
||||
const textFileModel = <TextFileEditorModel>resolvedModel;
|
||||
const textFileModel = <ITextFileEditorModel>resolvedModel;
|
||||
|
||||
const hasInput = !!this.getInput();
|
||||
const modelDisposed = textFileModel.isDisposed();
|
||||
|
|
|
@ -32,8 +32,8 @@ export class TextFileEditorModelManager implements ITextFileEditorModelManager {
|
|||
|
||||
private mapResourceToDisposeListener: { [resource: string]: IDisposable; };
|
||||
private mapResourceToStateChangeListener: { [resource: string]: IDisposable; };
|
||||
private mapResourceToModel: { [resource: string]: TextFileEditorModel; };
|
||||
private mapResourceToPendingModelLoaders: { [resource: string]: TPromise<TextFileEditorModel> };
|
||||
private mapResourceToModel: { [resource: string]: ITextFileEditorModel; };
|
||||
private mapResourceToPendingModelLoaders: { [resource: string]: TPromise<ITextFileEditorModel> };
|
||||
|
||||
constructor(
|
||||
@ILifecycleService private lifecycleService: ILifecycleService,
|
||||
|
@ -162,11 +162,11 @@ export class TextFileEditorModelManager implements ITextFileEditorModelManager {
|
|||
return this._onModelEncodingChanged.event;
|
||||
}
|
||||
|
||||
public get(resource: URI): TextFileEditorModel {
|
||||
public get(resource: URI): ITextFileEditorModel {
|
||||
return this.mapResourceToModel[resource.toString()];
|
||||
}
|
||||
|
||||
public loadOrCreate(resource: URI, encoding: string, refresh?: boolean): TPromise<TextFileEditorModel> {
|
||||
public loadOrCreate(resource: URI, encoding: string, refresh?: boolean): TPromise<ITextFileEditorModel> {
|
||||
|
||||
// Return early if model is currently being loaded
|
||||
const pendingLoad = this.mapResourceToPendingModelLoaders[resource.toString()];
|
||||
|
@ -174,7 +174,7 @@ export class TextFileEditorModelManager implements ITextFileEditorModelManager {
|
|||
return pendingLoad;
|
||||
}
|
||||
|
||||
let modelPromise: TPromise<TextFileEditorModel>;
|
||||
let modelPromise: TPromise<ITextFileEditorModel>;
|
||||
|
||||
// Model exists
|
||||
let model = this.get(resource);
|
||||
|
@ -238,13 +238,13 @@ export class TextFileEditorModelManager implements ITextFileEditorModelManager {
|
|||
});
|
||||
}
|
||||
|
||||
public getAll(resource?: URI): TextFileEditorModel[] {
|
||||
public getAll(resource?: URI): ITextFileEditorModel[] {
|
||||
return Object.keys(this.mapResourceToModel)
|
||||
.filter(r => !resource || resource.toString() === r)
|
||||
.map(r => this.mapResourceToModel[r]);
|
||||
}
|
||||
|
||||
public add(resource: URI, model: TextFileEditorModel): void {
|
||||
public add(resource: URI, model: ITextFileEditorModel): void {
|
||||
const knownModel = this.mapResourceToModel[resource.toString()];
|
||||
if (knownModel === model) {
|
||||
return; // already cached
|
||||
|
|
|
@ -274,6 +274,8 @@ export interface ITextFileEditorModelManager {
|
|||
|
||||
export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport {
|
||||
|
||||
onDidStateChange: Event<StateChange>;
|
||||
|
||||
getResource(): URI;
|
||||
|
||||
getLastSaveAttemptTime(): number;
|
||||
|
@ -282,6 +284,8 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport
|
|||
|
||||
getState(): ModelState;
|
||||
|
||||
updatePreferredEncoding(encoding: string): void;
|
||||
|
||||
save(overwriteReadonly?: boolean, overwriteEncoding?: boolean): TPromise<void>;
|
||||
|
||||
revert(): TPromise<void>;
|
||||
|
|
|
@ -9,8 +9,7 @@ import URI from 'vs/base/common/uri';
|
|||
import paths = require('vs/base/common/paths');
|
||||
import errors = require('vs/base/common/errors');
|
||||
import Event, {Emitter} from 'vs/base/common/event';
|
||||
import {TextFileEditorModel} from 'vs/workbench/parts/files/common/editors/textFileEditorModel';
|
||||
import {IResult, ITextFileOperationResult, ITextFileService, IRawTextContent, IAutoSaveConfiguration, AutoSaveMode, ITextFileEditorModelManager} from 'vs/workbench/parts/files/common/files';
|
||||
import {IResult, ITextFileOperationResult, ITextFileService, IRawTextContent, IAutoSaveConfiguration, AutoSaveMode, ITextFileEditorModelManager, ITextFileEditorModel} from 'vs/workbench/parts/files/common/files';
|
||||
import {ConfirmResult} from 'vs/workbench/common/editor';
|
||||
import {ILifecycleService} from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
|
||||
|
@ -329,11 +328,11 @@ export abstract class TextFileService implements ITextFileService {
|
|||
});
|
||||
}
|
||||
|
||||
private getFileModels(resources?: URI[]): TextFileEditorModel[];
|
||||
private getFileModels(resource?: URI): TextFileEditorModel[];
|
||||
private getFileModels(arg1?: any): TextFileEditorModel[] {
|
||||
private getFileModels(resources?: URI[]): ITextFileEditorModel[];
|
||||
private getFileModels(resource?: URI): ITextFileEditorModel[];
|
||||
private getFileModels(arg1?: any): ITextFileEditorModel[] {
|
||||
if (Array.isArray(arg1)) {
|
||||
const models: TextFileEditorModel[] = [];
|
||||
const models: ITextFileEditorModel[] = [];
|
||||
(<URI[]>arg1).forEach(resource => {
|
||||
models.push(...this.getFileModels(resource));
|
||||
});
|
||||
|
@ -344,9 +343,9 @@ export abstract class TextFileService implements ITextFileService {
|
|||
return this._models.getAll(<URI>arg1);
|
||||
}
|
||||
|
||||
private getDirtyFileModels(resources?: URI[]): TextFileEditorModel[];
|
||||
private getDirtyFileModels(resource?: URI): TextFileEditorModel[];
|
||||
private getDirtyFileModels(arg1?: any): TextFileEditorModel[] {
|
||||
private getDirtyFileModels(resources?: URI[]): ITextFileEditorModel[];
|
||||
private getDirtyFileModels(resource?: URI): ITextFileEditorModel[];
|
||||
private getDirtyFileModels(arg1?: any): ITextFileEditorModel[] {
|
||||
return this.getFileModels(arg1).filter(model => model.isDirty());
|
||||
}
|
||||
|
||||
|
@ -381,7 +380,7 @@ export abstract class TextFileService implements ITextFileService {
|
|||
private doSaveAs(resource: URI, target?: URI): TPromise<URI> {
|
||||
|
||||
// Retrieve text model from provided resource if any
|
||||
let modelPromise: TPromise<TextFileEditorModel | UntitledEditorModel> = TPromise.as(null);
|
||||
let modelPromise: TPromise<ITextFileEditorModel | UntitledEditorModel> = TPromise.as(null);
|
||||
if (resource.scheme === 'file') {
|
||||
modelPromise = TPromise.as(this._models.get(resource));
|
||||
} else if (resource.scheme === 'untitled') {
|
||||
|
@ -411,11 +410,11 @@ export abstract class TextFileService implements ITextFileService {
|
|||
});
|
||||
}
|
||||
|
||||
private doSaveTextFileAs(sourceModel: TextFileEditorModel | UntitledEditorModel, resource: URI, target: URI): TPromise<void> {
|
||||
private doSaveTextFileAs(sourceModel: ITextFileEditorModel | UntitledEditorModel, resource: URI, target: URI): TPromise<void> {
|
||||
// create the target file empty if it does not exist already
|
||||
return this.fileService.resolveFile(target).then(stat => stat, () => null).then(stat => stat || this.fileService.createFile(target)).then(stat => {
|
||||
// resolve a model for the file (which can be binary if the file is not a text file)
|
||||
return this.editorService.resolveEditorModel({ resource: target }).then((targetModel: TextFileEditorModel) => {
|
||||
return this.editorService.resolveEditorModel({ resource: target }).then((targetModel: ITextFileEditorModel) => {
|
||||
// binary model: delete the file and run the operation again
|
||||
if (targetModel instanceof BinaryEditorModel) {
|
||||
return this.fileService.del(target).then(() => this.doSaveTextFileAs(sourceModel, resource, target));
|
||||
|
|
|
@ -41,7 +41,7 @@ export function appendKeyBindingLabel(label: string, keyBinding: any, keyBinding
|
|||
|
||||
export class ShowNextSearchTermAction extends Action {
|
||||
|
||||
public static ID = 'search.history.nextSearchTerm';
|
||||
public static ID = 'search.history.showNext';
|
||||
public static LABEL = nls.localize('nextSearchTerm', "Show next search term");
|
||||
|
||||
constructor(id: string, label: string, @IViewletService private viewletService: IViewletService) {
|
||||
|
@ -57,7 +57,7 @@ export class ShowNextSearchTermAction extends Action {
|
|||
|
||||
export class ShowPreviousSearchTermAction extends Action {
|
||||
|
||||
public static ID = 'search.history.previousSearchTerm';
|
||||
public static ID = 'search.history.showPrevious';
|
||||
public static LABEL = nls.localize('previousSearchTerm', "Show previous search term");
|
||||
|
||||
constructor(id: string, label: string, @IViewletService private viewletService: IViewletService) {
|
||||
|
|
|
@ -508,15 +508,19 @@ function _processIconThemeDocument(id: string, iconThemeDocumentPath: string, ic
|
|||
let fileExtensions = associations.fileExtensions;
|
||||
if (fileExtensions) {
|
||||
for (let fileExtension in fileExtensions) {
|
||||
addSelector(`${qualifier} .${escapeCSS(fileExtension.toLowerCase())}-ext-file-icon.file-icon::before`, fileExtensions[fileExtension]);
|
||||
let selectors = [];
|
||||
let segments = fileExtension.toLowerCase().split('.');
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
selectors.push(`.${escapeCSS(segments.slice(i).join('.'))}-ext-file-icon`);
|
||||
}
|
||||
addSelector(`${qualifier} ${selectors.join('')}.file-icon::before`, fileExtensions[fileExtension]);
|
||||
}
|
||||
}
|
||||
let fileNames = associations.fileNames;
|
||||
if (fileNames) {
|
||||
for (let fileName in fileNames) {
|
||||
fileName = fileName.toLowerCase();
|
||||
let selectors = [];
|
||||
let segments = fileName.split('.');
|
||||
let segments = fileName.toLowerCase().split('.');
|
||||
if (segments[0]) {
|
||||
selectors.push(`.${escapeCSS(segments[0])}-name-file-icon`);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue