This commit is contained in:
Jorge Morante 2023-03-27 09:23:45 +02:00
parent 661c6210a9
commit e98baf6ba6
15 changed files with 321 additions and 49 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ vendor/bundle
.cache
.byebug_history
shared
build/*

47
Rakefile Normal file
View File

@ -0,0 +1,47 @@
# frozen_string_literal: true
MRUBY_REV = '1c765dc37a80bf681bbab271b0ba90711d935be9'
MRUBY_ROOT = 'build/mruby'
RUBY_FILES = [
'lib/tmux.rb',
'lib/tmux_format_printer.rb',
'lib/huffman.rb',
'lib/priority_queue.rb',
'lib/fingers/version.rb',
'lib/fingers/dirs.rb',
'lib/fingers/config.rb',
'lib/fingers/commands.rb',
'lib/fingers/commands/base.rb',
'lib/fingers/commands/show_version.rb',
'lib/fingers/commands/load_config.rb',
'lib/fingers/commands/start.rb',
'lib/fingers/cli.rb',
'lib/fingers/hinter.rb',
'lib/fingers/logger.rb',
'lib/fingers/view.rb',
'lib/fingers/match_formatter.rb',
'lib/main.rb'
].freeze
directory MRUBY_ROOT do |_t|
sh "git clone git@github.com:mruby/mruby #{MRUBY_ROOT}"
Dir.chdir('build/mruby') do
sh "git checkout #{MRUBY_REV}"
end
end
desc 'Compile mruby'
task build_mruby: [MRUBY_ROOT] do
Dir.chdir('build/mruby') do
sh 'MRUBY_CONFIG=../../build_config.rb rake'
end
end
desc 'Compile tmux-fingers'
task compile: ['build_mruby'] do
sh "#{MRUBY_ROOT}/bin/mrbc -B main_ruby -o build/bytecode.c #{RUBY_FILES.join(' ')}"
sh "gcc -std=c99 -I#{MRUBY_ROOT}/include main.c -o build/tmux-fingers #{MRUBY_ROOT}/build/host/lib/libmruby.a -lm"
sh 'echo tmux-fingers build complete'
end

90
build_config.rb Normal file
View File

@ -0,0 +1,90 @@
MRuby::Build.new do |conf|
# load specific toolchain settings
conf.toolchain
# Use mrbgems
conf.gem :core => 'mruby-sleep'
conf.gem :github => 'iij/mruby-env'
conf.gem :github => 'mttech/mruby-getopts'
conf.gem :github => 'ksss/mruby-singleton'
conf.gem :github => 'iij/mruby-tempfile'
conf.gem :github => 'mattn/mruby-onig-regexp' do |g|
g.bundle_onigmo
end
conf.gem :github => 'katzer/mruby-logger'
conf.gem :github => 'mattn/mruby-json'
# conf.gem 'examples/mrbgems/ruby_extension_example'
# conf.gem 'examples/mrbgems/c_extension_example' do |g|
# g.cc.flags << '-g' # append cflags in this gem
# end
# conf.gem 'examples/mrbgems/c_and_ruby_extension_example'
conf.gem :core => 'mruby-eval'
# conf.gem :mgem => 'mruby-onig-regexp'
# conf.gem :github => 'mattn/mruby-onig-regexp'
# conf.gem :git => 'git@github.com:mattn/mruby-onig-regexp.git', :branch => 'master', :options => '-v'
# include the GEM box
conf.gembox 'default'
# C compiler settings
# conf.cc do |cc|
# cc.command = ENV['CC'] || 'gcc'
# cc.flags = [ENV['CFLAGS'] || %w()]
# cc.include_paths = ["#{root}/include"]
# cc.defines = %w()
# cc.option_include_path = %q[-I"%s"]
# cc.option_define = '-D%s'
# cc.compile_options = %Q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"]
# end
# mrbc settings
# conf.mrbc do |mrbc|
# mrbc.compile_options = "-g -B%{funcname} -o-" # The -g option is required for line numbers
# end
# Linker settings
# conf.linker do |linker|
# linker.command = ENV['LD'] || 'gcc'
# linker.flags = [ENV['LDFLAGS'] || []]
# linker.flags_before_libraries = []
# linker.libraries = %w()
# linker.flags_after_libraries = []
# linker.library_paths = []
# linker.option_library = '-l%s'
# linker.option_library_path = '-L%s'
# linker.link_options = %Q[%{flags} -o "%{outfile}" %{objs} %{libs}]
# end
# Archiver settings
# conf.archiver do |archiver|
# archiver.command = ENV['AR'] || 'ar'
# archiver.archive_options = 'rs "%{outfile}" %{objs}'
# end
# Parser generator settings
# conf.yacc do |yacc|
# yacc.command = ENV['YACC'] || 'bison'
# yacc.compile_options = %q[-o "%{outfile}" "%{infile}"]
# end
# gperf settings
# conf.gperf do |gperf|
# gperf.command = 'gperf'
# gperf.compile_options = %q[-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" "%{infile}" > "%{outfile}"]
# end
# file extensions
# conf.exts do |exts|
# exts.object = '.o'
# exts.executable = '' # '.exe' if Windows
# exts.library = '.a'
# end
# file separator
# conf.file_separator = '/'
# Turn on `enable_debug` for better debugging
# conf.enable_debug
conf.enable_bintest
conf.enable_test
end

47
build_config.rb.lock Normal file
View File

@ -0,0 +1,47 @@
---
mruby:
version: 3.2.0
release_no: 30200
git_commit: 1c765dc37a80bf681bbab271b0ba90711d935be9
builds:
host:
https://github.com/iij/mruby-env.git:
url: https://github.com/iij/mruby-env.git
branch: HEAD
commit: 056ae324451ef16a50c7887e117f0ea30921b71b
version: 0.0.0
https://github.com/mttech/mruby-getopts.git:
url: https://github.com/mttech/mruby-getopts.git
branch: HEAD
commit: 32878292c1162a911b39e1e0810a28ab2cb83f6a
version: 0.0.0
https://github.com/ksss/mruby-singleton.git:
url: https://github.com/ksss/mruby-singleton.git
branch: HEAD
commit: 73dd4bae1a47d82e49b8f85bf27f49ec4462052e
version: 0.0.0
https://github.com/iij/mruby-tempfile.git:
url: https://github.com/iij/mruby-tempfile.git
branch: HEAD
commit: 9b883438547020dae328e34c8a2fe736171cd0ab
version: 0.0.0
https://github.com/mattn/mruby-onig-regexp.git:
url: https://github.com/mattn/mruby-onig-regexp.git
branch: HEAD
commit: 074325207f9181ad242ffb8de34072607164f57f
version: 0.0.0
https://github.com/katzer/mruby-logger.git:
url: https://github.com/katzer/mruby-logger.git
branch: HEAD
commit: f794ef6f6ceff1794d02a6d9cfc1d281bdfcad21
version: 0.0.0
https://github.com/iij/mruby-iijson.git:
url: https://github.com/iij/mruby-iijson.git
branch: HEAD
commit: c5e730c30090d3cddae258f57ab9508edb3e9fce
version: 0.0.0
https://github.com/mattn/mruby-json.git:
url: https://github.com/mattn/mruby-json.git
branch: HEAD
commit: f99d9428025469f2400f93c53b185f65f963e507
version: 0.0.0

View File

@ -1,5 +1,3 @@
#!/usr/bin/env ruby
module Fingers
class CLI
def initialize(args, cli_path)
@ -15,6 +13,8 @@ module Fingers
Fingers::Commands::Start
when "check_version"
Fingers::Commands::CheckVersion
when "show_version"
Fingers::Commands::ShowVersion
when "send_input"
Fingers::Commands::SendInput
when "load_config"
@ -28,6 +28,7 @@ module Fingers
begin
command_class.new(args, cli_path).run
rescue => e
puts e
Fingers.logger.error(e)
end
end

View File

@ -4,12 +4,12 @@ class Fingers::Commands::LoadConfig < Fingers::Commands::Base
FINGERS_FILE_PATH = "#{ENV["HOME"]}/.fingersrc"
DEFAULT_PATTERNS = {
ip: '\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}',
uuid: "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
sha: "[0-9a-f]{7,128}",
#ip: '\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}',
#uuid: "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
#sha: "[0-9a-f]{7,128}",
digit: "[0-9]{4,}",
url: "((https?://|git@|git://|ssh://|ftp://|file:///)[^ ()'\"]+)",
path: '(([.\\w\\-~\\$@]+)?(/[.\\w\\-@]+)+/?)'
#url: "((https?://|git@|git://|ssh://|ftp://|file:///)[^ ()'\"]+)",
#path: '(([.\\w\\-~\\$@]+)?(/[.\\w\\-@]+)+/?)'
}.freeze
ALPHABET_MAP = {
@ -74,17 +74,6 @@ class Fingers::Commands::LoadConfig < Fingers::Commands::Base
Fingers.config.alphabet = ALPHABET_MAP[Fingers.config.keyboard_layout.to_sym].split("")
fingers_file_require_path = File.expand_path(FINGERS_FILE_PATH, __dir__)
Fingers.logger.debug("Config: #{FINGERS_FILE_PATH}")
Fingers.logger.debug("fingers_file_require_path: #{fingers_file_require_path}")
if File.exist?(FINGERS_FILE_PATH)
`cp #{FINGERS_FILE_PATH} /tmp/fingersrc.rb`
require "/tmp/fingersrc"
`rm /tmp/fingersrc.rb`
end
Fingers.save_config
end
@ -94,10 +83,9 @@ class Fingers::Commands::LoadConfig < Fingers::Commands::Base
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 '#{input_mode}' '\#{pane_id}' self >>#{Fingers::Dirs::LOG_PATH} 2>&1"`
`tmux bind-key O run-shell -b "#{ruby_bin} #{cli} start '#{input_mode}' '\#{pane_id}' other >>#{Fingers::Dirs::LOG_PATH} 2>&1"`
`tmux bind-key #{Fingers.config.key} run-shell -b "#{cli} start '#{input_mode}' '\#{pane_id}' self >>#{Fingers::Dirs::LOG_PATH} 2>&1"`
`tmux bind-key O run-shell -b "#{cli} start '#{input_mode}' '\#{pane_id}' other >>#{Fingers::Dirs::LOG_PATH} 2>&1"`
setup_fingers_mode_bindings if input_mode == "fingers-mode"
end
@ -148,12 +136,12 @@ class Fingers::Commands::LoadConfig < Fingers::Commands::Base
def valid_option?(option)
option_method = option_to_method(option)
puts "option method #{option_method}"
Fingers.config.respond_to?(option_method) || option.match(/^@fingers-pattern-\d+$/)
end
def ensure_cache_folder
require "fileutils"
FileUtils.mkdir_p(Fingers::Dirs::CACHE) unless File.exist?(Fingers::Dirs::CACHE)
`mkdir -p #{Fingers::Dirs::CACHE}`
end
def fingers_options_names

View File

@ -0,0 +1,5 @@
class Fingers::Commands::ShowVersion < Fingers::Commands::Base
def run
puts "tmux-fingers #{Fingers::VERSION}"
end
end

View File

@ -29,6 +29,7 @@ class Fingers::Commands::Start < Fingers::Commands::Base
)
def run
Fingers.logger.info("args: #{args.to_json}")
_, _input_mode, from_pane_id, target = args
Fingers.logger.debug("from_pane_id: #{from_pane_id}")
@ -39,7 +40,9 @@ class Fingers::Commands::Start < Fingers::Commands::Base
track_options_to_restore!
show_hints
handle_input
sleep 2
#handle_input
teardown
end
@ -174,6 +177,8 @@ class Fingers::Commands::Start < Fingers::Commands::Base
from_pane = tmux.pane_by_id(from_pane_id)
return from_pane if target == "self"
Fingers.logger.info("from pane #{from_pane_id}")
Fingers.logger.info("target #{target}")
sibling_panes = tmux.panes_by_window_id(from_pane.window_id)
# TODO display message or pick pane

View File

@ -43,7 +43,7 @@ module Fingers
def self.config
$config ||= Fingers.load_from_cache
rescue
rescue StandardError => e
$config ||= ConfigStruct.new
end
@ -52,14 +52,54 @@ module Fingers
end
def self.save_config
File.write(CONFIG_PATH, Marshal.dump(Fingers.config))
f = File.open(CONFIG_PATH, 'w')
json = {}
output = "_config = ConfigStruct.new\n"
ConfigStruct.members.map do |member|
value = Fingers.escape_control_chars(Fingers.config.send(member))
if value.is_a?(String)
output += "_config.#{member} = \"#{value.gsub('"', '\"')}\"\n"
end
# Assuming all arrays are string arrays for now
if value.is_a?(Array)
output += "_config.#{member} = ["
output += value.map {|val| "\"#{val.gsub('"', '\"')}\"" }.join(", ")
output += "]\n"
end
end
output += '_config'
f.write(output)
f.close
end
def self.load_from_cache
Fingers.benchmark_stamp("load-config-from-cache:start")
result = Marshal.load(File.open(CONFIG_PATH))
Fingers.benchmark_stamp("load-config-from-cache:end")
result
#Fingers.benchmark_stamp("load-config-from-cache:start")
config_file = File.open(CONFIG_PATH)
config = Kernel.eval(config_file.read)
#json.keys.each do |member|
#config.send("#{member}=".to_sym, json[member])
#end
config
#Fingers.benchmark_stamp("load-config-from-cache:end")
#result
end
def self.escape_control_chars(value)
if value.is_a?(String)
value = value.gsub(/[\x00-\x1f]/) do |match|
"\\u%04x" % match.ord
end
elsif value.is_a?(Array)
value.map! { |v| escape_control_chars(v) }
elsif value.is_a?(Hash)
value.each do |k, v|
value[k] = escape_control_chars(v)
end
end
value
end
def self.configure

View File

@ -1,11 +1,9 @@
module Fingers::Dirs
tmux_pid = (ENV["TMUX"] || ",0000").split(",")[1]
FINGERS_REPO_ROOT = Pathname.new(__dir__).parent.parent
root = "#{Dir.tmpdir}/tmux-fingers".freeze
root = Pathname.new(Dir.tmpdir) / "tmux-fingers"
LOG_PATH = FINGERS_REPO_ROOT / "fingers.log"
CACHE = root / "tmux-#{tmux_pid}"
CONFIG_PATH = CACHE / "fingers.config"
SOCKET_PATH = CACHE / "fingers.sock"
LOG_PATH = "#{root}/mruby-fingers.log".freeze
CACHE = "#{root}/tmux-#{tmux_pid}".freeze
CONFIG_PATH = "#{CACHE}/fingers.mruby.config".freeze
SOCKET_PATH = "#{CACHE}/fingers.mruby.sock".freeze
end

View File

@ -56,6 +56,7 @@ class ::Fingers::Hinter
end
def process_line(line, ending)
Fingers.logger.info("processing line")
result = line.gsub(pattern) { |_m| replace($~) }
output.print(result + ending)
end
@ -73,16 +74,18 @@ class ::Fingers::Hinter
def replace(match)
text = match[0]
captured_text = match && match.named_captures["capture"] || text
#captured_text = match && match.named_captures["capture"] || text
captured_text = match && match || text
if match.named_captures["capture"]
match_start, match_end = match.offset(0)
capture_start, capture_end = match.offset(:capture)
#if match.named_captures["capture"]
#match_start, match_end = match.offset(0)
#capture_start, capture_end = match.offset(:capture)
capture_offset = [capture_start - match_start, capture_end - capture_start]
else
#capture_offset = [capture_start - match_start, capture_end - capture_start]
#else
capture_offset = nil
end
#end
if hints_by_text.has_key?(captured_text)
hint = hints_by_text[captured_text]
@ -91,6 +94,7 @@ class ::Fingers::Hinter
hints_by_text[captured_text] = hint
end
# TODO: this should be output hint without ansi escape sequences
formatter.format(
hint: hint,
@ -98,10 +102,11 @@ class ::Fingers::Hinter
selected: state.selected_hints.include?(hint),
offset: capture_offset
)
end
def lines
@lines ||= input.force_encoding("UTF-8").split("\n")
@lines ||= input.split("\n")
end
def n_matches
@ -112,6 +117,9 @@ class ::Fingers::Hinter
Fingers.benchmark_stamp("counting-matches:start")
lines.each do |line|
Fingers.logger.info("line: #{line}")
Fingers.logger.info("pattern: #{pattern}")
Fingers.logger.info("----")
line.scan(pattern) do |match|
match_set.add($&)
end

View File

@ -1,5 +1,3 @@
require "logger"
module Fingers
def self.logger
return @logger if @logger
@ -12,7 +10,7 @@ module Fingers
end
def self.benchmark_stamp(tag)
Fingers.logger.debug("benchmark:#{tag} #{Process.clock_gettime(Process::CLOCK_MONOTONIC)}")
#Fingers.logger.debug("benchmark:#{tag} #{Process.clock_gettime(Process::CLOCK_MONOTONIC)}")
end
def self.trace_for_tests_do_not_remove_or_the_whole_fabric_of_reality_will_tear_apart_with_unforeseen_consequences(msg)

18
lib/main.rb Normal file
View File

@ -0,0 +1,18 @@
module Kernel
def system(*args)
`#{args.join(' ')}`
$? == 0
end
end
puts "hello"
begin
absolute_fingers_path = "/home/morantron/hacking/tmux-fingers/build/tmux-fingers"
ARGV.shift
Fingers::CLI.new(ARGV, absolute_fingers_path).run
rescue StandardError => e
puts "error"
puts e
puts e.backtrace
end
puts "goodbye"

View File

@ -209,7 +209,7 @@ class Tmux
end
def socket_flag_value
return ENV["FINGERS_TMUX_SOCKET"] if ENV["FINGERS_TMUX_SOCKET"]
#return ENV["FINGERS_TMUX_SOCKET"] if ENV["FINGERS_TMUX_SOCKET"]
socket
end
end

26
main.c Normal file
View File

@ -0,0 +1,26 @@
#include <mruby.h>
#include <mruby/irep.h>
#include <mruby/array.h>
#include "./build/bytecode.c"
int
main(int argc, char *argv[])
{
mrb_state *mrb = mrb_open();
if (!mrb) { /* handle error */ }
// Create a new mrb_value array to hold the command-line arguments
mrb_value args = mrb_ary_new_capa(mrb, argc);
// Convert each command-line argument to an mrb_value and add it to the array
for (int i = 0; i < argc; i++) {
mrb_ary_push(mrb, args, mrb_str_new_cstr(mrb, argv[i]));
}
// Set the ARGV constant to the array of command-line arguments
mrb_define_global_const(mrb, "ARGV", args);
mrb_load_irep(mrb, main_ruby);
mrb_close(mrb);
return 0;
}