mirror of
https://github.com/Eugeny/tabby.git
synced 2025-07-28 12:48:35 +00:00
Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0d4ebe3d96 | ||
![]() |
c856f460e6 | ||
![]() |
6a969d2cd2 | ||
![]() |
b6cbd42d8b | ||
![]() |
7237c2b05a | ||
![]() |
19a217923e | ||
![]() |
7f160e9421 | ||
![]() |
d0c245d0d5 | ||
![]() |
693edab597 | ||
![]() |
d42e070e6c | ||
![]() |
c5958bc9a0 | ||
![]() |
9dc2337787 | ||
![]() |
1a38cc30a8 | ||
![]() |
4949f14184 | ||
![]() |
11902020a5 | ||
![]() |
3f96c21f33 | ||
![]() |
9e81f0aa0e | ||
![]() |
1cce23cef5 | ||
![]() |
b7a56adb60 | ||
![]() |
eb02752cbf | ||
![]() |
3a6eb8cb2f | ||
![]() |
a7d62b0234 | ||
![]() |
b9cbe4f12d | ||
![]() |
5f74b35ba9 | ||
![]() |
affb439ab2 |
23
README.md
23
README.md
@@ -1,31 +1,36 @@
|
||||

|
||||
|
||||
<p align="center">
|
||||
<a href="https://raw.githubusercontent.com/Eugeny/terminus/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg"/></a> <a href="https://travis-ci.org/Eugeny/terminus"><img src="https://travis-ci.org/Eugeny/terminus.svg?branch=master"/></a>
|
||||
<a href="https://ci.appveyor.com/project/Eugeny/terminus"><img src="https://ci.appveyor.com/api/projects/status/wnnq4hm5mbd9rgoy?svg=true"/></a>
|
||||
<a href="https://raw.githubusercontent.com/Eugeny/terminus/master/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/eugeny/terminus.svg?label=License&style=flat-square"></a> <a href="https://travis-ci.org/Eugeny/terminus"><img alt="Travis (.org)" src="https://img.shields.io/travis/Eugeny/terminus.svg?label=CI&logo=travis&logoColor=white&style=flat-square"></a>
|
||||
<a href="https://ci.appveyor.com/project/Eugeny/terminus"><img alt="AppVeyor" src="https://img.shields.io/appveyor/ci/eugeny/terminus.svg?label=CI&logo=appveyor&logoColor=white&style=flat-square"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/Eugeny/terminus/releases/latest">Downloads</a> | <a href="https://gitter.im/terminus-terminal/community">Community</a> | <a href="https://ci.appveyor.com/project/Eugeny/terminus/build/artifacts">Latest Windows nightly</a>
|
||||
<a href="https://github.com/Eugeny/terminus/releases/latest"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/eugeny/terminus/total.svg?label=DOWNLOAD&logo=github&style=for-the-badge"></a> <a href="https://ci.appveyor.com/project/Eugeny/terminus/build/artifacts"><img src="https://img.shields.io/badge/download-nightly%20build-magenta.svg?logo=appveyor&style=for-the-badge"/></a> <a href="https://gitter.im/terminus-terminal/community"><img alt="Gitter" src="https://img.shields.io/gitter/room/terminus/community.svg?color=blue&logo=gitter&style=for-the-badge"></a>
|
||||
</p>
|
||||
|
||||
----
|
||||
|
||||
**Terminus** is a terminal heavily inspired by Hyper. It is, however, designed for people who need to get things done.
|
||||
**Terminus** is a highly configurable terminal emulator for Windows, macOS and Linux
|
||||
|
||||
* Runs on Windows, macOS and Linux
|
||||
* Theming and color schemes
|
||||
* Fully configurable shortcuts
|
||||
* Split panes
|
||||
* Remembers your tabs
|
||||
* PowerShell (and PS Core), WSL, Git-Bash, Cygwin, Cmder and CMD support
|
||||
* Integrated SSH client and connection manager
|
||||
* Full Unicode support including double-width characters
|
||||
* Doesn't choke on fast-flowing outputs
|
||||
* Proper shell-like experience on Windows including tab completion (via Clink)
|
||||
* PowerShell (+Core), WSL (Bash on Windows), Git-Bash, Cygwin, Cmder and CMD support
|
||||
* Remembers your tabs
|
||||
* Integrated SSH client and connection manager
|
||||
* Proper shell experience on Windows including tab completion (via Clink)
|
||||
|
||||
|
||||
[](https://ko-fi.com/eugeny)
|
||||
|
||||
---
|
||||
|
||||
* **Terminus is** an alternative to Windows' standard terminal (conhost), PowerShell ISE, PuTTY or iTerm
|
||||
|
||||
* **Terminus is not** a new shell or a MinGW or Cygwin replacement. Neither is it lightweight - if RAM usage is of importance, consider [Conemu](https://conemu.github.io) or [Alacritty](https://github.com/jwilm/alacritty)
|
||||
|
||||
---
|
||||
|
||||
|
BIN
app/assets/activity.png
Normal file
BIN
app/assets/activity.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
@@ -14,7 +14,7 @@ module.exports = {
|
||||
minimize: false,
|
||||
},
|
||||
context: __dirname,
|
||||
devtool: 'source-map',
|
||||
devtool: 'eval-source-map',
|
||||
output: {
|
||||
path: path.join(__dirname, 'dist'),
|
||||
pathinfo: true,
|
||||
|
@@ -9,7 +9,7 @@ module.exports = {
|
||||
},
|
||||
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
|
||||
context: __dirname,
|
||||
devtool: 'source-map',
|
||||
devtool: 'eval-source-map',
|
||||
output: {
|
||||
path: path.join(__dirname, 'dist'),
|
||||
pathinfo: true,
|
||||
|
26
snap/snapcraft.yaml
Normal file
26
snap/snapcraft.yaml
Normal file
@@ -0,0 +1,26 @@
|
||||
name: terminus
|
||||
version: '1.0.0'
|
||||
summary: A terminal for a modern age
|
||||
description: |
|
||||
Terminus is a terminal heavily inspired by Hyper. It is, however, designed for people who need to get things done.
|
||||
|
||||
grade: devel
|
||||
confinement: devmode
|
||||
|
||||
apps:
|
||||
terminus:
|
||||
command: opt/terminus/terminus
|
||||
|
||||
parts:
|
||||
app:
|
||||
plugin: nodejs
|
||||
source: .
|
||||
build-packages:
|
||||
- libfontconfig-dev
|
||||
override-build: |
|
||||
yarn
|
||||
./scripts/build-native.js
|
||||
yarn run build
|
||||
./scripts/build-linux.js
|
||||
mkdir -p $SNAPCRAFT_PART_INSTALL/opt/terminus || true
|
||||
cp -ar dist/linux-unpacked/* $SNAPCRAFT_PART_INSTALL/opt/terminus/
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "terminus-community-color-schemes",
|
||||
"version": "1.0.68-c17-g8b64a81",
|
||||
"version": "1.0.73-c4-ga7d62b0",
|
||||
"description": "Community color schemes for Terminus",
|
||||
"keywords": [
|
||||
"terminus-builtin-plugin"
|
||||
|
36
terminus-community-color-schemes/schemes/Relaxed
Normal file
36
terminus-community-color-schemes/schemes/Relaxed
Normal file
@@ -0,0 +1,36 @@
|
||||
! special
|
||||
*.foreground: #d8d8d8
|
||||
*.background: #343a43
|
||||
*.cursorColor: #d8d8d8
|
||||
|
||||
! black
|
||||
*.color0: #2c3037
|
||||
*.color8: #626262
|
||||
|
||||
! red
|
||||
*.color1: #bb5653
|
||||
*.color9: #c35956
|
||||
|
||||
! green
|
||||
*.color2: #909d62
|
||||
*.color10: #9fab76
|
||||
|
||||
! yellow
|
||||
*.color3: #eac179
|
||||
*.color11: #ecc179
|
||||
|
||||
! blue
|
||||
*.color4: #698698
|
||||
*.color12: #7da9c7
|
||||
|
||||
! magenta
|
||||
*.color5: #b06597
|
||||
*.color13: #ba6ca0
|
||||
|
||||
! cyan
|
||||
*.color6: #c9dfff
|
||||
*.color14: #abbacf
|
||||
|
||||
! white
|
||||
*.color7: #d8d8d8
|
||||
*.color15: #f7f7f7
|
@@ -4,7 +4,7 @@ const webpack = require('webpack')
|
||||
module.exports = {
|
||||
target: 'node',
|
||||
entry: 'src/index.ts',
|
||||
devtool: 'source-map',
|
||||
devtool: 'eval-source-map',
|
||||
context: __dirname,
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "terminus-core",
|
||||
"version": "1.0.68-c17-g8b64a81",
|
||||
"version": "1.0.73-c4-ga7d62b0",
|
||||
"description": "Terminus core",
|
||||
"keywords": [
|
||||
"terminus-builtin-plugin"
|
||||
|
@@ -210,18 +210,21 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
||||
case 'split-left':
|
||||
this.splitTab(this.focusedTab, 'l')
|
||||
break
|
||||
case 'split-nav-left':
|
||||
case 'pane-nav-left':
|
||||
this.navigate('l')
|
||||
break
|
||||
case 'split-nav-right':
|
||||
case 'pane-nav-right':
|
||||
this.navigate('r')
|
||||
break
|
||||
case 'split-nav-up':
|
||||
case 'pane-nav-up':
|
||||
this.navigate('t')
|
||||
break
|
||||
case 'split-nav-down':
|
||||
case 'pane-nav-down':
|
||||
this.navigate('b')
|
||||
break
|
||||
case 'close-pane':
|
||||
this.removeTab(this.focusedTab)
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -336,6 +339,8 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
||||
|
||||
if (this.root.children.length === 0) {
|
||||
this.destroy()
|
||||
} else {
|
||||
this.focusAnyIn(parent)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -42,12 +42,13 @@ hotkeys:
|
||||
- 'Ctrl-Shift-D'
|
||||
split-left: []
|
||||
split-top: []
|
||||
split-nav-right:
|
||||
pane-nav-right:
|
||||
- 'Ctrl-Alt-ArrowRight'
|
||||
split-nav-down:
|
||||
pane-nav-down:
|
||||
- 'Ctrl-Alt-ArrowDown'
|
||||
split-nav-up:
|
||||
pane-nav-up:
|
||||
- 'Ctrl-Alt-ArrowUp'
|
||||
split-nav-left:
|
||||
pane-nav-left:
|
||||
- 'Ctrl-Alt-ArrowLeft'
|
||||
close-pane: []
|
||||
pluginBlacklist: ['ssh']
|
||||
|
@@ -40,12 +40,14 @@ hotkeys:
|
||||
- '⌘-D'
|
||||
split-left: []
|
||||
split-top: []
|
||||
split-nav-right:
|
||||
pane-nav-right:
|
||||
- '⌘-⌥-ArrowRight'
|
||||
split-nav-down:
|
||||
pane-nav-down:
|
||||
- '⌘-⌥-ArrowDown'
|
||||
split-nav-up:
|
||||
pane-nav-up:
|
||||
- '⌘-⌥-ArrowUp'
|
||||
split-nav-left:
|
||||
pane-nav-left:
|
||||
- '⌘-⌥-ArrowLeft'
|
||||
close-pane:
|
||||
- '⌘-Shift-W'
|
||||
pluginBlacklist: ['ssh']
|
||||
|
@@ -42,12 +42,13 @@ hotkeys:
|
||||
- 'Ctrl-Shift-D'
|
||||
split-left: []
|
||||
split-top: []
|
||||
split-nav-right:
|
||||
pane-nav-right:
|
||||
- 'Ctrl-Alt-ArrowRight'
|
||||
split-nav-down:
|
||||
pane-nav-down:
|
||||
- 'Ctrl-Alt-ArrowDown'
|
||||
split-nav-up:
|
||||
pane-nav-up:
|
||||
- 'Ctrl-Alt-ArrowUp'
|
||||
split-nav-left:
|
||||
pane-nav-left:
|
||||
- 'Ctrl-Alt-ArrowLeft'
|
||||
close-pane: []
|
||||
pluginBlacklist: []
|
||||
|
@@ -94,21 +94,25 @@ export class AppHotkeyProvider extends HotkeyProvider {
|
||||
name: 'Split to the top',
|
||||
},
|
||||
{
|
||||
id: 'split-nav-up',
|
||||
id: 'pane-nav-up',
|
||||
name: 'Focus the pane above',
|
||||
},
|
||||
{
|
||||
id: 'split-nav-down',
|
||||
id: 'pane-nav-down',
|
||||
name: 'Focus the pane below',
|
||||
},
|
||||
{
|
||||
id: 'split-nav-left',
|
||||
id: 'pane-nav-left',
|
||||
name: 'Focus the pane on the left',
|
||||
},
|
||||
{
|
||||
id: 'split-nav-right',
|
||||
id: 'pane-nav-right',
|
||||
name: 'Focus the pane on the right',
|
||||
},
|
||||
{
|
||||
id: 'close-pane',
|
||||
name: 'Close focused pane',
|
||||
},
|
||||
]
|
||||
|
||||
async provide (): Promise<IHotkeyDescription[]> {
|
||||
|
@@ -10,6 +10,7 @@ import { IToolbarButton, ToolbarButtonProvider } from '../api'
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class TouchbarService {
|
||||
private tabsSegmentedControl: TouchBarSegmentedControl
|
||||
private buttonsSegmentedControl: TouchBarSegmentedControl
|
||||
private tabSegments: SegmentedControlSegment[] = []
|
||||
private nsImageCache: {[id: string]: Electron.NativeImage} = {}
|
||||
|
||||
@@ -24,16 +25,31 @@ export class TouchbarService {
|
||||
if (this.hostApp.platform !== Platform.macOS) {
|
||||
return
|
||||
}
|
||||
app.tabsChanged$.subscribe(() => this.update())
|
||||
app.activeTabChange$.subscribe(() => this.update())
|
||||
app.tabsChanged$.subscribe(() => this.updateTabs())
|
||||
app.activeTabChange$.subscribe(() => this.updateTabs())
|
||||
|
||||
let activityIconPath = `${electron.app.getAppPath()}/assets/activity.png`
|
||||
let activityIcon = this.electron.nativeImage.createFromPath(activityIconPath)
|
||||
app.tabOpened$.subscribe(tab => {
|
||||
tab.titleChange$.subscribe(title => {
|
||||
this.tabSegments[app.tabs.indexOf(tab)].label = this.shortenTitle(title)
|
||||
this.tabsSegmentedControl.segments = this.tabSegments
|
||||
})
|
||||
tab.activity$.subscribe(hasActivity => {
|
||||
let showIcon = this.app.activeTab !== tab && hasActivity
|
||||
this.tabSegments[app.tabs.indexOf(tab)].icon = showIcon ? activityIcon : null
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
updateTabs () {
|
||||
this.tabSegments = this.app.tabs.map(tab => ({
|
||||
label: this.shortenTitle(tab.title),
|
||||
}))
|
||||
this.tabsSegmentedControl.segments = this.tabSegments
|
||||
this.tabsSegmentedControl.selectedIndex = this.app.tabs.indexOf(this.app.activeTab)
|
||||
}
|
||||
|
||||
update () {
|
||||
if (this.hostApp.platform !== Platform.macOS) {
|
||||
return
|
||||
@@ -47,6 +63,7 @@ export class TouchbarService {
|
||||
this.tabSegments = this.app.tabs.map(tab => ({
|
||||
label: this.shortenTitle(tab.title),
|
||||
}))
|
||||
|
||||
this.tabsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({
|
||||
segments: this.tabSegments,
|
||||
selectedIndex: this.app.tabs.indexOf(this.app.activeTab),
|
||||
@@ -54,23 +71,32 @@ export class TouchbarService {
|
||||
this.app.selectTab(this.app.tabs[selectedIndex])
|
||||
})
|
||||
})
|
||||
|
||||
this.buttonsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({
|
||||
segments: buttons.map(button => this.getButton(button)),
|
||||
mode: 'buttons',
|
||||
change: (selectedIndex) => this.zone.run(() => {
|
||||
buttons[selectedIndex].click()
|
||||
})
|
||||
})
|
||||
|
||||
let touchBar = new this.electron.TouchBar({
|
||||
items: [
|
||||
this.tabsSegmentedControl,
|
||||
new this.electron.TouchBar.TouchBarSpacer({ size: 'flexible' }),
|
||||
new this.electron.TouchBar.TouchBarSpacer({ size: 'small' }),
|
||||
...buttons.map(button => this.getButton(button))
|
||||
this.buttonsSegmentedControl,
|
||||
]
|
||||
})
|
||||
this.hostApp.setTouchBar(touchBar)
|
||||
}
|
||||
|
||||
private getButton (button: IToolbarButton): Electron.TouchBarButton {
|
||||
return new this.electron.TouchBar.TouchBarButton({
|
||||
private getButton (button: IToolbarButton): Electron.SegmentedControlSegment {
|
||||
return {
|
||||
label: button.touchBarNSImage ? null : this.shortenTitle(button.touchBarTitle || button.title),
|
||||
icon: button.touchBarNSImage ? this.getCachedNSImage(button.touchBarNSImage) : null,
|
||||
click: () => this.zone.run(() => button.click()),
|
||||
})
|
||||
// click: () => this.zone.run(() => button.click()),
|
||||
}
|
||||
}
|
||||
|
||||
private getCachedNSImage (name: string) {
|
||||
|
@@ -6,6 +6,10 @@ app-root {
|
||||
|
||||
.btn-tab-bar {
|
||||
line-height: 29px !important;
|
||||
|
||||
svg {
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -4,7 +4,7 @@ const webpack = require('webpack')
|
||||
module.exports = {
|
||||
target: 'node',
|
||||
entry: 'src/index.ts',
|
||||
devtool: 'source-map',
|
||||
devtool: 'eval-source-map',
|
||||
context: __dirname,
|
||||
mode: 'development',
|
||||
output: {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "terminus-plugin-manager",
|
||||
"version": "1.0.68-c17-g8b64a81",
|
||||
"version": "1.0.73-c4-ga7d62b0",
|
||||
"description": "Terminus' plugin manager",
|
||||
"keywords": [
|
||||
"terminus-builtin-plugin"
|
||||
|
@@ -4,7 +4,7 @@ const webpack = require('webpack')
|
||||
module.exports = {
|
||||
target: 'node',
|
||||
entry: 'src/index.ts',
|
||||
devtool: 'source-map',
|
||||
devtool: 'eval-source-map',
|
||||
context: __dirname,
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "terminus-settings",
|
||||
"version": "1.0.68-c17-g8b64a81",
|
||||
"version": "1.0.73-c4-ga7d62b0",
|
||||
"description": "Terminus terminal settings page",
|
||||
"keywords": [
|
||||
"terminus-builtin-plugin"
|
||||
|
@@ -4,7 +4,7 @@ const webpack = require('webpack')
|
||||
module.exports = {
|
||||
target: 'node',
|
||||
entry: 'src/index.ts',
|
||||
devtool: 'source-map',
|
||||
devtool: 'eval-source-map',
|
||||
context: __dirname,
|
||||
mode: 'development',
|
||||
output: {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "terminus-ssh",
|
||||
"version": "1.0.68-c17-g8b64a81",
|
||||
"version": "1.0.73-c4-ga7d62b0",
|
||||
"description": "SSH connection manager for Terminus",
|
||||
"keywords": [
|
||||
"terminus-builtin-plugin"
|
||||
|
@@ -3,7 +3,7 @@ const path = require('path')
|
||||
module.exports = {
|
||||
target: 'node',
|
||||
entry: 'src/index.ts',
|
||||
devtool: 'source-map',
|
||||
devtool: 'eval-source-map',
|
||||
context: __dirname,
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "terminus-terminal",
|
||||
"version": "1.0.68-c17-g8b64a81",
|
||||
"version": "1.0.73-c4-ga7d62b0",
|
||||
"description": "Terminus' terminal emulation core",
|
||||
"keywords": [
|
||||
"terminus-builtin-plugin"
|
||||
@@ -28,7 +28,7 @@
|
||||
"slug": "^0.9.3",
|
||||
"uuid": "^3.3.2",
|
||||
"xterm": "3.10.1",
|
||||
"xterm-addon-ligatures-tmp": "^0.1.0-beta-1"
|
||||
"xterm-addon-ligatures": "^0.1.0-beta-2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "4.0.1",
|
||||
|
@@ -110,12 +110,6 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
|
||||
case 'reset-zoom':
|
||||
this.resetZoom()
|
||||
break
|
||||
case 'home':
|
||||
this.sendInput('\x1bOH')
|
||||
break
|
||||
case 'end':
|
||||
this.sendInput('\x1bOF')
|
||||
break
|
||||
case 'previous-word':
|
||||
this.sendInput('\x1bb')
|
||||
break
|
||||
|
@@ -1,9 +1,11 @@
|
||||
import { Component, Input } from '@angular/core'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { first } from 'rxjs/operators'
|
||||
import { BaseTabProcess } from 'terminus-core'
|
||||
import { BaseTerminalTabComponent } from './baseTerminalTab.component'
|
||||
import { SessionOptions } from '../api'
|
||||
import { Session } from '../services/sessions.service'
|
||||
import { WIN_BUILD_CONPTY_SUPPORTED, isWindowsBuild } from '../utils'
|
||||
|
||||
/** @hidden */
|
||||
@Component({
|
||||
@@ -13,11 +15,28 @@ import { Session } from '../services/sessions.service'
|
||||
})
|
||||
export class TerminalTabComponent extends BaseTerminalTabComponent {
|
||||
@Input() sessionOptions: SessionOptions
|
||||
private homeEndSubscription: Subscription
|
||||
|
||||
ngOnInit () {
|
||||
this.logger = this.log.create('terminalTab')
|
||||
this.session = new Session(this.config)
|
||||
|
||||
let isConPTY = isWindowsBuild(WIN_BUILD_CONPTY_SUPPORTED) && this.config.store.terminal.useConPTY
|
||||
|
||||
this.homeEndSubscription = this.hotkeys.matchedHotkey.subscribe(hotkey => {
|
||||
if (!this.hasFocus) {
|
||||
return
|
||||
}
|
||||
switch (hotkey) {
|
||||
case 'home':
|
||||
this.sendInput(isConPTY ? '\x1b[H' : '\x1bOH')
|
||||
break
|
||||
case 'end':
|
||||
this.sendInput(isConPTY ? '\x1b[F' : '\x1bOF')
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
this.frontendReady$.pipe(first()).subscribe(() => {
|
||||
this.initializeSession(this.size.columns, this.size.rows)
|
||||
})
|
||||
@@ -73,4 +92,9 @@ export class TerminalTabComponent extends BaseTerminalTabComponent {
|
||||
}
|
||||
)).response === 1
|
||||
}
|
||||
|
||||
ngOnDestroy () {
|
||||
this.homeEndSubscription.unsubscribe()
|
||||
super.ngOnDestroy()
|
||||
}
|
||||
}
|
||||
|
@@ -1,14 +1,11 @@
|
||||
import { Frontend } from './frontend'
|
||||
import { Terminal, ITheme } from 'xterm'
|
||||
import * as fit from 'xterm/src/addons/fit/fit'
|
||||
import * as ligatures from 'xterm-addon-ligatures-tmp'
|
||||
import { fit } from 'xterm/src/addons/fit/fit'
|
||||
import { enableLigatures } from 'xterm-addon-ligatures'
|
||||
import 'xterm/lib/xterm.css'
|
||||
import './xterm.css'
|
||||
import deepEqual = require('deep-equal')
|
||||
|
||||
Terminal.applyAddon(fit)
|
||||
Terminal.applyAddon(ligatures)
|
||||
|
||||
/** @hidden */
|
||||
export class XTermFrontend extends Frontend {
|
||||
enableResizing = true
|
||||
@@ -25,6 +22,7 @@ export class XTermFrontend extends Frontend {
|
||||
this.xterm = new Terminal({
|
||||
allowTransparency: true,
|
||||
enableBold: true,
|
||||
experimentalCharAtlas: 'dynamic',
|
||||
})
|
||||
this.xtermCore = (this.xterm as any)._core
|
||||
|
||||
@@ -74,7 +72,7 @@ export class XTermFrontend extends Frontend {
|
||||
|
||||
this.resizeHandler = () => {
|
||||
try {
|
||||
(this.xterm as any).fit()
|
||||
fit(this.xterm)
|
||||
} catch {
|
||||
// tends to throw when element wasn't shown yet
|
||||
}
|
||||
@@ -145,11 +143,14 @@ export class XTermFrontend extends Frontend {
|
||||
configure (): void {
|
||||
let config = this.configService.store
|
||||
|
||||
setTimeout(() => {
|
||||
setImmediate(() => {
|
||||
if (this.xterm.cols && this.xterm.rows) {
|
||||
this.xtermCore.charMeasure.measure(this.xtermCore.options)
|
||||
this.xtermCore.renderer._updateDimensions()
|
||||
this.resizeHandler()
|
||||
}
|
||||
})
|
||||
|
||||
this.xterm.setOption('fontFamily', `"${config.terminal.font}", "monospace-fallback", monospace`)
|
||||
this.xterm.setOption('bellStyle', config.terminal.bell)
|
||||
this.xterm.setOption('cursorStyle', {
|
||||
@@ -184,7 +185,7 @@ export class XTermFrontend extends Frontend {
|
||||
}
|
||||
|
||||
if (config.terminal.ligatures && this.xterm.element) {
|
||||
(this.xterm as any).enableLigatures()
|
||||
enableLigatures(this.xterm)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -4,7 +4,7 @@ const webpack = require('webpack')
|
||||
module.exports = {
|
||||
target: 'node',
|
||||
entry: 'src/index.ts',
|
||||
devtool: 'source-map',
|
||||
devtool: 'eval-source-map',
|
||||
context: __dirname,
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
|
@@ -253,10 +253,10 @@ windows-process-tree@^0.2.3:
|
||||
dependencies:
|
||||
nan "^2.10.0"
|
||||
|
||||
xterm-addon-ligatures-tmp@^0.1.0-beta-1:
|
||||
xterm-addon-ligatures@^0.1.0-beta-2:
|
||||
version "0.1.0-beta-2"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-ligatures-tmp/-/xterm-addon-ligatures-tmp-0.1.0-beta-2.tgz#1063a282b279b7586372dee7892cea59738c613e"
|
||||
integrity sha512-d+UoX5dfP7ZSEE/DnQlqubs7Bpw5UxLfTAibpo4pOU2KFw+lRlsLgHg5fcmhXoEvD9rj01enYTsIjedNwnwC5Q==
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-ligatures/-/xterm-addon-ligatures-0.1.0-beta-2.tgz#def635fd0ca671fe61179629f8492b76c66dec6e"
|
||||
integrity sha512-MN5zCBxrF9xagzUYIpcgHS4L/Isod3m3ET5S7AUEEbymLJ+4zccio32eyq65Bcc50x/Bm57Hoh9gaSEUdojs8g==
|
||||
dependencies:
|
||||
font-finder "^1.0.2"
|
||||
font-ligatures "^1.3.1"
|
||||
|
Reference in New Issue
Block a user