This commit is contained in:
Alexandru Dima 2016-09-13 16:43:15 +02:00
commit 47bc908e39
25 changed files with 457 additions and 203 deletions

View file

@ -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 + '/'
}));
});

View file

@ -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,

View file

@ -1,7 +1,7 @@
{
"comments": {
"lineComment": "//",
"blockComment": [ "/*", "*/" ]
"lineComment": "#",
"blockComment": [ "#", " " ]
},
"brackets": [
["{", "}"],

View file

@ -1,7 +1,7 @@
{
"comments": {
"lineComment": "//",
"blockComment": [ "/*", "*/" ]
"lineComment": "#",
"blockComment": [ "#", " " ]
},
"brackets": [
["{", "}"],

View file

@ -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"
}]

View file

@ -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);
}

View file

@ -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",

View file

@ -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;

View file

@ -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 {

View file

@ -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
}
}));

View file

@ -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;

View file

@ -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,

View file

@ -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;
}
});

View file

@ -28,6 +28,8 @@ export interface IEditorService {
export interface IEditorModel {
onDispose: Event<void>;
/**
* Loads the model.
*/

View file

@ -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) {

View file

@ -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';

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}

View file

@ -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();

View file

@ -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

View file

@ -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>;

View file

@ -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));

View file

@ -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) {

View file

@ -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`);
}