Skip to content

Commit 7f68685

Browse files
committed
Update: editor options (tabSize and insertSpaces)
1 parent cd31774 commit 7f68685

File tree

3 files changed

+174
-58
lines changed

3 files changed

+174
-58
lines changed

src/app.vue

Lines changed: 120 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
<template>
22
<div class="app__root">
33
<div class="app__header">
4-
<label class="app__show-fixed-code-button">
5-
<input
6-
type="checkbox"
7-
v-model="showFixedCode"
8-
>
9-
Show fixed code
4+
<div class="app__header-title">
5+
Playground for <a href="https://github.com/vuejs/eslint-plugin-vue#readme" target="_blank">eslint-plugin-vue</a>.
6+
</div>
7+
<label class="app__header-option-item">
8+
<select v-model.number="indentSize">
9+
<option value="2">TabSize: 2</option>
10+
<option value="4">TabSize: 4</option>
11+
<option value="8">TabSize: 8</option>
12+
</select>
13+
</label>
14+
<label class="app__header-option-item">
15+
<select v-model="indentType">
16+
<option value="space">Indent: spaces</option>
17+
<option value="tab">Indent: tabs</option>
18+
</select>
19+
</label>
20+
<label class="app__header-option-item">
21+
<select v-model="editorType">
22+
<option value="codeAndFixedCode">FixedCode: show</option>
23+
<option value="codeOnly">FixedCode: hide</option>
24+
</select>
1025
</label>
11-
Playground for <a href="https://github.com/vuejs/eslint-plugin-vue#readme" target="_blank">eslint-plugin-vue</a>.
1226
</div>
1327
<div class="app__body">
1428
<rule-select
@@ -23,8 +37,9 @@
2337
:messages="messages"
2438
:fixed-code="fixedCode"
2539
:fixed-messages="fixedMessages"
40+
:format-options="formatOptions"
2641
:show-fixed-code="showFixedCode"
27-
@edit="onEdit"
42+
@edit="onCodeChange"
2843
@initialize.once="onEditorInitialize"
2944
/>
3045
<message-list class="app__errors" :messages="messages" />
@@ -66,70 +81,61 @@ export default {
6681
},
6782
6883
computed: {
69-
messages() {
70-
try {
71-
return linter.verify(this.code, this.config, "vue-eslint-demo.vue")
72-
}
73-
catch (err) {
74-
return [{
75-
fatal: true,
76-
severity: 2,
77-
message: err.message,
78-
line: 1,
79-
column: 0,
80-
}]
84+
formatOptions() {
85+
return {
86+
insertSpaces: this.indentType === "space",
87+
tabSize: this.indentSize,
8188
}
8289
},
8390
84-
fixResult() {
85-
try {
86-
return linter.verifyAndFix(this.code, this.config, "vue-eslint-demo.vue")
87-
}
88-
catch (err) {
89-
return {
90-
output: this.code,
91-
messages: [{
92-
fatal: true,
93-
severity: 2,
94-
message: err.message,
95-
line: 1,
96-
column: 0,
97-
}],
98-
}
99-
}
91+
showFixedCode() {
92+
return this.editorType === "codeAndFixedCode"
10093
},
10194
102-
fixedCode() {
103-
return this.fixResult.output
95+
versions() {
96+
return versions
10497
},
98+
},
10599
106-
fixedMessages() {
107-
return this.fixResult.messages
100+
// Use `watch` to re-use the internal state of the linter while making `messages` and `fixedCode`.
101+
watch: {
102+
code() {
103+
this.lint()
104+
this.applyUrlHash()
108105
},
109-
110-
versions() {
111-
return versions
106+
indentSize() {
107+
this.lint()
108+
this.applyUrlHash()
109+
},
110+
indentType() {
111+
this.lint()
112+
this.applyUrlHash()
113+
},
114+
editorType() {
115+
this.applyUrlHash()
112116
},
113117
},
114118
115119
mounted() {
120+
this.lint()
116121
window.addEventListener("hashchange", this.onUrlHashChange)
117122
},
118123
beforeDestroey() {
119124
window.removeEventListener("hashchange", this.onUrlHashChange)
120125
},
121126
122127
methods: {
123-
onEdit(code) {
124-
this.code = code
125-
this.applyUrlHash()
126-
},
127-
128128
onEditorInitialize() {
129129
window.MainContent.show()
130130
},
131131
132+
onCodeChange(code) {
133+
this.code = code
134+
},
135+
132136
onConfigChange() {
137+
// The inside of `this.config` was changed directly.
138+
this.lint()
133139
this.applyUrlHash()
134140
},
135141
@@ -144,6 +150,53 @@ export default {
144150
applyUrlHash() {
145151
window.location.replace(`#${serializeState(this.$data)}`)
146152
},
153+
154+
lint() {
155+
// Adjust the indentation options to the editor settings.
156+
const config = Object.assign({}, this.config)
157+
const rules = config.rules = Object.assign({}, this.config.rules)
158+
const indentType = (this.indentType === "space") ? this.indentSize : "tab"
159+
rules.indent = [rules.indent, indentType]
160+
rules["vue/html-indent"] = [rules["vue/html-indent"], indentType]
161+
162+
// Fix
163+
try {
164+
// At first, fix because `linter.verifyAndFix` does not accept SourceCode object.
165+
const ret = linter.verifyAndFix(this.code, config, "vue-eslint-demo.vue")
166+
this.fixedCode = ret.output
167+
this.fixedMessages = ret.messages
168+
}
169+
catch (err) {
170+
this.fixedCode = this.code
171+
this.fixedMessages = [{
172+
fatal: true,
173+
severity: 2,
174+
message: err.message,
175+
line: 1,
176+
column: 0,
177+
}]
178+
}
179+
180+
// Lint
181+
try {
182+
this.messages = linter.verify(
183+
// Cannot reuse until https://github.com/eslint/eslint/pull/8755 is merged.
184+
// linter.getSourceCode(), // Reuse the AST of the previous `linter.verifyAndFix`.
185+
this.code,
186+
config,
187+
"vue-eslint-demo.vue"
188+
)
189+
}
190+
catch (err) {
191+
this.messages = [{
192+
fatal: true,
193+
severity: 2,
194+
message: err.message,
195+
line: 1,
196+
column: 0,
197+
}]
198+
}
199+
},
147200
},
148201
}
149202
</script>
@@ -164,13 +217,30 @@ a:hover {
164217
}
165218
166219
.app__header {
220+
display: flex;
221+
flex-wrap: wrap;
222+
align-items: center;
223+
justify-content: flex-end;
167224
flex-shrink: 0;
168-
padding: 8px;
169225
background-color: #A5D6A7;
170226
border-bottom: 1px solid #4CAF50;
171-
font-weight: bold;
172227
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
173228
}
229+
.app__header-title {
230+
flex-grow: 1;
231+
padding: 8px;
232+
font-weight: bold;
233+
}
234+
.app__header-option-item {
235+
flex-shrink: 0;
236+
padding: 2px;
237+
}
238+
.app__header-option-item > select {
239+
padding: 4px;
240+
border: 1px solid #4CAF50;
241+
border-radius: 3px;
242+
background-color: #E8F5E9;
243+
}
174244
175245
.app__body {
176246
display: flex;

src/code-editor.vue

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ export default {
147147
return []
148148
},
149149
},
150+
formatOptions: {
151+
type: Object,
152+
default() {
153+
return { insertSpaces: true, tabSize: 2 }
154+
},
155+
},
150156
showFixedCode: {
151157
type: Boolean,
152158
default: false,
@@ -222,14 +228,22 @@ export default {
222228
},
223229
224230
// But it's not shown.
225-
// See https://github.com/Microsoft/monaco-editor/issues/311
231+
// See https://github.com/mysticatea/vue-eslint-demo/issues/5
226232
fixedMessages(value) {
227233
const editor = this.fixedCodeEditor
228234
if (editor != null) {
229235
updateMarkers(editor, value)
230236
}
231237
},
232238
239+
formatOptions(value) {
240+
for (const editor of [this.codeEditor, this.fixedCodeEditor]) {
241+
if (editor != null) {
242+
editor.getModel().updateOptions(value)
243+
}
244+
}
245+
},
246+
233247
showFixedCode() {
234248
this.ready.then(this.initialize)
235249
},

src/state.js

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@ import pako from "pako"
22
import defaultCode from "./default-code.js"
33
import defaultConfig from "./default-config.js"
44

5+
/**
6+
* @typedef {Object} State
7+
* @property {string} code The source code the user input.
8+
* @property {Object} config The config object to lint.
9+
* @property {(2|4|8)} indentSize The indent size to set the editor.
10+
* @property {("space"|"tab")} indentType The indent type to set the editor.
11+
* @property {("codeAndFixedCode"|"codeOnly")} editorType The editor type to set the editor.
12+
* @property {Object[]} messages The error messages of the linting result.
13+
* @property {string} fixedCode The auto-fixed code.
14+
* @property {Object[]} fixedMessages The error messages of the linting result with `--fix`.
15+
*/
16+
517
/**
618
* Convert an Unicode string to base64.
719
* @param {string} text The string to convert.
@@ -24,23 +36,31 @@ function decodeFromBase64(base64) {
2436

2537
/**
2638
* Create the default state.
27-
* @returns {{config:any,code:string,showFixedCode:boolean}} The created state.
39+
* @returns {State} The created state.
2840
*/
2941
function createDefaultState() {
3042
const code = defaultCode
3143
const config = Object.assign({}, defaultConfig)
3244
config.rules = Object.assign({}, defaultConfig.rules)
33-
const showFixedCode = true
3445

35-
return { code, config, showFixedCode }
46+
return {
47+
code,
48+
config,
49+
indentSize: 2,
50+
indentType: "space",
51+
editorType: "codeAndFixedCode",
52+
messages: [],
53+
fixedCode: code,
54+
fixedMessages: [],
55+
}
3656
}
3757

3858
/**
3959
* Initialize state.
4060
* @param {string} serializedText The string to deserialize.
41-
* @returns {{config:any,code:string,showFixedCode:boolean}} The created state.
61+
* @returns {State} The created state.
4262
*/
43-
export function deserializeState(serializedText) {
63+
export function deserializeState(serializedText) { //eslint-disable-line complexity
4464
const state = createDefaultState()
4565

4666
try {
@@ -60,6 +80,15 @@ export function deserializeState(serializedText) {
6080
}
6181
}
6282
}
83+
if (json.indentSize === 2 || json.indentSize === 4 || json.indentSize === 8) {
84+
state.indentSize = json.indentSize
85+
}
86+
if (json.indentType === "space" || json.indentType === "tab") {
87+
state.indentType = json.indentType
88+
}
89+
if (json.editorType === "codeAndFixedCode" || json.editorType === "codeOnly") {
90+
state.editorType = json.editorType
91+
}
6392
}
6493
catch (_err) {
6594
// ignores.
@@ -70,7 +99,7 @@ export function deserializeState(serializedText) {
7099

71100
/**
72101
* Create the base64
73-
* @param {object} state The state object.
102+
* @param {State} state The state object.
74103
* @returns {string} Serialized string.
75104
*/
76105
export function serializeState(state) {
@@ -85,7 +114,10 @@ export function serializeState(state) {
85114
},
86115
{}
87116
)
88-
const jsonText = JSON.stringify({ code, rules })
117+
const indentSize = state.indentSize
118+
const indentType = state.indentType
119+
const editorType = state.editorType
120+
const jsonText = JSON.stringify({ code, rules, indentSize, indentType, editorType })
89121
const compressedText = pako.deflate(jsonText, { to: "string" })
90122
return encodeToBase64(compressedText)
91123
}

0 commit comments

Comments
 (0)