Line objects
local buf, lines
before_each ->
buf = buffer 'hƏllØ\n wØrld\nagain!'
lines = buf.lines
.buffer points to the corresponding buffer
assert.same buf, lines[1].buffer
.nr holds the line number
assert.equal lines[1].nr, 1
.text returns the text of the specified line, sans linebreak
assert.equal lines[1].text, 'hƏllØ'
assert.equal lines[2].text, ' wØrld'
assert.equal lines[3].text, 'again!'
.size is the size of the line, sans linebreak
lines = buffer('åäö\n123\n').lines
assert.equal 6, lines[1].size
assert.equal 3, lines[2].size
tostring(line) gives the same as .text
assert.equal tostring(lines[1]), lines[1].text
.start_pos returns the start position for line
assert.equal lines[2].start_pos, 7
buf.text = ''
assert.equal lines[1].start_pos, 1
.end_pos returns the end position for line, right before the newline
assert.equal 6, lines[1].end_pos
buf.text = ''
assert.equal 1, lines[1].end_pos
buf.text = '1'
assert.equal 2, lines[1].end_pos
.has_eol is true if the line has an EOL
buf.text = 'one\ntwo'
assert.is_true lines[1].has_eol
assert.is_false lines[2].has_eol
.byte_start_pos returns the byte start position for line
buf.text = 'åäö\nwØrld'
assert.equal lines[2].byte_start_pos, 8
buf.text = ''
assert.equal lines[1].byte_start_pos, 1
.byte_end_pos returns the byte end position for line
buf.text = 'åäö\nwØrld'
assert.equal 7, lines[1].byte_end_pos
buf.text = ''
assert.equal 1, lines[1].byte_end_pos
buf.text = '1'
assert.equal 2, lines[1].byte_end_pos
.previous returns the line above this one, or nil if none
assert.equal lines[2].previous, lines[1]
assert.is_nil lines[1].previous
.previous_non_blank returns the first preceding non-blank line, or nil if none
assert.is_nil lines[1].previous_non_blank
assert.equal lines[1], lines[2].previous_non_blank
lines\insert 3, ''
assert.equal lines[2], lines[4].previous_non_blank
.previous_blank returns the first preceding blank line, or nil if none
buf.text = 'one\n\nthree\nfour'
assert.is_nil lines[1].previous_blank
assert.equal lines[2], lines[3].previous_blank
assert.equal lines[2], lines[4].previous_blank
.next returns the line below this one, or nil if none
assert.equal lines[1].next, lines[2]
assert.is_nil lines[3].next
.next_non_blank returns the first succeding non-blank line, or nil if none
assert.is_nil lines[3].next_non_blank
assert.equal lines[3], lines[2].next_non_blank
lines\insert 3, ''
assert.equal lines[4], lines[2].next_non_blank
.next_blank returns the first succeding blank line, or nil if none
buf.text = 'one\n\nthree\nfour'
assert.is_nil lines[3].next_blank
assert.equal lines[2], lines[1].next_blank
.indent() indents the line by <config.indent>
config.indent = 2
buf.lines[1]\indent!
assert.equal ' hƏllØ\n wØrld\nagain!', buf.text
buf.config.indent = 1
buf.lines[3]\indent!
assert.equal ' hƏllØ\n wØrld\n again!', buf.text
#line returns the length of the line
buf.text = 'åäö'
assert.equal #lines[1], 3
lines are equal if they have the same text
lines[2] = 'hƏllØ'
assert.equal lines[1], lines[2]
string methods can be accessed directly on the object
buf.text = 'first line'
line = lines[1]
assert.equal 'fi', line\sub(1,2)
assert.equal 8, (line\find('in'))
assert.equal 'first win', (line\gsub('line', 'win'))
string properties can be accessed directly on the object
assert.is_false lines[1].is_empty
assert.is_false lines[1].is_blank
lines[1] = ''
assert.is_true lines[1].is_empty
assert.is_true lines[1].is_blank
.text = <content>
replaces the line text with <content>
lines[1].text = 'Hola'
assert.equal buf.text, 'Hola\n wØrld\nagain!'
raises an error if <content> is nil
assert.raises 'nil', -> lines[1].text = nil
.indentation
.indentation returns the indentation for the line
assert.equal lines[1].indentation, 0
assert.equal lines[2].indentation, 2
buf = buffer '\tfirst\n \tsecond'
lines = buf.lines
buf.config.tab_width = 3
assert.equal 3, lines[1].indentation
assert.equal 5, lines[2].indentation
.indentation = <nr>
works for empty lines
buf = buffer 'first\n'
lines = buf.lines
buf.config.use_tabs = false
lines[2].indentation = 2
assert.equal 'first\n ', buf.text
(when `use_tabs` is false)
set the indentation for the line to <nr> spaces
buf = buffer 'first\n'
lines = buf.lines
buf.config.use_tabs = false
lines[1].indentation = 8
assert.equal ' first\n', buf.text
(when `use_tabs` is true)
before_each ->
buf.config.use_tabs = true
buf.config.tab_width = 4
squeezes in as many tabs as possible
buf.text = 'first\nsecond'
lines[1].indentation = 5
assert.equal '\t first', lines[1].text
lines[2].indentation = 8
assert.equal '\t\tsecond', lines[2].text
handles lines with existing tabs
buf.text = '\tx'
lines[1].indentation = 8
assert.equal '\t\tx', lines[1].text
(when markers are present in the intentation)
preserves and shifts markers
buf.text = ' abc\n'
buf.markers\add {{
name: 'test'
start_offset: 3
end_offset: 5
}}
line = buf.lines[1]
line.indentation -= 1
assert.same {{name: 'test', start_offset: 2, end_offset: 4}}, buf.markers\for_range(1, #buf)
line.indentation -= 1
assert.same {{name: 'test', start_offset: 1, end_offset: 3}}, buf.markers\for_range(1, #buf)
line.indentation += 2
assert.same {{name: 'test', start_offset: 3, end_offset: 5}}, buf.markers\for_range(1, #buf)
.chunk
a Chunk object for the line, disregarding the newline
buf.text = 'hƏllØ\nbare'
chunk = lines[1].chunk
assert.equal 'Chunk', typeof chunk
assert.equal 'hƏllØ', chunk.text
assert.equal 1, chunk.start_pos
assert.equal 5, chunk.end_pos
chunk = lines[2].chunk
assert.equal 'bare', chunk.text
assert.equal 7, chunk.start_pos
assert.equal 10, chunk.end_pos
respects the buffer eol
buf.text = 'MORE\r\nDOS'
buf.eol = '\r\n'
chunk = lines[1].chunk
assert.equal 'MORE', chunk.text
assert.equal 1, chunk.start_pos
assert.equal 4, chunk.end_pos
is an empty chunk for empty lines
buf.text = '\n'
chunk = lines[1].chunk
assert.equal '', chunk.text
assert.equal 1, chunk.start_pos
assert.equal 0, chunk.end_pos
chunk = lines[2].chunk
assert.equal '', chunk.text
assert.equal 2, chunk.start_pos
assert.equal 1, chunk.end_pos
describe .unindent()
unindents the line by <config.indent>
buf.text = ' first\n second'
config.indent = 2
buf.lines[1]\unindent!
assert.equal buf.text, 'first\n second'
buf.config.indent = 1
buf.lines[2]\unindent!
assert.equal buf.text, 'first\n second'
unindents back to a valid indentation line for uneven indents
buf.text = ' first\n second'
buf.config.indent = 2
buf.lines[1]\unindent!
assert.equal ' first\n second', buf.text
unindents back to zero for a 1-space indent
buf.text = ' first\n second'
buf.config.indent = 2
buf.lines[1]\unindent!
assert.equal 'first\n second', buf.text
replace(i, j, replacement)
replaces the range [i,j] with <replacement>
buf.text = '123\n567'
buf.lines[2]\replace 1, 2, 'x'
buf.lines[1]\replace 1, 1, 'x'
assert.equal 'x23\nx7', buf.text
works with character offsets
buf.text = 'åäö'
buf.lines[1]\replace 2, 2, 'x'
assert.equal 'åxö', buf.text
real_column(column)
before_each ->
buf.config.tab_width = 4
returns the real column index of <column>, accounting for tabs
buf.text = '\tsome text'
assert.equal 2, buf.lines[1]\real_column 5
works with character offsets
buf.text = 'åäö'
assert.equal 2, buf.lines[1]\real_column 2
handles boundary cases correctly
buf.text = '\t56'
line = buf.lines[1]
assert.equal 1, line\real_column 1
assert.equal 4, line\real_column 7
raises an error for out of bounds <column>s
buf.text = '\t56'
line = buf.lines[1]
assert.raises 'column', -> line\real_column 0
returns the last real column if the virtual column overshoots
buf.text = '\t56'
line = buf.lines[1]
assert.equal 4, line\real_column 8
assert.equal 4, line\real_column 9
virtual_column(column)
returns the virtual column, accounting for tabs
buf.config.tab_width = 4
buf.text = '\tsome text after'
assert.equal 5, buf.lines[1]\virtual_column 2
works with character offsets
buf.text = 'åäö'
assert.equal 2, buf.lines[1]\virtual_column 2
handles boundary cases correctly
buf.text = '123'
line = buf.lines[1]
assert.equal 1, line\virtual_column 1
assert.equal 4, line\virtual_column 4
raises an error for out of bounds <column>s
buf.text = '123'
line = buf.lines[1]
assert.raises 'column', -> line\virtual_column 0
assert.raises 'column', -> line\virtual_column 5