dotnet-shell / Shell

The C# script compatible shell
https://dotnet-shell.github.io/
MIT License
61 stars 6 forks source link

Best practice for environment variables / exports? #5

Closed MostHated closed 3 years ago

MostHated commented 3 years ago

Hey there, I tried looking through the API site under Shell and saw Paths, AddCmdAlias, and AddCSAlias, and the like, then I tried to use the search for env / environment but didn't see anything come up. I was wondering if there was a best practice for creating/using env variables / export data?

I tried a few dotnet methods from the shell just to see what may or may not work, such as:

var p = System.Environment.GetEnvironmentVariable("path", System.EnvironmentVariableTarget.User)  
Console.WriteLine(p);

var p = System.Environment.GetEnvironmentVariable("path", System.EnvironmentVariableTarget.Machine)                                 
Console.WriteLine(p); 

But both came up empty. I was able to use var p = `echo $PATH`; and then write that to console just fine, of course, but I wasn't sure if that would be the "proper" way to go about it. Is the overall intention to use the underlying system's data for things like setting default location path for specific things, etc, or maintain that within the dotnet shell itself?

The main reason I ask, is that my prompt shows up as

# -- Typical prompt in zsh
~
zsh > 

# -- Prompt when using dotnet-shell with Starship
%{%}~%{%}
zsh %{%}>%{%}

Starship uses a config file, which you set via export STARSHIP_CONFIG="$HOME/.config/starship/starship.toml", my first thought when it was displaying oddly, was that using it in dotnet shell, it must not know where my config is, but I guess technically starship is just grabbing it from zsh, since var prompt = `starship prompt ..etc`; is being executed on the underlying shell and then returned, and it looks like it technically is using my settings, they just didn't show up right:

That said, I currently have a few starship configs, one for zsh, one for PScore on Linux, then one for Pwsh on Windows which are on a shared drive. For Pwsh, I had to set the env variables within the PSCore profile, as it doesn't just pick them up as is:


if ($IsWindows) {
    $ENV:STARSHIP_CONFIG = "${DOTROOT}/config/starship/starship.toml"
    ...
} else {
    $ENV:STARSHIP_CONFIG = "${DOTROOT}/config/starship/starship_linux.toml"
}

That is what lead me to this post, (which has became much longer than I had anticipated sorry about that), I wasn't quite sure if I should be relying on the shell to pick things like that up on it's own, if I should be grabbing them from the existing environment, or if there was a way I just am not seeing to set them specifically for dotnet shell along with Paths and Aliases?

Thanks, -MH

i-am-shodan commented 3 years ago

I'm going to be out for a while but in general variables are treated as environment variables if they are not null. If bash is your shell type.

var TEST123="hello";

then run the command export

You'll see that TEST123 is now an env variable.

MostHated commented 3 years ago

You mentioned being out for a while, so no worries about replying until you are back.

It's a total hack, and will probably end up messing something up down the road, but I got my prompt fixed up using the below. I am not sure where those characters are coming from, exactly.


// -- Before -----
%{%}~%{%}
zsh %{%}>%{%}
// ---------------

string CleanString(string inputStr)
{
    HashSet<char> removeChars = new HashSet<char>("{}%");
    StringBuilder result = new StringBuilder(inputStr.Length);
    foreach (char c in inputStr)
        if (!removeChars.Contains(c))
            result.Append(c);
    var str = result.ToString();
    if (str.Contains("zsh ")) str = str.Replace("zsh ", "dotnet ");
    return str;
}

// ...
return ColorString.FromRawANSI(CleanString(prompt));

// -- After -----
~
dotnet >
// --------------

The thing I actually wanted to report, though, is that while messing around with that, I noticed that in dotnet-shell, no terminal input that uses a modifier work. Such as ctrl+c to interrupt or clear the current terminal input. As well as ctrl, or alt + left or right arrow to move the cursor.

Left or Right on their own work to move a character at a time, and ctrl+shift+v works to paste (slowly), but that and standard character input are all that seem to work.

To make sure it wasn't something wrong with Alacritty, I tried in a few terminals, including the default Gnome Terminal, and all of that seemed to have the same symptoms.

