Compare commits
2 Commits
141204164a
...
ed15d94255
| Author | SHA1 | Date | |
|---|---|---|---|
| ed15d94255 | |||
| 1d54c8b650 |
@@ -13,7 +13,7 @@ const init = () => {
|
||||
(key: string, isCharacter: boolean) => localBroadcaster.emit('keyup', key, isCharacter),
|
||||
)
|
||||
|
||||
const terminal = new Terminal(localBroadcaster)
|
||||
const terminal = new Terminal()
|
||||
terminal.LoadShell(new Wush(localBroadcaster, terminal))
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,9 @@ import type { EventBroadcaster } from '../utils/EventBroadcaster'
|
||||
import { Shell } from './Shell'
|
||||
|
||||
export class Wush extends Shell {
|
||||
private buffer: string[] = []
|
||||
private bufferPos: number = 0
|
||||
|
||||
constructor(broadcaster: EventBroadcaster, terminal: Terminal) {
|
||||
super(broadcaster, terminal)
|
||||
}
|
||||
@@ -21,20 +24,63 @@ export class Wush extends Shell {
|
||||
this.terminal.Write('hi -> ')
|
||||
}
|
||||
|
||||
PushToBuffer(text: string) {
|
||||
text.split('').forEach(char => {
|
||||
this.buffer.splice(this.bufferPos, 0, char)
|
||||
this.bufferPos++
|
||||
})
|
||||
|
||||
console.log(this.buffer)
|
||||
}
|
||||
|
||||
RemoveLastCharsFromBuffer(amount: number) {
|
||||
this.buffer.splice(this.buffer.length - amount, amount)
|
||||
this.bufferPos -= amount
|
||||
|
||||
console.log(this.buffer)
|
||||
}
|
||||
|
||||
MoveBufferPos(index: number, absolute: boolean = false) {
|
||||
this.bufferPos = Math.max(absolute ? index : this.bufferPos + index, 0)
|
||||
}
|
||||
|
||||
FlushBuffer() {
|
||||
this.buffer = []
|
||||
this.bufferPos = 0
|
||||
}
|
||||
|
||||
ExecuteBuffer() {
|
||||
const args = this.buffer.join('').split(' ')
|
||||
this.FlushBuffer()
|
||||
|
||||
console.log(`Executing ${args[0]} with args '${args}'`)
|
||||
}
|
||||
|
||||
HandleKeyInput(key: string, isCharacter: boolean) {
|
||||
if (!isCharacter)
|
||||
if (!isCharacter) {
|
||||
switch (key) {
|
||||
case 'ArrowLeft':
|
||||
this.terminal.MoveCursor(-1, 0)
|
||||
this.MoveBufferPos(-1)
|
||||
break
|
||||
case 'ArrowRight':
|
||||
this.terminal.MoveCursor(1, 0)
|
||||
this.MoveBufferPos(1)
|
||||
break
|
||||
case 'Backspace':
|
||||
this.terminal.RemoveCell()
|
||||
this.RemoveLastCharsFromBuffer(1)
|
||||
this.terminal.MoveCursor(-1, 0)
|
||||
break
|
||||
case 'Enter':
|
||||
this.terminal.MoveCursor(0, 4, { x: true, y: false })
|
||||
this.terminal.MoveCursor(0, 1, { x: true, y: false })
|
||||
this.ExecuteBuffer()
|
||||
this.Prompt()
|
||||
break
|
||||
}
|
||||
else {
|
||||
this.terminal.Write(key)
|
||||
} else {
|
||||
this.terminal.InsertCell(key)
|
||||
this.PushToBuffer(key)
|
||||
this.terminal.MoveCursor(1, 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,4 +7,6 @@
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
background: colors.$terminal-white;
|
||||
|
||||
transition: .2s cubic-bezier(0, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
}
|
||||
|
||||
.line {
|
||||
background: red;
|
||||
width: fit-content
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import type { Shell } from '../shell/Shell'
|
||||
import type { EventBroadcaster } from '../utils/EventBroadcaster'
|
||||
import sqs from '../utils/sqs'
|
||||
import type { CellContent } from './CellContent'
|
||||
import type { CursorPosition, CursorStyle } from './CursorProperties'
|
||||
|
||||
export class Terminal {
|
||||
@@ -17,13 +15,13 @@ export class Terminal {
|
||||
|
||||
private shell?: Shell
|
||||
|
||||
constructor(broadcaster: EventBroadcaster) {
|
||||
constructor() {
|
||||
this.terminal = sqs('#terminal')
|
||||
this.cursor = sqs('#cursor')
|
||||
|
||||
this.SetCursorStyle('bar')
|
||||
|
||||
this.ResetCellSize()
|
||||
|
||||
this.SetCursorStyle('bar')
|
||||
this.NewPage()
|
||||
}
|
||||
|
||||
@@ -45,6 +43,12 @@ export class Terminal {
|
||||
paragraph.className = 'line'
|
||||
|
||||
this.terminal.appendChild(paragraph)
|
||||
paragraph.scrollIntoView({behavior: 'smooth'})
|
||||
}
|
||||
|
||||
UpdateLines() {
|
||||
const lines = new Array(...this.terminal.children)
|
||||
lines.forEach((line, i) => line.id = `line-${i}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,13 +59,10 @@ export class Terminal {
|
||||
}
|
||||
|
||||
Write(text: string) {
|
||||
let adjustment = 0
|
||||
|
||||
text.split('').forEach((char) => {
|
||||
this.MoveCursor(adjustment, 0)
|
||||
adjustment = 1
|
||||
|
||||
this.SetCell(char)
|
||||
this.MoveCursor(1, 0)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -94,13 +95,23 @@ export class Terminal {
|
||||
sqs(selector).innerText = char[0]
|
||||
}
|
||||
|
||||
AppendCells(content: string) {
|
||||
const paragraph = sqs(`#line-${this.cursorPosition.row}`)
|
||||
UpdateCells() {
|
||||
const cells = new Array(...sqs(`#line-${this.cursorPosition.row}`).children)
|
||||
cells.forEach((cell, i) => cell.className = `cell-${i}`)
|
||||
}
|
||||
|
||||
content.split('').forEach((char) => {
|
||||
paragraph.textContent += char.replace(' ', '\u00A0')
|
||||
this.MoveCursor(1, 0)
|
||||
})
|
||||
InsertCell(char: string) {
|
||||
const cell = document.createElement('span')
|
||||
cell.className = `cell-${this.cursorPosition.col}`
|
||||
cell.style.width = `${this.cellWidth}px`
|
||||
cell.style.height = `${this.cellHeight}px`
|
||||
cell.style.lineHeight = `${this.cellHeight}px`
|
||||
|
||||
cell.innerText = char[0]
|
||||
|
||||
sqs(`#line-${this.cursorPosition.row} .cell-${this.cursorPosition.col}`).insertAdjacentElement('beforebegin', cell)
|
||||
|
||||
this.UpdateCells()
|
||||
}
|
||||
|
||||
RemoveCell() {
|
||||
@@ -108,6 +119,8 @@ export class Terminal {
|
||||
sqs(`#line-${this.cursorPosition.row} .cell-${this.cursorPosition.col - 1}`).remove()
|
||||
} catch (_) {
|
||||
|
||||
} finally {
|
||||
this.UpdateCells()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user