@@ -91,13 +91,7 @@ export async function resolveProcessId(config: ResolvingNodeAttachConfiguration,
91
91
*/
92
92
export async function pickProcess ( ) : Promise < string | null > {
93
93
try {
94
- const items = await listProcesses ( ) ;
95
- const options : vscode . QuickPickOptions = {
96
- placeHolder : localize ( 'pickNodeProcess' , 'Pick the node.js process to attach to' ) ,
97
- matchOnDescription : true ,
98
- matchOnDetail : true ,
99
- } ;
100
- const item = await vscode . window . showQuickPick ( items , options ) ;
94
+ const item = await listProcesses ( ) ;
101
95
return item ? item . pidAndPort : null ;
102
96
} catch ( err ) {
103
97
await vscode . window . showErrorMessage (
@@ -116,25 +110,41 @@ const decodePidAndPort = (encoded: string) => {
116
110
return { pid : Number ( pid ) , port : port ? Number ( port ) : undefined } ;
117
111
} ;
118
112
119
- async function listProcesses ( ) : Promise < IProcessItem [ ] > {
113
+ async function listProcesses ( ) : Promise < IProcessItem > {
120
114
const nodeProcessPattern = / ^ (?: n o d e | i o j s ) $ / i;
121
115
let seq = 0 ; // default sort key
122
116
123
- const items = await processTree . lookup < IProcessItem [ ] > ( ( leaf , acc ) => {
124
- if ( process . platform === 'win32' && leaf . command . indexOf ( '\\??\\' ) === 0 ) {
125
- // remove leading device specifier
126
- leaf . command = leaf . command . replace ( '\\??\\' , '' ) ;
127
- }
117
+ const quickPick = await vscode . window . createQuickPick < IProcessItem > ( ) ;
118
+ quickPick . placeholder = localize ( 'pickNodeProcess' , 'Pick the node.js process to attach to' ) ;
119
+ quickPick . matchOnDescription = true ;
120
+ quickPick . matchOnDetail = true ;
121
+ quickPick . busy = true ;
122
+ quickPick . show ( ) ;
123
+
124
+ let hasPicked = false ;
125
+ const itemPromise = new Promise < IProcessItem > ( resolve => {
126
+ quickPick . onDidAccept ( ( ) => resolve ( quickPick . selectedItems [ 0 ] ) ) ;
127
+ quickPick . onDidHide ( ( ) => resolve ( undefined ) ) ;
128
+ } ) ;
129
+
130
+ processTree
131
+ . lookup < IProcessItem [ ] > ( ( leaf , acc ) => {
132
+ if ( hasPicked ) {
133
+ return acc ;
134
+ }
128
135
129
- const executableName = basename ( leaf . command , '.exe' ) ;
130
- const { port } = analyseArguments ( leaf . args ) ;
131
- if ( ! port && ! nodeProcessPattern . test ( executableName ) ) {
132
- return acc ;
133
- }
136
+ if ( process . platform === 'win32' && leaf . command . indexOf ( '\\??\\' ) === 0 ) {
137
+ // remove leading device specifier
138
+ leaf . command = leaf . command . replace ( '\\??\\' , '' ) ;
139
+ }
134
140
135
- return [
136
- ...acc ,
137
- {
141
+ const executableName = basename ( leaf . command , '.exe' ) ;
142
+ const { port } = analyseArguments ( leaf . args ) ;
143
+ if ( ! port && ! nodeProcessPattern . test ( executableName ) ) {
144
+ return acc ;
145
+ }
146
+
147
+ const newItem = {
138
148
label : executableName ,
139
149
description : leaf . args ,
140
150
pidAndPort : encodePidAndPort ( leaf . pid , port ) ,
@@ -148,11 +158,19 @@ async function listProcesses(): Promise<IProcessItem[]> {
148
158
'SIGUSR1' ,
149
159
)
150
160
: localize ( 'process.id.signal' , 'process id: {0} ({1})' , leaf . pid , 'SIGUSR1' ) ,
151
- } ,
152
- ] ;
153
- } , [ ] ) ;
161
+ } ;
162
+
163
+ const index = acc . findIndex ( item => item . sortKey < newItem . sortKey ) ;
164
+ acc . splice ( index === - 1 ? acc . length : index , 0 , newItem ) ;
165
+ quickPick . items = acc ;
166
+ return acc ;
167
+ } , [ ] )
168
+ . then ( ( ) => ( quickPick . busy = false ) ) ;
154
169
155
- return items . sort ( ( a , b ) => b . sortKey - a . sortKey ) ; // sort items by process id, newest first
170
+ const item = await itemPromise ;
171
+ hasPicked = true ;
172
+ quickPick . dispose ( ) ;
173
+ return item ;
156
174
}
157
175
158
176
function putPidInDebugMode ( pid : number ) : void {
0 commit comments