Comparing version 0.4.5 to 0.5.0
{ | ||
"name": "node-fzf", | ||
"version": "0.4.5", | ||
"version": "0.5.0", | ||
"description": "fzf ( junegunn/fzf ) inspired cli utility for node", | ||
@@ -5,0 +5,0 @@ "main": "src/main.js", |
@@ -31,2 +31,5 @@ [![npm](https://img.shields.io/npm/v/node-fzf.svg?maxAge=3600&style=flat-square)](https://www.npmjs.com/package/node-fzf) | ||
// if you only care about r.query | ||
// nfzf.getInput( label ) | ||
const opts = { | ||
@@ -67,2 +70,5 @@ list: [ 'whale', 'giraffe', 'monkey' ] | ||
// if you only care about r.query | ||
// nfzf.getInput( label, callback ) | ||
const list = [ 'whale', 'giraffe', 'monkey' ] | ||
@@ -69,0 +75,0 @@ |
207
src/main.js
@@ -22,2 +22,16 @@ // used to read keyboard input while at the same time | ||
// helper to only get user input | ||
module.exports.getInput = getInput | ||
function getInput ( label, callback ) | ||
{ | ||
const opts = { | ||
label: label, | ||
list: [], | ||
nolist: true // don't print list/matches | ||
} | ||
return queryUser( opts, callback ) | ||
} | ||
function queryUser ( opts, callback ) | ||
@@ -672,103 +686,120 @@ { | ||
// print input buffer arrow | ||
stdout.write( clcFgBufferArrow( '> ' ) ) | ||
const inputLabel = _opts.label || clcFgBufferArrow( '> ' ) | ||
const inputLabels = inputLabel.split( '\n' ) | ||
const lastInputLabel = inputLabels[ inputLabels.length - 1 ] | ||
const inputLabelHeight = inputLabels.length - 1 | ||
if ( render.init ) stdout.write( clc.move.up( inputLabelHeight ) ) | ||
render.init = true | ||
// print input label | ||
stdout.write( inputLabel ) | ||
stdout.write( buffer ) | ||
stdout.write( '\n' ) | ||
/* Here we color the matched items text for terminal | ||
* printing based on what characters were found/matched. | ||
* | ||
* Since each filter is separated by space we first | ||
* combine all matches from all filters(words). | ||
* | ||
* If we want to only color based on the most recent | ||
* filter (last word) then just use the matches from the | ||
* last word. | ||
*/ | ||
for ( let i = 0; i < _matches.length; i++ ) { | ||
const match = _matches[ i ] | ||
// do not print the list at all when `nolist` is set | ||
// this is used when we only care about the input query | ||
if ( !_opts.nolist ) { | ||
stdout.write( '\n' ) | ||
const words = buffer.split( /\s+/ ) | ||
let indexMap = {} // as map to prevent duplicates indexes | ||
for ( let i = 0; i < words.length; i++ ) { | ||
const word = words[ i ] | ||
const matches = getMatches( _opts.mode, word, match.text ) | ||
matches.forEach( function ( i ) { | ||
indexMap[ i ] = true | ||
} ) | ||
} | ||
/* Here we color the matched items text for terminal | ||
* printing based on what characters were found/matched. | ||
* | ||
* Since each filter is separated by space we first | ||
* combine all matches from all filters(words). | ||
* | ||
* If we want to only color based on the most recent | ||
* filter (last word) then just use the matches from the | ||
* last word. | ||
*/ | ||
for ( let i = 0; i < _matches.length; i++ ) { | ||
const match = _matches[ i ] | ||
const words = buffer.split( /\s+/ ) | ||
let indexMap = {} // as map to prevent duplicates indexes | ||
for ( let i = 0; i < words.length; i++ ) { | ||
const word = words[ i ] | ||
const matches = getMatches( _opts.mode, word, match.text ) | ||
matches.forEach( function ( i ) { | ||
indexMap[ i ] = true | ||
} ) | ||
} | ||
const indexes = Object.keys( indexMap ) | ||
indexes.sort() // sort indexes | ||
// transform the text to a colorized version | ||
match.text = colorIndexesOnText( indexes, match.text /*, clcFgGreen */ ) | ||
} | ||
const indexes = Object.keys( indexMap ) | ||
indexes.sort() // sort indexes | ||
// print matches length vs original list length | ||
const n = _matches.length | ||
stdout.write( ' ' ) | ||
stdout.write( clcFgGreen( n + '/' + _list.length ) ) | ||
// transform the text to a colorized version | ||
match.text = colorIndexesOnText( indexes, match.text /*, clcFgGreen */ ) | ||
} | ||
// TODO print mode | ||
stdout.write( ' ' + clcFgModeStatus( _opts.mode + ' mode' ) ) | ||
// print matches length vs original list length | ||
const n = _matches.length | ||
stdout.write( ' ' ) | ||
stdout.write( clcFgGreen( n + '/' + _list.length ) ) | ||
// show mode switch suggestion | ||
let suggestionColor = clc.blackBright | ||
if ( n === 0 || n === _opts.list.length ) { | ||
suggestionColor = clc.yellowBright | ||
} | ||
stdout.write( suggestionColor( ' ctrl-s to switch' ) ) | ||
// TODO print mode | ||
stdout.write( ' ' + clcFgModeStatus( _opts.mode + ' mode' ) ) | ||
stdout.write( '\n' ) | ||
// show mode switch suggestion | ||
let suggestionColor = clc.blackBright | ||
if ( n === 0 || n === _opts.list.length ) { | ||
suggestionColor = clc.yellowBright | ||
} | ||
stdout.write( suggestionColor( ' ctrl-s to switch' ) ) | ||
// select first item in list by default ( empty fuzzy search matches first | ||
// item.. ) | ||
if ( !_selectedItem ) { | ||
_selectedItem = _matches[ 0 ] | ||
} | ||
stdout.write( '\n' ) | ||
// print the matches | ||
_printedMatches = 0 | ||
// select first item in list by default ( empty fuzzy search matches first | ||
// item.. ) | ||
if ( !_selectedItem ) { | ||
_selectedItem = _matches[ 0 ] | ||
} | ||
// max lines to use for printing matched results | ||
const maxPrintedLines = Math.min( _matches.length, MIN_HEIGHT ) | ||
// print the matches | ||
_printedMatches = 0 | ||
let paddingBottom = 2 // 1 extra padding at the bottom when scrolling down | ||
if ( _matches.length <= MIN_HEIGHT ) { | ||
// no extra padding at the bottom since there is no room for it | ||
// - othewise first match is cut off and will not be visible | ||
paddingBottom = 1 | ||
} | ||
// max lines to use for printing matched results | ||
const maxPrintedLines = Math.min( _matches.length, MIN_HEIGHT ) | ||
// first matched result to print | ||
const startIndex = Math.max( 0, selectedIndex - maxPrintedLines + paddingBottom ) | ||
let paddingBottom = 2 // 1 extra padding at the bottom when scrolling down | ||
if ( _matches.length <= MIN_HEIGHT ) { | ||
// no extra padding at the bottom since there is no room for it | ||
// - othewise first match is cut off and will not be visible | ||
paddingBottom = 1 | ||
} | ||
// last matched result to print | ||
const endIndex = Math.min( maxPrintedLines + startIndex, _matches.length ) | ||
// first matched result to print | ||
const startIndex = Math.max( 0, selectedIndex - maxPrintedLines + paddingBottom ) | ||
// print matches | ||
for ( let i = startIndex; i < endIndex; i++ ) { | ||
_printedMatches++ | ||
// last matched result to print | ||
const endIndex = Math.min( maxPrintedLines + startIndex, _matches.length ) | ||
const match = _matches[ i ] | ||
// print matches | ||
for ( let i = startIndex; i < endIndex; i++ ) { | ||
_printedMatches++ | ||
const item = match.text | ||
const match = _matches[ i ] | ||
const itemSelected = ( | ||
( selectedIndex === i ) | ||
) | ||
const item = match.text | ||
if ( itemSelected ) { | ||
_selectedItem = match | ||
stdout.write( clcBgGray( clcFgArrow( '> ' ) ) ) | ||
stdout.write( clcBgGray( item ) ) | ||
stdout.write( '\n' ) | ||
} else { | ||
stdout.write( clcBgGray( ' ' ) ) | ||
stdout.write( ' ' ) | ||
stdout.write( item ) | ||
stdout.write( '\n' ) | ||
const itemSelected = ( | ||
( selectedIndex === i ) | ||
) | ||
if ( itemSelected ) { | ||
_selectedItem = match | ||
stdout.write( clcBgGray( clcFgArrow( '> ' ) ) ) | ||
stdout.write( clcBgGray( item ) ) | ||
stdout.write( '\n' ) | ||
} else { | ||
stdout.write( clcBgGray( ' ' ) ) | ||
stdout.write( ' ' ) | ||
stdout.write( item ) | ||
stdout.write( '\n' ) | ||
} | ||
} | ||
// move back to cursor position after printing matches | ||
stdout.write( clc.move.up( 2 + _printedMatches ) ) | ||
} | ||
@@ -781,7 +812,4 @@ | ||
stdout.write( clc.move.up( 2 + _printedMatches ) ) | ||
// if ( inputLabelHeight > 0 ) stdout.write( clc.move.up( inputLabelHeight ) ) | ||
// set cursor position to end of buffer | ||
// stdout.write( clc.move.right( 1 + buffer.length + 1 ) ) | ||
// reset cursor left position | ||
@@ -792,4 +820,6 @@ stdout.write( clc.move( -stdout.columns ) ) | ||
const cursorLeftPadding = stringWidth( lastInputLabel ) | ||
// set cursor left position | ||
stdout.write( clc.move.right( 2 + cursorOffset ) ) | ||
stdout.write( clc.move.right( cursorLeftPadding + cursorOffset ) ) | ||
} | ||
@@ -813,10 +843,5 @@ | ||
;( async function () { | ||
const opts = { | ||
mode: 'normal', | ||
list: require( '../test/youtube-search-results.json' ) | ||
} | ||
// const r = await queryUser( require( '../test/animals.json' ) ) | ||
const r = await queryUser( opts ) | ||
console.log( r.selected ) | ||
const r = await getInput( 'Name: ' ) | ||
console.log( r.query ) | ||
} )() | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
31879
744
152