Skip to content

Commit 554a3cb

Browse files
authored
Merge pull request #56 from zardoy/develop
2 parents a04a238 + ffddfe1 commit 554a3cb

17 files changed

+349
-180
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@
1414
],
1515
}
1616
}
17+
],
18+
"githubPullRequests.ignoredPullRequestBranches": [
19+
"develop"
1720
]
1821
}

README.MD

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ usersList.map // -> usersList.map((user) => )
6666

6767
## Minor Useful Features
6868

69+
### `enablePlugin` setting
70+
71+
You can quickly disable this plugin functionality by setting this setting to false. Useful for debugging a problem for example.
72+
6973
### Web Support
7074

7175
> Note: when you open TS/JS file in the web for the first time you currently need to switch editors to make everything work!

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
"@vscode/emmet-helper": "^2.8.4",
7676
"@vscode/test-electron": "^2.1.5",
7777
"@zardoy/utils": "^0.0.9",
78-
"@zardoy/vscode-utils": "^0.0.36",
78+
"@zardoy/vscode-utils": "^0.0.41",
7979
"chai": "^4.3.6",
8080
"chokidar": "^3.5.3",
8181
"chokidar-cli": "^3.0.0",

pnpm-lock.yaml

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

src/apiCommands.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import * as vscode from 'vscode'
2+
import { getExtensionCommandId } from 'vscode-framework'
3+
import { passthroughExposedApiCommands, TriggerCharacterCommand } from '../typescript/src/ipcTypes'
4+
import { sendCommand } from './sendCommand'
5+
6+
export default () => {
7+
const sharedRequest = (type: TriggerCharacterCommand, { offset, relativeOffset = 0 }: RequestOptions) => {
8+
const { activeTextEditor } = vscode.window
9+
if (!activeTextEditor) return
10+
const { document, selection } = activeTextEditor
11+
offset ??= document.offsetAt(selection.active) + relativeOffset
12+
return sendCommand(type, { document, position: document.positionAt(offset) })
13+
}
14+
15+
type RequestOptions = Partial<{
16+
offset: number
17+
relativeOffset: number
18+
}>
19+
for (const cmd of passthroughExposedApiCommands)
20+
vscode.commands.registerCommand(getExtensionCommandId(cmd as never), async (options: RequestOptions = {}) => sharedRequest(cmd, options))
21+
}

src/configurationType.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ type ReplaceRule = {
3434
// For easier testing, specify every default
3535
// TODO support scripting
3636
export type Configuration = {
37+
/**
38+
* Controls wether TypeScript Essentials plugin is enabled or not.
39+
* @default true
40+
*/
41+
enablePlugin: boolean
3742
/**
3843
* Removes `Symbol`, `caller`, `prototype` everywhere
3944
* @default true
@@ -120,10 +125,10 @@ export type Configuration = {
120125
'removeCodeFixes.codefixes': ('fixMissingMember' | 'fixMissingProperties' | 'fixMissingAttributes' | 'fixMissingFunctionDeclaration')[]
121126
/**
122127
* Use full-blown emmet in jsx/tsx files!
123-
* Requires `jsxPseudoEmmet` be off and `emmet.excludeLanguages` to have `javascriptreact` and `typescriptreact`
128+
* Requires `jsxPseudoEmmet.enabled` to be disabled and `emmet.excludeLanguages` to have `javascriptreact` and `typescriptreact`
124129
* @default true
125130
* */
126-
jsxEmmet: boolean
131+
'jsxEmmet.enable': boolean
127132
/**
128133
* Override snippet inserted on `.` literally
129134
* @default false
@@ -141,7 +146,7 @@ export type Configuration = {
141146
* Suggests only common tags such as div
142147
* @default false
143148
*/
144-
jsxPseudoEmmet: boolean
149+
'jsxPseudoEmmet.enable': boolean
145150
/**
146151
* Note: Sorting matters
147152
*/
@@ -275,4 +280,12 @@ export type Configuration = {
275280
}
276281
| false
277282
}
283+
/**
284+
* The integration is enabled, only when this array is not empty
285+
* Integration supports only string within function call
286+
* Examples: `cp.exec(`, `executeShellCommand(`
287+
* @uniqueItems
288+
* @default []
289+
*/
290+
'figIntegration.enableWhenStartsWith': string[]
278291
}

