Rules: indentation: Add the 'indent-sequences' option

Using either 'yes', 'no' or 'whatever', the user will be able to choose
whether to force block sequence items to be indented, to force them not
to be indented, or don't care, respectively.
pull/4/head
Adrien Vergé 9 years ago
parent ad5cec9c6c
commit 0b0251bacc

@ -42,7 +42,7 @@ class ColonTestCase(RuleTestCase):
' - p: kdjf\n' ' - p: kdjf\n'
' - q: val0\n' ' - q: val0\n'
' - q2:\n' ' - q2:\n'
' - val1\n' ' - val1\n'
'...\n', conf) '...\n', conf)
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
@ -67,7 +67,7 @@ class ColonTestCase(RuleTestCase):
' - o: {k1: v1}\n' ' - o: {k1: v1}\n'
' - o: {k1: v1}\n' ' - o: {k1: v1}\n'
' - q2:\n' ' - q2:\n'
' - val1\n' ' - val1\n'
'...\n', conf) '...\n', conf)
self.check('---\n' self.check('---\n'
'a: {b: {c: d, e : f}}\n', conf) 'a: {b: {c: d, e : f}}\n', conf)
@ -94,7 +94,7 @@ class ColonTestCase(RuleTestCase):
'...\n', conf, problem=(2, 4)) '...\n', conf, problem=(2, 4))
self.check('---\n' self.check('---\n'
'- lib :\n' '- lib :\n'
' - var\n' ' - var\n'
'...\n', conf, problem=(2, 6)) '...\n', conf, problem=(2, 6))
self.check('---\n' self.check('---\n'
'a: {b: {c : d, e : f}}\n', conf, 'a: {b: {c : d, e : f}}\n', conf,

@ -115,7 +115,7 @@ class CommentsIndentationTestCase(RuleTestCase):
' # comments\n' ' # comments\n'
' b: 2\n', conf) ' b: 2\n', conf)
self.check('---\n' self.check('---\n'
'mylist:\n' 'my list for today:\n'
' - todo 1\n' ' - todo 1\n'
' - todo 2\n' ' - todo 2\n'
' # commented for now\n' ' # commented for now\n'

@ -36,12 +36,12 @@ class HyphenTestCase(RuleTestCase):
'- elem2\n', conf) '- elem2\n', conf)
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
'- elem1\n' ' - elem1\n'
'- elem2\n', conf) ' - elem2\n', conf)
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
'- elem1\n' ' - elem1\n'
'- elem2\n', conf) ' - elem2\n', conf)
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
' subobject:\n' ' subobject:\n'
@ -69,12 +69,12 @@ class HyphenTestCase(RuleTestCase):
'- elem2\n', conf, problem=(2, 3)) '- elem2\n', conf, problem=(2, 3))
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
'- elem1\n' ' - elem1\n'
'- elem2\n', conf, problem=(4, 3)) ' - elem2\n', conf, problem=(4, 5))
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
'- elem1\n' ' - elem1\n'
'- elem2\n', conf, problem1=(3, 3), problem2=(4, 3)) ' - elem2\n', conf, problem1=(3, 5), problem2=(4, 5))
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
' subobject:\n' ' subobject:\n'

