function! targets#target#new(sl, sc, el, ec, error)
return {
\ 'error': a:error,
\ 'sl': a:sl,
\ 'sc': a:sc,
\ 'el': a:el,
\ 'ec': a:ec,
\ 'linewise': 0,
\
\ 'copy': function('targets#target#copy'),
\ 'setS': function('targets#target#setS'),
\ 'setE': function('targets#target#setE'),
\ 's': function('targets#target#s'),
\ 'e': function('targets#target#e'),
\ 'searchposS': function('targets#target#searchposS'),
\ 'searchposE': function('targets#target#searchposE'),
\ 'getcharS': function('targets#target#getcharS'),
\ 'getcharE': function('targets#target#getcharE'),
\ 'getposS': function('targets#target#getposS'),
\ 'getposE': function('targets#target#getposE'),
\ 'cursorS': function('targets#target#cursorS'),
\ 'cursorE': function('targets#target#cursorE'),
\ 'state': function('targets#target#state'),
\ 'range': function('targets#target#range'),
\ 'select': function('targets#target#select'),
\ 'string': function('targets#target#string')
\ }
endfunction
function! targets#target#fromValues(sl, sc, el, ec)
if a:sl == 0 || a:sc == 0 || a:el == 0 || a:ec == 0
return targets#target#withError("zero found")
endif
return targets#target#new(a:sl, a:sc, a:el, a:ec, '')
endfunction
function! targets#target#fromVisualSelection()
let [sl, sc] = getpos("'<")[1:2]
let [el, ec] = getpos("'>")[1:2]
return targets#target#fromValues(sl, sc, el, ec)
endfunction
function! targets#target#withError(error)
return targets#target#new(0, 0, 0, 0, a:error)
endfunction
function! targets#target#copy() dict
return targets#target#fromValues(self.sl, self.sc, self.el, self.ec)
endfunction
function! targets#target#setS(line, column) dict
let [self.sl, self.sc] = [a:line, a:column]
endfunction
function! targets#target#setE(line, column) dict
let [self.el, self.ec] = [a:line, a:column]
endfunction
function! targets#target#s() dict
return [self.sl, self.sc]
endfunction
function! targets#target#e() dict
return [self.el, self.ec]
endfunction
function! targets#target#searchposS(...) dict
let pattern = a:1
let flags = a:0 > 1 ? a:2 : ''
let stopline = a:0 > 2 ? a:3 : 0
let [self.sl, self.sc] = searchpos(pattern, flags, stopline)
endfunction
function! targets#target#searchposE(...) dict
let pattern = a:1
let flags = a:0 > 1 ? a:2 : ''
let stopline = a:0 > 2 ? a:3 : 0
let [self.el, self.ec] = searchpos(pattern, flags, stopline)
endfunction
function! targets#target#getcharS() dict
return getline(self.sl)[self.sc-1]
endfunction
function! targets#target#getcharE() dict
return getline(self.el)[self.ec-1]
endfunction
" args (mark = '.')
function! targets#target#getposS(...) dict
let mark = a:0 > 0 ? a:1 : '.'
let [self.sl, self.sc] = getpos(mark)[1:2]
endfunction
" args (mark = '.')
function! targets#target#getposE(...) dict
let mark = a:0 > 0 ? a:1 : '.'
let [self.el, self.ec] = getpos(mark)[1:2]
endfunction
function! targets#target#cursorS() dict
call cursor(self.s())
endfunction
function! targets#target#cursorE() dict
call cursor(self.e())
endfunction
function! targets#target#state() dict
if self.error != ''
return targets#state#invalid()
endif
if self.sl == 0 || self.el == 0
return targets#state#invalid()
elseif self.sl < self.el
return targets#state#nonempty()
elseif self.sl > self.el
return targets#state#invalid()
elseif self.sc == self.ec + 1
return targets#state#empty()
elseif self.sc > self.ec
return targets#state#invalid()
else
return targets#state#nonempty()
endif
endfunction
function! targets#target#range(cursor, min, max) dict
if self.error != ''
return ''
endif
let positionS = s:position(self.sl, self.sc, a:cursor, a:min, a:max, 'c')
let positionE = s:position(self.el, self.ec, a:cursor, a:min, a:max, 'c')
return positionS . positionE
endfunction
function! s:position(line, column, cursor, min, max, tie)
let cursorLine = a:cursor[1]
if a:line == cursorLine " cursor line
let cursorColumn = a:cursor[2]
if a:column == cursorColumn " same column
return a:tie
elseif a:column < cursorColumn " left of cursor
return 'l'
else " a:column > cursorColumn " right of cursor
return 'r'
endif
elseif a:line < cursorLine
if a:line >= a:min " above on screen
return 'a'
else " above off screen
return 'A'
endif
else " a:line > cursorLine
if a:line <= a:max " below on screen
return 'b'
else " below off screen
return 'B'
endif
endif
endfunction
" visually select the target
function! targets#target#select() dict
call cursor(self.s())
if self.linewise
silent! normal! V
else
silent! normal! v
endif
call cursor(self.e())
endfunction
function! targets#target#string() dict
if self.error != ''
return '[err:' . self.error . ']'
endif
return '[' . self.sl . ' ' . self.sc . '; ' . self.el . ' ' . self.ec . ']'
endfunction