@@ -31,26 +31,19 @@ const {
3131} = require ( 'readline' ) ;
3232
3333const {
34- commonPrefix
34+ commonPrefix,
35+ getStringWidth,
3536} = require ( 'internal/readline/utils' ) ;
3637
3738const { inspect } = require ( 'util' ) ;
3839
3940const debug = require ( 'internal/util/debuglog' ) . debuglog ( 'repl' ) ;
4041
41- const inspectOptions = {
42- depth : 1 ,
42+ const previewOptions = {
4343 colors : false ,
44- compact : true ,
45- breakLength : Infinity
46- } ;
47- // Specify options that might change the output in a way that it's not a valid
48- // stringified object anymore.
49- const inspectedOptions = inspect ( inspectOptions , {
5044 depth : 1 ,
51- colors : false ,
5245 showHidden : false
53- } ) ;
46+ } ;
5447
5548// If the error is that we've unexpectedly ended the input,
5649// then let the user try to recover by adding more input.
@@ -254,7 +247,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
254247 }
255248 const { result } = preview ;
256249 if ( result . value !== undefined ) {
257- callback ( null , inspect ( result . value , inspectOptions ) ) ;
250+ callback ( null , inspect ( result . value , previewOptions ) ) ;
258251 // Ignore EvalErrors, SyntaxErrors and ReferenceErrors. It is not clear
259252 // where they came from and if they are recoverable or not. Other errors
260253 // may be inspected.
@@ -264,8 +257,19 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
264257 result . className === 'ReferenceError' ) ) {
265258 callback ( null , null ) ;
266259 } else if ( result . objectId ) {
260+ // The writer options might change and have influence on the inspect
261+ // output. The user might change e.g., `showProxy`, `getters` or
262+ // `showHidden`. Use `inspect` instead of `JSON.stringify` to keep
263+ // `Infinity` and similar intact.
264+ const inspectOptions = inspect ( {
265+ ...repl . writer . options ,
266+ colors : false ,
267+ depth : 1 ,
268+ compact : true ,
269+ breakLength : Infinity
270+ } , previewOptions ) ;
267271 session . post ( 'Runtime.callFunctionOn' , {
268- functionDeclaration : `(v) => util.inspect(v, ${ inspectedOptions } )` ,
272+ functionDeclaration : `(v) => util.inspect(v, ${ inspectOptions } )` ,
269273 objectId : result . objectId ,
270274 arguments : [ result ]
271275 } , ( error , preview ) => {
@@ -337,15 +341,33 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
337341 // Limit the output to maximum 250 characters. Otherwise it becomes a)
338342 // difficult to read and b) non terminal REPLs would visualize the whole
339343 // output.
340- const maxColumns = MathMin ( repl . columns , 250 ) ;
341-
342- if ( inspected . length > maxColumns ) {
343- inspected = `${ inspected . slice ( 0 , maxColumns - 6 ) } ...` ;
344+ let maxColumns = MathMin ( repl . columns , 250 ) ;
345+
346+ // Support unicode characters of width other than one by checking the
347+ // actual width.
348+ // TODO(BridgeAR): Add a test case to verify full-width characters work as
349+ // expected. Also test that the line break in case of deactivated colors
350+ // work as expected.
351+ if ( inspected . length * 2 >= maxColumns &&
352+ getStringWidth ( inspected ) > maxColumns ) {
353+ maxColumns -= 4 + ( repl . useColors ? 0 : 3 ) ;
354+ let res = '' ;
355+ for ( const char of inspected ) {
356+ maxColumns -= getStringWidth ( char ) ;
357+ if ( maxColumns < 0 )
358+ break ;
359+ res += char ;
360+ }
361+ inspected = `${ res } ...` ;
344362 }
363+
364+ // Line breaks are very rare and probably only occur in case of error
365+ // messages with line breaks.
345366 const lineBreakPos = inspected . indexOf ( '\n' ) ;
346367 if ( lineBreakPos !== - 1 ) {
347368 inspected = `${ inspected . slice ( 0 , lineBreakPos ) } ` ;
348369 }
370+
349371 const result = repl . useColors ?
350372 `\u001b[90m${ inspected } \u001b[39m` :
351373 `// ${ inspected } ` ;
0 commit comments