@ -48,7 +48,20 @@ class IndentationTestCase(RuleTestCase):
'...\n', conf) '...\n', conf)
def test_one_space(self): def test_one_space(self):
conf = 'indentation: {spaces: 1}' conf = 'indentation: {spaces: 1, indent-sequences: no}'
self.check('---\n'
'object:\n'
' k1:\n'
' - a\n'
' - b\n'
' k2: v2\n'
' k3:\n'
' - name: Unix\n'
' date: 1969\n'
' - name: Linux\n'
' date: 1991\n'
'...\n', conf)
conf = 'indentation: {spaces: 1, indent-sequences: yes}'
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
' k1:\n' ' k1:\n'
@ -63,7 +76,20 @@ class IndentationTestCase(RuleTestCase):
'...\n', conf) '...\n', conf)
def test_two_spaces(self): def test_two_spaces(self):
conf = 'indentation: {spaces: 2}' conf = 'indentation: {spaces: 2, indent-sequences: no}'
self.check('---\n'
'object:\n'
' k1:\n'
' - a\n'
' - b\n'
' k2: v2\n'
' k3:\n'
' - name: Unix\n'
' date: 1969\n'
' - name: Linux\n'
' date: 1991\n'
'...\n', conf)
conf = 'indentation: {spaces: 2, indent-sequences: yes}'
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
' k1:\n' ' k1:\n'
@ -78,7 +104,20 @@ class IndentationTestCase(RuleTestCase):
'...\n', conf) '...\n', conf)
def test_three_spaces(self): def test_three_spaces(self):
conf = 'indentation: {spaces: 3}' conf = 'indentation: {spaces: 3, indent-sequences: no}'
self.check('---\n'
'object:\n'
' k1:\n'
' - a\n'
' - b\n'
' k2: v2\n'
' k3:\n'
' - name: Unix\n'
' date: 1969\n'
' - name: Linux\n'
' date: 1991\n'
'...\n', conf)
conf = 'indentation: {spaces: 3, indent-sequences: yes}'
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
' k1:\n' ' k1:\n'
@ -92,8 +131,122 @@ class IndentationTestCase(RuleTestCase):
' date: 1991\n' ' date: 1991\n'
'...\n', conf) '...\n', conf)
def test_under_indented(self): def test_indent_sequences_whatever(self):
conf = 'indentation: {spaces: 4, indent-sequences: whatever}'
self.check('---\n'
'list one:\n'
'- 1\n'
'- 2\n'
'- 3\n'
'list two:\n'
' - a\n'
' - b\n'
' - c\n', conf)
self.check('---\n'
'list one:\n'
' - 1\n'
' - 2\n'
' - 3\n'
'list two:\n'
' - a\n'
' - b\n'
' - c\n', conf, problem=(3, 3))
self.check('---\n'
'list one:\n'
'- 1\n'
'- 2\n'
'- 3\n'
'list two:\n'
' - a\n'
' - b\n'
' - c\n', conf, problem=(7, 3))
self.check('---\n'
'list:\n'
' - 1\n'
' - 2\n'
' - 3\n'
'- a\n'
'- b\n'
'- c\n', conf, problem=(6, 1, 'syntax'))
def test_flow_mappings(self):
conf = 'indentation: {spaces: 2}'
self.check('---\n'
'a: {x: 1,\n'
' y,\n'
' z: 1}\n', conf)
self.check('---\n'
'a: {x: 1,\n'
' y,\n'
' z: 1}\n', conf, problem=(3, 4))
self.check('---\n'
'a: {x: 1,\n'
' y,\n'
' z: 1}\n', conf, problem=(3, 6))
self.check('---\n'
'a: {x: 1,\n'
' y, z: 1\n'
'}\n', conf, problem=(3, 3))
self.check('---\n'
'a: {\n'
' x: 1,\n'
' y, z: 1\n'
'}\n', conf)
self.check('---\n'
'a: {\n'
' x: 1,\n'
' y, z: 1}\n', conf)
self.check('---\n'
'a: {\n'
' x: 1,\n'
' y, z: 1\n'
'}\n', conf, problem=(3, 4))
self.check('---\n'
'a: {\n'
' x: 1,\n'
' y, z: 1\n'
' }\n', conf, problem=(5, 3))
def test_flow_sequences(self):
conf = 'indentation: {spaces: 2}' conf = 'indentation: {spaces: 2}'
self.check('---\n'
'a: [x,\n'
' y,\n'
' z]\n', conf)
self.check('---\n'
'a: [x,\n'
' y,\n'
' z]\n', conf, problem=(3, 4))
self.check('---\n'
'a: [x,\n'
' y,\n'
' z]\n', conf, problem=(3, 6))
self.check('---\n'
'a: [x,\n'
' y, z\n'
']\n', conf, problem=(3, 3))
self.check('---\n'
'a: [\n'
' x,\n'
' y, z\n'
']\n', conf)
self.check('---\n'
'a: [\n'
' x,\n'
' y, z]\n', conf)
self.check('---\n'
'a: [\n'
' x,\n'
' y, z\n'
']\n', conf, problem=(3, 4))
self.check('---\n'
'a: [\n'
' x,\n'
' y, z\n'
' ]\n', conf, problem=(5, 3))
def test_under_indented(self):
conf = 'indentation: {spaces: 2, indent-sequences: yes}'
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
' val: 1\n' ' val: 1\n'
@ -109,7 +262,7 @@ class IndentationTestCase(RuleTestCase):
' - name: Unix\n' ' - name: Unix\n'
' date: 1969\n' ' date: 1969\n'
'...\n', conf, problem=(5, 6, 'syntax')) '...\n', conf, problem=(5, 6, 'syntax'))
conf = 'indentation: {spaces: 4}' conf = 'indentation: {spaces: 4, indent-sequences: yes}'
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
' val: 1\n' ' val: 1\n'
@ -127,7 +280,7 @@ class IndentationTestCase(RuleTestCase):
'...\n', conf, problem=(5, 10, 'syntax')) '...\n', conf, problem=(5, 10, 'syntax'))
def test_over_indented(self): def test_over_indented(self):
conf = 'indentation: {spaces: 2}' conf = 'indentation: {spaces: 2, indent-sequences: yes}'
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
' val: 1\n' ' val: 1\n'
@ -143,7 +296,7 @@ class IndentationTestCase(RuleTestCase):
' - name: Unix\n' ' - name: Unix\n'
' date: 1969\n' ' date: 1969\n'
'...\n', conf, problem=(5, 12, 'syntax')) '...\n', conf, problem=(5, 12, 'syntax'))
conf = 'indentation: {spaces: 4}' conf = 'indentation: {spaces: 4, indent-sequences: yes}'
self.check('---\n' self.check('---\n'
'object:\n' 'object:\n'
' val: 1\n' ' val: 1\n'
@ -165,7 +318,7 @@ class IndentationTestCase(RuleTestCase):
self.check('---\n' self.check('---\n'
' - el1\n' ' - el1\n'
' - el2:\n' ' - el2:\n'
' - subel\n' ' - subel\n'
'...\n', conf, '...\n', conf,
problem=(2, 3)) problem=(2, 3))
self.check('---\n' self.check('---\n'
@ -174,24 +327,32 @@ class IndentationTestCase(RuleTestCase):
' - name: Linux\n' ' - name: Linux\n'
' date: 1991\n' ' date: 1991\n'
'...\n', conf, problem=(5, 16, 'syntax')) '...\n', conf, problem=(5, 16, 'syntax'))
conf = 'indentation: {spaces: 4, indent-sequences: whatever}'
self.check('---\n'
' - el1\n'
' - el2:\n'
' - subel\n'
'...\n', conf,
problem=(2, 3))
def test_multi_lines(self): def test_multi_lines(self):
conf = 'indentation: {spaces: 2, indent-sequences: yes}'
self.check('---\n' self.check('---\n'
'long_string: >\n' 'long_string: >\n'
' bla bla blah\n' ' bla bla blah\n'
' blah bla bla\n' ' blah bla bla\n'
'...\n', None) '...\n', conf)
self.check('---\n' self.check('---\n'
'- long_string: >\n' '- long_string: >\n'
' bla bla blah\n' ' bla bla blah\n'
' blah bla bla\n' ' blah bla bla\n'
'...\n', None) '...\n', conf)
self.check('---\n' self.check('---\n'
'obj:\n' 'obj:\n'
' - long_string: >\n' ' - long_string: >\n'
' bla bla blah\n' ' bla bla blah\n'
' blah bla bla\n' ' blah bla bla\n'
'...\n', None) '...\n', conf)
def test_empty_value(self): def test_empty_value(self):
conf = 'indentation: {spaces: 2}' conf = 'indentation: {spaces: 2}'
@ -233,8 +394,23 @@ class IndentationTestCase(RuleTestCase):
'- o:\n' '- o:\n'
' k1: v1\n' ' k1: v1\n'
'...\n', conf, problem=(3, 8)) '...\n', conf, problem=(3, 8))
self.check('---\n'
'- - - - item\n'
' - elem 1\n'
' - elem 2\n'
' - - - - - very nested: a\n'
' key: value\n'
'...\n', conf)
self.check('---\n'
' - - - - item\n'
' - elem 1\n'
' - elem 2\n'
' - - - - - very nested: a\n'
' key: value\n'
'...\n', conf, problem=(2, 2))
def test_return(self): def test_return(self):
conf = 'indentation: {spaces: 2}'
self.check('---\n' self.check('---\n'
'a:\n' 'a:\n'
' b:\n' ' b:\n'
@ -243,19 +419,19 @@ class IndentationTestCase(RuleTestCase):
' e:\n' ' e:\n'
' f:\n' ' f:\n'
'g:\n' 'g:\n'
'...\n', None) '...\n', conf)
self.check('---\n' self.check('---\n'
'a:\n' 'a:\n'
' b:\n' ' b:\n'
' c:\n' ' c:\n'
' d:\n' ' d:\n'
'...\n', None, problem=(5, 4, 'syntax')) '...\n', conf, problem=(5, 4, 'syntax'))
self.check('---\n' self.check('---\n'
'a:\n' 'a:\n'
' b:\n' ' b:\n'
' c:\n' ' c:\n'
' d:\n' ' d:\n'
'...\n', None, problem=(5, 2, 'syntax')) '...\n', conf, problem=(5, 2, 'syntax'))
def test_first_line(self): def test_first_line(self):
conf = ('indentation: {spaces: 2}\n' conf = ('indentation: {spaces: 2}\n'

@ -31,7 +31,7 @@ rules:
max-spaces-after: 1 max-spaces-after: 1
indentation: indentation:
spaces: 2 spaces: 2
# indent-sequences: no indent-sequences: yes
line-length: line-length:
max: 80 max: 80
new-line-at-end-of-file: {level: error} new-line-at-end-of-file: {level: error}

@ -22,7 +22,8 @@ from yamllint.rules.common import is_explicit_key
ID = 'indentation' ID = 'indentation'
TYPE = 'token' TYPE = 'token'
CONF = {'spaces': int} CONF = {'spaces': int,
'indent-sequences': (True, False, 'whatever')}
ROOT, MAP, B_SEQ, F_SEQ, KEY, VAL = range(6) ROOT, MAP, B_SEQ, F_SEQ, KEY, VAL = range(6)
@ -164,16 +165,21 @@ def check(conf, token, prev, next, context):
# yaml.scan()ning this: # yaml.scan()ning this:
# '- lib:\n' # '- lib:\n'
# ' - var\n' # ' - var\n'
if next.start_mark.column == context['stack'][-1].indent: if conf['indent-sequences'] is False:
# key:
# - e1
# - e2
indent = context['stack'][-1].indent indent = context['stack'][-1].indent
else: elif conf['indent-sequences'] is True:
# key:
# - e1
# - e2
indent = context['stack'][-1].indent + conf['spaces'] indent = context['stack'][-1].indent + conf['spaces']
else: # 'whatever'
if next.start_mark.column == context['stack'][-1].indent:
# key:
# - e1
# - e2
indent = context['stack'][-1].indent
else:
# key:
# - e1
# - e2
indent = context['stack'][-1].indent + conf['spaces']
else: else:
# k: # k:
# value # value

Loading…
Cancel
Save