Skip to content

Commit 05b6c7d

Browse files
committed
widgets.diff: Save and restore selection across updates
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 git-cola#155 Reported-by: Peter Júnoš <petoju@gmail.com> Signed-off-by: David Aguilar <davvid@gmail.com>
1 parent 2ea5ca5 commit 05b6c7d

File tree

3 files changed

+41
-5
lines changed

3 files changed

+41
-5
lines changed

cola/widgets/diff.py

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
from cola import cmds
88
from cola import qtutils
99
from cola.cmds import run
10-
from cola.widgets import defs
1110
from cola.widgets.text import DiffTextEdit
1211

1312

1413
class DiffEditor(DiffTextEdit):
14+
1515
def __init__(self, parent):
1616
DiffTextEdit.__init__(self, parent)
1717
self.model = model = cola.model()
@@ -143,13 +143,40 @@ def setPlainText(self, text):
143143
highlight = (self.mode != self.model.mode_none and
144144
self.mode != self.model.mode_untracked)
145145
self.highlighter.set_enabled(highlight)
146+
146147
scrollbar = self.verticalScrollBar()
147148
if scrollbar:
148149
scrollvalue = scrollbar.value()
149-
if text is not None:
150-
DiffTextEdit.setPlainText(self, text)
151-
if scrollbar:
152-
scrollbar.setValue(scrollvalue)
150+
else:
151+
scrollvalue = None
152+
153+
if text is None:
154+
return
155+
156+
offset, selection = self.offset_and_selection()
157+
old_text = unicode(self.toPlainText())
158+
159+
DiffTextEdit.setPlainText(self, text)
160+
161+
# If the old selection exists in the new text then
162+
# re-select it.
163+
if selection and selection in text:
164+
idx = text.index(selection)
165+
cursor = self.textCursor()
166+
cursor.setPosition(idx)
167+
cursor.setPosition(idx + len(selection),
168+
QtGui.QTextCursor.KeepAnchor)
169+
self.setTextCursor(cursor)
170+
171+
# Otherwise, if the text is identical and there
172+
# is no selection then restore the cursor position.
173+
elif text == old_text:
174+
cursor = self.textCursor()
175+
cursor.setPosition(offset)
176+
self.setTextCursor(cursor)
177+
178+
if scrollbar and scrollvalue is not None:
179+
scrollbar.setValue(scrollvalue)
153180

154181
def offset_and_selection(self):
155182
cursor = self.textCursor()

share/doc/git-cola/relnotes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ Usability, bells and whistles
99

1010
Fixes
1111
-----
12+
* The inotify auto-refresh feature makes it difficult to select text in
13+
the "diff" editor when files are being continually modified by another
14+
process. The auto-refresh causes it to lose the currently selected text,
15+
which is not wanted. We now avoid this problem by saving and restoring
16+
the selection when refreshing the editor.
17+
18+
http://github.com/git-cola/git-cola/issues/155
19+
1220
* Fixed the Alt+D Diffstat shortcut.
1321

1422
http://github.com/git-cola/git-cola/issues/159

share/doc/git-cola/thanks.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Thanks
3333
* Michael Homer
3434
* Omega Weapon
3535
* Paolo G. Giarrusso
36+
* Peter Júnoš
3637
* Rustam Safin
3738
* Stefan Naewe
3839
* Steffen Prohaska

0 commit comments

Comments
 (0)