-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
use xdiff to implement internal diff algorithm #2732
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2732 +/- ##
==========================================
- Coverage 75% 74.19% -0.82%
==========================================
Files 92 98 +6
Lines 134149 135619 +1470
==========================================
+ Hits 100614 100618 +4
- Misses 33535 35001 +1466
Continue to review full report at Codecov.
|
I have disabled the libxdiff feature on Windows, because the windows Makefile has not been changed yet to include the xdiff source and there were some issues with Also I have not yet included any tests, mainly because I am not sure how to test the resulting diff. Perhaps it would be possible to run Vim recursively inside a terminal window in diff mode and snapshot the resulting diff using |
Nice, I wrote a small tool using xdiff to have nice/fast diffs and avoid messing with the vim source code. |
Ha, I like the name ;) |
I think it is now in a shape, that is safe to include. I can squash it into a single commit if needed. Once this prooved to be stable enough, it might even allow us to get rid of distributing diff together with Vim. I added a couple of tests, implemented the missing 'diffopt' values and made it work on Windows. Tests pass except for some slight differences in the term_dump() function. This can be seen here: https://api.travis-ci.org/v3/job/357269023/log.txt The only difference is this part: @@ -17,4 +17,4 @@
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|X+3#0000000&|f|i|l|e|1| @12|1|,|1| @11|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|A|l@1
-|:+0&&> @73
+|:+0&&> | @72 which I think is a bug in the Which also looks like a bug in the There is still room for improvement though. For one thing one could avoid the whole I/O overhead by making it use without using temporary files. But I have the feeling that is something I cannot easily implement and might take some additional time and effort, which I do not have currently. Second, the And finally it might make sense to allow context lines when parsing the unified diff. This would mean, one needs to actually adjust the hunk addresses ( And finally here are two screencasts how to make use of the new diff algorithms in Vim that comes with xdiff:
Kudos goes to the git developers for developing those parts. |
On my Mac, the build was done successfully, and the resulting Vim worked fine, just the same way as the screencasts are showing. I have used my own Lua script to have Vim accept the output of As to the screen dump test, I got
Also, when I tried to compile the patched source with
|
The screen dump diff looks similar to the one above from the CI. I am not sure, but I think the difference is only that for one dump there a 73 spaces while the result of the test was 1 single space followed by 72 spaces. If you load it into Vim using regarding the C89 issue, I have seen a similar error on Windows and have therefore disabled the inline and attribute flags using 0c40761. Perhaps those should be done unconditionally? (I didn't do it, because I didn't want to change too much of the upstream source. Or is there a similar compile property available to check against when compiling? |
Is libxdiff not available for linking instead of inlining the entire thing (GPL license) into the Vim tree? |
Indeed, I can't distinguish one from another. For convenience, I'm uploading a screenshot obtained by the suggested command:
I think that would be the easiest, practical way to go unless avoiding the inline ends up a noticeable deterioration in performance. That said, I also understand
as, IIRC, an option once introduced to
I'm afraid there's not. |
As far as I can see, there is no |
06c9b5e
to
40a8078
Compare
I tried and failed miserably.
On Mac and on Windows with Mingw. Wow, I did not expect that. So I am rolling it back for now. |
rebased and added another test for 'diffopt+=iwhite' |
What are the implications of pasting GPL-licensed code into Vim's source? |
@justinmk : from a page or so below
|
The library is LGPL-licensed so including the library doesn't require changing the Vim license to GPL. There are other requirements though like mentioning that the library is used and covered by the LGPL (this could be added to the |
The Vim source code is compatible with the GNU GPL so it should be possible to link in the additional libxdiff library which is distributed under the GNU LGPL license. Since the xdiff library is distributed under LGPL 2.1 license, add the license file to the imported source code. Note, that each file has its own copyright section which also mentions who is the author of the code. http://www.xmailserver.org/xdiff-lib.html https://www.gnu.org/copyleft/lesser.html Note, that this includes the xdiff library as it is distributed by the git project (https://git-scm.com/), which is heavily modified from the upstream project (http://www.xmailserver.org/xdiff-lib.html). So it does not contain the complete upstream source but only the needed parts for git (which happen to be also enough for Vim).
This makes it possible to either parse an "ed" style diff (which is the traditional diff) or parse the unified diff. The unified diff is created by the xdiff library. Note: it is highly experimental. Note: it only works, if there are zero context lines. Still this allows a 'diffexpr' to return a unified diff and parse it correctly, as long as it is in a unified diff with zero context lines.
include Vims auto/config.h header and redefine UNUSED according to the HAVE_ATTRIBUTE_UNUSED property.
This is not stricktly required for the xdiff feature but an enhancement to the test suite in general. By default, whenever a SwapFile Exists message is shown in the Test suite, the Test will stop waiting indefinitely until a key is pressed. However this will cause an indefinite hang on the CI infrastructure which will then eventually time out. So avoid this at all by globally setting `:set shortmess+=A`. Since one test however does check the SwapFileExist warning, it needs to be adjusted to remove the 'A' flag from the shortmess setting.
Thanks for those comments. I added a commit mentioning the license of libxdiff and included the LGPL for further distribution. I leave the decision to mention the license in the I also added a second commit to make the tests work better by disableing the SwapFile Exists warning. There is still an ASAN failure which looks like |
[The library is
LGPL-licensed](http://www.xmailserver.org/xdiff-lib.html) so including
the library doesn't require changing the Vim license to GPL. There are
[other requirements though](https://www.gnu.org/copyleft/lesser.html)
like mentioning that the library is used and covered by the LGPL (this
could be added to the `:version` output for instance), and adding a
copy of the GPL and LGPL to the project.
AFAIK it's sufficient to include a copy of the LGPL. A copyright notice
in the binary is only needed if other copyright notices are given, which
I don't think we do anywhere. Mentioning the copyright in the help
somewhere is appropriate.
I also think the code can be modified, since we will distribute it
together with the Vim source code.
Now back to actually making this work. And perhaps there is another
diff library that is better (faster/smaller/etc.).
…--
hundred-and-one symptoms of being an internet addict:
142. You dream about creating the world's greatest web site.
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|
Vim doesn't even put it's own licensing info in the output of |
I thought the license was mentioned there as a lot of tools are displaying that kind of info when running them with |
Okay, this is very highly experimental and still work in progress. But it might be good enough to share what I have, because it seems to pass my very basic tests and I do not know how much time I have to work on it in the future.
This PR imports the libxdiff from the git source tree to implement an internal diff parser (this is from git-2.17.0-rc0, plus some slight style changes [added a couple of casts]). This will make creating diffs a lot faster, since we do not need to shell out to parse the output of
diff foobar foobar.new
.Currently, it runs the xdiff algorithm on the already written temp files tmp_new and tmp_orig and write the result to tmp_diff. We can probably skip writing temp files for creating diffs at all, but I am currently not sure how to do it. So there is some room for even more performance improvements later.
In addition, by using the git diff included xdiff, we can in the future support several improvements to the diff algorithm, e.g. implement patience and histogram diff algorithm, without much fuzz. Currently this is not supported, but it should be easily possible. Also the new indent heuristics from git which is the default starting with 2.14 should be possible with some kind of a switch.
To use the new algorithm, make sure to
:set diffopt+=internal
. As said before, this is highly experimental and might crash :(Also note, I have basically no clue of how to import that part into the Makefile, so I changed src/Makefile manually and it might be cumbersome. But at least, it seems to work :)
BTW: feedback welcome, however, I am not sure how much time in the future I have to work on it. So I leave this here and hopefully this will make it easier to implement an internal diff in Vim.
However, note, I did not yet check which files from git/git source xdiff directory are actually needed. Currently, it will compile a couple of files, which might not (all) be necessary. So it imports a couple of more files than currently needed. But it will enable additional diff options later.
However, once we have this change in place, it should be straight forward to make further adjustments as needed (e.g. do not write temp files at all to speed up diffing even further).
Also this has the further advantage to support unified diffs, when using a custom diffexpression. Currently only ed like style diffs are supported, which kind of sucks and prevents us from simply using
:set diffexpr=git diff
, because unified style diffs seems to be what most tools nowadays understand and ed like style diffs seem kind of traditional and even unsupported.Note, there might be a some disadvantages with using libxdiff:
we got a lot of testing. (git has imported this library around 2006, so there are at least 10
years of thoroughly testing).