Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support truecolor #756

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c7d6fe6
Refactor character attributes format
Tyriar Jul 4, 2017
879b1a4
Support truecolor
Tyriar Jul 4, 2017
8b52c85
Properly clear spans
Tyriar Jul 4, 2017
d392ff4
Correct back color erase
Tyriar Jul 4, 2017
ce793c6
Type char data
Tyriar Jul 4, 2017
9720d6f
Fix selection to work with new char format
Tyriar Jul 4, 2017
adf9985
Simplify the renderer
Tyriar Jul 4, 2017
cbf3828
Fix a bunch of tests
Tyriar Jul 4, 2017
98ac45e
Add more types to renderer
Tyriar Jul 4, 2017
645a386
Remove out of date doc
Tyriar Jul 7, 2017
59d7cd5
Merge remote-tracking branch 'ups/master' into 484_truecolor_2
Tyriar Jul 14, 2017
06ff1da
Initial working version of new memory optimizations
Tyriar Jul 15, 2017
64175cc
Merge remote-tracking branch 'ups/master' into 484_truecolor_2
Tyriar Jul 15, 2017
341a34d
Merge remote-tracking branch 'ups/master' into 484_truecolor_2
Tyriar Jul 16, 2017
6d4bcbe
Fix tests and lint
Tyriar Jul 16, 2017
10dcfc0
Move translate function to Buffer, fixes after merge
Tyriar Jul 16, 2017
80a4c32
Support trimming of charAttributes
Tyriar Jul 16, 2017
9bde18c
Pull charattribute creation and finalizing into Buffer
Tyriar Jul 16, 2017
cc315ea
Rename CharAttributes to TextStyle
Tyriar Jul 16, 2017
8377fb4
Merge remote-tracking branch 'ups/master' into 484_truecolor_2
Tyriar Jul 22, 2017
fbbd664
Fix build
Tyriar Jul 22, 2017
b94d8a2
Merge remote-tracking branch 'ups/master' into 484_truecolor_2
Tyriar Jul 30, 2017
999d00d
Merge remote-tracking branch 'origin/master' into 484_truecolor_2
Tyriar Aug 5, 2017
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
101 changes: 97 additions & 4 deletions src/Buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
* @license MIT
*/

import { ITerminal } from './Interfaces';
import { ITerminal, IBuffer } from './Interfaces';
import { CircularList } from './utils/CircularList';
import { LineData } from './Types';
import { TextStyle } from './TextStyle';

export const CHAR_DATA_CHAR_INDEX = 0;
export const CHAR_DATA_WIDTH_INDEX = 1;

/**
* This class represents a terminal buffer (an internal state of the terminal), where the
Expand All @@ -12,8 +17,13 @@ import { CircularList } from './utils/CircularList';
* - cursor position
* - scroll position
*/
export class Buffer {
public lines: CircularList<[number, string, number][]>;
export class Buffer implements IBuffer {
public lines: CircularList<LineData>;
public textStyles: TextStyle[];

private _currentTextStyle: TextStyle;
// linesIndexOffset usage should be encapsulated
private _linesIndexOffset: number;

public savedY: number;
public savedX: number;
Expand All @@ -36,7 +46,90 @@ export class Buffer {
public scrollTop: number = 0,
public tabs: any = {},
) {
this.lines = new CircularList<[number, string, number][]>(this.terminal.scrollback);
this.lines = new CircularList<LineData>(this.terminal.scrollback);
this.textStyles = [];
this._linesIndexOffset = 0;
this.scrollBottom = this.terminal.rows - 1;

// TODO: Listen to line's trim and adjust char attributes
this.lines.on('trim', (amount: number) => this._onTrim(amount));
}

/**
* Starts a new character attributes at the cursor.
*/
public startTextStyle(flags: number, fgColor: number, bgColor: number): void {
// TODO: Move current* variables into the buffer?
this._currentTextStyle = new TextStyle(this.x, this.ybase + this.y + this._linesIndexOffset, null, null, [flags, fgColor, bgColor]);
this.textStyles.push(this._currentTextStyle);
}

/**
* Finishes the current character attributes at the cursor. Do nothing if
* there is not a current character attributes.
*/
public finishTextStyle(): void {
if (!this._currentTextStyle) {
return;
}
this._currentTextStyle.x2 = this.x;
this._currentTextStyle.y2 = this._linesIndexOffset + this.ybase + this.y;
this._currentTextStyle = null;
}

private _onTrim(amount: number): void {
// Trim the top of charAttributes to ensure it never points at trimmed rows
this._linesIndexOffset += amount;
while (this.textStyles.length > 0 && this.textStyles[0].y1 < this._linesIndexOffset) {
this.textStyles.shift();
}
}

/**
* Translates a buffer line to a string, with optional start and end columns.
* Wide characters will count as two columns in the resulting string. This
* function is useful for getting the actual text underneath the raw selection
* position.
* @param line The line being translated.
* @param trimRight Whether to trim whitespace to the right.
* @param startCol The column to start at.
* @param endCol The column to end at.
*/
public translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol: number = 0, endCol: number = null): string {
// Get full line
let lineString = '';
let widthAdjustedStartCol = startCol;
let widthAdjustedEndCol = endCol;
const line = this.lines.get(lineIndex);
for (let i = 0; i < line.length; i++) {
const char = line[i];
lineString += char[CHAR_DATA_CHAR_INDEX];
// Adjust start and end cols for wide characters if they affect their
// column indexes
if (char[CHAR_DATA_WIDTH_INDEX] === 0) {
if (startCol >= i) {
widthAdjustedStartCol--;
}
if (endCol >= i) {
widthAdjustedEndCol--;
}
}
}

// Calculate the final end col by trimming whitespace on the right of the
// line if needed.
let finalEndCol = widthAdjustedEndCol || line.length;
if (trimRight) {
const rightWhitespaceIndex = lineString.search(/\s+$/);
if (rightWhitespaceIndex !== -1) {
finalEndCol = Math.min(finalEndCol, rightWhitespaceIndex);
}
// Return the empty string if only trimmed whitespace is selected
if (finalEndCol <= widthAdjustedStartCol) {
return '';
}
}

return lineString.substring(widthAdjustedStartCol, finalEndCol);
}
}
Loading