* Xterm package, plus demo

This commit is contained in:
Michaël Van Canneyt 2021-12-24 13:43:15 +01:00
parent 4b07d2f9bb
commit 6f1f064d16
4 changed files with 662 additions and 0 deletions

25
demo/xterm/index.html Normal file
View File

@ -0,0 +1,25 @@
<!doctype html>
<html lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://unpkg.com/xterm@4.16.0/css/xterm.css" rel="stylesheet">
<script src="https://unpkg.com/xterm@4.16.0/lib/xterm.js"></script>
<title>XTerm demo</title>
<script src="xtermdemo.js"></script>
</head>
<body>
<div id="xterm" style="width: 100%; height: 80vh; background-color: black;">
</div>
<div>
<input type="text" id="edtInput">
<button id="btnSend">Send</button>
</div>
<script>
rtl.showUncaughtExceptions=true;
window.addEventListener("load", rtl.run);
</script>
</body>
</html>

91
demo/xterm/xtermdemo.lpi Normal file
View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<General>
<Flags>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
<Runnable Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="xtermdemo"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<CustomData Count="5">
<Item0 Name="MaintainHTML" Value="1"/>
<Item1 Name="PasJSHTMLFile" Value="project1.html"/>
<Item2 Name="PasJSPort" Value="0"/>
<Item3 Name="PasJSWebBrowserProject" Value="1"/>
<Item4 Name="RunAtReady" Value="1"/>
</CustomData>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<Units>
<Unit>
<Filename Value="xtermdemo.lpr"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="index.html"/>
<IsPartOfProject Value="True"/>
<CustomData Count="1">
<Item0 Name="PasJSIsProjectHTMLFile" Value="1"/>
</CustomData>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<Target FileExt=".js">
<Filename Value="xtermdemo"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="js"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<AllowLabel Value="False"/>
<CPPInline Value="False"/>
<UseAnsiStrings Value="False"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<TargetOS Value="browser"/>
</CodeGeneration>
<Linking>
<Debugging>
<GenerateDebugInfo Value="False"/>
<UseLineInfoUnit Value="False"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-Jeutf-8 -Jirtl.js -Jc -Jminclude"/>
<CompilerPath Value="$(pas2js)"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

86
demo/xterm/xtermdemo.lpr Normal file
View File

