diff --git a/Library/Homebrew/cmd/completions.rb b/Library/Homebrew/cmd/completions.rb new file mode 100644 index 0000000000000000000000000000000000000000..8839aff511e7fb48e00b15f8f74b5945c33abf0d --- /dev/null +++ b/Library/Homebrew/cmd/completions.rb @@ -0,0 +1,52 @@ +# typed: true +# frozen_string_literal: true + +require "cli/parser" +require "completions" + +module Homebrew + extend T::Sig + + module_function + + sig { returns(CLI::Parser) } + def completions_args + Homebrew::CLI::Parser.new do + usage_banner <<~EOS + `completions` [<subcommand>] + + Control whether Homebrew automatically links shell files. + Read more at <https://docs.brew.sh/Shell-Completion>. + + `brew completions` [`state`]: + Display the current state of Homebrew's completions. + + `brew completions` (`link`|`unlink`): + Link or unlink Homebrew's completions. + EOS + + max_named 1 + end + end + + def completions + args = completions_args.parse + + case args.named.first + when nil, "state" + if Completions.link_completions? + puts "Completions are not linked." + else + puts "Completions are linked." + end + when "link" + Completions.link! + puts "Completions are now linked." + when "unlink" + Completions.unlink! + puts "Completions are no longer linked." + else + raise UsageError, "unknown subcommand: #{args.named.first}" + end + end +end diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb index f38b341394d713257b69655333517a612515503d..4d7af92b36060491af7316c47e349557336970ab 100644 --- a/Library/Homebrew/cmd/update-report.rb +++ b/Library/Homebrew/cmd/update-report.rb @@ -8,6 +8,7 @@ require "descriptions" require "cleanup" require "description_cache_store" require "cli/parser" +require "completions" module Homebrew extend T::Sig @@ -150,6 +151,15 @@ module Homebrew puts "Already up-to-date." unless args.quiet? end + if Completions.read_completions_option.empty? + ohai "Homebrew completions are unlinked by default!" + puts <<~EOS + To opt-in to automatically linking Homebrew shell competion files, run: + brew completions link + Then, follow the directions at #{Formatter.url("https://docs.brew.sh/Shell-Completion")} + EOS + end + Commands.rebuild_commands_completion_list link_completions_manpages_and_docs Tap.each(&:link_completions_and_manpages) @@ -188,7 +198,8 @@ module Homebrew def link_completions_manpages_and_docs(repository = HOMEBREW_REPOSITORY) command = "brew update" - Utils::Link.link_completions(repository, command) + + Completions.link_if_allowed! command: command Utils::Link.link_manpages(repository, command) Utils::Link.link_docs(repository, command) rescue => e diff --git a/Library/Homebrew/completions.rb b/Library/Homebrew/completions.rb new file mode 100644 index 0000000000000000000000000000000000000000..d266d95fa90fa8703b04d2968ce30efb0de81769 --- /dev/null +++ b/Library/Homebrew/completions.rb @@ -0,0 +1,53 @@ +# typed: true +# frozen_string_literal: true + +require "utils/link" + +# Helper functions for generating shell completions. +# +# @api private +module Completions + extend T::Sig + + module_function + + sig { params(command: String).void } + def link_if_allowed!(command: "brew completions link") + if link_completions? + link! command: command + else + unlink! + end + end + + sig { params(command: String).void } + def link!(command: "brew completions link") + write_completions_option "yes" + Utils::Link.link_completions HOMEBREW_REPOSITORY, command + end + + sig { void } + def unlink! + write_completions_option "no" + Utils::Link.unlink_completions HOMEBREW_REPOSITORY + end + + sig { returns(T::Boolean) } + def link_completions? + read_completions_option == "yes" + end + + sig { returns(String) } + def read_completions_option + HOMEBREW_REPOSITORY.cd do + Utils.popen_read("git", "config", "--get", "homebrew.linkcompletions").chomp + end + end + + sig { params(state: String).void } + def write_completions_option(state) + HOMEBREW_REPOSITORY.cd do + T.unsafe(self).safe_system "git", "config", "--replace-all", "homebrew.linkcompletions", state.to_s + end + end +end diff --git a/Library/Homebrew/utils/link.rb b/Library/Homebrew/utils/link.rb index 8078390f60b39b5a4ab64e3c17eca97bb979f3a9..8ca992a802fe1d524e882ad09c424e34e0b73075 100644 --- a/Library/Homebrew/utils/link.rb +++ b/Library/Homebrew/utils/link.rb @@ -1,6 +1,8 @@ # typed: true # frozen_string_literal: true +require "completions" + module Utils # Helper functions for creating symlinks. # @@ -64,6 +66,11 @@ module Utils end def link_completions(path, command) + unless Completions.link_completions? + unlink_completions path + return + end + link_src_dst_dirs(path/"completions/bash", HOMEBREW_PREFIX/"etc/bash_completion.d", command) link_src_dst_dirs(path/"completions/zsh", HOMEBREW_PREFIX/"share/zsh/site-functions", command) link_src_dst_dirs(path/"completions/fish", HOMEBREW_PREFIX/"share/fish/vendor_completions.d", command) diff --git a/completions/internal_commands_list.txt b/completions/internal_commands_list.txt index f1a952a9e1ecfcf82073bcfa0d35a67899c26535..13e278cc73c7a2450ef556d77ef4539509fa899e 100644 --- a/completions/internal_commands_list.txt +++ b/completions/internal_commands_list.txt @@ -25,6 +25,7 @@ cat cleanup command commands +completions config configure create diff --git a/docs/Manpage.md b/docs/Manpage.md index bda3f0502c2a69d026e3edead09a66fa958e8f27..ec35d579169fa31e8db5d65bc9ebce2b1ad25d4e 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -94,6 +94,17 @@ Show lists of built-in and external commands. * `--include-aliases`: Include aliases of internal commands. +### `completions` [*`subcommand`*] + +Control whether Homebrew automatically links shell files. +Read more at <https://docs.brew.sh/Shell-Completion>. + +`brew completions` [`state`] +<br>Display the current state of Homebrew's completions. + +`brew completions` (`link`|`unlink`) +<br>Link or unlink Homebrew's completions. + ### `config` Show Homebrew and system configuration info useful for debugging. If you file diff --git a/manpages/brew.1 b/manpages/brew.1 index 09132afcc72a1366c7aff018b123fe097bf6eecc..6edecb36bf4a4fc7279de4072c594f736b5e177c 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -93,6 +93,17 @@ List only the names of commands without category headers\. \fB\-\-include\-aliases\fR Include aliases of internal commands\. . +.SS "\fBcompletions\fR [\fIsubcommand\fR]" +Control whether Homebrew automatically links shell files\. Read more at \fIhttps://docs\.brew\.sh/Shell\-Completion\fR\. +. +.P +\fBbrew completions\fR [\fBstate\fR] + Display the current state of Homebrew\'s completions\. +. +.P +\fBbrew completions\fR (\fBlink\fR|\fBunlink\fR) + Link or unlink Homebrew\'s completions\. +. .SS "\fBconfig\fR" Show Homebrew and system configuration info useful for debugging\. If you file a bug report, you will be required to provide this information\. .