make it easier to find out how a var was `set`
Hello,
I ran into a problem when my home folder was moved and the default environment variable values in fishd.fish --debug-level=5 I still wasn't able to ascertain if the default values had been hard-coded, compiled using #ifdefs , etc.
Only a grep of the faulty values in all files with "fish" in their name (grep yada $(find -name "*fish*" ~)) gave me a hint and rm ~/.config/fish/fishd.* gave me resolve.
TL;DR Please adding logging to the cpp-function called when calling set in fish.
Cheers!
What sort of messages would have been useful here? Using set -U, set -g and set -l can help with revealing the scope of a variable.
As a side note, fish manages somewhat poorly with a change or movement in home directory, and it's something that could be improved.
Ah, good question. I was a bit hasty in creating the issue.
Looking at all the facts again what would've been helpful was that fishd.<hostname> was being read at all and the result of set or another command e.g 0,1,sucess,error, etc.
Here's an example of set being executed (in config.fish at startup)
fish: Exec job 'set -g IFS \n\ \t' with id 2
fish: Set status of set -g IFS \n\ \t to 1 using short circuit
fish: Job is constructed
fish: Continue job 2, gid 0 (set -g IFS \n\ \t), COMPLETED, NON-INTERACTIVE
The "Set status of set [...]" - is "set [...]" the job name ? What does the 1 status mean?
If it fails would there be FAILED instead of COMPLETED ?
Yes - that is diagnostic on the status of a job.
The fishd.hostname file is read by the fishd process, and instances of the fish process don't actually know what the file is called. The 'right way' to interact with it is using set -U, which might have helped in this instance.
set -U would've forced the value to be universal and thus resolve the issue, but I wouldn't have found the root that way. I wouldn't have known where the variable was being set and when.
Is there a function to tell me the scope of an existing variable? set -q just tests for presence and not scope.
You can test for scope by combining the -q and scope operators.
> set -g somevar 1
> set -q somevar; echo $status
0
> set -qU somevar; echo $status
1
> set -qx somevar; echo $status
1
> set -qg somevar; echo $status
0
There are two things we should do here. First, improve the debug messages so that when a var is created, modified, erased that action is logged at a debug level (probably two or three since this is fairly fundamental information). Second, add state to each var to track where it was modified. Then add an option to the set command (perhaps set -qv $varname) to display that state. This is similar to Vim's ability to ask where an option was last set; e.g., :verbose set expandtab? might output
expandtab
Last set from /usr/local/Cellar/vim/8.0.0084/share/vim/vim80/indent.vim
Note that as of today if you build from the git master or major branches you no longer need to do the series of set -q statements in @zanchey's comment to figure out which scopes a variable appears in. You can simply do set --show varname. Now that we have that feature I would love to track where the var was last set and include that in the set --show output.