chrisant996 / clink-flex-prompt

Flex prompt for Clink
MIT License
135 stars 17 forks source link

Feature request: Add env var module #40

Closed sebthom closed 1 year ago

sebthom commented 1 year ago

Would be great to be able to do something like this out of the box:

flexprompt.settings.left_prompt = "{env:HOSTNAME:color=magenta}{cwd}"
chrisant996 commented 1 year ago

I infer that you're requesting for someone to write a {env} module that shows the value of a specified environment variable, using a different (and simpler but more limited) color syntax than other modules.

Am I understanding correctly?

I assume it's because the request is not actually about HOSTNAME, and is instead about generic environment variables? Since the hostname is already covered by the {user} module, {user:type=computer:color=magenta}.

But why stop at environment variables? Seems like any text might be desirable, e.g. `"{env:Host %HOSTNAME%:38;5;20}".

And presumably it would be desirable to be able to include colons or braces, so some kind of escaping mechanism would be needed as well. But if color went first, then everything after the color would be the text, so only } would be unusable, which would essentially avoid needing an escaping mechanism.

It seems like a pretty quick and easy module to write. Would you like to do it?

sebthom commented 1 year ago

You inferred correctly. Yes, it would be nice to have a generic module that allows to display the content of any environment variable.

To answer your last question honestely: no, I would not like to implement it. 🙂 I don't enjoy programming in Lua.

Nevertheless, I tried to create a module but it doesn't work. flexprompt.parse_arg_keyword returns nil.

-- usage: "env:var=hostip:color=magenta"
local function env_module(args)
  local env_var = flexprompt.parse_arg_keyword(args, "var")
  local color = flexprompt.parse_arg_keyword(args, "color")
  print(args)    -- prints var=hostip:color=magenta
  print(env_var) -- prints nil
  print(color)   -- prints nil
  return os.getenv(env_var), color
end

flexprompt.add_module("env", env_module)
chrisant996 commented 1 year ago

Look at the comments above parse_arg_keyword and parse_arg_token.

In the syntax you originally propose, there are no keyword names, so neither of those functions would be relevant.

In the example code and new syntax "env:var=hostip:color=magenta", the latter would be correct, flexprompt.parse_arg_token. Replacing parse_arg_token with parse_arg_keyword makes your code work.

But ideally, you wanted to use a custom args format that's different from other modules. That's fine, but you have to parse it yourself.

Since you want a simple list of : delimited strings, string.explode() is what you want.

    local strings = string.explode(args, ":")

    local env_var = strings[1] or ""
    local color = strings[2] or ""
    if env_var == "" or color == "" then
        return
    end

    local text = os.getenv(env_var) or ""
    return text, color
sebthom commented 1 year ago

OK, thanks for the explanations. I am now using this:

local function env_module(args)
  local env_var_name, color = args:match("([^:]+):(.+)")
  if env_var_name == "" then
      return
  end
  return os.getenv(env_var_name) or "", color
end

flexprompt.add_module("env", env_module)

Unfortunately it does not work as I expected, os.getenv() does not return anything for environment variables I set inside the current command prompt session after clink was loaded. Is there a way that clink somehow updates it's internal lua interpreter with the current effective env vars?

chrisant996 commented 1 year ago

Unfortunately it does not work as I expected, os.getenv() does not return anything for environment variables I set inside the current command prompt session after clink was loaded.

Can you describe specifically how are you setting the environment variables inside the current command prompt session after clink was loaded? What variable name are you trying to use?

Maybe the variable is being set in a separate spawned sub-cmd.exe instance, not in the current command prompt session. Or maybe a setlocal in a script is causing the environment variable value to be reverted after it's been set. Or maybe the variable name is misspelled.

Using "{env:foo:green}{cwd}", if you run set foo=hello then the prompt will become hello C:\curdir.

Any variable you can print via set varname will show up in the prompt with "{env:varname:magenta}".

Is there a way that clink somehow updates it's internal lua interpreter with the current effective env vars?

That isn't how it operates. os.getenv("foo") directly asks the OS for the current value of %FOO% in the current cmd.exe process. If it's not returning a value, then the variable isn't set or the variable name is misspelled.

sebthom commented 1 year ago

Yeah it was a setlocal somewhere in a batch file. Works now.

sebthom commented 1 year ago

@chrisant996 thanks!!

sebthom commented 1 year ago

@chrisant996 would it be possible for you to create a new release of clink-flex-prompt?

I think you can also remove the TBD: publish via scoop? from the readme, since it is already on scoop https://github.com/ScoopInstaller/Main/blob/master/bucket/clink-flex-prompt.json