Skip to content

Commit fce91cb

Browse files
mtaran-googlemarijnh
authored andcommitted
[xml mode] Improved indentation for attributes and multi-line tags
Issue #1694
1 parent ce8d1e7 commit fce91cb

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

mode/xml/xml.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
CodeMirror.defineMode("xml", function(config, parserConfig) {
22
var indentUnit = config.indentUnit;
33
var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
4+
var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag || true;
45

56
var Kludges = parserConfig.htmlMode ? {
67
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
@@ -111,6 +112,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
111112
return "error";
112113
} else if (/[\'\"]/.test(ch)) {
113114
state.tokenize = inAttribute(ch);
115+
state.stringStartCol = stream.column();
114116
return state.tokenize(stream, state);
115117
} else {
116118
stream.eatWhile(/[^\s\u00a0=<>\"\']/);
@@ -119,7 +121,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
119121
}
120122

121123
function inAttribute(quote) {
122-
return function(stream, state) {
124+
var closure = function(stream, state) {
123125
while (!stream.eol()) {
124126
if (stream.next() == quote) {
125127
state.tokenize = inTag;
@@ -128,6 +130,8 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
128130
}
129131
return "string";
130132
};
133+
closure.isInAttribute = true;
134+
return closure;
131135
}
132136

133137
function inBlock(style, terminator) {
@@ -299,10 +303,20 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
299303

300304
indent: function(state, textAfter, fullLine) {
301305
var context = state.context;
306+
// Indent multi-line strings (e.g. css).
307+
if (state.tokenize.isInAttribute) {
308+
return state.stringStartCol + 1;
309+
}
302310
if ((state.tokenize != inTag && state.tokenize != inText) ||
303311
context && context.noIndent)
304312
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
305-
if (state.tagName) return state.tagStart + indentUnit * multilineTagIndentFactor;
313+
// Indent the starts of attribute names.
314+
if (state.tagName) {
315+
if (multilineTagIndentPastTag)
316+
return state.tagStart + state.tagName.length + 2;
317+
else
318+
return state.tagStart + indentUnit * multilineTagIndentFactor;
319+
}
306320
if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
307321
if (context && /^<\//.test(textAfter))
308322
context = context.prev;

0 commit comments

Comments
 (0)