You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
3.8 KiB
150 lines
3.8 KiB
5 years ago
|
" vim:sw=2:
|
||
|
" ============================================================================
|
||
|
" FileName: resolver.vim
|
||
|
" Author: voldikss <dyzplus@gmail.com>
|
||
|
" GitHub: https://github.com/voldikss
|
||
|
" Description: This is modified from part of skywind3000/asyncrun
|
||
|
" ============================================================================
|
||
|
|
||
|
if has('win32') || has('win64')
|
||
|
let s:is_windows = 1
|
||
|
else
|
||
|
let s:is_windows = 0
|
||
|
endif
|
||
|
|
||
|
" find project root
|
||
|
function! s:find_root(path, markers, strict) abort
|
||
|
function! s:guess_root(filename, markers) abort
|
||
|
let fullname = s:fullname(a:filename)
|
||
|
if exists('b:asyncrun_root')
|
||
|
return b:asyncrun_root
|
||
|
endif
|
||
|
if fullname =~ '^fugitive:/'
|
||
|
if exists('b:git_dir')
|
||
|
return fnamemodify(b:git_dir, ':h')
|
||
|
endif
|
||
|
return '' " skip any fugitive buffers early
|
||
|
endif
|
||
|
let pivot = fullname
|
||
|
if !isdirectory(pivot)
|
||
|
let pivot = fnamemodify(pivot, ':h')
|
||
|
endif
|
||
|
while 1
|
||
|
let prev = pivot
|
||
|
for marker in a:markers
|
||
|
let newname = s:path_join(pivot, marker)
|
||
|
if newname =~ '[\*\?\[\]]'
|
||
|
if glob(newname) != ''
|
||
|
return pivot
|
||
|
endif
|
||
|
elseif filereadable(newname)
|
||
|
return pivot
|
||
|
elseif isdirectory(newname)
|
||
|
return pivot
|
||
|
endif
|
||
|
endfor
|
||
|
let pivot = fnamemodify(pivot, ':h')
|
||
|
if pivot == prev
|
||
|
break
|
||
|
endif
|
||
|
endwhile
|
||
|
return ''
|
||
|
endfunction
|
||
|
let root = s:guess_root(a:path, a:markers)
|
||
|
if root != ''
|
||
|
return s:fullname(root)
|
||
|
elseif a:strict != 0
|
||
|
return ''
|
||
|
endif
|
||
|
" Not found: return parent directory of current file / file itself.
|
||
|
let fullname = s:fullname(a:path)
|
||
|
if isdirectory(fullname)
|
||
|
return fullname
|
||
|
endif
|
||
|
return s:fullname(fnamemodify(fullname, ':h'))
|
||
|
endfunction
|
||
|
|
||
|
" Replace string
|
||
|
function! s:StringReplace(text, old, new) abort
|
||
|
let l:data = split(a:text, a:old, 1)
|
||
|
return join(l:data, a:new)
|
||
|
endfunction
|
||
|
|
||
|
function! s:fullname(f) abort
|
||
|
let f = a:f
|
||
|
if f =~ "'."
|
||
|
try
|
||
|
redir => m
|
||
|
silent exe ':marks' f[1]
|
||
|
redir END
|
||
|
let f = split(split(m, '\n')[-1])[-1]
|
||
|
let f = filereadable(f)? f : ''
|
||
|
catch
|
||
|
let f = '%'
|
||
|
endtry
|
||
|
endif
|
||
|
let f = (f != '%')? f : expand('%')
|
||
|
let f = fnamemodify(f, ':p')
|
||
|
if s:is_windows
|
||
|
let f = substitute(f, "\\", '/', 'g')
|
||
|
endif
|
||
|
if len(f) > 1
|
||
|
let size = len(f)
|
||
|
if f[size - 1] == '/'
|
||
|
let f = strpart(f, 0, size - 1)
|
||
|
endif
|
||
|
endif
|
||
|
return f
|
||
|
endfunction
|
||
|
|
||
|
function! s:path_join(home, name) abort
|
||
|
let l:size = strlen(a:home)
|
||
|
if l:size == 0 | return a:name | endif
|
||
|
let l:last = strpart(a:home, l:size - 1, 1)
|
||
|
if has("win32") || has("win64") || has("win16") || has('win95')
|
||
|
let l:first = strpart(a:name, 0, 1)
|
||
|
if l:first == "/" || l:first == "\\"
|
||
|
let head = strpart(a:home, 1, 2)
|
||
|
if index([":\\", ":/"], head) >= 0
|
||
|
return strpart(a:home, 0, 2) . a:name
|
||
|
endif
|
||
|
return a:name
|
||
|
elseif index([":\\", ":/"], strpart(a:name, 1, 2)) >= 0
|
||
|
return a:name
|
||
|
endif
|
||
|
if l:last == "/" || l:last == "\\"
|
||
|
return a:home . a:name
|
||
|
else
|
||
|
return a:home . '/' . a:name
|
||
|
endif
|
||
|
else
|
||
|
if strpart(a:name, 0, 1) == '/'
|
||
|
return a:name
|
||
|
endif
|
||
|
if l:last == "/"
|
||
|
return a:home . a:name
|
||
|
else
|
||
|
return a:home . '/' . a:name
|
||
|
endif
|
||
|
endif
|
||
|
endfunction
|
||
|
|
||
|
function! floaterm#resolver#get_root() abort
|
||
|
let markers = g:floaterm_rootmarkers
|
||
|
let strict = 0
|
||
|
let l:hr = s:find_root(getcwd(), markers, strict)
|
||
|
if s:is_windows
|
||
|
let l:hr = s:StringReplace(l:hr, '/', "\\")
|
||
|
endif
|
||
|
return l:hr
|
||
|
endfunction
|
||
|
|
||
|
function! floaterm#resolver#chdir(path) abort
|
||
|
if has('nvim')
|
||
|
let cmd = haslocaldir()? 'lcd' : (haslocaldir(-1, 0)? 'tcd' : 'cd')
|
||
|
else
|
||
|
let cmd = haslocaldir()? ((haslocaldir() == 1)? 'lcd' : 'tcd') : 'cd'
|
||
|
endif
|
||
|
silent execute cmd . ' '. fnameescape(a:path)
|
||
|
endfunction
|