Ticket #40964

per-session history

Open Date: 2020-11-15 07:28 Last Update: 2020-11-22 15:52

Reporter:
(Anonymous)
Owner:
(None)
Status:
Open
Component:
(None)
MileStone:
(None)
Priority:
5 - Medium
Severity:
5 - Medium
Resolution:
None
File:
None
Vote
Score: 0
No votes
0.0% (0/0)
0.0% (0/0)

Details

i find it very confusing/disturbing that when i enter a command in one terminal, let's say in ~/project1, and then switch to another terminal which is in ~/project2, and hit cursor-up, to *not* get the last command i entered in that very same terminal, but the one i entered in project1. i've studied the manual to see whether i can make the behaviour like in bash, but it doesn't seem to be possible at the moment. please consider adding this as a configuration option, because it is annoying to such a degree that i consider to switch back to bash, even though yash is much nicer in many other aspects. it already happened to me several times that i hit cursor-up-enter as i'm accustomed to to repeat the last command (like e.g. "make") but instead have a completely unrelated command show up (and starting), like youtube-dl something. i know that bash loses some commands of the history (afaik it writes to .bash_history whenever the bash session is closed from the point where the history file was when that shell was started), but that's not really an issue for me. the optimal behaviour in my opinion would be that yash keeps updating the history file as it does currently, but doesn't reload its contents after a change in active sessions, so the current yash session stays unaware of commands entered in other shells.

Ticket History (3/5 Histories)

2020-11-15 07:28 Updated by: None
  • New Ticket "per-session history" created
2020-11-18 06:38 Updated by: None
Comment

head 1===

i came up with a patch that makes the behaviour as in bash, however it seems some junk is written in the histfile.

patch follows, unfortunately i didnt find out what markup language this forum uses.

https://0x0.st/i59D.patch

<pre> this patch makes it so history between yash instances isn't synchronized and never reloaded from file during a session. on exit it's written to file as usual. this is just like the behaviour of bash.

yash's default behaviour is that you enter a command in term1, then hit cursor-up in term2, and you suddenly have the command from term1 in the history.

diff --git a/history.c b/history.c index 6e9143b..86a8524 100644 --- a/history.c +++ b/history.c @@ -1062,7 +1062,7 @@ void add_history(const wchar_t *line)

if (histfile != NULL)
lock_histfile(F_WRLCK);
update_time();

- update_history(true); + //update_history(true);

for (;;) {
size_t len = wcscspn(line, L"\n");

@@ -1141,6 +1141,7 @@ const histlink_T *get_history_entry(unsigned number)

/* Calls maybe_init_history' or update_history' and locks the history. */ void start_using_history(void) {

+#if 0

if (!hist_lock) {
if (histfile != NULL) { lock_histfile(F_RDLCK);

@@ -1153,12 +1154,17 @@ void start_using_history(void)

} hist_lock = true;
}

+#else + update_time(); +#endif

} /* Unlocks the history. */ void end_using_history(void) {

+#if 0

hist_lock = false;

+#endif

} #endif /* YASH_ENABLE_LINEEDIT */

diff --git a/yash.c b/yash.c index 66e8cb3..6d7bd6e 100644 --- a/yash.c +++ b/yash.c @@ -236,6 +236,12 @@ int main(int argc, char **argv)

shell_initialized = true;

+#if YASH_ENABLE_LINEEDIT + /* if line editing and interactive and connected to a terminal, start history */ + if (is_interactive && isatty(STDIN_FILENO) && isatty(STDERR_FILENO)) + maybe_init_history(); +#endif +

if (shopt_cmdline)
exec_wcs(input.command, inputname, true);
else

</pre>

2020-11-22 12:05 Updated by: magicant
Comment

Thank you for the feature request.

I used to think the bash-like behavior could be implemented by tweaking the yashrc file, but now I think that will not fully work since the abilities of the history and fc built-ins are limited. I consider adding an option to switch the behavior.


Some workarounds that can be done in the current version of yash:

Unset the HISTFILE variable in yashrc, then yash instances do not share history, but the history is lost when you close yash. To save history over sessions, use the history built-in to save and load the history to and from a file. To save the history automatically when the shell is closed, set the EXIT trap in yashrc. Note that this will overwrite history that may have been written by another shell instance.

2020-11-22 15:17 Updated by: None
Comment

thanks for your reply. what came to my mind after spending a couple hours with history.c was that instead of writing pid on start and end, every line could be prefixed by pid in hex, afaik pid can never be > 0xffff so 4 bytes additional should be sufficient. on start the entire hist file is loaded, but after that only lines with own pid will be added to history in "bash mode", in yash mode any. i didn't actually figure out the current purpose of saving the pids, but i saw in strace that other pids active were "killed" - maybe a signal sent? though i dont think this is actually necessary when flock() is used. alternatively the file can be opened in append-only mode, but then duplicates can't be removed (although the writing process could simply not write commands it has buffered in memory).

2020-11-22 15:52 Updated by: magicant
Comment

Yash saves PIDs in the history file and sends signals to other yash processes in order to check if there are other yash processes sharing the same history file. To prevent the command number of history items from increasing forever, yash resets the command number after removing old items, counting from 1 again. This is done only when there are no other shell processes because POSIX requires to do so.

Attachment File List

No attachments

Edit

You are not logged in. I you are not logged in, your comment will be treated as an anonymous post. » Login