Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,14 @@ if uenv_cli
'src/cli/completion.cpp',
]

completion_bash_dep = custom_target(
'completion-bash-dep',
input: 'src/cli/completion.bash',
output: 'completion.bash.h',
command: ['xxd', '-i', '-n', 'completion_bash_main', '@INPUT@', '@OUTPUT@'])

cli = executable('uenv',
sources: cli_src,
sources: cli_src + completion_bash_dep,
dependencies: [uenv_dep, sqlite3_dep, fmt_dep, spdlog_dep, cli11_dep, barkeep_dep],
c_args: [
'-DVERSION="@0@"'.format(version),
Expand Down
55 changes: 55 additions & 0 deletions src/cli/completion.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
_uenv_completions()
{
local cur prefix func_name UENV_OPTS

local -a COMP_WORDS_NO_FLAGS
local index=0
while [[ "$index" -lt "$COMP_CWORD" ]]
do
if [[ "${COMP_WORDS[$index]}" == [a-z]* ]]
then
COMP_WORDS_NO_FLAGS+=("${COMP_WORDS[$index]}")
fi
let index++
done
COMP_WORDS_NO_FLAGS+=("${COMP_WORDS[$COMP_CWORD]}")
local COMP_CWORD_NO_FLAGS=$((${#COMP_WORDS_NO_FLAGS[@]} - 1))

cur="${COMP_WORDS_NO_FLAGS[COMP_CWORD_NO_FLAGS]}"
prefix="_${COMP_WORDS_NO_FLAGS[*]:0:COMP_CWORD_NO_FLAGS}"
func_name="${prefix// /_}"
func_name="${func_name//-/_}"

local UENV_OPTS=""
local FILE_COMPLETION="false"
if typeset -f $func_name >/dev/null
then
$func_name
fi

local SUBCOMMAND_OPTS=$(compgen -W "${UENV_OPTS}" -- "${cur}")
local FILE_OPTS=""
local FILE_OPTS_FORMATED=""
if [ "${FILE_COMPLETION}" = "true" ]; then
FILE_OPTS=$(compgen -f -- "${cur}")
for item in $FILE_OPTS; do
if [[ -d "${item}" ]]; then
FILE_OPTS_FORMATED+="${item}/ "
else
FILE_OPTS_FORMATED+="${item} "
fi
done
fi

# Do not add space after suggestion if completing a directory
local DIRS=$(compgen -d -- "${cur}")
if [[ -n "${DIRS}" ]]; then
compopt -o nospace
else
compopt +o nospace
fi

COMPREPLY=(${SUBCOMMAND_OPTS} ${FILE_OPTS_FORMATED})
}

complete -F _uenv_completions uenv
62 changes: 4 additions & 58 deletions src/cli/completion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <ranges>
#include <string>
#include <string_view>

#include <fmt/core.h>
#include <fmt/ranges.h>
Expand Down Expand Up @@ -124,67 +125,12 @@ std::string bash_completion(CLI::App* cli, const std::string& name) {
item.file_completion ? "true" : "false");
};

std::string main_functions = R"(
_uenv_completions()
{
local cur prefix func_name UENV_OPTS

local -a COMP_WORDS_NO_FLAGS
local index=0
while [[ "$index" -lt "$COMP_CWORD" ]]
do
if [[ "${COMP_WORDS[$index]}" == [a-z]* ]]
then
COMP_WORDS_NO_FLAGS+=("${COMP_WORDS[$index]}")
fi
let index++
done
COMP_WORDS_NO_FLAGS+=("${COMP_WORDS[$COMP_CWORD]}")
local COMP_CWORD_NO_FLAGS=$((${#COMP_WORDS_NO_FLAGS[@]} - 1))

cur="${COMP_WORDS_NO_FLAGS[COMP_CWORD_NO_FLAGS]}"
prefix="_${COMP_WORDS_NO_FLAGS[*]:0:COMP_CWORD_NO_FLAGS}"
func_name="${prefix// /_}"
func_name="${func_name//-/_}"

local UENV_OPTS=""
local FILE_COMPLETION="false"
if typeset -f $func_name >/dev/null
then
$func_name
fi

local SUBCOMMAND_OPTS=$(compgen -W "${UENV_OPTS}" -- "${cur}")
local FILE_OPTS=""
local FILE_OPTS_FORMATED=""
if [ "${FILE_COMPLETION}" = "true" ]; then
FILE_OPTS=$(compgen -f -- "${cur}")
for item in $FILE_OPTS; do
if [[ -d "${item}" ]]; then
FILE_OPTS_FORMATED+="${item}/ "
else
FILE_OPTS_FORMATED+="${item} "
fi
done
fi

# Do not add space after suggestion if completing a directory
local DIRS=$(compgen -d -- "${cur}")
if [[ -n "${DIRS}" ]]; then
compopt -o nospace
else
compopt +o nospace
fi

COMPREPLY=(${SUBCOMMAND_OPTS} ${FILE_OPTS_FORMATED})
}

complete -F _uenv_completions uenv
)";
#include "completion.bash.h"

return fmt::format(
"{}{}", fmt::join(std::views::transform(cl, gen_bash_function), ""),
main_functions);
std::string_view(reinterpret_cast<const char*>(completion_bash_main),
completion_bash_main_len));
}
} // namespace impl

Expand Down