Skip to content

Commit

Permalink
feat(add clink support): add clink to support window cmd terminal
Browse files Browse the repository at this point in the history
Support the clink terminal's automatic completion and vfox environment switching functions by writing Lua scripts

link: version-fox#129
  • Loading branch information
jan-bar committed Apr 2, 2024
1 parent 1bf6a79 commit c704b18
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 1 deletion.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ New-Item -Type File -Path $PROFILE # Just ignore the 'file already exists' error
Invoke-Item $PROFILE
# 2. Add the following line to the end of your $PROFILE and save:
Invoke-Expression "$(vfox activate pwsh)"

# For Clink:
# 1. Install clink: https://github.com/chrisant996/clink/releases
# Or Install cmder: https://github.com/cmderdev/cmder/releases
# 2. Find script path: clink info | findstr scripts
# 3. copy internal/shell/clink_vfox.lua to script path
```

> Remember to restart your shell to apply the changes.
Expand Down
6 changes: 6 additions & 0 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ New-Item -Type File -Path $PROFILE # 无需在意 `文件已存在` 错误
Invoke-Item $PROFILE
# 2. 将下面一行添加到你的 $PROFILE 文件末尾并保存:
Invoke-Expression "$(vfox activate pwsh)"

# Clink:
# 1. 安装 clink: https://github.com/chrisant996/clink/releases
# 或者安装 cmder: https://github.com/cmderdev/cmder/releases
# 2. 找到脚本路径: clink info | findstr scripts
# 3. 复制 internal/shell/clink_vfox.lua 到脚本路径
```

> 请记住重启你的 Shell 以应用更改。
Expand Down
51 changes: 51 additions & 0 deletions internal/shell/clink.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2024 Han Li and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package shell

import (
"fmt"

"github.com/version-fox/vfox/internal/env"
)

const clinkHook = `
{{.EnvContent}}
"{{.SelfPath}}" env --cleanup > nul 2> nul
`

type clink struct{}

var Clink = clink{}

func (b clink) Activate() (string, error) {
return clinkHook, nil
}

func (b clink) Export(envs env.Vars) (out string) {
for key, value := range envs {
if value == nil {
out += b.set(key, "")
} else {
out += b.set(key, *value)
}
}
return
}

func (b clink) set(key, value string) string {
return fmt.Sprintf("set \"%s=%s\"\n", key, value)
}
83 changes: 83 additions & 0 deletions internal/shell/clink_vfox.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
local vfox_sdk_table = {}
local vfox_available = io.popen('vfox available')
for line in vfox_available:lines() do
local sdk, yes = line:gsub('%c%[%d+m', ''):match('^(%a+)%s+(%u%u%u?)')
if sdk and yes and (yes == 'YES' or yes == 'NO') then
table.insert(vfox_sdk_table, sdk)
end
end
vfox_available:close()

local vfox_sdk = clink.argmatcher():nofiles():addarg(vfox_sdk_table)

local vfox_version = clink.argmatcher():nofiles():addarg({ function()
local pre, ls = '', {}
local vfox_ls = io.popen('vfox ls')
for line in vfox_ls:lines() do
local txt = line:gsub('%c%[%d+m', ''):match('(%a.+)')
if txt then
if string.find(txt, 'v') == 1 then
table.insert(ls, pre .. '@' .. string.sub(txt, 2))
else
pre = txt
end
end
end
vfox_ls:close()
return ls
end, vfox_sdk })

local vfox_use = clink.argmatcher():nofiles():addflags({
'--global' .. vfox_version, '-g' .. vfox_version,
'--session' .. vfox_version, '-s' .. vfox_version,
'--project' .. vfox_version, '-p' .. vfox_version,
})

local vfox_shell = clink.argmatcher():nofiles():addarg('bash', 'zsh', 'pwsh', 'fish', 'clink')

local vfox_env = clink.argmatcher():nofiles():addarg({ vfox_sdk }):addflags({
'--shell' .. vfox_shell, '-s' .. vfox_shell,
'--cleanup', '-c',
'--json', '-j',
})

clink.argmatcher('vfox'):nofiles():addarg({
'add' .. clink.argmatcher():nofiles():addarg({ vfox_sdk }):addflags('--source', '-s', '--alias'),
'use' .. vfox_use, 'u' .. vfox_use,
'info' .. vfox_sdk,
'remove' .. vfox_sdk,
'search' .. vfox_sdk,
'update' .. vfox_sdk,
'available',
'current' .. vfox_sdk, 'c' .. vfox_sdk,
'list' .. vfox_sdk, 'ls' .. vfox_sdk,
'uninstall' .. vfox_version, 'un' .. vfox_version,
'install' .. vfox_sdk, 'i' .. vfox_sdk,
'env' .. vfox_env,
'activate' .. vfox_shell,
})

local vfox_setenv = function(str)
local key, val = str:match('^set "(.+)=(.*)"')
if key and val then
return os.setenv(key, val ~= '' and val or nil)
end
end

os.setenv('__VFOX_PID', os.getpid())
local vfox_activate = io.popen('vfox activate clink')
for line in vfox_activate:lines() do
if not vfox_setenv(line) then
io.popen(line):close()
end
end
vfox_activate:close()

local vfox_prompt = clink.promptfilter(30)
function vfox_prompt:filter(prompt)
local env = io.popen('vfox env -s clink')
for line in env:lines() do
vfox_setenv(line)
end
env:close()
end
5 changes: 4 additions & 1 deletion internal/shell/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
package shell

import (
"github.com/version-fox/vfox/internal/env"
"strings"

"github.com/version-fox/vfox/internal/env"
)

type Shell interface {
Expand All @@ -36,6 +37,8 @@ func NewShell(name string) Shell {
return Pwsh
case "fish":
return Fish
case "clink":
return Clink
}
return nil

Expand Down

0 comments on commit c704b18

Please sign in to comment.