diff --git a/packages/devtools/client/pages/settings.vue b/packages/devtools/client/pages/settings.vue index 3bf76a67e6..bd1d18e3cb 100644 --- a/packages/devtools/client/pages/settings.vue +++ b/packages/devtools/client/pages/settings.vue @@ -28,7 +28,7 @@ const editorOptions = [ ['Zed', 'zed'], ['Zed (zeditor)', 'zeditor'], ['WebStorm', 'webstorm'], - ['Sublime Text', 'sublime'], + ['Sublime Text', 'subl'], ['Atom', 'atom'], ['Windsurf', 'windsurf'], ] diff --git a/packages/devtools/src/server-rpc/general.ts b/packages/devtools/src/server-rpc/general.ts index ee51182ea2..01704b35b7 100644 --- a/packages/devtools/src/server-rpc/general.ts +++ b/packages/devtools/src/server-rpc/general.ts @@ -210,6 +210,8 @@ export function setupGeneralRPC({ let editor = getOptions()?.behavior.openInEditor ?? undefined if (editor === 'auto') editor = undefined + else if (editor === 'sublime') + editor = 'subl' await import('devframe/utils/launch-editor').then(r => r.launchEditor(path + suffix, editor)) return true } diff --git a/packages/devtools/test/open-in-editor.test.ts b/packages/devtools/test/open-in-editor.test.ts index 6b53297d28..336b43ca72 100644 --- a/packages/devtools/test/open-in-editor.test.ts +++ b/packages/devtools/test/open-in-editor.test.ts @@ -2,12 +2,22 @@ import type { Nuxt } from 'nuxt/schema' import type { NuxtDevtoolsServerContext } from '../src/types' import fsp from 'node:fs/promises' import { tmpdir } from 'node:os' +import { launchEditor } from 'devframe/utils/launch-editor' import { createHooks } from 'hookable' import { join, normalize } from 'pathe' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { setupGeneralRPC } from '../src/server-rpc/general' +import { getOptions } from '../src/server-rpc/options' -function fakeContext(root: string) { +vi.mock('devframe/utils/launch-editor', () => ({ + launchEditor: vi.fn(), +})) + +vi.mock('../src/server-rpc/options', () => ({ + getOptions: vi.fn(), +})) + +function fakeContext(root: string, handledByHook = true) { const hooks = createHooks() const opened: string[] = [] const ctx = { @@ -23,7 +33,7 @@ function fakeContext(root: string) { refresh: () => {}, openInEditorHooks: [(filepath: string) => { opened.push(filepath) - return true + return handledByHook }], } as unknown as NuxtDevtoolsServerContext return { ctx, opened } @@ -37,6 +47,8 @@ describe('openInEditor', () => { await fsp.mkdir(join(root, 'apps/web/app/components'), { recursive: true }) await fsp.writeFile(join(root, 'apps/web/app/components/Foo.vue'), '') vi.spyOn(process, 'cwd').mockReturnValue(join(root, 'apps/web')) + vi.mocked(getOptions).mockReset() + vi.mocked(launchEditor).mockClear() }) afterEach(async () => { @@ -78,6 +90,19 @@ describe('openInEditor', () => { expect(opened).toEqual([filepath]) }) + it.each(['subl', 'sublime'])('opens Sublime Text with subl for the %s setting', async (setting) => { + vi.mocked(getOptions).mockReturnValue({ + behavior: { openInEditor: setting }, + } as any) + const { ctx, opened } = fakeContext(root, false) + const { openInEditor } = setupGeneralRPC(ctx) + const filepath = join(root, 'apps/web/app/components/Foo.vue') + + await expect(openInEditor('app/components/Foo.vue')).resolves.toBe(true) + expect(opened).toEqual([filepath]) + expect(launchEditor).toHaveBeenCalledWith(filepath, 'subl') + }) + it('reports a path that exists under none of the base directories', async () => { const error = vi.spyOn(console, 'error').mockImplementation(() => {}) const { ctx, opened } = fakeContext(root) diff --git a/skills-lock.json b/skills-lock.json index f205f70b40..19336cbc3c 100644 --- a/skills-lock.json +++ b/skills-lock.json @@ -186,7 +186,7 @@ "source": "vuejs-ai/skills", "sourceType": "github", "skillPath": "skills/vue-best-practices/SKILL.md", - "computedHash": "70a50d6ee12edf24e0be9a79f59ea55a581961e8a38de2a20b96c7ae766ce3ef", + "computedHash": "2f4da0a95f19b225e784981413f727ff03bfdec7818a1e5bb0a477aab633095e", "via": "@antfu/skills" }, "vue-debug-guides": {