Skip to content

Commit 073aa08

Browse files
committed
improve signature, restore snippets
1 parent 1b1dfcd commit 073aa08

File tree

7 files changed

+94
-43
lines changed

7 files changed

+94
-43
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ All notable changes to the "vscode-pgsql" extension will be documented in this f
33

44
## [Unreleased]
55

6+
## 0.1.0
7+
### Changed
8+
- Signature loaded from Postgres 9.5
9+
### Fixed
10+
- Signature completion for multiline scenario
11+
- Restore snippets
12+
613
## 0.0.9
714
### Fixed
815
- Signature completion

extension/signature-update.bat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
psql -U postgres -f signature.sql -t -o signature.json postgres

extension/signature.js

Lines changed: 61 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,72 @@
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
}

extension/signature.json

Lines changed: 2 additions & 0 deletions
Large diffs are not rendered by default.

extension/signature.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
With signatures as (
2+
Select --n.nspname || '.' ||
3+
p.proname as nm, --name
4+
pg_catalog.pg_get_function_arguments(p.oid) as "args",
5+
pg_catalog.pg_get_function_result(p.oid) as "ret", --returns
6+
d.description as nt --note
7+
From pg_catalog.pg_proc p
8+
Left Join pg_catalog.pg_namespace n ON n.oid = p.pronamespace
9+
Left Join pg_catalog.pg_description d On p.oid = d.objoid
10+
Where pg_catalog.pg_function_is_visible(p.oid)
11+
And p.prorettype <> 'pg_catalog.trigger'::pg_catalog.regtype
12+
--AND n.nspname <> 'pg_catalog'
13+
--AND n.nspname <> 'information_schema'
14+
Order By 1
15+
) Select array_to_json( array_agg( s.* ) ) From signatures s;

extension/snippets.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
"prefix": "pgsql",
44
"body": [
55
"Select * ",
6-
"From ${tableName}",
6+
"From ${1:tableName}",
77
"Where 1=1 And id = ? ",
88
";"
99
],
10-
"description": "Insert 'Select * From ... Where ... ' statement"
10+
"description": "Insert 'Select From Where' statement"
1111
},
1212

1313
"Create Function": {
1414
"prefix": "pgsql",
1515
"body": [
16-
"Create Or Replace Function ${funcName}( data json ) Returns json As $$",
16+
"Create Or Replace Function ${1:funcName}( data json ) Returns json As $$",
1717
"\tDeclare",
1818
"\t\t-- declare variables",
1919
"\t\t-- for example: id int := Cast( data->>'id' as int ); ",
@@ -29,14 +29,14 @@
2929
"Create Table": {
3030
"prefix": "pgsql",
3131
"body": [
32-
"Create Table ${tableName} (",
32+
"Create Table ${1:tableName} (",
3333
"\tid serial primary key,",
3434
"\tcd text not null,",
3535
"\tnm text,",
3636
"\t--ref int references another.table,",
3737
"\tcreated timestamptz default now()",
3838
");",
39-
"Create Index on ${tableName} (cd);"
39+
"Create Index on ${1:tableName} (cd);"
4040
],
4141
"description": "Insert 'Create Table ...' statement"
4242
}

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "pgsql",
33
"description": "run sql in your postgres instance",
44
"license": "MIT",
5-
"version": "0.0.9",
5+
"version": "0.1.0",
66
"publisher": "doublefint",
77
"engines": {
88
"vscode": "^1.19.0"
@@ -68,7 +68,8 @@
6868
"description": "connection string to your postgres db"
6969
}
7070
}
71-
}
71+
},
72+
"snippets": [ { "language": "pgsql", "path": "./extension/snippets.json" } ]
7273
},
7374
"scripts": {
7475
"postinstall": "node ./node_modules/vscode/bin/install",

0 commit comments

Comments
 (0)