Vincent van Ravesteijn - TNW wrote:
I might be a bit annoying, but let's pretend we don't know the problem
with the filesystem checks. Then, how would you explain to someone that
you're implementing administrative tools, touching many files and
thinking of all different special cases with the risk you forget one,
while you can find out whether a file is loaded just by looping over all
buffers in the memory and comparing a handful of strings to each other.
As I have said somewhere else, you can probably do very very many string
comparisons before the user will notice.
Yes, but the problem is that you CAN'T do this just by comparing
strings. In many cases, to be sure, you could tell that the file is
loaded by comparing strings. But you can't be sure it isn't loaded just
by comparing strings. Maybe it's loaded, but under a different pathname.
Although this will probably be a solution to my problem and it certainly
seems reasonable, I'd would also like to see a FileName class that
compares filenames (in a cross-platform way) that does not access the
filesystem every time.
It is very hard for me to see how to do that. Of course, you can check
if the filesystem is case sensitive and make use of that information in
the string comparisons (as QFileInfo does). But what about absolute and
relative paths? What about symlinked files? Worse, symlinked directories
that occur in the path name? On my main machine, e.g.,
/home/rgheck/files/file.lyx and /mnt/mail/files/file.lyx are the same
file, because /home/rgheck/files is a symlink to /mnt/mail/files. But
not on my laptop. So that's not a cross-platform but a *cross-machine*
issue, and I can't see that there's any possible way to deal with it
except by asking the OS to help us. Maybe it would be possible to cache
that information ourselves somehow. But if we go that way, we accept
that it won't work in every case, because we'd be assuming that the
answer to the question "Do these two filenames point at the same file?"
won't change.
Here's another idea: Have each InsetInclude cache a pointer to the
buffer in which its child resides. When we call
InsetInclude::loadIfNeeded(), we check the buffer list to make sure that
Buffer is still open, which is cheap, and if so, just return it. This
will work in the great majority of cases. We'd need some kind of way to
invalidate the cache when necessary. This would be e.g. when a buffer is
saved under a new name. Then an InsetInclude that pointed to it would
point to the wrong buffer, and it'd need to be reloaded. Are there other
cases? I suppose the same corner cases exist here, too: There could be
changes to the underlying filesystem that caused what used to be the
right buffer no longer to be. But maybe these are not very plausible.
And it would be possible to check for that when LyX wasn't otherwise busy.
rh