Skip to content

Commit 8f884d1

Browse files
authored
Merge pull request #116 from zardoy/develop
2 parents f2296a7 + 9641211 commit 8f884d1

34 files changed

+1024
-517
lines changed

.vscode/launch.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
],
1616
"sourceMaps": true,
1717
"env": {
18-
"TSS_DEBUG": "9229",
19-
"TSS_REMOTE_DEBUG": "9229"
18+
"TSS_DEBUG": "9223",
19+
"TSS_REMOTE_DEBUG": "9223"
2020
}
2121
},
2222
{

README.MD

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ const usersList = []
6767
usersList.map // -> usersList.map((user) => )
6868
```
6969

70+
### Locality Bonus
71+
72+
(*disabled by default*, SUPER recommended, enable with `suggestions.localityBonus`)
73+
74+
Suggestions closer to cursor will appear higher, useful for local variables (eg callback parameters), requires TS >=5.0
75+
76+
Why not enable built-in *Locality Bonus* setting:
77+
78+
- Sometimes it just doesn't work
79+
- In other cases it might lead to misleading suggestions (as it's text-based and not smart)
80+
7081
### Case-sensitive Completions
7182

7283
(*disabled by default*)
@@ -256,6 +267,7 @@ There are value descriptions for two settings:
256267
257268
```ts
258269
const example = ({ a }, b?, c = 5, ...d) => { }
270+
259271
// binding-name (default)
260272
example({ a }, b, c, ...d)
261273
// always-declaration (also popular)
@@ -268,11 +280,14 @@ example(__0, b, c, d)
268280
269281
```ts
270282
const example = ({ a }, b?, c = 5, ...d) => { }
283+
271284
// only-rest
272285
example({ a }, b, c)
273-
// optional-and-rest
286+
// optional-and-rest (default)
274287
example({ a })
275-
// no-skip (default)
288+
// all
289+
example() // (cursor inside)
290+
// no-skip (popular)
276291
example({ a }, b, c, ...d)
277292
```
278293
@@ -300,6 +315,22 @@ function Foo() {
300315
}
301316
```
302317

318+
### Ambiguous Suggestions
319+
320+
Some variables like `Object` or `lodash` are common to access properties as well as call directly:
321+
322+
```ts
323+
Object.assign(...)
324+
Object()
325+
// or
326+
lodash.version
327+
lodash(...)
328+
```
329+
330+
To not be annoying, we don't insert a method snippet on such suggestion accept.
331+
332+
Instead, for these *ambiguous* suggestions we require you to accept the same suggestion twice to ensure you actually want a method snippet.
333+
303334
## Auto Imports
304335

305336
With this plugin you have total (almost) control over auto imports that appear in completions, quick fixes and import all quick fix. Some examples of what you can do:

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
{
22
"name": "ts-essential-plugins",
33
"displayName": "TypeScript Essential Plugins",
4-
"version": "0.0.1",
4+
"version": "0.0.0-dev",
55
"license": "MIT",
6-
"preview": true,
76
"web": true,
87
"contributes": {
98
"commands": [
@@ -111,7 +110,7 @@
111110
"@types/fs-extra": "^9.0.13",
112111
"@types/node": "^16.11.21",
113112
"@types/semver": "^7.3.13",
114-
"@types/vscode": "^1.63.1",
113+
"@types/vscode": "1.72.0",
115114
"@zardoy/tsconfig": "^1.3.1",
116115
"esbuild": "^0.16.16",
117116
"fs-extra": "^10.1.0",

pnpm-lock.yaml

Lines changed: 17 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/apiCommands.ts

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,58 @@ import { getExtensionCommandId } from 'vscode-framework'
33
import { passthroughExposedApiCommands, TriggerCharacterCommand } from '../typescript/src/ipcTypes'
44
import { sendCommand } from './sendCommand'
55

6-
export default () => {
7-
/** @unique */
8-
const cacheableCommands: Set<(typeof passthroughExposedApiCommands)[number]> = new Set(['getNodePath', 'getSpanOfEnclosingComment', 'getNodeAtPosition'])
9-
const operationsCache = new Map<string, { key: string; data; time?: number }>()
10-
const sharedRequest = async (type: TriggerCharacterCommand, { offset, relativeOffset = 0, document, position }: RequestOptions) => {
11-
if (position && offset) throw new Error('Only position or offset parameter can be provided')
12-
if (document && !offset && !position) throw new Error('When custom document is provided, offset or position must be provided')
6+
type RequestOptions = Partial<{
7+
/**
8+
* Should be rarely overrided, this document must be part of opened project
9+
* If specificed, offset or position must be provided too
10+
*/
11+
document: vscode.TextDocument
12+
offset: number
13+
relativeOffset: number
14+
position: vscode.Position
15+
}>
1316

14-
const { activeTextEditor } = vscode.window
15-
document ??= activeTextEditor?.document
16-
if (!document) return
17-
if (!position) offset ??= document.offsetAt(activeTextEditor!.selection.active) + relativeOffset
18-
const requestOffset = offset ?? document.offsetAt(position!)
19-
const requestPos = position ?? document.positionAt(offset!)
20-
const getData = async () => sendCommand(type, { document: document!, position: requestPos })
21-
const CACHE_UNDEFINED_TIMEOUT = 1000
22-
if (cacheableCommands.has(type as any)) {
23-
const cacheEntry = operationsCache.get(type)
24-
const operationKey = `${document.uri.toString()}:${document.version}:${requestOffset}`
25-
if (cacheEntry?.key === operationKey && cacheEntry?.time && Date.now() - cacheEntry.time < CACHE_UNDEFINED_TIMEOUT) {
26-
return cacheEntry.data
27-
}
17+
/** @unique */
18+
const cacheableCommands: Set<(typeof passthroughExposedApiCommands)[number]> = new Set(['getNodePath', 'getSpanOfEnclosingComment', 'getNodeAtPosition'])
19+
const operationsCache = new Map<string, { key: string; data; time?: number }>()
20+
export const sharedApiRequest = async (type: TriggerCharacterCommand, { offset, relativeOffset = 0, document, position }: RequestOptions) => {
21+
if (position && offset) throw new Error('Only position or offset parameter can be provided')
22+
if (document && !offset && !position) throw new Error('When custom document is provided, offset or position must be provided')
2823

29-
const data = getData()
30-
// intentionally storing data only per one offset because it was created for this specific case:
31-
// extension 1 completion provider requests API data
32-
// at the same time:
33-
// extension 2 completion provider requests API data at the same document and position
34-
// and so on
35-
operationsCache.set(type, { key: operationKey, data, time: data === undefined ? Date.now() : undefined })
36-
if (type === 'getNodePath') {
37-
operationsCache.set('getNodeAtPosition', { key: operationKey, data: data.then((path: any) => path?.[path.length - 1]) })
38-
}
24+
const { activeTextEditor } = vscode.window
25+
document ??= activeTextEditor?.document
26+
if (!document) return
27+
if (!position) offset ??= document.offsetAt(activeTextEditor!.selection.active) + relativeOffset
28+
const requestOffset = offset ?? document.offsetAt(position!)
29+
const requestPos = position ?? document.positionAt(offset!)
30+
const getData = async () => sendCommand(type, { document: document!, position: requestPos })
31+
const CACHE_UNDEFINED_TIMEOUT = 1000
32+
if (cacheableCommands.has(type as any)) {
33+
const cacheEntry = operationsCache.get(type)
34+
const operationKey = `${document.uri.toString()}:${document.version}:${requestOffset}`
35+
if (cacheEntry?.key === operationKey && cacheEntry?.time && Date.now() - cacheEntry.time < CACHE_UNDEFINED_TIMEOUT) {
36+
return cacheEntry.data
37+
}
3938

40-
return data
39+
const data = getData()
40+
// intentionally storing data only per one offset because it was created for this specific case:
41+
// extension 1 completion provider requests API data
42+
// at the same time:
43+
// extension 2 completion provider requests API data at the same document and position
44+
// and so on
45+
operationsCache.set(type, { key: operationKey, data, time: data === undefined ? Date.now() : undefined })
46+
if (type === 'getNodePath') {
47+
operationsCache.set('getNodeAtPosition', { key: operationKey, data: data.then((path: any) => path?.[path.length - 1]) })
4148
}
4249

43-
return getData()
50+
return data
4451
}
4552

46-
type RequestOptions = Partial<{
47-
/**
48-
* Should be rarely overrided, this document must be part of opened project
49-
* If specificed, offset or position must be provided too
50-
*/
51-
document: vscode.TextDocument
52-
offset: number
53-
relativeOffset: number
54-
position: vscode.Position
55-
}>
56-
for (const cmd of passthroughExposedApiCommands)
57-
vscode.commands.registerCommand(getExtensionCommandId(cmd as never), async (options: RequestOptions = {}) => sharedRequest(cmd, options))
53+
return getData()
54+
}
55+
56+
export default () => {
57+
for (const cmd of passthroughExposedApiCommands) {
58+
vscode.commands.registerCommand(getExtensionCommandId(cmd as never), async (options: RequestOptions = {}) => sharedApiRequest(cmd, options))
59+
}
5860
}

0 commit comments

Comments
 (0)