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

colon notation for the parser #2241

Merged
merged 30 commits into from Jul 6, 2019
Merged

Conversation

jerch
Copy link
Member

@jerch jerch commented Jun 17, 2019

PR to get support for colon parameter notation in the parser. Should fix #2200.

Several things todo:

  • new Params type to hold params and subparams in a speedy manner
  • apply ':' to the transition table and extend parse loop accordingly
  • apply new Params type to parser API and inputhandler methods
  • fix SGR handling for sub params
  • parser tests for new colon sequences
  • integration tests for stacked SGR params/subparams
  • add COLORTERM=truecolor to env

@jerch jerch added the work-in-progress Do not merge label Jun 17, 2019
@jerch jerch self-assigned this Jun 17, 2019
@jerch
Copy link
Member Author

jerch commented Jun 17, 2019

@Tyriar:
The last commit introduces the new params type to the rest of the codebase. Due to the addCsiHandler this type gets pulled right up to xterm.d.ts - we need to find a solution for that (just c&p'ed the interface for now to resolve the conflicts).

@jerch jerch mentioned this pull request Jun 18, 2019
11 tasks
@jerch jerch removed the work-in-progress Do not merge label Jun 18, 2019
@jerch
Copy link
Member Author

jerch commented Jun 26, 2019

Some notes on the subparams implementation:

  • parser support
    So far there is only one known CSI sequence with subparams - SGR. Due to syntactical limitations of sequences where the last byte decides which final action has to be triggered there is no elegant way to limit the subparams handling to SGR only at parser level. Thus the parser applies the subparams logic to all escape sequences with digit params (all CSI, all DCS).
  • new Params type
    Any action handler that received params: number[] before now receives params: IParams. Compared to the old number array this new data type has several constraints:
    • all params and subparams are borrowed and only valid for the current handler invocation (clone the data if you need a persistant version)
    • params limits: int16_t, default: 0 (ZDM - zero default mode)
    • subparams limits: int16_t, default: -1
    • 32 slots for each params / subparams (configurable via ctor), >32 will be silently ignored
    • params can be accessed by .params[idx]
    • reading multiple params requires a .length check, reading beyond length - 1 might return arbitrary data
    • existence of .params[0] is guaranteed, sequences that only support one param can omit the length check
    • existence of subparams can be checked for every valid param index
  • SGR
    This PR implements the subparams handling for foreground and background colors in SGR in an xterm compatible fashion (allowing some mixed semicolon/colon notations additionally to both standards). Support for underline color (SGR 58) and style (SGR 4) is not implemented yet.

param = 1;
}
public cursorForward(params: IParams): void {
const param = params.params[0] || 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will let negative numbers though now unless IParams handles this, is that a concern? Math.max(params.params[0], 1)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, currently there is no way to set this to a negative value from a sequence. The parser currently applies zero default mode to params (as it always did), maybe just change the params typed array to uint16_t to be on the save side?

Copy link
Member Author

@jerch jerch Jul 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought again about this - imho it can keep it this way as long as we stick to ZDM. If we ever change this, we have to change default handling in all handlers anyway.

@Tyriar Tyriar added this to the 4.0.0 milestone Jun 29, 2019
demo/server.js Show resolved Hide resolved
src/Types.d.ts Outdated
/** CSI r */ setScrollRegion(params?: number[], collect?: string): void;
/** CSI s */ saveCursor(params?: number[]): void;
/** CSI u */ restoreCursor(params?: number[]): void;
/** CSI @ */ insertChars(params?: IParams): void;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checking if params still optional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eww good finding. Def. have to check all handler again, if they check for params before getting into business. Alternatively we could make params non optional for all handlers, but I am not sure if this would break on direct invocations here and there. So Id have to check this first.
Any preference whether to go with optional / non optional here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the question mark from params thus making it mandatory. They were not optional on Inputhandler anyway thus this chance is just getting the interface in line with the class.

* Get a JS array representation of the current parameters and sub parameters.
* The array is structured as follows:
* sequence: "1;2:3:4;5::6"
* array : [1, 2, [3, 4], 5, [-1, 6]]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:: => -1? Is that the default value for sub parameters?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kinda.

In the past I had a longer discussion with @egmontkob about ZDM (zero default mode) for params (vte does not do this for params either). We do currently to be in line with the parser from vt100.net, and I would not change that for params unless we run into troubles for a certain sequence.
For subparams there is no ZDM thingy, which means it might be anything. I took -1 a placeholder for default since negative values cannot be reached by normal sequence means. This way the final action can place its real default value whenever it sees -1.

@jerch
Copy link
Member Author

jerch commented Jul 2, 2019

Last changes:

  • allow greater values (int32 now), no need to stick to smallish int16
  • clamp max value to 0x7FFFFFFF (fixes possible negative overflow)
  • reject values below -1

@@ -499,7 +499,7 @@ declare module 'xterm' {
* The most recently-added handler is tried first.
* @return An IDisposable you can call to remove this handler.
*/
addCsiHandler(flag: string, callback: (params: number[], collect: string) => boolean): IDisposable;
addCsiHandler(flag: string, callback: (params: IParams, collect: string) => boolean): IDisposable;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should just use (number | number[])[] here to hide the complexity?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Note that the translation to (number | number[])[] by calling Params.toArray() is ~5 times slower than directly using the Param type. Imho not a problem, since most handlers will be not invoked often.

src/InputHandler.ts Show resolved Hide resolved
src/common/parser/EscapeSequenceParser.test.ts Outdated Show resolved Hide resolved
src/common/parser/EscapeSequenceParser.test.ts Outdated Show resolved Hide resolved
src/common/parser/EscapeSequenceParser.test.ts Outdated Show resolved Hide resolved
src/common/parser/EscapeSequenceParser.ts Show resolved Hide resolved
src/common/parser/EscapeSequenceParser.ts Outdated Show resolved Hide resolved
src/common/parser/Params.ts Outdated Show resolved Hide resolved
@jerch
Copy link
Member Author

jerch commented Jul 4, 2019

@Tyriar Further documented ZDM. If you feel uneasy about it (we are not in line with the latest specs here), we could lift that restriction. For this to work we only have to fix all action handlers in Inputhandler to do a proper check against the param default of -1.

Up to you, I currently see no need to switch.

Edit: Looking at the tests we have for any method in InputHandler I suggest not to change this until we have better test coverage (including edge cases from the escape sequence test files) to avoid regressions going unnoticed.

Copy link
Member

@Tyriar Tyriar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, great job!

@jerch jerch merged commit 68694da into xtermjs:master Jul 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

parser colon support
2 participants