Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
5dbd0935
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,发现更多精彩内容 >>
提交
5dbd0935
编写于
9月 04, 2018
作者:
S
Sandeep Somavarapu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
#57618: ExtHost: Implement writable output channels using spdlog
上级
a030947f
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
182 addition
and
111 deletion
+182
-111
src/vs/platform/output/node/outputAppender.ts
src/vs/platform/output/node/outputAppender.ts
+24
-0
src/vs/workbench/api/electron-browser/mainThreadOutputService.ts
...workbench/api/electron-browser/mainThreadOutputService.ts
+28
-15
src/vs/workbench/api/node/extHost.api.impl.ts
src/vs/workbench/api/node/extHost.api.impl.ts
+4
-1
src/vs/workbench/api/node/extHost.protocol.ts
src/vs/workbench/api/node/extHost.protocol.ts
+5
-4
src/vs/workbench/api/node/extHostOutputService.ts
src/vs/workbench/api/node/extHostOutputService.ts
+59
-28
src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts
...ts/extensions/electron-browser/extensions.contribution.ts
+1
-1
src/vs/workbench/parts/logs/electron-browser/logs.contribution.ts
...orkbench/parts/logs/electron-browser/logs.contribution.ts
+4
-4
src/vs/workbench/parts/output/browser/outputActions.ts
src/vs/workbench/parts/output/browser/outputActions.ts
+19
-21
src/vs/workbench/parts/output/common/output.ts
src/vs/workbench/parts/output/common/output.ts
+15
-14
src/vs/workbench/parts/output/electron-browser/outputServices.ts
...workbench/parts/output/electron-browser/outputServices.ts
+21
-21
src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts
...vs/workbench/parts/quickopen/browser/viewPickerHandler.ts
+1
-1
src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts
...rkbench/parts/tasks/electron-browser/task.contribution.ts
+1
-1
未找到文件。
src/vs/platform/output/node/outputAppender.ts
0 → 100644
浏览文件 @
5dbd0935
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
RotatingLogger
}
from
'
spdlog
'
;
export
class
OutputAppender
{
private
appender
:
RotatingLogger
;
constructor
(
name
:
string
,
file
:
string
)
{
this
.
appender
=
new
RotatingLogger
(
name
,
file
,
1024
*
1024
*
30
,
1
);
this
.
appender
.
clearFormatters
();
}
append
(
content
:
string
):
void
{
this
.
appender
.
critical
(
content
);
}
flush
():
void
{
this
.
appender
.
flush
();
}
}
\ No newline at end of file
src/vs/workbench/api/electron-browser/mainThreadOutputService.ts
浏览文件 @
5dbd0935
...
...
@@ -11,6 +11,7 @@ import { IPartService } from 'vs/workbench/services/part/common/partService';
import
{
IPanelService
}
from
'
vs/workbench/services/panel/common/panelService
'
;
import
{
MainThreadOutputServiceShape
,
MainContext
,
IExtHostContext
}
from
'
../node/extHost.protocol
'
;
import
{
extHostNamedCustomer
}
from
'
vs/workbench/api/electron-browser/extHostCustomers
'
;
import
{
UriComponents
,
URI
}
from
'
vs/base/common/uri
'
;
@
extHostNamedCustomer
(
MainContext
.
MainThreadOutputService
)
export
class
MainThreadOutputService
implements
MainThreadOutputServiceShape
{
...
...
@@ -34,28 +35,33 @@ export class MainThreadOutputService implements MainThreadOutputServiceShape {
// Leave all the existing channels intact (e.g. might help with troubleshooting)
}
public
$
append
(
channelId
:
string
,
label
:
string
,
value
:
string
):
TPromise
<
void
>
{
this
.
_getChannel
(
channelId
,
label
).
append
(
value
);
return
undefined
;
public
$
register
(
id
:
string
,
label
:
string
,
file
?:
UriComponents
):
TPromise
<
void
>
{
Registry
.
as
<
IOutputChannelRegistry
>
(
Extensions
.
OutputChannels
).
registerChannel
({
id
,
label
,
file
:
file
?
URI
.
revive
(
file
)
:
null
,
log
:
false
}
);
return
TPromise
.
as
(
null
)
;
}
public
$clear
(
channelId
:
string
,
label
:
string
):
TPromise
<
void
>
{
this
.
_getChannel
(
channelId
,
label
).
clear
();
public
$append
(
channelId
:
string
,
value
:
string
):
TPromise
<
void
>
{
const
channel
=
this
.
_getChannel
(
channelId
);
if
(
channel
)
{
channel
.
append
(
value
);
}
return
undefined
;
}
public
$reveal
(
channelId
:
string
,
label
:
string
,
preserveFocus
:
boolean
):
TPromise
<
void
>
{
const
channel
=
this
.
_getChannel
(
channelId
,
label
);
this
.
_outputService
.
showChannel
(
channel
.
id
,
preserveFocus
);
public
$clear
(
channelId
:
string
):
TPromise
<
void
>
{
const
channel
=
this
.
_getChannel
(
channelId
);
if
(
channel
)
{
channel
.
clear
();
}
return
undefined
;
}
private
_getChannel
(
channelId
:
string
,
label
:
string
):
IOutputChannel
{
if
(
!
Registry
.
as
<
IOutputChannelRegistry
>
(
Extensions
.
OutputChannels
).
getChannel
(
channelId
))
{
Registry
.
as
<
IOutputChannelRegistry
>
(
Extensions
.
OutputChannels
).
registerChannel
(
channelId
,
label
);
public
$reveal
(
channelId
:
string
,
preserveFocus
:
boolean
):
TPromise
<
void
>
{
const
channel
=
this
.
_getChannel
(
channelId
);
if
(
channel
)
{
this
.
_outputService
.
showChannel
(
channel
.
id
,
preserveFocus
);
}
return
this
.
_outputService
.
getChannel
(
channelId
);
return
undefined
;
}
public
$close
(
channelId
:
string
):
TPromise
<
void
>
{
...
...
@@ -67,8 +73,15 @@ export class MainThreadOutputService implements MainThreadOutputServiceShape {
return
undefined
;
}
public
$dispose
(
channelId
:
string
,
label
:
string
):
TPromise
<
void
>
{
this
.
_getChannel
(
channelId
,
label
).
dispose
();
public
$dispose
(
channelId
:
string
):
TPromise
<
void
>
{
const
channel
=
this
.
_getChannel
(
channelId
);
if
(
channel
)
{
channel
.
dispose
();
}
return
undefined
;
}
private
_getChannel
(
channelId
:
string
):
IOutputChannel
{
return
this
.
_outputService
.
getChannel
(
channelId
);
}
}
src/vs/workbench/api/node/extHost.api.impl.ts
浏览文件 @
5dbd0935
...
...
@@ -61,6 +61,8 @@ import { ExtHostWebviews } from 'vs/workbench/api/node/extHostWebview';
import
{
ExtHostComments
}
from
'
./extHostComments
'
;
import
{
ExtHostSearch
}
from
'
./extHostSearch
'
;
import
{
ExtHostUrls
}
from
'
./extHostUrls
'
;
import
{
toLocalISOString
}
from
'
vs/base/common/date
'
;
import
{
posix
}
from
'
path
'
;
export
interface
IExtensionApiFactory
{
(
extension
:
IExtensionDescription
):
typeof
vscode
;
...
...
@@ -136,7 +138,8 @@ export function createApiFactory(
const
extHostMessageService
=
new
ExtHostMessageService
(
rpcProtocol
);
const
extHostDialogs
=
new
ExtHostDialogs
(
rpcProtocol
);
const
extHostStatusBar
=
new
ExtHostStatusBar
(
rpcProtocol
);
const
extHostOutputService
=
new
ExtHostOutputService
(
rpcProtocol
);
const
outputDir
=
posix
.
join
(
initData
.
logsPath
,
`output_logging_
${
initData
.
windowId
}
_
${
toLocalISOString
(
new
Date
()).
replace
(
/-|:|
\.\d
+Z$/g
,
''
)}
`
);
const
extHostOutputService
=
new
ExtHostOutputService
(
outputDir
,
rpcProtocol
);
const
extHostLanguages
=
new
ExtHostLanguages
(
rpcProtocol
);
// Register API-ish commands
...
...
src/vs/workbench/api/node/extHost.protocol.ts
浏览文件 @
5dbd0935
...
...
@@ -302,11 +302,12 @@ export interface MainThreadMessageServiceShape extends IDisposable {
}
export
interface
MainThreadOutputServiceShape
extends
IDisposable
{
$
append
(
channelId
:
string
,
label
:
string
,
value
:
string
):
TPromise
<
void
>
;
$
clear
(
channelId
:
string
,
label
:
string
):
TPromise
<
void
>
;
$
dispose
(
channelId
:
string
,
label
:
string
):
TPromise
<
void
>
;
$reveal
(
channelId
:
string
,
label
:
string
,
preserveFocus
:
boolean
):
TPromise
<
void
>
;
$
register
(
channelId
:
string
,
label
:
string
,
file
?:
UriComponents
):
TPromise
<
void
>
;
$
append
(
channelId
:
string
,
value
:
string
):
TPromise
<
void
>
;
$
clear
(
channelId
:
string
):
TPromise
<
void
>
;
$reveal
(
channelId
:
string
,
preserveFocus
:
boolean
):
TPromise
<
void
>
;
$close
(
channelId
:
string
):
TPromise
<
void
>
;
$dispose
(
channelId
:
string
):
TPromise
<
void
>
;
}
export
interface
MainThreadProgressShape
extends
IDisposable
{
...
...
src/vs/workbench/api/node/extHostOutputService.ts
浏览文件 @
5dbd0935
...
...
@@ -6,19 +6,24 @@
import
{
MainContext
,
MainThreadOutputServiceShape
,
IMainContext
}
from
'
./extHost.protocol
'
;
import
*
as
vscode
from
'
vscode
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
posix
}
from
'
path
'
;
import
{
OutputAppender
}
from
'
vs/platform/output/node/outputAppender
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
export
class
ExtHostOutputChannel
implements
vscode
.
OutputChannel
{
export
abstract
class
Abstract
ExtHostOutputChannel
implements
vscode
.
OutputChannel
{
private
static
_idPool
=
1
;
private
_proxy
:
MainThreadOutputServiceShape
;
private
_name
:
string
;
private
_id
:
string
;
protected
readonly
_id
:
string
;
private
readonly
_name
:
string
;
protected
readonly
_proxy
:
MainThreadOutputServiceShape
;
protected
_registerationPromise
:
TPromise
<
void
>
=
TPromise
.
as
(
null
);
private
_disposed
:
boolean
;
constructor
(
name
:
string
,
proxy
:
MainThreadOutputServiceShape
)
{
this
.
_id
=
'
extension-output-#
'
+
(
AbstractExtHostOutputChannel
.
_idPool
++
);
this
.
_name
=
name
;
this
.
_id
=
'
extension-output-#
'
+
(
ExtHostOutputChannel
.
_idPool
++
);
this
.
_proxy
=
proxy
;
}
...
...
@@ -26,18 +31,7 @@ export class ExtHostOutputChannel implements vscode.OutputChannel {
return
this
.
_name
;
}
dispose
():
void
{
if
(
!
this
.
_disposed
)
{
this
.
_proxy
.
$dispose
(
this
.
_id
,
this
.
_name
).
then
(()
=>
{
this
.
_disposed
=
true
;
});
}
}
append
(
value
:
string
):
void
{
this
.
validate
();
this
.
_proxy
.
$append
(
this
.
_id
,
this
.
_name
,
value
);
}
abstract
append
(
value
:
string
):
void
;
appendLine
(
value
:
string
):
void
{
this
.
validate
();
...
...
@@ -46,44 +40,81 @@ export class ExtHostOutputChannel implements vscode.OutputChannel {
clear
():
void
{
this
.
validate
();
this
.
_
proxy
.
$clear
(
this
.
_id
,
this
.
_name
);
this
.
_
registerationPromise
.
then
(()
=>
this
.
_proxy
.
$clear
(
this
.
_id
)
);
}
show
(
columnOrPreserveFocus
?:
vscode
.
ViewColumn
|
boolean
,
preserveFocus
?:
boolean
):
void
{
this
.
validate
();
if
(
typeof
columnOrPreserveFocus
===
'
boolean
'
)
{
preserveFocus
=
columnOrPreserveFocus
;
}
this
.
_proxy
.
$reveal
(
this
.
_id
,
this
.
_name
,
preserveFocus
);
this
.
_registerationPromise
.
then
(()
=>
this
.
_proxy
.
$reveal
(
this
.
_id
,
typeof
columnOrPreserveFocus
===
'
boolean
'
?
columnOrPreserveFocus
:
preserveFocus
));
}
hide
():
void
{
this
.
validate
();
this
.
_
proxy
.
$close
(
this
.
_id
);
this
.
_
registerationPromise
.
then
(()
=>
this
.
_proxy
.
$close
(
this
.
_id
)
);
}
pr
ivate
validate
():
void
{
pr
otected
validate
():
void
{
if
(
this
.
_disposed
)
{
throw
new
Error
(
'
Channel has been closed
'
);
}
}
dispose
():
void
{
if
(
!
this
.
_disposed
)
{
this
.
_registerationPromise
.
then
(()
=>
this
.
_proxy
.
$dispose
(
this
.
_id
))
.
then
(()
=>
this
.
_disposed
=
true
);
}
}
}
export
class
ExtHostOutputChannel
extends
AbstractExtHostOutputChannel
{
constructor
(
name
:
string
,
proxy
:
MainThreadOutputServiceShape
)
{
super
(
name
,
proxy
);
this
.
_registerationPromise
=
proxy
.
$register
(
this
.
_id
,
name
);
}
append
(
value
:
string
):
void
{
this
.
validate
();
this
.
_registerationPromise
.
then
(()
=>
this
.
_proxy
.
$append
(
this
.
_id
,
value
));
}
}
export
class
ExtHostLoggingOutputChannel
extends
AbstractExtHostOutputChannel
{
private
_appender
:
OutputAppender
;
constructor
(
name
:
string
,
outputDir
:
string
,
proxy
:
MainThreadOutputServiceShape
)
{
super
(
name
,
proxy
);
const
file
=
URI
.
file
(
posix
.
join
(
outputDir
,
`
${
this
.
_id
}
.log`
));
this
.
_appender
=
new
OutputAppender
(
this
.
_id
,
file
.
fsPath
);
this
.
_registerationPromise
=
proxy
.
$register
(
this
.
_id
,
this
.
name
,
file
);
}
append
(
value
:
string
):
void
{
this
.
validate
();
this
.
_appender
.
append
(
value
);
}
}
export
class
ExtHostOutputService
{
private
_proxy
:
MainThreadOutputServiceShape
;
private
_outputDir
:
string
;
constructor
(
mainContext
:
IMainContext
)
{
constructor
(
outputDir
:
string
,
mainContext
:
IMainContext
)
{
this
.
_outputDir
=
outputDir
;
this
.
_proxy
=
mainContext
.
getProxy
(
MainContext
.
MainThreadOutputService
);
}
createOutputChannel
(
name
:
string
):
vscode
.
OutputChannel
{
createOutputChannel
(
name
:
string
,
logging
?:
boolean
):
vscode
.
OutputChannel
{
name
=
name
.
trim
();
if
(
!
name
)
{
throw
new
Error
(
'
illegal argument `name`. must not be falsy
'
);
}
else
{
return
new
ExtHostOutputChannel
(
name
,
this
.
_proxy
);
return
logging
?
new
ExtHostLoggingOutputChannel
(
name
,
this
.
_outputDir
,
this
.
_proxy
)
:
new
ExtHostOutputChannel
(
name
,
this
.
_proxy
);
}
}
}
src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts
浏览文件 @
5dbd0935
...
...
@@ -55,7 +55,7 @@ workbenchRegistry.registerWorkbenchContribution(KeymapExtensions, LifecyclePhase
workbenchRegistry
.
registerWorkbenchContribution
(
ExtensionsViewletViewsContribution
,
LifecyclePhase
.
Starting
);
Registry
.
as
<
IOutputChannelRegistry
>
(
OutputExtensions
.
OutputChannels
)
.
registerChannel
(
ExtensionsChannelId
,
ExtensionsLabel
);
.
registerChannel
(
{
id
:
ExtensionsChannelId
,
label
:
ExtensionsLabel
,
log
:
false
}
);
// Quickopen
Registry
.
as
<
IQuickOpenRegistry
>
(
Extensions
.
Quickopen
).
registerQuickOpenHandler
(
...
...
src/vs/workbench/parts/logs/electron-browser/logs.contribution.ts
浏览文件 @
5dbd0935
...
...
@@ -29,10 +29,10 @@ class LogOutputChannels extends Disposable implements IWorkbenchContribution {
)
{
super
();
let
outputChannelRegistry
=
Registry
.
as
<
IOutputChannelRegistry
>
(
OutputExt
.
OutputChannels
);
outputChannelRegistry
.
registerChannel
(
Constants
.
mainLogChannelId
,
nls
.
localize
(
'
mainLog
'
,
"
Log (Main)
"
),
URI
.
file
(
join
(
this
.
environmentService
.
logsPath
,
`main.log`
))
);
outputChannelRegistry
.
registerChannel
(
Constants
.
sharedLogChannelId
,
nls
.
localize
(
'
sharedLog
'
,
"
Log (Shared)
"
),
URI
.
file
(
join
(
this
.
environmentService
.
logsPath
,
`sharedprocess.log`
))
);
outputChannelRegistry
.
registerChannel
(
Constants
.
rendererLogChannelId
,
nls
.
localize
(
'
rendererLog
'
,
"
Log (Window)
"
),
URI
.
file
(
join
(
this
.
environmentService
.
logsPath
,
`renderer
${
this
.
windowService
.
getCurrentWindowId
()}
.log`
))
);
outputChannelRegistry
.
registerChannel
(
Constants
.
extHostLogChannelId
,
nls
.
localize
(
'
extensionsLog
'
,
"
Log (Extension Host)
"
),
URI
.
file
(
join
(
this
.
environmentService
.
logsPath
,
`exthost
${
this
.
windowService
.
getCurrentWindowId
()}
.log`
))
);
outputChannelRegistry
.
registerChannel
(
{
id
:
Constants
.
mainLogChannelId
,
label
:
nls
.
localize
(
'
mainLog
'
,
"
Log (Main)
"
),
file
:
URI
.
file
(
join
(
this
.
environmentService
.
logsPath
,
`main.log`
)),
log
:
true
}
);
outputChannelRegistry
.
registerChannel
(
{
id
:
Constants
.
sharedLogChannelId
,
label
:
nls
.
localize
(
'
sharedLog
'
,
"
Log (Shared)
"
),
file
:
URI
.
file
(
join
(
this
.
environmentService
.
logsPath
,
`sharedprocess.log`
)),
log
:
true
}
);
outputChannelRegistry
.
registerChannel
(
{
id
:
Constants
.
rendererLogChannelId
,
label
:
nls
.
localize
(
'
rendererLog
'
,
"
Log (Window)
"
),
file
:
URI
.
file
(
join
(
this
.
environmentService
.
logsPath
,
`renderer
${
this
.
windowService
.
getCurrentWindowId
()}
.log`
)),
log
:
true
}
);
outputChannelRegistry
.
registerChannel
(
{
id
:
Constants
.
extHostLogChannelId
,
label
:
nls
.
localize
(
'
extensionsLog
'
,
"
Log (Extension Host)
"
),
file
:
URI
.
file
(
join
(
this
.
environmentService
.
logsPath
,
`exthost
${
this
.
windowService
.
getCurrentWindowId
()}
.log`
)),
log
:
true
}
);
const
workbenchActionsRegistry
=
Registry
.
as
<
IWorkbenchActionRegistry
>
(
WorkbenchActionExtensions
.
WorkbenchActions
);
const
devCategory
=
nls
.
localize
(
'
developer
'
,
"
Developer
"
);
...
...
src/vs/workbench/parts/output/browser/outputActions.ts
浏览文件 @
5dbd0935
...
...
@@ -8,7 +8,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import
*
as
nls
from
'
vs/nls
'
;
import
*
as
aria
from
'
vs/base/browser/ui/aria/aria
'
;
import
{
IAction
,
Action
}
from
'
vs/base/common/actions
'
;
import
{
IOutputService
,
OUTPUT_PANEL_ID
,
IOutputChannelRegistry
,
Extensions
as
OutputExt
,
IOutputChannel
Identifie
r
,
COMMAND_OPEN_LOG_VIEWER
}
from
'
vs/workbench/parts/output/common/output
'
;
import
{
IOutputService
,
OUTPUT_PANEL_ID
,
IOutputChannelRegistry
,
Extensions
as
OutputExt
,
IOutputChannel
Descripto
r
,
COMMAND_OPEN_LOG_VIEWER
}
from
'
vs/workbench/parts/output/common/output
'
;
import
{
SelectActionItem
}
from
'
vs/base/browser/ui/actionbar/actionbar
'
;
import
{
IPartService
}
from
'
vs/workbench/services/part/common/partService
'
;
import
{
IPanelService
}
from
'
vs/workbench/services/panel/common/panelService
'
;
...
...
@@ -20,7 +20,6 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView
import
{
Registry
}
from
'
vs/platform/registry/common/platform
'
;
import
{
groupBy
}
from
'
vs/base/common/arrays
'
;
import
{
ICommandService
}
from
'
vs/platform/commands/common/commands
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
export
class
ToggleOutputAction
extends
TogglePanelAction
{
...
...
@@ -112,8 +111,8 @@ export class SwitchOutputActionItem extends SelectActionItem {
private
static
readonly
SEPARATOR
=
'
─────────
'
;
private
normalChannels
:
IOutputChannelIdentifie
r
[];
private
fileChannels
:
IOutputChannelIdentifie
r
[];
private
outputChannels
:
IOutputChannelDescripto
r
[];
private
logChannels
:
IOutputChannelDescripto
r
[];
constructor
(
action
:
IAction
,
...
...
@@ -133,30 +132,30 @@ export class SwitchOutputActionItem extends SelectActionItem {
}
protected
getActionContext
(
option
:
string
,
index
:
number
):
string
{
const
channel
=
index
<
this
.
normalChannels
.
length
?
this
.
normalChannels
[
index
]
:
this
.
fileChannels
[
index
-
this
.
normal
Channels
.
length
-
1
];
const
channel
=
index
<
this
.
outputChannels
.
length
?
this
.
outputChannels
[
index
]
:
this
.
logChannels
[
index
-
this
.
output
Channels
.
length
-
1
];
return
channel
?
channel
.
id
:
option
;
}
private
updateOtions
(
selectedChannel
:
string
):
void
{
const
groups
=
groupBy
(
this
.
outputService
.
getChannel
s
(),
(
c1
:
IOutputChannelIdentifier
,
c2
:
IOutputChannelIdentifie
r
)
=>
{
if
(
!
c1
.
file
&&
c2
.
file
)
{
const
groups
=
groupBy
(
this
.
outputService
.
getChannel
Descriptors
(),
(
c1
:
IOutputChannelDescriptor
,
c2
:
IOutputChannelDescripto
r
)
=>
{
if
(
!
c1
.
log
&&
c2
.
log
)
{
return
-
1
;
}
if
(
c1
.
file
&&
!
c2
.
file
)
{
if
(
c1
.
log
&&
!
c2
.
log
)
{
return
1
;
}
return
0
;
});
this
.
normal
Channels
=
groups
[
0
]
||
[];
this
.
file
Channels
=
groups
[
1
]
||
[];
const
showSeparator
=
this
.
normalChannels
.
length
&&
this
.
file
Channels
.
length
;
const
separatorIndex
=
showSeparator
?
this
.
normal
Channels
.
length
:
-
1
;
const
options
:
string
[]
=
[...
this
.
normalChannels
.
map
(
c
=>
c
.
label
),
...(
showSeparator
?
[
SwitchOutputActionItem
.
SEPARATOR
]
:
[]),
...
this
.
file
Channels
.
map
(
c
=>
c
.
label
)];
this
.
output
Channels
=
groups
[
0
]
||
[];
this
.
log
Channels
=
groups
[
1
]
||
[];
const
showSeparator
=
this
.
outputChannels
.
length
&&
this
.
log
Channels
.
length
;
const
separatorIndex
=
showSeparator
?
this
.
output
Channels
.
length
:
-
1
;
const
options
:
string
[]
=
[...
this
.
outputChannels
.
map
(
c
=>
c
.
label
),
...(
showSeparator
?
[
SwitchOutputActionItem
.
SEPARATOR
]
:
[]),
...
this
.
log
Channels
.
map
(
c
=>
c
.
label
)];
let
selected
=
0
;
if
(
selectedChannel
)
{
selected
=
this
.
normal
Channels
.
map
(
c
=>
c
.
id
).
indexOf
(
selectedChannel
);
selected
=
this
.
output
Channels
.
map
(
c
=>
c
.
id
).
indexOf
(
selectedChannel
);
if
(
selected
===
-
1
)
{
selected
=
separatorIndex
+
1
+
this
.
file
Channels
.
map
(
c
=>
c
.
id
).
indexOf
(
selectedChannel
);
selected
=
separatorIndex
+
1
+
this
.
log
Channels
.
map
(
c
=>
c
.
id
).
indexOf
(
selectedChannel
);
}
}
this
.
setOptions
(
options
,
Math
.
max
(
0
,
selected
),
separatorIndex
!==
-
1
?
separatorIndex
:
void
0
);
...
...
@@ -180,17 +179,16 @@ export class OpenLogOutputFile extends Action {
}
private
update
():
void
{
const
logFile
=
this
.
getActiveLogChannelFile
();
this
.
enabled
=
!!
logFile
;
this
.
enabled
=
this
.
isLogChannel
();
}
public
run
():
TPromise
<
any
>
{
return
this
.
commandService
.
executeCommand
(
COMMAND_OPEN_LOG_VIEWER
,
this
.
getActiveLogChannelFile
());
return
this
.
commandService
.
executeCommand
(
COMMAND_OPEN_LOG_VIEWER
,
this
.
isLogChannel
());
}
private
getActiveLogChannelFile
():
URI
{
private
isLogChannel
():
boolean
{
const
channel
=
this
.
outputService
.
getActiveChannel
();
const
identifier
=
channel
?
this
.
outputService
.
getChannel
s
().
filter
(
c
=>
c
.
id
===
channel
.
id
)[
0
]
:
null
;
return
identifier
?
identifier
.
file
:
null
;
const
descriptor
=
channel
?
this
.
outputService
.
getChannelDescriptor
s
().
filter
(
c
=>
c
.
id
===
channel
.
id
)[
0
]
:
null
;
return
descriptor
&&
descriptor
.
log
;
}
}
src/vs/workbench/parts/output/common/output.ts
浏览文件 @
5dbd0935
...
...
@@ -78,9 +78,9 @@ export interface IOutputService {
getChannel
(
id
:
string
):
IOutputChannel
;
/**
* Returns an array of all known output channels
as identifie
rs.
* Returns an array of all known output channels
descripto
rs.
*/
getChannel
s
():
IOutputChannelIdentifie
r
[];
getChannel
Descriptors
():
IOutputChannelDescripto
r
[];
/**
* Returns the currently active channel.
...
...
@@ -132,9 +132,10 @@ export interface IOutputChannel {
dispose
():
void
;
}
export
interface
IOutputChannel
Identifie
r
{
export
interface
IOutputChannel
Descripto
r
{
id
:
string
;
label
:
string
;
log
:
boolean
;
file
?:
URI
;
}
...
...
@@ -146,17 +147,17 @@ export interface IOutputChannelRegistry {
/**
* Make an output channel known to the output world.
*/
registerChannel
(
id
:
string
,
name
:
string
,
file
?:
URI
):
void
;
registerChannel
(
descriptor
:
IOutputChannelDescriptor
):
void
;
/**
* Returns the list of channels known to the output world.
*/
getChannels
():
IOutputChannel
Identifie
r
[];
getChannels
():
IOutputChannel
Descripto
r
[];
/**
* Returns the channel with the passed id.
*/
getChannel
(
id
:
string
):
IOutputChannel
Identifie
r
;
getChannel
(
id
:
string
):
IOutputChannel
Descripto
r
;
/**
* Remove the output channel with the passed id.
...
...
@@ -165,7 +166,7 @@ export interface IOutputChannelRegistry {
}
class
OutputChannelRegistry
implements
IOutputChannelRegistry
{
private
channels
=
new
Map
<
string
,
IOutputChannel
Identifie
r
>
();
private
channels
=
new
Map
<
string
,
IOutputChannel
Descripto
r
>
();
private
readonly
_onDidRegisterChannel
:
Emitter
<
string
>
=
new
Emitter
<
string
>
();
readonly
onDidRegisterChannel
:
Event
<
string
>
=
this
.
_onDidRegisterChannel
.
event
;
...
...
@@ -173,20 +174,20 @@ class OutputChannelRegistry implements IOutputChannelRegistry {
private
readonly
_onDidRemoveChannel
:
Emitter
<
string
>
=
new
Emitter
<
string
>
();
readonly
onDidRemoveChannel
:
Event
<
string
>
=
this
.
_onDidRemoveChannel
.
event
;
public
registerChannel
(
id
:
string
,
label
:
string
,
file
?:
URI
):
void
{
if
(
!
this
.
channels
.
has
(
id
))
{
this
.
channels
.
set
(
id
,
{
id
,
label
,
file
}
);
this
.
_onDidRegisterChannel
.
fire
(
id
);
public
registerChannel
(
descriptor
:
IOutputChannelDescriptor
):
void
{
if
(
!
this
.
channels
.
has
(
descriptor
.
id
))
{
this
.
channels
.
set
(
descriptor
.
id
,
descriptor
);
this
.
_onDidRegisterChannel
.
fire
(
descriptor
.
id
);
}
}
public
getChannels
():
IOutputChannel
Identifie
r
[]
{
const
result
:
IOutputChannel
Identifie
r
[]
=
[];
public
getChannels
():
IOutputChannel
Descripto
r
[]
{
const
result
:
IOutputChannel
Descripto
r
[]
=
[];
this
.
channels
.
forEach
(
value
=>
result
.
push
(
value
));
return
result
;
}
public
getChannel
(
id
:
string
):
IOutputChannel
Identifie
r
{
public
getChannel
(
id
:
string
):
IOutputChannel
Descripto
r
{
return
this
.
channels
.
get
(
id
);
}
...
...
src/vs/workbench/parts/output/electron-browser/outputServices.ts
浏览文件 @
5dbd0935
...
...
@@ -15,7 +15,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import
{
IStorageService
,
StorageScope
}
from
'
vs/platform/storage/common/storage
'
;
import
{
Registry
}
from
'
vs/platform/registry/common/platform
'
;
import
{
EditorOptions
}
from
'
vs/workbench/common/editor
'
;
import
{
IOutputChannel
Identifie
r
,
IOutputChannel
,
IOutputService
,
Extensions
,
OUTPUT_PANEL_ID
,
IOutputChannelRegistry
,
OUTPUT_SCHEME
,
OUTPUT_MIME
,
LOG_SCHEME
,
LOG_MIME
,
CONTEXT_ACTIVE_LOG_OUTPUT
}
from
'
vs/workbench/parts/output/common/output
'
;
import
{
IOutputChannel
Descripto
r
,
IOutputChannel
,
IOutputService
,
Extensions
,
OUTPUT_PANEL_ID
,
IOutputChannelRegistry
,
OUTPUT_SCHEME
,
OUTPUT_MIME
,
LOG_SCHEME
,
LOG_MIME
,
CONTEXT_ACTIVE_LOG_OUTPUT
}
from
'
vs/workbench/parts/output/common/output
'
;
import
{
OutputPanel
}
from
'
vs/workbench/parts/output/browser/outputPanel
'
;
import
{
IPanelService
}
from
'
vs/workbench/services/panel/common/panelService
'
;
import
{
IModelService
}
from
'
vs/editor/common/services/modelService
'
;
...
...
@@ -31,7 +31,6 @@ import { IFileService } from 'vs/platform/files/common/files';
import
{
IPanel
}
from
'
vs/workbench/common/panel
'
;
import
{
ResourceEditorInput
}
from
'
vs/workbench/common/editor/resourceEditorInput
'
;
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
import
{
RotatingLogger
}
from
'
spdlog
'
;
import
{
toLocalISOString
}
from
'
vs/base/common/date
'
;
import
{
IWindowService
}
from
'
vs/platform/windows/common/windows
'
;
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
...
...
@@ -39,6 +38,7 @@ import { Schemas } from 'vs/base/common/network';
import
{
ILifecycleService
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
IContextKeyService
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
CancellationToken
}
from
'
vs/base/common/cancellation
'
;
import
{
OutputAppender
}
from
'
vs/platform/output/node/outputAppender
'
;
const
OUTPUT_ACTIVE_CHANNEL_KEY
=
'
output.activechannel
'
;
...
...
@@ -83,6 +83,7 @@ abstract class AbstractFileOutputChannel extends Disposable {
protected
_onDispose
:
Emitter
<
void
>
=
new
Emitter
<
void
>
();
readonly
onDispose
:
Event
<
void
>
=
this
.
_onDispose
.
event
;
private
readonly
mimeType
:
string
;
protected
modelUpdater
:
RunOnceScheduler
;
protected
model
:
ITextModel
;
readonly
file
:
URI
;
...
...
@@ -91,25 +92,25 @@ abstract class AbstractFileOutputChannel extends Disposable {
protected
endOffset
:
number
=
0
;
constructor
(
protected
readonly
outputChannel
Identifier
:
IOutputChannelIdentifie
r
,
protected
readonly
outputChannel
Descriptor
:
IOutputChannelDescripto
r
,
private
readonly
modelUri
:
URI
,
private
mimeType
:
string
,
protected
fileService
:
IFileService
,
protected
modelService
:
IModelService
,
protected
modeService
:
IModeService
,
)
{
super
();
this
.
file
=
this
.
outputChannelIdentifier
.
file
;
this
.
mimeType
=
outputChannelDescriptor
.
log
?
LOG_MIME
:
OUTPUT_MIME
;
this
.
file
=
this
.
outputChannelDescriptor
.
file
;
this
.
modelUpdater
=
new
RunOnceScheduler
(()
=>
this
.
updateModel
(),
300
);
this
.
_register
(
toDisposable
(()
=>
this
.
modelUpdater
.
cancel
()));
}
get
id
():
string
{
return
this
.
outputChannel
Identifie
r
.
id
;
return
this
.
outputChannel
Descripto
r
.
id
;
}
get
label
():
string
{
return
this
.
outputChannel
Identifie
r
.
label
;
return
this
.
outputChannel
Descripto
r
.
label
;
}
clear
():
void
{
...
...
@@ -162,14 +163,14 @@ abstract class AbstractFileOutputChannel extends Disposable {
*/
class
OutputChannelBackedByFile
extends
AbstractFileOutputChannel
implements
OutputChannel
{
private
outputWriter
:
RotatingLogg
er
;
private
appender
:
OutputAppend
er
;
private
appendedMessage
=
''
;
private
loadingFromFileInProgress
:
boolean
=
false
;
private
resettingDelayer
:
ThrottledDelayer
<
void
>
;
private
readonly
rotatingFilePath
:
string
;
constructor
(
outputChannel
Identifier
:
IOutputChannelIdentifie
r
,
outputChannel
Descriptor
:
IOutputChannelDescripto
r
,
outputDir
:
string
,
modelUri
:
URI
,
@
IFileService
fileService
:
IFileService
,
...
...
@@ -177,12 +178,11 @@ class OutputChannelBackedByFile extends AbstractFileOutputChannel implements Out
@
IModeService
modeService
:
IModeService
,
@
ILogService
logService
:
ILogService
)
{
super
({
...
outputChannel
Identifier
,
file
:
URI
.
file
(
paths
.
join
(
outputDir
,
`
${
outputChannelIdentifier
.
id
}
.log`
))
},
modelUri
,
OUTPUT_MIME
,
fileService
,
modelService
,
modeService
);
super
({
...
outputChannel
Descriptor
,
file
:
URI
.
file
(
paths
.
join
(
outputDir
,
`
${
outputChannelDescriptor
.
id
}
.log`
))
},
modelUri
,
fileService
,
modelService
,
modeService
);
// Use one rotating file to check for main file reset
this
.
outputWriter
=
new
RotatingLogger
(
this
.
id
,
this
.
file
.
fsPath
,
1024
*
1024
*
30
,
1
);
this
.
outputWriter
.
clearFormatters
();
this
.
rotatingFilePath
=
`
${
outputChannelIdentifier
.
id
}
.1.log`
;
this
.
appender
=
new
OutputAppender
(
this
.
id
,
this
.
file
.
fsPath
);
this
.
rotatingFilePath
=
`
${
outputChannelDescriptor
.
id
}
.1.log`
;
this
.
_register
(
watchOutputDirectory
(
paths
.
dirname
(
this
.
file
.
fsPath
),
logService
,
(
eventType
,
file
)
=>
this
.
onFileChangedInOutputDirector
(
eventType
,
file
)));
this
.
resettingDelayer
=
new
ThrottledDelayer
<
void
>
(
50
);
...
...
@@ -264,11 +264,11 @@ class OutputChannelBackedByFile extends AbstractFileOutputChannel implements Out
}
private
write
(
content
:
string
):
void
{
this
.
outputWriter
.
critical
(
content
);
this
.
appender
.
append
(
content
);
}
private
flush
():
void
{
this
.
outputWrit
er
.
flush
();
this
.
append
er
.
flush
();
}
}
...
...
@@ -323,14 +323,14 @@ class FileOutputChannel extends AbstractFileOutputChannel implements OutputChann
private
updateInProgress
:
boolean
=
false
;
constructor
(
outputChannel
Identifier
:
IOutputChannelIdentifie
r
,
outputChannel
Descriptor
:
IOutputChannelDescripto
r
,
modelUri
:
URI
,
@
IFileService
fileService
:
IFileService
,
@
IModelService
modelService
:
IModelService
,
@
IModeService
modeService
:
IModeService
,
@
ILogService
logService
:
ILogService
,
)
{
super
(
outputChannel
Identifier
,
modelUri
,
LOG_MIME
,
fileService
,
modelService
,
modeService
);
super
(
outputChannel
Descriptor
,
modelUri
,
fileService
,
modelService
,
modeService
);
this
.
fileHandler
=
this
.
_register
(
new
OutputFileListener
(
this
.
file
,
this
.
fileService
));
this
.
_register
(
this
.
fileHandler
.
onDidContentChange
(()
=>
this
.
onDidContentChange
()));
...
...
@@ -426,7 +426,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo
// Set active channel to first channel if not set
if
(
!
this
.
activeChannel
)
{
const
channels
=
this
.
getChannels
();
const
channels
=
this
.
getChannel
Descriptor
s
();
this
.
activeChannel
=
channels
&&
channels
.
length
>
0
?
this
.
getChannel
(
channels
[
0
].
id
)
:
null
;
}
...
...
@@ -461,7 +461,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo
return
this
.
channels
.
get
(
id
);
}
getChannel
s
():
IOutputChannelIdentifie
r
[]
{
getChannel
Descriptors
():
IOutputChannelDescripto
r
[]
{
return
Registry
.
as
<
IOutputChannelRegistry
>
(
Extensions
.
OutputChannels
).
getChannels
();
}
...
...
@@ -521,7 +521,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo
channel
.
onDispose
(()
=>
{
Registry
.
as
<
IOutputChannelRegistry
>
(
Extensions
.
OutputChannels
).
removeChannel
(
id
);
if
(
this
.
activeChannel
===
channel
)
{
const
channels
=
this
.
getChannels
();
const
channels
=
this
.
getChannel
Descriptor
s
();
if
(
this
.
isPanelShown
()
&&
channels
.
length
)
{
this
.
doShowChannel
(
this
.
getChannel
(
channels
[
0
].
id
),
true
);
this
.
_onActiveOutputChannel
.
fire
(
channels
[
0
].
id
);
...
...
@@ -610,7 +610,7 @@ export class LogContentProvider {
let
channel
=
this
.
channels
.
get
(
id
);
if
(
!
channel
)
{
const
channelDisposables
:
IDisposable
[]
=
[];
channel
=
this
.
instantiationService
.
createInstance
(
FileOutputChannel
,
{
id
,
label
:
''
,
file
:
resource
.
with
({
scheme
:
Schemas
.
file
})
},
resource
);
channel
=
this
.
instantiationService
.
createInstance
(
FileOutputChannel
,
{
id
,
label
:
''
,
file
:
resource
.
with
({
scheme
:
Schemas
.
file
})
,
log
:
true
},
resource
);
channel
.
onDispose
(()
=>
dispose
(
channelDisposables
),
channelDisposables
);
this
.
channels
.
set
(
id
,
channel
);
}
...
...
src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts
浏览文件 @
5dbd0935
...
...
@@ -167,7 +167,7 @@ export class ViewPickerHandler extends QuickOpenHandler {
});
// Output Channels
const
channels
=
this
.
outputService
.
getChannels
();
const
channels
=
this
.
outputService
.
getChannel
Descriptor
s
();
channels
.
forEach
((
channel
,
index
)
=>
{
const
outputCategory
=
nls
.
localize
(
'
channels
'
,
"
Output
"
);
const
entry
=
new
ViewEntry
(
channel
.
label
,
outputCategory
,
()
=>
this
.
outputService
.
showChannel
(
channel
.
id
));
...
...
src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts
浏览文件 @
5dbd0935
...
...
@@ -2503,7 +2503,7 @@ MenuRegistry.addCommand({ id: 'workbench.action.tasks.configureDefaultTestTask',
// Tasks Output channel. Register it before using it in Task Service.
let
outputChannelRegistry
=
Registry
.
as
<
IOutputChannelRegistry
>
(
OutputExt
.
OutputChannels
);
outputChannelRegistry
.
registerChannel
(
TaskService
.
OutputChannelId
,
TaskService
.
OutputChannelLabel
);
outputChannelRegistry
.
registerChannel
(
{
id
:
TaskService
.
OutputChannelId
,
label
:
TaskService
.
OutputChannelLabel
,
log
:
false
}
);
// Task Service
registerSingleton
(
ITaskService
,
TaskService
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录