提交 89dd0455 编写于 作者: R Ramya Rao 提交者: GitHub

Fixes #11478 trigger tab when emmet expansion is the same (#24923)

* Fixes #11478 trigger tab when emmet expansion is the same

* Add test case and telemetry
上级 9da58ec1
......@@ -30,7 +30,8 @@ class EncodeDecodeDataUrlAction extends EmmetEditorAction {
id: 'editor.emmet.action.encodeDecodeDataUrl',
label: nls.localize('encodeDecodeDataUrl', "Emmet: Encode\\Decode data:URL image"),
alias: 'Emmet: Encode\\Decode data:URL image',
precondition: EditorContextKeys.Writable
precondition: EditorContextKeys.Writable,
actionName: 'encode_decode_data_url'
});
}
......
......@@ -20,7 +20,8 @@ class UpdateTagAction extends EmmetEditorAction {
id: 'editor.emmet.action.updateTag',
label: nls.localize('updateTag', "Emmet: Update Tag"),
alias: 'Emmet: Update Tag',
precondition: EditorContextKeys.Writable
precondition: EditorContextKeys.Writable,
actionName: 'update_tag'
});
}
......
......@@ -20,7 +20,8 @@ class WrapWithAbbreviationAction extends EmmetEditorAction {
id: 'editor.emmet.action.wrapWithAbbreviation',
label: nls.localize('wrapWithAbbreviationAction', "Emmet: Wrap with Abbreviation"),
alias: 'Emmet: Wrap with Abbreviation',
precondition: EditorContextKeys.Writable
precondition: EditorContextKeys.Writable,
actionName: 'wrap_with_abbreviation'
});
}
......
......@@ -5,7 +5,7 @@
'use strict';
import { ICommonCodeEditor } from 'vs/editor/common/editorCommon';
import { ICommonCodeEditor, Handler } from 'vs/editor/common/editorCommon';
import strings = require('vs/base/common/strings');
import snippets = require('vs/editor/contrib/snippet/common/snippet');
import { Range } from 'vs/editor/common/core/range';
......@@ -30,18 +30,19 @@ export class EditorAccessor implements emmet.Editor {
private _syntaxProfiles: any;
private _excludedLanguages: any;
private _grammars: IGrammarContributions;
private _emmetActionName: string;
private _hasMadeEdits: boolean;
private emmetSupportedModes = ['html', 'css', 'xml', 'xsl', 'haml', 'jade', 'jsx', 'slim', 'scss', 'sass', 'less', 'stylus', 'styl', 'svg'];
constructor(languageIdentifierResolver: ILanguageIdentifierResolver, editor: ICommonCodeEditor, syntaxProfiles: any, excludedLanguages: String[], grammars: IGrammarContributions) {
constructor(languageIdentifierResolver: ILanguageIdentifierResolver, editor: ICommonCodeEditor, syntaxProfiles: any, excludedLanguages: String[], grammars: IGrammarContributions, emmetActionName?: string) {
this._languageIdentifierResolver = languageIdentifierResolver;
this._editor = editor;
this._syntaxProfiles = syntaxProfiles;
this._excludedLanguages = excludedLanguages;
this._hasMadeEdits = false;
this._grammars = grammars;
this._emmetActionName = emmetActionName;
}
public isEmmetEnabledMode(): boolean {
......@@ -84,6 +85,15 @@ export class EditorAccessor implements emmet.Editor {
}
public replaceContent(value: string, start: number, end: number, no_indent: boolean): void {
let range = this.getRangeToReplace(value, start, end);
if (!range) {
return;
}
let codeSnippet = snippets.CodeSnippet.fromEmmet(value);
SnippetController.get(this._editor).runWithReplaceRange(codeSnippet, range);
}
public getRangeToReplace(value: string, start: number, end: number): Range {
//console.log('value', value);
let startPosition = this.getPositionFromOffset(start);
let endPosition = this.getPositionFromOffset(end);
......@@ -95,7 +105,7 @@ export class EditorAccessor implements emmet.Editor {
if (strings.startsWith(value, match[0])) {
startPosition = new Position(startPosition.lineNumber, startPosition.column - match[0].length);
} else {
return; // ignore
return null; // ignore
}
}
......@@ -104,7 +114,7 @@ export class EditorAccessor implements emmet.Editor {
if (strings.endsWith(value, '>')) {
endPosition = new Position(endPosition.lineNumber, endPosition.column + 1);
} else {
return; // ignore
return null; // ignore
}
}
......@@ -115,8 +125,16 @@ export class EditorAccessor implements emmet.Editor {
}
let range = new Range(startPosition.lineNumber, startPosition.column, endPosition.lineNumber, endPosition.column);
let codeSnippet = snippets.CodeSnippet.fromEmmet(value);
SnippetController.get(this._editor).runWithReplaceRange(codeSnippet, range);
let textToReplace = this._editor.getModel().getValueInRange(range);
// During Expand Abbreviation action, if the expanded abbr is the same as the text it intends to replace,
// then treat it as a no-op and return TAB to the editor
if (this._emmetActionName === 'expand_abbreviation' && (value === textToReplace || value === textToReplace + '${0}')) {
this._editor.trigger('emmet', Handler.Tab, {});
return null;
}
return range;
}
public onAfterEmmetAction(): void {
......
......@@ -7,7 +7,7 @@
import { TPromise } from 'vs/base/common/winjs.base';
import { ICommonCodeEditor, EditorContextKeys } from 'vs/editor/common/editorCommon';
import { EditorAction, ServicesAccessor } from 'vs/editor/common/editorCommonExtensions';
import { EditorAction, ServicesAccessor, IActionOptions } from 'vs/editor/common/editorCommonExtensions';
import { ICommandKeybindingsOptions } from 'vs/editor/common/config/config';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { grammarsExtPoint, ITMSyntaxExtensionPoint } from 'vs/editor/node/textMate/TMGrammars';
......@@ -199,8 +199,19 @@ export class EmmetActionContext {
}
}
export interface IEmmetActionOptions extends IActionOptions {
actionName: string;
}
export abstract class EmmetEditorAction extends EditorAction {
protected emmetActionName: string;
constructor(opts: IEmmetActionOptions) {
super(opts);
this.emmetActionName = opts.actionName;
}
abstract runEmmetAction(accessor: ServicesAccessor, ctx: EmmetActionContext);
protected noExpansionOccurred(editor: ICommonCodeEditor) {
......@@ -227,6 +238,7 @@ export abstract class EmmetEditorAction extends EditorAction {
const messageService = accessor.get(IMessageService);
const contextService = accessor.get(IWorkspaceContextService);
const workspaceRoot = contextService.getWorkspace() ? contextService.getWorkspace().resource.fsPath : '';
const telemetryService = accessor.get(ITelemetryService);
return this._withGrammarContributions(extensionService).then((grammarContributions) => {
......@@ -235,7 +247,8 @@ export abstract class EmmetEditorAction extends EditorAction {
editor,
configurationService.getConfiguration<IEmmetConfiguration>().emmet.syntaxProfiles,
configurationService.getConfiguration<IEmmetConfiguration>().emmet.excludeLanguages,
grammarContributions
grammarContributions,
this.emmetActionName
);
if (!editorAccessor.isEmmetEnabledMode()) {
......@@ -253,6 +266,7 @@ export abstract class EmmetEditorAction extends EditorAction {
this.runEmmetAction(accessor, new EmmetActionContext(editor, _emmet, editorAccessor));
});
editorAccessor.onAfterEmmetAction();
telemetryService.publicLog('emmetActionCompleted', { action: this.emmetActionName });
});
});
......@@ -261,17 +275,15 @@ export abstract class EmmetEditorAction extends EditorAction {
export class BasicEmmetEditorAction extends EmmetEditorAction {
private emmetActionName: string;
constructor(id: string, label: string, alias: string, actionName: string, kbOpts?: ICommandKeybindingsOptions) {
super({
id: id,
label: label,
alias: alias,
id,
label,
alias,
precondition: EditorContextKeys.Writable,
kbOpts: kbOpts
kbOpts,
actionName
});
this.emmetActionName = actionName;
}
public runEmmetAction(accessor: ServicesAccessor, ctx: EmmetActionContext) {
......
......@@ -167,4 +167,22 @@ suite('Emmet', () => {
});
});
});
test('emmet replace range', () => {
withMockCodeEditor(['This is line 1'], {}, (editor) => {
let editorAccessor = new EditorAccessor(null, editor, null, [], new MockGrammarContributions(''), 'expand_abbreviation');
editor.getModel().setValue('This is line 1');
assert.equal(editorAccessor.getRangeToReplace('line', 8, 12), null);
editor.getModel().setValue('This is line 1');
assert.equal(editorAccessor.getRangeToReplace('line${0}', 8, 12), null);
editor.getModel().setValue('This is line 1');
let range = editorAccessor.getRangeToReplace('some other text', 8, 12);
assert.equal(range.startLineNumber, 1);
assert.equal(range.endLineNumber, 1);
assert.equal(range.startColumn, 9);
assert.equal(range.endColumn, 13);
});
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册