howl.editing.formatting

local buffer, editor, cursor
before_each ->
  buffer = Buffer!
  buffer.config.indent = 2
  editor = Editor buffer
  cursor = editor.cursor

ensure_block(editor, block_start_p, block_end_p, end_s)

(when block_start_p does not match)

does nothing and returns false

buffer.text = '{\n}'
cursor.line = 2
assert.is_false formatting.ensure_block editor, 'foo', 'bar', 'bar'
assert.equals '{\n}', buffer.text

(when block_start_p matches)

formats an existing block as necessary

buffer.text = '{\n}'
cursor.line = 2
assert.is_true formatting.ensure_block editor, '{$', '}', '}'
assert.equals '{\n  \n}', buffer.text
assert.equals 2, cursor.line

completes an existing block as necessary

buffer.text = '{\n'
cursor.line = 2
assert.is_true formatting.ensure_block editor, '{$', '}', '}'
assert.equals '{\n  \n}\n', buffer.text
assert.equals 2, cursor.line

is not fooled by subsequent blocks

buffer.text = '{\n\n{\n}'
cursor.line = 2
assert.is_true formatting.ensure_block editor, '{$', '}', '}'
assert.equals '{\n  \n}\n{\n}', buffer.text
assert.equals 2, cursor.line

leaves an already ok indented block alone

buffer.text = '{\n  \n}\n'
cursor.line = 2
assert.is_false formatting.ensure_block editor, '{%s*$', '}', '}'
assert.equals '{\n  \n}\n', buffer.text
assert.equals 2, cursor.line

leaves an already ok non-indented block alone

buffer.text = '{\n\nfoo\n}\n'
cursor.line = 2
assert.is_false formatting.ensure_block editor, '{%s*$', '}', '}'
assert.equals '{\n\nfoo\n}\n', buffer.text
assert.equals 2, cursor.line

leaves blocks with content in them alone

buffer.text = '{\n  \n  foo\n}\n'
for line in *{2, 3}
  cursor.line = line
  assert.is_false formatting.ensure_block editor, '{$', '}', '}'
  assert.equals '{\n  \n  foo\n}\n', buffer.text
  assert.equals line, cursor.line

handles nested blocks

buffer.text = '{\n  {\n\n}\n'
cursor.line = 3
assert.is_true formatting.ensure_block editor, '{$', '}', '}'
assert.equals '{\n  {\n    \n  }\n}\n', buffer.text
assert.equals 3, cursor.line

(.. when block_start_p equals block_end_p)

formats an existing block as necessary

buffer.text = '|\n|'
cursor.line = 2
assert.is_true formatting.ensure_block editor, '|$', '|', '|'
assert.equals '|\n  \n|', buffer.text
assert.equals 2, cursor.line

completes an existing block as necessary

buffer.text = '|\n'
cursor.line = 2
assert.is_true formatting.ensure_block editor, '|$', '|', '|'
assert.equals '|\n  \n|\n', buffer.text
assert.equals 2, cursor.line

leaves an already ok indented block alone

buffer.text = '|\n  \n|\n'
cursor.line = 2
assert.is_false formatting.ensure_block editor, '|$', '|', '|'
assert.equals '|\n  \n|\n', buffer.text
assert.equals 2, cursor.line

leaves an already ok non-indented block alone

buffer.text = '|\n\nfoo\n|\n'
cursor.line = 2
assert.is_false formatting.ensure_block editor, '|$', '|', '|'
assert.equals '|\n\nfoo\n|\n', buffer.text
assert.equals 2, cursor.line

recognizes a previous block if it is all non-blank lines

buffer.text = '|\nfoo\n|\n'
cursor.line = 4
assert.is_false formatting.ensure_block editor, '|$', '|', '|'
assert.equals '|\nfoo\n|\n', buffer.text
assert.equals 4, cursor.line

is not fooled by earlier block ends on the same line

buffer.text = '{\n} {\n'
cursor.line = 3
assert.is_true formatting.ensure_block editor, '{$', '^%s*}', '}'
assert.equals '{\n} {\n  \n}\n', buffer.text
assert.equals 3, cursor.line

(.. indentation & cursor)

indents the new line using the "indent" config variable by default

buffer.config.indent = 4
buffer.text = '{\n'
cursor.line = 2
formatting.ensure_block editor, '{$', '}', '}'
assert.equals '{\n    \n}\n', buffer.text

indents the new line using the editor

buffer.mode = indent: (ed) => ed.current_line.indentation = 5
buffer.text = '{\n'
cursor.line = 2
formatting.ensure_block editor, '{$', '}', '}'
assert.equals '{\n     \n}\n', buffer.text

positions the cursor after the indentation of the new line

buffer.text = '{\n'
cursor.line = 2
assert.is_true formatting.ensure_block editor, '{$', '}', '}'
assert.equals 3, cursor.column