Skip to content

Commit d9e0df7

Browse files
authored
Add menu command to "Open Primer documentation for variable" (#43)
* add Open Primer documentation for variable * update docs
1 parent 114d918 commit d9e0df7

8 files changed

Lines changed: 61 additions & 34 deletions

File tree

.github/content/definition.gif

-2.87 MB
Binary file not shown.

.github/content/documentation.gif

1.65 MB
Loading

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ Hover over a variable to see its value. Or values in the case of colors across d
2727

2828
![Hover preview](https://raw.githubusercontent.com/primer/primitives-vscode-extension/refs/heads/main/.github/content/hover.gif)
2929

30-
## Go to definition in Docs
30+
## Open documentation for variable
3131

32-
Right click -> `Go to definition` to open documentation in a preview within VSCode.
32+
Right click -> `Open Primer documentation for variable` to open documentation in a preview within VSCode.
3333

34-
![Open definition in docs](https://raw.githubusercontent.com/primer/primitives-vscode-extension/refs/heads/main/.github/content/definition.gif)
34+
![Open documentation for variable](https://raw.githubusercontent.com/primer/primitives-vscode-extension/refs/heads/main/.github/content/documentation.gif)
3535

3636
 
3737

package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,23 @@
1212
"activationEvents": [
1313
"onStartupFinished"
1414
],
15+
"contributes": {
16+
"menus": {
17+
"editor/context": [
18+
{
19+
"command": "primer-primitives-autocomplete.openDocs",
20+
"group": "navigation@100",
21+
"when": "editorTextFocus && editorHasHoverProvider"
22+
}
23+
]
24+
},
25+
"commands": [
26+
{
27+
"command": "primer-primitives-autocomplete.openDocs",
28+
"title": "Open Primer documentation for variable"
29+
}
30+
]
31+
},
1532
"repository": {
1633
"type": "git",
1734
"url": "https://github.com/primer/primitives-vscode-extension.git"

src/index.ts

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import {join} from 'node:path'
2-
import {workspace, ExtensionContext, window, ViewColumn, WebviewPanel} from 'vscode'
2+
import {workspace, ExtensionContext, window, ViewColumn, WebviewPanel, commands} from 'vscode'
33
import {LanguageClient, LanguageClientOptions, ServerOptions, TransportKind} from 'vscode-languageclient/node'
4+
import {getCssVariable} from './utils/get-css-variable'
5+
import {getVariableInfo} from './utils/get-variable-info'
6+
import {getCurrentWord} from './utils/get-current-word'
47

58
let client: LanguageClient
69

@@ -57,19 +60,39 @@ export function activate(context: ExtensionContext) {
5760

5861
let panel: WebviewPanel
5962

60-
client.onRequest('open-docs', ({variable, openPanelIfClosed = true}) => {
61-
if (!panel && openPanelIfClosed) {
63+
commands.registerCommand('primer-primitives-autocomplete.openDocs', async () => {
64+
const editor = window.activeTextEditor
65+
if (!editor) return
66+
67+
const document = editor.document
68+
if (!document) return null
69+
70+
const position = editor.selection.active
71+
const offset = document.offsetAt(position)
72+
const variableName = getCssVariable(document, offset)
73+
if (!variableName) {
74+
const currentWord = getCurrentWord(document, offset)
75+
window.showInformationMessage(`Unrecognized variable: ${currentWord}. Cannot open Primer documentation.`)
76+
return null
77+
}
78+
79+
const variableInfo = getVariableInfo(variableName)
80+
if (!variableInfo) {
81+
const currentWord = getCurrentWord(document, offset)
82+
window.showInformationMessage(`Unrecognized variable: ${currentWord}. Cannot open Primer documentation.`)
83+
return null
84+
}
85+
86+
if (!panel) {
6287
panel = window.createWebviewPanel('custom view type', 'Primer Primitives', ViewColumn.Beside, {
6388
enableScripts: true,
6489
enableFindWidget: true,
6590
})
6691
panel.onDidDispose(() => (panel = null))
6792
}
6893

69-
if (panel) {
70-
panel.title = variable.name
71-
72-
panel.webview.html = `
94+
panel.title = variableInfo.name
95+
panel.webview.html = `
7396
<style>
7497
body {
7598
padding: 0;
@@ -88,17 +111,16 @@ export function activate(context: ExtensionContext) {
88111
89112
</style>
90113
91-
<a href=${variable.docsUrl}>
114+
<a href=${variableInfo.docsUrl}>
92115
Open in Browser
93116
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
94117
<path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path>
95118
</svg>
96119
</a>
97120
98-
<iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="${variable.docsUrl}"></iframe>
121+
<iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="${variableInfo.docsUrl}"></iframe>
99122
100123
`
101-
}
102124
})
103125
}
104126

src/language-server.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import camelCase from 'lodash.camelcase'
1616
import {isColor} from './utils/is-color'
1717
import {getSuggestions, getSuggestionsLikeVariable, type SuggestionWithSortText} from './suggestions'
1818
import {getCssVariable} from './utils/get-css-variable'
19-
import {getVariableInfo} from './utils/get-variable-info'
2019
import {getDocumentation} from './documentation'
2120
import {getCurrentWord} from './utils/get-current-word'
2221

@@ -34,7 +33,6 @@ connection.onInitialize(async () => {
3433
completionProvider: {resolveProvider: true, triggerCharacters: [':']},
3534
hoverProvider: true,
3635
textDocumentSync: TextDocumentSyncKind.Incremental,
37-
definitionProvider: true,
3836
},
3937
}
4038

@@ -163,21 +161,6 @@ connection.onHover(params => {
163161
return {contents: {kind: 'markdown', value: documentation}} as Hover
164162
})
165163

166-
connection.onDefinition(params => {
167-
const doc = documents.get(params.textDocument.uri)
168-
if (!doc) return null
169-
170-
const offset = doc.offsetAt(params.position)
171-
const variableName = getCssVariable(doc, offset)
172-
if (!variableName) return null
173-
174-
const variableInfo = getVariableInfo(variableName)
175-
if (!variableInfo) return null
176-
177-
connection.sendRequest('open-docs', {variable: variableInfo})
178-
return null
179-
})
180-
181164
// Make the text document manager listen on the connection
182165
// for open, change and close text document events
183166
documents.listen(connection)

src/utils/get-css-variable.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
import {TextDocument} from 'vscode-languageserver-textdocument'
1+
import {TextDocument as LanguageServerTextDocument} from 'vscode-languageserver-textdocument'
2+
import {TextDocument as VSCodeTextDocument} from 'vscode'
23
import {getCurrentWord} from './get-current-word'
34

45
/**
56
* Extracts a CSS variable name from the current cursor position.
67
* @returns The CSS variable name (e.g., '--color-red') or null if not found
78
*/
8-
export function getCssVariable(document: TextDocument, offset: number): `--${string}` | null {
9+
export function getCssVariable(
10+
document: LanguageServerTextDocument | VSCodeTextDocument,
11+
offset: number,
12+
): `--${string}` | null {
913
const currentWord = getCurrentWord(document, offset)
1014

1115
const match = currentWord.match(/--[a-zA-Z0-9-]+/)

src/utils/get-current-word.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import {TextDocument} from 'vscode-languageserver-textdocument'
1+
import {TextDocument as LanguageServerTextDocument} from 'vscode-languageserver-textdocument'
2+
import {TextDocument as VSCodeTextDocument} from 'vscode'
23

3-
export function getCurrentWord(document: TextDocument, offset: number): string {
4+
export function getCurrentWord(document: LanguageServerTextDocument | VSCodeTextDocument, offset: number): string {
45
const text = document.getText()
56
const delimiters = ' \t\n\r":{[()]},*>+'
67

0 commit comments

Comments
 (0)