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.
149 lines
3.8 KiB
149 lines
3.8 KiB
" 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
|
|
|