Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
01fa1f6c
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
01fa1f6c
编写于
10月 27, 2021
作者:
D
Daniel Imms
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Move onLineData to an xterm addon and test
Part of #133757
上级
4d694341
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
142 addition
and
43 deletion
+142
-43
src/vs/workbench/contrib/terminal/browser/addons/lineDataEventAddon.ts
...nch/contrib/terminal/browser/addons/lineDataEventAddon.ts
+74
-0
src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
...vs/workbench/contrib/terminal/browser/terminalInstance.ts
+9
-43
src/vs/workbench/contrib/terminal/test/browser/addons/lineDataEventAddon.ts
...ontrib/terminal/test/browser/addons/lineDataEventAddon.ts
+59
-0
未找到文件。
src/vs/workbench/contrib/terminal/browser/addons/lineDataEventAddon.ts
0 → 100644
浏览文件 @
01fa1f6c
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
DisposableStore
,
toDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
OperatingSystem
}
from
'
vs/base/common/platform
'
;
import
type
{
Terminal
as
XTermTerminal
,
IBuffer
,
ITerminalAddon
}
from
'
xterm
'
;
/**
* Provides extensions to the xterm object in a modular, testable way.
*/
export
class
LineDataEventAddon
extends
DisposableStore
implements
ITerminalAddon
{
private
_xterm
?:
XTermTerminal
;
private
_isOsSet
=
false
;
private
readonly
_onLineData
=
this
.
add
(
new
Emitter
<
string
>
());
readonly
onLineData
=
this
.
_onLineData
.
event
;
activate
(
xterm
:
XTermTerminal
)
{
this
.
_xterm
=
xterm
;
// Fire onLineData when a line feed occurs, taking into account wrapped lines
xterm
.
onLineFeed
(()
=>
{
const
buffer
=
xterm
.
buffer
;
const
newLine
=
buffer
.
active
.
getLine
(
buffer
.
active
.
baseY
+
buffer
.
active
.
cursorY
);
if
(
newLine
&&
!
newLine
.
isWrapped
)
{
this
.
_sendLineData
(
buffer
.
active
,
buffer
.
active
.
baseY
+
buffer
.
active
.
cursorY
-
1
);
}
});
// Fire onLineData when disposing object to flush last line
this
.
add
(
toDisposable
(()
=>
{
const
buffer
=
xterm
.
buffer
;
this
.
_sendLineData
(
buffer
.
active
,
buffer
.
active
.
baseY
+
buffer
.
active
.
cursorY
);
}));
}
setOperatingSystem
(
os
:
OperatingSystem
)
{
if
(
this
.
_isOsSet
||
!
this
.
_xterm
)
{
return
;
}
this
.
_isOsSet
=
true
;
// Force line data to be sent when the cursor is moved, the main purpose for
// this is because ConPTY will often not do a line feed but instead move the
// cursor, in which case we still want to send the current line's data to tasks.
if
(
os
===
OperatingSystem
.
Windows
)
{
const
xterm
=
this
.
_xterm
;
xterm
.
parser
.
registerCsiHandler
({
final
:
'
H
'
},
()
=>
{
const
buffer
=
xterm
.
buffer
;
this
.
_sendLineData
(
buffer
.
active
,
buffer
.
active
.
baseY
+
buffer
.
active
.
cursorY
);
return
false
;
});
}
}
private
_sendLineData
(
buffer
:
IBuffer
,
lineIndex
:
number
):
void
{
let
line
=
buffer
.
getLine
(
lineIndex
);
if
(
!
line
)
{
return
;
}
let
lineData
=
line
.
translateToString
(
true
);
while
(
lineIndex
>
0
&&
line
.
isWrapped
)
{
line
=
buffer
.
getLine
(
--
lineIndex
);
if
(
!
line
)
{
break
;
}
lineData
=
line
.
translateToString
(
false
)
+
lineData
;
}
this
.
_onLineData
.
fire
(
lineData
);
}
}
src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
浏览文件 @
01fa1f6c
...
...
@@ -73,6 +73,7 @@ import { ISeparator, template } from 'vs/base/common/labels';
import
{
IPathService
}
from
'
vs/workbench/services/path/common/pathService
'
;
import
{
DomScrollableElement
}
from
'
vs/base/browser/ui/scrollbar/scrollableElement
'
;
import
{
ScrollbarVisibility
}
from
'
vs/base/common/scrollable
'
;
import
{
LineDataEventAddon
}
from
'
vs/workbench/contrib/terminal/browser/addons/lineDataEventAddon
'
;
// How long in milliseconds should an average frame take to render for a notification to appear
// which suggests the fallback DOM-based renderer
...
...
@@ -645,6 +646,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
});
this
.
_xterm
=
xterm
;
this
.
_xtermCore
=
(
xterm
as
any
).
_core
as
XTermCore
;
const
lineDataEventAddon
=
new
LineDataEventAddon
();
this
.
_xterm
.
loadAddon
(
lineDataEventAddon
);
this
.
_updateUnicodeVersion
();
this
.
updateAccessibilitySupport
();
this
.
_terminalInstanceService
.
getXtermSearchConstructor
().
then
(
addonCtor
=>
{
...
...
@@ -655,10 +658,10 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
// onLineData events containing initialText
if
(
this
.
_shellLaunchConfig
.
initialText
)
{
this
.
_xterm
.
writeln
(
this
.
_shellLaunchConfig
.
initialText
,
()
=>
{
xterm
.
onLineFeed
(()
=>
this
.
_onLineFeed
(
));
lineDataEventAddon
.
onLineData
(
e
=>
this
.
_onLineData
.
fire
(
e
));
});
}
else
{
this
.
_xterm
.
onLineFeed
(()
=>
this
.
_onLineFeed
(
));
lineDataEventAddon
.
onLineData
(
e
=>
this
.
_onLineData
.
fire
(
e
));
}
// Delay the creation of the bell listener to avoid showing the bell when the terminal
// starts up or reconnects
...
...
@@ -697,15 +700,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
return
;
}
if
(
this
.
_processManager
.
os
)
{
lineDataEventAddon
.
setOperatingSystem
(
this
.
_processManager
.
os
);
}
if
(
this
.
_processManager
.
os
===
OperatingSystem
.
Windows
)
{
xterm
.
setOption
(
'
windowsMode
'
,
processTraits
.
requiresWindowsMode
||
false
);
// Force line data to be sent when the cursor is moved, the main purpose for
// this is because ConPTY will often not do a line feed but instead move the
// cursor, in which case we still want to send the current line's data to tasks.
xterm
.
parser
.
registerCsiHandler
({
final
:
'
H
'
},
()
=>
{
this
.
_onCursorMove
();
return
false
;
});
}
this
.
_linkManager
=
this
.
_instantiationService
.
createInstance
(
TerminalLinkManager
,
xterm
,
this
.
_processManager
!
);
this
.
_areLinksReady
=
true
;
...
...
@@ -1075,11 +1074,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this
.
_horizontalScrollbar
=
undefined
;
}
}
if
(
this
.
_xterm
)
{
const
buffer
=
this
.
_xterm
.
buffer
;
this
.
_sendLineData
(
buffer
.
active
,
buffer
.
active
.
baseY
+
buffer
.
active
.
cursorY
);
this
.
_xterm
.
dispose
();
}
this
.
_xterm
?.
dispose
();
if
(
this
.
_pressAnyKeyToCloseListener
)
{
this
.
_pressAnyKeyToCloseListener
.
dispose
();
...
...
@@ -1525,41 +1520,12 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this
.
reuseTerminal
(
this
.
_shellLaunchConfig
,
true
);
}
private
_onLineFeed
():
void
{
const
buffer
=
this
.
_xterm
!
.
buffer
;
const
newLine
=
buffer
.
active
.
getLine
(
buffer
.
active
.
baseY
+
buffer
.
active
.
cursorY
);
if
(
newLine
&&
!
newLine
.
isWrapped
)
{
this
.
_sendLineData
(
buffer
.
active
,
buffer
.
active
.
baseY
+
buffer
.
active
.
cursorY
-
1
);
}
}
private
_onCursorMove
():
void
{
const
buffer
=
this
.
_xterm
!
.
buffer
;
this
.
_sendLineData
(
buffer
.
active
,
buffer
.
active
.
baseY
+
buffer
.
active
.
cursorY
);
}
private
_onTitleChange
(
title
:
string
):
void
{
if
(
this
.
isTitleSetByProcess
)
{
this
.
refreshTabLabels
(
title
,
TitleEventSource
.
Sequence
);
}
}
private
_sendLineData
(
buffer
:
IBuffer
,
lineIndex
:
number
):
void
{
let
line
=
buffer
.
getLine
(
lineIndex
);
if
(
!
line
)
{
return
;
}
let
lineData
=
line
.
translateToString
(
true
);
while
(
lineIndex
>
0
&&
line
.
isWrapped
)
{
line
=
buffer
.
getLine
(
--
lineIndex
);
if
(
!
line
)
{
break
;
}
lineData
=
line
.
translateToString
(
false
)
+
lineData
;
}
this
.
_onLineData
.
fire
(
lineData
);
}
private
_onKey
(
key
:
string
,
ev
:
KeyboardEvent
):
void
{
const
event
=
new
StandardKeyboardEvent
(
ev
);
...
...
src/vs/workbench/contrib/terminal/test/browser/addons/lineDataEventAddon.ts
0 → 100644
浏览文件 @
01fa1f6c
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
Terminal
}
from
'
xterm
'
;
import
{
LineDataEventAddon
}
from
'
vs/workbench/contrib/terminal/browser/addons/lineDataEventAddon
'
;
import
{
deepStrictEqual
}
from
'
assert
'
;
async
function
writeP
(
terminal
:
Terminal
,
data
:
string
):
Promise
<
void
>
{
return
new
Promise
<
void
>
(
r
=>
terminal
.
write
(
data
,
r
));
}
suite
.
only
(
'
XtermExtensions
'
,
()
=>
{
let
xterm
:
Terminal
;
let
lineDataEventAddon
:
LineDataEventAddon
;
suite
(
'
onLineData
'
,
()
=>
{
let
events
:
string
[];
setup
(()
=>
{
xterm
=
new
Terminal
({
cols
:
4
});
lineDataEventAddon
=
new
LineDataEventAddon
();
xterm
.
loadAddon
(
lineDataEventAddon
);
events
=
[];
lineDataEventAddon
.
onLineData
(
e
=>
events
.
push
(
e
));
});
test
(
'
should fire when a non-wrapped line ends with a
\\
n
'
,
async
()
=>
{
await
writeP
(
xterm
,
'
foo
'
);
deepStrictEqual
(
events
,
[]);
await
writeP
(
xterm
,
'
\n\r
'
);
deepStrictEqual
(
events
,
[
'
foo
'
]);
await
writeP
(
xterm
,
'
bar
'
);
deepStrictEqual
(
events
,
[
'
foo
'
]);
await
writeP
(
xterm
,
'
\n
'
);
deepStrictEqual
(
events
,
[
'
foo
'
,
'
bar
'
]);
});
test
(
'
should not fire soft wrapped lines
'
,
async
()
=>
{
await
writeP
(
xterm
,
'
foo.
'
);
deepStrictEqual
(
events
,
[]);
await
writeP
(
xterm
,
'
bar.
'
);
deepStrictEqual
(
events
,
[]);
await
writeP
(
xterm
,
'
baz.
'
);
deepStrictEqual
(
events
,
[]);
});
test
(
'
should fire when a wrapped line ends with a
\\
n
'
,
async
()
=>
{
await
writeP
(
xterm
,
'
foo.bar.baz.
'
);
deepStrictEqual
(
events
,
[]);
await
writeP
(
xterm
,
'
\n\r
'
);
deepStrictEqual
(
events
,
[
'
foo.bar.baz.
'
]);
});
});
});
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录