From 0ad630da4c6403afaf958a4da6b0ebc25eb077fd Mon Sep 17 00:00:00 2001 From: Claudio Bley Date: Thu, 14 Jan 2021 21:57:43 +0100 Subject: [PATCH] Properly encode hyperlinks with special characters This also works on Windows now, since absolute paths include a colon after the drive letter, the `file:` URI needs to start with a triple slash. --- colorls.gemspec | 1 + lib/colorls.rb | 1 + lib/colorls/core.rb | 4 ++-- spec/color_ls/flags_spec.rb | 10 ++++++++-- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/colorls.gemspec b/colorls.gemspec index 924ae8e..023e7f9 100644 --- a/colorls.gemspec +++ b/colorls.gemspec @@ -61,6 +61,7 @@ Gem::Specification.new do |spec| spec.post_install_message = POST_INSTALL_MESSAGE + spec.add_runtime_dependency 'addressable', '~> 2.7' spec.add_runtime_dependency 'clocale', '~> 0' spec.add_runtime_dependency 'filesize', '~> 0' spec.add_runtime_dependency 'manpages', '~> 0' diff --git a/lib/colorls.rb b/lib/colorls.rb index 8787246..6973986 100644 --- a/lib/colorls.rb +++ b/lib/colorls.rb @@ -8,6 +8,7 @@ require 'io/console' require 'rainbow/ext/string' require 'clocale' require 'unicode/display_width' +require 'addressable/uri' require 'colorls/core' require 'colorls/fileinfo' diff --git a/lib/colorls/core.rb b/lib/colorls/core.rb index 2ed52cd..f77c2e7 100644 --- a/lib/colorls/core.rb +++ b/lib/colorls/core.rb @@ -377,8 +377,8 @@ module ColorLS end def make_link(path, name) - href = "file://#{File.absolute_path(path)}/#{name}" - "\033]8;;#{href}\007#{name}\033]8;;\007" + uri = Addressable::URI.convert_path(File.absolute_path(File.join(path, name))) + "\033]8;;#{uri}\007#{name}\033]8;;\007" end end end diff --git a/spec/color_ls/flags_spec.rb b/spec/color_ls/flags_spec.rb index 081cb87..92e4b7c 100644 --- a/spec/color_ls/flags_spec.rb +++ b/spec/color_ls/flags_spec.rb @@ -291,9 +291,15 @@ RSpec.describe ColorLS::Flags do context 'with --hyperlink flag' do let(:args) { ['--hyperlink', FIXTURES] } - href = "file://#{File.absolute_path(FIXTURES)}/a.txt" + href = if File::ALT_SEPARATOR.nil? + "file://#{File.absolute_path(FIXTURES)}/a.txt" + else + "file:///#{File.absolute_path(FIXTURES)}/a.txt" + end - it { expect { subject }.to output(include(href)).to_stdout } + pattern = File.fnmatch('cat', 'CAT', File::FNM_SYSCASE) ? /#{href}/i : /#{href}/ + + it { expect { subject }.to output(match(pattern)).to_stdout } end context 'symlinked directory' do