Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
17738f76
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
17738f76
编写于
12月 12, 2017
作者:
D
Daniel Imms
提交者:
GitHub
12月 12, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #40122 from Microsoft/tyriar/30685-2
Dynamically import xterm.js
上级
43db454a
a58e51c1
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
110 addition
and
99 deletion
+110
-99
src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts
...bench/parts/terminal/electron-browser/terminalInstance.ts
+108
-98
src/vs/workbench/parts/terminal/test/electron-browser/terminalInstance.test.ts
...s/terminal/test/electron-browser/terminalInstance.test.ts
+2
-1
未找到文件。
src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts
浏览文件 @
17738f76
...
...
@@ -41,10 +41,7 @@ import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspac
/** The amount of time to consider terminal errors to be related to the launch */
const
LAUNCHING_DURATION
=
500
;
// Enable search functionality in xterm.js instance
XTermTerminal
.
loadAddon
(
'
search
'
);
// Enable the winpty compatibility addon which will simulate wraparound mode
XTermTerminal
.
loadAddon
(
'
winptyCompat
'
);
let
Terminal
:
typeof
XTermTerminal
;
enum
ProcessState
{
// The process has not been initialized yet.
...
...
@@ -99,6 +96,7 @@ export class TerminalInstance implements ITerminalInstance {
private
_initialCwd
:
string
;
private
_windowsShellHelper
:
WindowsShellHelper
;
private
_onLineDataListeners
:
((
lineData
:
string
)
=>
void
)[];
private
_xtermReadyPromise
:
TPromise
<
void
>
;
private
_widgetManager
:
TerminalWidgetManager
;
private
_linkHandler
:
TerminalLinkHandler
;
...
...
@@ -154,7 +152,6 @@ export class TerminalInstance implements ITerminalInstance {
this
.
_initDimensions
();
this
.
_createProcess
();
this
.
_createXterm
();
if
(
platform
.
isWindows
)
{
this
.
_processReady
.
then
(()
=>
{
...
...
@@ -164,10 +161,13 @@ export class TerminalInstance implements ITerminalInstance {
});
}
// Only attach xterm.js to the DOM if the terminal panel has been opened before.
if
(
_container
)
{
this
.
attachToElement
(
_container
);
}
this
.
_xtermReadyPromise
=
this
.
_createXterm
();
this
.
_xtermReadyPromise
.
then
(()
=>
{
// Only attach xterm.js to the DOM if the terminal panel has been opened before.
if
(
_container
)
{
this
.
attachToElement
(
_container
);
}
});
}
public
addDisposable
(
disposable
:
lifecycle
.
IDisposable
):
void
{
...
...
@@ -252,9 +252,17 @@ export class TerminalInstance implements ITerminalInstance {
/**
* Create xterm.js instance and attach data listeners.
*/
protected
_createXterm
():
void
{
protected
async
_createXterm
():
TPromise
<
void
>
{
if
(
!
Terminal
)
{
console
.
log
(
'
load xterm now
'
);
Terminal
=
(
await
import
(
'
xterm
'
)).
Terminal
;
// Enable search functionality in xterm.js instance
Terminal
.
loadAddon
(
'
search
'
);
// Enable the winpty compatibility addon which will simulate wraparound mode
Terminal
.
loadAddon
(
'
winptyCompat
'
);
}
const
font
=
this
.
_configHelper
.
getFont
(
true
);
this
.
_xterm
=
new
XTerm
Terminal
({
this
.
_xterm
=
new
Terminal
({
scrollback
:
this
.
_configHelper
.
config
.
scrollback
,
theme
:
this
.
_getXtermTheme
(),
fontFamily
:
font
.
fontFamily
,
...
...
@@ -288,100 +296,102 @@ export class TerminalInstance implements ITerminalInstance {
}
public
attachToElement
(
container
:
HTMLElement
):
void
{
if
(
this
.
_wrapperElement
)
{
throw
new
Error
(
'
The terminal instance has already been attached to a container
'
);
}
this
.
_container
=
container
;
this
.
_wrapperElement
=
document
.
createElement
(
'
div
'
);
dom
.
addClass
(
this
.
_wrapperElement
,
'
terminal-wrapper
'
);
this
.
_xtermElement
=
document
.
createElement
(
'
div
'
);
// Attach the xterm object to the DOM, exposing it to the smoke tests
(
<
any
>
this
.
_wrapperElement
).
xterm
=
this
.
_xterm
;
this
.
_xterm
.
open
(
this
.
_xtermElement
);
this
.
_xterm
.
attachCustomKeyEventHandler
((
event
:
KeyboardEvent
)
=>
{
// Disable all input if the terminal is exiting
if
(
this
.
_isExiting
)
{
return
false
;
this
.
_xtermReadyPromise
.
then
(()
=>
{
if
(
this
.
_wrapperElement
)
{
throw
new
Error
(
'
The terminal instance has already been attached to a container
'
);
}
// Skip processing by xterm.js of keyboard events that resolve to commands described
// within commandsToSkipShell
const
standardKeyboardEvent
=
new
StandardKeyboardEvent
(
event
);
const
resolveResult
=
this
.
_keybindingService
.
softDispatch
(
standardKeyboardEvent
,
standardKeyboardEvent
.
target
);
if
(
resolveResult
&&
this
.
_skipTerminalCommands
.
some
(
k
=>
k
===
resolveResult
.
commandId
))
{
event
.
preventDefault
();
return
false
;
}
// If tab focus mode is on, tab is not passed to the terminal
if
(
TabFocus
.
getTabFocusMode
()
&&
event
.
keyCode
===
9
)
{
return
false
;
}
return
undefined
;
});
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
this
.
_xterm
.
element
,
'
mouseup
'
,
(
event
:
KeyboardEvent
)
=>
{
// Wait until mouseup has propagated through the DOM before
// evaluating the new selection state.
setTimeout
(()
=>
this
.
_refreshSelectionContextKey
(),
0
);
}));
this
.
_container
=
container
;
this
.
_wrapperElement
=
document
.
createElement
(
'
div
'
);
dom
.
addClass
(
this
.
_wrapperElement
,
'
terminal-wrapper
'
);
this
.
_xtermElement
=
document
.
createElement
(
'
div
'
);
// xterm.js currently drops selection on keyup as we need to handle this case.
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
this
.
_xterm
.
element
,
'
keyup
'
,
(
event
:
KeyboardEvent
)
=>
{
// Wait until keyup has propagated through the DOM before evaluating
// the new selection state.
setTimeout
(()
=>
this
.
_refreshSelectionContextKey
(),
0
);
}));
// Attach the xterm object to the DOM, exposing it to the smoke tests
(
<
any
>
this
.
_wrapperElement
).
xterm
=
this
.
_xterm
;
const
xtermHelper
:
HTMLElement
=
<
HTMLElement
>
this
.
_xterm
.
element
.
querySelector
(
'
.xterm-helpers
'
);
const
focusTrap
:
HTMLElement
=
document
.
createElement
(
'
div
'
);
focusTrap
.
setAttribute
(
'
tabindex
'
,
'
0
'
);
dom
.
addClass
(
focusTrap
,
'
focus-trap
'
);
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
focusTrap
,
'
focus
'
,
(
event
:
FocusEvent
)
=>
{
let
currentElement
=
focusTrap
;
while
(
!
dom
.
hasClass
(
currentElement
,
'
part
'
))
{
currentElement
=
currentElement
.
parentElement
;
}
const
hidePanelElement
=
<
HTMLElement
>
currentElement
.
querySelector
(
'
.hide-panel-action
'
);
hidePanelElement
.
focus
();
}));
xtermHelper
.
insertBefore
(
focusTrap
,
this
.
_xterm
.
textarea
);
this
.
_xterm
.
open
(
this
.
_xtermElement
);
this
.
_xterm
.
attachCustomKeyEventHandler
((
event
:
KeyboardEvent
)
=>
{
// Disable all input if the terminal is exiting
if
(
this
.
_isExiting
)
{
return
false
;
}
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
this
.
_xterm
.
textarea
,
'
focus
'
,
(
event
:
KeyboardEvent
)
=>
{
this
.
_terminalFocusContextKey
.
set
(
true
);
}));
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
this
.
_xterm
.
textarea
,
'
blur
'
,
(
event
:
KeyboardEvent
)
=>
{
this
.
_terminalFocusContextKey
.
reset
();
this
.
_refreshSelectionContextKey
();
}));
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
this
.
_xterm
.
element
,
'
focus
'
,
(
event
:
KeyboardEvent
)
=>
{
this
.
_terminalFocusContextKey
.
set
(
true
);
}));
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
this
.
_xterm
.
element
,
'
blur
'
,
(
event
:
KeyboardEvent
)
=>
{
this
.
_terminalFocusContextKey
.
reset
();
this
.
_refreshSelectionContextKey
();
}));
// Skip processing by xterm.js of keyboard events that resolve to commands described
// within commandsToSkipShell
const
standardKeyboardEvent
=
new
StandardKeyboardEvent
(
event
);
const
resolveResult
=
this
.
_keybindingService
.
softDispatch
(
standardKeyboardEvent
,
standardKeyboardEvent
.
target
);
if
(
resolveResult
&&
this
.
_skipTerminalCommands
.
some
(
k
=>
k
===
resolveResult
.
commandId
))
{
event
.
preventDefault
();
return
false
;
}
this
.
_wrapperElement
.
appendChild
(
this
.
_xtermElement
);
this
.
_widgetManager
=
new
TerminalWidgetManager
(
this
.
_wrapperElement
);
this
.
_linkHandler
.
setWidgetManager
(
this
.
_widgetManager
)
;
this
.
_container
.
appendChild
(
this
.
_wrapperElement
);
// If tab focus mode is on, tab is not passed to the terminal
if
(
TabFocus
.
getTabFocusMode
()
&&
event
.
keyCode
===
9
)
{
return
false
;
}
const
computedStyle
=
window
.
getComputedStyle
(
this
.
_container
);
const
width
=
parseInt
(
computedStyle
.
getPropertyValue
(
'
width
'
).
replace
(
'
px
'
,
''
),
10
);
const
height
=
parseInt
(
computedStyle
.
getPropertyValue
(
'
height
'
).
replace
(
'
px
'
,
''
),
10
);
this
.
layout
(
new
Dimension
(
width
,
height
));
this
.
setVisible
(
this
.
_isVisible
);
this
.
updateConfig
();
// If IShellLaunchConfig.waitOnExit was true and the process finished before the terminal
// panel was initialized.
if
(
this
.
_xterm
.
getOption
(
'
disableStdin
'
))
{
this
.
_attachPressAnyKeyToCloseListener
();
}
return
undefined
;
});
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
this
.
_xterm
.
element
,
'
mouseup
'
,
(
event
:
KeyboardEvent
)
=>
{
// Wait until mouseup has propagated through the DOM before
// evaluating the new selection state.
setTimeout
(()
=>
this
.
_refreshSelectionContextKey
(),
0
);
}));
// xterm.js currently drops selection on keyup as we need to handle this case.
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
this
.
_xterm
.
element
,
'
keyup
'
,
(
event
:
KeyboardEvent
)
=>
{
// Wait until keyup has propagated through the DOM before evaluating
// the new selection state.
setTimeout
(()
=>
this
.
_refreshSelectionContextKey
(),
0
);
}));
const
xtermHelper
:
HTMLElement
=
<
HTMLElement
>
this
.
_xterm
.
element
.
querySelector
(
'
.xterm-helpers
'
);
const
focusTrap
:
HTMLElement
=
document
.
createElement
(
'
div
'
);
focusTrap
.
setAttribute
(
'
tabindex
'
,
'
0
'
);
dom
.
addClass
(
focusTrap
,
'
focus-trap
'
);
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
focusTrap
,
'
focus
'
,
(
event
:
FocusEvent
)
=>
{
let
currentElement
=
focusTrap
;
while
(
!
dom
.
hasClass
(
currentElement
,
'
part
'
))
{
currentElement
=
currentElement
.
parentElement
;
}
const
hidePanelElement
=
<
HTMLElement
>
currentElement
.
querySelector
(
'
.hide-panel-action
'
);
hidePanelElement
.
focus
();
}));
xtermHelper
.
insertBefore
(
focusTrap
,
this
.
_xterm
.
textarea
);
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
this
.
_xterm
.
textarea
,
'
focus
'
,
(
event
:
KeyboardEvent
)
=>
{
this
.
_terminalFocusContextKey
.
set
(
true
);
}));
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
this
.
_xterm
.
textarea
,
'
blur
'
,
(
event
:
KeyboardEvent
)
=>
{
this
.
_terminalFocusContextKey
.
reset
();
this
.
_refreshSelectionContextKey
();
}));
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
this
.
_xterm
.
element
,
'
focus
'
,
(
event
:
KeyboardEvent
)
=>
{
this
.
_terminalFocusContextKey
.
set
(
true
);
}));
this
.
_instanceDisposables
.
push
(
dom
.
addDisposableListener
(
this
.
_xterm
.
element
,
'
blur
'
,
(
event
:
KeyboardEvent
)
=>
{
this
.
_terminalFocusContextKey
.
reset
();
this
.
_refreshSelectionContextKey
();
}));
this
.
_wrapperElement
.
appendChild
(
this
.
_xtermElement
);
this
.
_widgetManager
=
new
TerminalWidgetManager
(
this
.
_wrapperElement
);
this
.
_linkHandler
.
setWidgetManager
(
this
.
_widgetManager
);
this
.
_container
.
appendChild
(
this
.
_wrapperElement
);
const
computedStyle
=
window
.
getComputedStyle
(
this
.
_container
);
const
width
=
parseInt
(
computedStyle
.
getPropertyValue
(
'
width
'
).
replace
(
'
px
'
,
''
),
10
);
const
height
=
parseInt
(
computedStyle
.
getPropertyValue
(
'
height
'
).
replace
(
'
px
'
,
''
),
10
);
this
.
layout
(
new
Dimension
(
width
,
height
));
this
.
setVisible
(
this
.
_isVisible
);
this
.
updateConfig
();
// If IShellLaunchConfig.waitOnExit was true and the process finished before the terminal
// panel was initialized.
if
(
this
.
_xterm
.
getOption
(
'
disableStdin
'
))
{
this
.
_attachPressAnyKeyToCloseListener
();
}
});
}
public
registerLinkMatcher
(
regex
:
RegExp
,
handler
:
(
url
:
string
)
=>
void
,
matchIndex
?:
number
,
validationCallback
?:
(
uri
:
string
,
callback
:
(
isValid
:
boolean
)
=>
void
)
=>
void
):
number
{
...
...
src/vs/workbench/parts/terminal/test/electron-browser/terminalInstance.test.ts
浏览文件 @
17738f76
...
...
@@ -20,6 +20,7 @@ import { MockContextKeyService, MockKeybindingService } from 'vs/platform/keybin
import
{
IKeybindingService
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
IContextKeyService
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IHistoryService
}
from
'
vs/workbench/services/history/common/history
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
class
TestTerminalInstance
extends
TerminalInstance
{
public
_getCwd
(
shell
:
IShellLaunchConfig
,
root
:
Uri
):
string
{
...
...
@@ -27,7 +28,7 @@ class TestTerminalInstance extends TerminalInstance {
}
protected
_createProcess
():
void
{
}
protected
_createXterm
():
void
{
}
protected
_createXterm
():
TPromise
<
void
>
{
return
TPromise
.
as
(
void
0
);
}
}
suite
(
'
Workbench - TerminalInstance
'
,
()
=>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录