208 lines
6.8 KiB
Crystal
208 lines
6.8 KiB
Crystal
require "json"
|
|
require "../tmux_style_printer"
|
|
|
|
module Fingers
|
|
struct Config
|
|
FORMAT_PRINTER = TmuxStylePrinter.new
|
|
|
|
ALPHABET_MAP = {
|
|
"qwerty": "asdfqwerzxcvjklmiuopghtybn",
|
|
"qwerty-homerow": "asdfjklgh",
|
|
"qwerty-left-hand": "asdfqwerzcxv",
|
|
"qwerty-right-hand": "jkluiopmyhn",
|
|
"azerty": "qsdfazerwxcvjklmuiopghtybn",
|
|
"azerty-homerow": "qsdfjkmgh",
|
|
"azerty-left-hand": "qsdfazerwxcv",
|
|
"azerty-right-hand": "jklmuiophyn",
|
|
"qwertz": "asdfqweryxcvjkluiopmghtzbn",
|
|
"qwertz-homerow": "asdfghjkl",
|
|
"qwertz-left-hand": "asdfqweryxcv",
|
|
"qwertz-right-hand": "jkluiopmhzn",
|
|
"dvorak": "aoeuqjkxpyhtnsgcrlmwvzfidb",
|
|
"dvorak-homerow": "aoeuhtnsid",
|
|
"dvorak-left-hand": "aoeupqjkyix",
|
|
"dvorak-right-hand": "htnsgcrlmwvz",
|
|
"colemak": "arstqwfpzxcvneioluymdhgjbk",
|
|
"colemak-homerow": "arstneiodh",
|
|
"colemak-left-hand": "arstqwfpzxcv",
|
|
"colemak-right-hand": "neioluymjhk",
|
|
}
|
|
|
|
DISALLOWED_CHARS = /[cimqn]/
|
|
|
|
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}",
|
|
"digit": "[0-9]{4,}",
|
|
"url": "((https?://|git@|git://|ssh://|ftp://|file:///)[^\\s()\"]+)",
|
|
"path": "(([.\\w\\-~\\$@]+)?(/[.\\w\\-@]+)+/?)",
|
|
"hex": "(0x[0-9a-fA-F]+)",
|
|
"kubernetes": "(deployment.app|binding|componentstatuse|configmap|endpoint|event|limitrange|namespace|node|persistentvolumeclaim|persistentvolume|pod|podtemplate|replicationcontroller|resourcequota|secret|serviceaccount|service|mutatingwebhookconfiguration.admissionregistration.k8s.io|validatingwebhookconfiguration.admissionregistration.k8s.io|customresourcedefinition.apiextension.k8s.io|apiservice.apiregistration.k8s.io|controllerrevision.apps|daemonset.apps|deployment.apps|replicaset.apps|statefulset.apps|tokenreview.authentication.k8s.io|localsubjectaccessreview.authorization.k8s.io|selfsubjectaccessreviews.authorization.k8s.io|selfsubjectrulesreview.authorization.k8s.io|subjectaccessreview.authorization.k8s.io|horizontalpodautoscaler.autoscaling|cronjob.batch|job.batch|certificatesigningrequest.certificates.k8s.io|events.events.k8s.io|daemonset.extensions|deployment.extensions|ingress.extensions|networkpolicies.extensions|podsecuritypolicies.extensions|replicaset.extensions|networkpolicie.networking.k8s.io|poddisruptionbudget.policy|clusterrolebinding.rbac.authorization.k8s.io|clusterrole.rbac.authorization.k8s.io|rolebinding.rbac.authorization.k8s.io|role.rbac.authorization.k8s.io|storageclasse.storage.k8s.io)[[:alnum:]_#$%&+=/@-]+",
|
|
"git-status": "(modified|deleted|new file): +(?<match>.+)",
|
|
"git-status-branch": "Your branch is up to date with '(?<match>.*)'.",
|
|
"diff": "(---|\\+\\+\\+) [ab]/(?<match>.*)",
|
|
}
|
|
|
|
def self.build
|
|
from_json("{}")
|
|
end
|
|
|
|
def self.alphabet_for(layout)
|
|
ALPHABET_MAP[layout].split("").reject { |char| char =~ DISALLOWED_CHARS }
|
|
end
|
|
|
|
def self.parse_style(style)
|
|
FORMAT_PRINTER.print(style)
|
|
end
|
|
|
|
include JSON::Serializable
|
|
|
|
property key : String = "F"
|
|
|
|
getter keyboard_layout : String = "qwerty"
|
|
def keyboard_layout=(value)
|
|
if !ALPHABET_MAP[value]?
|
|
errors << "Invalid layout #{value}"
|
|
return
|
|
end
|
|
|
|
@keyboard_layout = value
|
|
end
|
|
|
|
def alphabet
|
|
self.class.alphabet_for(keyboard_layout)
|
|
end
|
|
|
|
getter patterns : Array(String) = [] of String
|
|
def patterns=(value)
|
|
value.each do |pattern|
|
|
error = Regex.error?(pattern)
|
|
if error
|
|
@errors << "Invalid regexp\n\t#{pattern}\n\t#{error}"
|
|
return
|
|
end
|
|
end
|
|
|
|
@patterns = value
|
|
end
|
|
|
|
getter highlight_style : String = parse_style("fg=green,bold")
|
|
def highlight_style=(value)
|
|
parsed_style = parse_style!(value)
|
|
@highlight_style if parsed_style
|
|
end
|
|
|
|
def parse_style!(style)
|
|
begin
|
|
self.class.parse_style(style)
|
|
rescue TmuxStylePrinter::InvalidFormat
|
|
@errors << "Invalid style: #{style}"
|
|
end
|
|
end
|
|
|
|
getter highlight_style : String = parse_style("fg=yellow")
|
|
def highlight_style=(value)
|
|
parsed_style = parse_style!(value)
|
|
@highlight_style if parsed_style
|
|
end
|
|
|
|
getter hint_style : String = parse_style("fg=green,bold")
|
|
def hint_style=(value)
|
|
parsed_style = parse_style!(value)
|
|
@hint_style if parsed_style
|
|
end
|
|
|
|
getter selected_highlight_style : String = parse_style("fg=blue")
|
|
def highlight_style=(value)
|
|
parsed_style = parse_style!(value)
|
|
@highlight_style if parsed_style
|
|
end
|
|
|
|
getter selected_hint_style : String = parse_style("fg=blue,bold")
|
|
def hint_style=(value)
|
|
parsed_style = parse_style!(value)
|
|
@hint_style if parsed_style
|
|
end
|
|
|
|
getter backdrop_style : String = ""
|
|
def hint_style=(value)
|
|
parsed_style = parse_style!(value)
|
|
@backdrop_style if parsed_style
|
|
end
|
|
|
|
def parse_style!(style)
|
|
begin
|
|
self.class.parse_style(style)
|
|
rescue TmuxStylePrinter::InvalidFormat
|
|
@errors << "Invalid style: #{style}"
|
|
end
|
|
end
|
|
|
|
property tmux_version : String = ""
|
|
property main_action : String = ":copy:"
|
|
property ctrl_action : String = ":open:"
|
|
property alt_action : String = ""
|
|
property shift_action : String = ":paste: "
|
|
|
|
getter hint_position : String = "left"
|
|
def hint_position=(value)
|
|
if !["left", "right"].includes?(value)
|
|
@errors << "Invalid hint_position #{value}"
|
|
end
|
|
@hint_position = value
|
|
end
|
|
|
|
property benchmark_mode : String = "0"
|
|
property skip_wizard : String = "0"
|
|
|
|
@[JSON::Field(ignore: true)]
|
|
property errors : Array(String) = [] of String
|
|
|
|
def valid?
|
|
errors.empty?
|
|
end
|
|
|
|
macro define_set_option
|
|
def set_option(option : String, value : String | Array(String))
|
|
case option
|
|
{% for method in @type.methods %}
|
|
{% if method.name.split("").last == "=" && method.name != "patterns=" && method.name != "errors=" %}
|
|
when "{{method.name.gsub(/=$/, "")}}"
|
|
self.{{method.name}} value
|
|
{% end %}
|
|
{% end %}
|
|
else
|
|
errors << "#{option} is not a valid option"
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.load_from_cache
|
|
Config.from_json(File.open(::Fingers::Dirs::CONFIG_PATH))
|
|
end
|
|
|
|
def save
|
|
to_json(File.open(::Fingers::Dirs::CONFIG_PATH, "w"))
|
|
end
|
|
|
|
def members : Array(String)
|
|
JSON.parse(to_json).as_h.keys
|
|
end
|
|
|
|
macro finished
|
|
define_set_option
|
|
end
|
|
end
|
|
|
|
def self.config
|
|
@@config ||= Config.load_from_cache
|
|
rescue
|
|
@@config ||= Config.build
|
|
end
|
|
|
|
def self.reset_config
|
|
@@config = nil
|
|
end
|
|
end
|