mirror of
https://github.com/Eugeny/tabby.git
synced 2025-02-17 14:49:39 +08:00
removed hterm - #4295
This commit is contained in:
parent
a560f0c96e
commit
1ae8d9c643
@ -20,7 +20,7 @@ sh.cd('web')
|
|||||||
sh.exec(`${npx} yarn install --force`)
|
sh.exec(`${npx} yarn install --force`)
|
||||||
sh.cd('..')
|
sh.cd('..')
|
||||||
|
|
||||||
vars.builtinPlugins.forEach(plugin => {
|
vars.allPackages.forEach(plugin => {
|
||||||
log.info('deps', plugin)
|
log.info('deps', plugin)
|
||||||
sh.cd(plugin)
|
sh.cd(plugin)
|
||||||
sh.exec(`${npx} yarn install --force`)
|
sh.exec(`${npx} yarn install --force`)
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
"author": "Eugene Pankov",
|
"author": "Eugene Pankov",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"hterm-umdjs": "1.4.1",
|
|
||||||
"opentype.js": "^1.3.3"
|
"opentype.js": "^1.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -174,11 +174,6 @@ has@^1.0.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
function-bind "^1.1.1"
|
function-bind "^1.1.1"
|
||||||
|
|
||||||
hterm-umdjs@1.4.1:
|
|
||||||
version "1.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/hterm-umdjs/-/hterm-umdjs-1.4.1.tgz#0cd5352eaf927c70b83c36146cf2c2a281dba957"
|
|
||||||
integrity sha512-r5JOmdDK1bZCmp3cKcuGRLVeum33H+pzD119ZxmQou+QUVe6SAVSz03HvKWVhM2Ao1Biv+fkhFDmnsaRPq0tFg==
|
|
||||||
|
|
||||||
is-arguments@^1.0.4, is-arguments@^1.1.0:
|
is-arguments@^1.0.4, is-arguments@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9"
|
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9"
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
"author": "Eugene Pankov",
|
"author": "Eugene Pankov",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"hterm-umdjs": "1.4.1",
|
|
||||||
"opentype.js": "^1.3.3"
|
"opentype.js": "^1.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -9,7 +9,6 @@ h3.mb-3 Terminal
|
|||||||
[(ngModel)]='config.store.terminal.frontend',
|
[(ngModel)]='config.store.terminal.frontend',
|
||||||
(ngModelChange)='config.save()',
|
(ngModelChange)='config.save()',
|
||||||
)
|
)
|
||||||
option(value='hterm') hterm
|
|
||||||
option(value='xterm') xterm
|
option(value='xterm') xterm
|
||||||
option(value='xterm-webgl') xterm (WebGL)
|
option(value='xterm-webgl') xterm (WebGL)
|
||||||
|
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
/** @hidden */
|
|
||||||
export const hterm = require('hterm-umdjs')
|
|
||||||
|
|
||||||
hterm.hterm.defaultStorage = new hterm.lib.Storage.Memory()
|
|
||||||
|
|
||||||
/** @hidden */
|
|
||||||
export const preferenceManager = new hterm.hterm.PreferenceManager('default')
|
|
||||||
|
|
||||||
hterm.hterm.VT.ESC['k'] = function (parseState) {
|
|
||||||
parseState.resetArguments()
|
|
||||||
|
|
||||||
function parseOSC (ps) {
|
|
||||||
if (!this.parseUntilStringTerminator_(ps) || ps.func === parseOSC) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.terminal.setWindowTitle(ps.args[0])
|
|
||||||
}
|
|
||||||
parseState.func = parseOSC
|
|
||||||
}
|
|
||||||
|
|
||||||
preferenceManager.set('background-color', '#1D272D')
|
|
||||||
preferenceManager.set('color-palette-overrides', {
|
|
||||||
0: '#1D272D',
|
|
||||||
})
|
|
||||||
|
|
||||||
hterm.hterm.Terminal.prototype.showOverlay = () => null
|
|
||||||
|
|
||||||
hterm.hterm.Terminal.prototype.setCSS = function (css) {
|
|
||||||
const doc = this.scrollPort_.document_
|
|
||||||
if (!doc.querySelector('#user-css')) {
|
|
||||||
const node = doc.createElement('style')
|
|
||||||
node.id = 'user-css'
|
|
||||||
doc.head.appendChild(node)
|
|
||||||
}
|
|
||||||
doc.querySelector('#user-css').innerText = css
|
|
||||||
}
|
|
||||||
|
|
||||||
const oldCharWidthDisregardAmbiguous = hterm.lib.wc.charWidthDisregardAmbiguous
|
|
||||||
hterm.lib.wc.charWidthDisregardAmbiguous = codepoint => {
|
|
||||||
if ((codepoint >= 0x1f300 && codepoint <= 0x1f64f) ||
|
|
||||||
(codepoint >= 0x1f680 && codepoint <= 0x1f6ff)) {
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
return oldCharWidthDisregardAmbiguous(codepoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
hterm.hterm.Terminal.prototype.applyCursorShape = function () {
|
|
||||||
const modes = [
|
|
||||||
[hterm.hterm.Terminal.cursorShape.BLOCK, true],
|
|
||||||
[this.defaultCursorShape || hterm.hterm.Terminal.cursorShape.BLOCK, false],
|
|
||||||
[hterm.hterm.Terminal.cursorShape.BLOCK, false],
|
|
||||||
[hterm.hterm.Terminal.cursorShape.UNDERLINE, true],
|
|
||||||
[hterm.hterm.Terminal.cursorShape.UNDERLINE, false],
|
|
||||||
[hterm.hterm.Terminal.cursorShape.BEAM, true],
|
|
||||||
[hterm.hterm.Terminal.cursorShape.BEAM, false],
|
|
||||||
]
|
|
||||||
const modeNumber = this.cursorMode || 1
|
|
||||||
if (modeNumber >= modes.length) {
|
|
||||||
console.warn('Unknown cursor style: ' + modeNumber)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
this.setCursorShape(modes[modeNumber][0])
|
|
||||||
this.setCursorBlink(modes[modeNumber][1])
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
this.setCursorVisible(true)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
hterm.hterm.VT.CSI[' q'] = function (parseState) {
|
|
||||||
const arg = parseState.args[0]
|
|
||||||
this.terminal.cursorMode = arg
|
|
||||||
this.terminal.applyCursorShape()
|
|
||||||
}
|
|
||||||
|
|
||||||
hterm.hterm.VT.OSC['4'] = function (parseState) {
|
|
||||||
const args: string[] = parseState.args[0].split(';')
|
|
||||||
|
|
||||||
const pairCount = args.length / 2
|
|
||||||
const colorPalette = this.terminal.getTextAttributes().colorPalette
|
|
||||||
const responseArray: string[] = []
|
|
||||||
|
|
||||||
for (let pairNumber = 0; pairNumber < pairCount; ++pairNumber) {
|
|
||||||
const colorIndex = parseInt(args[pairNumber * 2])
|
|
||||||
let colorValue = args[pairNumber * 2 + 1]
|
|
||||||
|
|
||||||
if (colorIndex >= colorPalette.length) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colorValue === '?') {
|
|
||||||
colorValue = hterm.lib.colors.rgbToX11(colorPalette[colorIndex])
|
|
||||||
if (colorValue) {
|
|
||||||
responseArray.push(colorIndex.toString() + ';' + colorValue)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
colorValue = hterm.lib.colors.x11ToCSS(colorValue)
|
|
||||||
if (colorValue) {
|
|
||||||
this.terminal.colorPaletteOverrides[colorIndex] = colorValue
|
|
||||||
colorPalette[colorIndex] = colorValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (responseArray.length) {
|
|
||||||
this.terminal.io.sendString('\x1b]4;' + responseArray.join(';') + '\x07')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const _collapseToEnd = Selection.prototype.collapseToEnd
|
|
||||||
Selection.prototype.collapseToEnd = function () {
|
|
||||||
try {
|
|
||||||
_collapseToEnd.apply(this)
|
|
||||||
} catch (e) { }
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
a {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
x-screen {
|
|
||||||
transition: 0.125s ease background;
|
|
||||||
background: transparent;
|
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
width: 3px;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: rgba(255, 255, 255, 0.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
x-row > span {
|
|
||||||
display: inline-block;
|
|
||||||
height: inherit;
|
|
||||||
|
|
||||||
&.wc-node {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "monospace-fallback";
|
|
||||||
src: url(../fonts/SourceCodePro.otf) format("opentype");
|
|
||||||
}
|
|
@ -1,302 +0,0 @@
|
|||||||
import { Injector } from '@angular/core'
|
|
||||||
import { ConfigService, getCSSFontFamily, ThemesService } from 'tabby-core'
|
|
||||||
import { Frontend, SearchOptions } from './frontend'
|
|
||||||
import { hterm, preferenceManager } from './hterm'
|
|
||||||
|
|
||||||
/** @hidden */
|
|
||||||
export class HTermFrontend extends Frontend {
|
|
||||||
term: any
|
|
||||||
io: any
|
|
||||||
private htermIframe: HTMLElement
|
|
||||||
private initialized = false
|
|
||||||
private configuredFontSize = 0
|
|
||||||
private configuredLinePadding = 0
|
|
||||||
private configuredBackgroundColor = 'transparent'
|
|
||||||
private zoom = 0
|
|
||||||
|
|
||||||
private configService: ConfigService
|
|
||||||
private themesService: ThemesService
|
|
||||||
|
|
||||||
constructor (injector: Injector) {
|
|
||||||
super(injector)
|
|
||||||
this.configService = injector.get(ConfigService)
|
|
||||||
this.themesService = injector.get(ThemesService)
|
|
||||||
}
|
|
||||||
|
|
||||||
async attach (host: HTMLElement): Promise<void> {
|
|
||||||
if (!this.initialized) {
|
|
||||||
this.init()
|
|
||||||
this.initialized = true
|
|
||||||
preferenceManager.set('background-color', 'transparent')
|
|
||||||
this.term.decorate(host)
|
|
||||||
this.htermIframe = this.term.scrollPort_.iframe_
|
|
||||||
} else {
|
|
||||||
host.appendChild(this.htermIframe)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getSelection (): string {
|
|
||||||
return this.term.getSelectionText()
|
|
||||||
}
|
|
||||||
|
|
||||||
copySelection (): void {
|
|
||||||
this.term.copySelectionToClipboard()
|
|
||||||
}
|
|
||||||
|
|
||||||
selectAll (): void {
|
|
||||||
const content = this.term.getDocument().body.children[0]
|
|
||||||
const selection = content.ownerDocument.defaultView.getSelection()
|
|
||||||
selection.setBaseAndExtent(content, 0, content, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
clearSelection (): void {
|
|
||||||
this.term.getDocument().getSelection().removeAllRanges()
|
|
||||||
}
|
|
||||||
|
|
||||||
focus (): void {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.term.scrollPort_.resize()
|
|
||||||
this.term.scrollPort_.focus()
|
|
||||||
}, 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
write (data: string): void {
|
|
||||||
this.io.writeUTF8(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
clear (): void {
|
|
||||||
this.term.wipeContents()
|
|
||||||
this.term.onVTKeystroke('\f')
|
|
||||||
}
|
|
||||||
|
|
||||||
configure (): void {
|
|
||||||
const config = this.configService.store
|
|
||||||
|
|
||||||
this.configuredFontSize = config.terminal.fontSize
|
|
||||||
this.configuredLinePadding = config.terminal.linePadding
|
|
||||||
this.setFontSize()
|
|
||||||
|
|
||||||
preferenceManager.set('font-family', getCSSFontFamily(config))
|
|
||||||
preferenceManager.set('enable-bold', true)
|
|
||||||
// preferenceManager.set('audible-bell-sound', '')
|
|
||||||
preferenceManager.set('desktop-notification-bell', config.terminal.bell === 'notification')
|
|
||||||
preferenceManager.set('enable-clipboard-notice', false)
|
|
||||||
preferenceManager.set('receive-encoding', 'raw')
|
|
||||||
preferenceManager.set('send-encoding', 'raw')
|
|
||||||
preferenceManager.set('ctrl-plus-minus-zero-zoom', false)
|
|
||||||
preferenceManager.set('scrollbar-visible', process.platform === 'darwin')
|
|
||||||
preferenceManager.set('copy-on-select', config.terminal.copyOnSelect)
|
|
||||||
preferenceManager.set('pass-meta-v', false)
|
|
||||||
preferenceManager.set('alt-is-meta', config.terminal.altIsMeta)
|
|
||||||
preferenceManager.set('alt-sends-what', 'browser-key')
|
|
||||||
preferenceManager.set('alt-gr-mode', 'ctrl-alt')
|
|
||||||
preferenceManager.set('pass-alt-number', true)
|
|
||||||
preferenceManager.set('cursor-blink', config.terminal.cursorBlink)
|
|
||||||
preferenceManager.set('clear-selection-after-copy', true)
|
|
||||||
preferenceManager.set('scroll-on-output', false)
|
|
||||||
preferenceManager.set('scroll-on-keystroke', config.terminal.scrollOnInput)
|
|
||||||
|
|
||||||
if (config.terminal.colorScheme.foreground) {
|
|
||||||
preferenceManager.set('foreground-color', config.terminal.colorScheme.foreground)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.terminal.background === 'colorScheme') {
|
|
||||||
if (config.terminal.colorScheme.background) {
|
|
||||||
preferenceManager.set('background-color', config.terminal.colorScheme.background)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
preferenceManager.set('background-color', config.appearance.vibrancy ? 'transparent' : this.themesService.findCurrentTheme().terminalBackground)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.configuredBackgroundColor = preferenceManager.get('background-color')
|
|
||||||
|
|
||||||
if (!this.term) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let css = require('./hterm.userCSS.scss') // eslint-disable-line
|
|
||||||
if (!config.terminal.ligatures) {
|
|
||||||
css += `
|
|
||||||
* {
|
|
||||||
font-feature-settings: "liga" 0;
|
|
||||||
font-variant-ligatures: none;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
} else {
|
|
||||||
css += `
|
|
||||||
* {
|
|
||||||
font-feature-settings: "liga" 1;
|
|
||||||
font-variant-ligatures: initial;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
css += config.appearance.css
|
|
||||||
this.term.setCSS(css)
|
|
||||||
|
|
||||||
if (config.terminal.colorScheme.colors) {
|
|
||||||
preferenceManager.set(
|
|
||||||
'color-palette-overrides',
|
|
||||||
Object.assign([], config.terminal.colorScheme.colors, this.term.colorPaletteOverrides)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (config.terminal.colorScheme.cursor) {
|
|
||||||
preferenceManager.set('cursor-color', config.terminal.colorScheme.cursor)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.term.setBracketedPaste(config.terminal.bracketedPaste)
|
|
||||||
this.term.defaultCursorShape = {
|
|
||||||
block: hterm.hterm.Terminal.cursorShape.BLOCK,
|
|
||||||
underline: hterm.hterm.Terminal.cursorShape.UNDERLINE,
|
|
||||||
beam: hterm.hterm.Terminal.cursorShape.BEAM,
|
|
||||||
}[config.terminal.cursor]
|
|
||||||
this.term.applyCursorShape()
|
|
||||||
this.term.setCursorBlink(config.terminal.cursorBlink)
|
|
||||||
if (config.terminal.cursorBlink) {
|
|
||||||
this.term.onCursorBlink_()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setZoom (zoom: number): void {
|
|
||||||
this.zoom = zoom
|
|
||||||
this.setFontSize()
|
|
||||||
}
|
|
||||||
|
|
||||||
visualBell (): void {
|
|
||||||
preferenceManager.set('background-color', 'rgba(128,128,128,.25)')
|
|
||||||
setTimeout(() => {
|
|
||||||
preferenceManager.set('background-color', this.configuredBackgroundColor)
|
|
||||||
}, 125)
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollToBottom (): void {
|
|
||||||
this.term.scrollEnd()
|
|
||||||
}
|
|
||||||
|
|
||||||
findNext (_term: string, _searchOptions?: SearchOptions): boolean {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
findPrevious (_term: string, _searchOptions?: SearchOptions): boolean {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
||||||
saveState (): any { }
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
||||||
restoreState (_state: string): void { }
|
|
||||||
|
|
||||||
private setFontSize () {
|
|
||||||
const size = this.configuredFontSize * Math.pow(1.1, this.zoom)
|
|
||||||
preferenceManager.set('font-size', size)
|
|
||||||
if (this.term) {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.term.scrollPort_.characterSize = this.term.scrollPort_.measureCharacterSize()
|
|
||||||
this.term.setFontSize(size)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private init () {
|
|
||||||
this.term = new hterm.hterm.Terminal()
|
|
||||||
this.term.colorPaletteOverrides = []
|
|
||||||
this.term.onTerminalReady = () => {
|
|
||||||
this.term.installKeyboard()
|
|
||||||
this.term.scrollPort_.setCtrlVPaste(true)
|
|
||||||
this.io = this.term.io.push()
|
|
||||||
this.io.onVTKeystroke = this.io.sendString = data => this.input.next(Buffer.from(data, 'utf-8'))
|
|
||||||
this.io.onTerminalResize = (columns, rows) => {
|
|
||||||
this.resize.next({ columns, rows })
|
|
||||||
}
|
|
||||||
this.ready.next()
|
|
||||||
this.ready.complete()
|
|
||||||
|
|
||||||
this.term.scrollPort_.document_.addEventListener('dragOver', event => {
|
|
||||||
this.dragOver.next(event)
|
|
||||||
})
|
|
||||||
|
|
||||||
this.term.scrollPort_.document_.addEventListener('drop', event => {
|
|
||||||
this.drop.next(event)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.term.setWindowTitle = title => this.title.next(title)
|
|
||||||
|
|
||||||
const _setAlternateMode = this.term.setAlternateMode.bind(this.term)
|
|
||||||
this.term.setAlternateMode = (state) => {
|
|
||||||
_setAlternateMode(state)
|
|
||||||
this.alternateScreenActive.next(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.term.primaryScreen_.syncSelectionCaret = () => null
|
|
||||||
this.term.alternateScreen_.syncSelectionCaret = () => null
|
|
||||||
this.term.primaryScreen_.terminal = this.term
|
|
||||||
this.term.alternateScreen_.terminal = this.term
|
|
||||||
|
|
||||||
this.term.scrollPort_.onPaste_ = (event) => {
|
|
||||||
event.preventDefault()
|
|
||||||
}
|
|
||||||
|
|
||||||
const _resize = this.term.scrollPort_.resize.bind(this.term.scrollPort_)
|
|
||||||
this.term.scrollPort_.resize = () => {
|
|
||||||
if (this.enableResizing) {
|
|
||||||
_resize()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const _onMouse = this.term.onMouse_.bind(this.term)
|
|
||||||
this.term.onMouse_ = (event) => {
|
|
||||||
this.mouseEvent.next(event)
|
|
||||||
if (event.type === 'mousedown' && event.which === 3) {
|
|
||||||
event.preventDefault()
|
|
||||||
event.stopPropagation()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (event.type === 'mousewheel' && event.altKey) {
|
|
||||||
event.preventDefault()
|
|
||||||
}
|
|
||||||
_onMouse(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.term.ringBell = () => this.bell.next()
|
|
||||||
|
|
||||||
for (const screen of [this.term.primaryScreen_, this.term.alternateScreen_]) {
|
|
||||||
const _insertString = screen.insertString.bind(screen)
|
|
||||||
screen.insertString = (data) => {
|
|
||||||
_insertString(data)
|
|
||||||
this.contentUpdated.next()
|
|
||||||
}
|
|
||||||
|
|
||||||
const _deleteChars = screen.deleteChars.bind(screen)
|
|
||||||
screen.deleteChars = (count) => {
|
|
||||||
const ret = _deleteChars(count)
|
|
||||||
this.contentUpdated.next()
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
const _expandSelection = screen.expandSelection.bind(screen)
|
|
||||||
screen.expandSelection = (selection) => {
|
|
||||||
// Drop whitespace at the end of selection
|
|
||||||
const range = selection.getRangeAt(0)
|
|
||||||
if (range.endOffset > 0 && range.endContainer.nodeType === 3 && range.endContainer.textContent !== '') {
|
|
||||||
while (/[\s\S]+\s$/.test(range.endContainer.textContent.substr(0, range.endOffset))) {
|
|
||||||
range.setEnd(range.endContainer, range.endOffset - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_expandSelection(selection)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const _measureCharacterSize = this.term.scrollPort_.measureCharacterSize.bind(this.term.scrollPort_)
|
|
||||||
this.term.scrollPort_.measureCharacterSize = () => {
|
|
||||||
const size = _measureCharacterSize()
|
|
||||||
size.height += this.configuredLinePadding
|
|
||||||
return size
|
|
||||||
}
|
|
||||||
|
|
||||||
const _onCursorBlink = this.term.onCursorBlink_.bind(this.term)
|
|
||||||
this.term.onCursorBlink_ = () => {
|
|
||||||
this.term.cursorNode_.style.opacity = '0'
|
|
||||||
_onCursorBlink()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,7 +4,7 @@ import { FormsModule } from '@angular/forms'
|
|||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { ToastrModule } from 'ngx-toastr'
|
import { ToastrModule } from 'ngx-toastr'
|
||||||
|
|
||||||
import TabbyCorePlugin, { ConfigProvider, HotkeysService, HotkeyProvider, TabContextMenuItemProvider, CLIHandler } from 'tabby-core'
|
import TabbyCorePlugin, { ConfigProvider, HotkeyProvider, TabContextMenuItemProvider, CLIHandler } from 'tabby-core'
|
||||||
import { SettingsTabProvider } from 'tabby-settings'
|
import { SettingsTabProvider } from 'tabby-settings'
|
||||||
|
|
||||||
import { AppearanceSettingsTabComponent } from './components/appearanceSettingsTab.component'
|
import { AppearanceSettingsTabComponent } from './components/appearanceSettingsTab.component'
|
||||||
@ -29,9 +29,7 @@ import { TerminalConfigProvider } from './config'
|
|||||||
import { TerminalHotkeyProvider } from './hotkeys'
|
import { TerminalHotkeyProvider } from './hotkeys'
|
||||||
import { CopyPasteContextMenu, MiscContextMenu, LegacyContextMenu } from './tabContextMenu'
|
import { CopyPasteContextMenu, MiscContextMenu, LegacyContextMenu } from './tabContextMenu'
|
||||||
|
|
||||||
import { hterm } from './frontends/hterm'
|
|
||||||
import { Frontend } from './frontends/frontend'
|
import { Frontend } from './frontends/frontend'
|
||||||
import { HTermFrontend } from './frontends/htermFrontend'
|
|
||||||
import { XTermFrontend, XTermWebGLFrontend } from './frontends/xtermFrontend'
|
import { XTermFrontend, XTermWebGLFrontend } from './frontends/xtermFrontend'
|
||||||
import { TerminalCLIHandler } from './cli'
|
import { TerminalCLIHandler } from './cli'
|
||||||
|
|
||||||
@ -83,37 +81,10 @@ import { TerminalCLIHandler } from './cli'
|
|||||||
LoginScriptsSettingsComponent,
|
LoginScriptsSettingsComponent,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export default class TerminalModule { // eslint-disable-line @typescript-eslint/no-extraneous-class
|
export default class TerminalModule { } // eslint-disable-line @typescript-eslint/no-extraneous-class
|
||||||
constructor (
|
|
||||||
hotkeys: HotkeysService,
|
|
||||||
) {
|
|
||||||
const events = [
|
|
||||||
{
|
|
||||||
name: 'keydown',
|
|
||||||
htermHandler: 'onKeyDown_',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'keyup',
|
|
||||||
htermHandler: 'onKeyUp_',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
events.forEach(event => {
|
|
||||||
const oldHandler = hterm.hterm.Keyboard.prototype[event.htermHandler]
|
|
||||||
hterm.hterm.Keyboard.prototype[event.htermHandler] = function (nativeEvent) {
|
|
||||||
hotkeys.pushKeyEvent(event.name, nativeEvent)
|
|
||||||
if (hotkeys.matchActiveHotkey(true) !== null) {
|
|
||||||
oldHandler.bind(this)(nativeEvent)
|
|
||||||
} else {
|
|
||||||
nativeEvent.stopPropagation()
|
|
||||||
nativeEvent.preventDefault()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export { TerminalFrontendService, TerminalDecorator, TerminalContextMenuItemProvider, TerminalColorSchemeProvider }
|
export { TerminalFrontendService, TerminalDecorator, TerminalContextMenuItemProvider, TerminalColorSchemeProvider }
|
||||||
export { Frontend, XTermFrontend, XTermWebGLFrontend, HTermFrontend }
|
export { Frontend, XTermFrontend, XTermWebGLFrontend }
|
||||||
export { BaseTerminalTabComponent } from './api/baseTerminalTab.component'
|
export { BaseTerminalTabComponent } from './api/baseTerminalTab.component'
|
||||||
export * from './api/interfaces'
|
export * from './api/interfaces'
|
||||||
export * from './api/streamProcessing'
|
export * from './api/streamProcessing'
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Injectable, Injector } from '@angular/core'
|
import { Injectable, Injector } from '@angular/core'
|
||||||
import { ConfigService } from 'tabby-core'
|
import { ConfigService } from 'tabby-core'
|
||||||
import { Frontend } from '../frontends/frontend'
|
import { Frontend } from '../frontends/frontend'
|
||||||
import { HTermFrontend } from '../frontends/htermFrontend'
|
|
||||||
import { XTermFrontend, XTermWebGLFrontend } from '../frontends/xtermFrontend'
|
import { XTermFrontend, XTermWebGLFrontend } from '../frontends/xtermFrontend'
|
||||||
import { BaseSession } from '../session'
|
import { BaseSession } from '../session'
|
||||||
|
|
||||||
@ -17,12 +16,11 @@ export class TerminalFrontendService {
|
|||||||
|
|
||||||
getFrontend (session?: BaseSession|null): Frontend {
|
getFrontend (session?: BaseSession|null): Frontend {
|
||||||
if (!session) {
|
if (!session) {
|
||||||
const frontend: Frontend = new {
|
const cls = {
|
||||||
xterm: XTermFrontend,
|
xterm: XTermFrontend,
|
||||||
'xterm-webgl': XTermWebGLFrontend,
|
'xterm-webgl': XTermWebGLFrontend,
|
||||||
hterm: HTermFrontend,
|
}[this.config.store.terminal.frontend] ?? XTermFrontend
|
||||||
}[this.config.store.terminal.frontend](this.injector)
|
return new cls(this.injector)
|
||||||
return frontend
|
|
||||||
}
|
}
|
||||||
if (!this.containers.has(session)) {
|
if (!this.containers.has(session)) {
|
||||||
this.containers.set(
|
this.containers.set(
|
||||||
|
@ -3,7 +3,6 @@ module.exports = config({
|
|||||||
name: 'terminal',
|
name: 'terminal',
|
||||||
dirname: __dirname,
|
dirname: __dirname,
|
||||||
externals: [
|
externals: [
|
||||||
'hterm-umdjs',
|
|
||||||
'opentype.js',
|
'opentype.js',
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
@ -239,11 +239,6 @@ hexer@^1.5.0:
|
|||||||
process "^0.10.0"
|
process "^0.10.0"
|
||||||
xtend "^4.0.0"
|
xtend "^4.0.0"
|
||||||
|
|
||||||
hterm-umdjs@1.4.1:
|
|
||||||
version "1.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/hterm-umdjs/-/hterm-umdjs-1.4.1.tgz#0cd5352eaf927c70b83c36146cf2c2a281dba957"
|
|
||||||
integrity sha512-r5JOmdDK1bZCmp3cKcuGRLVeum33H+pzD119ZxmQou+QUVe6SAVSz03HvKWVhM2Ao1Biv+fkhFDmnsaRPq0tFg==
|
|
||||||
|
|
||||||
is-arguments@^1.0.4, is-arguments@^1.1.0:
|
is-arguments@^1.0.4, is-arguments@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9"
|
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -86,24 +86,6 @@ Tabby.registerModule('crypto', {
|
|||||||
return a.equals(b)
|
return a.equals(b)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
Tabby.registerMock('hterm-umdjs', {
|
|
||||||
hterm: {
|
|
||||||
PreferenceManager: class { set () {} },
|
|
||||||
VT: {
|
|
||||||
ESC: {},
|
|
||||||
CSI: {},
|
|
||||||
OSC: {},
|
|
||||||
},
|
|
||||||
Terminal: class {},
|
|
||||||
Keyboard: class {},
|
|
||||||
},
|
|
||||||
lib: {
|
|
||||||
wc: {},
|
|
||||||
Storage: {
|
|
||||||
Memory: class {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
Tabby.registerMock('dns', {})
|
Tabby.registerMock('dns', {})
|
||||||
Tabby.registerMock('socksv5', {})
|
Tabby.registerMock('socksv5', {})
|
||||||
Tabby.registerMock('util', require('util/'))
|
Tabby.registerMock('util', require('util/'))
|
||||||
|
Loading…
Reference in New Issue
Block a user