Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
c287c3cf
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,发现更多精彩内容 >>
提交
c287c3cf
编写于
6月 17, 2019
作者:
D
Daniel Imms
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Get default shell selector working
上级
7dfbccb8
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
191 addition
and
150 deletion
+191
-150
remote/package.json
remote/package.json
+2
-1
remote/yarn.lock
remote/yarn.lock
+7
-0
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
+11
-2
src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts
...rkbench/contrib/terminal/browser/terminal.contribution.ts
+4
-4
src/vs/workbench/contrib/terminal/browser/terminalActions.ts
src/vs/workbench/contrib/terminal/browser/terminalActions.ts
+5
-6
src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts
...rkbench/contrib/terminal/browser/terminalNativeService.ts
+5
-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
+9
-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
+4
-99
src/vs/workbench/contrib/terminal/node/terminal.ts
src/vs/workbench/contrib/terminal/node/terminal.ts
+69
-2
未找到文件。
remote/package.json
浏览文件 @
c287c3cf
...
...
@@ -28,6 +28,7 @@
"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
浏览文件 @
c287c3cf
...
...
@@ -1112,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
浏览文件 @
c287c3cf
...
...
@@ -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
.
onRequestWindowsShells
(
r
=>
this
.
_onRequestDetectWindowsShell
(
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
_onRequestDetectWindowsShell
(
resolve
:
(
shells
:
IShellDefinition
[])
=>
void
):
void
{
this
.
_proxy
.
$requestWindowsShells
().
then
(
shells
=>
resolve
(
shells
));
}
}
src/vs/workbench/api/common/extHost.protocol.ts
浏览文件 @
c287c3cf
...
...
@@ -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
;
$requestWindowsShells
():
Promise
<
IShellDefinitionDto
[]
>
;
}
export
interface
ExtHostSCMShape
{
...
...
src/vs/workbench/api/node/extHostTerminalService.ts
浏览文件 @
c287c3cf
...
...
@@ -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
,
detectWindowsShells
}
from
'
vs/workbench/contrib/terminal/node/terminal
'
;
const
RENDERER_NO_PROCESS_ID
=
-
1
;
...
...
@@ -575,6 +575,15 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
return
id
;
}
public
$requestWindowsShells
():
Promise
<
IShellDefinitionDto
[]
>
{
console
.
log
(
'
$requestWindowsShells
'
);
if
(
!
platform
.
isWindows
)
{
throw
new
Error
(
'
Can only detect Windows shells on Windows
'
);
}
console
.
log
(
'
$requestWindowsShells2
'
);
return
detectWindowsShells
();
}
private
_onProcessExit
(
id
:
number
,
exitCode
:
number
):
void
{
// Remove listeners
this
.
_terminalProcesses
[
id
].
dispose
();
...
...
src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts
浏览文件 @
c287c3cf
...
...
@@ -370,10 +370,10 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClearTerminalAct
primary
:
0
,
mac
:
{
primary
:
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
}
},
KEYBINDING_CONTEXT_TERMINAL_FOCUS
,
KeybindingWeight
.
WorkbenchContrib
+
1
),
'
Terminal: Clear
'
,
category
);
// TODO:
Web should support this as well, the shell query needs to go to the ext host though
if
(
platform
.
isWindows
&&
!
platform
.
isWeb
)
{
actionRegistry
.
registerWorkbenchAction
(
new
SyncActionDescriptor
(
SelectDefaultShellWindowsTerminalAction
,
SelectDefaultShellWindowsTerminalAction
.
ID
,
SelectDefaultShellWindowsTerminalAction
.
LABEL
),
'
Terminal: Select Default Shell
'
,
category
);
}
// TODO:
This should be the remote OS
// if (platform.isWindows
) {
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
浏览文件 @
c287c3cf
...
...
@@ -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
'
;
...
...
@@ -624,13 +624,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 +712,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 +727,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
);
...
...
src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts
浏览文件 @
c287c3cf
...
...
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import
{
IOpenFileRequest
}
from
'
vs/platform/windows/common/windows
'
;
import
{
ITerminalNativeService
,
LinuxDistro
}
from
'
vs/workbench/contrib/terminal/common/terminal
'
;
import
{
ITerminalNativeService
,
LinuxDistro
,
IShellDefinition
}
from
'
vs/workbench/contrib/terminal/common/terminal
'
;
import
{
Emitter
,
Event
}
from
'
vs/base/common/event
'
;
export
class
TerminalNativeService
implements
ITerminalNativeService
{
...
...
@@ -23,15 +23,16 @@ export class TerminalNativeService implements ITerminalNativeService {
throw
new
Error
(
'
Not implemented
'
);
}
public
selectDefaultWindowsShell
():
Promise
<
string
|
undefined
>
{
public
getWslPath
():
Promise
<
string
>
{
throw
new
Error
(
'
Not implemented
'
);
}
public
getW
slPath
():
Promise
<
string
>
{
public
getW
indowsBuildNumber
():
number
{
throw
new
Error
(
'
Not implemented
'
);
}
public
getWindowsBuildNumber
():
number
{
// TODO: Remove local impl
public
detectWindowsShells
():
Promise
<
IShellDefinition
[]
>
{
throw
new
Error
(
'
Not implemented
'
);
}
}
\ No newline at end of file
src/vs/workbench/contrib/terminal/browser/terminalService.ts
浏览文件 @
c287c3cf
...
...
@@ -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
浏览文件 @
c287c3cf
...
...
@@ -222,6 +222,7 @@ export interface ITerminalService {
onInstancesChanged
:
Event
<
void
>
;
onInstanceTitleChanged
:
Event
<
ITerminalInstance
>
;
onActiveInstanceChanged
:
Event
<
ITerminalInstance
|
undefined
>
;
onRequestWindowsShells
:
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,12 @@ export interface ITerminalNativeService {
getWindowsBuildNumber
():
number
;
whenFileDeleted
(
path
:
URI
):
Promise
<
void
>
;
getWslPath
(
path
:
string
):
Promise
<
string
>
;
selectDefaultWindowsShell
():
Promise
<
string
|
undefined
>
;
detectWindowsShells
():
Promise
<
IShellDefinition
[]
>
;
}
export
interface
IShellDefinition
{
label
:
string
;
path
:
string
;
}
export
const
enum
Direction
{
...
...
src/vs/workbench/contrib/terminal/common/terminalService.ts
浏览文件 @
c287c3cf
...
...
@@ -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
_onRequestWindowsShells
=
new
Emitter
<
(
shells
:
IShellDefinition
[])
=>
void
>
();
public
get
onRequestWindowsShells
():
Event
<
(
shells
:
IShellDefinition
[])
=>
void
>
{
return
this
.
_onRequestWindowsShells
.
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
;
...
...
@@ -522,4 +528,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
.
_onRequestWindowsShells
.
fire
(
r
));
}
}
src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts
浏览文件 @
c287c3cf
...
...
@@ -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
{
ITerminalNativeService
,
LinuxDistro
,
IShellDefinition
}
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
{
getWindowsBuildNumber
,
linuxDistro
,
detectWindowsShells
}
from
'
vs/workbench/contrib/terminal/node/terminal
'
;
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,97 +52,8 @@ 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
];
});
public
detectWindowsShells
():
Promise
<
IShellDefinition
[]
>
{
return
detectWindowsShells
();
}
/**
...
...
src/vs/workbench/contrib/terminal/node/terminal.ts
浏览文件 @
c287c3cf
...
...
@@ -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
}
from
'
vs/base/common/path
'
;
export
function
getDefaultShell
(
p
:
platform
.
Platform
):
string
{
if
(
p
===
platform
.
Platform
.
Windows
)
{
...
...
@@ -82,3 +84,68 @@ export function getWindowsBuildNumber(): number {
}
return
buildNumber
;
}
export
async
function
detectWindowsShells
():
Promise
<
IShellDefinition
[]
>
{
console
.
log
(
'
a
'
);
// 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
])));
console
.
log
(
'
$detectWindowsShells
'
);
return
Promise
.
all
(
promises
).
then
(
coalesce
);
}
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录