Skip to content
Snippets Groups Projects
Commit e8b6928d authored by Jerome Reybert's avatar Jerome Reybert
Browse files

plugin/magit.vim: handle directories recursively (fix #10)

parent 3ab04b28
No related branches found
No related tags found
No related merge requests found
...@@ -3,6 +3,11 @@ function! magit#state#is_file_visible(section, filename) dict ...@@ -3,6 +3,11 @@ function! magit#state#is_file_visible(section, filename) dict
\ ( self.dict[a:section][a:filename].visible == 1 ) ) \ ( self.dict[a:section][a:filename].visible == 1 ) )
endfunction endfunction
function! magit#state#is_dir(section, filename) dict
return ( has_key(self.dict[a:section], a:filename) &&
\ ( self.dict[a:section][a:filename].dir != 0 ) )
endfunction
function! magit#state#get_files(mode) dict function! magit#state#get_files(mode) dict
return self.dict[a:mode] return self.dict[a:mode]
endfunction endfunction
...@@ -28,6 +33,7 @@ let s:file_template = { ...@@ -28,6 +33,7 @@ let s:file_template = {
\ 'exists': 0, \ 'exists': 0,
\ 'status': '', \ 'status': '',
\ 'empty': 0, \ 'empty': 0,
\ 'dir': 0,
\ 'binary': 0, \ 'binary': 0,
\ 'symlink': '', \ 'symlink': '',
\ 'diff': s:diff_template, \ 'diff': s:diff_template,
...@@ -87,10 +93,7 @@ endfunction ...@@ -87,10 +93,7 @@ endfunction
" param[in] mode: can be staged or unstaged " param[in] mode: can be staged or unstaged
" param[in] status: one character status code of the file (AMDRCU?) " param[in] status: one character status code of the file (AMDRCU?)
" param[in] filename: filename " param[in] filename: filename
function! magit#state#add_file(mode, status, filename) dict function! magit#state#add_file(mode, status, filename, depth) dict
let dir = getcwd()
try
call magit#utils#lcd(magit#utils#top_dir())
let dev_null = ( a:status == '?' ) ? " /dev/null " : " " let dev_null = ( a:status == '?' ) ? " /dev/null " : " "
let staged_flag = ( a:mode == 'staged' ) ? " --staged " : " " let staged_flag = ( a:mode == 'staged' ) ? " --staged " : " "
let diff_cmd="git diff --no-ext-diff " . staged_flag . let diff_cmd="git diff --no-ext-diff " . staged_flag .
...@@ -103,10 +106,16 @@ function! magit#state#add_file(mode, status, filename) dict ...@@ -103,10 +106,16 @@ function! magit#state#add_file(mode, status, filename) dict
let diff_dict_file = self.get_file(a:mode, a:filename, 1) let diff_dict_file = self.get_file(a:mode, a:filename, 1)
let diff_dict_file.exists = 1 let diff_dict_file.exists = 1
let diff_dict_file.status = a:status let diff_dict_file.status = a:status
let diff_dict_file.depth = a:depth
if ( a:status == '?' && getftype(a:filename) == 'link' ) if ( a:status == '?' && getftype(a:filename) == 'link' )
let diff_dict_file.symlink = resolve(a:filename) let diff_dict_file.symlink = resolve(a:filename)
call add(diff_dict_file.diff.header, 'no header') call add(diff_dict_file.diff.header, 'no header')
let diff_dict_file.diff.hunks[0].header = 'New symbolic link file' let diff_dict_file.diff.hunks[0].header = 'New symbolic link file'
elseif ( a:status == '?' && isdirectory(a:filename) == 1 )
let diff_dict_file.dir = 1
for subfile in split(globpath(a:filename, '\(.[^.]*\|*\)'), '\n')
call self.add_file(a:mode, a:status, subfile, a:depth + 1)
endfor
elseif ( a:status == '?' && getfsize(a:filename) == 0 ) elseif ( a:status == '?' && getfsize(a:filename) == 0 )
let diff_dict_file.empty = 1 let diff_dict_file.empty = 1
call add(diff_dict_file.diff.header, 'no header') call add(diff_dict_file.diff.header, 'no header')
...@@ -138,9 +147,6 @@ function! magit#state#add_file(mode, status, filename) dict ...@@ -138,9 +147,6 @@ function! magit#state#add_file(mode, status, filename) dict
call add(hunk.lines, diff_line) call add(hunk.lines, diff_line)
endfor endfor
endif endif
finally
call magit#utils#lcd(dir)
endtry
endfunction endfunction
" magit#state#update: update self.dict " magit#state#update: update self.dict
...@@ -157,8 +163,10 @@ function! magit#state#update() dict ...@@ -157,8 +163,10 @@ function! magit#state#update() dict
endfor endfor
endfor endfor
let dir = getcwd()
try
call magit#utils#lcd(magit#utils#top_dir())
for [mode, diff_dict_mode] in items(self.dict) for [mode, diff_dict_mode] in items(self.dict)
let status_list = magit#git#get_status() let status_list = magit#git#get_status()
for file_status in status_list for file_status in status_list
let status=file_status[mode] let status=file_status[mode]
...@@ -167,9 +175,12 @@ function! magit#state#update() dict ...@@ -167,9 +175,12 @@ function! magit#state#update() dict
if ( status == ' ' || ( ( mode == 'staged' ) && status == '?' ) ) if ( status == ' ' || ( ( mode == 'staged' ) && status == '?' ) )
continue continue
endif endif
call self.add_file(mode, status, file_status.filename) call self.add_file(mode, status, file_status.filename, 0)
endfor endfor
endfor endfor
finally
call magit#utils#lcd(dir)
endtry
" remove files that have changed their mode or been committed/deleted/discarded... " remove files that have changed their mode or been committed/deleted/discarded...
for diff_dict_mode in values(self.dict) for diff_dict_mode in values(self.dict)
...@@ -202,6 +213,7 @@ let magit#state#state = { ...@@ -202,6 +213,7 @@ let magit#state#state = {
\ 'get_hunks': function("magit#state#get_hunks"), \ 'get_hunks': function("magit#state#get_hunks"),
\ 'get_flat_hunks': function("magit#state#get_flat_hunks"), \ 'get_flat_hunks': function("magit#state#get_flat_hunks"),
\ 'add_file': function("magit#state#add_file"), \ 'add_file': function("magit#state#add_file"),
\ 'is_dir': function("magit#state#is_dir"),
\ 'is_file_visible': function("magit#state#is_file_visible"), \ 'is_file_visible': function("magit#state#is_file_visible"),
\ 'update': function("magit#state#update"), \ 'update': function("magit#state#update"),
\ 'dict': { 'staged': {}, 'unstaged': {}}, \ 'dict': { 'staged': {}, 'unstaged': {}},
......
...@@ -21,6 +21,7 @@ let g:magit_git_status_code = { ...@@ -21,6 +21,7 @@ let g:magit_git_status_code = {
\ '!': 'ignored', \ '!': 'ignored',
\ 'E': 'empty', \ 'E': 'empty',
\ 'L': 'symlink', \ 'L': 'symlink',
\ 'N': 'new dir',
\ } \ }
" Regular expressions used to select blocks " Regular expressions used to select blocks
......
...@@ -140,24 +140,23 @@ function! s:mg_get_info() ...@@ -140,24 +140,23 @@ function! s:mg_get_info()
silent put ='' silent put =''
endfunction endfunction
function! s:mg_display_files(mode, curdir, depth)
" s:mg_get_staged_section: this function writes in current buffer all staged " FIXME: ouch, must store subdirs in more efficient way
" or unstaged files, using s:state.dict information
" WARNING: this function writes in file, it should only be called through
" protected functions like magit#update_buffer
" param[in] mode: 'staged' or 'unstaged'
function! s:mg_get_staged_section(mode)
put =''
put =g:magit_sections[a:mode]
call <SID>mg_section_help(a:mode)
put =magit#utils#underline(g:magit_sections[a:mode])
put =''
for [ filename, file_props ] in items(s:state.get_files(a:mode)) for [ filename, file_props ] in items(s:state.get_files(a:mode))
if ( file_props.depth != a:depth || filename !~ a:curdir . '.*' )
continue
endif
if ( file_props.empty == 1 ) if ( file_props.empty == 1 )
put =g:magit_git_status_code.E . ': ' . filename put =g:magit_git_status_code.E . ': ' . filename
elseif ( file_props.symlink != '' ) elseif ( file_props.symlink != '' )
put =g:magit_git_status_code.L . ': ' . filename . ' -> ' . file_props.symlink put =g:magit_git_status_code.L . ': ' . filename . ' -> ' . file_props.symlink
elseif ( file_props.dir != 0 )
put =g:magit_git_status_code.N . ': ' . filename
if ( file_props.visible == 1 )
call s:mg_display_files(a:mode, filename, a:depth + 1)
continue
endif
else else
put =g:magit_git_status_code[file_props.status] . ': ' . filename put =g:magit_git_status_code[file_props.status] . ': ' . filename
endif endif
...@@ -177,6 +176,20 @@ function! s:mg_get_staged_section(mode) ...@@ -177,6 +176,20 @@ function! s:mg_get_staged_section(mode)
endfor endfor
endfunction endfunction
" s:mg_get_staged_section: this function writes in current buffer all staged
" or unstaged files, using s:state.dict information
" WARNING: this function writes in file, it should only be called through
" protected functions like magit#update_buffer
" param[in] mode: 'staged' or 'unstaged'
function! s:mg_get_staged_section(mode)
put =''
put =g:magit_sections[a:mode]
call <SID>mg_section_help(a:mode)
put =magit#utils#underline(g:magit_sections[a:mode])
put =''
call s:mg_display_files(a:mode, '', 0)
endfunction
" s:mg_get_stashes: this function write in current buffer all stashes " s:mg_get_stashes: this function write in current buffer all stashes
" WARNING: this function writes in file, it should only be called through " WARNING: this function writes in file, it should only be called through
" protected functions like magit#update_buffer " protected functions like magit#update_buffer
...@@ -663,7 +676,8 @@ function! s:mg_select_closed_file() ...@@ -663,7 +676,8 @@ function! s:mg_select_closed_file()
let list = matchlist(getline("."), g:magit_file_re) let list = matchlist(getline("."), g:magit_file_re)
let filename = list[2] let filename = list[2]
let section=<SID>mg_get_section() let section=<SID>mg_get_section()
if ( s:state.is_file_visible(section, filename) == 0 ) if ( s:state.is_file_visible(section, filename) == 0 ||
\ s:state.is_dir(section, filename) == 1 )
let selection = s:state.get_flat_hunks(section, filename) let selection = s:state.get_flat_hunks(section, filename)
return selection return selection
endif endif
...@@ -687,6 +701,7 @@ function! magit#stage_block(selection, discard) abort ...@@ -687,6 +701,7 @@ function! magit#stage_block(selection, discard) abort
if ( section == 'unstaged' ) if ( section == 'unstaged' )
if ( file.empty == 1 || if ( file.empty == 1 ||
\ file.symlink != '' || \ file.symlink != '' ||
\ file.dir != 0 ||
\ file.binary == 1 ) \ file.binary == 1 )
call magit#utils#system('git add ' . call magit#utils#system('git add ' .
\ magit#utils#add_quotes(filename)) \ magit#utils#add_quotes(filename))
...@@ -696,6 +711,7 @@ function! magit#stage_block(selection, discard) abort ...@@ -696,6 +711,7 @@ function! magit#stage_block(selection, discard) abort
elseif ( section == 'staged' ) elseif ( section == 'staged' )
if ( file.empty == 1 || if ( file.empty == 1 ||
\ file.symlink != '' || \ file.symlink != '' ||
\ file.dir != 0 ||
\ file.binary == 1 ) \ file.binary == 1 )
call magit#utils#system('git reset ' . call magit#utils#system('git reset ' .
\ magit#utils#add_quotes(filename)) \ magit#utils#add_quotes(filename))
...@@ -711,6 +727,7 @@ function! magit#stage_block(selection, discard) abort ...@@ -711,6 +727,7 @@ function! magit#stage_block(selection, discard) abort
if ( section == 'unstaged' ) if ( section == 'unstaged' )
if ( file.empty == 1 || if ( file.empty == 1 ||
\ file.symlink != '' || \ file.symlink != '' ||
\ file.dir != 0 ||
\ file.binary == 1 ) \ file.binary == 1 )
call delete(filename) call delete(filename)
else else
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment