From f32316dcc7e4de3751b9a1bb32555cb04a8c6029 Mon Sep 17 00:00:00 2001
From: Jerome Reybert <jreybert@gmail.com>
Date: Fri, 16 Mar 2018 10:33:41 +0100
Subject: [PATCH] smarter cursor position when refreshing

---
 autoload/magit/state.vim |  8 ++++++
 plugin/magit.vim         | 58 ++++++++++++++++++++++++----------------
 2 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/autoload/magit/state.vim b/autoload/magit/state.vim
index 8440706..d33229e 100644
--- a/autoload/magit/state.vim
+++ b/autoload/magit/state.vim
@@ -321,6 +321,13 @@ function! magit#state#get_files(mode) dict
 	return self.dict[a:mode]
 endfunction
 
+" magit#state#get_files_nb: returns the number of files in a given section
+" param[in] mode: mode to select, can be 'staged' or 'unstaged'
+" return number of files of this section
+function! magit#state#get_files_nb(mode) dict
+	return len(self.dict[a:mode])
+endfunction
+
 " magit#state#get_files: global dict file objects (copy) getter function
 " param[in] mode: mode to select, can be 'staged' or 'unstaged'
 " return ordered list of file objects belonging to mode
@@ -366,6 +373,7 @@ let magit#state#state = {
 			\ 'nb_diff_lines': 0,
 			\ 'get_file': function("magit#state#get_file"),
 			\ 'get_files': function("magit#state#get_files"),
+			\ 'get_files_nb': function("magit#state#get_files_nb"),
 			\ 'get_files_ordered': function("magit#state#get_files_ordered"),
 			\ 'get_filenames': function("magit#state#get_filenames"),
 			\ 'add_file': function("magit#state#add_file"),
diff --git a/plugin/magit.vim b/plugin/magit.vim
index ba33e9f..46845ac 100644
--- a/plugin/magit.vim
+++ b/plugin/magit.vim
@@ -654,31 +654,43 @@ function! magit#update_buffer(...)
 	endif
 
 	if ( a:0 >= 3 )
-		" if, in this order, current file, next file, previous file exists in
-		" current section, move cursor to it
-		let cur_file = 1
-		for fname in [cur_filename, next_filename, prev_filename]
-			try
-				let file = b:state.get_file(cur_section, fname)
-				if ( cur_file )
-					let hunk_id = max([0, min([len(file.get_hunks())-1, cur_hunk_id])])
-					let cur_file = 0
-				else
-					let hunk_id = 0
-				endif
+		if (b:state.get_files_nb(cur_section) > 0)
+			" if, in this order, current file, next file, previous file exists in
+			" current section, move cursor to it
+			let cur_file = 1
+			for fname in [cur_filename, next_filename, prev_filename]
+				try
+					let file = b:state.get_file(cur_section, fname)
+					if ( cur_file )
+						let hunk_id = max([0, min([len(file.get_hunks())-1, cur_hunk_id])])
+						let cur_file = 0
+					else
+						let hunk_id = 0
+					endif
 
-				if ( file.is_visible() )
-					call cursor(file.get_hunks()[hunk_id].line_pos, 0)
-					if ( g:magit_auto_foldopen )
-						foldopen
+					if ( file.is_visible() )
+						call cursor(file.get_hunks()[hunk_id].line_pos, 0)
+						if ( g:magit_auto_foldopen )
+							foldopen
+						endif
+					else
+						call cursor(file.line_pos, 0)
 					endif
-				else
-					call cursor(file.line_pos, 0)
-				endif
-				break
-			catch 'file_doesnt_exists'
-			endtry
-		endfor
+					break
+				catch 'file_doesnt_exists'
+				endtry
+			endfor
+		else
+			" if current section is empty, move cursor to top to other section
+			if (cur_section == 'staged')
+				let cur_section = 'unstaged'
+			elseif (cur_section == 'unstaged')
+				let cur_section = 'staged'
+			endif
+			let section_line=search(g:magit_sections[cur_section], "bnw")
+			call cursor(section_line, 0)
+		endif
+		silent execute "normal! zt"
 	endif
 
 	if exists(':AirlineRefresh')
-- 
GitLab