diff --git a/types/nextgen-events/index.d.ts b/types/nextgen-events/index.d.ts new file mode 100644 index 0000000000..dec25485d5 --- /dev/null +++ b/types/nextgen-events/index.d.ts @@ -0,0 +1,279 @@ +// Type definitions for nextgen-events 1.1 +// Project: https://github.com/cronvel/nextgen-events#readme +// Definitions by: katsanva +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.2 + +export = NextGenEvents; + +declare class NextGenEvents { + static readonly CONTEXT_ENABLED: 0; + static readonly CONTEXT_DISABLED: 1; + static readonly CONTEXT_QUEUED: 2; + + constructor(); + + addListener( + eventName: string, + fn?: any, + options?: NextGenEvents.AddListenerOptions + ): this; + on( + eventName: string, + fn?: any, + options?: NextGenEvents.AddListenerOptions + ): this; + once( + eventName: string, + fn?: any, + options?: NextGenEvents.AddListenerOptions + ): this; + waitFor(eventName: string): Promise; + waitForAll(eventName: string): Promise; + removeListener(eventName: string, id: any): this; + off(eventName: string, id: any): this; + removeAllListeners(eventName: string): this; + emit(nice: number, name: string, ...args: any[]): NextGenEvents.Event; + emit(name: string, ...args: any[]): NextGenEvents.Event; + waitForEmit(nice: number, name: string, ...args: any[]): Promise; + waitForEmit(name: string, ...args: any[]): Promise; + listeners(eventName: string): NextGenEvents.Func[]; + listenerCount(eventName: string): number; + setNice(nice: number): void; + desyncUseNextTick(useNextTick: boolean): void; + setInterruptible(isInterruptible: boolean): void; + getMaxListeners(): number; + setMaxListeners(n: number): this; + defineStates(...states: any[]): void; + hasState(state: string): boolean; + getAllStates(): NextGenEvents.States; + addListenerContext( + contextName: string, + options: NextGenEvents.ContextOptions + ): this; + disableListenerContext(contextName: string): this; + enableListenerContext(contextName: string): this; + queueListenerContext(contextName: string): this; + serializeListenerContext(contextName: string, value?: boolean): this; + setListenerContextNice(contextName: string, nice: number): this; + destroyListenerContext(contextName: string): this; + + static emitEvent(event: NextGenEvents.Event): NextGenEvents.Event; + static init(): void; + static initFrom(from: NextGenEvents): void; + static mergeListeners(foreigners: NextGenEvents.Listeners): void; + static filterOutCallback(what: any, currentElement: any): boolean; + static listenerWrapper( + listener: any, + event: any, + contextScope: string, + serial: any + ): void; + static emitToOneListener( + event: NextGenEvents.Event, + listener: any, + removedListeners: any + ): void; + static emitCallback(event: NextGenEvents.Event): void; + static listenerCount(emitter: NextGenEvents, eventName: string): number; + static share(source: NextGenEvents, target: NextGenEvents): void; + static reset(emitter: NextGenEvents): void; + static noop(...args: any[]): void; + static groupAddListener( + emitters: NextGenEvents[], + eventName: string, + fn?: NextGenEvents.Func, + options?: NextGenEvents.AddListenerOptions + ): any; + static groupOn( + emitters: NextGenEvents[], + eventName: string, + fn?: NextGenEvents.Func, + options?: NextGenEvents.AddListenerOptions + ): any; + static groupOnce( + emitters: NextGenEvents[], + eventName: string, + fn?: NextGenEvents.Func, + options?: NextGenEvents.AddListenerOptions + ): void; + static groupWaitFor( + emitters: NextGenEvents[], + eventName: string + ): Promise; + static groupWaitForAll( + emitters: NextGenEvents[], + eventName: string + ): Promise; + static groupOnceFirst( + emitters: NextGenEvents[], + eventName: string, + fn?: NextGenEvents.Func, + options?: NextGenEvents.AddListenerOptions + ): void; + static groupGlobalOnce( + emitters: NextGenEvents[], + eventName: string, + fn?: NextGenEvents.Func, + options?: NextGenEvents.AddListenerOptions + ): void; + static groupWaitForFirst( + emitters: NextGenEvents[], + eventName: string + ): Promise; + static groupWaitForFirstAll( + emitters: NextGenEvents[], + eventName: string + ): Promise; + static groupOnceLast( + emitters: NextGenEvents[], + eventName: string, + fn?: NextGenEvents.Func, + options?: NextGenEvents.AddListenerOptions + ): void; + static groupGlobalOnceAll( + emitters: NextGenEvents[], + eventName: string, + fn?: NextGenEvents.Func, + options?: NextGenEvents.AddListenerOptions + ): void; + static groupWaitForLast( + emitters: NextGenEvents[], + eventName: string + ): Promise; + static groupWaitForLastAll( + emitters: NextGenEvents[], + eventName: string + ): Promise; + static groupRemoveListener( + emitters: NextGenEvents[], + eventName: string, + id: number + ): void; + static groupRemoveAllListeners( + emitters: NextGenEvents[], + eventName: string + ): void; + static groupEmit( + emitters: NextGenEvents[], + nice?: number, + ...args: any[] + ): void; + static groupWaitForEmit( + emitters: NextGenEvents[], + nice?: number, + ...args: any[] + ): Promise; + static groupDefineStates(emitters: NextGenEvents[], ...args: any[]): void; + static getContextScope( + context: NextGenEvents.Context, + scopeName: string + ): NextGenEvents.Scope; + static processScopeQueue( + self: NextGenEvents, + contextScope: NextGenEvents.Scope, + serial: boolean, + isCompletionCallback: boolean + ): void; +} + +declare namespace NextGenEvents { + interface Event { + emitter: NextGenEvents; + interrupt: null; + sync: boolean; + mice: number; + name: string; + callback: (interrupt: any) => any; + args: any; + } + + type AddListenerOptions = + | boolean + | { + fn: any; + id?: any; + once: any; + async: any; + eventObject: any; + nice?: number; + context?: string; + }; + + const SYNC: number; + const DESYNC: number; + const defaultMaxListeners: number; + + type Func = (...args: any[]) => any; + + interface Listeners { + error: Func[]; + interrupt: Func[]; + newListener: Func[]; + removeListener: Func[]; + } + + interface States { + [key: string]: any; + } + + interface Context { + nice: typeof SYNC; + ready: boolean; + status: any; + serial: boolean; + scopes: { [key: string]: any }; + } + + interface Scope { + ready: boolean; + queue: any[]; + } + + interface ContextOptions { + nice?: typeof SYNC; + ready: boolean; + status?: any; + serial?: any; + scopes: { + [key: string]: Scope; + }; + } + + class Internal { + nice: typeof SYNC; + interruptible: boolean; + contexts: { + [key: string]: Context; + }; + desync: (fn: (...args: any[]) => void, ...args: any[]) => void; + depth: number; + states: States; + stateGroups: { [key: string]: any }; + listeners: Listeners; + maxListeners: typeof defaultMaxListeners; + + constructor(from?: NextGenEvents); + } + + class Proxy { + receive: (raw: any) => void; + send: (message: any) => void; + + remoteServices: { + [key: string]: NextGenEvents; + }; + + addLocalService( + name: string, + heartBeatEmitter: any, + options: { listen: boolean; emit: boolean; ack: boolean } + ): void; + + addRemoteService(name: string): void; + + push(data: any): void; + + destroy(): any; + } +} diff --git a/types/nextgen-events/nextgen-events-tests.ts b/types/nextgen-events/nextgen-events-tests.ts new file mode 100644 index 0000000000..fda0373b0b --- /dev/null +++ b/types/nextgen-events/nextgen-events-tests.ts @@ -0,0 +1,251 @@ +import * as NgEmitter from 'nextgen-events'; +import * as WebSocket from 'ws'; +const emitter = new NgEmitter(); + +// Normal listener +emitter.on('message', (message: any) => {}); + +// One time listener: +emitter.once('close', () => {}); + +// The error listener: if it is not defined, the error event will throw an exception +emitter.on('error', (error: any) => {}); + +emitter.emit('message', 'Hello world!'); +// ... + +emitter.on('connection', { + context: 'ctx', + fn: (stream: any) => {}, +}); + +emitter.on('close', { + context: 'ctx', + fn: () => { + // Destroy the context and all listeners tied to it: + emitter.destroyListenerContext('ctx'); + }, +}); + +emitter.on('erroHr', { + context: 'ctx', + fn: () => { + // some error handling code + + // Destroy the context and all listeners tied to it: + emitter.destroyListenerContext('ctx'); + }, +}); + +emitter.once('connection', (stream: any) => {}); + +emitter.on('connection', { + fn: (stream: any) => {}, + once: true, +}); + +async () => { + const remote = await emitter.waitFor('connect'); + + emitter.defineStates('connect'); + emitter.emit('connect', remote); + + // ... somewhere else or in another file... +}; + +// Now we are sure that we are ready! +// We can connect to the DB or whatever your emitter is for... + +const callback1 = (stream: any) => {}; + +emitter.on('connection', callback1); +// ... +emitter.removeListener('connection', callback1); + +const callback2 = (stream: any) => {}; + +emitter.on('connection', { id: 'foo', fn: callback2 }); +emitter.on('connection', { id: 'bar', fn: callback2 }); + +// ... + +// Does nothing! we have used custom IDs! +emitter.removeListener('connection', callback2); + +// Remove the first listener only, despite the fact they are sharing the same function +emitter.removeListener('connection', 'foo'); + +emitter.on('connection', (stream: any) => {}); + +// output: +// [ { id: [Function], fn: [Function], nice: -Infinity, event: 'connection' } ] + +emitter.defineStates('ready'); +emitter.emit('ready'); + +// ... later... ... ... + +emitter.once('ready', () => { + // Your listener code fire immediately +}); + +emitter.on('foo', () => { + return new Error('Dang!'); +}); + +emitter.on('foo', () => { + // Never ever called... +}); + +emitter.on('interrupt', (interruption: any) => { + // interruption is eql to Error( 'Dang!' ) +}); + +emitter.emit('foo', (interruption: any) => { + // interruption is eql to Error( 'Dang!' ) +}); + +const performSomeCriticalAsyncStuff = (f: any) => + (async () => { + return f(); + })(); + +emitter.on('maintenance', { + context: 'maintenanceHandlers', + async: true, + fn: (type: any, done: any) => { + performSomeCriticalAsyncStuff(() => { + done(); + }); + }, +}); +const maintenanceHandlers = 'foo'; +emitter.serializeListenerContext(maintenanceHandlers); + +// ... + +emitter.emit('maintenance', 'doBackup'); + +// Despite the fact we emit synchronously, the listener will not be called now, +// it will be queued and called later when the previous call will be finished +emitter.emit('maintenance', 'doUpgrade'); + +const performBackup = (fn: any) => {}; +const performUpgrade = (fn: any) => {}; + +emitter.on('doBackup', { + context: 'maintenanceHandlers', + async: true, + fn: (done: any) => { + performBackup(() => { + done(); + }); + }, +}); + +emitter.on('doUpgrade', { + context: 'maintenanceHandlers', + async: true, + fn: (done: any) => { + performUpgrade(() => { + done(); + }); + }, +}); + +emitter.on('whatever', () => { + // Some actions... +}); + +emitter.serializeListenerContext(maintenanceHandlers); + +// ... + +emitter.emit('doBackup'); + +// Despite the fact we emit synchronously, the second listener will not be called now, +// it will be queued and called later when the first listener will have finished its job +emitter.emit('doUpgrade'); + +// The third listener is not part of the 'maintenanceHandlers' context, so it will be called +// right now, before the first listener finished, and before the second listener ever start +emitter.emit('whatever'); + +// Create our service/emitter +const heartBeatEmitter = new NgEmitter(); + +// Create our server +const server = new WebSocket.Server({ port: 12345 }); + +// On new connection... +emitter.on('connection', function connection(ws: any) { + // Create a proxy for this client + const proxy = new NgEmitter.Proxy(); + + // Add the local service exposed to this client and grant it all right + proxy.addLocalService('heartBeatService', heartBeatEmitter, { + listen: true, + emit: true, + ack: true, + }); + + // message received: just hook to proxy.receive() + ws.on('message', function incoming(message: any) { + proxy.receive(message); + }); + + // Define the receive method: should call proxy.push() + // after decoding the raw message + proxy.receive = function receive(raw: any) { + try { + proxy.push(JSON.parse(raw)); + } catch (error) {} + }; + + // Define the send method + proxy.send = function send(message: any) { + ws.send(JSON.stringify(message)); + }; + + // Clean up after everything is done + ws.on('close', function close() { + proxy.destroy(); + }); +}); + +const ws = new WebSocket('ws://127.0.0.1:12345'); + +// Create a proxy +const proxy = new NgEmitter.Proxy(); + +// Once the connection is established... +ws.on('open', function open() { + // Add the remote service we want to access + proxy.addRemoteService('heartBeatService'); + + // Listen to the event 'heartBeat' on this service + proxy.remoteServices.heartBeatService.on('heartBeat', (beat: any) => {}); +}); + +// message received: just hook to proxy.receive() +ws.on('message', (message: any) => { + proxy.receive(message); +}); + +// Define the receive method: should call proxy.push() +// after decoding the raw message +proxy.receive = function receive(raw: any) { + try { + proxy.push(JSON.parse(raw)); + } catch (error) {} +}; + +// Define the send method +proxy.send = function send(message: any) { + ws.send(JSON.stringify(message)); +}; + +// Clean up after everything is done +ws.on('close', function close() { + proxy.destroy(); +}); diff --git a/types/nextgen-events/tsconfig.json b/types/nextgen-events/tsconfig.json new file mode 100644 index 0000000000..0af4647354 --- /dev/null +++ b/types/nextgen-events/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": ["es6"], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": ["../"], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "strictFunctionTypes": false + }, + "files": ["index.d.ts", "nextgen-events-tests.ts"] +} diff --git a/types/nextgen-events/tslint.json b/types/nextgen-events/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/nextgen-events/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/terminal-kit/Rect.d.ts b/types/terminal-kit/Rect.d.ts new file mode 100644 index 0000000000..c1a41f6056 --- /dev/null +++ b/types/terminal-kit/Rect.d.ts @@ -0,0 +1,61 @@ +import Terminal = require("./Terminal"); +import ScreenBuffer = require("./ScreenBuffer"); +import TextBuffer = require("./TextBuffer"); + +declare class Rect { + readonly width: number; + readonly height: number; + readonly xmin: number; + readonly ymin: number; + readonly xmax: number; + readonly ymax: number; + readonly isNull: boolean; + + constructor( + options: + | Rect.AbsoluteOptions + | Rect.Region + | Rect + | Terminal + | ScreenBuffer + | TextBuffer + ); + constructor(xmin: number, xmax: number, ymin: number, ymax: number); + + static wrappingRect(params: { + srcRect: Rect; + dstRect: Rect; + offsetX: number; + offsetY: number; + wrapOnly?: "x" | "y"; + }): void; + + set(obj: Rect.Region): void; + + clip( + dstRect: Rect, + offsetX: number, + offsetY: number, + dstClipping: boolean + ): void; +} + +export = Rect; + +declare namespace Rect { + type Options = AbsoluteOptions | Region; + + interface AbsoluteOptions { + width: number; + height: number; + x?: number; + y?: number; + } + + interface Region { + xmin: number; + ymin: number; + xmax: number; + ymax: number; + } +} diff --git a/types/terminal-kit/ScreenBuffer.d.ts b/types/terminal-kit/ScreenBuffer.d.ts new file mode 100644 index 0000000000..45df94b729 --- /dev/null +++ b/types/terminal-kit/ScreenBuffer.d.ts @@ -0,0 +1,139 @@ +import NextGenEvents = require("nextgen-events"); + +import Terminal = require("./Terminal"); +import ScreenBufferHD = require("./ScreenBufferHD"); +import Rect = require("./Rect"); + +declare class ScreenBuffer extends NextGenEvents { + readonly dst: Terminal | ScreenBuffer; + readonly x: number; + readonly y: number; + readonly blending: boolean | ScreenBufferHD.IsBlending; + + constructor(options: ScreenBuffer.Options); + + static create(options: ScreenBuffer.Options): ScreenBuffer; + + static createFromString( + options: { + attr: number | ScreenBuffer.Attributes; + transparencyChar: string; + transparencyType: number; + }, + str: string + ): ScreenBuffer; + + static loadImage( + url: string, + options: { + terminal: Terminal; + shrink?: { + width: number; + height: number; + }; + }, + calback: (error: any, image: ScreenBufferHD) => void + ): void; + + static loadImage( + url: string, + calback: (error?: any, image?: ScreenBufferHD) => void + ): void; + + static attr2object(attrFlags: number): void; + attr2object(attrFlags: number): void; + + static object2attr(attrObject: ScreenBuffer.Attributes): void; + object2attr(attrObject: ScreenBuffer.Attributes): void; + + static loadSync(filepath: string): ScreenBuffer; + + fill(options?: { + attr: ScreenBuffer.Attributes | number; + char?: string; + }): void; + + clear(): void; + + put( + options: ScreenBuffer.PutOptions, + format: string, + ...formatArgumets: any[] + ): void; + + get(options?: { + x: number; + y: number; + }): { char: string; attr: ScreenBuffer.Attributes }; + + resize(fromRect: Rect | Rect.Options): void; + + draw(options?: ScreenBuffer.DrawOptions): void; + + drawCursor(options?: { dst: Terminal | ScreenBuffer }): void; + + moveTo(x: number, y: number): void; + + vScroll(offset: number, drawToTerminal: boolean): void; + + dumpChars(): string; + + saveSync(filepath: string): void; +} + +export = ScreenBuffer; + +declare namespace ScreenBuffer { + interface Options { + width?: number; + height?: number; + dst: Terminal | ScreenBuffer; + x?: number; + y?: number; + blending?: boolean; + wrap?: boolean; + noFill?: boolean; + } + + interface DrawOptions { + dst?: Terminal | ScreenBuffer; + x?: number; + y?: number; + srcClipRect?: Rect; + dstClipRect?: Rect; + blending?: boolean; + delta?: boolean; + wrap?: boolean | "x" | "y"; + tile?: boolean; + } + + interface Attributes { + color?: number; + defaultColor?: boolean; + bgColor?: number; + bgDefaultColor?: boolean; + bold?: boolean; + dim?: boolean; + italic?: boolean; + underline?: boolean; + blink?: boolean; + inverse?: boolean; + hidden?: boolean; + strike?: boolean; + transparency?: boolean; + fgTransparency?: boolean; + bgTransparency?: boolean; + styleTransparency?: boolean; + charTransparency?: boolean; + } + + interface PutOptions { + x: number; + y: number; + attr: Attributes | number; + wrap: boolean; + direction?: "right" | "left" | "up" | "down" | null; + dx: number; + dy: number; + } +} diff --git a/types/terminal-kit/ScreenBufferHD.d.ts b/types/terminal-kit/ScreenBufferHD.d.ts new file mode 100644 index 0000000000..76a9571cda --- /dev/null +++ b/types/terminal-kit/ScreenBufferHD.d.ts @@ -0,0 +1,83 @@ +import ScreenBuffer = require("./ScreenBuffer"); + +declare class ScreenBufferHD extends ScreenBuffer { + constructor( + options: { blending: ScreenBufferHD.IsBlending } | ScreenBuffer.Options + ); + + readonly blending: ScreenBufferHD.IsBlending; + + static loadImage( + url: string, + calback: (error?: any, image?: ScreenBufferHD) => void + ): void; + + static loadImage( + url: string, + options: { shrink?: { height: number; width: number } }, + callback: (error: any, image: ScreenBufferHD) => void + ): void; + + draw( + options?: ScreenBuffer.DrawOptions | { blending: ScreenBufferHD.IsBlending } + ): void; + + fill( + options?: + | { + attr: ScreenBuffer.Attributes | number; + char?: string; + } + | { + attr: ScreenBufferHD.Attributes | number; + char?: string; + } + ): void; +} + +export = ScreenBufferHD; + +declare namespace ScreenBufferHD { + interface Attributes { + r: number; + g: number; + b: number; + a?: number; + defaultColor?: boolean; + bgR: number; + bgG: number; + bgB: number; + bgA?: number; + bgDefaultColor?: boolean; + bold?: boolean; + dim?: boolean; + italic?: boolean; + underline?: boolean; + blink?: boolean; + inverse?: boolean; + hidden?: boolean; + strike?: boolean; + transparency?: boolean; + styleTransparency?: boolean; + charTransparency?: boolean; + } + + type IsBlending = false | Blending; + + interface Blending { + fn: BlendFunction; + opacity: number; + blendSrcFgWithDstBg: boolean; + } + + type BlendFunction = (src: number, dst: number) => number; + + interface BlendFn { + normal: BlendFunction; + multiply: BlendFunction; + screen: BlendFunction; + overlay: BlendFunction; + hardLight: BlendFunction; + softLight: BlendFunction; + } +} diff --git a/types/terminal-kit/Terminal.d.ts b/types/terminal-kit/Terminal.d.ts new file mode 100644 index 0000000000..21434c1a5c --- /dev/null +++ b/types/terminal-kit/Terminal.d.ts @@ -0,0 +1,545 @@ +import EventEmitter = require("nextgen-events"); + +type Terminal = Terminal.Impl & EventEmitter; + +export = Terminal; + +type Callback = ((err: any) => void) | ((err: undefined, arg: T) => void); + +declare namespace Terminal { + interface Impl { + width: number; + height: number; + appName: string; + app: string; + generic: string; + termconfigFile: string; + + (str?: string): Terminal; + (...args: any[]): Terminal; + + defaultColor: CTerminal; + black: CTerminal; + red: CTerminal; + green: CTerminal; + yellow: CTerminal; + blue: CTerminal; + magenta: CTerminal; + cyan: CTerminal; + white: CTerminal; + brightBlack: CTerminal; + gray: CTerminal; + grey: CTerminal; + brightRed: CTerminal; + brightGreen: CTerminal; + brightYellow: CTerminal; + brightBlue: CTerminal; + brightMagenta: CTerminal; + brightCyan: CTerminal; + brightWhite: CTerminal; + color: (register: number) => Terminal; + darkColor: (register: number) => Terminal; + brightColor: (register: number) => Terminal; + color256: (register: number) => Terminal; + colorRgb: (r: number, g: number, b: number) => Terminal; + colorRgbHex: (rgb: string) => Terminal; + colorGrayscale: (I: number) => Terminal; + + bgDefaultColor: CTerminal; + bgBlack: CTerminal; + bgRed: CTerminal; + bgGreen: CTerminal; + bgYellow: CTerminal; + bgBlue: CTerminal; + bgMagenta: CTerminal; + bgCyan: CTerminal; + bgWhite: CTerminal; + bgBrightBlack: CTerminal; + bgGray: CTerminal; + bgGrey: CTerminal; + bgBrightRed: CTerminal; + bgBrightGreen: CTerminal; + bgBrightYellow: CTerminal; + bgBrightBlue: CTerminal; + bgBrightMagenta: CTerminal; + bgBrightCyan: CTerminal; + bgBrightWhite: CTerminal; + bgColor: (register: number) => Terminal; + bgDarkColor: (register: number) => Terminal; + bgBrightColor: (register: number) => Terminal; + bgColor256: (register: number) => Terminal; + bgColorRgb: (r: number, g: number, b: number) => Terminal; + bgColorRgbHex: (rgb: string) => Terminal; + bgColorGrayscale: (I: number) => Terminal; + + styleReset: CTerminal; + bold: CTerminal; + dim: CTerminal; + italic: CTerminal; + underline: CTerminal; + blink: CTerminal; + inverse: CTerminal; + hidden: CTerminal; + strike: CTerminal; + + saveCursor: Terminal; + restoreCursor: Terminal; + up: ((n: number) => Terminal) | ((n: number, ...args: any[]) => Terminal); + down: (n: number) => Terminal; + right: (n: number) => Terminal; + left: (n: number) => Terminal; + nextLine: (n: number) => Terminal; + previousLine: (n: number) => Terminal; + column: (x: number) => Terminal; + scrollUp: (n: number) => Terminal; + scrollDown: (n: number) => Terminal; + scrollingRegion: (top: number, bottom: number) => Terminal; + resetScrollingRegion: Terminal; + moveTo: CTerminal; + move: (x: number, y: number) => Terminal; + hideCursor: Terminal; + tabSet: Terminal; + tabClear: Terminal; + tabClearAll: Terminal; + forwardTab: (n: number) => Terminal; + backwardTab: (n: number) => Terminal; + + clear: Terminal; + eraseDisplayBelow: Terminal; + eraseDisplayAbove: Terminal; + eraseDisplay: Terminal; + eraseScrollback: Terminal; + eraseLineAfter: Terminal; + eraseLineBefore: Terminal; + eraseLine: Terminal; + eraseArea: ( + x: number, + y: number, + width?: number, + height?: number + ) => Terminal; + insertLine: (n: number) => Terminal; + deleteLine: (n: number) => Terminal; + insert: (n: number) => Terminal; + delete: (n: number) => Terminal; + backDelete: Terminal; + alternateScreenBuffer: Terminal; + + requestCursorLocation: Terminal; + requestScreenSize: Terminal; + requestColor: (n: number) => Terminal; + applicationKeypad: Terminal; + + mouseButton: Terminal; + mouseDrag: Terminal; + mouseMotion: Terminal; + mouseSGR: Terminal; + focusEvent: Terminal; + cwd: (uri: string) => Terminal; + windowTitle: (str: string) => Terminal; + iconName: (str: string) => Terminal; + notify: (title: string, text: string) => Terminal; + + error: Terminal; + str: Terminal; + noFormat: (str: string) => Terminal; + markupOnly: (str: string) => Terminal; + wrap: CTerminal; + bindArgs: (...args: any[]) => Terminal; + + reset: Terminal; + bell: Terminal; + setCursorColor: (register: number) => Terminal; + setCursorColorRgb: (r: number, g: number, b: number) => Terminal; + resetCursorColorRgb: Terminal; + setDefaultColorRgb: (r: number, g: number, b: number) => Terminal; + resetDefaultColorRgb: Terminal; + setDefaultBgColorRgb: (r: number, g: number, b: number) => Terminal; + resetDefaultBgColorRgb: Terminal; + setHighlightBgColorRgb: (r: number, g: number, b: number) => Terminal; + resetHighlightBgColorRgb: Terminal; + + fullscreen: (options: boolean | { noAlternate: boolean }) => void; + processExit: (code: number) => void; + grabInput( + options: + | boolean + | { + mouse?: "button" | "drag" | "motion"; + safe?: boolean; + }, + safeCallback?: boolean + ): void; + + getCursorLocation: ( + callback: (error: any, x?: number, y?: number) => void + ) => void; + getColor( + register: number, + callback?: Callback<{ r: number; g: number; b: number }> + ): void; + setColor( + register: number, + r: number, + g: number, + b: number, + names?: ReadonlyArray + ): void; + setColor( + register: number, + rgb: { r: number; g: number; b: number }, + names?: ReadonlyArray + ): void; + getPalette(register: number, callback?: Callback): void; + setPalette(palette: string | Palette): void; + + wrapColumn(options?: { + width: null | number; + x: number; + continue?: boolean; + offset?: number; + }): void; + wrapColumn(x: undefined | number, width: number): void; + + yesOrNo(options: YesOrNoOptions, callback: Callback): void; + + yesOrNo( + options?: YesOrNoOptions + ): { + abort: () => void; + promise?: Promise; + }; + + inputField(options: InputFieldOptions, callback: Callback): void; + inputField(callback: Callback): void; + inputField( + options?: InputFieldOptions + ): { + abort: () => void; + promise?: Promise; + }; + + fileInput(options: IFileInputOptions, callback: Callback): void; + fileInput(options?: IFileInputOptions): Promise; + + singleLineMenu( + menuItems: ReadonlyArray, + options: SingleLineMenuOptions, + callback: Callback + ): void; + + singleLineMenu( + menuItems: ReadonlyArray, + callback: Callback + ): void; + + singleLineMenu( + menuItems: ReadonlyArray, + options?: SingleLineMenuOptions + ): { + promise: Promise; + }; + + singleRowMenu( + menuItems: ReadonlyArray, + options: SingleLineMenuOptions, + callback: Callback + ): void; + + singleRowMenu( + menuItems: ReadonlyArray, + callback: Callback + ): void; + + singleRowMenu( + menuItems: ReadonlyArray, + options?: SingleLineMenuOptions + ): { + promise: Promise; + }; + + singleColumnMenu( + menuItems: ReadonlyArray, + options: SingleColumnMenuOptions, + callback: Callback + ): void; + + singleColumnMenu( + menuItems: ReadonlyArray, + callback: Callback + ): void; + + singleColumnMenu( + menuItems: ReadonlyArray, + options?: SingleColumnMenuOptions + ): { + promise: Promise; + }; + + gridMenu( + menuItems: ReadonlyArray, + options: GridMenuOptions, + callback: Callback + ): void; + + gridMenu( + menuItems: ReadonlyArray, + callback: Callback + ): void; + + gridMenu( + menuItems: ReadonlyArray, + options?: GridMenuOptions + ): { + promise: Promise; + }; + + progressBar(options?: ProgressBarOptions): ProgressBarController; + + bar( + value: number, + options?: { innerSize?: number; barStyle?: CTerminal } + ): void; + + slowTyping( + str: string, + options: { + style?: CTerminal; + flashStyle?: CTerminal; + delay?: number; + flashDelay?: number; + }, + callback: Callback + ): void; + slowTyping(str: string, callback: Callback): void; + + slowTyping( + str: string, + options?: { + style?: CTerminal; + flashStyle?: CTerminal; + delay?: number; + flashDelay?: number; + } + ): Promise; + + drawImage( + url: string, + options: { + shrink?: { + width: number; + height: number; + }; + }, + callback: Callback + ): void; + + drawImage(url: string, callback: Callback): void; + + drawImage( + url: string, + options?: { + shrink?: { + width: number; + height: number; + }; + } + ): Promise; + } + + interface ChainableInterface { + (str: string, ...args: any[]): T; + (...args: any[]): T; + } + + type Chainable = T & ChainableInterface; + + type CTerminal = Terminal & ((...args: any[]) => Terminal); + + type Palette = Array<{ + r: number; + g: number; + b: number; + names: ReadonlyArray; + }>; + + interface YesOrNoOptions { + yes: string | ReadonlyArray; + no: string | ReadonlyArray; + echoYes?: string; + echoNo?: string; + } + + type Autocompletion = + | (( + inputString: string, + callback: Callback> + ) => void) + | ((inputString: string) => Promise>); + + interface CreateOptions { + stdin?: NodeJS.Process; + stdout?: NodeJS.Process; + stderr?: NodeJS.Process; + generic?: string; + appId: string; + appName: string; + isTTY?: boolean; + isSSH?: boolean; + pid?: any; + preferProcessSigwinch?: boolean; + processSigwinch?: boolean; + } + + class AutocompletionArray extends Array { + prefix?: string; + postfix?: string; + } + + interface HookConfig { + style?: CTerminal; + hintStyle?: CTerminal; + tokenRegExp?: RegExp; + autoComplete?: string[] | Autocompletion; + autoCompleteMenu?: boolean | Autocompletion; + autoCompleteHint?: boolean; + } + + interface InputFieldOptions { + echo?: boolean; + echoChar?: string | true; + default?: string; + cursorPosition?: number; + cancelable?: boolean; + style?: CTerminal; + hintStyle?: CTerminal; + maxLength?: number; + minLength?: number; + history?: string[]; + autoComplete?: string[] | Autocompletion; + autoCompleteMenu?: boolean | Autocompletion; + autoCompleteHint?: boolean; + keyBindings?: { [key: string]: string }; + tokenHook?: ( + token: string, + isEndOfInput: boolean, + previousTokens: ReadonlyArray, + term: Terminal, + config: HookConfig + ) => string | CTerminal | null | void; + tokenResetHook?: ( + term: Terminal, + config?: HookConfig + ) => string | CTerminal; + tokenRegExp?: RegExp; + } + + type IFileInputOptions = InputFieldOptions & { baseDir: string }; + + interface SingleLineMenuResponse { + selectedIndex: number; + selectedText: string; + x: number; + y: number; + canceled: boolean; + unexpectedKey: string; + } + + interface SingleLineMenuOptions { + y?: number; + separator?: string; + nextPageHint?: string; + previousPageHint?: string; + style?: CTerminal; + selectedStyle?: CTerminal; + keyBindings?: { [key: string]: string }; + cancelable?: boolean; + exitOnUnexpectedKey?: boolean; + } + + interface SingleColumnMenuOptions { + y?: number; + style?: CTerminal; + selectedStyle?: CTerminal; + submittedStyle?: CTerminal; + leftPadding?: string; + selectedLeftPadding?: string; + submittedLeftPadding?: string; + extraLines?: number; + oneLineItem?: boolean; + itemMaxWidth?: number; + continueOnSubmit?: boolean; + selectedIndex?: number; + keyBindings?: { [key: string]: string }; + cancelable?: boolean; + exitOnUnexpectedKey?: boolean; + } + + interface SingleColumnMenuResponse { + selectedIndex: number; + selectedText: string; + submitted: boolean; + x: number; + y: number; + canceled: boolean; + unexpectedKey: string; + } + + interface GridMenuOptions { + y?: number; + x?: number; + width: number; + style?: CTerminal; + selectedStyle?: CTerminal; + leftPadding?: string; + selectedLeftPadding?: string; + rightPadding?: string; + selectedRightPadding?: string; + itemMaxWidth?: number; + keyBindings?: { [key: string]: string }; + exitOnUnexpectedKey?: boolean; + } + + interface GridMenuResponse { + selectedIndex: number; + selectedText: string; + x: number; + y: number; + unexpectedKey: string; + } + + interface ProgressBarOptions { + width?: number; + percent?: boolean; + eta?: boolean; + items?: number; + title?: string; + barStyle?: CTerminal; + barBracketStyle?: CTerminal; + percentStyle?: CTerminal; + etaStyle?: CTerminal; + itemStyle?: CTerminal; + titleStyle?: CTerminal; + itemSize?: number; + titleSize?: number; + barChar?: string; + barHeadChar?: string; + maxRefreshTime?: number; + minRefreshTime?: number; + inline?: boolean; + syncMode?: boolean; + } + + interface ProgressBarController { + update: ( + updateObject: + | number + | { progress: number | null; items?: number; title?: string } + ) => void; + startItem: (name: string) => void; + itemDone: (name: string) => void; + stop: () => void; + resume: () => void; + reset: () => void; + } +} diff --git a/types/terminal-kit/TextBuffer.d.ts b/types/terminal-kit/TextBuffer.d.ts new file mode 100644 index 0000000000..ef7c79458b --- /dev/null +++ b/types/terminal-kit/TextBuffer.d.ts @@ -0,0 +1,94 @@ +import ScreenBuffer = require("./ScreenBuffer"); +import Rect = require("./Rect"); + +export as namespace TextBuffer; + +declare class TextBuffer { + readonly x: number; + readonly y: number; + + constructor(options: TextBuffer.Options); + + getText(): string; + setText(text: string): void; + + getHidden(): boolean; + setHidden(state: boolean): void; + + getContentSize(): { width: number; height: number }; + + setEmptyCellAttr(attr: ScreenBuffer.Attributes | number): void; + + setAttrAt(attr: ScreenBuffer.Attributes | number, x: number, y: number): void; + setAttrCodeAt(attr: number, x: number, y: number): void; + + setAttrRegion( + attr: ScreenBuffer.Attributes | number, + region?: Rect.Region + ): void; + setAttrCodeRegion(attr: number, region?: Rect.Region): void; + + getMisc(): any; + getMiscAt(x: number, y: number): any; + + moveTo(x: number, y: number): void; + moveToColumn(x: number): void; + moveToLine(y: number): void; + moveToRow(y: number): void; + + move(x: number, y: number): void; + moveUp(): void; + moveDown(): void; + moveLeft(): void; + moveRight(): void; + moveForward(justSkipNullCells: boolean): void; + moveBackward(justSkipNullCells: boolean): void; + moveToEndOfLine(): void; + moveInBound(ignoreCx: boolean): void; + + insert(text: string, attr?: ScreenBuffer.Attributes | number): void; + + delete(n?: number): void; + bulkDelete(n?: number): void; + + newLine(): void; + joinLine(): void; + + iterate( + options: { finalCall: boolean }, + callback: ( + cellData: { + offset: number; + x: number; + y: number; + text: string; + attr: number; + misc: any; + } + ) => void + ): void; + + draw(options?: ScreenBuffer.DrawOptions): void; + + drawCursor(options?: { dst: ScreenBuffer }): void; + + load(filepath: string, callback: (error?: any) => void): void; + + save(filepath: string, callback: (error?: any) => void): void; +} + +export = TextBuffer; + +declare namespace TextBuffer { + interface Options { + dst: ScreenBuffer; + width?: number; + height?: number; + x?: number; + y?: number; + tabWidth?: number; + forceInBound?: number; + hidden?: boolean; + wrap?: boolean; + } +} diff --git a/types/terminal-kit/index.d.ts b/types/terminal-kit/index.d.ts new file mode 100644 index 0000000000..4746623fbd --- /dev/null +++ b/types/terminal-kit/index.d.ts @@ -0,0 +1,43 @@ +// Type definitions for terminal-kit 1.26 +// Project: https://github.com/cronvel/terminal-kit#readme +// Definitions by: katsanva +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.7 + +import Rect = require("./Rect"); +import ScreenBuffer = require("./ScreenBuffer"); +import ScreenBufferHD = require("./ScreenBufferHD"); +import Terminal = require("./Terminal"); +import TextBuffer = require("./TextBuffer"); + +export const terminal: Terminal; + +export const realTerminal: Terminal; + +export function createTerminal( + createOptions?: Terminal.CreateOptions +): Terminal; + +export function getParentTerminalInfo( + callback: (error: any, codename?: string, name?: string, pid?: number) => void +): void; + +export function getDetectedTerminal( + calback: (error: any, term: Terminal) => void +): void; + +export function autoComplete( + array: ReadonlyArray, + startString: string, + returnAlternatives?: boolean, + prefix?: string, + postfix?: string +): string; + +export function stripEscapeSequences(str: string): string; + +export function stringWidth(str: string): number; + +export function truncateString(str: string, maxWidth: number): string; + +export { Rect, ScreenBuffer, ScreenBufferHD, Terminal, TextBuffer }; diff --git a/types/terminal-kit/terminal-kit-tests.ts b/types/terminal-kit/terminal-kit-tests.ts new file mode 100644 index 0000000000..cdcdd4f5ac --- /dev/null +++ b/types/terminal-kit/terminal-kit-tests.ts @@ -0,0 +1,469 @@ +// Require the lib, get a working terminal +import t, { + terminal as term, + autoComplete as ac, + getDetectedTerminal, + ScreenBufferHD, + ScreenBuffer, + Terminal +} from "terminal-kit"; +import "node"; +import * as fs from "fs"; + +new t.Rect({width: 4, height: 4}); +// The term() function simply output a string to stdout, using current style +// output "Hello world!" in default terminal's colors +t.terminal("Hello world!\n"); + +// This output 'red' in red +term.red("red"); + +// This output 'bold' in bold +term.bold("bold"); + +// output 'mixed' using bold, underlined & red, exposing the style-mixing syntax +term.bold.underline.red("mixed"); + +// printf() style formatting everywhere: +// this will output 'My name is Jack, I'm 32.' in green +term.green("My name is %s, I'm %d.\n", "Jack", 32); + +// Since v0.16.x, style markup are supported as a shorthand. +// Those two lines produce the same result. +term("My name is ") + .red("Jack")(" and I'm ") + .green("32\n"); +term("My name is ^rJack^ and I'm ^g32\n"); + +// Width and height of the terminal +term("The terminal size is %dx%d", term.width, term.height); + +// Move the cursor at the upper-left corner +term.moveTo(1, 1); + +// We can always pass additional arguments that will be displayed... +term.moveTo(1, 1, "Upper-left corner"); + +// ... and formated +term.moveTo(1, 1, "My name is %s, I'm %d.\n", "Jack", 32); + +// ... or even combined with other styles +term.moveTo.cyan(1, 1, "My name is %s, I'm %d.\n", "Jack", 32); + +// Get some user input +term.magenta("Enter your name: "); +term.inputField((error: any, input: any) => { + term.green("\nYour name is '%s'\n", input); +}); + +function terminate() { + term.grabInput(false); + setTimeout(() => {}, 100); +} + +term.bold.cyan("Type anything on the keyboard...\n"); +term.green("Hit CTRL-C to quit.\n\n"); + +term.grabInput({ mouse: "button" }); + +term.on("key", (name: string, matches: any[], data: any) => { + console.log("'key' event:", name); + if (name === "CTRL_C") { + terminate(); + } +}); + +term.on("terminal", (name: string, data: any) => { + console.log("'terminal' event:", name, data); +}); + +term.on("mouse", (name: string, data: any) => { + console.log("'mouse' event:", name, data); +}); + +// Word-wrap this along the full terminal width +term.wrap.yellow( + `'Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish'` +); + +// Word-wrap this inside a column starting at x=10 with a width of 25 terminal cells +term.wrapColumn({ x: 10, width: 25 }); +term.wrap.green( + `'Permission is hereby granted, free of charge, to any person obtaining a copy of this software an + d associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish'` +); + +// This reset the offset +term("\n"); +// term.wrapColumn() could be used as well, but the next text would overwrite the last line + +// Text continuation: the second text start at the end of line of the first text +term.wrap.blue("^GP^re^Yr^um^Mi^bs^bs^ci^ro^mn^ is "); +term.wrap.red("hereby granted"); + +function question() { + term("Do you like javascript? [Y|n]\n"); + + // Exit on y and ENTER key + // Ask again on n + term.yesOrNo( + { yes: ["y", "ENTER"], no: ["n"] }, + (error: any, result: any) => { + if (result) { + term.green("'Yes' detected! Good bye!\n"); + } else { + term.red("'No' detected, are you sure?\n"); + question(); + } + } + ); +} + +question(); + +const history = ["John", "Jack", "Joey", "Billy", "Bob"]; + +const autoComplete = [ + "Barack Obama", + "George W. Bush", + "Bill Clinton", + "George Bush", + "Ronald W. Reagan", + "Jimmy Carter", + "Gerald Ford", + "Richard Nixon", + "Lyndon Johnson", + "John F. Kennedy", + "Dwight Eisenhower", + "Harry Truman", + "Franklin Roosevelt" +]; + +term("Please enter your name: "); + +term.inputField( + { history, autoComplete, autoCompleteMenu: true }, + (error: any, input: string) => { + term.green("\nYour name is '%s'\n", input); + } +); + +const history1 = ["John", "Jack", "Joey", "Billy", "Bob"]; + +const autoComplete1 = [ + "Barack Obama", + "George W. Bush", + "Bill Clinton", + "George Bush", + "Ronald W. Reagan", + "Jimmy Carter", + "Gerald Ford", + "Richard Nixon", + "Lyndon Johnson", + "John F. Kennedy", + "Dwight Eisenhower", + "Harry Truman", + "Franklin Roosevelt" +]; + +term("Please enter your name: "); +() => { + const input = term.inputField({ + history: history1, + autoComplete: autoComplete1, + autoCompleteMenu: true + }).promise; + + term.green("\nYour name is '%s'\n", input); +}; + +const autoCompleter = function autoCompleter( + inputString: string, + callback: (err: any, input: string) => void +) { + fs.readdir(__dirname, (error, files) => { + callback(undefined, ac(files, inputString, true)); + }); +}; + +term("Choose a file: "); + +term.inputField( + { autoComplete: autoCompleter, autoCompleteMenu: true }, + (error: any, input: any) => { + if (error) { + term.red.bold(`'\nAn error occurs: ' + ${error} + '\n'`); + } else { + term.green("\nYour file is '%s'\n", input); + } + } +); + +const autoComplete2 = [ + "dnf install", + "dnf install nodejs", + "dnf search", + "sudo", + "sudo dnf install", + "sudo dnf install nodejs", + "sudo dnf search" +]; + +term.inputField( + { + autoComplete: autoComplete2, + autoCompleteHint: true, + autoCompleteMenu: true, + tokenHook: ( + token: any, + isEndOfInput: any, + previousTokens: any, + term: any, + config: any + ) => { + const previousText = previousTokens.join(" "); + + switch (token) { + case "sudo": + config.style = term.red; + return previousTokens.length ? null : term.bold.red; + case "dnf": + return previousText === "" || previousText === "sudo" + ? term.brightMagenta + : null; + case "install": + config.style = term.brightBlue; + config.hintStyle = term.brightBlack.italic; + return previousText === "dnf" || previousText === "sudo dnf" + ? term.brightYellow + : null; + case "search": + config.style = term.brightBlue; + return previousText === "dnf" || previousText === "sudo dnf" + ? term.brightCyan + : null; + default: + return; + } + } + }, + (error: any, input: any) => { + term.green("\nYour command is: '%s'\n", input); + } +); + +term("Choose a file: "); + +term.fileInput({ baseDir: "../" }, (error: any, input: any) => { + if (error) { + term.red.bold(`'\nAn error occurs: ' + ${error} + '\n'`); + } else { + term.green("\nYour file is '%s'\n", input); + } +}); + +const items1 = [ + "File", + "Edit", + "View", + "History", + "Bookmarks", + "Tools", + "Help" +]; + +const options = { + y: 1, // the menu will be on the top of the terminal + style: term.inverse, + selectedStyle: term.dim.blue.bgGreen +}; + +term.clear(); + +term.singleLineMenu(items1, options, (error: any, response: any) => { + term("\n").eraseLineAfter.green( + "#%s selected: %s (%s,%s)\n", + response.selectedIndex, + response.selectedText, + response.x, + response.y + ); +}); + +term.cyan("The hall is spacious. Someone lighted few chandeliers.\n"); +term.cyan("There are doorways south and west.\n"); + +const items2 = ["a. Go south", "b. Go west", "c. Go back to the street"]; + +term.singleColumnMenu(items2, (error: any, response: any) => { + term("\n").eraseLineAfter.green( + "#%s selected: %s (%s,%s)\n", + response.selectedIndex, + response.selectedText, + response.x, + response.y + ); +}); + +term.cyan("Choose a file:\n"); + +const items = fs.readdirSync(process.cwd()); + +term.gridMenu(items, (error: any, response: any) => { + term("\n").eraseLineAfter.green( + "#%s selected: %s (%s,%s)\n", + response.selectedIndex, + response.selectedText, + response.x, + response.y + ); +}); + +let progressBar: Terminal.ProgressBarController; +let progress = 0; + +function doProgress() { + // Add random progress + progress += Math.random() / 10; + progressBar.update(progress); + + if (progress >= 1) { + // Cleanup and exit + setTimeout(() => { + term("\n"); + }, 200); + } else { + setTimeout(doProgress, 100 + Math.random() * 400); + } +} + +progressBar = term.progressBar({ + width: 80, + title: "Serious stuff in progress:", + eta: true, + percent: true +}); + +doProgress(); + +const thingsToDo = [ + "update my lib", + "data analyzing", + "serious business", + "decrunching data", + "do my laundry", + "optimizing" +]; + +let countDown = thingsToDo.length; + +function start() { + const task = thingsToDo.shift(); + + if (!task) { + return; + } + + progressBar.startItem(task); + + // Finish the task in... + setTimeout(done.bind(null, task), 500 + Math.random() * 1200); + + // Start another parallel task in... + setTimeout(start, 400 + Math.random() * 400); +} + +function done(task: string) { + progressBar.itemDone(task); + countDown--; + + // Cleanup and exit + if (!countDown) { + setTimeout(() => { + term("\n"); + }, 200); + } +} + +progressBar = term.progressBar({ + width: 80, + title: "Daily tasks:", + eta: true, + percent: true, + items: thingsToDo.length +}); + +start(); + +term.slowTyping( + "What a wonderful world!\n", + { flashStyle: term.brightWhite }, + () => {} +); + +// low level + +term("My name is ") + .red("Jack")(" and I'm ") + .green("32\n"); +term("My name is ^rJack^ and I'm ^g32\n"); + +getDetectedTerminal((error: any, term: any) => { + term.cyan("Terminal name: %s\n", term.appName); + term.cyan("Terminal app: %s\n", term.app); + term.cyan("Terminal generic: %s\n", term.generic); + term.cyan("Config file: %s\n", term.termconfigFile); +}); + +const screen = new ScreenBufferHD({ dst: term, noFill: true }); + +screen.fill({ + attr: { + // Both foreground and background must have the same color + r: 40, + g: 20, + b: 0, + bgR: 40, + bgG: 20, + bgB: 0 + } +}); + +const path_to_image = "/home/imoti/Downloads/photo_2019-01-24_13-15-50.jpg"; + +ScreenBufferHD.loadImage( + path_to_image, + { shrink: { width: term.width, height: term.height * 2 } }, + (error: any, image: any) => { + if (error) { + throw error; + } // Doh! + + image.draw({ dst: screen, blending: true }); + screen.draw(); + } +); + +const screen1 = new ScreenBuffer({ dst: term, noFill: true }); + +screen1.fill({ + attr: { + // Both foreground and background must have the same color + color: 0, + bgColor: 0 + } +}); + +ScreenBuffer.loadImage( + path_to_image, + { terminal: term, shrink: { width: term.width, height: term.height * 2 } }, + (error: any, image: any) => { + if (error) { + throw error; + } // Doh! + + image.draw({ dst: screen, blending: true }); + screen.draw(); + } +); diff --git a/types/terminal-kit/tsconfig.json b/types/terminal-kit/tsconfig.json new file mode 100644 index 0000000000..949b61722b --- /dev/null +++ b/types/terminal-kit/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": ["es2017"], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "esModuleInterop": true, + "baseUrl": "../", + "typeRoots": ["../"], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "strictFunctionTypes": false + }, + "files": ["index.d.ts", "terminal-kit-tests.ts"] +} diff --git a/types/terminal-kit/tslint.json b/types/terminal-kit/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/terminal-kit/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }