From 2631e869e4ee67483d6ac36f42b6558940020b08 Mon Sep 17 00:00:00 2001 From: Piotr Murach Date: Mon, 26 Aug 2024 13:40:40 +0200 Subject: [PATCH] Add TTY::Link::Terminals::Vscode to detect hyperlinks support in VSCode --- lib/tty/link/terminals/vscode.rb | 54 +++++++++++++++++++++++ spec/unit/link_spec.rb | 12 +++++ spec/unit/terminals/vscode_spec.rb | 70 ++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 lib/tty/link/terminals/vscode.rb create mode 100644 spec/unit/terminals/vscode_spec.rb diff --git a/lib/tty/link/terminals/vscode.rb b/lib/tty/link/terminals/vscode.rb new file mode 100644 index 0000000..6763ad7 --- /dev/null +++ b/lib/tty/link/terminals/vscode.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require_relative "abstract" + +module TTY + class Link + module Terminals + # Responsible for detecting hyperlink support in the VSCode terminal + # + # @api private + class Vscode < Abstract + # The VSCode terminal name pattern + # + # @return [Regexp] + # + # @api private + VSCODE = /vscode/i.freeze + private_constant :VSCODE + + private + + # Detect VSCode terminal + # + # @example + # vscode.name? + # # => true + # + # @return [Boolean] + # + # @api private + def name? + !(term_program =~ VSCODE).nil? + end + + # Detect whether the VSCode version supports terminal hyperlinks + # + # @example + # vscode.version? + # # => true + # + # @return [Boolean] + # + # @api private + def version? + return false unless term_program_version + + current_semantic_version = semantic_version(term_program_version) + + current_semantic_version >= semantic_version(1, 72, 0) + end + end # Vscode + end # Terminals + end # Link +end # TTY diff --git a/spec/unit/link_spec.rb b/spec/unit/link_spec.rb index 3cc8bc0..f95be18 100644 --- a/spec/unit/link_spec.rb +++ b/spec/unit/link_spec.rb @@ -180,6 +180,18 @@ end end + context "when VSCode" do + it "supports links above the 1.72.0 version" do + env = { + "TERM_PROGRAM" => "vscode", + "TERM_PROGRAM_VERSION" => "1.72.0" + } + link = described_class.new(env: env, output: output) + + expect(link.link?).to eq(true) + end + end + context "when VTE" do it "supports links above the 0.50.1 version" do env = {"VTE_VERSION" => "5001"} diff --git a/spec/unit/terminals/vscode_spec.rb b/spec/unit/terminals/vscode_spec.rb new file mode 100644 index 0000000..4ac9a22 --- /dev/null +++ b/spec/unit/terminals/vscode_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +RSpec.describe TTY::Link::Terminals::Vscode, "#link?" do + let(:env_with_name) { {"TERM_PROGRAM" => "vscode"} } + let(:semantic_version) { TTY::Link::SemanticVersion } + + it "doesn't support links without the term program environment variable" do + vscode = described_class.new(semantic_version, {}) + + expect(vscode.link?).to eq(false) + end + + it "doesn't support links without a terminal program name" do + env = {"TERM_PROGRAM" => nil} + vscode = described_class.new(semantic_version, env) + + expect(vscode.link?).to eq(false) + end + + it "doesn't support links with a non-VSCode program name" do + env = {"TERM_PROGRAM" => "other-terminal"} + vscode = described_class.new(semantic_version, env) + + expect(vscode.link?).to eq(false) + end + + it "supports links above the 1.92.2 version" do + env = { + "TERM_PROGRAM" => "VSCode", + "TERM_PROGRAM_VERSION" => "2.3.4" + } + vscode = described_class.new(semantic_version, env) + + expect(vscode.link?).to eq(true) + end + + it "supports links above the 1.72.0 version" do + env = env_with_name.merge({"TERM_PROGRAM_VERSION" => "1.72.1"}) + vscode = described_class.new(semantic_version, env) + + expect(vscode.link?).to eq(true) + end + + it "supports links on the 1.72.0 version" do + env = env_with_name.merge({"TERM_PROGRAM_VERSION" => "1.72.0"}) + vscode = described_class.new(semantic_version, env) + + expect(vscode.link?).to eq(true) + end + + it "doesn't support links below the 1.72.0 version" do + env = env_with_name.merge({"TERM_PROGRAM_VERSION" => "1.71.2"}) + vscode = described_class.new(semantic_version, env) + + expect(vscode.link?).to eq(false) + end + + it "doesn't support links without a version" do + env = env_with_name.merge({"TERM_PROGRAM_VERSION" => nil}) + vscode = described_class.new(semantic_version, env) + + expect(vscode.link?).to eq(false) + end + + it "doesn't support links without the term program version env variable" do + vscode = described_class.new(semantic_version, env_with_name) + + expect(vscode.link?).to eq(false) + end +end