cli: add support for partial completion with separator character master
authorFelix Fietkau <nbd@nbd.name>
Mon, 24 Feb 2025 20:22:52 +0000 (21:22 +0100)
committerFelix Fietkau <nbd@nbd.name>
Mon, 24 Feb 2025 20:22:54 +0000 (21:22 +0100)
Useful for completing long lists of possible values with common prefix

Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/utils/cli/files/usr/sbin/cli
package/utils/cli/files/usr/share/ucode/cli/context.uc

index 0a763f2fdb343204014aaa5cf0aef00b4b4134b5..7d950e6adc5caf30a5f8172ba95a787584c811b7 100755 (executable)
@@ -311,7 +311,10 @@ function completion(count) {
                                add = "    ";
                        cat = "";
 
-                       add += sprintf("%-"+len+"s", entry.name);
+                       let name = entry.name;
+                       if (entry.incomplete)
+                               name += "...";
+                       add += sprintf("%-"+len+"s", name);
                        str += add;
                        x += length(add);
 
index b3f24f77a8cbd7f9bd9f5ab1e702fa635bf22e94..53b5f57047fd15b5bce9e65794cabf3e1716725c 100644 (file)
@@ -355,7 +355,36 @@ function complete_arg_list(e, ctx, arg_info, args, base_args, named_args)
        for (let i = 0; i <= cur_idx; i++)
                val = shift(args);
 
-       return complete_param(e, ctx, cur, val, base_args, named_args);
+       let ret = complete_param(e, ctx, cur, val, base_args, named_args);
+       if (!cur.prefix_separator)
+               return ret;
+
+       let prefix_len = length(val);
+       let vals = [];
+       let match_prefix;
+       for (let cur_val in ret.value) {
+               let cur_str = cur_val.name;
+               let cur_suffix = substr(cur_str, prefix_len);
+               let idx = index(cur_suffix, cur.prefix_separator);
+               if (idx < 0) {
+                       push(vals, cur_val);
+                       continue;
+               }
+
+               let cur_prefix = substr(cur_str, 0, prefix_len + idx + 1);
+               if (cur_prefix == match_prefix)
+                       continue;
+
+               match_prefix = cur_prefix;
+               push(vals, {
+                       ...cur_val,
+                       name: cur_prefix,
+                       incomplete: true
+               });
+       }
+       ret.value = vals;
+
+       return ret;
 }
 
 function handle_empty_param(entry, spec, name, argv, named_args)