Files
react-native/Libraries/LogBox/UI/AnsiHighlight.js
T
Christoph Nakazawa 03766d6a08 Remove unnecessary whitespace from code frames
Summary:
This removes common whitespace from a code frame to show more code. This is especially useful for heavily intended code that may not even be visible in the small window.

I am not 100% confident I wrote the right code because I'm under time pressure but it seems to work. I'm an intern and it's my last day.

Changelog: [Internal]

(Note: this ignores all push blocking failures!)

Reviewed By: rickhanlonii

Differential Revision: D18657572

fbshipit-source-id: 6b93999c4482891f2123d67005843ce5db0d2976
2019-11-22 09:09:10 -08:00

102 lines
3.1 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/
import {ansiToJson} from 'anser';
import {Text, View} from 'react-native';
import * as React from 'react';
import type {TextStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
// Afterglow theme from https://iterm2colorschemes.com/
const COLORS = {
'ansi-black': 'rgb(27, 27, 27)',
'ansi-red': 'rgb(187, 86, 83)',
'ansi-green': 'rgb(144, 157, 98)',
'ansi-yellow': 'rgb(234, 193, 121)',
'ansi-blue': 'rgb(125, 169, 199)',
'ansi-magenta': 'rgb(176, 101, 151)',
'ansi-cyan': 'rgb(140, 220, 216)',
// Instead of white, use the default color provided to the component
// 'ansi-white': 'rgb(216, 216, 216)',
'ansi-bright-black': 'rgb(98, 98, 98)',
'ansi-bright-red': 'rgb(187, 86, 83)',
'ansi-bright-green': 'rgb(144, 157, 98)',
'ansi-bright-yellow': 'rgb(234, 193, 121)',
'ansi-bright-blue': 'rgb(125, 169, 199)',
'ansi-bright-magenta': 'rgb(176, 101, 151)',
'ansi-bright-cyan': 'rgb(140, 220, 216)',
'ansi-bright-white': 'rgb(247, 247, 247)',
};
export default function Ansi({
text,
style,
}: {
text: string,
style: TextStyleProp,
}): React.Node {
let commonWhitespaceLength = Infinity;
const parsedLines = text.split(/\n/).map(line =>
ansiToJson(line, {
json: true,
remove_empty: true,
use_classes: true,
}),
);
parsedLines.map(lines => {
// The third item on each line includes the whitespace of the source code.
// We are looking for the least amount of common whitespace to trim all lines.
// Example: Array [" ", " 96 |", " text", ...]
const match = lines[2] && lines[2]?.content?.match(/^ +/);
const whitespaceLength = (match && match[0]?.length) || Infinity;
if (whitespaceLength < commonWhitespaceLength) {
commonWhitespaceLength = whitespaceLength;
}
});
const getText = (content, key) => {
if (key === 1) {
// Remove the vertical bar after line numbers
return content.replace(/\| $/, ' ');
} else if (key === 2 && commonWhitespaceLength < Infinity) {
// Remove common whitespace at the beginning of the line
return content.substr(commonWhitespaceLength);
} else {
return content;
}
};
return (
<View style={{flexDirection: 'column'}}>
{parsedLines.map((items, i) => (
<View style={{flexDirection: 'row'}} key={i}>
{items.map((bundle, key) => {
const textStyle =
bundle.fg && COLORS[bundle.fg]
? {
backgroundColor: bundle.bg && COLORS[bundle.bg],
color: bundle.fg && COLORS[bundle.fg],
}
: {
backgroundColor: bundle.bg && COLORS[bundle.bg],
};
return (
<Text style={[style, textStyle]} key={key}>
{getText(bundle.content, key)}
</Text>
);
})}
</View>
))}
</View>
);
}