xshell 1.1.9 → 1.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/utils.js CHANGED
@@ -2,7 +2,7 @@ import { Stream, Writable, Transform } from 'stream';
2
2
  import util from 'util';
3
3
  import timers from 'timers/promises';
4
4
  import { t } from "./i18n/instance.js";
5
- import { build_selector, not_empty, is_key_type, noop } from "./prototype.js";
5
+ import { build_mapper, not_empty, is_key_type, noop, ident } from "./prototype.js";
6
6
  /** `230` term 字符宽度 (实际上有 240) */
7
7
  export const output_width = 230;
8
8
  export function set_inspect_options(colors = true) {
@@ -26,6 +26,7 @@ export function assert(assertion, message) {
26
26
  debugger;
27
27
  throw new Error(`${t('断言失败')}: ${message ? `${message}: ` : ''}`);
28
28
  }
29
+ return assertion;
29
30
  }
30
31
  /** 做参数校验,逻辑检查 */
31
32
  export function check(condition, message) {
@@ -33,6 +34,7 @@ export function check(condition, message) {
33
34
  debugger;
34
35
  throw new Error(message || t('检查失败'));
35
36
  }
37
+ return condition;
36
38
  }
37
39
  export function log(...args) {
38
40
  if (args.length === 2) {
@@ -46,16 +48,16 @@ export function log(...args) {
46
48
  return obj;
47
49
  }
48
50
  }
49
- /** 数组或 iterable 去重(可按 selector 去重),重复值保留最后出现的那个
50
- - selector?: 可以是 key (string, number, symbol) 或 (obj: any) => any */
51
- export function unique(iterable, selector) {
52
- if (!selector)
51
+ /** 数组或 iterable 去重(可按 mapper 选择或计算某个值来去重),重复值保留最后出现的那个
52
+ - mapper?: 可以是 key (string, number, symbol) 或 (obj: any) => any */
53
+ export function unique(iterable, mapper) {
54
+ if (!mapper)
53
55
  return [...new Set(iterable)];
54
- if (is_key_type(selector))
55
- selector = build_selector(selector);
56
+ if (is_key_type(mapper))
57
+ mapper = build_mapper(mapper);
56
58
  let map = new Map();
57
59
  for (const x of iterable)
58
- map.set(selector(x), x);
60
+ map.set(mapper(x), x);
59
61
  return [...map.values()];
60
62
  }
61
63
  /** 生成 0, 1, ..., n - 1 (不包括 n) 的数组,支持传入 generator 函数,通过 index 生成各个元素
@@ -130,6 +132,33 @@ export function vercmp(l, r, loose = false) {
130
132
  // loose 下按短的优先,否则应该一样,为 0
131
133
  return lparts.length - rparts.length;
132
134
  }
135
+ /** 模糊过滤字符串列表或对象列表,常用于根据用户输入补全或搜索过滤
136
+ - query: 查询字符串,要求为全小写
137
+ - list: 要过滤的列表
138
+ - list_lower?: 要过滤的列表对应的全小写字符串列表形式,传入时可复用缓存,加快搜索速度 */
139
+ export function fuzzyfilter(query, list, mapper = ident, list_lower, single_char_startswith = false) {
140
+ if (!query)
141
+ return list;
142
+ if (is_key_type(mapper))
143
+ mapper = build_mapper(mapper);
144
+ mapper ??= ident;
145
+ list_lower ??= list.map(item => mapper(item).toLowerCase());
146
+ if (single_char_startswith && query.length === 1) {
147
+ const c = query[0];
148
+ return list.filter((_, i) => list_lower[i].startsWith(c));
149
+ }
150
+ const query_lower = query.toLowerCase();
151
+ return list.filter((_, i) => {
152
+ const str_lower = list_lower[i];
153
+ let j = 0;
154
+ for (const c of query_lower) {
155
+ j = str_lower.indexOf(c, j) + 1;
156
+ if (!j) // 找不到则 j === 0
157
+ return false;
158
+ }
159
+ return true;
160
+ });
161
+ }
133
162
  export function get(obj, keypath) {
134
163
  let obj_ = obj;
135
164
  for (const key of keypath.split('.'))