Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
856c80b
v0.3.9 - Added a new configuration option to enable or disable escapi…
Apr 30, 2025
97c3f9c
v0.3.9 - Added packaging task
Apr 30, 2025
78a3562
v0.3.9 - Added packaging task
Apr 30, 2025
b326c8e
v0.3.9 - Added packaging task
Apr 30, 2025
4e8bb00
v0.3.9 - Removed code-workspace from repo
Apr 30, 2025
3c07a94
v0.3.9 - Reverted default configuration override for PowerShell. Unab…
Apr 30, 2025
4c9a3cb
添加 .prettierignore 文件以忽略 package-lock.json
wenfangdu May 13, 2025
bf44be0
refactor: format package.json for improved readability and maintainab…
wenfangdu May 13, 2025
bc34a47
fix: 修复未激活文本编辑器和未选择文本时的错误处理
wenfangdu May 13, 2025
0b866c1
fix: 更新剪贴板信息提示,指导用户如何粘贴代码片段
wenfangdu May 13, 2025
ee24849
fix: 简化正则表达式逻辑以处理特殊变量转义
wenfangdu May 13, 2025
6b4d9b3
refactor: 移除冗余注释以提高代码清晰度
wenfangdu May 13, 2025
74e1cb3
fix: 更新剪贴板信息提示,指导用户如何粘贴代码片段
wenfangdu May 13, 2025
e849aed
fix: 修正变更日志标题的拼写错误
wenfangdu May 13, 2025
07d8bc8
fix: 修正变更日志标题的格式
wenfangdu May 13, 2025
0f611f4
fix: 移除冗余的打包脚本命令
wenfangdu May 13, 2025
10c90fb
docs: 添加设置部分,说明特殊变量的处理方式
wenfangdu May 13, 2025
8e1422b
fix: 修正变更日志中的布尔值格式,更新剪贴板信息提示
wenfangdu May 13, 2025
b17372a
fix: 更新版本号至0.4.0
wenfangdu May 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ node_modules
.vscode-test/
*.vsix
.DS_Store
build/
*.code-workspace
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock.json
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Changelog for Snippet Generator

## [0.3.9]

1. Added a configuration option ( `doNotEscapeSpecialVariables` ) that will not escape special variables when they correspond to [special snippet syntax constructs](https://code.visualstudio.com/docs/editing/userdefinedsnippets#_snippet-syntax). The default is `true` and this behavior is identical to how the plugin has always functioned.
2. This includes text that starts with a dollar sign and follows the format of `$name`, `${name:default}`, or `$TM_SELECTED_TEXT`. Any text that follows this naming pattern will not be escaped.
3. If `doNotEscapeSpecialVariables` is set to `false`, then all instances of the dollar sign will be escaped with double backslashes.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ Command: `Generate Snippet`

![Demo](https://github.com/raw/wenfangdu/vscode-snippet-generator/main/images/demo.gif)

## Settings

`snippet-generator.doNotEscapeSpecialVariables`: Do not escape special snippet variables that follow the syntax of `$name`, `${name:somevalue}`, or `$TM_SELECTED_TEXT`. (`true` by default, thanks [@Jay](https://github.com/futuremotiondev))

## Inspired By

- [Johnson Chu's comment](https://github.com/johnsoncodehk/volar/issues/183#issuecomment-842804053)
Expand Down
164 changes: 92 additions & 72 deletions extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,79 +3,99 @@
const { commands, window, workspace, env } = require('vscode')

exports.activate = ({ subscriptions }) => {
const disposable = commands.registerCommand('snippet-generator.generate-snippet', async () => {
const editor = window.activeTextEditor

if (!editor) {
return window.showErrorMessage('No active text editor')
}

const selection = editor.document.getText(editor.selection)

if (!selection.length) {
return window.showErrorMessage('No selected text')
}

const name = await window.showInputBox({
placeHolder: 'Please enter name (required)',
validateInput: input => (input ? '' : 'Name is required'),
})

if (name === undefined) {
return
}

const scope = await window.showInputBox({
placeHolder: 'Please enter scope (optional)',
})

if (scope === undefined) {
return
let doNotEscapeSpecialVariables = workspace
.getConfiguration('snippet-generator')
.get('doNotEscapeSpecialVariables')

const respondToConfigChange = workspace.onDidChangeConfiguration(event => {
if (event.affectsConfiguration('snippet-generator')) {
doNotEscapeSpecialVariables = workspace
.getConfiguration('snippet-generator')
.get('doNotEscapeSpecialVariables')
}

const prefix = await window.showInputBox({
placeHolder: 'Please enter prefix (required)',
validateInput: input => (input ? '' : 'Prefix is required'),
})

if (prefix === undefined) {
return
}

const description = await window.showInputBox({
placeHolder: 'Please enter description (optional)',
})

if (description === undefined) {
return
}

const tabSize = workspace.getConfiguration('editor').get('tabSize')

const spaces = new RegExp(` {${tabSize}}`, 'g')

const snippetObj = {
[name]: {
...(scope && { scope }),
prefix,
body: selection
.split(/\r?\n/)
.map(line => line.replace(/\$(?![\d{]|TM_)/g, '\\$').replace(spaces, '\t')),
...(description && { description }),
},
}

const snippetJSON = JSON.stringify(snippetObj, null, tabSize)
.split('\n')
.slice(1, -1)
.join('\n')

env.clipboard.writeText(`${snippetJSON},`)

window.showInformationMessage(
'Snippet has been copied into the clipboard, please use the command "Snippets: Configure User Snippets" to paste it.',
)
})

subscriptions.push(disposable)
const generateSnippetCommand = commands.registerCommand(
'snippet-generator.generate-snippet',
async () => {
const editor = window.activeTextEditor

if (!editor) {
window.showErrorMessage('Error: No text editor is active')
return
}

const selection = editor.document.getText(editor.selection)

if (!selection.length) {
window.showErrorMessage('Error: No text is selected')
return
}

const name = await window.showInputBox({
placeHolder: 'Please enter snippet name (required)',
validateInput: input => (input ? '' : 'Snippet Name is required'),
})

if (name === undefined) {
return
}

const scope = await window.showInputBox({
placeHolder: 'Please enter a scope (optional)',
})

if (scope === undefined) {
return
}

const prefix = await window.showInputBox({
placeHolder: 'Please enter a prefix for intellisense (required)',
validateInput: input => (input ? '' : 'Snippet Prefix is required'),
})

if (prefix === undefined) {
return
}

const description = await window.showInputBox({
placeHolder: 'Please enter a description (optional)',
})

if (description === undefined) {
return
}

const tabSize = workspace.getConfiguration('editor').get('tabSize')

const spaces = new RegExp(` {${tabSize}}`, 'g')

const regex = doNotEscapeSpecialVariables ? /\$(?![\d{]|TM_)/g : /\$/g

const snippetObj = {
[name]: {
...(scope && { scope }),
prefix,
body: selection
.split(/\r?\n/)
.map(line => line.replace(regex, '\\$').replace(spaces, '\t')),
...(description && { description }),
},
}

const snippetJSON = JSON.stringify(snippetObj, null, tabSize)
.split('\n')
.slice(1, -1)
.join('\n')

env.clipboard.writeText(`${snippetJSON},`)

window.showInformationMessage(
'Snippet has been copied, please use the command "Snippets: Configure Snippets" to paste it.',
)
},
)

subscriptions.push(generateSnippetCommand)
subscriptions.push(respondToConfigChange)
}
Loading