Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
76b54755
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,发现更多精彩内容 >>
未验证
提交
76b54755
编写于
6月 18, 2019
作者:
D
Daniel Imms
提交者:
GitHub
6月 18, 2019
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #75644 from microsoft/tyriar/75456_windows_term
Support Windows on web
上级
da1061a2
331da82a
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
201 addition
and
173 deletion
+201
-173
remote/package.json
remote/package.json
+6
-5
remote/yarn.lock
remote/yarn.lock
+13
-11
src/vs/workbench/api/browser/mainThreadTerminalService.ts
src/vs/workbench/api/browser/mainThreadTerminalService.ts
+32
-27
src/vs/workbench/api/common/extHost.protocol.ts
src/vs/workbench/api/common/extHost.protocol.ts
+6
-0
src/vs/workbench/api/node/extHostTerminalService.ts
src/vs/workbench/api/node/extHostTerminalService.ts
+9
-3
src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts
...rkbench/contrib/terminal/browser/terminal.contribution.ts
+1
-3
src/vs/workbench/contrib/terminal/browser/terminalActions.ts
src/vs/workbench/contrib/terminal/browser/terminalActions.ts
+8
-14
src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts
...rkbench/contrib/terminal/browser/terminalNativeService.ts
+0
-4
src/vs/workbench/contrib/terminal/browser/terminalService.ts
src/vs/workbench/contrib/terminal/browser/terminalService.ts
+6
-2
src/vs/workbench/contrib/terminal/common/terminal.ts
src/vs/workbench/contrib/terminal/common/terminal.ts
+8
-1
src/vs/workbench/contrib/terminal/common/terminalService.ts
src/vs/workbench/contrib/terminal/common/terminalService.ts
+31
-2
src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts
...ontrib/terminal/electron-browser/terminalNativeService.ts
+0
-99
src/vs/workbench/contrib/terminal/node/terminal.ts
src/vs/workbench/contrib/terminal/node/terminal.ts
+81
-2
未找到文件。
remote/package.json
浏览文件 @
76b54755
...
...
@@ -12,7 +12,7 @@
"keytar"
:
"4.2.1"
,
"minimist"
:
"1.2.0"
,
"native-watchdog"
:
"1.0.0"
,
"node-pty"
:
"0.
8.1
"
,
"node-pty"
:
"0.
9.0-beta17
"
,
"onigasm-umd"
:
"^2.2.2"
,
"semver"
:
"^5.5.0"
,
"spdlog"
:
"^0.9.0"
,
...
...
@@ -21,13 +21,14 @@
"vscode-proxy-agent"
:
"0.4.0"
,
"vscode-ripgrep"
:
"^1.2.5"
,
"vscode-textmate"
:
"^4.1.1"
,
"yauzl"
:
"^2.9.2"
,
"yazl"
:
"^2.4.3"
,
"xterm"
:
"3.15.0-beta34"
,
"xterm-addon-search"
:
"0.1.0-beta6"
,
"xterm-addon-web-links"
:
"0.1.0-beta10"
"xterm-addon-web-links"
:
"0.1.0-beta10"
,
"yauzl"
:
"^2.9.2"
,
"yazl"
:
"^2.4.3"
},
"optionalDependencies"
:
{
"vscode-windows-ca-certs"
:
"0.1.0"
"vscode-windows-ca-certs"
:
"0.1.0"
,
"vscode-windows-registry"
:
"1.0.1"
}
}
remote/yarn.lock
浏览文件 @
76b54755
...
...
@@ -599,11 +599,6 @@ ms@2.0.0:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
nan@2.12.1:
version "2.12.1"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552"
integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==
nan@2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
...
...
@@ -614,7 +609,7 @@ nan@^2.10.0:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099"
integrity sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==
nan@^2.12.1, nan@^2.14.0:
nan@^2.12.1, nan@^2.1
3.2, nan@^2.1
4.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
...
...
@@ -636,12 +631,12 @@ node-addon-api@1.6.2:
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.6.2.tgz#d8aad9781a5cfc4132cc2fecdbdd982534265217"
integrity sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA==
node-pty@0.
8.1
:
version "0.
8.1
"
resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.
8.1.tgz#94b457bec013e7a09b8d9141f63b0787fa25c23f
"
integrity sha512-
j+/g0Q5dR+vkELclpJpz32HcS3O/3EdPSGPvDXJZVJQLCvgG0toEbfmymxAEyQyZEpaoKHAcoL+PvKM+4N9nlw
==
node-pty@0.
9.0-beta17
:
version "0.
9.0-beta17
"
resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.
9.0-beta17.tgz#9b490df86a8124dea595e9fbedeaaf4b2eedbbcb
"
integrity sha512-
E94XwIs3JxLKAboquHY9Kytbbj/T/tJtRpQoAUdfPE7UXRta/NV+xdmRNhZkeU9jCji+plm656GbYFievgNPkQ
==
dependencies:
nan "
2.12.1
"
nan "
^2.13.2
"
noop-logger@^0.1.1:
version "0.1.1"
...
...
@@ -1117,6 +1112,13 @@ vscode-windows-ca-certs@0.1.0:
dependencies:
node-addon-api "1.6.2"
vscode-windows-registry@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/vscode-windows-registry/-/vscode-windows-registry-1.0.1.tgz#bc9f765563eb6dc1c9ad9a41f9eaacc84dfadc7c"
integrity sha512-q0aKXi9Py1OBdmXIJJFeJBzpPJMMUxMJNBU9FysWIXEwJyMQGEVevKzM2J3Qz/cHSc5LVqibmoUWzZ7g+97qRg==
dependencies:
nan "^2.12.1"
which-pm-runs@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb"
...
...
src/vs/workbench/api/browser/mainThreadTerminalService.ts
浏览文件 @
76b54755
...
...
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
ITerminalService
,
ITerminalInstance
,
IShellLaunchConfig
,
ITerminalProcessExtHostProxy
,
ITerminalProcessExtHostRequest
,
ITerminalDimensions
,
EXT_HOST_CREATION_DELAY
}
from
'
vs/workbench/contrib/terminal/common/terminal
'
;
import
{
ITerminalService
,
ITerminalInstance
,
IShellLaunchConfig
,
ITerminalProcessExtHostProxy
,
ITerminalProcessExtHostRequest
,
ITerminalDimensions
,
EXT_HOST_CREATION_DELAY
,
IShellDefinition
}
from
'
vs/workbench/contrib/terminal/common/terminal
'
;
import
{
ExtHostContext
,
ExtHostTerminalServiceShape
,
MainThreadTerminalServiceShape
,
MainContext
,
IExtHostContext
,
ShellLaunchConfigDto
}
from
'
vs/workbench/api/common/extHost.protocol
'
;
import
{
extHostNamedCustomer
}
from
'
vs/workbench/api/common/extHostCustomers
'
;
import
{
UriComponents
,
URI
}
from
'
vs/base/common/uri
'
;
...
...
@@ -22,11 +22,11 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
constructor
(
extHostContext
:
IExtHostContext
,
@
ITerminalService
private
readonly
terminalService
:
ITerminalService
@
ITerminalService
private
readonly
_
terminalService
:
ITerminalService
)
{
this
.
_proxy
=
extHostContext
.
getProxy
(
ExtHostContext
.
ExtHostTerminalService
);
this
.
_remoteAuthority
=
extHostContext
.
remoteAuthority
;
this
.
_toDispose
.
push
(
terminalService
.
onInstanceCreated
((
instance
)
=>
{
this
.
_toDispose
.
push
(
_
terminalService
.
onInstanceCreated
((
instance
)
=>
{
// Delay this message so the TerminalInstance constructor has a chance to finish and
// return the ID normally to the extension host. The ID that is passed here will be used
// to register non-extension API terminals in the extension host.
...
...
@@ -35,25 +35,26 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
this
.
_onInstanceDimensionsChanged
(
instance
);
},
EXT_HOST_CREATION_DELAY
);
}));
this
.
_toDispose
.
push
(
terminalService
.
onInstanceDisposed
(
instance
=>
this
.
_onTerminalDisposed
(
instance
)));
this
.
_toDispose
.
push
(
terminalService
.
onInstanceProcessIdReady
(
instance
=>
this
.
_onTerminalProcessIdReady
(
instance
)));
this
.
_toDispose
.
push
(
terminalService
.
onInstanceDimensionsChanged
(
instance
=>
this
.
_onInstanceDimensionsChanged
(
instance
)));
this
.
_toDispose
.
push
(
terminalService
.
onInstanceRequestExtHostProcess
(
request
=>
this
.
_onTerminalRequestExtHostProcess
(
request
)));
this
.
_toDispose
.
push
(
terminalService
.
onActiveInstanceChanged
(
instance
=>
this
.
_onActiveTerminalChanged
(
instance
?
instance
.
id
:
null
)));
this
.
_toDispose
.
push
(
terminalService
.
onInstanceTitleChanged
(
instance
=>
this
.
_onTitleChanged
(
instance
.
id
,
instance
.
title
)));
this
.
_toDispose
.
push
(
terminalService
.
configHelper
.
onWorkspacePermissionsChanged
(
isAllowed
=>
this
.
_onWorkspacePermissionsChanged
(
isAllowed
)));
this
.
_toDispose
.
push
(
_terminalService
.
onInstanceDisposed
(
instance
=>
this
.
_onTerminalDisposed
(
instance
)));
this
.
_toDispose
.
push
(
_terminalService
.
onInstanceProcessIdReady
(
instance
=>
this
.
_onTerminalProcessIdReady
(
instance
)));
this
.
_toDispose
.
push
(
_terminalService
.
onInstanceDimensionsChanged
(
instance
=>
this
.
_onInstanceDimensionsChanged
(
instance
)));
this
.
_toDispose
.
push
(
_terminalService
.
onInstanceRequestExtHostProcess
(
request
=>
this
.
_onTerminalRequestExtHostProcess
(
request
)));
this
.
_toDispose
.
push
(
_terminalService
.
onActiveInstanceChanged
(
instance
=>
this
.
_onActiveTerminalChanged
(
instance
?
instance
.
id
:
null
)));
this
.
_toDispose
.
push
(
_terminalService
.
onInstanceTitleChanged
(
instance
=>
this
.
_onTitleChanged
(
instance
.
id
,
instance
.
title
)));
this
.
_toDispose
.
push
(
_terminalService
.
configHelper
.
onWorkspacePermissionsChanged
(
isAllowed
=>
this
.
_onWorkspacePermissionsChanged
(
isAllowed
)));
this
.
_toDispose
.
push
(
_terminalService
.
onRequestAvailableShells
(
r
=>
this
.
_onRequestAvailableShells
(
r
)));
// Set initial ext host state
this
.
terminalService
.
terminalInstances
.
forEach
(
t
=>
{
this
.
_
terminalService
.
terminalInstances
.
forEach
(
t
=>
{
this
.
_onTerminalOpened
(
t
);
t
.
processReady
.
then
(()
=>
this
.
_onTerminalProcessIdReady
(
t
));
});
const
activeInstance
=
this
.
terminalService
.
getActiveInstance
();
const
activeInstance
=
this
.
_
terminalService
.
getActiveInstance
();
if
(
activeInstance
)
{
this
.
_proxy
.
$acceptActiveTerminalChanged
(
activeInstance
.
id
);
}
this
.
terminalService
.
extHostReady
(
extHostContext
.
remoteAuthority
);
this
.
_
terminalService
.
extHostReady
(
extHostContext
.
remoteAuthority
);
}
public
dispose
():
void
{
...
...
@@ -75,7 +76,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
strictEnv
,
runInBackground
};
const
terminal
=
this
.
terminalService
.
createTerminal
(
shellLaunchConfig
);
const
terminal
=
this
.
_
terminalService
.
createTerminal
(
shellLaunchConfig
);
return
Promise
.
resolve
({
id
:
terminal
.
id
,
name
:
terminal
.
title
...
...
@@ -83,55 +84,55 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
}
public
$createTerminalRenderer
(
name
:
string
):
Promise
<
number
>
{
const
instance
=
this
.
terminalService
.
createTerminalRenderer
(
name
);
const
instance
=
this
.
_
terminalService
.
createTerminalRenderer
(
name
);
return
Promise
.
resolve
(
instance
.
id
);
}
public
$show
(
terminalId
:
number
,
preserveFocus
:
boolean
):
void
{
const
terminalInstance
=
this
.
terminalService
.
getInstanceFromId
(
terminalId
);
const
terminalInstance
=
this
.
_
terminalService
.
getInstanceFromId
(
terminalId
);
if
(
terminalInstance
)
{
this
.
terminalService
.
setActiveInstance
(
terminalInstance
);
this
.
terminalService
.
showPanel
(
!
preserveFocus
);
this
.
_
terminalService
.
setActiveInstance
(
terminalInstance
);
this
.
_
terminalService
.
showPanel
(
!
preserveFocus
);
}
}
public
$hide
(
terminalId
:
number
):
void
{
const
instance
=
this
.
terminalService
.
getActiveInstance
();
const
instance
=
this
.
_
terminalService
.
getActiveInstance
();
if
(
instance
&&
instance
.
id
===
terminalId
)
{
this
.
terminalService
.
hidePanel
();
this
.
_
terminalService
.
hidePanel
();
}
}
public
$dispose
(
terminalId
:
number
):
void
{
const
terminalInstance
=
this
.
terminalService
.
getInstanceFromId
(
terminalId
);
const
terminalInstance
=
this
.
_
terminalService
.
getInstanceFromId
(
terminalId
);
if
(
terminalInstance
)
{
terminalInstance
.
dispose
();
}
}
public
$terminalRendererWrite
(
terminalId
:
number
,
text
:
string
):
void
{
const
terminalInstance
=
this
.
terminalService
.
getInstanceFromId
(
terminalId
);
const
terminalInstance
=
this
.
_
terminalService
.
getInstanceFromId
(
terminalId
);
if
(
terminalInstance
&&
terminalInstance
.
shellLaunchConfig
.
isRendererOnly
)
{
terminalInstance
.
write
(
text
);
}
}
public
$terminalRendererSetName
(
terminalId
:
number
,
name
:
string
):
void
{
const
terminalInstance
=
this
.
terminalService
.
getInstanceFromId
(
terminalId
);
const
terminalInstance
=
this
.
_
terminalService
.
getInstanceFromId
(
terminalId
);
if
(
terminalInstance
&&
terminalInstance
.
shellLaunchConfig
.
isRendererOnly
)
{
terminalInstance
.
setTitle
(
name
,
false
);
}
}
public
$terminalRendererSetDimensions
(
terminalId
:
number
,
dimensions
:
ITerminalDimensions
):
void
{
const
terminalInstance
=
this
.
terminalService
.
getInstanceFromId
(
terminalId
);
const
terminalInstance
=
this
.
_
terminalService
.
getInstanceFromId
(
terminalId
);
if
(
terminalInstance
&&
terminalInstance
.
shellLaunchConfig
.
isRendererOnly
)
{
terminalInstance
.
setDimensions
(
dimensions
);
}
}
public
$terminalRendererRegisterOnInputListener
(
terminalId
:
number
):
void
{
const
terminalInstance
=
this
.
terminalService
.
getInstanceFromId
(
terminalId
);
const
terminalInstance
=
this
.
_
terminalService
.
getInstanceFromId
(
terminalId
);
if
(
!
terminalInstance
)
{
return
;
}
...
...
@@ -147,14 +148,14 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
}
public
$sendText
(
terminalId
:
number
,
text
:
string
,
addNewLine
:
boolean
):
void
{
const
terminalInstance
=
this
.
terminalService
.
getInstanceFromId
(
terminalId
);
const
terminalInstance
=
this
.
_
terminalService
.
getInstanceFromId
(
terminalId
);
if
(
terminalInstance
)
{
terminalInstance
.
sendText
(
text
,
addNewLine
);
}
}
public
$registerOnDataListener
(
terminalId
:
number
):
void
{
const
terminalInstance
=
this
.
terminalService
.
getInstanceFromId
(
terminalId
);
const
terminalInstance
=
this
.
_
terminalService
.
getInstanceFromId
(
terminalId
);
if
(
!
terminalInstance
)
{
return
;
}
...
...
@@ -275,4 +276,8 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
}
this
.
_terminalProcesses
[
terminalId
].
emitLatency
(
sum
/
COUNT
);
}
private
_onRequestAvailableShells
(
resolve
:
(
shells
:
IShellDefinition
[])
=>
void
):
void
{
this
.
_proxy
.
$requestAvailableShells
().
then
(
shells
=>
resolve
(
shells
));
}
}
src/vs/workbench/api/common/extHost.protocol.ts
浏览文件 @
76b54755
...
...
@@ -1106,6 +1106,11 @@ export interface ShellLaunchConfigDto {
env
?:
{
[
key
:
string
]:
string
|
null
};
}
export
interface
IShellDefinitionDto
{
label
:
string
;
path
:
string
;
}
export
interface
ExtHostTerminalServiceShape
{
$acceptTerminalClosed
(
id
:
number
):
void
;
$acceptTerminalOpened
(
id
:
number
,
name
:
string
):
void
;
...
...
@@ -1123,6 +1128,7 @@ export interface ExtHostTerminalServiceShape {
$acceptProcessRequestCwd
(
id
:
number
):
void
;
$acceptProcessRequestLatency
(
id
:
number
):
number
;
$acceptWorkspacePermissionsChanged
(
isAllowed
:
boolean
):
void
;
$requestAvailableShells
():
Promise
<
IShellDefinitionDto
[]
>
;
}
export
interface
ExtHostSCMShape
{
...
...
src/vs/workbench/api/node/extHostTerminalService.ts
浏览文件 @
76b54755
...
...
@@ -10,7 +10,7 @@ import { URI, UriComponents } from 'vs/base/common/uri';
import
*
as
platform
from
'
vs/base/common/platform
'
;
import
*
as
terminalEnvironment
from
'
vs/workbench/contrib/terminal/common/terminalEnvironment
'
;
import
{
Event
,
Emitter
}
from
'
vs/base/common/event
'
;
import
{
ExtHostTerminalServiceShape
,
MainContext
,
MainThreadTerminalServiceShape
,
IMainContext
,
ShellLaunchConfigDto
}
from
'
vs/workbench/api/common/extHost.protocol
'
;
import
{
ExtHostTerminalServiceShape
,
MainContext
,
MainThreadTerminalServiceShape
,
IMainContext
,
ShellLaunchConfigDto
,
IShellDefinitionDto
}
from
'
vs/workbench/api/common/extHost.protocol
'
;
import
{
ExtHostConfiguration
,
ExtHostConfigProvider
}
from
'
vs/workbench/api/common/extHostConfiguration
'
;
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
import
{
EXT_HOST_CREATION_DELAY
,
IShellLaunchConfig
,
ITerminalEnvironment
}
from
'
vs/workbench/contrib/terminal/common/terminal
'
;
...
...
@@ -20,7 +20,7 @@ import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import
{
IWorkspaceFolder
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
ExtHostVariableResolverService
}
from
'
vs/workbench/api/node/extHostDebugService
'
;
import
{
ExtHostDocumentsAndEditors
}
from
'
vs/workbench/api/common/extHostDocumentsAndEditors
'
;
import
{
getDefaultShell
}
from
'
vs/workbench/contrib/terminal/node/terminal
'
;
import
{
getDefaultShell
,
detectAvailableShells
}
from
'
vs/workbench/contrib/terminal/node/terminal
'
;
const
RENDERER_NO_PROCESS_ID
=
-
1
;
...
...
@@ -534,7 +534,9 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
// Fork the process and listen for messages
this
.
_logService
.
debug
(
`Terminal process launching on ext host`
,
shellLaunchConfig
,
initialCwd
,
cols
,
rows
,
env
);
const
p
=
new
TerminalProcess
(
shellLaunchConfig
,
initialCwd
,
cols
,
rows
,
env
,
terminalConfig
.
get
(
'
windowsEnableConpty
'
)
as
boolean
,
this
.
_logService
);
// TODO: Support conpty on remote, it doesn't seem to work for some reason?
const
enableConpty
=
false
;
//terminalConfig.get('windowsEnableConpty') as boolean;
const
p
=
new
TerminalProcess
(
shellLaunchConfig
,
initialCwd
,
cols
,
rows
,
env
,
enableConpty
,
this
.
_logService
);
p
.
onProcessReady
((
e
:
{
pid
:
number
,
cwd
:
string
})
=>
this
.
_proxy
.
$sendProcessReady
(
id
,
e
.
pid
,
e
.
cwd
));
p
.
onProcessTitleChanged
(
title
=>
this
.
_proxy
.
$sendProcessTitle
(
id
,
title
));
p
.
onProcessData
(
data
=>
this
.
_proxy
.
$sendProcessData
(
id
,
data
));
...
...
@@ -573,6 +575,10 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
return
id
;
}
public
$requestAvailableShells
():
Promise
<
IShellDefinitionDto
[]
>
{
return
detectAvailableShells
();
}
private
_onProcessExit
(
id
:
number
,
exitCode
:
number
):
void
{
// Remove listeners
this
.
_terminalProcesses
[
id
].
dispose
();
...
...
src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts
浏览文件 @
76b54755
...
...
@@ -370,9 +370,7 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClearTerminalAct
primary
:
0
,
mac
:
{
primary
:
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
}
},
KEYBINDING_CONTEXT_TERMINAL_FOCUS
,
KeybindingWeight
.
WorkbenchContrib
+
1
),
'
Terminal: Clear
'
,
category
);
if
(
platform
.
isWindows
)
{
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
SelectDefaultShellWindowsTerminalAction
,
SelectDefaultShellWindowsTerminalAction
.
ID
,
SelectDefaultShellWindowsTerminalAction
.
LABEL
),
'
Terminal: Select Default Shell
'
,
category
);
}
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
SelectDefaultShellWindowsTerminalAction
,
SelectDefaultShellWindowsTerminalAction
.
ID
,
SelectDefaultShellWindowsTerminalAction
.
LABEL
),
'
Terminal: Select Default Shell
'
,
category
);
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
AllowWorkspaceShellTerminalCommand
,
AllowWorkspaceShellTerminalCommand
.
ID
,
AllowWorkspaceShellTerminalCommand
.
LABEL
),
'
Terminal: Allow Workspace Shell Configuration
'
,
category
);
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
DisallowWorkspaceShellTerminalCommand
,
DisallowWorkspaceShellTerminalCommand
.
ID
,
DisallowWorkspaceShellTerminalCommand
.
LABEL
),
'
Terminal: Disallow Workspace Shell Configuration
'
,
category
);
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
RenameTerminalAction
,
RenameTerminalAction
.
ID
,
RenameTerminalAction
.
LABEL
),
'
Terminal: Rename
'
,
category
);
...
...
src/vs/workbench/contrib/terminal/browser/terminalActions.ts
浏览文件 @
76b54755
...
...
@@ -7,7 +7,7 @@ import * as nls from 'vs/nls';
import
{
Action
,
IAction
}
from
'
vs/base/common/actions
'
;
import
{
EndOfLinePreference
}
from
'
vs/editor/common/model
'
;
import
{
ICodeEditorService
}
from
'
vs/editor/browser/services/codeEditorService
'
;
import
{
ITerminalService
,
TERMINAL_PANEL_ID
,
ITerminalInstance
,
Direction
,
ITerminalConfigHelper
,
ITerminalNativeService
}
from
'
vs/workbench/contrib/terminal/common/terminal
'
;
import
{
ITerminalService
,
TERMINAL_PANEL_ID
,
ITerminalInstance
,
Direction
,
ITerminalConfigHelper
}
from
'
vs/workbench/contrib/terminal/common/terminal
'
;
import
{
SelectActionViewItem
}
from
'
vs/base/browser/ui/actionbar/actionbar
'
;
import
{
TogglePanelAction
}
from
'
vs/workbench/browser/panel
'
;
import
{
IWorkbenchLayoutService
}
from
'
vs/workbench/services/layout/browser/layoutService
'
;
...
...
@@ -35,7 +35,6 @@ import { Schemas } from 'vs/base/common/network';
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
isWindows
}
from
'
vs/base/common/platform
'
;
import
{
withNullAsUndefined
}
from
'
vs/base/common/types
'
;
import
{
IWorkbenchEnvironmentService
}
from
'
vs/workbench/services/environment/common/environmentService
'
;
export
const
TERMINAL_PICKER_PREFIX
=
'
term
'
;
...
...
@@ -624,13 +623,13 @@ export class SelectDefaultShellWindowsTerminalAction extends Action {
constructor
(
id
:
string
,
label
:
string
,
@
ITerminal
NativeService
private
readonly
_terminalNativeService
:
ITerminalNative
Service
@
ITerminal
Service
private
readonly
_terminalService
:
ITerminal
Service
)
{
super
(
id
,
label
);
}
public
run
(
event
?:
any
):
Promise
<
any
>
{
return
this
.
_terminal
Native
Service
.
selectDefaultWindowsShell
();
return
this
.
_terminalService
.
selectDefaultWindowsShell
();
}
}
...
...
@@ -712,8 +711,7 @@ export class SwitchTerminalAction extends Action {
constructor
(
id
:
string
,
label
:
string
,
@
ITerminalService
private
readonly
terminalService
:
ITerminalService
,
@
ITerminalNativeService
private
readonly
terminalNativeService
:
ITerminalNativeService
@
ITerminalService
private
readonly
terminalService
:
ITerminalService
)
{
super
(
id
,
label
,
'
terminal-action switch-terminal
'
);
}
...
...
@@ -728,7 +726,7 @@ export class SwitchTerminalAction extends Action {
}
if
(
item
===
SelectDefaultShellWindowsTerminalAction
.
LABEL
)
{
this
.
terminalService
.
refreshActiveTab
();
return
this
.
terminal
Native
Service
.
selectDefaultWindowsShell
();
return
this
.
terminalService
.
selectDefaultWindowsShell
();
}
const
selectedTabIndex
=
parseInt
(
item
.
split
(
'
:
'
)[
0
],
10
)
-
1
;
this
.
terminalService
.
setActiveTabByIndex
(
selectedTabIndex
);
...
...
@@ -744,8 +742,7 @@ export class SwitchTerminalActionViewItem extends SelectActionViewItem {
action
:
IAction
,
@
ITerminalService
private
readonly
terminalService
:
ITerminalService
,
@
IThemeService
themeService
:
IThemeService
,
@
IContextViewService
contextViewService
:
IContextViewService
,
@
IWorkbenchEnvironmentService
private
workbenchEnvironmentService
:
IWorkbenchEnvironmentService
@
IContextViewService
contextViewService
:
IContextViewService
)
{
super
(
null
,
action
,
terminalService
.
getTabLabels
().
map
(
label
=>
<
ISelectOptionItem
>
{
text
:
label
}),
terminalService
.
activeTabIndex
,
contextViewService
,
{
ariaLabel
:
nls
.
localize
(
'
terminals
'
,
'
Open Terminals.
'
)
});
...
...
@@ -757,11 +754,8 @@ export class SwitchTerminalActionViewItem extends SelectActionViewItem {
private
_updateItems
():
void
{
const
items
=
this
.
terminalService
.
getTabLabels
().
map
(
label
=>
<
ISelectOptionItem
>
{
text
:
label
});
let
enableSelectDefaultShell
=
this
.
workbenchEnvironmentService
.
configuration
.
remoteAuthority
?
false
:
isWindows
;
if
(
enableSelectDefaultShell
)
{
items
.
push
({
text
:
SwitchTerminalActionViewItem
.
SEPARATOR
});
items
.
push
({
text
:
SelectDefaultShellWindowsTerminalAction
.
LABEL
});
}
items
.
push
({
text
:
SwitchTerminalActionViewItem
.
SEPARATOR
});
items
.
push
({
text
:
SelectDefaultShellWindowsTerminalAction
.
LABEL
});
this
.
setOptions
(
items
,
this
.
terminalService
.
activeTabIndex
);
}
}
...
...
src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts
浏览文件 @
76b54755
...
...
@@ -23,10 +23,6 @@ export class TerminalNativeService implements ITerminalNativeService {
throw
new
Error
(
'
Not implemented
'
);
}
public
selectDefaultWindowsShell
():
Promise
<
string
|
undefined
>
{
throw
new
Error
(
'
Not implemented
'
);
}
public
getWslPath
():
Promise
<
string
>
{
throw
new
Error
(
'
Not implemented
'
);
}
...
...
src/vs/workbench/contrib/terminal/browser/terminalService.ts
浏览文件 @
76b54755
...
...
@@ -21,6 +21,8 @@ import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal
import
{
IBrowserTerminalConfigHelper
}
from
'
vs/workbench/contrib/terminal/browser/terminal
'
;
import
{
IRemoteAgentService
}
from
'
vs/workbench/services/remote/common/remoteAgentService
'
;
import
{
TerminalConfigHelper
}
from
'
vs/workbench/contrib/terminal/browser/terminalConfigHelper
'
;
import
{
IQuickInputService
}
from
'
vs/platform/quickinput/common/quickInput
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
export
class
TerminalService
extends
CommonTerminalService
implements
ITerminalService
{
private
_configHelper
:
IBrowserTerminalConfigHelper
;
...
...
@@ -39,9 +41,11 @@ export class TerminalService extends CommonTerminalService implements ITerminalS
@
IExtensionService
extensionService
:
IExtensionService
,
@
IFileService
fileService
:
IFileService
,
@
IRemoteAgentService
remoteAgentService
:
IRemoteAgentService
,
@
ITerminalNativeService
readonly
terminalNativeService
:
ITerminalNativeService
@
ITerminalNativeService
readonly
terminalNativeService
:
ITerminalNativeService
,
@
IQuickInputService
readonly
quickInputService
:
IQuickInputService
,
@
IConfigurationService
readonly
configurationService
:
IConfigurationService
)
{
super
(
contextKeyService
,
panelService
,
lifecycleService
,
storageService
,
notificationService
,
dialogService
,
extensionService
,
fileService
,
remoteAgentService
,
terminalNativeService
);
super
(
contextKeyService
,
panelService
,
lifecycleService
,
storageService
,
notificationService
,
dialogService
,
extensionService
,
fileService
,
remoteAgentService
,
terminalNativeService
,
quickInputService
,
configurationService
);
this
.
_configHelper
=
this
.
_instantiationService
.
createInstance
(
TerminalConfigHelper
,
this
.
terminalNativeService
.
linuxDistro
);
}
...
...
src/vs/workbench/contrib/terminal/common/terminal.ts
浏览文件 @
76b54755
...
...
@@ -222,6 +222,7 @@ export interface ITerminalService {
onInstancesChanged
:
Event
<
void
>
;
onInstanceTitleChanged
:
Event
<
ITerminalInstance
>
;
onActiveInstanceChanged
:
Event
<
ITerminalInstance
|
undefined
>
;
onRequestAvailableShells
:
Event
<
(
shells
:
IShellDefinition
[])
=>
void
>
;
/**
* Creates a terminal.
...
...
@@ -267,6 +268,8 @@ export interface ITerminalService {
findNext
():
void
;
findPrevious
():
void
;
selectDefaultWindowsShell
():
Promise
<
void
>
;
setContainers
(
panelContainer
:
HTMLElement
,
terminalContainer
:
HTMLElement
):
void
;
setWorkspaceShellAllowed
(
isAllowed
:
boolean
):
void
;
...
...
@@ -299,7 +302,11 @@ export interface ITerminalNativeService {
getWindowsBuildNumber
():
number
;
whenFileDeleted
(
path
:
URI
):
Promise
<
void
>
;
getWslPath
(
path
:
string
):
Promise
<
string
>
;
selectDefaultWindowsShell
():
Promise
<
string
|
undefined
>
;
}
export
interface
IShellDefinition
{
label
:
string
;
path
:
string
;
}
export
const
enum
Direction
{
...
...
src/vs/workbench/contrib/terminal/common/terminalService.ts
浏览文件 @
76b54755
...
...
@@ -8,7 +8,7 @@ import { Event, Emitter } from 'vs/base/common/event';
import
{
IContextKeyService
,
IContextKey
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
ILifecycleService
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
IPanelService
}
from
'
vs/workbench/services/panel/common/panelService
'
;
import
{
ITerminalService
,
ITerminalInstance
,
IShellLaunchConfig
,
ITerminalConfigHelper
,
KEYBINDING_CONTEXT_TERMINAL_FOCUS
,
KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE
,
TERMINAL_PANEL_ID
,
ITerminalTab
,
ITerminalProcessExtHostProxy
,
ITerminalProcessExtHostRequest
,
KEYBINDING_CONTEXT_TERMINAL_IS_OPEN
,
ITerminalNativeService
}
from
'
vs/workbench/contrib/terminal/common/terminal
'
;
import
{
ITerminalService
,
ITerminalInstance
,
IShellLaunchConfig
,
ITerminalConfigHelper
,
KEYBINDING_CONTEXT_TERMINAL_FOCUS
,
KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE
,
TERMINAL_PANEL_ID
,
ITerminalTab
,
ITerminalProcessExtHostProxy
,
ITerminalProcessExtHostRequest
,
KEYBINDING_CONTEXT_TERMINAL_IS_OPEN
,
ITerminalNativeService
,
IShellDefinition
}
from
'
vs/workbench/contrib/terminal/common/terminal
'
;
import
{
IStorageService
}
from
'
vs/platform/storage/common/storage
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
FindReplaceState
}
from
'
vs/editor/contrib/find/findState
'
;
...
...
@@ -22,6 +22,8 @@ import { basename } from 'vs/base/common/path';
import
{
IRemoteAgentService
}
from
'
vs/workbench/services/remote/common/remoteAgentService
'
;
import
{
timeout
}
from
'
vs/base/common/async
'
;
import
{
IOpenFileRequest
}
from
'
vs/platform/windows/common/windows
'
;
import
{
IPickOptions
,
IQuickPickItem
,
IQuickInputService
}
from
'
vs/platform/quickinput/common/quickInput
'
;
import
{
IConfigurationService
,
ConfigurationTarget
}
from
'
vs/platform/configuration/common/configuration
'
;
export
abstract
class
TerminalService
implements
ITerminalService
{
public
_serviceBrand
:
any
;
...
...
@@ -63,6 +65,8 @@ export abstract class TerminalService implements ITerminalService {
public
get
onActiveInstanceChanged
():
Event
<
ITerminalInstance
|
undefined
>
{
return
this
.
_onActiveInstanceChanged
.
event
;
}
protected
readonly
_onTabDisposed
=
new
Emitter
<
ITerminalTab
>
();
public
get
onTabDisposed
():
Event
<
ITerminalTab
>
{
return
this
.
_onTabDisposed
.
event
;
}
protected
readonly
_onRequestAvailableShells
=
new
Emitter
<
(
shells
:
IShellDefinition
[])
=>
void
>
();
public
get
onRequestAvailableShells
():
Event
<
(
shells
:
IShellDefinition
[])
=>
void
>
{
return
this
.
_onRequestAvailableShells
.
event
;
}
public
abstract
get
configHelper
():
ITerminalConfigHelper
;
...
...
@@ -76,7 +80,9 @@ export abstract class TerminalService implements ITerminalService {
@
IExtensionService
private
readonly
_extensionService
:
IExtensionService
,
@
IFileService
protected
readonly
_fileService
:
IFileService
,
@
IRemoteAgentService
readonly
_remoteAgentService
:
IRemoteAgentService
,
@
ITerminalNativeService
private
readonly
_terminalNativeService
:
ITerminalNativeService
@
ITerminalNativeService
private
readonly
_terminalNativeService
:
ITerminalNativeService
,
@
IQuickInputService
private
readonly
_quickInputService
:
IQuickInputService
,
@
IConfigurationService
private
readonly
_configurationService
:
IConfigurationService
)
{
this
.
_activeTabIndex
=
0
;
this
.
_isShuttingDown
=
false
;
...
...
@@ -526,4 +532,27 @@ export abstract class TerminalService implements ITerminalService {
c
(
escapeNonWindowsPath
(
originalPath
));
});
}
public
selectDefaultWindowsShell
():
Promise
<
void
>
{
return
this
.
_detectWindowsShells
().
then
(
shells
=>
{
const
options
:
IPickOptions
<
IQuickPickItem
>
=
{
placeHolder
:
nls
.
localize
(
'
terminal.integrated.chooseWindowsShell
'
,
"
Select your preferred terminal shell, you can change this later in your settings
"
)
};
const
quickPickItems
=
shells
.
map
(
s
=>
{
return
{
label
:
s
.
label
,
description
:
s
.
path
};
});
return
this
.
_quickInputService
.
pick
(
quickPickItems
,
options
).
then
(
async
value
=>
{
if
(
!
value
)
{
return
undefined
;
}
const
shell
=
value
.
description
;
await
this
.
_configurationService
.
updateValue
(
'
terminal.integrated.shell.windows
'
,
shell
,
ConfigurationTarget
.
USER
).
then
(()
=>
shell
);
return
Promise
.
resolve
();
});
});
}
private
_detectWindowsShells
():
Promise
<
IShellDefinition
[]
>
{
return
new
Promise
(
r
=>
this
.
_onRequestAvailableShells
.
fire
(
r
));
}
}
src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts
浏览文件 @
76b54755
...
...
@@ -3,19 +3,15 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
*
as
nls
from
'
vs/nls
'
;
import
{
ipcRenderer
as
ipc
}
from
'
electron
'
;
import
{
IOpenFileRequest
}
from
'
vs/platform/windows/common/windows
'
;
import
{
ITerminalNativeService
,
LinuxDistro
}
from
'
vs/workbench/contrib/terminal/common/terminal
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
getWindowsBuildNumber
,
linuxDistro
}
from
'
vs/workbench/contrib/terminal/node/terminal
'
;
import
{
IQuickPickItem
,
IPickOptions
,
IQuickInputService
}
from
'
vs/platform/quickinput/common/quickInput
'
;
import
{
escapeNonWindowsPath
}
from
'
vs/workbench/contrib/terminal/common/terminalEnvironment
'
;
import
{
execFile
}
from
'
child_process
'
;
import
{
coalesce
}
from
'
vs/base/common/arrays
'
;
import
{
Emitter
,
Event
}
from
'
vs/base/common/event
'
;
import
{
IConfigurationService
,
ConfigurationTarget
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
export
class
TerminalNativeService
implements
ITerminalNativeService
{
...
...
@@ -30,8 +26,6 @@ export class TerminalNativeService implements ITerminalNativeService {
constructor
(
@
IFileService
private
readonly
_fileService
:
IFileService
,
@
IQuickInputService
private
readonly
_quickInputService
:
IQuickInputService
,
@
IConfigurationService
private
readonly
_configurationService
:
IConfigurationService
,
@
IInstantiationService
readonly
instantiationService
:
IInstantiationService
,
)
{
ipc
.
on
(
'
vscode:openFiles
'
,
(
_event
:
any
,
request
:
IOpenFileRequest
)
=>
this
.
_onOpenFileRequest
.
fire
(
request
));
...
...
@@ -58,99 +52,6 @@ export class TerminalNativeService implements ITerminalNativeService {
});
}
public
selectDefaultWindowsShell
():
Promise
<
string
|
undefined
>
{
return
this
.
_detectWindowsShells
().
then
(
shells
=>
{
const
options
:
IPickOptions
<
IQuickPickItem
>
=
{
placeHolder
:
nls
.
localize
(
'
terminal.integrated.chooseWindowsShell
'
,
"
Select your preferred terminal shell, you can change this later in your settings
"
)
};
return
this
.
_quickInputService
.
pick
(
shells
,
options
).
then
(
value
=>
{
if
(
!
value
)
{
return
undefined
;
}
const
shell
=
value
.
description
;
return
this
.
_configurationService
.
updateValue
(
'
terminal.integrated.shell.windows
'
,
shell
,
ConfigurationTarget
.
USER
).
then
(()
=>
shell
);
});
});
}
/**
* Get the executable file path of shell from registry.
* @param shellName The shell name to get the executable file path
* @returns `[]` or `[ 'path' ]`
*/
private
async
_getShellPathFromRegistry
(
shellName
:
string
):
Promise
<
string
[]
>
{
const
Registry
=
await
import
(
'
vscode-windows-registry
'
);
try
{
const
shellPath
=
Registry
.
GetStringRegKey
(
'
HKEY_LOCAL_MACHINE
'
,
`SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\
\$
{shellName}.exe`
,
''
);
if
(
shellPath
===
undefined
)
{
return
[];
}
return
[
shellPath
];
}
catch
(
error
)
{
return
[];
}
}
private
async
_detectWindowsShells
():
Promise
<
IQuickPickItem
[]
>
{
// Determine the correct System32 path. We want to point to Sysnative
// when the 32-bit version of VS Code is running on a 64-bit machine.
// The reason for this is because PowerShell's important PSReadline
// module doesn't work if this is not the case. See #27915.
const
is32ProcessOn64Windows
=
process
.
env
.
hasOwnProperty
(
'
PROCESSOR_ARCHITEW6432
'
);
const
system32Path
=
`
${
process
.
env
[
'
windir
'
]}
\
\$
{is32ProcessOn64Windows ? 'Sysnative' : 'System32'}`
;
let
useWSLexe
=
false
;
if
(
getWindowsBuildNumber
()
>=
16299
)
{
useWSLexe
=
true
;
}
const
expectedLocations
=
{
'
Command Prompt
'
:
[
`
${
system32Path
}
\\cmd.exe`
],
PowerShell
:
[
`
${
system32Path
}
\\WindowsPowerShell\\v1.0\\powershell.exe`
],
'
PowerShell Core
'
:
await
this
.
_getShellPathFromRegistry
(
'
pwsh
'
),
'
WSL Bash
'
:
[
`
${
system32Path
}
\
\$
{useWSLexe ? 'wsl.exe' : 'bash.exe'}`
],
'
Git Bash
'
:
[
`
${
process
.
env
[
'
ProgramW6432
'
]}
\\Git\\bin\\bash.exe`
,
`
${
process
.
env
[
'
ProgramW6432
'
]}
\\Git\\usr\\bin\\bash.exe`
,
`
${
process
.
env
[
'
ProgramFiles
'
]}
\\Git\\bin\\bash.exe`
,
`
${
process
.
env
[
'
ProgramFiles
'
]}
\\Git\\usr\\bin\\bash.exe`
,
`
${
process
.
env
[
'
LocalAppData
'
]}
\\Programs\\Git\\bin\\bash.exe`
,
]
};
const
promises
:
PromiseLike
<
[
string
,
string
]
>
[]
=
[];
Object
.
keys
(
expectedLocations
).
forEach
(
key
=>
promises
.
push
(
this
.
_validateShellPaths
(
key
,
expectedLocations
[
key
])));
return
Promise
.
all
(
promises
)
.
then
(
coalesce
)
.
then
(
results
=>
{
return
results
.
map
(
result
=>
{
return
<
IQuickPickItem
>
{
label
:
result
[
0
],
description
:
result
[
1
]
};
});
});
}
private
_validateShellPaths
(
label
:
string
,
potentialPaths
:
string
[]):
Promise
<
[
string
,
string
]
|
null
>
{
if
(
potentialPaths
.
length
===
0
)
{
return
Promise
.
resolve
(
null
);
}
const
current
=
potentialPaths
.
shift
();
if
(
current
!
===
''
)
{
return
this
.
_validateShellPaths
(
label
,
potentialPaths
);
}
return
this
.
_fileService
.
exists
(
URI
.
file
(
current
!
)).
then
(
exists
=>
{
if
(
!
exists
)
{
return
this
.
_validateShellPaths
(
label
,
potentialPaths
);
}
return
[
label
,
current
]
as
[
string
,
string
];
});
}
/**
* Converts a path to a path on WSL using the wslpath utility.
* @param path The original path.
...
...
src/vs/workbench/contrib/terminal/node/terminal.ts
浏览文件 @
76b54755
...
...
@@ -6,8 +6,10 @@
import
*
as
os
from
'
os
'
;
import
*
as
platform
from
'
vs/base/common/platform
'
;
import
*
as
processes
from
'
vs/base/node/processes
'
;
import
{
readFile
,
fileExists
}
from
'
vs/base/node/pfs
'
;
import
{
LinuxDistro
}
from
'
vs/workbench/contrib/terminal/common/terminal
'
;
import
{
readFile
,
fileExists
,
stat
}
from
'
vs/base/node/pfs
'
;
import
{
LinuxDistro
,
IShellDefinition
}
from
'
vs/workbench/contrib/terminal/common/terminal
'
;
import
{
coalesce
}
from
'
vs/base/common/arrays
'
;
import
{
normalize
,
basename
}
from
'
vs/base/common/path
'
;
export
function
getDefaultShell
(
p
:
platform
.
Platform
):
string
{
if
(
p
===
platform
.
Platform
.
Windows
)
{
...
...
@@ -82,3 +84,80 @@ export function getWindowsBuildNumber(): number {
}
return
buildNumber
;
}
export
function
detectAvailableShells
():
Promise
<
IShellDefinition
[]
>
{
return
platform
.
isWindows
?
detectAvailableWindowsShells
()
:
detectAvailableUnixShells
();
}
async
function
detectAvailableWindowsShells
():
Promise
<
IShellDefinition
[]
>
{
// Determine the correct System32 path. We want to point to Sysnative
// when the 32-bit version of VS Code is running on a 64-bit machine.
// The reason for this is because PowerShell's important PSReadline
// module doesn't work if this is not the case. See #27915.
const
is32ProcessOn64Windows
=
process
.
env
.
hasOwnProperty
(
'
PROCESSOR_ARCHITEW6432
'
);
const
system32Path
=
`
${
process
.
env
[
'
windir
'
]}
\
\$
{is32ProcessOn64Windows ? 'Sysnative' : 'System32'}`
;
let
useWSLexe
=
false
;
if
(
getWindowsBuildNumber
()
>=
16299
)
{
useWSLexe
=
true
;
}
const
expectedLocations
=
{
'
Command Prompt
'
:
[
`
${
system32Path
}
\\cmd.exe`
],
PowerShell
:
[
`
${
system32Path
}
\\WindowsPowerShell\\v1.0\\powershell.exe`
],
'
PowerShell Core
'
:
[
await
getShellPathFromRegistry
(
'
pwsh
'
)],
'
WSL Bash
'
:
[
`
${
system32Path
}
\
\$
{useWSLexe ? 'wsl.exe' : 'bash.exe'}`
],
'
Git Bash
'
:
[
`
${
process
.
env
[
'
ProgramW6432
'
]}
\\Git\\bin\\bash.exe`
,
`
${
process
.
env
[
'
ProgramW6432
'
]}
\\Git\\usr\\bin\\bash.exe`
,
`
${
process
.
env
[
'
ProgramFiles
'
]}
\\Git\\bin\\bash.exe`
,
`
${
process
.
env
[
'
ProgramFiles
'
]}
\\Git\\usr\\bin\\bash.exe`
,
`
${
process
.
env
[
'
LocalAppData
'
]}
\\Programs\\Git\\bin\\bash.exe`
,
]
};
const
promises
:
PromiseLike
<
IShellDefinition
|
undefined
>
[]
=
[];
Object
.
keys
(
expectedLocations
).
forEach
(
key
=>
promises
.
push
(
validateShellPaths
(
key
,
expectedLocations
[
key
])));
return
Promise
.
all
(
promises
).
then
(
coalesce
);
}
async
function
detectAvailableUnixShells
():
Promise
<
IShellDefinition
[]
>
{
const
contents
=
await
readFile
(
'
/etc/shells
'
,
'
utf8
'
);
const
shells
=
contents
.
split
(
'
\n
'
).
filter
(
e
=>
e
.
trim
().
indexOf
(
'
#
'
)
!==
0
&&
e
.
trim
().
length
>
0
);
return
shells
.
map
(
e
=>
{
return
{
label
:
basename
(
e
),
path
:
e
};
});
}
function
validateShellPaths
(
label
:
string
,
potentialPaths
:
string
[]):
Promise
<
IShellDefinition
|
undefined
>
{
if
(
potentialPaths
.
length
===
0
)
{
return
Promise
.
resolve
(
undefined
);
}
const
current
=
potentialPaths
.
shift
()
!
;
if
(
current
!
===
''
)
{
return
validateShellPaths
(
label
,
potentialPaths
);
}
return
stat
(
normalize
(
current
)).
then
(
stat
=>
{
if
(
!
stat
.
isFile
&&
!
stat
.
isSymbolicLink
)
{
return
validateShellPaths
(
label
,
potentialPaths
);
}
return
{
label
,
path
:
current
};
});
}
async
function
getShellPathFromRegistry
(
shellName
:
string
):
Promise
<
string
>
{
const
Registry
=
await
import
(
'
vscode-windows-registry
'
);
try
{
const
shellPath
=
Registry
.
GetStringRegKey
(
'
HKEY_LOCAL_MACHINE
'
,
`SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\
\$
{shellName}.exe`
,
''
);
return
shellPath
?
shellPath
:
''
;
}
catch
(
error
)
{
return
''
;
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录