Skip to content

Allow opening files, folders, and workspaces in existing code-server from CLI #1994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 27, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Next Next commit
Add open-in, new-window and reuse-window
Add initial support for opening files / folders in running code-server instance.

Current limitations:

- unable to open a file in a new window, only folders
- unable to use addMode feature
- others...
  • Loading branch information
shayne committed Aug 27, 2020
commit 2189baeaf7d5323ac4799740b4df7099d8283b15
15 changes: 15 additions & 0 deletions src/node/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export interface Args extends VsArgs {
readonly "proxy-domain"?: string[]
readonly locale?: string
readonly _: string[]
readonly "open-in"?: boolean
readonly "reuse-window"?: boolean
readonly "new-window"?: boolean
}

interface Option<T> {
Expand Down Expand Up @@ -139,6 +142,18 @@ const options: Options<Required<Args>> = {
"show-versions": { type: "boolean", description: "Show VS Code extension versions." },
"proxy-domain": { type: "string[]", description: "Domain used for proxying ports." },

"open-in": { type: "boolean", short: "oi", description: "Open file(s) or folder(s) in running instance" },
"new-window": {
type: "boolean",
short: "n",
description: "Force to open a new window. (use with open-in)",
},
"reuse-window": {
type: "boolean",
short: "r",
description: "Force to open a file or folder in an already opened window. (use with open-in)",
},

locale: { type: "string" },
log: { type: LogLevel },
verbose: { type: "boolean", short: "vvv", description: "Enable verbose logging." },
Expand Down
54 changes: 49 additions & 5 deletions src/node/entry.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { field, logger } from "@coder/logger"
import * as cp from "child_process"
import { promises as fs } from "fs"
import http from "http"
import * as path from "path"
import { CliMessage } from "../../lib/vscode/src/vs/server/ipc"
import { plural } from "../common/util"
import { CliMessage, OpenCommandPipeArgs } from "../../lib/vscode/src/vs/server/ipc"
import { LoginHttpProvider } from "./app/login"
import { ProxyHttpProvider } from "./app/proxy"
import { StaticHttpProvider } from "./app/static"
Expand Down Expand Up @@ -63,9 +64,9 @@ const main = async (args: Args, cliArgs: Args, configArgs: Args): Promise<void>
...(args.cert && !args.cert.value
? await generateCertificate()
: {
cert: args.cert && args.cert.value,
certKey: args["cert-key"],
}),
cert: args.cert && args.cert.value,
certKey: args["cert-key"],
}),
}

if (options.cert && !options.certKey) {
Expand Down Expand Up @@ -162,6 +163,49 @@ async function entry(): Promise<void> {
console.log(version, commit)
}
process.exit(0)
} else if (args["open-in"]) {
if (!process.env["VSCODE_IPC_HOOK_CLI"]) {
logger.error("VSCODE_IPC_HOOK_CLI missing from environment, unable to run")
process.exit(1)
}
const pipeArgs: OpenCommandPipeArgs = { type: "open", folderURIs: [] }
pipeArgs.forceReuseWindow = args["reuse-window"]
pipeArgs.forceNewWindow = args["new-window"]
for (const a in args._) {
if (Object.prototype.hasOwnProperty.call(args._, a)) {
try {
const fp = await fs.realpath(args._[a])
const st = await fs.stat(fp)
if (st.isDirectory()) {
pipeArgs.folderURIs = [...pipeArgs.folderURIs, fp]
} else {
pipeArgs.fileURIs = [...(pipeArgs.fileURIs || []), fp]
}
} catch (error) {
pipeArgs.fileURIs = [...(pipeArgs.fileURIs || []), args._[a]]
}
}
}
if (pipeArgs.forceNewWindow && pipeArgs.fileURIs && pipeArgs.fileURIs.length > 0) {
logger.error("new-window can only be used with folder paths")
process.exit(1)
}
const vscode = http.request({
path: "/",
method: "POST",
socketPath: process.env["VSCODE_IPC_HOOK_CLI"],
},
(res) => {
res.on("data", (message) => {
logger.debug("Got message from VS Code", field("message", message.toString()))
})
},
)
vscode.on("error", (err) => {
logger.debug("Got error from VS Code", field("error", err))
})
vscode.write(JSON.stringify(pipeArgs))
vscode.end()
} else if (args["list-extensions"] || args["install-extension"] || args["uninstall-extension"]) {
logger.debug("forking vs code cli...")
const vscode = cp.fork(path.resolve(__dirname, "../../lib/vscode/out/vs/server/fork"), [], {
Expand Down