├── .gitignore ├── LICENSE ├── README.md ├── after └── plugin │ └── exproject.vim ├── autoload └── exproject.vim ├── doc └── exproject.txt ├── ftdetect └── exproject.vim ├── ftplugin └── exproject.vim ├── plugin └── exproject.vim └── syntax └── exproject.vim /.gitignore: -------------------------------------------------------------------------------- 1 | # mac-osx files 2 | .DS_store 3 | profile 4 | 5 | # visual-studio files 6 | *.ncb 7 | *.suo 8 | *.vcproj.*.user 9 | *.pdb 10 | *.idb 11 | 12 | # xcode files 13 | PLBlocks.framework/* 14 | *.pbxuser 15 | *.mode1v3 16 | *~.nib/ 17 | *.perspective 18 | *.perspectivev3 19 | xcuserdata/ 20 | 21 | # gcc files 22 | *.gch 23 | 24 | # exvim files 25 | *.err 26 | *.exvim 27 | *.vimentry 28 | *.vimproject 29 | .vimfiles.*/ 30 | .exvim.*/ 31 | quick_gen_project_*_autogen.bat 32 | quick_gen_project_*_autogen.sh 33 | 34 | # project files 35 | doc/tags 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 exvim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | - - - 2 | - [Intro](#intro) 3 | - [Requirements](#requirements) 4 | - [Installation](#installation) 5 | - [Install ex-utility](#install-ex-utility) 6 | - [Install ex-project](#install-ex-project) 7 | - [Usage](#usage) 8 | 9 | For more details, check [exVim's Docs: Project Window](http://exvim.github.io/docs/project-window) 10 | 11 | - - - 12 | 13 | # Intro 14 | 15 | ex-project is a file browser focus on your current working directory. It provides a tree view 16 | window and allow you to manipulate folders and files directly in it. 17 | 18 | Many Vim users thought ex-project is yet another NERDTree. But actually they have different scope. 19 | ex-project is more focus on your current project ( or working directory ). It provides folder 20 | and file filter with it and building the whole project tree very fast first time you working the 21 | project. It also allow you create folders, files directly in the tree view window. 22 | 23 | More over that, ex-project can be working with NERDTree seamlessly by its window swapping functions. 24 | 25 | ![ex-project-window](http://exvim.github.io/images/ext/ex-project-window.png) 26 | 27 | ex-project is also a part of [exVim](https://github.com/exvim/main) project. 28 | 29 | ## Requirements 30 | 31 | - Vim 6.0 or higher. 32 | - [exvim/ex-utility](https://github.com/exvim/ex-utility) 33 | 34 | ## Installation 35 | 36 | ### Install ex-utility 37 | 38 | ex-project is written based on [exvim/ex-utility](https://github.com/exvim/ex-utility). This 39 | is the basic library of ex-vim-plugins. Follow the readme file in ex-utility to install it first. 40 | 41 | ### Install ex-project 42 | 43 | ex-project follows the standard runtime path structure, and as such it can 44 | be installed with a variety of plugin managers: 45 | 46 | To install using [Vundle](https://github.com/gmarik/vundle): 47 | 48 | # add this line to your .vimrc file 49 | Bundle 'exvim/ex-project' 50 | 51 | To install using [Pathogen](https://github.com/tpope/vim-pathogen): 52 | 53 | cd ~/.vim/bundle 54 | git clone https://github.com/exvim/ex-project 55 | 56 | To install using [NeoBundle](https://github.com/Shougo/neobundle.vim): 57 | 58 | # add this line to your .vimrc file 59 | NeoBundle 'exvim/ex-project' 60 | 61 | [Download zip file](https://github.com/exvim/ex-project/archive/master.zip): 62 | 63 | cd ~/.vim 64 | unzip ex-project-master.zip 65 | copy all of the files into your ~/.vim directory 66 | 67 | ## Usage 68 | 69 | Open your Vim, type `:EXProject your_project_file.exproject` create your project. 70 | Go to the project window and type `R` to build the project tree. Now you 71 | can start your project! 72 | 73 | More details, check [exVim's Docs: Project-Window Usage](http://exvim.github.io/docs/project-window/) 74 | and `:help exproject` in Vim. 75 | 76 | -------------------------------------------------------------------------------- /after/plugin/exproject.vim: -------------------------------------------------------------------------------- 1 | " ex-project, NERDTree swap 2 | if exists ( ':NERDTreeToggle' ) && exists( ':EXProjectOpen' ) 3 | " ex-project to NERDTree 4 | call exproject#register_hotkey( 100 , 1, '', ":call EXProjectToNERDTree()", 'Switch to NERDTree.' ) 5 | function! EXProjectToNERDTree() 6 | exec 'EXProjectClose' 7 | exec 'NERDTreeToggle' 8 | " exec 'NERDTreeFind' 9 | 10 | if maparg('fc','n') != "" 11 | nunmap fc 12 | endif 13 | nnoremap fc :NERDTreeFind 14 | 15 | if has('gui_running') " the key is only available in gui mode. 16 | if has ('mac') 17 | if maparg('Ø','n') != "" 18 | nunmap Ø 19 | endif 20 | nnoremap Ø :NERDTreeFind:redraw/ 21 | else 22 | if maparg('','n') != "" 23 | nunmap 24 | endif 25 | nnoremap :NERDTreeFind:redraw/ 26 | endif 27 | endif 28 | endfunction 29 | 30 | " NERDTree to ex-project 31 | call NERDTreeAddKeyMap ( { 32 | \ 'key': '', 33 | \ 'callback': 'NERDTreeToEXProject', 34 | \ 'quickhelpText': 'Switch to ex-project', 35 | \ 'scope': 'all' 36 | \ } ) 37 | 38 | function! NERDTreeToEXProject() 39 | exec 'NERDTreeClose' 40 | exec 'EXProjectOpen' 41 | " exec 'EXProjectFind' 42 | 43 | if maparg('fc','n') != "" 44 | nunmap fc 45 | endif 46 | call exproject#register_hotkey( 100, 0, 'fc', ":EXProjectFind", 'Find current edit buffer in project window.' ) 47 | 48 | if has('gui_running') 49 | if has ('mac') 50 | if maparg('Ø','n') != "" 51 | nunmap Ø 52 | endif 53 | call exproject#register_hotkey( 101, 0, 'Ø', ":EXProjectOpen:redraw/", 'Open project window and stay in search mode.' ) 54 | else 55 | if maparg('','n') != "" 56 | nunmap 57 | endif 58 | call exproject#register_hotkey( 101, 0, '', ":EXProjectOpen:redraw/", 'Open project window and stay in search mode.' ) 59 | endif 60 | endif 61 | endfunction 62 | endif 63 | -------------------------------------------------------------------------------- /autoload/exproject.vim: -------------------------------------------------------------------------------- 1 | " variables {{{1 2 | let s:cur_project_file = "" 3 | 4 | let s:file_filters = [] 5 | let s:file_ignore_patterns = [] 6 | let s:folder_filters = [] 7 | let s:folder_filter_include = 1 8 | 9 | let s:zoom_in = 0 10 | let s:keymap = {} 11 | 12 | let s:help_open = 0 13 | let s:help_text_short = [ 14 | \ '" Press for help', 15 | \ '', 16 | \ ] 17 | let s:help_text = s:help_text_short 18 | " }}} 19 | 20 | " internal functions {{{1 21 | 22 | " s:search_for_pattern {{{2 23 | function s:search_for_pattern( linenr, pattern ) 24 | for linenr in range(a:linenr , 1 , -1) 25 | if match( getline(linenr) , a:pattern ) != -1 26 | return linenr 27 | endif 28 | endfor 29 | return 0 30 | endfunction 31 | 32 | " s:getname {{{2 33 | function s:getname( linenr ) 34 | let line = getline(a:linenr) 35 | " let line = substitute(line,'.\{-}\[.\{-}\]\(.\{-}\)','\1','') 36 | let line = substitute(line,'.\{-}-\(\[F\]\)\{0,1}\(.\{-}\)','\2','') 37 | let idx_end_1 = stridx(line,' {') 38 | let idx_end_2 = stridx(line,' }') 39 | if idx_end_1 != -1 40 | let line = strpart(line,0,idx_end_1) 41 | elseif idx_end_2 != -1 42 | let line = strpart(line,0,idx_end_2) 43 | endif 44 | return line 45 | endfunction 46 | 47 | " s:getpath {{{2 48 | " Desc: Get the full path of the line, by YJR 49 | function s:getpath( linenr ) 50 | let foldlevel = s:getfoldlevel(a:linenr) 51 | let fullpath = "" 52 | 53 | " recursively make full path 54 | if match(getline(a:linenr),'[^^]-\C\[F\]') != -1 55 | let fullpath = s:getname( a:linenr ) 56 | endif 57 | 58 | let level_pattern = repeat('.',foldlevel-1) 59 | let searchpos = a:linenr 60 | while foldlevel > 1 " don't parse level:0 61 | let foldlevel -= 1 62 | let level_pattern = repeat('.',foldlevel*2) 63 | let fold_pattern = '^'.level_pattern.'-\C\[F\]' 64 | let searchpos = s:search_for_pattern(searchpos , fold_pattern) 65 | if searchpos 66 | let fullpath = s:getname(searchpos).'/'.fullpath 67 | else 68 | call ex#warning('Fold not found') 69 | break 70 | endif 71 | endwhile 72 | 73 | return fullpath 74 | endfunction 75 | 76 | " s:getfoldlevel {{{2 77 | function s:getfoldlevel(linenr) 78 | let curline = getline(a:linenr) 79 | let curline = strpart(curline,0,strridx(curline,'|')+1) 80 | let str_len = strlen(curline) 81 | return str_len/2 82 | endfunction 83 | 84 | " s:set_level_list {{{2 85 | function s:set_level_list( linenr ) 86 | " clean the list 87 | let s:level_list = [] 88 | 89 | let cur_line = getline(a:linenr+1) 90 | let idx = strridx(cur_line, '|') -2 91 | let cur_line = strpart(cur_line, 1, idx) 92 | 93 | let len = strlen(cur_line) 94 | let idx = 0 95 | while idx <= len 96 | if cur_line[idx] == '|' 97 | silent call add( s:level_list, {'is_last':0,'short_dir':''} ) 98 | else 99 | silent call add( s:level_list, {'is_last':1,'short_dir':''} ) 100 | endif 101 | let idx += 2 102 | endwhile 103 | endfunction 104 | 105 | " s:sort_filename {{{2 106 | function s:sort_filename( i1, i2 ) 107 | return a:i1 ==? a:i2 ? 0 : a:i1 >? a:i2 ? 1 : -1 108 | endfunction 109 | 110 | " s:build_tree {{{2 111 | function s:build_tree( entry_path, file_pattern, file_ignore_pattern, folder_pattern, folder_filter_include, included ) 112 | " show progress 113 | " echon ex#short_message( 'processing: ' . fnamemodify(a:entry_path, ':p:.') ) . "\r" 114 | 115 | " get short_dir 116 | " let short_dir = strpart( a:entry_path, strridx(a:entry_path,'\')+1 ) 117 | let included = a:included 118 | let short_dir = fnamemodify( a:entry_path, ':t' ) 119 | let is_dir = isdirectory(a:entry_path) 120 | 121 | let level_list_len = len(s:level_list) 122 | let is_rootfile = (level_list_len == 1 && is_dir == 0) || level_list_len == 0 123 | 124 | " if directory 125 | if is_dir == 1 126 | " split the first level to file_list 127 | let file_list = split(globpath(a:entry_path,'*'),'\n') " NOTE, globpath('.','.*') will show hidden folder 128 | let inc_list = [] 129 | silent call sort( file_list, function('s:sort_filename') ) 130 | 131 | " sort and filter the list as we want (file|dir ) 132 | let list_idx = 0 133 | let list_last = len(file_list)-1 134 | let list_count = 0 135 | while list_count <= list_last 136 | " remove not fit file types 137 | if isdirectory(file_list[list_idx]) == 0 138 | let suffix = fnamemodify ( file_list[list_idx], ':e' ) 139 | if suffix == '' 140 | let suffix = '__EMPTY__' 141 | endif 142 | let filename = fnamemodify ( file_list[list_idx], ':t' ) 143 | " move the file to the end of the list 144 | 145 | if (a:file_ignore_pattern == "" || match ( filename, a:file_ignore_pattern) == -1) && match ( suffix, a:file_pattern ) != -1 146 | let file = remove(file_list,list_idx) 147 | silent call add(file_list, file) 148 | else " if not found file type in file filter 149 | silent call remove(file_list,list_idx) 150 | endif 151 | let list_idx -= 1 152 | 153 | elseif a:folder_pattern != '' " remove not fit dirs 154 | " if folder filter mode is exclude 155 | if a:folder_filter_include == 0 156 | if match( file_list[list_idx], a:folder_pattern ) != -1 157 | silent call remove(file_list,list_idx) 158 | let list_idx -= 1 159 | endif 160 | endif 161 | 162 | " DISABLE: in our case, globpath never search hidden folder. { 163 | " elseif len (s:level_list) == 0 " in first level directory, if we .vimfiles* folders, remove them 164 | " if match( file_list[list_idx], '\<.vimfiles.*' ) != -1 165 | " silent call remove(file_list,list_idx) 166 | " let list_idx -= 1 167 | " endif 168 | " } DISABLE end 169 | endif 170 | 171 | " 172 | let list_idx += 1 173 | let list_count += 1 174 | endwhile 175 | 176 | silent call add(s:level_list, {'is_last':0,'short_dir':short_dir}) 177 | " recuseve browse list 178 | let list_last = len(file_list)-1 179 | let list_idx = list_last 180 | let s:level_list[len(s:level_list)-1].is_last = 1 181 | while list_idx >= 0 182 | if list_idx != list_last 183 | let s:level_list[len(s:level_list)-1].is_last = 0 184 | endif 185 | 186 | let child_included = a:included 187 | 188 | " if folder filter mode is include and we are not included 189 | if a:folder_pattern != '' && a:folder_filter_include && child_included == 0 190 | if match( file_list[list_idx], a:folder_pattern ) != -1 191 | let child_included = 1 192 | endif 193 | endif 194 | 195 | " if the folder is empty or the folder/file is not added by filter 196 | if s:build_tree( 197 | \ file_list[list_idx], 198 | \ a:file_pattern, 199 | \ a:file_ignore_pattern, 200 | \ a:folder_pattern, 201 | \ a:folder_filter_include, 202 | \ child_included 203 | \ ) == 1 204 | silent call remove(file_list,list_idx) 205 | let list_last = len(file_list)-1 206 | else 207 | let included = 1 208 | endif 209 | 210 | let list_idx -= 1 211 | endwhile 212 | 213 | silent call remove( s:level_list, len(s:level_list)-1 ) 214 | 215 | if len(file_list) == 0 216 | return 1 217 | endif 218 | endif 219 | 220 | " write space 221 | let space = '' 222 | let list_idx = 0 223 | let list_last = len(s:level_list)-1 224 | for level in s:level_list 225 | if level.is_last != 0 && list_idx != list_last 226 | let space = space . ' ' 227 | else 228 | let space = space . ' |' 229 | endif 230 | let list_idx += 1 231 | endfor 232 | let space = space.'-' 233 | 234 | " get end_fold 235 | let end_fold = '' 236 | let rev_list = reverse(copy(s:level_list)) 237 | for level in rev_list 238 | if level.is_last != 0 239 | let end_fold = end_fold . ' }' 240 | else 241 | break 242 | endif 243 | endfor 244 | 245 | " 246 | if is_rootfile == 0 && a:folder_pattern != '' && a:folder_filter_include == 1 && included == 0 247 | return 1 248 | endif 249 | 250 | " judge if it is a dir 251 | if is_dir == 0 252 | " if file_end enter a new line for it 253 | if end_fold != '' 254 | let end_space = strpart(space,0,strridx(space,'-')-1) 255 | let end_space = strpart(end_space,0,strridx(end_space,'|')+1) 256 | silent put! = end_space " . end_fold 257 | endif 258 | 259 | " put it 260 | " let file_type = strpart( short_dir, strridx(short_dir,'.')+1, 1 ) 261 | let file_type = strpart( fnamemodify( short_dir, ":e" ), 0, 1 ) 262 | " silent put! = space.'['.file_type.']'.short_dir . end_fold 263 | silent put! = space.short_dir . end_fold 264 | return 0 265 | else 266 | "silent put = strpart(space, 0, strridx(space,'\|-')+1) 267 | if len(file_list) == 0 " if it is a empty directory 268 | if end_fold == '' 269 | " if dir_end enter a new line for it 270 | let end_space = strpart(space,0,strridx(space,'-')) 271 | else 272 | " if dir_end enter a new line for it 273 | let end_space = strpart(space,0,strridx(space,'-')-1) 274 | let end_space = strpart(end_space,0,strridx(end_space,'|')+1) 275 | endif 276 | let end_fold = end_fold . ' }' 277 | silent put! = end_space 278 | silent put! = space.'[F]'.short_dir . ' {' . end_fold 279 | else 280 | silent put! = space.'[F]'.short_dir . ' {' 281 | endif 282 | endif 283 | 284 | return 0 285 | endfunction 286 | 287 | " }}}1 288 | 289 | " functions {{{1 290 | 291 | " exproject#bind_mappings {{{2 292 | function exproject#bind_mappings() 293 | call ex#keymap#bind( s:keymap ) 294 | endfunction 295 | 296 | " exproject#register_hotkey {{{2 297 | function exproject#register_hotkey( priority, local, key, action, desc ) 298 | call ex#keymap#register( s:keymap, a:priority, a:local, a:key, a:action, a:desc ) 299 | endfunction 300 | 301 | " exproject#toggle_help {{{2 302 | 303 | " s:update_help_text {{{2 304 | function s:update_help_text() 305 | if s:help_open 306 | let s:help_text = ex#keymap#helptext(s:keymap) 307 | else 308 | let s:help_text = s:help_text_short 309 | endif 310 | endfunction 311 | 312 | function exproject#toggle_help() 313 | if !g:ex_project_enable_help 314 | return 315 | endif 316 | 317 | let s:help_open = !s:help_open 318 | silent exec '1,' . len(s:help_text) . 'd _' 319 | call s:update_help_text() 320 | silent call append ( 0, s:help_text ) 321 | silent keepjumps normal! gg 322 | call ex#hl#clear_confirm() 323 | endfunction 324 | 325 | " exproject#open {{{2 326 | function exproject#open(filename) 327 | " if the filename is empty, use default project file 328 | let filename = a:filename 329 | if filename == "" 330 | let filename = g:ex_project_file 331 | endif 332 | 333 | " if we open a different project, close the old one first. 334 | if filename !=# s:cur_project_file 335 | if s:cur_project_file != "" 336 | let winnr = bufwinnr(s:cur_project_file) 337 | if winnr != -1 338 | call ex#window#close(winnr) 339 | endif 340 | endif 341 | 342 | " reset project filename and title. 343 | let s:cur_project_file = a:filename 344 | endif 345 | 346 | " open and goto the window 347 | call exproject#open_window() 348 | endfunction 349 | 350 | " exproject#open_window {{{2 351 | 352 | function exproject#init_buffer() 353 | " NOTE: ex-project window open can happen during VimEnter. According to 354 | " Vim's documentation, event such as BufEnter, WinEnter will not be triggered 355 | " during VimEnter. 356 | " When I open exproject window and read the file through vimentry scripts, 357 | " the events define in exproject/ftdetect/exproject.vim will not execute. 358 | " I guess this is because when you are in BufEnter event( the .vimentry 359 | " enters ), and open the other buffers, the Vim will not trigger other 360 | " buffers' event 361 | " This is why I set the filetype manually here. 362 | set filetype=exproject 363 | augroup exproject 364 | au! BufWinLeave call on_close() 365 | augroup END 366 | 367 | if line('$') <= 1 && g:ex_project_enable_help 368 | silent call append ( 0, s:help_text ) 369 | silent exec '$d' 370 | else 371 | silent loadview 372 | endif 373 | endfunction 374 | 375 | function s:on_close() 376 | let s:zoom_in = 0 377 | let s:help_open = 0 378 | silent mkview 379 | 380 | " go back to edit buffer 381 | call ex#window#goto_edit_window() 382 | endfunction 383 | 384 | function exproject#open_window() 385 | let winnr = winnr() 386 | if ex#window#check_if_autoclose(winnr) 387 | call ex#window#close(winnr) 388 | endif 389 | call ex#window#goto_edit_window() 390 | 391 | if s:cur_project_file == "" 392 | let s:cur_project_file = g:ex_project_file 393 | endif 394 | 395 | let winnr = bufwinnr(s:cur_project_file) 396 | if winnr == -1 397 | call ex#window#open( 398 | \ s:cur_project_file, 399 | \ g:ex_project_winsize, 400 | \ g:ex_project_winpos, 401 | \ 0, 402 | \ 1, 403 | \ function('exproject#init_buffer') 404 | \ ) 405 | else 406 | exe winnr . 'wincmd w' 407 | endif 408 | endfunction 409 | 410 | " exproject#toggle_window {{{2 411 | function exproject#toggle_window() 412 | let result = exproject#close_window() 413 | if result == 0 414 | call exproject#open_window() 415 | endif 416 | endfunction 417 | 418 | " exproject#close_window {{{2 419 | function exproject#close_window() 420 | if s:cur_project_file != "" 421 | let winnr = bufwinnr(s:cur_project_file) 422 | if winnr != -1 423 | call ex#window#close(winnr) 424 | return 1 425 | endif 426 | endif 427 | return 0 428 | endfunction 429 | 430 | " exproject#toggle_zoom {{{2 431 | function exproject#toggle_zoom() 432 | if s:cur_project_file != "" 433 | let winnr = bufwinnr(s:cur_project_file) 434 | if winnr != -1 435 | if s:zoom_in == 0 436 | let s:zoom_in = 1 437 | call ex#window#resize( winnr, g:ex_project_winpos, g:ex_project_winsize_zoom ) 438 | else 439 | let s:zoom_in = 0 440 | call ex#window#resize( winnr, g:ex_project_winpos, g:ex_project_winsize ) 441 | endif 442 | endif 443 | endif 444 | endfunction 445 | 446 | " exproject#on_save {{{2 447 | function exproject#on_save() 448 | if s:help_open 449 | let cursor_line = line('.') 450 | let cursor_col = col('.') 451 | let cursor_line = cursor_line - (len(s:help_text) - len(s:help_text_short)) 452 | 453 | call exproject#toggle_help() 454 | 455 | silent call cursor(cursor_line,cursor_col) 456 | silent normal! zz 457 | endif 458 | endfunction 459 | 460 | " exproject#foldtext {{{2 461 | " This functions used in ftplugin/exproject.vim for 'setlocal foldtext=' 462 | function exproject#foldtext() 463 | let line = getline(v:foldstart) 464 | let line = substitute(line,'\[F\]\(.\{-}\) {.*','\[+\]\1 ','') 465 | return line 466 | endfunction 467 | 468 | " exproject#confirm_select {{{2 469 | " modifier: '' or 'shift' 470 | function exproject#confirm_select(modifier) 471 | " check if the line is valid file line 472 | let curline = getline('.') 473 | if match(curline, '-\(\C\[.*\]\)\{0,1}') == -1 474 | call ex#warning('Please select a folder/file') 475 | return 476 | endif 477 | 478 | let editcmd = 'e' 479 | if a:modifier == 'shift' 480 | let editcmd = 'bel sp' 481 | endif 482 | 483 | " initial variable 484 | let cursor_line = line('.') 485 | let cursor_col = col('.') 486 | 487 | " if this is a fold, do fold operation or open the path by terminal 488 | if foldclosed('.') != -1 || match(curline, '\C\[F\]') != -1 489 | if a:modifier == 'shift' 490 | call ex#os#open(s:getpath(cursor_line)) 491 | else 492 | normal! za 493 | endif 494 | return 495 | endif 496 | 497 | let fullpath = s:getpath(cursor_line) . s:getname(cursor_line) 498 | 499 | silent call cursor(cursor_line,cursor_col) 500 | 501 | " simplify the file name 502 | let fullpath = fnamemodify( fullpath, ':p' ) 503 | let fullpath = fnameescape(fullpath) 504 | 505 | " switch filetype 506 | let filetype = fnamemodify( fullpath, ':e' ) 507 | if filetype == 'err' 508 | " TODO: 509 | " call ex#hint('load quick fix list: ' . fullpath) 510 | " call exUtility#GotoPluginBuffer() 511 | " silent exec 'QF '.fullpath 512 | " " NOTE: when open error by QF, we don't want to exec exUtility#OperateWindow below ( we want keep stay in the exQF plugin ), so return directly 513 | return 514 | elseif filetype == 'exe' 515 | " TODO: 516 | " call ex#hint('debug ' . fullpath) 517 | " call exUtility#GotoEditBuffer() 518 | " call exUtility#Debug( fullpath ) 519 | return 520 | else " default 521 | " put the edit file 522 | call ex#hint(fnamemodify(fullpath, ':p:.')) 523 | 524 | " zoom out project before we goto edit window 525 | if s:zoom_in == 1 526 | call exproject#toggle_zoom() 527 | endif 528 | 529 | " goto edit window 530 | call ex#window#goto_edit_window() 531 | 532 | " TODO: we need to findfile, finddir, if both not exists, warning user. 533 | 534 | " do not open again if the current buffer is the file to be opened 535 | if fnamemodify(expand('%'),':p') != fnamemodify(fullpath,':p') 536 | silent exec editcmd.' '.fullpath 537 | endif 538 | endif 539 | endfunction 540 | 541 | " exproject#build_tree {{{2 542 | function exproject#build_tree() 543 | let s:level_list = [] " init level list 544 | 545 | " get entry dir 546 | let entry_dir = getcwd() 547 | if exists('g:ex_cwd') 548 | let entry_dir = g:ex_cwd 549 | endif 550 | 551 | echon 'Creating ex_project: ' . entry_dir . "\r" 552 | silent exec '1,$d _' 553 | 554 | " start tree building 555 | let file_filter_pattern = ex#pattern#last_words(s:file_filters) 556 | let folder_filter_patern = ex#pattern#last_words(s:folder_filters) 557 | let file_ignore_pattern = ex#pattern#files(s:file_ignore_patterns) 558 | call s:build_tree( 559 | \ entry_dir, 560 | \ file_filter_pattern, 561 | \ file_ignore_pattern, 562 | \ folder_filter_patern, 563 | \ s:folder_filter_include, 564 | \ 0, 565 | \ ) 566 | 567 | silent keepjumps normal! gg 568 | 569 | " add online help 570 | if g:ex_project_enable_help 571 | silent call append ( 0, s:help_text ) 572 | endif 573 | 574 | " save the build 575 | silent exec 'w!' 576 | echon 'ex_project: ' . entry_dir . ' created!' . "\r" 577 | endfunction 578 | 579 | " exproject#find_current_edit {{{2 580 | function exproject#find_current_edit( focus ) 581 | " first jump to edit window 582 | call ex#window#goto_edit_window() 583 | 584 | " get current buffer name then jump 585 | let bufname = bufname('%') 586 | let cur_filename = fnamemodify(bufname, ':t') 587 | let cur_filepath = fnamemodify(bufname, ':p') 588 | 589 | " go to the project window 590 | call exproject#open_window() 591 | 592 | " store position if we don't find, restore to the position 593 | let cursor_line = line ('.') 594 | let cursor_col = col ('.') 595 | 596 | " now go to the top start search 597 | silent normal gg 598 | 599 | " process search 600 | let found = 0 601 | while !found 602 | if search( cur_filename, 'W' ) > 0 603 | let linenr = line ('.') 604 | let searchfilename = s:getpath(linenr) . s:getname(linenr) 605 | if fnamemodify(searchfilename , ':p') == cur_filepath 606 | silent call cursor(linenr, 0) 607 | 608 | " unfold the line if it's folded 609 | silent normal! zv 610 | 611 | " if find, set the text line in the middel of the window 612 | silent normal! zz 613 | 614 | " 615 | let found = 1 616 | echon 'Locate file: ' . bufname . "\r" 617 | break 618 | endif 619 | 620 | " if file not found, warning and back to edit window regardless a:focus 621 | else 622 | silent call cursor ( cursor_line, cursor_col ) 623 | call ex#warning('File not found: ' . fnamemodify(cur_filepath, ':p:.') ) 624 | call ex#window#goto_edit_window() 625 | return 626 | endif 627 | endwhile 628 | 629 | " back to edit buffer if needed 630 | if !a:focus 631 | call ex#window#goto_edit_window() 632 | endif 633 | endfunction 634 | 635 | " exproject#refresh_current_folder {{{2 636 | function exproject#refresh_current_folder() 637 | let s:level_list = [] " init level list 638 | 639 | " if the line is neither a file/folder line nor a root folder line, return 640 | let file_line = getline('.') 641 | if match(file_line, '\( |\)\+-\{0,1}.*') == -1 && match(file_line, '-\C\[F\]') == -1 642 | call ex#warning( "Please select a file/folder for refresh" ) 643 | return 644 | endif 645 | 646 | " if fold, open it else if not a file return 647 | if foldclosed('.') != -1 648 | normal! zr 649 | endif 650 | 651 | " initial variable 652 | let fold_level = s:getfoldlevel(line('.')) 653 | let fold_level -= 1 654 | let level_pattern = repeat('.',fold_level*2) 655 | let full_path_name = '' 656 | let fold_pattern = '^'.level_pattern.'-\C\[F\]' 657 | 658 | " get first fold name 659 | if match(file_line, '\C\[F\]') == -1 660 | if search(fold_pattern,'b') 661 | let full_path_name = s:getname(line('.')) 662 | else 663 | call ex#warning('The project may broke, fold pattern not found: ' . fold_pattern) 664 | return 665 | endif 666 | else 667 | let full_path_name = s:getname(line('.')) 668 | let fold_level += 1 669 | endif 670 | let short_dir = full_path_name 671 | 672 | " fold_level 0 will not set path name 673 | if fold_level == 0 674 | let full_path_name = '' 675 | endif 676 | 677 | " save the position 678 | let cursor_line = line('.') 679 | let cursor_col = col('.') 680 | 681 | " recursively make full path 682 | let is_root = 0 683 | if fold_level == 0 684 | let is_root = 1 685 | else 686 | while fold_level > 1 687 | let fold_level -= 1 688 | let level_pattern = repeat('.',fold_level*2) 689 | let fold_pattern = '^'.level_pattern.'-\C\[F\]' 690 | if search(fold_pattern,'b') 691 | let full_path_name = s:getname(line('.')).'/'.full_path_name 692 | else 693 | call ex#warning('The project may broke, fold pattern not found: ' . fold_pattern) 694 | break 695 | endif 696 | endwhile 697 | endif 698 | silent call cursor(cursor_line,cursor_col) 699 | 700 | " simplify the file name 701 | let full_path_name = fnamemodify( full_path_name, ':p' ) 702 | " do not escape, or the directory with white-space can't be found 703 | "let full_path_name = fnameescape(simplify(full_path_name)) 704 | let full_path_name = strpart( full_path_name, 0, strlen(full_path_name)-1 ) 705 | echon "ex-project: Refresh folder: " . full_path_name . "\r" 706 | 707 | " set level list if not the root dir 708 | if is_root == 0 709 | call s:set_level_list(line('.')) 710 | endif 711 | " delete the whole fold 712 | silent exec "normal! zc" 713 | silent exec 'normal! "_2dd' 714 | 715 | " start broswing 716 | let file_filter_pattern = ex#pattern#last_words(s:file_filters) 717 | let folder_filter_patern = ex#pattern#last_words(s:folder_filters) 718 | let file_ignore_pattern = ex#pattern#files(s:file_ignore_patterns) 719 | call s:build_tree( 720 | \ full_path_name, 721 | \ file_filter_pattern, 722 | \ file_ignore_pattern, 723 | \ folder_filter_patern, 724 | \ s:folder_filter_include, 725 | \ 1 726 | \ ) 727 | 728 | " at the end, we need to rename the folder as simple one rename the folder 729 | let cur_line = getline('.') 730 | 731 | " if this is a empty directory, return 732 | let pattern = '\C\[F\].*\<' . short_dir . '\> {' 733 | if match(cur_line, pattern) == -1 734 | call ex#warning ('The folder is empty') 735 | return 736 | endif 737 | 738 | let idx_start = stridx(cur_line, ']') 739 | let start_part = strpart(cur_line,0,idx_start+1) 740 | 741 | let idx_end = stridx(cur_line, ' {') 742 | let end_part = strpart(cur_line,idx_end) 743 | 744 | silent call setline('.', start_part . short_dir . end_part) 745 | 746 | " save the changes 747 | silent exec 'w!' 748 | echon "ex-project: Refresh folder: " . full_path_name . " done!\r" 749 | endfunction 750 | 751 | " exproject#set_file_filters {{{2 752 | function exproject#set_file_filters( filters ) 753 | let s:file_filters = copy(a:filters) 754 | endfunction 755 | 756 | " exproject#set_file_ignore_patterns {{{2 757 | function exproject#set_file_ignore_patterns( patterns ) 758 | let s:file_ignore_patterns = copy(a:patterns) 759 | endfunction 760 | 761 | " exproject#set_folder_filters {{{2 762 | function exproject#set_folder_filters( filters ) 763 | let s:folder_filters = copy(a:filters) 764 | endfunction 765 | 766 | " exproject#set_folder_filter_mode {{{2 767 | function exproject#set_folder_filter_mode( mode ) 768 | let s:folder_filter_include = (a:mode == 'include') 769 | endfunction 770 | 771 | " exproject#newfile {{{2 772 | function exproject#newfile() 773 | " check if the line is valid file line 774 | let cur_line = getline('.') 775 | if match(cur_line, '\( |\)\+-.*') == -1 776 | call ex#warning ("Can't create new file here. Please move your cursor to a file or a folder.") 777 | return 778 | endif 779 | 780 | let reg_t = @t 781 | if foldclosed('.') != -1 782 | silent exec 'normal! j"tyy"t2p$a-' 783 | return 784 | endif 785 | 786 | " if this is directory 787 | if match(cur_line, '\C\[F\]') != -1 788 | let idx = stridx(cur_line, '}') 789 | if idx == -1 790 | silent exec 'normal! j"tyy"tP' 791 | silent call search('|-', 'c') 792 | silent exec 'normal! c$|-' 793 | silent exec 'startinsert!' 794 | else 795 | let surfix = strpart(cur_line,idx-1) 796 | silent call setline('.',strpart(cur_line,0,idx-1)) 797 | let file_line = strpart(cur_line, 0, stridx(cur_line,'-')) . " |-" . surfix 798 | put = file_line 799 | silent call search(' }', 'c') 800 | silent exec 'startinsert' 801 | endif 802 | " if this is file 803 | else 804 | let idx = stridx(cur_line, '}') 805 | if idx == -1 806 | silent exec 'normal! "tyyj"tP' 807 | silent call search('|-','c') 808 | silent exec 'normal! c$|-' 809 | silent exec 'startinsert!' 810 | else 811 | let surfix = strpart(cur_line,idx-1) 812 | silent call setline('.',strpart(cur_line,0,idx-1)) 813 | let file_line = strpart(cur_line, 0, stridx(cur_line,'-')) . "-" . surfix 814 | put = file_line 815 | silent call search(' }','c') 816 | silent exec 'startinsert' 817 | endif 818 | endif 819 | let @t = reg_t 820 | endfunction 821 | 822 | " exproject#newfolder {{{2 823 | function exproject#newfolder() 824 | " check if the line is valid folder line 825 | let cur_line = getline('.') 826 | if match(cur_line, '\C\[F\]') == -1 827 | call ex#warning ("Can't create new folder here, Please move your cursor to a parent folder.") 828 | return 829 | endif 830 | 831 | " let foldername = inputdialog( 'Folder Name: ', '' ) 832 | silent echohl Question 833 | let foldername = input( 'Folder Name: ', '' ) 834 | silent echohl none 835 | 836 | if foldername == '' 837 | call ex#warning ("Can't create empty folder.") 838 | return 839 | else 840 | let path = s:getpath(line('.')) 841 | if finddir( foldername, path ) != '' 842 | call ex#warning (" The folder " . foldername . " already exists!" ) 843 | return 844 | endif 845 | 846 | if path == '' 847 | let path = '.' 848 | endif 849 | call mkdir( path . '/' . foldername ) 850 | call ex#hint ( " created!" ) 851 | endif 852 | 853 | let reg_t = @t 854 | if foldclosed('.') != -1 855 | silent exec 'normal! j"tyy"t2p$a-[F]' . foldername . ' { }' 856 | return 857 | endif 858 | 859 | let idx = stridx(cur_line, '}') 860 | if idx == -1 861 | let file_line = cur_line 862 | put = file_line 863 | silent call search('-\[F\]','c') 864 | silent exec 'normal! c$ |-[F]' . foldername . ' { }' 865 | else 866 | let surfix = strpart(cur_line,idx-1) 867 | silent call setline('.',strpart(cur_line,0,idx-1)) 868 | let file_line = strpart(cur_line, 0, stridx(cur_line,'-')) 869 | \ . ' |-[F]' 870 | \ . foldername 871 | \ . ' { }' 872 | \ . surfix 873 | put = file_line 874 | endif 875 | 876 | let @t = reg_t 877 | endfunction 878 | 879 | " exproject#cursor_jump {{{2 880 | function exproject#cursor_jump ( search_pattern, search_direction ) 881 | let save_cursor = getpos(".") 882 | 883 | " get search flags, also move cursors 884 | let search_flags = '' 885 | if a:search_direction == 'up' 886 | let search_flags = 'bW' 887 | silent exec 'normal ^' 888 | else 889 | let search_flags = 'W' 890 | silent exec 'normal $' 891 | endif 892 | 893 | " jump to error,warning pattern 894 | let jump_line = search(a:search_pattern, search_flags ) 895 | if jump_line == 0 896 | silent call setpos(".", save_cursor) 897 | endif 898 | endfunction 899 | 900 | " }}}1 901 | 902 | " vim:ts=4:sw=4:sts=4 et fdm=marker: 903 | -------------------------------------------------------------------------------- /doc/exproject.txt: -------------------------------------------------------------------------------- 1 | *exproject.txt* A file browser focus on your current working directory. 2 | 3 | Author: Johnny Wu 4 | Licence: MIT licence 5 | Homepage: http://exvim.github.io/ 6 | Version: 0.1.0 7 | 8 | ============================================================================== 9 | Contents *exproject* *exproject-contents* 10 | 11 | 1. Intro ........................... |exproject-intro| 12 | 2. Requirements .................... |exproject-requirements| 13 | 3. Usage ........................... |exproject-usage| 14 | Commands ...................... |exproject-commands| 15 | Key mappings .................. |exproject-mappings| 16 | 4. Configuration ................... |exproject-configuration| 17 | Highlight colours ............. |exproject-highlighting| 18 | 5. Functions ....................... |exproject-functions| 19 | 6. Troubleshooting & Known issues .. |exproject-issues| 20 | 7. History ......................... |exproject-history| 21 | 22 | ============================================================================== 23 | 1. Intro *exproject-intro* 24 | 25 | ex-project is a file browser focus on your current working directory. 26 | It provides a tree view window and allow you to manipulate folders and files 27 | directly in it. 28 | 29 | Many Vim users thought ex-project is yet another NERDTree. But actually they 30 | have different scope. ex-project is more focus on your current project 31 | ( or working directory ). It provides folder and file filter with it and 32 | building the whole project tree very fast first time you working the project. 33 | It also allow you create folders, files directly in the tree view window. 34 | 35 | More over that, ex-project can be working with NERDTree seamlessly by its 36 | window swapping functions. 37 | 38 | ============================================================================== 39 | 2. Requirements *exproject-requirements* 40 | 41 | The following requirements have to be met in order to be able to use 42 | exproject: 43 | 44 | - Vim 6.0 or higher 45 | - ex-utility: (https://github.com/exvim/ex-utility) 46 | 47 | ============================================================================== 48 | 3. Usage *exproject-usage* 49 | 50 | Create new project file ~ 51 | 52 | Go to your working project, open the Vim. Type |:EXProject| 53 | `your_project_file.exproject`. You will see a project window open. Go to the 54 | project window and type |R| to build your file tree. 55 | 56 | ------------------------------------------------------------------------------ 57 | COMMANDS *exproject-commands* 58 | 59 | :EXProject {file} *:EXProject* 60 | Open project {file} in ex-project winow. If no {file} provide, exproject 61 | will use ./files.exproject as default. 62 | 63 | :EXProjectOpen *:EXProjectOpen* 64 | Open ex-project window. 65 | 66 | :EXProjectClose *:EXProjectClose* 67 | Close ex-project window. 68 | 69 | :EXProjectToggle *:EXProjectToggle* 70 | Toggle ex-project window. 71 | 72 | :EXProjectBuild *:EXProjectBuild* 73 | Build project tree. 74 | 75 | :EXProjectFind *:EXProjectFind* 76 | Find current edit file in project tree. 77 | 78 | :EXProjectRefresh *:EXProjectRefresh* 79 | Recursively refresh current folder in project tree. 80 | 81 | ------------------------------------------------------------------------------ 82 | KEY MAPPINGS *exproject-mappings* 83 | 84 | Default key mappings: 85 | 86 | *'exproject-'* 87 | 88 | Toggle Help 89 | 90 | *'exproject-'* 91 | 92 | Zoom in/out project window 93 | 94 | *'exproject-'* 95 | *'exproject-<2-LeftMouse>'* 96 | or <2-LeftMouse> 97 | When cursor on a file, it will open it in edit window. 98 | When cursor on a folder, it will fold in/out the folder. 99 | 100 | *'exproject-'* 101 | *'exproject-'* 102 | or 103 | When cursor on a file, it will open it in edit window splitted. 104 | When cursor on a folder, it will open the folder path in OS's file 105 | explorer 106 | 107 | 108 | *'exproject-'* 109 | 110 | Move cursor up to the nearest folder 111 | 112 | *'exproject-'* 113 | 114 | Move cursor down to the nearest folder 115 | 116 | 117 | *'exproject-R'* 118 | R 119 | Rebuild the project tree 120 | 121 | *'exproject-r'* 122 | r 123 | Refresh current folder your cursor in. 124 | 125 | *'exproject-o'* 126 | o 127 | Create new file. The cursor must in a file or folder line. 128 | 129 | *'exproject-O'* 130 | O 131 | Create new folder. The cursor must in a folder line. When start create, 132 | exproject will ask you to input the new folder name. 133 | 134 | *'exproject-'* 135 | 136 | Switch between NERDTree and exproject. To make it work, your Vim must 137 | have NERDTree installed. exproject will add keymapping of in 138 | NERDTree when it detect the plugin after Vim started. 139 | 140 | 141 | ============================================================================== 142 | 4. Configuration *exproject-configuration* 143 | 144 | *g:ex_project_file* 145 | g:ex_project_file~ 146 | Default: './files.exproject' 147 | 148 | The default path of the project file. When you open the project window and 149 | no project file specified, it will use this value as default project file 150 | path. 151 | 152 | *g:ex_project_winsize* 153 | g:ex_project_winsize~ 154 | Default: 30 155 | 156 | The window size of project window. 157 | 158 | *g:ex_project_winsize_zoom* 159 | g:ex_project_winsize_zoom~ 160 | Default: 60 161 | 162 | The zoomed size of project window. 163 | 164 | *g:ex_project_winpos* 165 | g:ex_project_winpos~ 166 | Default: 'left' 167 | Options: 'left', 'right', 'top', 'bottom' 168 | 169 | The position of project window. 170 | 171 | *g:ex_project_enable_help* 172 | g:ex_project_enable_help~ 173 | Default: 1 174 | 175 | Enable help text in the plugin 176 | 177 | ------------------------------------------------------------------------------ 178 | HIGHLIGHT COLOURS *exproject-highlighting* 179 | 180 | ex_pj_help~ 181 | Help text 182 | 183 | ex_pj_help_key~ 184 | Help mappings 185 | 186 | ex_pj_help_comma~ 187 | Help comma 188 | 189 | ex_pj_fold~ 190 | Folder 191 | 192 | ex_pj_tree_line~ 193 | Tree line 194 | 195 | ex_pj_file_name~ 196 | File name 197 | 198 | ex_pj_ft_exvim~ 199 | .exvim file 200 | 201 | ex_pj_ft_error~ 202 | .err file 203 | 204 | If you want to change any of those colours put a line like the following in 205 | your vimrc: 206 | > 207 | hi ex_pj_fold guifg=Green ctermfg=Green 208 | < 209 | See |:highlight| for more information. 210 | 211 | ============================================================================== 212 | 5. Functions *exproject-functions* 213 | 214 | *exproject#register_hotkey()* 215 | exproject#register_hotkey({priority}, {key}, {action}, {desc}) 216 | Register your key-mapping by {key} in ex-project window. The {key} will 217 | execute function you define in {action}. The {priority} will sort your 218 | {key} and {desc} in the help context in ex-project window. 219 | 220 | *exproject#find_current_edit()* 221 | exproject#find_current_edit({focus}) 222 | Find current edit file and locate the cursor to it in project window. If 223 | {focus} is 1, the cursor will jump to project window, otherwise it will 224 | stay in current buffer. 225 | 226 | *exproject#set_file_filters()* 227 | exproject#set_file_filters({filters}) 228 | Set file filters for ex-project. The {filters} is a file suffix array. 229 | For example: 230 | > 231 | call exproject#set_file_filters(['c','cpp','h']) 232 | < 233 | The script above will make ex-project only show files with `.c`, `.cpp` 234 | and `.h` suffix. 235 | 236 | *exproject#set_file_ignore_patterns()* 237 | exproject#set_file_ignore_patterns({patterns}) 238 | 239 | TODO: have not implemented yet 240 | 241 | *exproject#set_folder_filter_mode()* 242 | exproject#set_folder_filter_mode({mode}) 243 | Set folder filter mode. The {mode} accept value 'include' or 'exclude'. 244 | The mode will be used as filter method for folder fitler setted by 245 | |exproject#set_folder_filters()|. 246 | 247 | *exproject#set_folder_filters()* 248 | exproject#set_folder_filters({filters}) 249 | Set folder filters for ex-project. The {filters} is a string array which 250 | stores the first-level folder names. If filter mode is 'include', it 251 | will show the folders in {filters}. If filter mode is 'exclude', it 252 | *will not* show the folders in {fitlers}. 253 | For example: 254 | > 255 | call exproject#set_folder_filters(['src','include']) 256 | < 257 | The script above will make ex-project only show 'src' and 'inlucde' 258 | folder unders the root directory if filter mode is set to 'include'. 259 | 260 | ============================================================================== 261 | 6. Troubleshooting & Known issues *exproject-issues* 262 | 263 | 264 | ============================================================================== 265 | 7. History *exproject-history* 266 | 267 | 0.1.0 (2014-04-14) 268 | - Initial release 269 | 270 | ============================================================================== 271 | vim: tw=78 ts=8 sw=4 sts=4 et ft=help 272 | -------------------------------------------------------------------------------- /ftdetect/exproject.vim: -------------------------------------------------------------------------------- 1 | au BufRead,BufNewFile *.{exproject,project} set filetype=exproject 2 | 3 | " vim:ts=4:sw=4:sts=4 et fdm=marker: 4 | -------------------------------------------------------------------------------- /ftplugin/exproject.vim: -------------------------------------------------------------------------------- 1 | " local settings {{{1 2 | silent! setlocal buftype= 3 | silent! setlocal bufhidden=hide 4 | silent! setlocal nobuflisted 5 | 6 | silent! setlocal cursorline 7 | silent! setlocal nonumber 8 | silent! setlocal nowrap 9 | silent! setlocal statusline= 10 | 11 | silent! setlocal foldenable 12 | silent! setlocal foldmethod=marker foldmarker={,} 13 | silent! setlocal foldtext=exproject#foldtext() 14 | silent! setlocal foldminlines=0 15 | " }}}1 16 | 17 | " Key Mappings Binding {{{1 18 | call exproject#bind_mappings() 19 | " }}}1 20 | 21 | " auto command {{{1 22 | augroup ex_project 23 | au! 24 | au BufWritePre call exproject#on_save() 25 | " au CursorHold :call s:exPJ_EchoPath() 26 | augroup END 27 | " }}}1 28 | 29 | " vim:ts=4:sw=4:sts=4 et fdm=marker: 30 | -------------------------------------------------------------------------------- /plugin/exproject.vim: -------------------------------------------------------------------------------- 1 | " default configuration {{{1 2 | if !exists('g:ex_project_file') 3 | let g:ex_project_file = "./files.exproject" 4 | endif 5 | 6 | if !exists('g:ex_project_winsize') 7 | let g:ex_project_winsize = 30 8 | endif 9 | 10 | if !exists('g:ex_project_winsize_zoom') 11 | let g:ex_project_winsize_zoom = 60 12 | endif 13 | 14 | " left or right 15 | if !exists('g:ex_project_winpos') 16 | let g:ex_project_winpos = 'left' 17 | endif 18 | 19 | if !exists('g:ex_project_enable_help') 20 | let g:ex_project_enable_help = 1 21 | endif 22 | 23 | "}}} 24 | 25 | " commands {{{1 26 | command! -n=? -complete=file EXProject call exproject#open('') 27 | command! EXProjectOpen call exproject#open_window() 28 | command! EXProjectClose call exproject#close_window() 29 | command! EXProjectToggle call exproject#toggle_window() 30 | command! EXProjectBuild call exproject#build_tree() 31 | command! EXProjectFind call exproject#find_current_edit(1) 32 | command! EXProjectRefresh call exproject#refresh_current_folder() 33 | "}}} 34 | 35 | " default key mappings {{{1 36 | call exproject#register_hotkey( 1 , 1, '' , ":call exproject#toggle_help()" , 'Toggle help.' ) 37 | call exproject#register_hotkey( 2 , 1, '' , ":call exproject#toggle_zoom()" , 'Zoom in/out project window.' ) 38 | call exproject#register_hotkey( 3 , 1, '' , ":call exproject#confirm_select('')" , 'File: Open it. Folder: Fold in/out.' ) 39 | call exproject#register_hotkey( 4 , 1, '<2-LeftMouse>' , ":call exproject#confirm_select('')" , 'File: Open it. Folder: Fold in/out.' ) 40 | call exproject#register_hotkey( 5 , 1, '' , ":call exproject#confirm_select('shift')" , 'File: Split and open it. Folder: Open the folder in os file browser.' ) 41 | call exproject#register_hotkey( 6 , 1, '' , ":call exproject#confirm_select('shift')" , 'File: Split and open it. Folder: Open the folder in os file browser.' ) 42 | call exproject#register_hotkey( 7 , 1, '' , ":call exproject#cursor_jump( '\\C\\[F\\]', 'up' )" , 'Move cursor up to the nearest folder.' ) 43 | call exproject#register_hotkey( 8 , 1, '' , ":call exproject#cursor_jump( '\\C\\[F\\]', 'down' )" , 'Move cursor down to the nearest folder.' ) 44 | call exproject#register_hotkey( 9 , 1, 'R' , ":EXProjectBuild" , 'Rebuild project tree.' ) 45 | call exproject#register_hotkey( 10 , 1, 'r' , ":EXProjectRefresh" , 'Refresh current folder.' ) 46 | call exproject#register_hotkey( 11 , 1, 'o' , ":call exproject#newfile()" , 'Create new file.' ) 47 | call exproject#register_hotkey( 12 , 1, 'O' , ":call exproject#newfolder()" , 'Create new folder.' ) 48 | 49 | " TODO: 50 | " nnoremap e :call exPJ_EchoPath() 51 | "}}} 52 | 53 | call ex#register_plugin( 'exproject', {} ) 54 | call ex#register_plugin( 'nerdtree', { 'bufname': 'NERD_tree_\d\+', 'buftype': 'nofile' } ) 55 | 56 | " vim:ts=4:sw=4:sts=4 et fdm=marker: 57 | -------------------------------------------------------------------------------- /syntax/exproject.vim: -------------------------------------------------------------------------------- 1 | if version < 600 2 | syntax clear 3 | elseif exists("b:current_syntax") 4 | finish 5 | endif 6 | 7 | " syntax highlight 8 | syntax match ex_pj_help #^".*# contains=ex_pj_help_key 9 | syntax match ex_pj_help_key '^" \S\+:'hs=s+2,he=e-1 contained contains=ex_pj_help_comma 10 | syntax match ex_pj_help_comma ':' contained 11 | 12 | syntax match ex_pj_fold '{\|}' 13 | syntax match ex_pj_tree_line '\( |\)\+-\{0,1}.*' contains=ex_pj_folder_name,ex_pj_file_name 14 | 15 | syntax match ex_pj_folder_label '\C\[F\]' 16 | syntax match ex_pj_folder_name '\C\[F\].*'hs=s+3 contains=ex_pj_folder_label,ex_pj_fold 17 | 18 | syntax match ex_pj_file_name '|-[^\[]\+'ms=s+2 contains=@ex_pj_special_files,ex_pj_fold 19 | 20 | syntax match ex_pj_ft_clang_src '.*\.\(c\|cpp\|cxx\)\>' contained 21 | syntax match ex_pj_ft_clang_header '.*\.\(h\)\>' contained 22 | syntax match ex_pj_ft_script '.*\.\(js\|coffee\|typescript\|lua\|py\)\>' contained 23 | syntax match ex_pj_ft_html '.*\.\(html\|xml\|json\)\>' contained 24 | syntax match ex_pj_ft_style '.*\.\(css\|styl\|less\|sass\)\>' contained 25 | 26 | syntax match ex_pj_ft_exvim '.*\.\(exvim\|vimentry\|vimproject\)\>' contained 27 | syntax match ex_pj_ft_gulpfile 'gulpfile\.\(js\|coffee\)' contained 28 | syntax match ex_pj_ft_gruntfile 'gruntfile\.\(js\|coffee\)' contained 29 | syntax match ex_pj_ft_package_json 'package\.json' contained 30 | syntax match ex_pj_ft_bower_json 'bower\.json' contained 31 | syntax match ex_pj_ft_error '.*\.\(err\)\>' contained 32 | 33 | syntax cluster ex_pj_special_files contains= 34 | \ex_pj_ft_exvim 35 | \,ex_pj_ft_error 36 | \,ex_pj_ft_gulpfile 37 | \,ex_pj_ft_package_json 38 | \,ex_pj_ft_bower_json 39 | \,ex_pj_ft_clang_src 40 | \,ex_pj_ft_clang_header 41 | \,ex_pj_ft_script 42 | \,ex_pj_ft_html 43 | \,ex_pj_ft_style 44 | 45 | 46 | hi default link ex_pj_help Comment 47 | hi default link ex_pj_help_key Label 48 | hi default link ex_pj_help_comma Special 49 | 50 | hi default link ex_pj_fold exTransparent 51 | hi default link ex_pj_tree_line Comment 52 | 53 | hi default link ex_pj_folder_label Title 54 | hi default link ex_pj_folder_name Directory 55 | 56 | hi default link ex_pj_file_name Normal 57 | 58 | hi default link ex_pj_ft_exvim DiffAdd 59 | hi default link ex_pj_ft_gulpfile DiffChange 60 | hi default link ex_pj_ft_package_json DiffChange 61 | hi default link ex_pj_ft_bower_json DiffChange 62 | hi default link ex_pj_ft_error Error 63 | 64 | hi default link ex_pj_ft_clang_src Normal 65 | hi default link ex_pj_ft_clang_header Normal 66 | hi default link ex_pj_ft_script Normal 67 | hi default link ex_pj_ft_html helpVim 68 | hi default link ex_pj_ft_style Label 69 | 70 | let b:current_syntax = "exproject" 71 | 72 | " vim:ts=4:sw=4:sts=4 et fdm=marker: 73 | --------------------------------------------------------------------------------