src/emmet.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ export const registerEmmet = async () => {
1919
reactLangs,
2020
{
2121
async provideCompletionItems(document, position, token, context) {
22-
if (!getExtensionSetting('jsxEmmet')) return
22+
if (!getExtensionSetting('jsxEmmet.enable')) return
2323
const emmetConfig = vscode.workspace.getConfiguration('emmet')
2424
if (isEmmetEnabled && !emmetConfig.excludeLanguages.includes(document.languageId)) return
2525

2626
const result = await sendCommand<EmmetResult>('emmet-completions', { document, position })
2727
if (!result) return
28-
const offset = document.offsetAt(position)
28+
const offset: number = document.offsetAt(position)
2929
const sendToEmmet = document.getText().slice(offset + result.emmetTextOffset, offset)
3030
const emmetCompletions = emmet.doComplete(
3131
{

src/extension.ts

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22
import * as vscode from 'vscode'
33
import { defaultJsSupersetLangs } from '@zardoy/vscode-utils/build/langs'
44
import { getActiveRegularEditor } from '@zardoy/vscode-utils'
5-
import { extensionCtx, getExtensionSettingId, getExtensionCommandId, registerActiveDevelopmentCommand } from 'vscode-framework'
5+
import { extensionCtx, getExtensionSettingId } from 'vscode-framework'
66
import { pickObj } from '@zardoy/utils'
7-
import { TriggerCharacterCommand } from '../typescript/src/ipcTypes'
87
import { Configuration } from './configurationType'
98
import webImports from './webImports'
109
import { sendCommand } from './sendCommand'
1110
import { registerEmmet } from './emmet'
1211
import experimentalPostfixes from './experimentalPostfixes'
12+
import migrateSettings from './migrateSettings'
13+
import figIntegration from './figIntegration'
14+
import apiCommands from './apiCommands'
1315

1416
export const activateTsPlugin = (tsApi: { configurePlugin; onCompletionAccepted }) => {
1517
let webWaitingForConfigSync = false
@@ -77,23 +79,6 @@ export const activateTsPlugin = (tsApi: { configurePlugin; onCompletionAccepted
7779
}
7880
})
7981

80-
const sharedRequest = (type: TriggerCharacterCommand, { offset, relativeOffset = 0 }: RequestOptions) => {
81-
const { activeTextEditor } = vscode.window
82-
if (!activeTextEditor) return
83-
const { document, selection } = activeTextEditor
84-
offset ??= document.offsetAt(selection.active) + relativeOffset
85-
return sendCommand(type, { document, position: document.positionAt(offset) })
86-
}
87-
88-
type RequestOptions = Partial<{
89-
offset: number
90-
relativeOffset: number
91-
}>
92-
vscode.commands.registerCommand(getExtensionCommandId('getNodeAtPosition' as never), async (options: RequestOptions = {}) =>
93-
sharedRequest('nodeAtPosition', options),
94-
)
95-
vscode.commands.registerCommand(getExtensionCommandId('getNodePath' as never), async (options: RequestOptions = {}) => sharedRequest('nodePath', options))
96-
9782
if (process.env.PLATFORM === 'web') {
9883
const possiblySyncConfig = async () => {
9984
const { activeTextEditor } = vscode.window
@@ -111,16 +96,14 @@ export const activateTsPlugin = (tsApi: { configurePlugin; onCompletionAccepted
11196
experimentalPostfixes()
11297
void registerEmmet()
11398
webImports()
99+
apiCommands()
114100

115-
// registerActiveDevelopmentCommand(async () => {
116-
// const items: vscode.DocumentSymbol[] = await vscode.commands.executeCommand(
117-
// 'vscode.executeDocumentSymbolProvider',
118-
// vscode.Uri.file(...),
119-
// )
120-
// })
101+
figIntegration()
121102
}
122103

123104
export const activate = async () => {
105+
migrateSettings()
106+
124107
const possiblyActivateTsPlugin = async () => {
125108
const tsExtension = vscode.extensions.getExtension('vscode.typescript-language-features')
126109
if (!tsExtension) return

src/figIntegration.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import * as vscode from 'vscode'
2+
import { defaultJsSupersetLangs } from '@zardoy/vscode-utils/build/langs'
3+
import { getExtensionSetting } from 'vscode-framework'
4+
import { watchExtensionSettings } from '@zardoy/vscode-utils/build/settings'
5+
6+
let integrationActivated = false
7+
const possiblyActivateFigIntegration = async () => {
8+
if (integrationActivated) return
9+
// eslint-disable-next-line sonarjs/no-duplicate-string
10+
if (getExtensionSetting('figIntegration.enableWhenStartsWith').length === 0) return
11+
integrationActivated = true
12+
13+
// todo I think would be good to support zx package $ but not sure if needed
14+
const figExtension = vscode.extensions.getExtension('undefined_publisher.fig-unreleased')
15+
if (!figExtension) return
16+
const api = await figExtension.activate()
17+
18+
api.registerLanguageSupport(
19+
// why include react langs? becuase of ink package!
20+
defaultJsSupersetLangs,
21+
{
22+
async provideSingleLineRangeFromPosition(doc: vscode.TextDocument, position: vscode.Position) {
23+
const enableWhenStartsWith = getExtensionSetting('figIntegration.enableWhenStartsWith')
24+
if (enableWhenStartsWith.length === 0) return
25+
26+
const path: any[] = await vscode.commands.executeCommand('tsEssentialPlugins.getNodePath', {
27+
offset: doc.offsetAt(position.translate(0, -1)),
28+
})
29+
if (!path) return
30+
const lastTwoPaths = path.slice(-2)
31+
const kinds = lastTwoPaths.map(({ kindName }) => kindName)
32+
if (kinds[0] !== 'CallExpression' || !['StringLiteral', 'FirstTemplateToken'].includes(kinds[1])) return
33+
// todo use info from ts server isntead
34+
const callExpr = lastTwoPaths[0]
35+
const stringNode = lastTwoPaths[1]
36+
const callExpressionText = doc.getText(new vscode.Range(doc.positionAt(callExpr.start), doc.positionAt(callExpr.end)))
37+
if (enableWhenStartsWith.every(str => !callExpressionText.startsWith(str))) return
38+
return new vscode.Range(doc.positionAt((stringNode.start as number) + 1), doc.positionAt(stringNode.end - 1))
39+
},
40+
},
41+
{
42+
// don't collide with TS rename provider
43+
disableProviders: ['rename'],
44+
enableCompletionProvider: {
45+
processCompletions(completions) {
46+
// make it above vscode snippets, maybe should make it builtin?
47+
return completions.map(({ sortText = '', ...compl }) => ({ ...compl, sortText: `!${sortText}` }))
48+
},
49+
},
50+
},
51+
)
52+
}
53+
54+
export default () => {
55+
void possiblyActivateFigIntegration()
56+
watchExtensionSettings(['figIntegration.enableWhenStartsWith'], () => {
57+
void possiblyActivateFigIntegration()
58+
})
59+
}

src/migrateSettings.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { migrateExtensionSettings } from '@zardoy/vscode-utils/build/migrateSettings'
2+
3+
export default () => {
4+
void migrateExtensionSettings(
5+
[
6+
{
7+
rename: {
8+
old: 'jsxEmmet',
9+
new: 'jsxEmmet.enable',
10+
mustBePrimitive: true,
11+
},
12+
},
13+
{
14+
rename: {
15+
old: 'jsxPseudoEmmet',
16+
new: 'jsxPseudoEmmet.enable',
17+
mustBePrimitive: true,
18+
},
19+
},
20+
],
21+
process.env.IDS_PREFIX!,
22+
)
23+
}

0 commit comments

Comments
 (0)