///|
/// Policy rules that do not depend on another binding.
fn finding(
code : String,
kind : IssueKind,
severity : Severity,
message : String,
binding : Binding,
suggestion : String,
) -> Finding {
{
code,
kind,
severity,
message,
primary_id: binding.id,
secondary_id: "",
shortcut: binding.keys.canonical,
context: binding.context,
source: binding.source,
line: binding.line,
suggestion,
}
}
///|
fn pair_finding(
code : String,
kind : IssueKind,
severity : Severity,
message : String,
left : Binding,
right : Binding,
suggestion : String,
) -> Finding {
{
code,
kind,
severity,
message,
primary_id: left.id,
secondary_id: right.id,
shortcut: left.keys.canonical,
context: left.context,
source: left.source,
line: left.line,
suggestion,
}
}
///|
fn accessibility_finding(binding : Binding) -> Finding? {
if !binding.keys.has_modifier && binding.keys.steps.length() == 1 {
Some(
finding(
"MK201",
AccessibilityRisk,
Warning,
"single-key binding has no modifier and may be triggered accidentally",
binding,
"prefer a documented modifier chord or mark the command as intentional",
),
)
} else if binding.keys.modifier_count > 3 {
Some(
finding(
"MK202",
AccessibilityRisk,
Warning,
"chord contains more than three modifiers and is difficult to operate",
binding,
"reduce the modifier count or provide a command-palette alternative",
),
)
} else {
None
}
}
///|
fn duplicate_id_finding(left : Binding, right : Binding) -> Finding {
pair_finding(
"MK101",
InvalidRecord,
Error,
"binding ids must be unique within a keymap",
left,
right,
"rename one id so review tools can address the binding unambiguously",
)
}
///|
fn invalid_context_finding(keymap : Keymap, binding : Binding) -> Finding? {
if context_exists(keymap, binding.context) {
None
} else {
Some(
finding(
"MK102",
InvalidContext,
Error,
"binding refers to an undeclared context",
binding,
"declare the context before using it, or use global",
),
)
}
}
///|
fn disabled_finding(binding : Binding) -> Finding? {
if binding.enabled {
None
} else {
Some(
finding(
"MK301",
DisabledBinding,
Info,
"binding is disabled and will not be reachable at runtime",
binding,
"remove stale declarations or explain why the disabled entry is retained",
),
)
}
}
///|
fn reserved_finding(keymap : Keymap, binding : Binding) -> Finding? {
if reserved_matches(keymap, binding) {
Some(
finding(
"MK401",
ReservedShortcut,
Error,
"shortcut is reserved by the operating system or product policy",
binding,
"choose a non-reserved chord or scope the binding to a safe platform",
),
)
} else {
None
}
}