Last active
February 3, 2019 06:19
-
-
Save UrsaDK/06511ed246ff63e2e428 to your computer and use it in GitHub Desktop.
Project structure discovery with Vim & NERDTree
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"" | |
" Return project's root directory | |
" | |
" This function is used to return current projects root directory, as | |
" determined by GIT or SVN, without changing vim's cwd. | |
" | |
" @param string a:1 A comma seperated list of files or directories, the | |
" presence of which can be used to identify the root directory of a project. | |
" | |
function! UmkaDK#GetProjectRoot(...) | |
let l:root_markers = a:0 > 0 ? a:1 : | |
\ 'Vagrant, Makefile, Makefile.PL, Build.PL, composer.json, Gemfile' | |
let l:parent = expand("%:p:h") | |
if executable('git') | |
let l:git_root = system('cd ' . l:parent . ' && git rev-parse --show-toplevel 2>/dev/null') | |
if !v:shell_error | |
return substitute(l:git_root, '\(\n\|\s\)*$', '', '') | |
endif | |
endif | |
if executable('svn') | |
let l:label = 'Working Copy Root Path: ' | |
let l:svn_root = system('cd ' . l:parent . ' && svn info 2>/dev/null | grep "'. l:label . '"') | |
if !v:shell_error | |
let l:svn_root = strpart(l:svn_root, strlen(l:label)) | |
return substitute(l:svn_root, '\(\n\|\s\)*$', '', '') | |
endif | |
endif | |
if !empty(l:root_markers) | |
let l:parent_paths = [ l:parent ] | |
while l:parent_paths[-1] != '/' | |
call add(l:parent_paths, fnamemodify(l:parent_paths[-1], ':h')) | |
endwhile | |
let l:root_markers = substitute(l:root_markers, '^\s*\(.\{-}\)\s*$', '\1', '') | |
let l:root_markers = '{' . join(split(l:root_markers, '\v\s*,\s*'), ',') . '}' | |
let l:markers = globpath(join(l:parent_paths, ','), l:root_markers, 0, 1) | |
if !empty(l:markers) | |
let l:modifier = isdirectory(l:markers[0]) ? ':h:h' : ':h' | |
return fnamemodify(l:markers[0], l:modifier) | |
endif | |
endif | |
endfunction | |
"" | |
" Open NERDTree in a given directory | |
" | |
" This function is used to open NERDTree in a given directory and highlight | |
" current file within in directory's structure. | |
" | |
function! UmkaDK#NERDTreeFind() | |
let l:path = expand("%:p:h") | |
if !exists(":NERDTreeFind") | |
return 0 | |
endif | |
if !exists('b:project_root') || l:path !~ '^' . b:project_root | |
let l:project_root = UmkaDK#GetProjectRoot() | |
if !empty(b:project_root) | |
let b:project_root = l:project_root | |
exec 'NERDTreeToggle ' . b:project_root | |
exec 'NERDTreeClose' | |
endif | |
endif | |
if (!exists('b:project_root') && isdirectory(l:path)) || (b:project_root ==? l:path) | |
exec 'NERDTreeToggle ' . b:project_root | |
else | |
exec 'NERDTreeFind' | |
endif | |
endfunction | |
command! TreeFind call UmkaDK#NERDTreeFind() | |
nmap <silent> <Leader>wd :call UmkaDK#NERDTreeFind<CR> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment