If the history file is larger than 4GB on a 32 bit system, fish will
refuse to read it. However the check was incorrect because it cast the
file size to size_t, which may be 32 bit. Switch to using uint64.
Commit fe63c8ad3 (Shadow/override iswdigit instead of changing it at
individual call sites, 2021-10-04) added our own implementation of
iswdigit() to common.h. The "include-what-you-use" rule means that
files that use iswdigit() should now include common.h. Do that.
This avoids using locks for the history file if the file appears to be on
a remote file system, like NFS. This is to avoid hangs if the filesystem
does not support locking.
If locking is not enabled, then in rare cases, history items may be
dropped if multiple sessions try to write to the history file at once.
This is thought to be better than hanging. Hopefully the recent change to
require a trailing newline will avoid propagating partial items.
Rather than making the run-time complexity of the algorithm 𝒪(n) where n
is the length of the string, make it 𝒪(k) where k is the number of
trailing nul bytes.
The second parameter `index` with a default non-value is in lieu of a
helper function that would have had a name like `count_trailing_nuls()`.
This may slightly improve performance by allowing the compiler greater
visibility into what is happing on top of not executing at runtime in
some hot paths, but more importantly, it gets rid of magic constants in a
few different places.
Commands that start with a space should not be written to the history
file. Prior to this change, that was implemented by simply not adding them
to history. Items with leading spaces were simply dropped.
With this change, we add a 'history_persistence_mode_t' to
history_item_t, which tracks how the item persists. Items with leading
spaces are now marked as "ephemeral": they can be recovered via up arrow,
until the user runs another command, or types a space and hits return.
This matches zsh's HIST_IGNORE_SPACE feature.
Fixes#1383