parent
c977cf72d6
commit
e5a26b94d9
|
@ -1,8 +1,8 @@
|
|||
language: ruby
|
||||
rvm:
|
||||
- 2.6
|
||||
#- 2.7
|
||||
#- 3.0
|
||||
- 2.7
|
||||
- 3.0
|
||||
install: ./spec/provisioning/ci.sh
|
||||
script:
|
||||
- bash -c 'echo $BASH_VERSION'
|
||||
|
@ -10,7 +10,7 @@ script:
|
|||
- cat ./fingers.log
|
||||
os:
|
||||
- linux
|
||||
#- osx
|
||||
- osx
|
||||
cache: /opt
|
||||
jobs:
|
||||
exclude:
|
||||
|
|
|
@ -8,7 +8,6 @@ require 'socket'
|
|||
require 'pathname'
|
||||
require 'tmpdir'
|
||||
require 'set'
|
||||
require 'io/console'
|
||||
|
||||
# Top level fingers namespace
|
||||
module Fingers
|
||||
|
@ -25,7 +24,6 @@ require 'tmux'
|
|||
require 'tmux_format_printer'
|
||||
require 'huffman'
|
||||
require 'priority_queue'
|
||||
require 'version'
|
||||
|
||||
require 'fingers/version'
|
||||
require 'fingers/dirs'
|
||||
|
@ -35,7 +33,6 @@ require 'fingers/config'
|
|||
# TODO dynamically require command?
|
||||
require 'fingers/commands'
|
||||
require 'fingers/commands/base'
|
||||
require 'fingers/commands/capture_tty_input'
|
||||
require 'fingers/commands/check_version'
|
||||
require 'fingers/commands/load_config'
|
||||
require 'fingers/commands/send_input'
|
||||
|
@ -44,7 +41,6 @@ require 'fingers/commands/start'
|
|||
require 'fingers/action_runner'
|
||||
require 'fingers/hinter'
|
||||
require 'fingers/input_socket'
|
||||
require 'fingers/tty_input'
|
||||
require 'fingers/logger'
|
||||
require 'fingers/view'
|
||||
require 'fingers/match_formatter'
|
||||
|
|
|
@ -19,8 +19,6 @@ module Fingers
|
|||
Fingers::Commands::SendInput
|
||||
when 'load_config'
|
||||
Fingers::Commands::LoadConfig
|
||||
when 'capture_tty_input'
|
||||
Fingers::Commands::CaptureTtyInput
|
||||
else
|
||||
raise "Unknown command #{ARGV[0]}"
|
||||
end
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
class Fingers::Commands::CaptureTtyInput < Fingers::Commands::Base
|
||||
def run
|
||||
supress_stdout!
|
||||
TtyInput.new.forward_to_input_socket!
|
||||
rescue Errno::EIO => e
|
||||
Fingers.logger.debug(e)
|
||||
exit(0)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def supress_stdout!
|
||||
$stdout.reopen('/dev/null', 'w')
|
||||
end
|
||||
end
|
||||
|
|
@ -8,9 +8,9 @@ class Fingers::Commands::CheckVersion < Fingers::Commands::Base
|
|||
response = Net::HTTP.get_response(uri)
|
||||
json_response = JSON.parse(response.body)
|
||||
|
||||
latest_release = json_response.map { |tag| Version.new(tag['name']) }.max
|
||||
latest_release = json_response.map { |tag| Gem::Version.new(tag['name']) }.max
|
||||
|
||||
current_release = Version.new(Fingers::VERSION)
|
||||
current_release = Gem::Version.new(Fingers::VERSION)
|
||||
|
||||
puts "There is a new tmux-fingers release: #{latest_release}" if latest_release > current_release
|
||||
rescue StandardError => e
|
||||
|
|
|
@ -38,22 +38,10 @@ class Fingers::Commands::LoadConfig < Fingers::Commands::Base
|
|||
validate_options!
|
||||
parse_tmux_conf
|
||||
setup_bindings
|
||||
check_tmux_capabilities
|
||||
save_config
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_tmux_capabilities
|
||||
man_tmux = `man tmux 2> /dev/null`.chomp
|
||||
|
||||
can_swap_and_zoom = !man_tmux.scan(/swap-pane.*Z.*dst-pane.*\n/).empty?
|
||||
end
|
||||
|
||||
def save_config
|
||||
Fingers.save_config
|
||||
end
|
||||
|
||||
def parse_tmux_conf
|
||||
options = shell_safe_options
|
||||
|
||||
|
@ -84,6 +72,7 @@ class Fingers::Commands::LoadConfig < Fingers::Commands::Base
|
|||
|
||||
Fingers.config.alphabet = ALPHABET_MAP[Fingers.config.keyboard_layout.to_sym].split('')
|
||||
|
||||
Fingers.save_config
|
||||
end
|
||||
|
||||
def clean_up_patterns(patterns)
|
||||
|
@ -91,11 +80,12 @@ class Fingers::Commands::LoadConfig < Fingers::Commands::Base
|
|||
end
|
||||
|
||||
def setup_bindings
|
||||
input_mode = 'fingers-mode'
|
||||
ruby_bin = "#{RbConfig.ruby} --disable-gems"
|
||||
|
||||
`tmux bind-key #{Fingers.config.key} run-shell -b "#{ruby_bin} #{cli} start '\#{pane_id}' >>#{Fingers::Dirs::LOG_PATH} 2>&1"`
|
||||
`tmux bind-key #{Fingers.config.key} run-shell -b "#{ruby_bin} #{cli} start '#{input_mode}' '\#{pane_id}' >>#{Fingers::Dirs::LOG_PATH} 2>&1"`
|
||||
|
||||
setup_fingers_mode_bindings if tmux.supports_any_key?
|
||||
setup_fingers_mode_bindings if input_mode == 'fingers-mode'
|
||||
end
|
||||
|
||||
def setup_fingers_mode_bindings
|
||||
|
|
|
@ -5,7 +5,7 @@ class PanePrinter
|
|||
end
|
||||
|
||||
def print(msg)
|
||||
@file.write(msg)
|
||||
@file.print(msg)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -23,7 +23,7 @@ class Fingers::Commands::Start < Fingers::Commands::Base
|
|||
)
|
||||
|
||||
def run
|
||||
_, original_pane_id = args
|
||||
_, _input_mode, original_pane_id = args
|
||||
|
||||
@original_pane_id = original_pane_id
|
||||
|
||||
|
@ -50,16 +50,7 @@ class Fingers::Commands::Start < Fingers::Commands::Base
|
|||
end
|
||||
|
||||
def fingers_window
|
||||
@fingers_window ||= tmux.create_window('[fingers]', new_window_cmd, 80, 24)
|
||||
end
|
||||
|
||||
def new_window_cmd
|
||||
if tmux.supports_any_key?
|
||||
"cat"
|
||||
else
|
||||
ruby_bin = "#{RbConfig.ruby} --disable-gems"
|
||||
"#{ruby_bin} #{cli} capture_tty_input &> /dev/null"
|
||||
end
|
||||
@fingers_window ||= tmux.create_window('[fingers]', 'cat', 80, 24)
|
||||
end
|
||||
|
||||
def original_pane
|
||||
|
@ -109,7 +100,7 @@ class Fingers::Commands::Start < Fingers::Commands::Base
|
|||
view.render
|
||||
|
||||
tmux.swap_panes(fingers_pane_id, original_pane_id)
|
||||
maybe_zoom_pane(fingers_pane_id)
|
||||
tmux.zoom_pane(fingers_pane_id) if pane_was_zoomed?
|
||||
end
|
||||
|
||||
def fingers_pane_id
|
||||
|
@ -119,10 +110,8 @@ class Fingers::Commands::Start < Fingers::Commands::Base
|
|||
def handle_input
|
||||
input_socket = InputSocket.new
|
||||
|
||||
if tmux.supports_any_key?
|
||||
tmux.disable_prefix
|
||||
tmux.set_key_table 'fingers'
|
||||
end
|
||||
tmux.disable_prefix
|
||||
tmux.set_key_table 'fingers'
|
||||
|
||||
Fingers.benchmark_stamp('ready-for-input:end')
|
||||
Fingers.trace_for_tests_do_not_remove_or_the_whole_fabric_of_reality_will_tear_apart_with_unforeseen_consequences('fingers-ready')
|
||||
|
@ -153,11 +142,6 @@ class Fingers::Commands::Start < Fingers::Commands::Base
|
|||
%w[prefix]
|
||||
end
|
||||
|
||||
def maybe_zoom_pane(pane_id)
|
||||
return if tmux.supports_zoom_when_swapping_panes?
|
||||
tmux.zoom_pane(pane_id) if pane_was_zoomed?
|
||||
end
|
||||
|
||||
def pane_was_zoomed?
|
||||
original_pane.window_zoomed_flag == '1'
|
||||
end
|
||||
|
@ -168,7 +152,7 @@ class Fingers::Commands::Start < Fingers::Commands::Base
|
|||
tmux.swap_panes(fingers_pane_id, original_pane_id)
|
||||
tmux.kill_pane(fingers_pane_id)
|
||||
|
||||
maybe_zoom_pane(original_pane_id)
|
||||
tmux.zoom_pane(original_pane_id) if pane_was_zoomed?
|
||||
|
||||
restore_options
|
||||
view.run_action if state.result
|
||||
|
|
|
@ -12,11 +12,9 @@ module Fingers
|
|||
:shift_action,
|
||||
:hint_position,
|
||||
:hint_format,
|
||||
:highlight_format,
|
||||
:selected_hint_format,
|
||||
:selected_highlight_format,
|
||||
:hint_separator,
|
||||
:hint_wrapper,
|
||||
:highlight_format,
|
||||
) do
|
||||
def initialize(
|
||||
key = 'F',
|
||||
|
|
|
@ -24,7 +24,7 @@ class ::Fingers::Hinter
|
|||
lines[0..-2].each { |line| process_line(line, "\n") }
|
||||
process_line(lines[-1], '')
|
||||
|
||||
#STDOUT.flush
|
||||
STDOUT.flush
|
||||
|
||||
build_lookup_table!
|
||||
end
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
class TtyInput
|
||||
def forward_to_input_socket!
|
||||
on_input do |input|
|
||||
translated_input = translate(input)
|
||||
|
||||
input_socket.send_message(translated_input) if translated_input
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def translate(input)
|
||||
case input
|
||||
when "ctrl_c"
|
||||
"exit"
|
||||
when "q"
|
||||
"exit"
|
||||
when "Escape"
|
||||
"exit"
|
||||
when "?"
|
||||
"toggle-help"
|
||||
when "Enter"
|
||||
"noop"
|
||||
when "Tab"
|
||||
"toggle-multi_mode"
|
||||
when /^[a-z]$/
|
||||
"hint:#{input}:main"
|
||||
when /^[A-Z]$/
|
||||
"hint:#{input.downcase}:shift"
|
||||
end
|
||||
end
|
||||
|
||||
def on_input
|
||||
input = ''
|
||||
|
||||
while char = tty.getch do
|
||||
input = char
|
||||
|
||||
if char.ord == 27
|
||||
input << tty.read_nonblock(2) rescue nil
|
||||
input << tty.read_nonblock(3) rescue nil
|
||||
end
|
||||
|
||||
case input
|
||||
when " "
|
||||
yield "Space"
|
||||
when "\r"
|
||||
yield "Enter"
|
||||
when "\t"
|
||||
yield "Tab"
|
||||
when "\e"
|
||||
yield "Escape"
|
||||
when "\u0003"
|
||||
yield "ctrl_c"
|
||||
when /^[a-zA-Z]$/
|
||||
yield input
|
||||
when "?"
|
||||
yield "?"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def tty
|
||||
@tty ||= File.open('/dev/tty')
|
||||
end
|
||||
|
||||
def input_socket
|
||||
@input_socket ||= InputSocket.new
|
||||
end
|
||||
end
|
|
@ -1,6 +1,5 @@
|
|||
class Fingers::View
|
||||
|
||||
CLEAR_ESCAPE_SEQUENCE = "\e[H\e[2J".freeze
|
||||
CLEAR_ESCAPE_SEQUENCE = "\e[H\e[J".freeze
|
||||
|
||||
def initialize(hinter:, state:, output:, original_pane:)
|
||||
@hinter = hinter
|
||||
|
@ -15,7 +14,7 @@ class Fingers::View
|
|||
end
|
||||
|
||||
def render
|
||||
output.print "---clear---\n"
|
||||
output.print CLEAR_ESCAPE_SEQUENCE
|
||||
hide_cursor
|
||||
hinter.run
|
||||
end
|
||||
|
@ -38,7 +37,7 @@ class Fingers::View
|
|||
attr_reader :hinter, :state, :output, :original_pane
|
||||
|
||||
def hide_cursor
|
||||
output.print ""
|
||||
output.print `tput civis`
|
||||
end
|
||||
|
||||
def toggle_help_message
|
||||
|
|
19
lib/tmux.rb
19
lib/tmux.rb
|
@ -109,11 +109,8 @@ class Tmux
|
|||
end
|
||||
|
||||
def swap_panes(src_id, dst_id)
|
||||
flags = ['-d', '-s', src_id, '-t', dst_id]
|
||||
|
||||
flags.unshift('-Z') if supports_zoom_when_swapping_panes?
|
||||
|
||||
system(tmux, 'swap-pane', *flags)
|
||||
# TODO: -Z not supported on all tmux versions
|
||||
system(tmux, 'swap-pane', '-d', '-s', src_id, '-t', dst_id)
|
||||
end
|
||||
|
||||
def kill_pane(id)
|
||||
|
@ -178,14 +175,6 @@ class Tmux
|
|||
format_printer.print(format).chomp
|
||||
end
|
||||
|
||||
def supports_any_key?
|
||||
version >= "2.8"
|
||||
end
|
||||
|
||||
def supports_zoom_when_swapping_panes?
|
||||
version >= "3.1"
|
||||
end
|
||||
|
||||
attr_accessor :socket, :config_file
|
||||
|
||||
private
|
||||
|
@ -212,8 +201,4 @@ class Tmux
|
|||
yield fields
|
||||
end
|
||||
end
|
||||
|
||||
def version
|
||||
@version ||= Version.new(`#{tmux} -V`.chomp)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
class Version
|
||||
include Comparable
|
||||
|
||||
EXTRACT_PATTERN = /([0-9])+\.([0-9])+\.?([0-9]+|[a-z]+)?/.freeze
|
||||
CHAR_SHIFT = 97 - 1
|
||||
|
||||
def initialize(version)
|
||||
segments = version.match(EXTRACT_PATTERN).to_a
|
||||
|
||||
@major = segments[1].to_i
|
||||
@minor = segments[2].to_i
|
||||
@patch = parse_patch(segments[3])
|
||||
end
|
||||
|
||||
def <=>(raw_other)
|
||||
other = if raw_other.is_a?(String)
|
||||
Version.new(raw_other)
|
||||
else
|
||||
raw_other
|
||||
end
|
||||
|
||||
[:major, :minor, :patch].each do |segment|
|
||||
this_segment = self.send(segment)
|
||||
other_segment = other.send(segment)
|
||||
|
||||
next if this_segment == other_segment
|
||||
|
||||
return this_segment <=> other_segment
|
||||
end
|
||||
|
||||
0
|
||||
end
|
||||
|
||||
def to_s
|
||||
segments = if alphabetic_patch?
|
||||
[major, minor.to_s + patch_representation]
|
||||
else
|
||||
[major, minor, patch_representation]
|
||||
end
|
||||
|
||||
segments.join('.')
|
||||
end
|
||||
|
||||
attr_reader :major, :minor, :patch
|
||||
|
||||
private
|
||||
|
||||
def patch_representation
|
||||
alphabetic_patch? ? (patch + CHAR_SHIFT).chr : patch
|
||||
end
|
||||
|
||||
def alphabetic_patch?
|
||||
@has_alphabetic_patch
|
||||
end
|
||||
|
||||
def parse_patch(patch)
|
||||
patch ||= '0'
|
||||
|
||||
if patch.match(/^[a-z]$/)
|
||||
@has_alphabetic_patch = true
|
||||
return patch.ord - CHAR_SHIFT
|
||||
else
|
||||
@has_alphabetic_patch = false
|
||||
return patch.to_i
|
||||
end
|
||||
end
|
||||
end
|
|
@ -78,7 +78,7 @@ describe 'acceptance', :retry => 3 do
|
|||
it { should contain_content('current pane is zoomed') }
|
||||
end
|
||||
|
||||
context 'alt action', :if => Tmux.instance.supports_any_key? do
|
||||
context 'alt action' do
|
||||
let(:config_name) { 'alt-action' }
|
||||
|
||||
before do
|
||||
|
@ -114,7 +114,7 @@ describe 'acceptance', :retry => 3 do
|
|||
it { should contain_content('yanked text is scripts/hints.sh') }
|
||||
end
|
||||
|
||||
context 'ctrl action', :if => Tmux.instance.supports_any_key? do
|
||||
context 'ctrl action' do
|
||||
let(:config_name) { 'ctrl-action' }
|
||||
let(:prefix) { 'C-b' }
|
||||
let(:hint_to_press) { 'C-y' }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
if [[ -n "$CI_TMUX_VERSION" ]]; then
|
||||
VERSIONS=("$CI_TMUX_VERSION")
|
||||
else
|
||||
VERSIONS=("2.1" "2.2" "2.3" "2.4" "2.5" "2.6" "2.7" "2.8" "2.9" "2.9a" "3.0" "3.0a" "3.1c")
|
||||
VERSIONS=("2.1" "2.2" "2.3" "2.4" "2.5" "2.6" "2.7" "2.8" "2.9" "2.9a" "3.0" "3.0a")
|
||||
fi
|
||||
|
||||
sudo mkdir -p /opt
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Version do
|
||||
it 'can be compared' do
|
||||
expect(Version.new("1.2.3") > Version.new("0.2.3")).to be(true)
|
||||
expect(Version.new("1.3.3") > Version.new("1.2.3")).to be(true)
|
||||
expect(Version.new("1.2.4") > Version.new("1.2.3")).to be(true)
|
||||
|
||||
expect(Version.new("0.2.3") < Version.new("1.2.3")).to be(true)
|
||||
expect(Version.new("1.2.3") < Version.new("1.3.3")).to be(true)
|
||||
expect(Version.new("1.2.3") < Version.new("1.2.4")).to be(true)
|
||||
|
||||
expect(Version.new("1.2.3") >= Version.new("0.2.3")).to be(true)
|
||||
expect(Version.new("1.3.3") >= Version.new("1.2.3")).to be(true)
|
||||
expect(Version.new("1.2.4") >= Version.new("1.2.3")).to be(true)
|
||||
|
||||
expect(Version.new("0.2.3") <= Version.new("1.2.3") ).to be(true)
|
||||
expect(Version.new("1.2.3") <= Version.new("1.3.3") ).to be(true)
|
||||
expect(Version.new("1.2.3") <= Version.new("1.2.4") ).to be(true)
|
||||
|
||||
expect(Version.new("0.2.3") <= Version.new("1.2.3") ).to be(true)
|
||||
expect(Version.new("1.2.3") <= Version.new("1.3.3") ).to be(true)
|
||||
expect(Version.new("1.2.3") <= Version.new("1.2.4") ).to be(true)
|
||||
end
|
||||
|
||||
it 'can be sorted' do
|
||||
puts [
|
||||
Version.new("3.1"),
|
||||
Version.new("3.2b"),
|
||||
Version.new("3.3b"),
|
||||
Version.new("1.1.2"),
|
||||
Version.new("3.3c"),
|
||||
Version.new("3.1.2"),
|
||||
Version.new("3.3a"),
|
||||
Version.new("2.1.2"),
|
||||
Version.new("3.3"),
|
||||
Version.new("3.1.1"),
|
||||
Version.new("3.2"),
|
||||
Version.new("3.2.2"),
|
||||
Version.new("0.1.2")
|
||||
].sort
|
||||
end
|
||||
end
|
||||
|
|
@ -3,11 +3,14 @@
|
|||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
sudo apt update
|
||||
sudo apt remove -y tmux xsel
|
||||
sudo apt install -y fish gawk perl libevent-dev libncurses5-dev
|
||||
sudo apt install -y fish gawk perl
|
||||
|
||||
sudo useradd -m -p "$(perl -e "print crypt('fishman','sa');")" -s "/usr/bin/fish" fishman
|
||||
|
||||
# remove system tmux and install tmux dependencies
|
||||
sudo aptitude remove -y tmux xsel
|
||||
sudo aptitude install -y libevent-dev libncurses5-dev
|
||||
|
||||
# stub xclip globally, to avoid having to use xvfb
|
||||
if [[ ! -e /usr/bin/xclip ]]; then
|
||||
sudo ln -s $CURRENT_DIR/stubs/action-stub.sh /usr/bin/xclip
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
version="$1"
|
||||
sudo rm -rf /usr/bin/tmux /usr/local/bin/tmux
|
||||
sudo ln -s /opt/tmux-${version}/tmux /usr/bin/tmux
|
||||
sudo rm -rf /usr/local/bin/tmux
|
||||
sudo ln -s /opt/tmux-${version}/tmux /usr/local/bin/tmux
|
||||
sudo ln -s /opt/tmux-${version}/tmux /usr/bin/tmux
|
||||
|
|
Loading…
Reference in New Issue