fix: read_history() multiple times will add repeat histories to histo… #101
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
…ry lists
Issue Description:
When sdcv found multiple items, whatever your choice is, sdcv will add double the current history entries to history file. For example, if current history is "a\nb", you search akjk and there's multiple results, whatever you choose, even -1, after this is done, the history file will be rewritten to "a\nb\nakjk\na\nb", note here \n is newline character. So if you have 500 lines of history, you search akjk and there's multiple results, you choose -1, after done there's 1001 lines of history.
How to reproduce:
You can download this dictionary file
https://github.com/skywind3000/ECDICT/releases/download/1.0.28/ecdict-stardict-28.zip and put into your dictionary directory, on Arch, with AUR, you can install from https://aur.archlinux.org/packages/stardict-ecdict. Then, make sure you also add the dictionary name to ~/.config/sdcv_ordering if you have one. Add some lines to your history file if you do not have. Then search for "akjk" with sdcv, e,g,
sdcv akjk
, then it will prompt you to choose, you can choose -1, then ctrl-d to exit. Expected result is history file add akjk at the end. Actual result is history file now contain original content + akjk + original content duplicate as I described in the issue description.Fix and reasons:
I'm a hobbyist and I'm not a professional, I haven't use C++ for years so many of my writings is very likely wrong. After some trail and error, I found that call read_history() multiple times will add repeat histories to history lists. In the commit d2327e2, a new IReadLine object is created (note name changes, also note I know this description of a IReadLine object is wrong). Here's a permalink:
sdcv/src/libwrapper.cpp
Line 418 in 49c8094
choice_readline
is it called read_history() again from ./src/readline.cpp constructor, because there's already a IReadLine objectio
constructed at ./src/sdcv.cpp. When read_history() is called twice, there's a "history lists" read from history file first then append from history file again, so when you destruct IReadLine object with write_history() in ./src/readline.cpp, the history file contain duplicate content after write. Here are permalinks:sdcv/src/readline.cpp
Line 88 in 49c8094
sdcv/src/readline.cpp
Line 94 in 49c8094
So my fix is to just to use
io
IReadLine object and not to create a newchoice_readline
object.Misc:
During my trial and errors process, I made an example code to show read_history()'s weird behavior. I did not dig deeper, I just guess maybe there's some kind of werid history list as mentioned in https://tiswww.cwru.edu/php/chet/readline/history.html#History-List-Management.
Here's the example code a.c, note you need to include stdio.h, readline/history.h, and readline/readline.h. I did not include them here because commit message seems will make them comment.
Here's the content of history.txt:
After build and run, as you can guess, history2.txt is same as history.txt. But history3.txt and history4.txt content are: