" ___vital___
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
" Do not mofidify the code nor insert new lines before '" ___vital___'
function! s:_SID() abort
  return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
endfunction
execute join(['function! vital#_over#Coaster#Buffer#Object#import() abort', printf("return map({'setbufline_if_python': '', 'setbufline_if_python3': '', 'setbufline_if_ruby': '', 'make': ''}, \"vital#_over#function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
delfunction s:_SID
" ___vital___
scriptencoding utf-8
let s:save_cpo = &cpo
set cpo&vim


let s:obj = {
\	"__variable" : {}
\}


function! s:obj.number()
	return self.__variable.bufnr
endfunction


function! s:obj.invoke(func, ...)
	let args = get(a:, 1, [])
	return call(a:func, [self.number()] + args)
endfunction


function! s:obj.name()
	return self.invoke("bufname")
endfunction


function! s:obj.get_variable(...)
	return self.invoke("getbufvar", a:000)
endfunction


function! s:obj.set_variable(...)
	return self.invoke("setbufvar", a:000)
endfunction


function! s:obj.get_option(name)
	return self.get_variable("&" . a:name)
endfunction


function! s:obj.set_option(name, var)
	return self.set_variable("&" . a:name, a:var)
endfunction


function! s:obj.winnr()
	return self.invoke("bufwinnr")
endfunction


function! s:obj.is_exists()
	return bufexists(self.number())
endfunction


function! s:obj.is_listed()
	return self.invoke("buflisted")
endfunction


function! s:obj.is_loaded()
	return self.invoke("bufloaded")
endfunction


function! s:obj.is_current()
	return self.number() == bufnr("%")
endfunction


function! s:obj.is_modifiable()
	return self.get_option("modifiable")
endfunction


function! s:obj.is_opened_in_current_tabpage()
	return self.winnr() != -1
endfunction


function! s:obj.tap()
	if !self.is_exists() || self.is_tapped()
		return
	endif
	let self.__variable.tap_bufnr = bufnr("%")
	split
	execute "b" self.number()
	return self.number()
endfunction


function! s:obj.untap()
	if !self.is_tapped()
		return
	endif
	quit
	silent! execute "buffer" self.__variable.tap_bufnr
	unlet self.__variable.tap_bufnr
	return self.number()
endfunction


function! s:obj.tap_modifiable(...)
	let force = get(a:, 1, 1)
	if !(self.is_modifiable() || force)
		return
	endif
	let result = self.tap()
	if result
		let self.__variable.modifiable = &modifiable
		set modifiable
	endif
	return result
endfunction


function! s:obj.untap_modifiable()
	if has_key(self.__variable, "modifiable")
		let &modifiable = self.__variable.modifiable
		unlet self.__variable.modifiable
		call self.untap()
	endif
endfunction


function! s:obj.is_tapped()
	return has_key(self.__variable, "tap_bufnr")
endfunction


function! s:obj.execute(cmd)
	if self.is_current()
		execute a:cmd
		return
	endif
	if self.tap()
		try
			execute a:cmd
		finally
			call self.untap()
		endtry
	endif

" 	let view = winsaveview()
" 	try
" 		noautocmd silent! execute "bufdo if bufnr('%') == " a:expr . ' | ' . string(a:cmd) . ' | endif'
" 	finally
" 		noautocmd silent! execute "buffer" bufnr
" 		call winrestview(view)
" 	endtry
endfunction


function! s:setbufline_if_python(expr, lnum, text)
	if len(getbufline(a:expr, 1, "$")) < a:lnum - 1
		return
	endif
	let list = type(a:text) == type([]) ? a:text : [a:text]
	python import vim
	py vim.buffers[int(vim.eval('a:expr'))][int(vim.eval("a:lnum")) - 1 : int(vim.eval("a:lnum")) - 1 + len(vim.eval("list"))] = vim.eval("list")
endfunction


function! s:setbufline_if_python3(expr, lnum, text)
	if len(getbufline(a:expr, 1, "$")) < a:lnum - 1
		return
	endif
	let list = type(a:text) == type([]) ? a:text : [a:text]
	python3 import vim
	py3 vim.buffers[int(vim.eval('a:expr'))][int(vim.eval("a:lnum")) - 1 : int(vim.eval("a:lnum")) - 1 + len(vim.eval("list"))] = vim.eval("list")
endfunction


function! s:setbufline_if_ruby(expr, lnum, text)
	if len(getbufline(a:expr, 1, "$")) < a:lnum - 1
		return
	endif
	let save_op = getbufvar(a:expr, "&buflisted")
	call setbufvar(a:expr, "&buflisted", 1)
	try
		let list = type(a:text) == type([]) ? a:text : [a:text]
		let bufnr = index(filter(range(1, bufnr("$")), "buflisted(v:val)"), bufnr(a:expr))
ruby << EOR
	bufnr = Vim::evaluate("bufnr")
	text = Vim::evaluate("list")
	lnum = Vim::evaluate("a:lnum")
	b = Vim::Buffer[bufnr]
	text.each_with_index {|it, i|
		if b.count < lnum + i
			b.append lnum + i - 1, it.to_s
		else
			b[lnum + i] = it.to_s
		end
	}
EOR
	finally
		let save_op = setbufvar(a:expr, "&buflisted", save_op)
	endtry
endfunction


function! s:obj.setline(lnum, text, ...)
" 	if has("ruby")
" 		return s:setbufline_if_ruby(self.number(), a:lnum, a:text)
" 	endif
	let force = get(a:, 1, 0)
	if self.tap_modifiable(force)
		try
			if exists("*setbufline")
				return setbufline(self.number(), a:lnum, a:text)
			endif

			if has("python")
				return s:setbufline_if_python(self.number(), a:lnum, a:text)
			endif

			if has("python3")
				return s:setbufline_if_python3(self.number(), a:lnum, a:text)
			endif

			call setline(a:lnum, a:text)
		finally
			call self.untap_modifiable()
		endtry
	endif
" 	return self.execute("call setline(" . a:lnum . "," . string(a:text) . ")")
endfunction


function! s:obj.append(lnum, text, ...)
	let force = get(a:, 1, 0)
	if self.tap_modifiable(force)
		try
			call append(a:lnum, a:text)
		finally
			call self.untap_modifiable()
		endtry
	endif
endfunction


function! s:obj.clear(...)
	let force = get(a:, 1, 0)
	if self.tap_modifiable(force)
		try
			silent % delete _
		finally
			call self.untap_modifiable()
		endtry
	endif
endfunction


function! s:obj.getline(...)
	return self.invoke("getbufline", a:000)
endfunction


function! s:obj.line_length()
	return len(getbufline(self.number(), 1, "$"))
endfunction


function! s:obj.open(...)
	let open_cmd = get(a:, 1, "")
	execute open_cmd
	execute "buffer" self.number()
endfunction


function! s:obj.close()
	call self.execute("close")
	call self.delete()
endfunction


function! s:obj.delete(...)
	let force = get(a:, 1, 0)
	if self.is_exists()
		try
			execute "bdelete" . (force ? "! " : " ") . self.number()
			return 0
		catch
			return -1
		endtry
	endif
endfunction


function! s:obj.set_name(name)
	return self.execute(":file " . string(a:name))
endfunction


function! s:make(expr)
	let obj = deepcopy(s:obj)
	let obj.__variable.bufnr = bufnr(a:expr)
	return obj
endfunction



let &cpo = s:save_cpo
unlet s:save_cpo