@@ -15,8 +15,12 @@ import { getBinPath } from './util';
15
15
import vscode = require( 'vscode' ) ;
16
16
import { CommandFactory } from './commands' ;
17
17
18
- // Supports only passing interface, see TODO in implCursor to finish
19
- const inputRegex = / ^ ( \w + \ \* ? \w + \ ) ? ( [ \w \. \- \/ ] + ) $ / ;
18
+ // Accepts input of the form:
19
+ // [f *File] io.Closer [, ...]
20
+ // [f *File] io.Closer
21
+ // io.Closer (type name will be deduced from variable name from cursor position)
22
+ // io.Closer, io.Reader (same as above)
23
+ const inputRegex = / ^ (?< identifier > (?< variable > [ \p{ Letter} _ ] [ \p{ Letter} _ \p{ Number} \d ] * ) * (?< type > [ * ] ? * [ \p{ Letter} _ ] [ \p{ Letter} _ \p{ Number} \d ] * ) + ) ? (?< interfaces > (?: [ \p{ Letter} _ ] [ \p{ Letter} _ \p{ Number} \d \. \- \/ ] * ) + (?: * , * (?: [ \p{ Letter} _ ] [ \p{ Letter} _ \p{ Number} \d \. \- \/ ] * ) + ) * ) $ / u;
20
24
21
25
export const implCursor : CommandFactory = ( ) => ( ) => {
22
26
const editor = vscode . window . activeTextEditor ;
@@ -27,50 +31,72 @@ export const implCursor: CommandFactory = () => () => {
27
31
const cursor = editor . selection ;
28
32
return vscode . window
29
33
. showInputBox ( {
30
- placeHolder : 'f *File io.Closer' ,
34
+ placeHolder : '[ f *File] io.Closer [, ...] ' ,
31
35
prompt : 'Enter receiver and interface to implement.'
32
36
} )
33
37
. then ( ( implInput ) => {
34
38
if ( typeof implInput === 'undefined' ) {
35
39
return ;
36
40
}
37
41
const matches = implInput . match ( inputRegex ) ;
38
- if ( ! matches ) {
42
+ if ( ! matches || ! matches . groups || ! matches . groups . interfaces ) {
39
43
vscode . window . showInformationMessage ( `Not parsable input: ${ implInput } ` ) ;
40
44
return ;
41
45
}
42
46
43
- // TODO: automatically detect type name at cursor
44
- // if matches[1] is undefined then detect receiver type
45
- // take first character and use as receiver name
47
+ let identifier = matches . groups ?. identifier ;
48
+ if ( ! identifier ) {
49
+ const beforeCursor = new vscode . Range ( new vscode . Position ( cursor . start . line , 0 ) , cursor . start ) ;
50
+ const beforeCursorText = editor . document . getText ( beforeCursor ) ;
51
+ const typeIndex = beforeCursorText . lastIndexOf ( 'type' ) ;
52
+ if ( typeIndex === - 1 ) {
53
+ vscode . window . showInformationMessage ( 'No identifier found at cursor.' ) ;
54
+ return ;
55
+ }
46
56
47
- runGoImpl ( [ matches [ 1 ] , matches [ 2 ] ] , cursor . start , editor ) ;
57
+ const variable = editor . document . getText ( cursor ) [ 0 ] . toLowerCase ( ) ;
58
+ identifier = editor . document . getText ( cursor ) ;
59
+ identifier = `${ variable } *${ identifier } ` ;
60
+
61
+ let newPosition = cursor . start . with ( cursor . start . line + 1 , 0 ) ;
62
+ newPosition = newPosition . translate ( 1 , 0 ) ;
63
+ editor . selection = new vscode . Selection ( newPosition , newPosition ) ;
64
+ }
65
+ const interfaces = matches . groups ?. interfaces . trim ( ) . split ( ',' ) ;
66
+ interfaces . forEach ( ( iface , i ) => {
67
+ interfaces [ i ] = iface . trim ( ) ;
68
+ } ) ;
69
+ runGoImpl ( [ identifier , interfaces ] , editor ) ;
48
70
} ) ;
49
71
} ;
50
72
51
- function runGoImpl ( args : string [ ] , insertPos : vscode . Position , editor : vscode . TextEditor ) {
73
+ function runGoImpl ( prompt : [ string , string [ ] ] , editor : vscode . TextEditor ) {
52
74
const goimpl = getBinPath ( 'impl' ) ;
53
- const p = cp . execFile (
54
- goimpl ,
55
- args ,
56
- { env : toolExecutionEnvironment ( ) , cwd : dirname ( editor . document . fileName ) } ,
57
- ( err , stdout , stderr ) => {
58
- if ( err && ( < any > err ) . code === 'ENOENT' ) {
59
- promptForMissingTool ( 'impl' ) ;
60
- return ;
61
- }
75
+ prompt [ 1 ] . forEach ( ( iface ) => {
76
+ const p = cp . execFile (
77
+ goimpl ,
78
+ [ prompt [ 0 ] , iface ] ,
79
+ { env : toolExecutionEnvironment ( ) , cwd : dirname ( editor . document . fileName ) } ,
80
+ ( err , stdout , stderr ) => {
81
+ if ( err && ( < any > err ) . code === 'ENOENT' ) {
82
+ promptForMissingTool ( 'impl' ) ;
83
+ return ;
84
+ }
62
85
63
- if ( err ) {
64
- vscode . window . showInformationMessage ( `Cannot stub interface: ${ stderr } ` ) ;
65
- return ;
66
- }
86
+ if ( err ) {
87
+ vscode . window . showInformationMessage ( `Cannot stub interface: ${ stderr } ` ) ;
88
+ return ;
89
+ }
67
90
68
- editor . edit ( ( editBuilder ) => {
69
- editBuilder . insert ( insertPos , stdout ) ;
70
- } ) ;
91
+ ( function ( out : string ) {
92
+ editor . edit ( ( editBuilder ) => {
93
+ editBuilder . insert ( editor . selection . start , out ) ;
94
+ } ) ;
95
+ } ) ( stdout ) ;
96
+ }
97
+ ) ;
98
+ if ( p . pid ) {
99
+ p . stdin ?. end ( ) ;
71
100
}
72
- ) ;
73
- if ( p . pid ) {
74
- p . stdin ?. end ( ) ;
75
- }
101
+ } ) ;
76
102
}
0 commit comments