Skip to content

Commit 5096cd6

Browse files
authored
Merge pull request #15 from owent-contrib/master
merge PR#14, add support for protobuf, format on save now works and etc.
2 parents bec4ef9 + 884acb1 commit 5096cd6

File tree

4 files changed

+168
-32
lines changed

4 files changed

+168
-32
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## Release history
44

5+
### DEVELOPING
6+
* add protobuf support(work with https://marketplace.visualstudio.com/items?itemName=peterj.proto)
7+
* add javascript/typescript support
8+
* allow different style & fallback style option for different languages
9+
* format on save is available now(just like https://github.com/Microsoft/vscode-go/blob/master/src/goMain.ts)
10+
511
### v 0.6.1
612
* clean up dependencies #9
713

package.json

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
"onLanguage:cpp",
1919
"onLanguage:c",
2020
"onLanguage:objective-c",
21-
"onLanguage:java"
21+
"onLanguage:java",
22+
"onLanguage:javascript",
23+
"onLanguage:typescript",
24+
"onLanguage:proto"
2225
],
2326
"contributes": {
2427
"configuration": {
@@ -35,15 +38,88 @@
3538
"default": "clang-format",
3639
"description": "clang-format executable path"
3740
},
41+
// style
3842
"clang-format.style": {
3943
"type": "string",
4044
"default": "file",
4145
"description": "clang-format style.(-style=value, value can be file, LLVM, Google, Chromium, Mozilla, WebKit or json configure)"
4246
},
47+
// fallback style
4348
"clang-format.fallbackStyle": {
4449
"type": "string",
4550
"default": "LLVM",
4651
"description": "clang-format fallback style.(-fallback-style=value, value can be none, LLVM, Google, Chromium, Mozilla, WebKit)"
52+
},
53+
// every language can has it's own style & fallback style option, if not confirured, use the default value above
54+
"clang-format.language.cpp.style": {
55+
"type": "string",
56+
"default": "",
57+
"description": "clang-format fallback style for c++, left empty to use clang-format.style"
58+
},
59+
"clang-format.language.cpp.fallbackStyle": {
60+
"type": "string",
61+
"default": "",
62+
"description": "clang-format fallback style for c++, left empty to use clang-format.fallbackStyle"
63+
},
64+
"clang-format.language.c.style": {
65+
"type": "string",
66+
"default": "",
67+
"description": "clang-format fallback style for c, left empty to use clang-format.style"
68+
},
69+
"clang-format.language.c.fallbackStyle": {
70+
"type": "string",
71+
"default": "",
72+
"description": "clang-format fallback style for c, left empty to use clang-format.fallbackStyle"
73+
},
74+
"clang-format.language.objective-c.style": {
75+
"type": "string",
76+
"default": "",
77+
"description": "clang-format fallback style for objective-c, left empty to use clang-format.style"
78+
},
79+
"clang-format.language.objective-c.fallbackStyle": {
80+
"type": "string",
81+
"default": "",
82+
"description": "clang-format fallback style for objective-c, left empty to use clang-format.fallbackStyle"
83+
},
84+
"clang-format.language.java.style": {
85+
"type": "string",
86+
"default": "",
87+
"description": "clang-format fallback style for java, left empty to use clang-format.style"
88+
},
89+
"clang-format.language.java.fallbackStyle": {
90+
"type": "string",
91+
"default": "",
92+
"description": "clang-format fallback style for java, left empty to use clang-format.fallbackStyle"
93+
},
94+
"clang-format.language.javascript.style": {
95+
"type": "string",
96+
"default": "",
97+
"description": "clang-format fallback style for javascript, left empty to use clang-format.style"
98+
},
99+
"clang-format.language.javascript.fallbackStyle": {
100+
"type": "string",
101+
"default": "",
102+
"description": "clang-format fallback style for javascript, left empty to use clang-format.fallbackStyle"
103+
},
104+
"clang-format.language.typescript.style": {
105+
"type": "string",
106+
"default": "",
107+
"description": "clang-format fallback style for typescript, left empty to use clang-format.style"
108+
},
109+
"clang-format.language.typescript.fallbackStyle": {
110+
"type": "string",
111+
"default": "",
112+
"description": "clang-format fallback style for typescript, left empty to use clang-format.fallbackStyle"
113+
},
114+
"clang-format.language.proto.style": {
115+
"type": "string",
116+
"default": "",
117+
"description": "clang-format fallback style for proto, left empty to use clang-format.style"
118+
},
119+
"clang-format.language.proto.fallbackStyle": {
120+
"type": "string",
121+
"default": "",
122+
"description": "clang-format fallback style for proto, left empty to use clang-format.fallbackStyle"
47123
}
48124
}
49125
}
@@ -54,8 +130,8 @@
54130
"postinstall": "node ./node_modules/vscode/bin/install"
55131
},
56132
"devDependencies": {
57-
"typescript": "^1.6.2",
58-
"vscode": "0.10.x"
133+
"typescript": "^1.8.5",
134+
"vscode": "^0.11.0"
59135
},
60136
"icon": "clang-format.png",
61137
"repository": {

src/clangMode.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,5 @@
22

33
import vscode = require('vscode');
44

5-
export const CPP_MODE: vscode.DocumentFilter = { language: 'cpp', scheme: 'file' }
6-
export const C_MODE: vscode.DocumentFilter = { language: 'c', scheme: 'file' }
7-
export const OBJECTIVE_C_MODE: vscode.DocumentFilter = { language: 'objective-c', scheme: 'file' }
8-
export const JAVA_MODE: vscode.DocumentFilter = { language: 'java', scheme: 'file' }
5+
const LANGUAGES: string[] = ['cpp', 'c', 'objective-c', 'java', 'javascript', 'typescript', 'proto'];
6+
export const MODES: vscode.DocumentFilter[] = LANGUAGES.map(language => ({ language, scheme: 'file' }));

src/extension.ts

Lines changed: 81 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as vscode from 'vscode';
22
import cp = require('child_process');
33
import path = require('path');
4-
import {C_MODE, CPP_MODE, OBJECTIVE_C_MODE, JAVA_MODE} from './clangMode';
4+
import {MODES} from './clangMode';
55
import { getBinPath } from './clangPath';
66
import sax = require('sax');
77

@@ -59,7 +59,9 @@ export class ClangDocumentFormattingEditProvider implements vscode.DocumentForma
5959

6060

6161
parser.onopentag = (tag) => {
62-
if (currentEdit) { reject("Malformed output"); }
62+
if (currentEdit) {
63+
reject("Malformed output");
64+
}
6365

6466
switch (tag.name) {
6567
case "replacements":
@@ -120,24 +122,27 @@ export class ClangDocumentFormattingEditProvider implements vscode.DocumentForma
120122
return this.defaultConfigure.executable;
121123
}
122124

123-
private getStyle() {
124-
let ret = vscode.workspace.getConfiguration('clang-format').get<string>('style');
125+
private getStyle(document: vscode.TextDocument) {
126+
let ret = vscode.workspace.getConfiguration('clang-format').get<string>(`language.${document.languageId}.style`);
125127
if (ret.trim()) {
126-
ret = ret.trim();
128+
return ret.trim();
129+
}
130+
131+
ret = vscode.workspace.getConfiguration('clang-format').get<string>('style');
132+
if (ret && ret.trim()) {
133+
return ret.trim();
127134
} else {
128-
ret = this.defaultConfigure.style;
135+
return this.defaultConfigure.style;
129136
}
130-
131-
// Custom style
132-
// if (ret.match(/[\\\{\" ]/)) {
133-
// return `"${ret.replace(/([\\\"])/g, "\\$1")}"`
134-
// }
135-
136-
return ret;
137137
}
138138

139-
private getFallbackStyle() {
140-
let strConf = vscode.workspace.getConfiguration('clang-format').get<string>('fallbackStyle');
139+
private getFallbackStyle(document: vscode.TextDocument) {
140+
let strConf = vscode.workspace.getConfiguration('clang-format').get<string>(`language.${document.languageId}.fallbackStyle`);
141+
if (strConf.trim()) {
142+
return strConf;
143+
}
144+
145+
strConf = vscode.workspace.getConfiguration('clang-format').get<string>('fallbackStyle');
141146
if (strConf.trim()) {
142147
return strConf;
143148
}
@@ -158,7 +163,9 @@ export class ClangDocumentFormattingEditProvider implements vscode.DocumentForma
158163
vscode.window.showInformationMessage("The '" + formatCommandBinPath + "' command is not available. Please check your clang.formatTool user setting and ensure it is installed.");
159164
return resolve(null);
160165
}
161-
if (err) return reject("Cannot format due to syntax errors.");
166+
if (err) {
167+
return reject("Cannot format due to syntax errors.");
168+
}
162169

163170
var dummyProcessor = (value: string) => {
164171
debugger;
@@ -171,9 +178,12 @@ export class ClangDocumentFormattingEditProvider implements vscode.DocumentForma
171178
}
172179
};
173180

174-
var formatArgs = ['-output-replacements-xml'];
175-
formatArgs.push(`-style=${this.getStyle()}`);
176-
formatArgs.push(`-fallback-style=${this.getFallbackStyle()}`);
181+
var formatArgs = [
182+
'-output-replacements-xml',
183+
`-style=${this.getStyle(document)}`,
184+
`-fallback-style=${this.getFallbackStyle(document)}`,
185+
`-assume-filename=${document.fileName}`,
186+
];
177187

178188
if (range) {
179189
var offset = document.offsetAt(range.start);
@@ -195,23 +205,69 @@ export class ClangDocumentFormattingEditProvider implements vscode.DocumentForma
195205
var child = cp.execFile(formatCommandBinPath, formatArgs, { cwd: workingPath }, childCompleted);
196206
child.stdin.end(codeContent);
197207

198-
token.onCancellationRequested(() => {
199-
child.kill();
200-
reject("Cancelation requested");
201-
});
208+
if(token) {
209+
token.onCancellationRequested(() => {
210+
child.kill();
211+
reject("Cancelation requested");
212+
});
213+
}
202214
});
203215
}
204216

217+
public formatDocument(document: vscode.TextDocument): Thenable<vscode.TextEdit[]>{
218+
return this.doFormatDocument(document, null, null, null);
219+
}
220+
205221
}
206222

