From b58cee1af39b23a3d3dd33de37b02d7165142188 Mon Sep 17 00:00:00 2001 From: Mark Amery Date: Mon, 24 Jun 2024 16:04:06 +0100 Subject: [PATCH 1/3] Add ignoreNewlineAtEof --- src/diff/line.js | 7 +++++++ test/diff/line.js | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/diff/line.js b/src/diff/line.js index 1ad05e20..5d313013 100644 --- a/src/diff/line.js +++ b/src/diff/line.js @@ -45,6 +45,13 @@ lineDiff.equals = function(left, right, options) { if (!options.newlineIsToken || !right.includes('\n')) { right = right.trim(); } + } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) { + if (left.endsWith('\n')) { + left = left.slice(0, -1); + } + if (right.endsWith('\n')) { + right = right.slice(0, -1); + } } return Diff.prototype.equals.call(this, left, right, options); }; diff --git a/test/diff/line.js b/test/diff/line.js index 1461b264..7ce78a68 100644 --- a/test/diff/line.js +++ b/test/diff/line.js @@ -244,4 +244,27 @@ describe('diff/line', function() { {value: 'line\nline', count: 2, added: false, removed: false} ]); }); + + it('ignores absence of newline on the last line of file wrt equality when ignoreNewlineAtEof', function() { + // Example taken directly from https://github.com/kpdecker/jsdiff/issues/324 + expect(diffLines('a\nb\nc', 'a\nb')).to.eql( + [ + { count: 1, added: false, removed: false, value: 'a\n' }, + { count: 2, added: false, removed: true, value: 'b\nc' }, + { count: 1, added: true, removed: false, value: 'b' } + ] + ); + expect(diffLines('a\nb\nc', 'a\nb', { ignoreNewlineAtEof: true })).to.eql( + [ + { count: 2, added: false, removed: false, value: 'a\nb' }, + { count: 1, added: false, removed: true, value: 'c' } + ] + ); + expect(diffLines('a\nb', 'a\nb\nc', { ignoreNewlineAtEof: true })).to.eql( + [ + { count: 2, added: false, removed: false, value: 'a\nb\n' }, + { count: 1, added: true, removed: false, value: 'c' } + ] + ); + }); }); From c10495eeb09fe72c78ab765d030ec2b53d3eae90 Mon Sep 17 00:00:00 2001 From: Mark Amery Date: Mon, 24 Jun 2024 16:10:52 +0100 Subject: [PATCH 2/3] Document new option --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 67010ac5..a8aefc97 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ Broadly, jsdiff's diff functions all take an old text and a new text and perform Options * `ignoreWhitespace`: `true` to ignore leading and trailing whitespace characters when checking if two lines are equal. Defaults to `false`. + * `ignoreNewlineAtEof`: `true` to ignore a missing newline character at the end of the last line when comparing it to other lines. (By default, the line `'b\n'` in text `'a\nb\nc'` is not considered equal to the line `'b'` in text `'a\nb'`; this option makes them be considered equal.) Ignored if `ignoreWhitespace` or `newlineIsToken` are also true. * `stripTrailingCr`: `true` to remove all trailing CR (`\r`) characters before performing the diff. Defaults to `false`. This helps to get a useful diff when diffing UNIX text files against Windows text files. * `newlineIsToken`: `true` to treat the newline character at the end of each line as its own token. This allows for changes to the newline structure to occur independently of the line content and to be treated as such. In general this is the more human friendly form of `diffLines`; the default behavior with this option turned off is better suited for patches and other computer friendly output. Defaults to `false`. From 51c4b521542e64fc9c25b8deb2634670bc24ccb4 Mon Sep 17 00:00:00 2001 From: Mark Amery Date: Mon, 24 Jun 2024 16:12:42 +0100 Subject: [PATCH 3/3] Add release notes --- release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/release-notes.md b/release-notes.md index 6289c904..033a524b 100644 --- a/release-notes.md +++ b/release-notes.md @@ -27,6 +27,7 @@ - [#518](https://github.com/kpdecker/jsdiff/pull/518) **`linedelimiters` no longer exists** on patch objects; instead, when a patch with Windows-style CRLF line endings is parsed, **the lines in `lines` will end with `\r`**. There is now a **new `autoConvertLineEndings` option, on by default**, which makes it so that when a patch with Windows-style line endings is applied to a source file with Unix style line endings, the patch gets autoconverted to use Unix-style line endings, and when a patch with Unix-style line endings is applied to a source file with Windows-style line endings, it gets autoconverted to use Windows-style line endings. - [#521](https://github.com/kpdecker/jsdiff/pull/521) **the `callback` option is now supported by `structuredPatch`, `createPatch`, and `createTwoFilesPatch`** - [#529](https://github.com/kpdecker/jsdiff/pull/522) **`parsePatch` can now parse patches where lines starting with `--` or `++` are deleted/inserted**; previously, there were edge cases where the parser would choke on valid patches or give wrong results. +- [#530](https://github.com/kpdecker/jsdiff/pull/530) **Added `ignoreNewlineAtEof` option` to `diffLines`** ## v5.2.0