Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
8.7 kB · 319 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320/** * CSI (Control Sequence Introducer) Types * * Enums and types for CSI command parameters. */
import { ESC, ESC_TYPE, SEP } from './ansi.js'
export const CSI_PREFIX = ESC + String.fromCharCode(ESC_TYPE.CSI)
/** * CSI parameter byte ranges */export const CSI_RANGE = { PARAM_START: 0x30, PARAM_END: 0x3f, INTERMEDIATE_START: 0x20, INTERMEDIATE_END: 0x2f, FINAL_START: 0x40, FINAL_END: 0x7e,} as const
/** Check if a byte is a CSI parameter byte */export function isCSIParam(byte: number): boolean { return byte >= CSI_RANGE.PARAM_START && byte <= CSI_RANGE.PARAM_END}
/** Check if a byte is a CSI intermediate byte */export function isCSIIntermediate(byte: number): boolean { return ( byte >= CSI_RANGE.INTERMEDIATE_START && byte <= CSI_RANGE.INTERMEDIATE_END )}
/** Check if a byte is a CSI final byte (@ through ~) */export function isCSIFinal(byte: number): boolean { return byte >= CSI_RANGE.FINAL_START && byte <= CSI_RANGE.FINAL_END}
/** * Generate a CSI sequence: ESC [ p1;p2;...;pN final * Single arg: treated as raw body * Multiple args: last is final byte, rest are params joined by ; */export function csi(...args: (string | number)[]): string { if (args.length === 0) return CSI_PREFIX if (args.length === 1) return `${CSI_PREFIX}${args[0]}` const params = args.slice(0, -1) const final = args[args.length - 1] return `${CSI_PREFIX}${params.join(SEP)}${final}`}
/** * CSI final bytes - the command identifier */export const CSI = { // Cursor movement CUU: 0x41, // A - Cursor Up CUD: 0x42, // B - Cursor Down CUF: 0x43, // C - Cursor Forward CUB: 0x44, // D - Cursor Back CNL: 0x45, // E - Cursor Next Line CPL: 0x46, // F - Cursor Previous Line CHA: 0x47, // G - Cursor Horizontal Absolute CUP: 0x48, // H - Cursor Position CHT: 0x49, // I - Cursor Horizontal Tab VPA: 0x64, // d - Vertical Position Absolute HVP: 0x66, // f - Horizontal Vertical Position
// Erase ED: 0x4a, // J - Erase in Display EL: 0x4b, // K - Erase in Line ECH: 0x58, // X - Erase Character
// Insert/Delete IL: 0x4c, // L - Insert Lines DL: 0x4d, // M - Delete Lines ICH: 0x40, // @ - Insert Characters DCH: 0x50, // P - Delete Characters
// Scroll SU: 0x53, // S - Scroll Up SD: 0x54, // T - Scroll Down
// Modes SM: 0x68, // h - Set Mode RM: 0x6c, // l - Reset Mode
// SGR SGR: 0x6d, // m - Select Graphic Rendition
// Other DSR: 0x6e, // n - Device Status Report DECSCUSR: 0x71, // q - Set Cursor Style (with space intermediate) DECSTBM: 0x72, // r - Set Top and Bottom Margins SCOSC: 0x73, // s - Save Cursor Position SCORC: 0x75, // u - Restore Cursor Position CBT: 0x5a, // Z - Cursor Backward Tabulation} as const
/** * Erase in Display regions (ED command parameter) */export const ERASE_DISPLAY = ['toEnd', 'toStart', 'all', 'scrollback'] as const
/** * Erase in Line regions (EL command parameter) */export const ERASE_LINE_REGION = ['toEnd', 'toStart', 'all'] as const
/** * Cursor styles (DECSCUSR) */export type CursorStyle = 'block' | 'underline' | 'bar'
export const CURSOR_STYLES: Array<{ style: CursorStyle; blinking: boolean }> = [ { style: 'block', blinking: true }, // 0 - default { style: 'block', blinking: true }, // 1 { style: 'block', blinking: false }, // 2 { style: 'underline', blinking: true }, // 3 { style: 'underline', blinking: false }, // 4 { style: 'bar', blinking: true }, // 5 { style: 'bar', blinking: false }, // 6]
// Cursor movement generators
/** Move cursor up n lines (CSI n A) */export function cursorUp(n = 1): string { return n === 0 ? '' : csi(n, 'A')}
/** Move cursor down n lines (CSI n B) */export function cursorDown(n = 1): string { return n === 0 ? '' : csi(n, 'B')}
/** Move cursor forward n columns (CSI n C) */export function cursorForward(n = 1): string { return n === 0 ? '' : csi(n, 'C')}
/** Move cursor back n columns (CSI n D) */export function cursorBack(n = 1): string { return n === 0 ? '' : csi(n, 'D')}
/** Move cursor to column n (1-indexed) (CSI n G) */export function cursorTo(col: number): string { return csi(col, 'G')}
/** Move cursor to column 1 (CSI G) */export const CURSOR_LEFT = csi('G')
/** Move cursor to row, col (1-indexed) (CSI row ; col H) */export function cursorPosition(row: number, col: number): string { return csi(row, col, 'H')}
/** Move cursor to home position (CSI H) */export const CURSOR_HOME = csi('H')
/** * Move cursor relative to current position * Positive x = right, negative x = left * Positive y = down, negative y = up */export function cursorMove(x: number, y: number): string { let result = '' // Horizontal first (matches ansi-escapes behavior) if (x < 0) { result += cursorBack(-x) } else if (x > 0) { result += cursorForward(x) } // Then vertical if (y < 0) { result += cursorUp(-y) } else if (y > 0) { result += cursorDown(y) } return result}
// Save/restore cursor position
/** Save cursor position (CSI s) */export const CURSOR_SAVE = csi('s')
/** Restore cursor position (CSI u) */export const CURSOR_RESTORE = csi('u')
// Erase generators
/** Erase from cursor to end of line (CSI K) */export function eraseToEndOfLine(): string { return csi('K')}
/** Erase from cursor to start of line (CSI 1 K) */export function eraseToStartOfLine(): string { return csi(1, 'K')}
/** Erase entire line (CSI 2 K) */export function eraseLine(): string { return csi(2, 'K')}
/** Erase entire line - constant form */export const ERASE_LINE = csi(2, 'K')
/** Erase from cursor to end of screen (CSI J) */export function eraseToEndOfScreen(): string { return csi('J')}
/** Erase from cursor to start of screen (CSI 1 J) */export function eraseToStartOfScreen(): string { return csi(1, 'J')}
/** Erase entire screen (CSI 2 J) */export function eraseScreen(): string { return csi(2, 'J')}
/** Erase entire screen - constant form */export const ERASE_SCREEN = csi(2, 'J')
/** Erase scrollback buffer (CSI 3 J) */export const ERASE_SCROLLBACK = csi(3, 'J')
/** * Erase n lines starting from cursor line, moving cursor up * This erases each line and moves up, ending at column 1 */export function eraseLines(n: number): string { if (n <= 0) return '' let result = '' for (let i = 0; i < n; i++) { result += ERASE_LINE if (i < n - 1) { result += cursorUp(1) } } result += CURSOR_LEFT return result}
// Scroll
/** Scroll up n lines (CSI n S) */export function scrollUp(n = 1): string { return n === 0 ? '' : csi(n, 'S')}
/** Scroll down n lines (CSI n T) */export function scrollDown(n = 1): string { return n === 0 ? '' : csi(n, 'T')}
/** Set scroll region (DECSTBM, CSI top;bottom r). 1-indexed, inclusive. */export function setScrollRegion(top: number, bottom: number): string { return csi(top, bottom, 'r')}
/** Reset scroll region to full screen (DECSTBM, CSI r). Homes the cursor. */export const RESET_SCROLL_REGION = csi('r')
// Bracketed paste markers (input from terminal, not output)// These are sent by the terminal to delimit pasted content when// bracketed paste mode is enabled (via DEC mode 2004)
/** Sent by terminal before pasted content (CSI 200 ~) */export const PASTE_START = csi('200~')
/** Sent by terminal after pasted content (CSI 201 ~) */export const PASTE_END = csi('201~')
// Focus event markers (input from terminal, not output)// These are sent by the terminal when focus changes while// focus events mode is enabled (via DEC mode 1004)
/** Sent by terminal when it gains focus (CSI I) */export const FOCUS_IN = csi('I')
/** Sent by terminal when it loses focus (CSI O) */export const FOCUS_OUT = csi('O')
// Kitty keyboard protocol (CSI u)// Enables enhanced key reporting with modifier information// See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/
/** * Enable Kitty keyboard protocol with basic modifier reporting * CSI > 1 u - pushes mode with flags=1 (disambiguate escape codes) * This makes Shift+Enter send CSI 13;2 u instead of just CR */export const ENABLE_KITTY_KEYBOARD = csi('>1u')
/** * Disable Kitty keyboard protocol * CSI < u - pops the keyboard mode stack */export const DISABLE_KITTY_KEYBOARD = csi('<u')
/** * Enable xterm modifyOtherKeys level 2. * tmux accepts this (not the kitty stack) to enable extended keys — when * extended-keys-format is csi-u, tmux then emits keys in kitty format. */export const ENABLE_MODIFY_OTHER_KEYS = csi('>4;2m')
/** * Disable xterm modifyOtherKeys (reset to default). */export const DISABLE_MODIFY_OTHER_KEYS = csi('>4m')