VSCode插件开发:春联生成模型代码辅助工具

最近在写一些带有传统文化元素的项目时,我常常需要为页面或功能添加春联内容。手动编写不仅耗时,而且很难保证对仗工整、寓意吉祥。于是,我就想,能不能在VSCode里直接调用一个模型,让它帮我生成符合上下文的春联呢?

这个想法催生了今天要分享的这个工具:一个集成在VSCode里的春联生成代码辅助插件。它能在你写代码时,根据注释或简单的描述,快速生成对应的春联文本,并一键插入到代码中。无论是为春节主题的网站添加装饰,还是为游戏内的场景设计文案,都能省去不少查资料和构思的时间。

接下来,我就带你一步步把这个想法变成现实,从插件的骨架搭建到与模型的“对话”,最后完成一个即开即用的实用工具。

1. 项目构思与环境搭建

在动手写代码之前,我们先明确一下这个插件要做什么,以及需要准备哪些东西。

简单来说,我们希望实现这样一个功能:开发者在代码文件里,通过一个简单的命令(比如输入特定注释),插件就能唤出一个输入框。开发者输入主题,比如“乔迁之喜”或“科技公司开业”,插件便调用后端的春联生成模型,将生成的结果以代码片段的形式插入到当前光标位置。

为了实现它,我们需要准备两个核心部分:

  1. VSCode插件开发环境:这是前端,负责与开发者交互。
  2. 春联生成模型API:这是后端,负责真正的文本生成。为了简化,我们可以假设已经有一个提供HTTP接口的模型服务。

首先,我们来搭建VSCode插件的开发环境。这比你想象的要简单。

1.1 初始化插件项目

确保你安装了Node.js和npm。然后,全局安装VSCode插件生成器:

npm install -g yo generator-code

安装完成后,找一个合适的目录,运行以下命令来生成一个插件项目骨架:

yo code

这时,命令行会交互式地询问你几个问题。对于我们的项目,可以这样选择:

  • What type of extension do you want to create? 选择 New Extension (TypeScript)。TypeScript能提供更好的类型提示,减少错误。
  • What's the name of your extension? 输入 couplet-helper
  • What's the identifier of your extension? 直接按回车用默认值。
  • What's the description of your extension? 输入 A VSCode extension that generates couplets based on context.
  • Initialize a git repository? 按需选择,建议选 Yes
  • Which package manager to use? 选择 npm

等待命令执行完毕,一个基本的插件项目就创建好了。用VSCode打开这个新生成的文件夹,你会看到类似下面的结构:

couplet-helper/
├── .vscode/
├── src/
│   └── extension.ts    # 插件的入口文件
├── package.json        # 插件的配置文件
├── tsconfig.json
└── ...其他配置文件

最关键的两个文件是 package.jsonsrc/extension.tspackage.json 定义了插件的名称、命令、激活条件等元信息;extension.ts 则是插件逻辑开始的地方。

1.2 配置插件基本信息

打开 package.json,我们需要修改和添加一些配置。找到 contributes 字段,它现在可能是空的。我们将在这里定义插件提供的命令。

{
  "contributes": {
    "commands": [
      {
        "command": "couplet-helper.generate",
        "title": "生成春联"
      }
    ],
    "menus": {
      "editor/context": [
        {
          "command": "couplet-helper.generate",
          "group": "navigation",
          "when": "editorTextFocus"
        }
      ]
    }
  }
}

这段配置做了两件事:

  1. 注册了一个名为 couplet-helper.generate 的命令,并在命令面板中显示为“生成春联”。
  2. 将这个命令添加到编辑器的右键上下文菜单中,方便快速调用。

2. 核心功能实现:连接模型与交互

环境搭好了,命令也注册了,现在我们来写核心逻辑。所有的逻辑都将写在 src/extension.ts 文件中。

2.1 激活插件与注册命令

首先,我们修改 activate 函数。这个函数在插件被激活时调用,是我们注册命令监听器的地方。

import * as vscode from 'vscode';

// 假设的模型API地址,在实际使用时需要替换成你自己的服务地址
const MODEL_API_URL = 'https://your-couplet-model-service.com/generate';