@ -0,0 +1,86 @@
program xtermdemo;
{$mode objfpc}
uses
browserapp, JS, Classes, SysUtils, Web, xterm;
type
{ TMyApplication }
TMyApplication = class(TBrowserApplication)
FTerminal : TXTerm.TTerminal;
FTermEl : TJSHTMLElement;
Finp : TJSHTMLInputElement;
FBtnSend : TJSHTMLButtonElement;
procedure doRun; override;
private
function DoData(data: String): Boolean;
function DoKey(key : TXTerm.TOnKeyCallbackDataType): Boolean;
function DoSendClick(aEvent: TJSMouseEvent): boolean;
end;
function TMyApplication.DoKey(key : TXTerm.TOnKeyCallbackDataType): Boolean;
Var
printable : Boolean;
begin
Result:=true;
With key do
printable :=Not (domEvent.altKey or domEvent.metaKey or domEvent.ctrlKey or domEvent.metaKey);
if key.domEvent.Key=TJSKeyNames.BackSpace then
FTerminal.write(#8' '#8)
else if key.domEvent.Key=TJSKeyNames.Enter then
FTerminal.writeln('')
else if Printable then
FTerminal.write(Key.Key)
end;
function TMyApplication.DoData(data: String): Boolean;
begin
Result:=True;
if Data=#8 then
begin
console.log('backspace detected');
FTerminal.Write(data+' '+data)
end
else
begin
console.log('OnData : ',Data, (length(data)));
FTerminal.Write(data)
end;
end;
procedure TMyApplication.doRun;
begin
FTermEl:=GetHTMLElement('xterm');
FInp:=TJSHTMLInputElement(GetHTMLElement('edtInput'));
FBtnSend:=TJSHTMLButtonElement(GetHTMLElement('btnSend'));
FBtnSend.OnClick:=@DoSendClick;
FTerminal:=TXTerm.TTerminal.New;
FTerminal.open(FTermEl);
// FTerminal.OnData(@DoData);
FTerminal.OnKey(@DoKey);
Terminate;
end;
function TMyApplication.DoSendClick(aEvent: TJSMouseEvent): boolean;
begin
FTerminal.Writeln(Finp.Value);
end;
var
Application : TMyApplication;
begin
Application:=TMyApplication.Create(nil);
Application.Initialize;
Application.Run;
end.

460
packages/xterm/xterm.pp Normal file
View File

@ -0,0 +1,460 @@
{
Xterm.js package, autogenerated from typescript description.
This is still incomplete (some event handlers need to be correctly typed)
}
Unit xterm;
{$MODE ObjFPC}
{$H+}
{$modeswitch externalclass}
interface
uses SysUtils, JS, Types, Web;
Type
// Forward class definitions
Txterm = Class;
// Modules
HTMLELement = TJSHTMLElement;
MouseEvent = TJSMouseEvent;
Txterm = class external name 'window' (TJSObject)
Public
Type
// Forward class definitions
TITerminalOptions = Class;
TITheme = Class;
TILinkMatcherOptions = Class;
TIDisposable = Class;
TIEvent = Class;
TIMarker = Class;
TILocalizableStrings = Class;
TIWindowOptions = Class;
TITerminalAddon = Class;
TISelectionPosition = Class;
TIViewportRange = Class;
TIViewportRangePosition = Class;
TILinkProvider = Class;
TILink = Class;
TILinkDecorations = Class;
TIBufferRange = Class;
TIBufferCellPosition = Class;
TIBuffer = Class;
TIBufferNamespace = Class;
TIBufferLine = Class;
TIBufferCell = Class;
TIFunctionIdentifier = Class;
TIParser = Class;
TIUnicodeVersionProvider = Class;
TIUnicodeHandling = Class;
TIModes = Class;
// Forward class definitions
TTerminal = Class;
TFontWeight = jsvalue; // number
TLogLevel = jsvalue; //
TRendererType = jsvalue; //
TattachCustomKeyEventHandler_customKeyEventHandler = reference to function (event: TJSKeyboardEvent): boolean;
TCallBack = reference to procedure;
TMarkersType = specialize TArray<TIMarker>;
TOnDataCallback = reference to function (data : String) : Boolean;
TOnRenderCallbackDataType = class external name 'Object' (TJSObject)
start : integer;
end_ : integer; external name 'end';
end;
TOnKeyCallbackDataType = class external name 'Object' (TJSObject)
key : string;
domEvent : TJSKeyBoardEvent;
end;
TOnResizeCallbackDataType = class external name 'Object' (TJSObject)
cols : integer;
rows : integer;
end;
TOnKeyCallback = reference to function(data : TOnKeyCallbackDataType) : Boolean;
TOnRenderCallBack = reference to function(data : TOnRenderCallBackDataType) : Boolean;
TOnResizeCallBack = reference to function(data : TOnResizeCallBackDataType) : Boolean;
TOnScrollCallBack = reference to function(data : double) : Boolean;
TTerminal = class external name 'Terminal' (TJSObject)
Private
Felement : jsvalue; external name 'element';
Ftextarea : jsvalue; external name 'textarea';
Frows : Double; external name 'rows';
Fcols : Double; external name 'cols';
Fbuffer : TIBufferNamespace; external name 'buffer';
Fmarkers : TMarkersType; external name 'markers';
Fparser : TIParser; external name 'parser';
Funicode : TIUnicodeHandling; external name 'unicode';
Fmodes : TIModes; external name 'modes';
Public
Function addMarker(cursorYOffset : Double): jsvalue;
Procedure attachCustomKeyEventHandler(customKeyEventHandler : TattachCustomKeyEventHandler_customKeyEventHandler);
Procedure blur;
Procedure clear;
Procedure clearSelection;
Procedure clearTextureAtlas;
constructor new(options : TITerminalOptions); overload;
constructor new; overload;
Procedure deregisterCharacterJoiner(joinerId : Double);
Procedure deregisterLinkMatcher(matcherId : Double);
Procedure dispose;
Procedure focus;
Function getOption(key : jsvalue): string; overload;
Function getOption(key : string): string; overload;
Function getSelection: string;
Function getSelectionPosition: jsvalue;
Function hasSelection: boolean;
Procedure loadAddon(addon : TITerminalAddon);
Procedure open(parent : HTMLElement);
Procedure paste(data : string);
Procedure refresh(start : Double; &end : Double);
// Function registerCharacterJoiner(handler : procedure): Double;
// Function registerLinkMatcher(regex : RegExp; handler : procedure; options : TILinkMatcherOptions): Double; overload;
// Function registerLinkMatcher(regex : RegExp; handler : procedure): Double; overload;
Function registerLinkProvider(linkProvider : TILinkProvider): TIDisposable;
Function registerMarker(cursorYOffset : Double): jsvalue;
Procedure reset;
Procedure resize(columns : Double; rows : Double);
Procedure scrollLines(amount : Double);
Procedure scrollPages(pageCount : Double);
Procedure scrollToBottom;
Procedure scrollToLine(line : Double);
Procedure scrollToTop;
Procedure select(column : Double; row : Double; &length : Double);
Procedure selectAll;
Procedure selectLines(start : Double; &end : Double);
Procedure setOption(key : jsvalue; value : string); overload;
Procedure setOption(key : jsvalue; value : jsvalue); overload;
Procedure setOption(key : String; value : TLogLevel); overload;
Procedure setOption(key : jsvalue; value : boolean); overload;
Procedure setOption(key : jsvalue; value : Double); overload;
Procedure setOption(key : String; value : TITheme); overload;
Procedure write(data : jsvalue; callback : TCallback); overload;
Procedure write(data : jsvalue); overload;
Procedure writeln(data : jsvalue; callback : TCallBack); overload;
Procedure writeln(data : jsvalue); overload;
Procedure writeUtf8(data : TJSUint8Array; callback : TCallback); overload;
Procedure writeUtf8(data : TJSUint8Array); overload;
Property element : jsvalue Read Felement;
Property textarea : jsvalue Read Ftextarea;
Property rows : Double Read Frows;
Property cols : Double Read Fcols;
Property buffer : TIBufferNamespace Read Fbuffer;
Property markers : TMarkersType Read Fmarkers;
Property parser : TIParser Read Fparser;
Property unicode : TIUnicodeHandling Read Funicode;
Property modes : TIModes Read Fmodes;
options : TITerminalOptions;
strings : TILocalizableStrings;
function onBell(listener: TCallBack) : TIDisposable;
function onBinary(listener : TOnDataCallBack) : TIDisposable;
Function onCursorMove(listener: TCallBack) : TIDisposable;
function onData (listener : TOnDataCallback) : TIDisposable;
function onKey(listener: TOnKeyCallback) : TIDisposable;
function onLineFeed (listener: TCallBack) : TIDisposable;
function onRender(listener : TOnRenderCallBack) : TIDisposable;
function onResize(listener : TOnResizeCallBack) : TIDisposable;
function onScroll(listener : TOnScrollCallBack) : TIDisposable;
function onSelectionChange(listener : TCallBack) : TIDisposable;
function onTitleChange(listener : TOnDataCallback) : TIDisposable;
end;
TITerminalOptions = class external name 'Object' (TJSObject)
allowProposedApi : boolean;
allowTransparency : boolean;
altClickMovesCursor : boolean;
bellSound : string;
bellStyle : jsvalue;
convertEol : boolean;
cols : Double;
cursorBlink : boolean;
cursorStyle : jsvalue;
cursorWidth : Double;
customGlyphs : boolean;
disableStdin : boolean;
drawBoldTextInBrightColors : boolean;
fastScrollModifier : jsvalue;
fastScrollSensitivity : Double;
fontSize : Double;
fontFamily : string;
fontWeight : TFontWeight;
fontWeightBold : TFontWeight;
letterSpacing : Double;
lineHeight : Double;
linkTooltipHoverDuration : Double;
logLevel : TLogLevel;
macOptionIsMeta : boolean;
macOptionClickForcesSelection : boolean;
minimumContrastRatio : Double;
rendererType : TRendererType;
rightClickSelectsWord : boolean;
rows : Double;
screenReaderMode : boolean;
scrollback : Double;
scrollSensitivity : Double;
tabStopWidth : Double;
theme : TITheme;
windowsMode : boolean;
wordSeparator : string;
windowOptions : TIWindowOptions;
end;
TITheme = class external name 'Object' (TJSObject)
foreground : string;
background : string;
cursor : string;
cursorAccent : string;
selection : string;
black : string;
red : string;
green : string;
yellow : string;
blue : string;
magenta : string;
cyan : string;
white : string;
brightBlack : string;
brightRed : string;
brightGreen : string;
brightYellow : string;
brightBlue : string;
brightMagenta : string;
brightCyan : string;
brightWhite : string;
end;
TILinkMatcherOptions = class external name 'Object' (TJSObject)
matchIndex : Double;
validationCallback : TCallBack;
tooltipCallback : TCallBack;
leaveCallback : TCallback;
priority : Double;
willLinkActivate : TCallBack;
end;
TIDisposable = class external name 'Object' (TJSObject)
Procedure dispose;
end;
TIEvent = class external name 'Object' (TJSObject)
constructor new(listener : TCallback);
end;
TIMarker = class external name 'Object' (TJSObject)
Fid : Double; external name 'id';
FisDisposed : boolean; external name 'isDisposed';
Fline : Double; external name 'line';
Property id : Double Read Fid;
Property isDisposed : boolean Read FisDisposed;
Property line : Double Read Fline;
onDispose : TIEvent;
end;
TILocalizableStrings = class external name 'Object' (TJSObject)
promptLabel : string;
tooMuchOutput : string;
end;
TIWindowOptions = class external name 'Object' (TJSObject)
restoreWin : boolean;
minimizeWin : boolean;
setWinPosition : boolean;
setWinSizePixels : boolean;
raiseWin : boolean;
lowerWin : boolean;
refreshWin : boolean;
setWinSizeChars : boolean;
maximizeWin : boolean;
fullscreenWin : boolean;
getWinState : boolean;
getWinPosition : boolean;
getWinSizePixels : boolean;
getScreenSizePixels : boolean;
getCellSizePixels : boolean;
getWinSizeChars : boolean;
getScreenSizeChars : boolean;
getIconTitle : boolean;
getWinTitle : boolean;
pushTitle : boolean;
popTitle : boolean;
setWinLines : boolean;
end;
TITerminalAddon = class external name 'Object' (TJSObject)
Procedure activate(terminal : TTerminal);
end;
TISelectionPosition = class external name 'Object' (TJSObject)
startColumn : Double;
startRow : Double;
endColumn : Double;
endRow : Double;
end;
TIViewportRange = class external name 'Object' (TJSObject)
start : TIViewportRangePosition;
&end : TIViewportRangePosition;external name 'end';
end;
TIViewportRangePosition = class external name 'Object' (TJSObject)
x : Double;
y : Double;
end;
TILinkProvider = class external name 'Object' (TJSObject)
Procedure provideLinks(bufferLineNumber : Double; callback : TCallback);
end;
TILink = class external name 'Object' (TJSObject)
Procedure activate(event : MouseEvent; text : string);
Procedure dispose;
Procedure hover(event : MouseEvent; text : string);
Procedure leave(event : MouseEvent; text : string);
range : TIBufferRange;
text : string;
decorations : TILinkDecorations;
end;
TILinkDecorations = class external name 'Object' (TJSObject)
pointerCursor : boolean;
underline : boolean;
end;
TIBufferRange = class external name 'Object' (TJSObject)
start : TIBufferCellPosition;
&end : TIBufferCellPosition;external name 'end';
end;
TIBufferCellPosition = class external name 'Object' (TJSObject)
x : Double;
y : Double;
end;
TIBuffer = class external name 'Object' (TJSObject)
Ftype : jsvalue; external name 'type';
FcursorY : Double; external name 'cursorY';
FcursorX : Double; external name 'cursorX';
FviewportY : Double; external name 'viewportY';
FbaseY : Double; external name 'baseY';
Flength : Double; external name 'length';
Function getLine(y : Double): jsvalue;
Function getNullCell: TIBufferCell;
Property &type : jsvalue Read Ftype;
Property cursorY : Double Read FcursorY;
Property cursorX : Double Read FcursorX;
Property viewportY : Double Read FviewportY;
Property baseY : Double Read FbaseY;
Property &length : Double Read Flength;
end;
TIBufferNamespace = class external name 'Object' (TJSObject)
Factive : TIBuffer; external name 'active';
Fnormal : TIBuffer; external name 'normal';
Falternate : TIBuffer; external name 'alternate';
Property active : TIBuffer Read Factive;
Property normal : TIBuffer Read Fnormal;
Property alternate : TIBuffer Read Falternate;
onBufferChange : TIEvent;
end;
TIBufferLine = class external name 'Object' (TJSObject)
FisWrapped : boolean; external name 'isWrapped';
Flength : Double; external name 'length';
Function getCell(x : Double; cell : TIBufferCell): jsvalue; overload;
Function getCell(x : Double): jsvalue; overload;
Function translateToString(trimRight : boolean; startColumn : Double; endColumn : Double): string; overload;
Function translateToString: string; overload;
Function translateToString(trimRight : boolean): string; overload;
Function translateToString(trimRight : boolean; startColumn : Double): string; overload;
Property isWrapped : boolean Read FisWrapped;
Property &length : Double Read Flength;
end;
TIBufferCell = class external name 'Object' (TJSObject)
Function getBgColor: Double;
Function getBgColorMode: Double;
Function getChars: string;
Function getCode: Double;
Function getFgColor: Double;
Function getFgColorMode: Double;
Function getWidth: Double;
Function isAttributeDefault: boolean;
Function isBgDefault: boolean;
Function isBgPalette: boolean;
Function isBgRGB: boolean;
Function isBlink: Double;
Function isBold: Double;
Function isDim: Double;
Function isFgDefault: boolean;
Function isFgPalette: boolean;
Function isFgRGB: boolean;
Function isInverse: Double;
Function isInvisible: Double;
Function isItalic: Double;
Function isStrikethrough: Double;
Function isUnderline: Double;
end;
TIFunctionIdentifier = class external name 'Object' (TJSObject)
prefix : string;
intermediates : string;
final : string;
end;
TIParser = class external name 'Object' (TJSObject)
Function registerCsiHandler(id : TIFunctionIdentifier; callback : TCallBack): TIDisposable;
Function registerDcsHandler(id : TIFunctionIdentifier; callback : TCallBack): TIDisposable;
Function registerEscHandler(id : TIFunctionIdentifier; handler : TCallBack): TIDisposable;
Function registerOscHandler(ident : Double; callback : TCallBack): TIDisposable;
end;
TIUnicodeVersionProvider = class external name 'Object' (TJSObject)
Fversion : string; external name 'version';
Function wcwidth(codepoint : Double): jsvalue;
Property version : string Read Fversion;
end;
TIUnicodeHandling = class external name 'Object' (TJSObject)
Fversions : TStringDynArray; external name 'versions';
Procedure register(provider : TIUnicodeVersionProvider);
Property versions : TStringDynArray Read Fversions;
activeVersion : string;
end;
TIModes = class external name 'Object' (TJSObject)
FapplicationCursorKeysMode : boolean; external name 'applicationCursorKeysMode';
FapplicationKeypadMode : boolean; external name 'applicationKeypadMode';
FbracketedPasteMode : boolean; external name 'bracketedPasteMode';
FinsertMode : boolean; external name 'insertMode';
FmouseTrackingMode : jsvalue; external name 'mouseTrackingMode';
ForiginMode : boolean; external name 'originMode';
FreverseWraparoundMode : boolean; external name 'reverseWraparoundMode';
FsendFocusMode : boolean; external name 'sendFocusMode';
FwraparoundMode : boolean; external name 'wraparoundMode';
Property applicationCursorKeysMode : boolean Read FapplicationCursorKeysMode;
Property applicationKeypadMode : boolean Read FapplicationKeypadMode;
Property bracketedPasteMode : boolean Read FbracketedPasteMode;
Property insertMode : boolean Read FinsertMode;
Property mouseTrackingMode : jsvalue Read FmouseTrackingMode;
Property originMode : boolean Read ForiginMode;
Property reverseWraparoundMode : boolean Read FreverseWraparoundMode;
Property sendFocusMode : boolean Read FsendFocusMode;
Property wraparoundMode : boolean Read FwraparoundMode;
end;
end;
implementation
end.