From 58d22e0c6edab4cb68af63d3ccaafcb875be995d Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Sun, 20 Oct 2019 11:47:04 +0200 Subject: [PATCH] Keep last file positions in last-use ordering Using a map would sort the elements in alphabetic ordering, which means that when the number of elements is larger than 100, the wrong elements get pruned. This commit uses a list instead. Searching an item needs linear time, but this should not be a problem for a list with less than 100 elements. Fixes bug #10310. --- src/BufferView.cpp | 3 ++- src/Session.cpp | 36 ++++++++++++++++++++++-------------- src/Session.h | 18 +++++++++--------- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 97adab820c..b960da6399 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -345,9 +345,10 @@ BufferView::~BufferView() // That is to say, if a cursor is in a nested inset, it will be // restore to the left of the top level inset. LastFilePosSection::FilePos fp; + fp.file = buffer_.fileName(); fp.pit = d->cursor_.bottom().pit(); fp.pos = d->cursor_.bottom().pos(); - theSession().lastFilePos().save(buffer_.fileName(), fp); + theSession().lastFilePos().save(fp); if (d->last_inset_) d->last_inset_->setMouseHover(this, false); diff --git a/src/Session.cpp b/src/Session.cpp index eb0fc64829..394788381e 100644 --- a/src/Session.cpp +++ b/src/Session.cpp @@ -196,10 +196,10 @@ void LastFilePosSection::read(istream & is) getline(itmp, fname); if (!FileName::isAbsolute(fname)) continue; - FileName const file(fname); - if (file.exists() && !file.isDirectory() + filepos.file = FileName(fname); + if (filepos.file.exists() && !filepos.file.isDirectory() && lastfilepos.size() < num_lastfilepos) - lastfilepos[file] = filepos; + lastfilepos.push_back(filepos); else LYXERR(Debug::INIT, "LyX: Warning: Ignore pos of last file: " << fname); } catch (...) { @@ -212,26 +212,34 @@ void LastFilePosSection::read(istream & is) void LastFilePosSection::write(ostream & os) const { os << '\n' << sec_lastfilepos << '\n'; - for (FilePosMap::const_iterator file = lastfilepos.begin(); - file != lastfilepos.end(); ++file) { - os << file->second.pit << ", " << file->second.pos << ", " - << file->first << '\n'; - } + for (auto const & file_p : lastfilepos) + os << file_p.pit << ", " << file_p.pos << ", " << file_p.file << '\n'; } -void LastFilePosSection::save(FileName const & fname, FilePos const & pos) +void LastFilePosSection::save(FilePos const & pos) { - lastfilepos[fname] = pos; + // Remove element if it was already present. Iterating should + // not be a problem since the list is small (<100 elements). + for (FilePosList::const_iterator it = lastfilepos.begin(); + it != lastfilepos.end(); ++it) + if (it->file == pos.file) { + lastfilepos.erase(it); + break; + } + + // insert new element at front. + lastfilepos.push_front(pos); } LastFilePosSection::FilePos LastFilePosSection::load(FileName const & fname) const { - FilePosMap::const_iterator entry = lastfilepos.find(fname); - // Has position information, return it. - if (entry != lastfilepos.end()) - return entry->second; + for (auto & fp : lastfilepos) + if (fp.file == fname) + // Has position information, return it. + return fp; + // Not found, return the first paragraph return FilePos(); } diff --git a/src/Session.h b/src/Session.h index 31ffee8841..65bf19de13 100644 --- a/src/Session.h +++ b/src/Session.h @@ -16,7 +16,7 @@ #include "support/FileName.h" #include "support/types.h" -#include +#include #include #include @@ -148,12 +148,13 @@ public: /// struct FilePos { FilePos() : pit(0), pos(0) {} + support::FileName file; pit_type pit; pos_type pos; }; /// - typedef std::map FilePosMap; + typedef std::list FilePosList; public: /// @@ -165,13 +166,12 @@ public: /// void write(std::ostream & os) const; - /** add cursor position to the fname entry in the filepos map - @param fname file entry for which to save position information - @param pos position of the cursor when the BufferView is closed. + /** add cursor position to the fname entry in the filepos list + @param pos file name and position of the cursor when the BufferView is closed. */ - void save(support::FileName const & fname, FilePos const & pos); + void save(FilePos const & pos); - /** load saved cursor position from the fname entry in the filepos map + /** load saved cursor position from the fname entry in the filepos list @param fname file entry for which to load position information */ FilePos load(support::FileName const & fname) const; @@ -181,8 +181,8 @@ private: unsigned int const num_lastfilepos; - /// a map of file positions - FilePosMap lastfilepos; + /// a list of file positions + FilePosList lastfilepos; };