1- const sigdatas = require ( './signature-data' ) . default
2-
3- const parse = sd => {
4- const regex = / \( ( [ ^ ) ] + ) \) /
5- const matches = regex . exec ( sd )
6- if ( ! matches ) return [ ]
7- if ( matches . length < 2 ) return [ ]
8- const sps = matches [ 1 ]
9- return sps . split ( "," ) . map ( sp => ( { label : sp } ) )
10- }
1+ const data = require ( './signature.json' )
2+
3+ /*const parse = args => {
4+ if ( !args ) return []
5+ return args.split(",").map( sp => ({ label: sp }))
6+ }*/
117
12- const signatures = sigdatas . map ( sd => {
13- if ( ! sd ) return
14- if ( sd . length < 2 ) return
8+ const signatures = data . map ( sd => {
159 return {
16- label : sd [ 0 ] ,
17- documentation : sd [ 1 ] ,
18- parameters : parse ( sd [ 0 ] )
10+ name : sd . nm ,
11+ label : sd . nm + "( " + sd . args + " )" ,
12+ documentation : sd . nt ,
13+ parameters : sd . args . split ( "," ) . map ( sp => ( { label : sp } ) )
1914 }
2015} )
2116
22- exports . default = {
23- provideSignatureHelp : ( doc , pos ) => {
24-
25- const text = doc . lineAt ( pos . line ) . text . substring ( 0 , pos . character )
26- const parts = text . split ( "(" ) //text before and after (
17+ const callLookup = ( code , commas ) => {
18+ const call = { commas }
19+ let char = '' , i = code . length - 1 ;
20+ for ( ; i >= 0 ; i -- ) {
21+ char = code [ i ]
22+ if ( char === ',' ) call . commas ++
23+ if ( char === '(' ) { // first open parenthesis
24+ let rest = code . substring ( 0 , i ) + "("
25+ var matches = rest . match ( / \S + (? = \( ) / g )
26+ if ( matches . length ) {
27+ //last sequence before (
28+ call . name = matches [ matches . length - 1 ]
29+ }
30+ break
31+ }
32+ }
33+ return call
34+ }
35+
36+ // walk back (and up)
37+ // find word before first open parenthesis
38+ // also calculate commas before first open parenthesis
39+ // return { word, commas: count }
40+ // NOTE: only for simple cases
41+ const walkbackToCall = ( doc , pos ) => {
42+
43+ let line = pos . line
44+ let code = doc . lineAt ( line ) . text
45+ code = code . substring ( 0 , pos . character )
46+
47+ let commas = 0 , maxLines = 10 , call = { }
48+
49+ while ( ! call . name ) {
50+ call = callLookup ( code , commas )
51+ commas = call . commas
2752
28- if ( ! parts . length ) return Promise . resolve ( null )
53+ if ( call . name ) break
54+ if ( ( line -- < 0 ) || ( maxLines -- < 0 ) ) break
2955
30- const ftext = parts [ 0 ]
31- const fwords = ftext . split ( " " )
32- if ( ! fwords . length ) return Promise . resolve ( null )
33-
34- const fname = fwords [ fwords . length - 1 ] ; // last word before '('
35- if ( ! fname ) return Promise . resolve ( null )
36-
37- let activeParameter = 0
38- if ( parts . length === 2 ) {
39- activeParameter = parts [ 1 ] . split ( "," ) . length - 1
40- }
56+ code = doc . lineAt ( line ) . text
57+ }
58+ return call
59+
60+ }
61+
62+ exports . default = {
63+ provideSignatureHelp : ( doc , pos ) => { // function called at "(" and ","
4164
42- const mask = fname . toUpperCase ( )
43- const filtered = signatures . filter ( s => ~ s . label . toUpperCase ( ) . indexOf ( mask ) && ( s . parameters . length > activeParameter ) )
44- return Promise . resolve ( { activeParameter, activeSignature : 0 , signatures : filtered } )
65+ const call = walkbackToCall ( doc , pos ) // returns { name: 'token before'}
66+ if ( ! call . name ) return Promise . resolve ( null )
67+ const mask = call . name . toLowerCase ( )
68+ const filtered = signatures . filter ( s => ~ s . name . indexOf ( mask ) && ( s . parameters . length > call . commas ) )
69+ return Promise . resolve ( { activeParameter : call . commas , activeSignature : 0 , signatures : filtered } )
4570
4671 }
4772}
0 commit comments