diff --git a/autoload/magit/state.vim b/autoload/magit/state.vim index fc225f2368f5632a370dc9c3cc8872d99dd7f632..2cb63c6921db034f1bd3e24bf1137b9f19689530 100644 --- a/autoload/magit/state.vim +++ b/autoload/magit/state.vim @@ -94,6 +94,7 @@ let s:file_template = { \ 'submodule': 0, \ 'symlink': '', \ 'diff': s:diff_template, +\ 'line_pos': 0, \ 'is_dir': function("magit#state#is_file_dir"), \ 'is_visible': function("magit#state#is_file_visible"), \ 'set_visible': function("magit#state#set_file_visible"), diff --git a/plugin/magit.vim b/plugin/magit.vim index 5b4fe051c9a8feceda0662cef524609b0f2d77e9..2d03cd8f0335aeb5fe34bff91fa6931e059d8b5d 100644 --- a/plugin/magit.vim +++ b/plugin/magit.vim @@ -184,6 +184,7 @@ function! s:mg_display_files(mode, curdir, depth) continue endif silent put =file.get_filename_header() + let file.line_pos = line('.') if ( file.dir != 0 ) if ( file.visible == 1 ) @@ -615,6 +616,13 @@ let s:mg_display_functions = { " 5. restore window state " param[in] updated file (optional): this filename is updated to absolute " path, set in g:magit_last_updated_buffer and the User autocmd +" param[in] current section (optional): when params 1 & 2 are set, it means +" that a stage/unstage action occured. We try to smartly set the cursor +" position after the refresh +" - on current file if still in current section +" - else on next file if any +" - else on previous file if any +" - or cursor stay where it is " VimagitUpdateFile event is raised function! magit#update_buffer(...) let buffer_name=bufname("%") @@ -622,6 +630,13 @@ function! magit#update_buffer(...) echoerr "Not in magit buffer but in " . buffer_name return endif + + if ( a:0 >= 1 ) + let cur_filename = a:1 + endif + if ( a:0 >= 2 ) + let cur_section = a:2 + endif if ( b:magit_current_commit_mode != '' ) try @@ -646,7 +661,16 @@ function! magit#update_buffer(...) " delete buffer silent! execute "silent :%delete _" - + + " be smart for the cursor position after refresh, if stage/unstaged + " occured + if ( a:0 >= 2 ) + let filenames = b:state.get_filenames(cur_section) + let pos = match(filenames, cur_filename) + let next_filename = (pos < len(filenames) - 1) ? filenames[pos+1] : '' + let prev_filename = (pos > 0) ? filenames[pos-1] : '' + endif + call b:state.update() for section in g:magit_default_sections @@ -678,8 +702,8 @@ function! magit#update_buffer(...) set filetype=magit let g:magit_last_updated_buffer = '' - if ( a:0 == 1 ) - let abs_filename = magit#git#top_dir() . a:1 + if ( a:0 >= 1 ) + let abs_filename = magit#git#top_dir() . cur_filename if ( bufexists(abs_filename) ) let g:magit_last_updated_buffer = abs_filename if exists('#User#VimagitUpdateFile') @@ -692,6 +716,19 @@ function! magit#update_buffer(...) doautocmd User VimagitRefresh endif + if ( a:0 >= 2 ) + " if, in this order, current file, next file, previous file exists in + " current section, move cursor to it + for fname in [cur_filename, next_filename, prev_filename] + try + let file = b:state.get_file(cur_section, fname) + call cursor(file.line_pos, 0) + break + catch 'file_doesnt_exists' + endtry + endfor + endif + endfunction " magit#toggle_help: toggle inline help showing in magit buffer @@ -901,7 +938,8 @@ function! s:mg_stage_closed_file(discard) endif endif - call magit#update_buffer(filename) + call magit#update_buffer(filename, section) + return endif endif @@ -951,7 +989,8 @@ function! magit#stage_block(selection, discard) abort endif endif - call magit#update_buffer(filename) + call magit#update_buffer(filename, section) + endfunction " magit#stage_file: this function (un)stage a whole file, from the current