Просмотр исходного кода

vscode: add cmd+shift+esc keybinding

Frank 8 месяцев назад
Родитель
Сommit
a07d149e28
4 измененных файлов с 89 добавлено и 65 удалено
  1. 2 1
      packages/web/src/content/docs/docs/ide.mdx
  2. 6 5
      sdks/vscode/README.md
  3. 18 2
      sdks/vscode/package.json
  4. 63 57
      sdks/vscode/src/extension.ts

+ 2 - 1
packages/web/src/content/docs/docs/ide.mdx

@@ -9,7 +9,8 @@ opencode integrates with VS Code, Cursor, or any IDE that supports a terminal. J
 
 
 ## Usage
 ## Usage
 
 
-- **Quick Launch**: Open opencode with `Cmd+Esc` (Mac) or `Ctrl+Esc` (Windows/Linux), or click the opencode button in the UI.
+- **Quick Launch**: Use `Cmd+Esc` (Mac) or `Ctrl+Esc` (Windows/Linux) to open opencode in a split terminal view, or focus an existing terminal session if one is already running.
+- **New Session**: Use `Cmd+Shift+Esc` (Mac) or `Ctrl+Shift+Esc` (Windows/Linux) to start a new opencode terminal session, even if one is already open. You can also click the opencode button in the UI.
 - **Context Awareness**: Automatically share your current selection or tab with opencode.
 - **Context Awareness**: Automatically share your current selection or tab with opencode.
 - **File Reference Shortcuts**: Use `Cmd+Option+K` (Mac) or `Alt+Ctrl+K` (Linux/Windows) to insert file references. For example, `@File#L37-42`.
 - **File Reference Shortcuts**: Use `Cmd+Option+K` (Mac) or `Alt+Ctrl+K` (Linux/Windows) to insert file references. For example, `@File#L37-42`.
 
 

+ 6 - 5
sdks/vscode/README.md

@@ -1,16 +1,17 @@
 # opencode VS Code Extension
 # opencode VS Code Extension
 
 
