tmux-fingers/src/fingers/commands/load_config.cr

207 lines
5.2 KiB
Crystal

require "file_utils"
require "./base"
require "../dirs"
require "../config"
require "../../tmux"
class Fingers::Commands::LoadConfig < Fingers::Commands::Base
@fingers_options_names : Array(String) | Nil
property config : Fingers::Config
DISALLOWED_CHARS = /[cimqn]/
def initialize(*args)
super(*args)
@config = Fingers::Config.new
end
def run
validate_options!
parse_tmux_conf
setup_bindings
end
# private
def parse_tmux_conf
options = shell_safe_options
user_defined_patterns = [] of String
Fingers.reset_config
config.tmux_version = `tmux -V`.chomp.split(" ").last
options.each do |option, value|
# TODO generate an enum somehow and use an exhaustive case
case option
when "key"
config.key = value
when "jump_key"
config.jump_key = value
when "keyboard_layout"
config.keyboard_layout = value
when "main_action"
config.main_action = value
when "ctrl_action"
config.ctrl_action = value
when "alt_action"
config.alt_action = value
when "shift_action"
config.shift_action = value
when "benchmark_mode"
config.benchmark_mode = value
when "hint_position"
config.hint_position = value
when "hint_style"
config.hint_style = tmux.parse_style(value)
when "selected_hint_style"
config.selected_hint_style = tmux.parse_style(value)
when "highlight_style"
config.highlight_style = tmux.parse_style(value)
when "backdrop_style"
config.backdrop_style = tmux.parse_style(value)
when "selected_highlight_style"
config.selected_highlight_style = tmux.parse_style(value)
when "show_copied_notification"
config.show_copied_notification = value
end
if option.match(/pattern/)
check_pattern!(value)
user_defined_patterns.push(value)
end
end
config.patterns = clean_up_patterns([
*enabled_default_patterns,
*user_defined_patterns,
])
config.alphabet = ::Fingers::Config::ALPHABET_MAP[Fingers.config.keyboard_layout].split("").reject do |char|
char.match(DISALLOWED_CHARS)
end
config.save
Fingers.reset_config
rescue e : TmuxStylePrinter::InvalidFormat
puts "[tmux-fingers] #{e.message}"
exit(1)
end
def clean_up_patterns(patterns)
patterns.reject(&.empty?)
end
def setup_bindings
`tmux bind-key #{Fingers.config.key} run-shell -b "#{cli} start "\#{pane_id}" self >>#{Fingers::Dirs::LOG_PATH} 2>&1"`
`tmux bind-key #{Fingers.config.jump_key} run-shell -b "#{cli} start "\#{pane_id}" jump >>#{Fingers::Dirs::LOG_PATH} 2>&1"`
setup_fingers_mode_bindings
end
def setup_fingers_mode_bindings
("a".."z").to_a.each do |char|
next if char.match(DISALLOWED_CHARS)
fingers_mode_bind(char, "hint:#{char}:main")
fingers_mode_bind(char.upcase, "hint:#{char}:shift")
fingers_mode_bind("C-#{char}", "hint:#{char}:ctrl")
fingers_mode_bind("M-#{char}", "hint:#{char}:alt")
end
fingers_mode_bind("Space", "fzf")
fingers_mode_bind("C-c", "exit")
fingers_mode_bind("q", "exit")
fingers_mode_bind("Escape", "exit")
fingers_mode_bind("?", "toggle-help")
fingers_mode_bind("Enter", "noop")
fingers_mode_bind("Tab", "toggle-multi-mode")
fingers_mode_bind("Any", "noop")
end
def enabled_default_patterns
::Fingers::Config::DEFAULT_PATTERNS.values
end
def to_bool(input)
input == "1"
end
def shell_safe_options
options = {} of String => String
fingers_options_names.each do |option|
option_method = option_to_method(option)
options[option_method] = `tmux show-option -gv #{option}`.chomp
end
options
end
def valid_option?(option)
option_method = option_to_method(option)
@config.members.includes?(option_method) || option_method.match(/pattern_[0-9]+/) || option_method == "skip_wizard"
end
def fingers_options_names
@fingers_options_names ||= `tmux show-options -g | grep ^@fingers`
.chomp.split("\n")
.map { |line| line.split(" ")[0] }
.reject { |option| option.empty? }
end
def unset_tmux_option!(option)
`tmux set-option -ug #{option}`
end
def check_pattern!(pattern)
begin
Regex.new(pattern)
rescue e: ArgumentError
puts "[tmux-fingers] Invalid pattern: #{pattern}"
puts "[tmux-fingers] #{e.message}"
exit(1)
end
end
def validate_options!
errors = [] of String
fingers_options_names.each do |option|
unless valid_option?(option)
errors << "'#{option}' is not a valid option"
unset_tmux_option!(option)
end
end
return if errors.empty?
puts "[tmux-fingers] Errors found in tmux.conf:"
errors.each { |error| puts " - #{error}" }
exit(1)
end
def option_to_method(option)
option.gsub(/^@fingers-/, "").tr("-", "_")
end
def fingers_mode_bind(key, command)
`tmux bind-key -Tfingers "#{key}" run-shell -b "#{cli} send-input #{command}"`
end
def cli
Process.executable_path
end
def tmux
Tmux.new(`tmux -V`.chomp.split(" ").last)
end
end