summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxq114 <[email protected]>2022-02-14 23:54:30 +0800
committerxq114 <[email protected]>2022-02-14 23:54:30 +0800
commit835d889cfcf7f0335b1822f96705ceede47032d7 (patch)
tree2dfdf000d0b1b226323328fecbb08c9160dc195e
parent8c0b564b4f3cdb62680dc70b91bc39a335f5d429 (diff)
add shell utility registration
-rw-r--r--xmake/actions/update/main.lua89
-rw-r--r--xmake/actions/update/xmake.lua3
-rw-r--r--xmake/scripts/profile-unix.sh87
-rw-r--r--xmake/scripts/profile-win.ps114
4 files changed, 192 insertions, 1 deletions
diff --git a/xmake/actions/update/main.lua b/xmake/actions/update/main.lua
index 7db7eda58..6436a874b 100644
--- a/xmake/actions/update/main.lua
+++ b/xmake/actions/update/main.lua
@@ -106,6 +106,30 @@ end
-- do uninstall
function _uninstall()
+
+ -- remove shell profile
+ local profiles = {}
+ if is_host("windows") then
+ for _, shell in ipairs({"pwsh", "powershell"}) do
+ for _, type in ipairs({"AllUsersAllHosts", "CurrentUserAllHosts", "CurrentUserCurrentHost"}) do
+ local outdata, errdata = os.iorunv(shell, {"-c", "Write-Output $PROFILE." .. type})
+ if outdata then
+ table.insert(profiles, outdata:trim())
+ end
+ end
+ end
+ else
+ for _, filename in ipairs({".zshrc", ".bashrc", ".kshrc", ".bash_profile", ".profile"}) do
+ table.insert(profiles, path.join(os.getenv("HOME"), filename))
+ end
+ end
+ for _, profile in ipairs(profiles) do
+ if os.isfile(profile) then
+ io.gsub(profile, "# >>> xmake >>>.-# <<< xmake <<<", "")
+ end
+ end
+
+ -- remove program
if is_host("windows") then
local uninstaller = path.join(os.programdir(), "uninstall.exe")
if os.isfile(uninstaller) then
@@ -257,6 +281,65 @@ function _install_script(sourcedir)
end
end
+-- initialize shells
+function _initialize_shell()
+
+ local target, command, profile
+ if is_host("windows") then
+ local psshell = os.iorun("pwsh -v") and "pwsh" or "powershell"
+ local outdata, errdata = os.iorunv(psshell, {"-c", "Write-Output $PROFILE.CurrentUserAllHosts"})
+ if outdata then
+ target = outdata:trim()
+ command = "if (Test-Path -Path \"%s\" -PathType Leaf) {\n . \"%s\"\n}"
+ profile = path.join(os.programdir(), "scripts", "profile-win.ps1")
+ else
+ raise("failed to get profile location from powershell!")
+ end
+ else
+ local shell = os.shell()
+ local filename = ".profile"
+ if shell:endswith("bash") then filename = (is_host("macosx") and ".bash_profile" or ".bashrc")
+ elseif shell:endswith("zsh") then filename = ".zshrc"
+ elseif shell:endswith("ksh") then filename = ".kshrc"
+ end
+ target = path.join(os.getenv("HOME"), filename)
+ command = "[[ -s \"%s\" ]] && source \"%s\""
+ profile = path.join(os.programdir(), "scripts", "profile-unix.sh")
+ end
+
+ -- trace
+ cprintf("\r${yellow} => ${clear}installing shell integration to %s .. ", target)
+
+ local ok = try
+ {
+ function ()
+ local file = ""
+ if os.isfile(target) then
+ file = io.readfile(target)
+ file = file:gsub("# >>> xmake >>>.-# <<< xmake <<<", "")
+ if file ~= "" then
+ file = file .. "\n"
+ end
+ end
+ file = file .. "# >>> xmake >>>\n" .. format(command, profile, profile) .. "\n# <<< xmake <<<"
+ io.writefile(target, file)
+ return true
+ end,
+ catch
+ {
+ function (errors)
+ vprint(errors)
+ end
+ }
+ }
+ -- trace
+ if ok then
+ cprint("${color.success}${text.success}")
+ else
+ cprint("${color.failure}${text.failure}")
+ end
+end
+
function _check_repo(sourcedir)
-- this file will exists for long time
if not os.isfile(path.join(sourcedir, "xmake/core/_xmake_main.lua")) then
@@ -298,6 +381,12 @@ function main()
return
end
+ -- initialize for shell interaction
+ if option.get("init") then
+ _initialize_shell()
+ return
+ end
+
-- enter environment
environment.enter()
diff --git a/xmake/actions/update/xmake.lua b/xmake/actions/update/xmake.lua
index 2672a1c97..8c3b1f33b 100644
--- a/xmake/actions/update/xmake.lua
+++ b/xmake/actions/update/xmake.lua
@@ -40,7 +40,8 @@ task("update")
{
{nil, "uninstall", "k", nil, "Uninstall the current xmake program." }
, { }
- , {'s', "scriptonly", "k", nil, "Update script only" }
+ , {'s', "scriptonly", "k", nil, "Update scripts only." }
+ , {'i', "init", "k", nil, "Initialize xmake for shell interaction." }
, {'f', "force", "k", nil, "Force to update and reinstall the given version." }
, {nil, "xmakever", "v", nil, "The given xmake version, or a git source (and branch). ",
"e.g.",
diff --git a/xmake/scripts/profile-unix.sh b/xmake/scripts/profile-unix.sh
new file mode 100644
index 000000000..26d9d6a66
--- /dev/null
+++ b/xmake/scripts/profile-unix.sh
@@ -0,0 +1,87 @@
+# parameter completions for *nix shell
+if [[ "$SHELL" = */zsh ]]; then
+ # zsh parameter completion for xmake
+ _xmake_zsh_complete()
+ {
+ local completions=("$(XMAKE_SKIP_HISTORY=1 XMAKE_ROOT=y xmake lua private.utils.complete 0 nospace "$words")")
+ reply=( "${(ps:\n:)completions}" )
+ }
+ compctl -f -S "" -K _xmake_zsh_complete xmake
+elif [[ "$SHELL" = */bash ]]; then
+ # bash parameter completion for xmake
+ _xmake_bash_complete()
+ {
+ local word=${COMP_WORDS[COMP_CWORD]}
+ local completions
+ completions="$(XMAKE_SKIP_HISTORY=1 XMAKE_ROOT=y xmake lua private.utils.complete "${COMP_POINT}" "nospace-nokey" "${COMP_LINE}")"
+ if [ $? -ne 0 ]; then
+ completions=""
+ fi
+ COMPREPLY=( $(compgen -W "$completions") )
+ }
+ complete -o default -o nospace -F _xmake_bash_complete xmake
+fi
+# virtual environments for *nix shell
+function xrepo {
+ if [ $# -ge 2 ] && [ "$1" = "env" ]; then
+ local cmd="${2-x}"
+ case "$cmd" in
+ shell)
+ if test "${XMAKE_PROMPT_BACKUP}"; then
+ PS1="${XMAKE_PROMPT_BACKUP}"
+ source "${XMAKE_ENV_BACKUP}" || return 1
+ unset XMAKE_PROMPT_BACKUP
+ unset XMAKE_ENV_BACKUP
+ fi
+ xmake lua private.xrepo.action.env.info config || return 1
+ local prompt="$(xmake lua --quiet private.xrepo.action.env.info prompt)" || return 1
+ if [ -z "${prompt+x}" ]; then
+ return 1
+ fi
+ local activateCommand="$(xmake lua private.xrepo.action.env.info script.bash)" || return 1
+ export XMAKE_ENV_BACKUP="$(xmake lua private.xrepo.action.env.info envfile)"
+ export XMAKE_PROMPT_BACKUP="${PS1}"
+ xmake lua private.xrepo.action.env.info backup.bash 1>"$XMAKE_ENV_BACKUP"
+ eval "$activateCommand"
+ PS1="${prompt} $PS1"
+ ;;
+ quit)
+ if test "${XMAKE_PROMPT_BACKUP}"; then
+ PS1="${XMAKE_PROMPT_BACKUP}"
+ source "${XMAKE_ENV_BACKUP}" || return 1
+ unset XMAKE_PROMPT_BACKUP
+ unset XMAKE_ENV_BACKUP
+ fi
+ ;;
+ -b|--bind)
+ if [ "$4" = "shell" ]; then
+ local bnd="${3-x}"
+ if test "${XMAKE_PROMPT_BACKUP}"; then
+ PS1="${XMAKE_PROMPT_BACKUP}"
+ source "${XMAKE_ENV_BACKUP}" || return 1
+ unset XMAKE_PROMPT_BACKUP
+ unset XMAKE_ENV_BACKUP
+ fi
+ xmake lua private.xrepo.action.env.info config $bnd || return 1
+ local prompt="$(xmake lua --quiet private.xrepo.action.env.info prompt $bnd)" || return 1
+ if [ -z "${prompt+x}" ]; then
+ return 1
+ fi
+ local activateCommand="$(xmake lua --quiet private.xrepo.action.env.info script.bash $bnd)" || return 1
+ export XMAKE_ENV_BACKUP="$(xmake lua private.xrepo.action.env.info envfile $bnd)"
+ export XMAKE_PROMPT_BACKUP="${PS1}"
+ xmake lua --quiet private.xrepo.action.env.info backup.bash $bnd 1>"$XMAKE_ENV_BACKUP"
+ eval "$activateCommand"
+ PS1="${prompt} $PS1"
+ else
+ xmake lua private.xrepo "$@"
+ fi
+ ;;
+ *)
+ xmake lua private.xrepo "$@"
+ ;;
+ esac
+ else
+ xmake lua private.xrepo "$@"
+ fi
+} \ No newline at end of file
diff --git a/xmake/scripts/profile-win.ps1 b/xmake/scripts/profile-win.ps1
new file mode 100644
index 000000000..493543040
--- /dev/null
+++ b/xmake/scripts/profile-win.ps1
@@ -0,0 +1,14 @@
+# PowerShell parameter completion for xmake
+Register-ArgumentCompleter -Native -CommandName xmake -ScriptBlock {
+ param($commandName, $wordToComplete, $cursorPosition)
+ $complete = "$wordToComplete"
+ if (-not $commandName) {
+ $complete = $complete + " "
+ }
+ $oldenv = $env:XMAKE_SKIP_HISTORY
+ $env:XMAKE_SKIP_HISTORY = 1
+ xmake lua --root private.utils.complete "0" "nospace" "$complete" | ForEach-Object {
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
+ }
+ $env:XMAKE_SKIP_HISTORY = $oldenv
+} \ No newline at end of file