From 89503d9a66b3234bed4a2ee938bbb948b765d84c Mon Sep 17 00:00:00 2001 From: sophia Date: Thu, 16 Apr 2020 13:44:26 -0400 Subject: [PATCH] Install zsh autocomplete --- lib/vagrant/cli.rb | 7 +++ lib/vagrant/util/install_cli_autocomplete.rb | 59 +++++++++++++++++++ .../util/install_cli_autocomplete_test.rb | 54 +++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 lib/vagrant/util/install_cli_autocomplete.rb create mode 100644 test/unit/vagrant/util/install_cli_autocomplete_test.rb diff --git a/lib/vagrant/cli.rb b/lib/vagrant/cli.rb index 9421c9c2b..54052490a 100644 --- a/lib/vagrant/cli.rb +++ b/lib/vagrant/cli.rb @@ -2,6 +2,7 @@ require 'log4r' require 'optparse' require 'vagrant/util/experimental' +require 'vagrant/util/install_cli_autocomplete' module Vagrant # Manages the command line interface to Vagrant. @@ -30,6 +31,12 @@ module Vagrant return 0 end + if @main_args.include?("-install_autocomplete") + # Install zsh autocomplete script + Vagrant::Util::InstallCLIAutocomplete.install + return 0 + end + if @sub_command == "login" $stderr.puts "WARNING: This command has been deprecated and aliased to `vagrant cloud auth login`" end diff --git a/lib/vagrant/util/install_cli_autocomplete.rb b/lib/vagrant/util/install_cli_autocomplete.rb new file mode 100644 index 000000000..bd94d7335 --- /dev/null +++ b/lib/vagrant/util/install_cli_autocomplete.rb @@ -0,0 +1,59 @@ +module Vagrant + module Util + class ZSHShell + PREPEND = "# >>>> Vagrant zsh completion (start)".freeze + STRING_INSERT = """fpath=(#{File.join(Vagrant.source_root, "contrib", "zsh")} $fpath)\ncompinit""".freeze + APPEND = "# <<<< Vagrant zsh completion (end)".freeze + + CONFIG_PATHS = [".zshrc"].freeze + + def self.shell_installed(home) + CONFIG_PATHS.each do |path| + config_file = File.join(home, path) + if File.exists?(config_file) + return config_file + end + end + return nil + end + + def self.is_installed(path) + File.foreach(path) do |line| + if line.include?(PREPEND) + return true + end + end + return false + end + + def self.install(home) + path = shell_installed(home) + if path && !is_installed(path) + File.open(path, "a") do |f| + f.write("\n") + f.write(PREPEND) + f.write("\n") + f.write(STRING_INSERT) + f.write("\n") + f.write(APPEND) + f.write("\n") + end + end + end + end + + # Install autocomplete script for supported shells + class InstallCLIAutocomplete + SUPPORTED_SHELLS = { + "zsh" => Vagrant::Util::ZSHShell + } + + def self.install + home = Dir.home + SUPPORTED_SHELLS.each do |k, shell| + shell.install(home) + end + end + end + end +end \ No newline at end of file diff --git a/test/unit/vagrant/util/install_cli_autocomplete_test.rb b/test/unit/vagrant/util/install_cli_autocomplete_test.rb new file mode 100644 index 000000000..0605ded44 --- /dev/null +++ b/test/unit/vagrant/util/install_cli_autocomplete_test.rb @@ -0,0 +1,54 @@ +require File.expand_path("../../../base", __FILE__) + +require 'vagrant/util/install_cli_autocomplete' +require 'fileutils' + +describe Vagrant::Util::ZSHShell do + + let(:home) { "#{Dir.tmpdir}/not-home" } + let(:target_file) { "#{home}/.zshrc" } + + subject { described_class } + + before do + Dir.mkdir(home) + File.open(target_file, "w") do |f| + f.write("some content") + end + end + + after do + FileUtils.rm_rf(home) + end + + describe ".shell_installed" do + it "should return path to config file if exists" do + expect(subject.shell_installed(home)).to eq(target_file) + end + end + + describe ".is_installed" do + it "returns false if autocompletion not already installed" do + expect(subject.is_installed(target_file)).to eq(false) + end + + it "returns true if autocompletion is already installed" do + File.open(target_file, "w") do |f| + f.write(Vagrant::Util::ZSHShell::PREPEND) + end + expect(subject.is_installed(target_file)).to eq(true) + end + end + + describe ".install" do + it "installs autocomplete" do + subject.install(home) + file = File.open(target_file) + content = file.read + expect(content.include?(Vagrant::Util::ZSHShell::PREPEND)).to eq(true) + expect(content.include?(Vagrant::Util::ZSHShell::STRING_INSERT)).to eq(true) + expect(content.include?(Vagrant::Util::ZSHShell::APPEND)).to eq(true) + file.close + end + end +end \ No newline at end of file