diff options
| author | Alexander Karatarakis <alex@karatarakis.com> | 2018-12-13 13:49:24 -0800 |
|---|---|---|
| committer | Alexander Karatarakis <alex@karatarakis.com> | 2018-12-13 14:02:02 -0800 |
| commit | fed9a245268df9591a4150fb1f916df0894ca9d3 (patch) | |
| tree | 1b78807ebade8a0319e7ba4372b82d9214f6d6c6 | |
| parent | 93d020f619ebc57267177651cf0677ebd519d263 (diff) | |
| download | vcpkg-fed9a245268df9591a4150fb1f916df0894ca9d3.tar.gz vcpkg-fed9a245268df9591a4150fb1f916df0894ca9d3.zip | |
[autocomplete] Add tab-completion support for bash
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | scripts/vcpkg_completion.bash | 17 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/commands.integrate.cpp | 52 |
3 files changed, 71 insertions, 5 deletions
@@ -42,11 +42,12 @@ For more information, see our [using a package](docs/examples/installing-and-usi Additional notes on macOS and Linux support can be found in the [official announcement](https://blogs.msdn.microsoft.com/vcblog/2018/04/24/announcing-a-single-c-library-manager-for-linux-macos-and-windows-vcpkg/). ## Tab-Completion / Auto-Completion -`vcpkg` supports auto-completion of commands, package names, options etc. To enable tab-completion in Powershell, use +`vcpkg` supports auto-completion of commands, package names, options etc in Powershell and bash. To enable tab-completion, use one of the following: ``` -.\vcpkg integrate powershell +PS> .\vcpkg integrate powershell +Linux:~/$ ./vcpkg integrate bash ``` -and restart Powershell. +and restart your console. ## Examples diff --git a/scripts/vcpkg_completion.bash b/scripts/vcpkg_completion.bash new file mode 100644 index 000000000..804507d58 --- /dev/null +++ b/scripts/vcpkg_completion.bash @@ -0,0 +1,17 @@ +#/usr/bin/env bash + +_vcpkg_completions() +{ + local vcpkg_executable=${COMP_WORDS[0]} + local remaining_command_line=${COMP_LINE:(${#vcpkg_executable}+1)} + COMPREPLY=($(${vcpkg_executable} autocomplete "${remaining_command_line}" -- 2>/dev/null)) + + # Colon is treated as a delimiter in bash. The following workaround + # allows triplet completion to work correctly in the syntax: + # zlib:x64-windows + local cur + _get_comp_words_by_ref -n : cur + __ltrim_colon_completions "$cur" +} + +complete -F _vcpkg_completions vcpkg diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 82172e363..c1d3a8c8d 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include <vcpkg/base/checks.h> +#include <vcpkg/base/expected.h> #include <vcpkg/base/files.h> #include <vcpkg/base/system.h> #include <vcpkg/base/util.h> @@ -122,7 +123,7 @@ namespace vcpkg::Commands::Integrate static ElevationPromptChoice elevated_cmd_execute(const std::string& param) { - SHELLEXECUTEINFOW sh_ex_info{}; + SHELLEXECUTEINFOW sh_ex_info {}; sh_ex_info.cbSize = sizeof(sh_ex_info); sh_ex_info.fMask = SEE_MASK_NOCLOSEPROCESS; sh_ex_info.hwnd = nullptr; @@ -404,6 +405,47 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console Checks::exit_with_code(VCPKG_LINE_INFO, rc); } +#elif defined(__unix__) + static void integrate_bash(const VcpkgPaths& paths) + { + const auto home_path = System::get_environment_variable("HOME").value_or_exit(VCPKG_LINE_INFO); + const fs::path bashrc_path = fs::path {home_path} / ".bashrc"; + + auto& fs = paths.get_filesystem(); + const fs::path completion_script_path = paths.scripts / "vcpkg_completion.bash"; + + Expected<std::vector<std::string>> maybe_bashrc_content = fs.read_lines(bashrc_path); + Checks::check_exit( + VCPKG_LINE_INFO, maybe_bashrc_content.has_value(), "Unable to read %s", bashrc_path.u8string()); + + std::vector<std::string> bashrc_content = maybe_bashrc_content.value_or_exit(VCPKG_LINE_INFO); + + std::vector<std::string> matches; + for (auto&& line : bashrc_content) + { + std::smatch match; + if (std::regex_match(line, match, std::regex {R"###(^source.*scripts/vcpkg_completion.bash$)###"})) + { + matches.push_back(line); + } + } + + if (!matches.empty()) + { + System::print("vcpkg bash completion is already imported to your %s file.\n" + "The following entries were found:\n" + " %s\n" + "Please make sure you have started a new bash shell for the changes to take effect.\n", + bashrc_path.u8string(), + Strings::join("\n ", matches)); + Checks::exit_success(VCPKG_LINE_INFO); + } + + System::print("Adding vcpkg completion entry to %s\n", bashrc_path.u8string()); + bashrc_content.push_back(Strings::format("source %s", completion_script_path.u8string())); + fs.write_contents(bashrc_path, Strings::join("\n", bashrc_content)); + Checks::exit_success(VCPKG_LINE_INFO); + } #endif #if defined(_WIN32) @@ -425,11 +467,12 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console static const std::string REMOVE = "remove"; static const std::string PROJECT = "project"; static const std::string POWERSHELL = "powershell"; + static const std::string BASH = "bash"; } static std::vector<std::string> valid_arguments(const VcpkgPaths&) { - return {Subcommand::INSTALL, Subcommand::REMOVE, Subcommand::PROJECT, Subcommand::POWERSHELL}; + return {Subcommand::INSTALL, Subcommand::REMOVE, Subcommand::PROJECT, Subcommand::POWERSHELL, Subcommand::BASH}; } const CommandStructure COMMAND_STRUCTURE = { @@ -463,6 +506,11 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console { return integrate_powershell(paths); } +#elif defined(__unix__) + if (args.command_arguments[0] == Subcommand::BASH) + { + return integrate_bash(paths); + } #endif Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown parameter %s for integrate", args.command_arguments[0]); |
