diff --git a/lib/ui/namespaces.js b/lib/ui/namespaces.js index 45d5107..b29331b 100644 --- a/lib/ui/namespaces.js +++ b/lib/ui/namespaces.js @@ -73,8 +73,11 @@ function prompt(screen, client, { current_namespace, promptAfterRequest } = { pr let namespaces = [], message; function updateList() { + const tokens = search.value.split(/\s+/).filter(w => w); const items = (namespaces.items || []) - .filter(n => n.metadata.name.includes(search.value)) + // Token matching + .filter(n => tokens.every(token => n.metadata.name.includes(token))) + // Color highlighting .map(n => { const item = n.metadata.name; if (search.value.length === 0) { @@ -83,13 +86,28 @@ function prompt(screen, client, { current_namespace, promptAfterRequest } = { pr } return item; } - const regex = new RegExp(search.value, 'g'); - let match, lastIndex = 0, res = ''; - while ((match = regex.exec(item)) !== null) { - res += item.substring(lastIndex, match.index) + '{yellow-fg}' + search.value + '{/yellow-fg}'; - lastIndex = regex.lastIndex; + // Highlight tokens (a bitset would probably be more efficient) + const matches = Buffer.alloc(item.length); + // Build the matching intervals + tokens.forEach(token => { + const regex = new RegExp(token, 'g'); + let match; + while ((match = regex.exec(item)) !== null) { + matches.fill(1, match.index, match.index + token.length); + } + }); + // Re-assemble the final string with the tags + let res = '', index = 0, match = false; + for (let i = 0; i < matches.length; i++) { + const m = matches.readUInt8(i) > 0; + if (match == m) continue; + res += item.substring(index, i); + res += m ? '{yellow-fg}' : '{/yellow-fg}'; + index = i; + match = m; } - res += item.substring(lastIndex); + res += item.substring(index); + // Highlight current namespace if (item === current_namespace) { res = `{blue-fg}${res}{/blue-fg}`; }