Date: Thu, 04 Jul 2024 10:47:12 -0700 From: "Greg A. Woods" <wo...@planix.ca> Message-ID: <m1sPQY4-003UYYC@more.local>
| Shouldn't the on-disk history initially be prepended to in-core history | (which might only be what has been sourced so far from the profiles etc.)? That might be nice, perhaps, though it would be a little weird if one did: HISTFILE=x HISTFILE=y HISTFILE=z and the data appeared in history in the order z y x ... I'm also just using the libedit (editline) history facilities - which is what sh has always used for its history. They have supported reading/writing files for ages, just sh didn't make use of that functionality (that only those minor changes were needed was how I made this stuff mostly work in a day and a half...) libedit has a "load" function, but it is "load and append", there's no "load and prepend" to make use of, so either libedit would need new functionality, or sh would need to duplicate a whole bunch of libedit code, or do some exotic manipulation: save history to temp file, clear hist buffer, load HISTFILE, load temp file, remove temp file. Only data typed by the user on stdin ever counts (or more correctly I think, only data read by the shell from stdin, in an interactive shell). If HISTFILE is set in the environment, or a startup script, then that setting happens before there's any possibility of any history eligible commands being entered, so whether we append or prepend the contents of the file makes no difference, the file contents will be everything at that point. It only makes a difference if HISTFILE is set (perhaps again) later. | Then, if HISTAPPEND is set any new history written to the file since it | was last read could be appended to in-core history. That one I don't think libedit supports. It might be possible to make work in sh, but I'm not sure that's what most people want. Eg: I have a sh function: !!() { fc -s -1; } which does what a simple "!!" does in csh (repeat the last command, the most recent in history ... the function just because that's my ancient finger muscle memory, and because it is shorter than typing the fc command) but whether one uses !! (or something like it) or just "fc -s -1", I doubt anyone would like it much if it repeated the most recent command that was made in any sh sharing a HISTFILE, so I think attempting to make that suggestion work would be something of a disaster. If someone really wanted that, then (after HISTFILE appears in sh, assuming that actually does happen) one could do PS1='$(HISTFILE=${HISTFILE})$ ' (along with set -o promptcmds) which would cause the shell to re-read the history file every time PS1 is printed - which would (almost) do what you're suggesting - the effect would be very similar, assuming HISTAPPEND is set as well. | Do you have plans for adding HISTSIZE as well? No need, that's been there for a long time (even documented). However, there's a bug, where if one attempts to set HISTSIZE to a non-numeric value which doesn't start with '-' an error will be generated (that's OK, and will remain, other than the "except -*" part which is just silly), but in existing shells, including today's HEAD, if you have HISTSIZE in the environment with a bad value like that, the shell won't start at all, just issues an error and exits. try: HISTSIZE=foo /bin/sh That's not good, but fixing it properly is a non-trivial change (I might make a temporary change to just ignore such bad settings, rather than error them, just to avoid this issue - that kind of change could be pulled up to -9 and -10). I'm not sure what other shells do, but in libedit, its internal version of HISTSIZE seems to be the number of history entries that the history mechanism won't allow to exist (so HISTSIZE=100 -- the default in sh -- means up to 99 history entries can exist). If it would be desirable, I could easily "fix" that (if needed) by just adding 1 to the value before passing it to the libedit history management routines. Note: setting HISTSIZE to 1 or 2 means 1 history element exists, as we don't allow none to be there, but setting it to 0 will cause sh to generate "internal error" for some attempted history manipulation, such as "fc -l" ... the "add one" solution is looking better and better... though I think an internal sh code change will be a better solution to that particular problem - that isn't a problem you'd normally ever see now, but: /bin/sh -csi 'fc -l' will make it happen in today's sh, regardless of what HISTSIZE is set to, as when that fc command is run, the history buffer is certain to be empty currently - the "si" are needed to allow history to be enabled at all, without them you'd just get a more reasonable "history is not active" error). Note this internal error isn't fatal to the shell, so after the above error you're still in an interactive sh. kre ps: if these changes go in, one more I forgot to mention yesterday, is that there will be a new "fc" option (-z) to clear the history buffer completely.