-A VS Code extension that integrates [opencode](https://opencode.ai) directly into your development environment.
+A Visual Studio Code extension that integrates [opencode](https://opencode.ai) directly into your development workflow.
 
 
 ## Prerequisites
 ## Prerequisites
 
 
-This extension requires [opencode](https://opencode.ai) to be installed on your system. Visit [opencode.ai](https://opencode.ai) for installation instructions.
+This extension requires the [opencode CLI](https://opencode.ai) to be installed on your system. Visit [opencode.ai](https://opencode.ai) for installation instructions.
 
 
 ## Features
 ## Features
 
 
-- **Cmd+Escape**: Launch opencode in a split terminal view
-- **Alt+Cmd+K**: Send selected code to opencode's prompt
-- **Tab awareness**: opencode automatically detects which files you have open
+- **Quick Launch**: Use `Cmd+Esc` (Mac) or `Ctrl+Esc` (Windows/Linux) to open opencode in a split terminal view, or focus an existing terminal session if one is already running.
+- **New Session**: Use `Cmd+Shift+Esc` (Mac) or `Ctrl+Shift+Esc` (Windows/Linux) to start a new opencode terminal session, even if one is already open. You can also click the opencode button in the UI.
+- **Context Awareness**: Automatically share your current selection or tab with opencode.
+- **File Reference Shortcuts**: Use `Cmd+Option+K` (Mac) or `Alt+Ctrl+K` (Linux/Windows) to insert file references. For example, `@File#L37-42`.
 
 
 ## Support
 ## Support
 
 

+ 18 - 2
sdks/vscode/package.json

@@ -26,7 +26,15 @@
     "commands": [
     "commands": [
       {
       {
         "command": "opencode.openTerminal",
         "command": "opencode.openTerminal",
-        "title": "Open Terminal with Opencode",
+        "title": "Open opencode",
+        "icon": {
+          "light": "images/button-dark.svg",
+          "dark": "images/button-light.svg"
+        }
+      },
+      {
+        "command": "opencode.openNewTerminal",
+        "title": "Open opencode in new tab",
         "icon": {
         "icon": {
           "light": "images/button-dark.svg",
           "light": "images/button-dark.svg",
           "dark": "images/button-light.svg"
           "dark": "images/button-light.svg"
@@ -40,7 +48,7 @@
     "menus": {
     "menus": {
       "editor/title": [
       "editor/title": [
         {
         {
-          "command": "opencode.openTerminal",
+          "command": "opencode.openNewTerminal",
           "group": "navigation"
           "group": "navigation"
         }
         }
       ]
       ]
@@ -54,6 +62,14 @@
         "win": "ctrl+escape",
         "win": "ctrl+escape",
         "linux": "ctrl+escape"
         "linux": "ctrl+escape"
       },
       },
+      {
+        "command": "opencode.openNewTerminal",
+        "title": "Run opencode",
+        "key": "cmd+shift+escape",
+        "mac": "cmd+shift+escape",
+        "win": "ctrl+shift+escape",
+        "linux": "ctrl+shift+escape"
+      },
       {
       {
         "command": "opencode.addFilepathToTerminal",
         "command": "opencode.addFilepathToTerminal",
         "title": "opencode: Insert At-Mentioned",
         "title": "opencode: Insert At-Mentioned",

+ 63 - 57
sdks/vscode/src/extension.ts

@@ -3,10 +3,13 @@ export function deactivate() {}
 
 
 import * as vscode from "vscode"
 import * as vscode from "vscode"
 
 
+const TERMINAL_NAME = "opencode"
+
 export function activate(context: vscode.ExtensionContext) {
 export function activate(context: vscode.ExtensionContext) {
-  const TERMINAL_NAME = "opencode"
+  let openNewTerminalDisposable = vscode.commands.registerCommand("opencode.openNewTerminal", async () => {
+    await openTerminal()
+  })
 
 
-  // Register command to open terminal in split screen and run opencode
   let openTerminalDisposable = vscode.commands.registerCommand("opencode.openTerminal", async () => {
   let openTerminalDisposable = vscode.commands.registerCommand("opencode.openTerminal", async () => {
     // An opencode terminal already exists => focus it
     // An opencode terminal already exists => focus it
     const existingTerminal = vscode.window.terminals.find((t) => t.name === TERMINAL_NAME)
     const existingTerminal = vscode.window.terminals.find((t) => t.name === TERMINAL_NAME)
@@ -15,6 +18,27 @@ export function activate(context: vscode.ExtensionContext) {
       return
       return
     }
     }
 
 
+    await openTerminal()
+  })
+
+  let addFilepathDisposable = vscode.commands.registerCommand("opencode.addFilepathToTerminal", async () => {
+    const fileRef = getActiveFile()
+    if (!fileRef) return
+
+    const terminal = vscode.window.activeTerminal
+    if (!terminal) return
+
+    if (terminal.name === TERMINAL_NAME) {
+      // @ts-ignore
+      const port = terminal.creationOptions.env?.["_EXTENSION_OPENCODE_PORT"]
+      port ? await appendPrompt(parseInt(port), fileRef) : terminal.sendText(fileRef)
+      terminal.show()
+    }
+  })
+
+  context.subscriptions.push(openTerminalDisposable, addFilepathDisposable)
+
+  async function openTerminal() {
     // Create a new terminal in split screen
     // Create a new terminal in split screen
     const port = Math.floor(Math.random() * (65535 - 16384 + 1)) + 16384
     const port = Math.floor(Math.random() * (65535 - 16384 + 1)) + 16384
     const terminal = vscode.window.createTerminal({
     const terminal = vscode.window.createTerminal({
@@ -57,64 +81,46 @@ export function activate(context: vscode.ExtensionContext) {
       await appendPrompt(port, `In ${fileRef}`)
       await appendPrompt(port, `In ${fileRef}`)
       terminal.show()
       terminal.show()
     }
     }
-  })
-
-  // Register command to add filepath to terminal
-  let addFilepathDisposable = vscode.commands.registerCommand("opencode.addFilepathToTerminal", async () => {
-    const fileRef = getActiveFile()
-    if (!fileRef) return
+  }
 
 
-    const terminal = vscode.window.activeTerminal
-    if (!terminal) return
+  async function appendPrompt(port: number, text: string) {
+    await fetch(`http://localhost:${port}/tui/append-prompt`, {
+      method: "POST",
+      headers: {
+        "Content-Type": "application/json",
+      },
+      body: JSON.stringify({ text }),
+    })
+  }
 
 
-    if (terminal.name === TERMINAL_NAME) {
-      // @ts-ignore
-      const port = terminal.creationOptions.env?.["_EXTENSION_OPENCODE_PORT"]
-      port ? await appendPrompt(parseInt(port), fileRef) : terminal.sendText(fileRef)
-      terminal.show()
+  function getActiveFile() {
+    const activeEditor = vscode.window.activeTextEditor
+    if (!activeEditor) return
+
+    const document = activeEditor.document
+    const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri)
+    if (!workspaceFolder) return
+
+    // Get the relative path from workspace root
+    const relativePath = vscode.workspace.asRelativePath(document.uri)
+    let filepathWithAt = `@${relativePath}`
+
+    // Check if there's a selection and add line numbers
+    const selection = activeEditor.selection
+    if (!selection.isEmpty) {
+      // Convert to 1-based line numbers
+      const startLine = selection.start.line + 1
+      const endLine = selection.end.line + 1
+
+      if (startLine === endLine) {
+        // Single line selection
+        filepathWithAt += `#L${startLine}`
+      } else {
+        // Multi-line selection
+        filepathWithAt += `#L${startLine}-${endLine}`
+      }
     }
     }
-  })
-
-  context.subscriptions.push(openTerminalDisposable, addFilepathDisposable)
-}
 
 
-async function appendPrompt(port: number, text: string) {
-  await fetch(`http://localhost:${port}/tui/append-prompt`, {
-    method: "POST",
-    headers: {
-      "Content-Type": "application/json",
-    },
-    body: JSON.stringify({ text }),
-  })
-}
-
-function getActiveFile() {
-  const activeEditor = vscode.window.activeTextEditor
-  if (!activeEditor) return
-
-  const document = activeEditor.document
-  const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri)
-  if (!workspaceFolder) return
-
-  // Get the relative path from workspace root
-  const relativePath = vscode.workspace.asRelativePath(document.uri)
-  let filepathWithAt = `@${relativePath}`
-
-  // Check if there's a selection and add line numbers
-  const selection = activeEditor.selection
-  if (!selection.isEmpty) {
-    // Convert to 1-based line numbers
-    const startLine = selection.start.line + 1
-    const endLine = selection.end.line + 1
-
-    if (startLine === endLine) {
-      // Single line selection
-      filepathWithAt += `#L${startLine}`
-    } else {
-      // Multi-line selection
-      filepathWithAt += `#L${startLine}-${endLine}`
-    }
+    return filepathWithAt
   }
   }
-
-  return filepathWithAt
 }
 }