Skip to content
Open
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
dc73372
feat: add fuzzy matching algorithm for tab completions
Snehil-Shah Mar 12, 2024
3cae6a7
refactor: fix function jsdoc
Snehil-Shah Mar 24, 2024
abe7525
Merge branch 'stdlib-js:develop' into repl-fuzzy
Snehil-Shah Mar 31, 2024
dcb6014
feat: rewrite the completer engine
Snehil-Shah Apr 2, 2024
bef5dd3
feat: improve fuzzy algorithm and sort by relevancy
Snehil-Shah Apr 2, 2024
0aee34d
feat: add support for highlighted completions in terminal mode
Snehil-Shah Apr 2, 2024
7efe1a7
fix: wrong completion previews displayed for fuzzy completion
Snehil-Shah Apr 2, 2024
b0ca5c1
fix: suggestions
Snehil-Shah Apr 3, 2024
7cc9270
feat: new tab completions UI with navigation
Snehil-Shah Apr 5, 2024
24da634
refactor: move `fuzzyMatch` to a module & don't fuzzy match for previews
Snehil-Shah Apr 5, 2024
6818055
fix: changes requested
Snehil-Shah Apr 5, 2024
95a72a4
Merge branch 'develop' into repl-fuzzy
Snehil-Shah Apr 5, 2024
0c8b11a
style: lint merged changes
Snehil-Shah Apr 5, 2024
6b7dc99
feat: add a setting to control fuzzy completions
Snehil-Shah Apr 5, 2024
237fb7f
fix: limit height of completions & fix completions with prefixes
Snehil-Shah Apr 5, 2024
576f402
feat: fuzzy completions only when no exact completions
Snehil-Shah Apr 6, 2024
89b5001
fix: bug in completer
Snehil-Shah Apr 6, 2024
c464944
test: add tests for tab completions
Snehil-Shah Apr 7, 2024
6d6d7c9
docs: fix test name and comments
Snehil-Shah Apr 8, 2024
2c15d15
fix: tune fuzzy algorithm
Snehil-Shah Apr 8, 2024
0e54cf5
docs: document setting
Snehil-Shah Apr 21, 2024
7128fac
Merge branch 'develop' into repl-fuzzy
Snehil-Shah Apr 25, 2024
fa22afb
fix: abnormal completer behavior
Snehil-Shah Apr 25, 2024
7b8074a
refactor: move flag to the completer engine namespace
Snehil-Shah Apr 25, 2024
cc2f3c5
refactor: abstract logics into private methods
Snehil-Shah Apr 26, 2024
85efce4
fix: make completer `SIGWINCH` aware
Snehil-Shah Apr 26, 2024
023c31a
test: update tests for TTY
Snehil-Shah Apr 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 68 additions & 1 deletion lib/node_modules/@stdlib/repl/lib/filter_by_prefix.js
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep the prior implementation, as well. Move the fuzzy match filtering to a separate file. The ability to use prefix or fuzzy completion should be user controlled. Additionally, for completion previews, we should not use the completions generated by the fuzzy completer. They should be completions generated by the previous completer logic, as fuzzy completion has an increased perf penalty and preview completions need to, by necessity, have a smaller list of completion candidates to process.

Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,73 @@
// MODULES //

var startsWith = require( '@stdlib/string/starts-with' );
var max = require( '@stdlib/math/base/special/max' );
var abs = require( '@stdlib/math/base/special/abs' );


// FUNCTIONS //

/**
* Checks if the completion is a fuzzy match for the input.
*
* A fuzzy match is determined by the number and order of matching characters, penalizing large distances between matches.
* A score above or equal to 0.8 indicates a match.
*
* @private
* @param {string} completion - The completion string.
* @param {string} input - The input string.
* @returns {boolean} - True if the completion is a fuzzy match for the input, false otherwise.
*/
function fuzzyMatch( completion, input ) {
var charPositions;
var finalScore;
var positions;
var distance;
var score;
var index;
var char;
var i;
var j;

if ( startsWith( completion, input ) ) {
return true; // Return true for perfect matches
}

// Preprocess the completion string to get the positions of each character
positions = {};
for ( i = 0; i < completion.length; i++ ) {
char = completion[ i ];
if (!positions[ char ]) {
positions[ char] = [];
}
positions[ char ].push( i );
}

score = 0;
index = 0;
for ( i = 0; i < input.length; i++ ) {
charPositions = positions[ input[ i ] ];
if ( !charPositions ) {
continue;
}

// Find the next position of the character that is greater than or equal to index
j = 0;
while ( j < charPositions.length && charPositions[ j ] < index ) {
j += 1;
}
if ( j === charPositions.length ) {
continue;
}

distance = abs( charPositions[ j ] - i );
score += max( 0, 1 - ( distance * 0.25 ) ); // Subtract a penalty based on the distance between matching characters
index = charPositions[ j ] + 1;
}
finalScore = score / input.length; // Calculate relative score

return finalScore >= 0.65;
}


// MAIN //
Expand All @@ -37,7 +104,7 @@ var startsWith = require( '@stdlib/string/starts-with' );
function filterByPrefix( out, arr, str ) {
var i;
for ( i = 0; i < arr.length; i++ ) {
if ( startsWith( arr[ i ], str ) ) {
if ( fuzzyMatch( arr[ i ], str ) ) {
out.push( arr[ i ] );
}
}
Expand Down