export function activate(context: vscode.ExtensionContext) {
    // 注册命令
    let disposable = vscode.commands.registerCommand('couplet-helper.generate', async () => {
        // 命令被触发时,执行这里的代码
        await generateCouplet();
    });

    context.subscriptions.push(disposable);
}

async function generateCouplet() {
    // 核心生成函数,下一步我们来实现它
}

2.2 实现用户交互与API调用

现在,我们来丰满 generateCouplet 函数。它的工作流程是:

  1. 弹出一个输入框,让用户输入春联的主题或关键词。
  2. 将用户输入发送给春联生成模型的API。
  3. 收到模型返回的结果后,将其插入到当前编辑器的光标位置。
import * as vscode from 'vscode';
import axios from 'axios'; // 需要安装axios库:npm install axios

const MODEL_API_URL = 'https://your-couplet-model-service.com/generate';

async function generateCouplet() {
    // 1. 获取当前活动的文本编辑器
    const editor = vscode.window.activeTextEditor;
    if (!editor) {
        vscode.window.showWarningMessage('请在编辑器中点击右键使用此功能。');
        return;
    }

    // 2. 弹出输入框获取用户主题
    const userTheme = await vscode.window.showInputBox({
        placeHolder: '请输入春联主题,例如:新春快乐、开业大吉',
        prompt: '模型将根据您输入的主题生成春联'
    });

    // 如果用户取消了输入,则直接返回
    if (userTheme === undefined) {
        return;
    }

    // 3. 显示一个进度提示,告诉用户正在生成
    vscode.window.withProgress({
        location: vscode.ProgressLocation.Notification,
        title: '正在生成春联...',
        cancellable: false
    }, async (progress) => {
        try {
            // 4. 调用模型API
            const response = await axios.post(MODEL_API_URL, {
                theme: userTheme,
                length: 'seven', // 可以指定生成七言或五言,这里示例用七言
                style: 'traditional' // 风格,如传统、现代、幽默等
            }, {
                timeout: 10000 // 设置10秒超时
            });

            // 5. 假设API返回 { upper: "上联", lower: "下联", horizontal: "横批" }
            const couplet = response.data;

            // 6. 构建要插入的文本
            // 这里我们格式化为一个多行字符串,并加上注释,方便直接使用
            const insertText = `// 生成春联:${userTheme}
// 横批:${couplet.horizontal}
"${couplet.upper}",
"${couplet.lower}",`;

            // 7. 在当前光标位置插入文本
            editor.edit(editBuilder => {
                // 在光标处插入
                editBuilder.insert(editor.selection.active, insertText);
            });

            vscode.window.showInformationMessage('春联已生成并插入!');

        } catch (error: any) {
            // 错误处理
            console.error('生成春联失败:', error);
            vscode.window.showErrorMessage(`生成失败: ${error.message || '请检查网络或模型服务'}`);
        }
    });
}

这段代码已经具备了完整的功能。我们使用了 axios 库来发起网络请求,你需要先在项目中安装它:npm install axios。同时,记得将 MODEL_API_URL 替换成你实际可用的模型服务地址。

2.3 处理模型返回与代码集成

上面的代码将生成的春联以带注释的字符串形式插入。但在实际开发中,我们可能需要更灵活的集成方式。比如,直接生成一个JavaScript对象、一个JSON配置,或者一段HTML代码。

我们可以通过简单的配置来让插件支持多种输出格式。修改一下交互流程,让用户可以选择格式:

async function generateCouplet() {
    const editor = vscode.window.activeTextEditor;
    if (!editor) { return; }

    // 先让用户选择输出格式
    const format = await vscode.window.showQuickPick(
        [
            { label: 'JavaScript 数组', detail: '生成一个数组,如 ["上联", "下联"]' },
            { label: 'JSON 对象', detail: '生成一个包含上下联和横批的对象' },
            { label: 'HTML 片段', detail: '生成带标签的HTML代码' },
            { label: '纯文本带注释', detail: '默认格式,带注释的字符串' }
        ],
        { placeHolder: '请选择生成春联的格式' }
    );

    if (!format) { return; }

    const userTheme = await vscode.window.showInputBox({ placeHolder: '请输入春联主题' });
    if (userTheme === undefined) { return; }

    vscode.window.withProgress({
        location: vscode.ProgressLocation.Notification,
        title: '正在生成...',
    }, async () => {
        try {
            const response = await axios.post(MODEL_API_URL, { theme: userTheme });
            const couplet = response.data;

            let insertText = '';
            switch (format.label) {
                case 'JavaScript 数组':
                    insertText = `const couplet = ["${couplet.upper}", "${couplet.lower}"]; // 横批:${couplet.horizontal}`;
                    break;
                case 'JSON 对象':
                    insertText = JSON.stringify({
                        theme: userTheme,
                        horizontal: couplet.horizontal,
                        upperLine: couplet.upper,
                        lowerLine: couplet.lower
                    }, null, 2);
                    break;
                case 'HTML 片段':
                    insertText = `<div class="couplet">
    <div class="horizontal">${couplet.horizontal}</div>
    <div class="upper">${couplet.upper}</div>
    <div class="lower">${couplet.lower}</div>
</div>`;
                    break;
                default: // 纯文本带注释
                    insertText = `// 主题:${userTheme}\n// 横批:${couplet.horizontal}\n"${couplet.upper}"\n"${couplet.lower}"`;
            }

            editor.edit(editBuilder => {
                editBuilder.insert(editor.selection.active, insertText);
            });

            vscode.window.showInformationMessage('生成成功!');

        } catch (error) {
            vscode.window.showErrorMessage('生成失败,请重试。');
        }
    });
}

这样,插件就变得更加实用了,可以根据不同的开发场景输出最合适的代码格式。

3. 功能增强与体验优化

基础功能跑通了,但一个友好的工具还需要一些“润色”。我们来添加几个提升体验的功能。

3.1 添加配置项

我们可能希望用户能自定义一些设置,比如默认的生成风格、是否自动添加注释等。这可以通过VSCode的配置系统来实现。

首先,在 package.jsoncontributes 部分添加 configuration

{
  "contributes": {
    "configuration": {
      "title": "春联助手",
      "properties": {
        "coupletHelper.defaultStyle": {
          "type": "string",
          "default": "traditional",
          "enum": ["traditional", "modern", "humorous", "business"],
          "description": "默认的春联生成风格"
        },
        "coupletHelper.autoAddComment": {
          "type": "boolean",
          "default": true,
          "description": "是否自动为生成的春联添加注释说明"
        }
      }
    }
  }
}

然后,在代码中读取这些配置:

import * as vscode from 'vscode';

async function generateCouplet() {
    // 读取用户配置
    const config = vscode.workspace.getConfiguration('coupletHelper');
    const defaultStyle = config.get<string>('defaultStyle', 'traditional');
    const autoAddComment = config.get<boolean>('autoAddComment', true);

    // ... 之前的交互代码 ...

    vscode.window.withProgress({
        // ...
    }, async () => {
        try {
            // 调用API时使用配置的默认风格,除非用户临时指定
            const response = await axios.post(MODEL_API_URL, {
                theme: userTheme,
                style: defaultStyle // 使用配置项
            });
            // ... 处理结果,根据 autoAddComment 决定是否加注释 ...
        } catch (error) {
            // ...
        }
    });
}

现在,用户可以在VSCode的设置中搜索“春联助手”来修改这些偏好,插件的行为会更个性化。

3.2 实现代码片段补全

除了主动命令触发,我们还可以让插件更“智能”一点,比如当用户输入特定关键词(如“春联”)时,自动提示可以调用我们的生成功能。

这可以通过实现一个 CompletionItemProvider 来完成。我们在 extension.ts 中新增一个提供器:

