[meld] filediff: Fix chunk deletion for CRLF endings (bgo#778856)
- From: Kai Willadsen <kaiw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [meld] filediff: Fix chunk deletion for CRLF endings (bgo#778856)
- Date: Sat, 18 Feb 2017 23:09:47 +0000 (UTC)
commit 83022aeb170aff16acf503bbcb1438581638a5b8
Author: Kai Willadsen <kai willadsen gmail com>
Date: Sun Feb 19 09:04:22 2017 +1000
filediff: Fix chunk deletion for CRLF endings (bgo#778856)
The problem here was that we were always only going backwards by a
single character for the last line in a file, even when file endings
were CRLF. The line ending behaviour here is weird, because of how
Gtk.TextBuffer handles the last line in a file, but it appears to be
correct.
Also added a test for this case.
meld/filediff.py | 5 ++++
test/test_chunk_actions.py | 57 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+), 0 deletions(-)
---
diff --git a/meld/filediff.py b/meld/filediff.py
index ff0ab46..8b05609 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -1816,7 +1816,12 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
b0 = self.textbuffer[src]
it = b0.get_iter_at_line_or_eof(chunk[1])
if chunk[2] >= b0.get_line_count():
+ # If this is the end of the buffer, we need to remove the
+ # previous newline, because the current line has none.
it.backward_char()
+ newline_type = b0.data.sourcefile.get_newline_type()
+ if newline_type == GtkSource.NewlineType.CR_LF:
+ it.backward_char()
b0.delete(it, b0.get_iter_at_line_or_eof(chunk[2]))
mark0 = b0.create_mark(None, it, True)
mark1 = b0.create_mark(None, it, True)
diff --git a/test/test_chunk_actions.py b/test/test_chunk_actions.py
new file mode 100644
index 0000000..b233303
--- /dev/null
+++ b/test/test_chunk_actions.py
@@ -0,0 +1,57 @@
+
+from unittest import mock
+
+import pytest
+from gi.repository import GtkSource
+
+import meld.meldbuffer
+from meld.filediff import FileDiff
+from meld.matchers.myers import DiffChunk
+
+
+@pytest.mark.parametrize("text, newline, expected_text", [
+ # For the following tests, newlines and text match
+ # Basic CRLF tests
+ ("ree\r\neee", GtkSource.NewlineType.CR_LF, 'ree'),
+ ("ree\r\neee\r\n", GtkSource.NewlineType.CR_LF, 'ree\r\neee'),
+ # Basic CR tests
+ ("ree\neee", GtkSource.NewlineType.CR, 'ree'),
+ ("ree\neee\n", GtkSource.NewlineType.CR, 'ree\neee'),
+ # Basic LF tests
+ ("ree\reee", GtkSource.NewlineType.LF, 'ree'),
+ ("ree\reee\r", GtkSource.NewlineType.LF, 'ree\reee'),
+
+ # This case is intentionally incorrect; the newline information is
+ # wrong for the text, and the result is also incorrect.
+ ("ree\r\neee", GtkSource.NewlineType.CR, 'ree\r'),
+])
+def test_delete_last_line_crlf(text, newline, expected_text):
+ filediff = mock.Mock(FileDiff)
+
+ with mock.patch.multiple(
+ 'meld.meldbuffer',
+ bind_settings=mock.DEFAULT, meldsettings=mock.DEFAULT):
+ with mock.patch('meld.meldbuffer.MeldBuffer.set_style_scheme'):
+ meldbuffer = meld.meldbuffer.MeldBuffer()
+ meldbuffer.set_text(text)
+
+ def make_last_line_chunk(buf):
+ end = buf.get_line_count()
+ last = end - 1
+ return DiffChunk('delete', last, end, last, end)
+
+ start, end = meldbuffer.get_bounds()
+ buf_text = meldbuffer.get_text(start, end, False)
+ print(repr(buf_text))
+
+ with mock.patch.object(
+ meldbuffer.data.sourcefile,
+ 'get_newline_type', return_value=newline):
+ filediff.textbuffer = [meldbuffer]
+ filediff.textview = [mock.Mock()]
+ FileDiff.delete_chunk(filediff, 0, make_last_line_chunk(meldbuffer))
+
+ start, end = meldbuffer.get_bounds()
+ buf_text = meldbuffer.get_text(start, end, False)
+ print(repr(buf_text))
+ assert buf_text == expected_text
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]