Comparing version 0.5.0 to 0.5.1
{ | ||
"name": "node-fzf", | ||
"version": "0.5.0", | ||
"version": "0.5.1", | ||
"description": "fzf ( junegunn/fzf ) inspired cli utility for node", | ||
@@ -5,0 +5,0 @@ "main": "src/main.js", |
194
src/main.js
@@ -71,2 +71,5 @@ // used to read keyboard input while at the same time | ||
// user defined vertical scrolling | ||
let scrollOffset = 0 | ||
_opts.update = function ( list ) { | ||
@@ -98,2 +101,4 @@ originalList = list | ||
stdout.removeListener( 'resize', handleResize ) | ||
stdin.removeListener( 'keypress', handleKeypress ) | ||
@@ -105,2 +110,5 @@ | ||
if ( !result ) { | ||
// quit, exit, cancel, abort | ||
buffer = undefined | ||
result = { | ||
@@ -150,2 +158,9 @@ selected: undefined, | ||
stdout.on( 'resize', handleResize ) | ||
function handleResize () { | ||
cleanDirtyScreen() | ||
render() | ||
} | ||
const debug = false | ||
@@ -282,2 +297,15 @@ | ||
// usually ALT key | ||
if ( key.meta ) { | ||
switch ( name ) { | ||
case 'n': // left arrow key | ||
scrollOffset-- | ||
return render() | ||
case 'p': // right arrow key | ||
scrollOffset++ | ||
return render() | ||
} | ||
} | ||
if ( key.ctrl ) return | ||
@@ -554,3 +582,4 @@ if ( key.meta ) return | ||
function colorIndexesOnText ( indexes, text, clcColor ) { | ||
function colorIndexesOnText ( indexes, text, clcColor ) | ||
{ | ||
const paintBucket = [] // characters to colorize at the end | ||
@@ -560,3 +589,3 @@ | ||
const index = indexes[ i ] | ||
paintBucket.push( { index: index, clc: clcFgMatchGreen || clcColor } ) | ||
paintBucket.push( { index: index, clc: clcColor || clcFgMatchGreen } ) | ||
} | ||
@@ -569,5 +598,39 @@ | ||
let len = stringWidth( t ) // use string-width to keep length in check | ||
const maxLen = getMaxWidth() // terminal width | ||
// colorise in reverse because invisible ANSI color | ||
// characters increases string length | ||
paintBucket.sort( function ( a, b ) { | ||
return b.index - a.index | ||
} ) | ||
for ( let i = 0; i < paintBucket.length; i++ ) { | ||
const paint = paintBucket[ i ] | ||
const index = Number( paint.index ) | ||
// skip fuzzy chars that have shifted out of view | ||
if ( index < 0 ) continue | ||
if ( index > t.length ) continue | ||
const c = paint.clc( t[ index ] ) | ||
t = t.slice( 0, index ) + c + t.slice( index + 1 ) | ||
} | ||
// return the colorized match text | ||
return t | ||
} | ||
function trimOnIndexes ( indexes, text ) | ||
{ | ||
let t = text | ||
indexes = ( | ||
indexes.map( function ( i ) { return Number( i ) } ) | ||
) | ||
indexes.sort() // sort indexes | ||
// the last ( right-most ) index/character we want to be | ||
// visible on screen as centered as possible until there are | ||
// no more text to be shown to the right of it | ||
const lastIndex = indexes[ indexes.length - 1 ] | ||
const maxLen = getMaxWidth() - 2 // terminal width + padding | ||
/* we want to show the user the last characters that matches | ||
@@ -580,60 +643,66 @@ * as those are the most relevant | ||
*/ | ||
const lastMatchIndex = indexes[ indexes.length - 1 ] | ||
const marginRight = Math.ceil( stdout.columns * 0.4 ) | ||
let matchMarginRight = ( lastMatchIndex + marginRight ) | ||
// how wide the last index would be printed currently | ||
const lastMatchLength = stringWidth( t.slice( 0, lastIndex ) ) | ||
// but don't shift too much | ||
if ( matchMarginRight > ( len + 8 ) ) matchMarginRight = ( len + 8 ) | ||
// how much to shift left to get last index to get into | ||
// marginRight range (almost center) | ||
let shiftLeft = ( marginRight - lastMatchLength ) | ||
const shiftRight = ( maxLen - matchMarginRight ) | ||
// [1] but not too much if there is no additional text | ||
// const delta = ( stringWidth( t ) - lastMatchLength ) | ||
// if ( Math.abs( shiftLeft ) > delta ) shiftLeft = -Math.floor( delta * .5 ) | ||
let startIndex = 0 | ||
let shiftAmount = 0 | ||
let startIndex = 0 | ||
let endIndex = len | ||
if ( shiftRight < 0 ) { | ||
// we need to shift so that the matched text and margin is in view | ||
shiftAmount = -shiftRight | ||
t = '...' + t.slice( shiftAmount ) | ||
if ( shiftLeft < 0 ) { | ||
// we need to shift left so that the matched text in view | ||
while ( shiftAmount > shiftLeft ) { | ||
startIndex++ | ||
shiftAmount = -stringWidth( t.slice( 0, startIndex ) ) | ||
if ( startIndex >= t.length ) { | ||
break // shouldn't happen because of [1] | ||
} | ||
} | ||
startIndex = 3 | ||
startIndex = startIndex + scrollOffset | ||
if ( startIndex < 0 ) { | ||
startIndex = 0 | ||
} | ||
t = t.slice( startIndex ) | ||
} | ||
// console.log( 't.length: ' + t.length ) | ||
// console.log( 'shiftLeft: ' + shiftLeft ) | ||
// console.log( 'shiftamount: ' + shiftAmount ) | ||
// console.log( 'startindex: ' + startIndex ) | ||
// normalize excessive lengths to avoid too much while looping | ||
// if ( t.length > ( maxLen * 2 + 20 ) ) t = t.slice( 0, maxLen * 2 + 20 ) | ||
/* Cut off from the end of the (visual) line until | ||
* it fits on the terminal width screen. | ||
*/ | ||
len = stringWidth( t ) | ||
if ( len > maxLen ) { | ||
let attempts = 0 | ||
while ( len > maxLen ) { | ||
t = t.slice( 0, maxLen - attempts++ ) | ||
const tlen = t.length | ||
let endIndex = t.length | ||
while ( stringWidth( t ) > maxLen ) { | ||
t = t.slice( 0, --endIndex ) | ||
if ( t.length <= 0 ) break | ||
} | ||
// re-calculate terminal/visual width | ||
len = stringWidth( t ) | ||
} | ||
t += '...' | ||
if ( startIndex > 0 ) { | ||
t = '...' + t | ||
} | ||
endIndex = len | ||
if ( endIndex < tlen ) { | ||
t = t + '...' | ||
} | ||
// colorise in reverse because invisible ANSI color | ||
// characters increases string length | ||
paintBucket.sort( function ( a, b ) { | ||
return b.index - a.index | ||
} ) | ||
for ( let i = 0; i < paintBucket.length; i++ ) { | ||
const paint = paintBucket[ i ] | ||
const index = paint.index - shiftAmount + startIndex | ||
// skip fuzzy chars that have shifted out of view | ||
if ( index < startIndex ) continue | ||
if ( index > endIndex ) continue | ||
const c = paint.clc( t[ index ] ) | ||
t = t.slice( 0, index ) + c + t.slice( index + 1 ) | ||
return { | ||
text: t, | ||
startOffset: startIndex ? ( startIndex - '...'.length ) : startIndex | ||
} | ||
// return the colorized match text | ||
return t | ||
} | ||
@@ -671,3 +740,3 @@ | ||
_matches = [] // reset matches | ||
const words = buffer.split( /\s+/ ) | ||
const words = buffer.split( /\s+/ ).filter( function ( word ) { return word.length > 0 } ) | ||
for ( let i = 0; i < words.length; i++ ) { | ||
@@ -685,2 +754,8 @@ const word = words[ i ] | ||
// special case no input ( show all with no matches ) | ||
if ( words.length === 0 ) { | ||
const matches = getList( _opts.mode, '', _list ) | ||
_matches = matches | ||
} | ||
if ( selectedIndex >= _matches.length ) { | ||
@@ -701,3 +776,9 @@ // max out at end of filtered/matched results | ||
if ( render.init ) stdout.write( clc.move.up( inputLabelHeight ) ) | ||
if ( render.init ) { | ||
stdout.write( clc.move.up( inputLabelHeight ) ) | ||
} else { | ||
// get rid of dirt when being pushed above MIN_HEIGHT | ||
// from the bottom of the terminal | ||
cleanDirtyScreen() | ||
} | ||
render.init = true | ||
@@ -728,4 +809,5 @@ | ||
const words = buffer.split( /\s+/ ) | ||
let indexMap = {} // as map to prevent duplicates indexes | ||
const words = buffer.split( /\s+/ ).filter( function ( word ) { return word.length > 0 } ) | ||
const indexMap = {} // as map to prevent duplicates indexes | ||
for ( let i = 0; i < words.length; i++ ) { | ||
@@ -739,4 +821,15 @@ const word = words[ i ] | ||
// trim and position text ( horizontally ) based on | ||
// last word/filter that matched ( most relevant ) | ||
const lastWord = words[ words.length - 1 ] || ' ' | ||
const lastIndexes = getMatches( _opts.mode, lastWord, match.text ) | ||
const { text, startOffset } = trimOnIndexes( lastIndexes, match.text ) | ||
match.text = text | ||
const indexes = Object.keys( indexMap ) | ||
if ( words.length === 0 ) continue | ||
const indexes = ( | ||
Object.keys( indexMap ) | ||
.map( function ( i ) { return Number( i ) - startOffset } ) | ||
) | ||
indexes.sort() // sort indexes | ||
@@ -762,2 +855,3 @@ | ||
stdout.write( suggestionColor( ' ctrl-s to switch' ) ) | ||
stdout.write( ' ' + clc.magenta( `[${ scrollOffset > 0 ? '+' : '' }${ scrollOffset }]` ) ) | ||
@@ -764,0 +858,0 @@ stdout.write( '\n' ) |
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
34845
821