// 在 activate 函数中注册提供器
export function activate(context: vscode.ExtensionContext) {
    // ... 之前的命令注册 ...

    // 注册代码补全提供器
    const provider = vscode.languages.registerCompletionItemProvider(
        { scheme: 'file' }, // 对所有文件生效
        {
            provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) {
                // 获取当前行的文本
                const linePrefix = document.lineAt(position).text.substr(0, position.character);

                // 如果用户输入了“couplet”这个词,则提供补全建议
                if (linePrefix.includes('couplet') || linePrefix.includes('春联')) {
                    const completionItem = new vscode.CompletionItem('生成春联', vscode.CompletionItemKind.Function);
                    completionItem.insertText = ''; // 不直接插入文本
                    completionItem.command = { // 触发我们的命令
                        command: 'couplet-helper.generate',
                        title: '生成春联'
                    };
                    completionItem.detail = '调用春联生成模型';
                    return [completionItem];
                }
                return undefined;
            }
        }
    );

    context.subscriptions.push(provider);
}

这样,当开发者在代码里输入“春联”时,VSCode的智能提示就会出现我们的插件选项,按回车即可直接触发生成流程,体验更加无缝。

3.3 添加本地历史与收藏功能

一个更进阶的想法是,让插件能保存用户生成过的、觉得特别好的春联,方便以后复用。

我们可以利用VSCode插件的本地存储能力(context.globalState)来实现一个简单的收藏夹。

interface SavedCouplet {
    theme: string;
    horizontal: string;
    upper: string;
    lower: string;
    timestamp: number;
}

export function activate(context: vscode.ExtensionContext) {
    // ... 之前的注册 ...

    // 注册一个“收藏当前春联”的命令
    let saveDisposable = vscode.commands.registerCommand('couplet-helper.saveCurrent', async () => {
        // 这里需要一种方式获取上一次生成的内容,可以通过一个全局变量存储
        // 为简化示例,我们假设能从编辑器中解析
        const editor = vscode.window.activeTextEditor;
        if (editor) {
            // 解析选中文本或当前行,这里逻辑略复杂,作为思路提示
            vscode.window.showInformationMessage('收藏功能(示例),需完善解析逻辑。');
        }
    });
    context.subscriptions.push(saveDisposable);

    // 注册一个“查看收藏”的命令
    let viewDisposable = vscode.commands.registerCommand('couplet-helper.viewFavorites', async () => {
        const favorites = context.globalState.get<SavedCouplet[]>('favorites', []);
        if (favorites.length === 0) {
            vscode.window.showInformationMessage('收藏夹为空。');
            return;
        }

        // 让用户选择一条收藏的春联
        const items = favorites.map(f => ({
            label: f.theme,
            description: `${f.upper.slice(0,10)}...`,
            detail: `横批:${f.horizontal}`,
            data: f
        }));

        const selected = await vscode.window.showQuickPick(items, { placeHolder: '选择一条春联插入' });
        if (selected && editor) {
            const f = selected.data;
            editor.edit(editBuilder => {
                editBuilder.insert(editor.selection.active, `"${f.upper}", "${f.lower}" // ${f.horizontal}`);
            });
        }
    });
    context.subscriptions.push(viewDisposable);
}

这只是一个思路框架,实现完整的解析和收藏逻辑需要更多的代码,但它展示了如何将一个小工具变得更具粘性和实用性。

4. 调试、打包与分享

4.1 调试插件

在项目根目录下,按下 F5 键,VSCode会启动一个“扩展开发主机”的新窗口。这个新窗口已经加载了你的插件。你可以:

  1. 在新窗口里打开一个文件。
  2. 在编辑器里右键,看看菜单里有没有“生成春联”选项。
  3. 或者按 Ctrl+Shift+P 打开命令面板,输入“生成春联”来触发命令。
  4. 原VSCode窗口会变成调试控制台,你可以在这里看到插件输出的日志和错误信息,方便排查问题。

4.2 打包与发布

当插件开发完成并测试无误后,你可以将它打包成 .vsix 文件,方便分享或发布到VSCode扩展市场。

首先,全局安装打包工具:

npm install -g @vscode/vsce

然后在插件项目根目录下运行打包命令:

vsce package

这会在当前目录生成一个 couplet-helper-0.0.1.vsix 这样的文件。其他人可以通过VSCode的“从VSIX安装”功能来安装你的插件。

如果你想分享给更多人,可以考虑发布到 Visual Studio Code Marketplace。这需要创建一个发布者账号,过程在官方文档中有详细指南。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