chrisant996 / clink

Bash's powerful command line editing in cmd.exe
https://chrisant996.github.io/clink/
GNU General Public License v3.0
3.44k stars 135 forks source link

color.env_variables option #666

Open nikitarevenco opened 2 weeks ago

nikitarevenco commented 2 weeks ago

Hi, I would love to be able to specify in my config file a color for env variables like %userprofile% to stand out from other text.

chrisant996 commented 2 weeks ago

Something like this?

I'll have to think about about whether it fits better in clink-completions, or clink-gizmos, or directly in Clink.

I'm leaning AWAY from putting it directly in Clink, because there's no way to do it accurately for compound if and for commands when delayed expansion is enabled. Also, it obviously only handles %name% and not !name! or etc.

_highlightenvvars.lua

settings.add("color.envvars", "", "Color for environment variables")

local ev = clink.classifier(1)
function ev:classify(commands) -- luacheck: no unused
    local color = settings.get("color.envvars") or ""
    if color ~= "" and commands and commands[1] then
        local line_state = commands[1].line_state
        local classifications = commands[1].classifications
        local line = line_state:getline()
        local in_out = false
        local index = 0

        while true do
            local next = line:find("%", index + 1, true--[[plain]])
            if not next then
                break
            end
            in_out = not in_out
            if in_out then
                index = next
            else
                local value = os.getenv(line:sub(index + 1, next - 1))
                if value then
                    classifications:applycolor(index, next + 1 - index, color)
                    index = next
                else
                    in_out = true
                    index = next
                end
            end
        end
    end
end
chrisant996 commented 2 weeks ago

P.S. I learned surprising things:

C:\Foo> set "a b=hello"
C:\Foo> echo %a b%
hello

C:\Foo> echo %userprofile^%
%userprofile^%
C:\Foo> set userprofile^^=world
C:\Foo> echo %userprofile^%
world

C:\Foo> for %a in (abc def) do echo %a
abc
def
C:\Foo> set "a in (abc def) do echo =mercy! "
C:\Foo> for %a in (abc def) do echo %a
mercy! a was unexpected at this time.

Cmd.exe's environment variable parsing seems to be very simple and consistent. /shrug

nikitarevenco commented 2 weeks ago
set "a in (abc def) do echo =mercy! "

thanks for this!

tbf biggest mindblower to me is that env variables can have spaces in them

nikitarevenco commented 2 weeks ago

that's pretty awesome!! 😄

chrisant996 commented 2 weeks ago

I'm adding it to clink-gizmos.

It can't handle delayed expansion.

nikitarevenco commented 2 weeks ago

I'm adding it to clink-gizmos.

It can't handle delayed expansion.

oh ok ok!

chrisant996 commented 2 weeks ago

I'll also look at adding some Lua APIs to be able to show expansion hints below the input line -- similar to what Clink does for History Expansion.

Once APIs have been added, then the script can be extended to also show what an environment variable expands to, when the cursor is on the environment variable in the input line.

(And doskey aliases will be able to show expansion hints, and maybe even argmatchers might be able to show syntax hints for an argument position.)