diff --git a/autoload/coquille.py b/autoload/coquille.py index 6c1493e..3746831 100644 --- a/autoload/coquille.py +++ b/autoload/coquille.py @@ -49,6 +49,27 @@ def vim_repr(value): def make_vim_range(start, stop): return [[start[0] + 1, start[2] + 1], [stop[0] + 1, stop[2] + 1]] +# Return a list of all windows that are displaying the buffer, along with their +# current cursor positions. +def get_cursors_for_buffer(vim_buffer): + result = [] + for win in vim.windows: + if win.buffer is vim_buffer: + result.append((win, win.cursor)) + return result + +# Takes the list of window cursor positions from get_cursor_for_buffer. If the +# cursor position is now lower for any of the windows, they are entered to +# rescroll the window. +def fix_scroll(cursors): + refresh_now = None + for win, (row, col) in cursors: + if win.cursor[0] < row or win.cursor[1] < col: + win.vars['coquille_needs_scroll_fix'] = 1 + if win.tabpage is vim.current.tabpage: + vim.command("call coquille#FixWindowScrollTabWin(%d, %d)" % + (win.tabpage.number, win.number)) + # All the python side state associated with the vim source buffer class BufferState(object): # Dict mapping source buffer id to BufferState @@ -274,6 +295,7 @@ def show_goal(self, response): modifiable = self.goal_buffer.options["modifiable"] self.goal_buffer.options["modifiable"] = True try: + cursors = get_cursors_for_buffer(self.goal_buffer) del self.goal_buffer[:] if response is None: @@ -320,6 +342,8 @@ def show_goal(self, response): lines = map(lambda s: s.encode('utf-8'), ccl.split('\n')) self.goal_buffer.append(list(lines)) self.goal_buffer.append('') + + fix_scroll(cursors) finally: self.goal_buffer.options["modifiable"] = modifiable return True @@ -329,6 +353,7 @@ def show_info(self, message): modifiable = self.info_buffer.options["modifiable"] self.info_buffer.options["modifiable"] = True try: + cursors = get_cursors_for_buffer(self.info_buffer) del self.info_buffer[:] lst = [] if message is not None: @@ -346,6 +371,7 @@ def show_info(self, message): # extend function, and its append mostly behaves like extend. self.info_buffer[0] = lst[0] self.info_buffer.append(lst[1:]) + fix_scroll(cursors) finally: self.info_buffer.options["modifiable"] = modifiable diff --git a/autoload/coquille.vim b/autoload/coquille.vim index c2b7d8e..ea7820e 100644 --- a/autoload/coquille.vim +++ b/autoload/coquille.vim @@ -682,6 +682,36 @@ endfunction let s:empty_range = [ { 'line': 0, 'col': 0}, { 'line': 0, 'col': 0} ] +function! coquille#FixWindowScroll(winid, hint_tabnr, hint_winnr) + let l:cur_tab = tabpagenr() + let l:cur_win = winnr() + let l:tabwin = coquille#WinId2TabWin(a:winid, a:hint_tabnr, a:hint_winnr) + if l:tabwin[0] != l:cur_tab + " Only fix the scroll for windows in the current tab. The other + " windows will be fixed when their tab is entered. + return 0 + endif + + if coquille#GetWinVar(a:winid, l:tabwin[0], l:tabwin[1], + \ "coquille_needs_scroll_fix", 0) + let l:cur_winid = coquille#WinGetId(l:cur_tab, l:cur_win) + call coquille#SetWinVar(a:winid, l:tabwin[0], l:tabwin[1], + \ "coquille_needs_scroll_fix", 0) + " When the cursor is at the last line of the buffer, then the number + " of lines in the buffer is reduced from python, vim leaves the window + " scrolled past the end. Just entering the window is enough to fix it. + call coquille#WinGoToId(a:winid, l:tabwin[0], l:tabwin[1]) + + call coquille#WinGoToId(l:cur_winid, l:cur_tab, l:cur_win) + return 1 + endif +endfunction + +function! coquille#FixWindowScrollTabWin(tabnr, winnr) + let l:winid = coquille#WinGetId(a:tabnr, a:winnr) + return coquille#FixWindowScroll(l:winid, a:tabnr, a:winnr) +endfunction + function! coquille#SyncWindowColors(winid, hint_tabnr, hint_winnr) let l:cur_tab = tabpagenr() let l:cur_win = winnr() @@ -772,8 +802,10 @@ function! coquille#TabActivated() while l:cur_win <= tabpagewinnr(l:cur_tab, "$") let l:cur_winid = coquille#WinGetId(l:cur_tab, l:cur_win) call coquille#SyncWindowColors(l:cur_winid, l:cur_tab, l:cur_win) + call coquille#FixWindowScroll(l:cur_winid, l:cur_tab, l:cur_win) let l:cur_win += 1 endwhile + endfunction function! coquille#WindowActivated(winid, hint_tabnr, hint_winnr)