i-am-shodan commented 3 years ago

Interesting. I use dotnet-shell via Windows Terminal and WSL2. Ctrl+C and Ctrl+Z definitely work for me there as well as running in Windows conhost.

Can you try Ctrl+Z as that explicitly uses a Linux interrupt handler from mono and is needed for backgrounding processes. If that is working it looks like that needs to be extended to SIGINT.

The dotnet console implementation is pretty poor and there is an issue to make handling more consistent in the dotnet project.

MostHated commented 3 years ago

Hitting ctrl + Z looks like it makes the current cursor go to a new line.

i-am-shodan commented 3 years ago

Looks like I’m going to have to break out the quality Linux UI experience when I get back.

MostHated commented 3 years ago

If it helps any, I fully intend on trying to use this as my daily driver. Being able to use C# for my desktop scripting needs has been at the top of my "can't wait until one-day" list for years.

i-am-shodan commented 3 years ago

It does help! I got so annoyed with bash I wrote this!

Pretty sure it will be a simple fix with a debugger attached.

i-am-shodan commented 3 years ago

I have news. I have installed Ubuntu 20.04 and the latest version of dotnet-shell without tmux. Using the default Ubuntu terminal which I'm assuming is Gnome-terminal I don't see any issues. Here is my test:

dotnet-shell
ping 8.8.8.8

hit Control-C - ping correctly terminates

ping 8.8.8.8

hit Control-Z - ping is correctly backgrounded

fg

ping resumes and can be killed with Control-C

I tested with starship in case that was the issue - still worked.

Reading through your bug report again I think the issue you are having is also the reason why you are getting garbage characters that you have to clean. In my distro - clean install of Ubuntu - I don't get any of those garbage characters so there is something wrong there.

I recorded a video to demonstrate what I see although the fonts are a bit screwed and for some reason asciinema doesn't show the prompt correctly at the start it all looks good on my terminal.

To set your config file you should be able to use

var STARSHIP_CONFIG=Path.Combine(Shell.HomeDirectory,".config/starship/starship.toml");

If you put that in the Shell.Prompt function before you call starship is will create a temporary environmental variable which starship will be able to see.

MostHated commented 3 years ago

I have tmux, I installed it as soon as you mentioned it was ideal to have it and not having it is what caused the initial issue I ran into. I will remove it and see if that makes a difference.

Edit - I removed it, tried it, then added tmux back again and it looks like Ctrl + C works for stopping ping, etc, but if I begin to type a command in the terminal, then hit Ctrl + C to clear out the line, that doesn't work. It looks like it's the same both with and without tmux. I suppose I assumed that since it didn't clear out the line of text, it seemed like it wasn't doing anything, so that is my bad. I use the Ctrl + C to clear out text pretty regularly, though.

Then, while not the end of the world, but particularly useful with long commands/lines of text, holding Ctrl while pressing left or right arrow to skip words when moving the cursor was really the only other thing that "popped out" in terms of usability. Mixing those two together, if you paste a long line of text, not only can you not Ctrl + C to get rid of it, you can't delete entire words at once quickly, you just have to sit there holding or repeatedly pressing backspace. It ends up being faster to just close the terminal all together and start up a new one, lol.

i-am-shodan commented 3 years ago

It shouldn't be difficult to clear the line on Ctrl+C I will check

i-am-shodan commented 3 years ago

New cursor keys in https://github.com/dotnet-shell/Shell/releases/tag/v1.0.0.8

MostHated commented 3 years ago

Awesome, just tested it out. Works great. :+1:

I know I have been asking a lot and I feel bad about it, but one last thing that can go on the backburner for whenever, as its not as important and would be a "nice to have" would be similar to ctrl + arrow, being able to ctrl + backspace to delete words backwards. That's hopefully the last thing I will have to bother you about, lol.

i-am-shodan commented 3 years ago

The console implementation is quite easy to adapt so Ctrl backspace should be quite easy.

If you have a look at the change it was something like 40 lines. I’ll see if I can bash something out.

i-am-shodan commented 3 years ago

In latest version