Skip to content

Commit

Permalink
widgets.diff: Save and restore selection across updates
Browse files Browse the repository at this point in the history
git-cola's inotify integration causes it to automatically refresh itself
when files are changed by another process.

This can be problematic because refreshing the "diff" viewer causes it
to lose the user's selection.

Teach the "diff" viewer to save and restore the selection when its
contents change.  When no selection is present, restore the previous
cursor position.

Closes #155

Reported-by: Peter Júnoš <petoju@gmail.com>
Signed-off-by: David Aguilar <davvid@gmail.com>
  • Loading branch information
davvid committed Jan 22, 2013
1 parent 2ea5ca5 commit 05b6c7d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
37 changes: 32 additions & 5 deletions cola/widgets/diff.py
Expand Up @@ -7,11 +7,11 @@
from cola import cmds
from cola import qtutils
from cola.cmds import run
from cola.widgets import defs
from cola.widgets.text import DiffTextEdit


class DiffEditor(DiffTextEdit):

def __init__(self, parent):
DiffTextEdit.__init__(self, parent)
self.model = model = cola.model()
Expand Down Expand Up @@ -143,13 +143,40 @@ def setPlainText(self, text):
highlight = (self.mode != self.model.mode_none and
self.mode != self.model.mode_untracked)
self.highlighter.set_enabled(highlight)

scrollbar = self.verticalScrollBar()
if scrollbar:
scrollvalue = scrollbar.value()
if text is not None:
DiffTextEdit.setPlainText(self, text)
if scrollbar:
scrollbar.setValue(scrollvalue)
else:
scrollvalue = None

if text is None:
return

offset, selection = self.offset_and_selection()
old_text = unicode(self.toPlainText())

DiffTextEdit.setPlainText(self, text)

# If the old selection exists in the new text then
# re-select it.
if selection and selection in text:
idx = text.index(selection)
cursor = self.textCursor()
cursor.setPosition(idx)
cursor.setPosition(idx + len(selection),
QtGui.QTextCursor.KeepAnchor)
self.setTextCursor(cursor)

# Otherwise, if the text is identical and there
# is no selection then restore the cursor position.
elif text == old_text:
cursor = self.textCursor()
cursor.setPosition(offset)
self.setTextCursor(cursor)

if scrollbar and scrollvalue is not None:
scrollbar.setValue(scrollvalue)

def offset_and_selection(self):
cursor = self.textCursor()
Expand Down
8 changes: 8 additions & 0 deletions share/doc/git-cola/relnotes.rst
Expand Up @@ -9,6 +9,14 @@ Usability, bells and whistles

Fixes
-----
* The inotify auto-refresh feature makes it difficult to select text in
the "diff" editor when files are being continually modified by another
process. The auto-refresh causes it to lose the currently selected text,
which is not wanted. We now avoid this problem by saving and restoring
the selection when refreshing the editor.

http://github.com/git-cola/git-cola/issues/155

* Fixed the Alt+D Diffstat shortcut.

http://github.com/git-cola/git-cola/issues/159
Expand Down
1 change: 1 addition & 0 deletions share/doc/git-cola/thanks.rst
Expand Up @@ -33,6 +33,7 @@ Thanks
* Michael Homer
* Omega Weapon
* Paolo G. Giarrusso
* Peter Júnoš
* Rustam Safin
* Stefan Naewe
* Steffen Prohaska
Expand Down

0 comments on commit 05b6c7d

Please sign in to comment.