Skip to content

Commit 359a17c

Browse files
committed
Merge branch 'develop'
2 parents ea7f01f + ec1b1b6 commit 359a17c

File tree

6 files changed

+205
-4
lines changed

6 files changed

+205
-4
lines changed

src/commons/formattingService.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2013-2014 François de Campredon
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
16+
import Promise = require('bluebird');
17+
18+
/**
19+
* A service allowing to retrieve formating information for a given file
20+
*/
21+
interface IFormattingService {
22+
/**
23+
* Retrieve formating information for a givent file
24+
* @param fileName the absolute path of the file
25+
* @param options formation options
26+
* @param startPos an option start position for the formating range
27+
* @param endPos an optional end position for the formating range
28+
*
29+
* @return a promise resolving to a formating range info
30+
*/
31+
getFormatingForFile(fileName: string, options: TypeScript.Services.FormatCodeOptions,
32+
startPos?: CodeMirror.Position, endPos?: CodeMirror.Position): Promise<IFormattingService.TextEdit[]>;
33+
}
34+
35+
module IFormattingService {
36+
export interface TextEdit {
37+
text: string;
38+
endPos: CodeMirror.Position;
39+
startPos: CodeMirror.Position;
40+
}
41+
}
42+
43+
export = IFormattingService;

src/declarations/brackets.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,7 @@ declare module brackets {
971971
//--------------------------------------------------------------------------
972972
interface CommandManager {
973973
execute(id: string, args: any): JQueryPromise<any>;
974+
register(name: string, id: string, callback: () => void): void;
974975
}
975976

976977

src/main/formattingManager.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright 2013-2014 François de Campredon
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
16+
'use strict';
17+
18+
import ServiceConsumer = require('./serviceConsumer');
19+
import IFormatingService = require('../commons/formattingService');
20+
21+
var EditorManager = brackets.getModule('editor/EditorManager'),
22+
Editor = brackets.getModule('editor/Editor').Editor;
23+
24+
25+
class FormattingManager extends ServiceConsumer<IFormatingService> {
26+
format = () => {
27+
var editor = EditorManager.getCurrentFullEditor();
28+
if (!editor) {
29+
return;
30+
}
31+
var useTabs = Editor.getUseTabChar();
32+
33+
var options: TypeScript.Services.FormatCodeOptions = {
34+
IndentSize: Editor.getSpaceUnits(),
35+
TabSize: Editor.getTabSize(),
36+
NewLineCharacter: '\n',
37+
ConvertTabsToSpaces: !useTabs,
38+
InsertSpaceAfterSemicolonInForStatements: true,
39+
InsertSpaceAfterCommaDelimiter: true,
40+
InsertSpaceBeforeAndAfterBinaryOperators: true,
41+
InsertSpaceAfterKeywordsInControlFlowStatements: true,
42+
InsertSpaceAfterFunctionKeywordForAnonymousFunctions: true,
43+
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
44+
PlaceOpenBraceOnNewLineForFunctions: false,
45+
PlaceOpenBraceOnNewLineForControlBlocks: false
46+
};
47+
var currentRange = editor.getSelection(true),
48+
startPos = currentRange ? currentRange.start : undefined,
49+
endPos = currentRange ? currentRange.end : undefined;
50+
51+
if (startPos && endPos && startPos.line === endPos.line && startPos.ch === endPos.ch) {
52+
startPos = endPos = undefined;
53+
}
54+
55+
56+
this.getService().then(service => {
57+
service.getFormatingForFile(editor.document.file.fullPath, options, startPos, endPos).then(textEdits => {
58+
if (EditorManager.getCurrentFullEditor() !== editor) {
59+
return;
60+
}
61+
textEdits.forEach(edit => {
62+
editor.document.replaceRange(edit.text, edit.startPos, edit.endPos);
63+
});
64+
});
65+
});
66+
};
67+
68+
static FORMAT_COMMAND_ID = 'fdecampred.brackets-typescript.format';
69+
70+
static FORMAT_LABEL = 'Format';
71+
}
72+
73+
export = FormattingManager;
74+

src/main/index.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import TypeScriptQuickEditProvider = require('./quickEdit');
2525
import TypeScriptQuickJumpProvider = require('./quickJump');
2626
import TypeScriptQuickFindDefitionProvider = require('./quickFindDefinition');
2727
import CodeHintProvider = require('./codeHintProvider');
28+
import FormattingManager = require('./formattingManager');
2829
import typeScriptModeFactory = require('./mode');
2930

3031

@@ -45,13 +46,16 @@ var LanguageManager = brackets.getModule('language/LanguageManager'),
4546
EditorManager = brackets.getModule('editor/EditorManager'),
4647
QuickOpen = brackets.getModule('search/QuickOpen'),
4748
PreferencesManager = brackets.getModule('preferences/PreferencesManager'),
48-
CodeMirror: typeof CodeMirror = brackets.getModule('thirdparty/CodeMirror2/lib/codemirror');
49+
CommandManager = brackets.getModule('command/CommandManager'),
50+
CodeMirror: typeof CodeMirror = brackets.getModule('thirdparty/CodeMirror2/lib/codemirror'),
51+
Menus = brackets.getModule('command/Menus');
4952

5053
var tsErrorReporter: TypeScriptErrorReporter,
5154
quickEditProvider: TypeScriptQuickEditProvider,
5255
codeHintProvider: CodeHintProvider,
5356
quickJumpProvider: TypeScriptQuickJumpProvider,
54-
quickFindDefinitionProvider: TypeScriptQuickFindDefitionProvider;
57+
quickFindDefinitionProvider: TypeScriptQuickFindDefitionProvider,
58+
formattingManager: FormattingManager;
5559

5660

5761

@@ -95,7 +99,12 @@ function init(config: { logLevel: string; typeScriptLocation: string; workerLoca
9599
//Register quickFindDefinitionProvider
96100
quickFindDefinitionProvider = new TypeScriptQuickFindDefitionProvider();
97101
QuickOpen.addQuickOpenPlugin(quickFindDefinitionProvider);
98-
102+
103+
//Register formatting command
104+
formattingManager = new FormattingManager();
105+
CommandManager.register(FormattingManager.FORMAT_LABEL, FormattingManager.FORMAT_COMMAND_ID, formattingManager.format);
106+
var contextMenu = Menus.getContextMenu(Menus.ContextMenuIds.EDITOR_MENU);
107+
contextMenu.addMenuItem(FormattingManager.FORMAT_COMMAND_ID);
99108

100109
initServices(config.workerLocation, config.typeScriptLocation, config.logLevel);
101110

@@ -111,6 +120,7 @@ function disposeServices() {
111120
workingSet.dispose();
112121
preferencesManager.dispose();
113122

123+
formattingManager.reset();
114124
tsErrorReporter.reset();
115125
codeHintProvider.reset();
116126
quickEditProvider.reset();
@@ -143,6 +153,7 @@ function initServices(workerLocation: string, typeScriptLocation: string, logLev
143153
quickEditProvider.setService(proxy.definitionService);
144154
quickJumpProvider.setService(proxy.definitionService);
145155
quickFindDefinitionProvider.setService(proxy.lexicalStructureService);
156+
formattingManager.setService(proxy.formattingService);
146157
});
147158
}
148159

src/ts-worker/formattingService.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright 2013-2014 François de Campredon
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
import IFormattingService = require('../commons/formattingService');
18+
import TypeScriptProjectManager = require('./projectManager');
19+
import Promise = require('bluebird');
20+
21+
22+
23+
class FormattingService implements IFormattingService {
24+
25+
/**
26+
* @param projectManager the Project manager used by the service to retrieve project
27+
*/
28+
constructor(
29+
private projectManager: TypeScriptProjectManager
30+
) {}
31+
32+
33+
/**
34+
* Retrieve formating information for a givent file
35+
* @param fileName the absolute path of the file
36+
* @param options formation options
37+
* @param startPos an option start position for the formating range
38+
* @param endPos an optional end position for the formating range
39+
*
40+
* @return a promise resolving to a formating range info
41+
*/
42+
getFormatingForFile(fileName: string, options: TypeScript.Services.FormatCodeOptions,
43+
startPos?: CodeMirror.Position, endPos?: CodeMirror.Position): Promise<IFormattingService.TextEdit[]> {
44+
return this.projectManager.getProjectForFile(fileName).then(project => {
45+
46+
var languageServiceHost = project.getLanguageServiceHost(),
47+
languageService = project.getLanguageService(),
48+
minChar: number, limChar: number;
49+
50+
if (!startPos || ! endPos) {
51+
minChar = 0;
52+
limChar = project.getLanguageServiceHost().getScriptContent(fileName).length - 1;
53+
} else {
54+
minChar = languageServiceHost.getIndexFromPos(fileName, startPos);
55+
limChar = languageServiceHost.getIndexFromPos(fileName, endPos);
56+
}
57+
58+
var result = languageService.getFormattingEditsForRange(fileName, minChar, limChar, options);
59+
60+
return result && result.reverse().map(editRange => ({
61+
text: editRange.text,
62+
startPos: languageServiceHost.indexToPosition(fileName, editRange.minChar),
63+
endPos: languageServiceHost.indexToPosition(fileName, editRange.limChar)
64+
}));
65+
});
66+
}
67+
}
68+
69+
export = FormattingService;

src/ts-worker/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import TypeScriptProject = require('./project');
2424
import ErrorService = require('./errorService');
2525
import DefinitionService = require('./definitionService');
2626
import CompletionService = require('./completionService');
27+
import FormattingService= require('./formattingService');
2728
import LexicalStructureService = require('./lexicalStructureService');
2829
import WorkerBridge = require('../commons/workerBridge');
2930
import logger = require('../commons/logger');
@@ -34,14 +35,16 @@ var projectManager = new TypeScriptProjectManager(),
3435
completionService = new CompletionService(projectManager),
3536
definitionService = new DefinitionService(projectManager),
3637
lexicalStructureService = new LexicalStructureService(projectManager),
38+
formattingService = new FormattingService(projectManager),
3739
bridge = new WorkerBridge(<any>self);
3840

3941
//expose the worker services
4042
bridge.init({
4143
errorService: errorService,
4244
completionService: completionService,
4345
definitionService: definitionService,
44-
lexicalStructureService: lexicalStructureService
46+
lexicalStructureService: lexicalStructureService,
47+
formattingService: formattingService
4548
}).then(proxy => {
4649
//inject main services into worker components
4750
proxy.getTypeScriptLocation().then( (location: string) => {

0 commit comments

Comments
 (0)