207223
let diagnosticCollection: vscode.DiagnosticCollection;
208224

209225
export function activate(ctx: vscode.ExtensionContext): void {
210226

211227
var formatter = new ClangDocumentFormattingEditProvider();
228+
var availableLanguages = {};
212229

213-
[C_MODE, CPP_MODE, JAVA_MODE, OBJECTIVE_C_MODE].forEach(mode => {
230+
MODES.forEach(mode => {
214231
ctx.subscriptions.push(vscode.languages.registerDocumentRangeFormattingEditProvider(mode, formatter));
215232
ctx.subscriptions.push(vscode.languages.registerDocumentFormattingEditProvider(mode, formatter));
216-
})
233+
availableLanguages[mode.language] = true;
234+
});
235+
236+
// TODO: This is really ugly. I'm not sure we can do better until
237+
// Code supports a pre-save event where we can do the formatting before
238+
// the file is written to disk.
239+
// @see https://github.com/Microsoft/vscode-go/blob/master/src/goMain.ts
240+
let ignoreNextSave = new WeakSet<vscode.TextDocument>();
241+
242+
vscode.workspace.onDidSaveTextDocument(document => {
243+
try {
244+
let formatOnSave = vscode.workspace.getConfiguration('clang-format').get<boolean>('formatOnSave');
245+
if (!formatOnSave) {
246+
return;
247+
}
248+
249+
if (!availableLanguages[document.languageId] || ignoreNextSave.has(document)) {
250+
return;
251+
}
252+
253+
let textEditor = vscode.window.activeTextEditor;
254+
formatter.formatDocument(document).then(edits => {
255+
return textEditor.edit(editBuilder => {
256+
edits.forEach(edit => editBuilder.replace(edit.range, edit.newText))
257+
});
258+
}).then(applied => {
259+
ignoreNextSave.add(document);
260+
return document.save();
261+
}).then(
262+
() => {
263+
ignoreNextSave.delete(document);
264+
}, () => {
265+
// Catch any errors and ignore so that we still trigger
266+
// the file save.
267+
}
268+
);
269+
} catch(e) {
270+
console.error('formate when save file failed.' + e.toString());
271+
}
272+
});
217273
}

0 commit comments

Comments
 (0)