Skip to content
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

Support for setting shell environment variables #32

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
13 changes: 12 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "edit-with-shell",
"displayName": "Edit with Shell Command",
"description": "Leverage your favourite shell commands to edit text",
"version": "1.3.0",
"version": "1.3.1",
"publisher": "ryu1kn",
"license": "SEE LICENSE IN LICENSE.txt",
"icon": "images/edit-with-shell.png",
Expand All @@ -28,6 +28,7 @@
"activationEvents": [
"onCommand:editWithShell.clearCommandHistory",
"onCommand:editWithShell.runCommand",
"onCommand:editWithShell.runLocalCommand",
"onCommand:editWithShell.runQuickCommand1",
"onCommand:editWithShell.runQuickCommand2",
"onCommand:editWithShell.runQuickCommand3",
Expand All @@ -47,6 +48,11 @@
"title": "Run command",
"category": "EditWithShell"
},
{
"command": "editWithShell.runLocalCommand",
"title": "Run local command",
"category": "EditWithShell"
},
{
"command": "editWithShell.runQuickCommand1",
"title": "Run quick command 1",
Expand Down Expand Up @@ -177,6 +183,11 @@
"/s",
"/c"
]
},
"editWithShell.shellEnv": {
"description": "shell environment variables",
"type": "object",
"default": {}
}
}
}
Expand Down
18 changes: 17 additions & 1 deletion src/lib/app-integrator-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {Editor} from './adapters/editor';
import {ShellCommandService} from './shell-command-service';
import {CommandReader} from './command-reader';
import {HistoryStore} from './history-store';
import {LocalCommandStore} from './local-command-store';
import {ProcessRunner} from './process-runner';
import {RunInputCommand} from './commands/run-input';
import {ClearHistoryCommand} from './commands/clear-history';
Expand All @@ -19,14 +20,15 @@ export class AppIntegratorFactory {
private readonly cache: {
workspaceAdapter?: WorkspaceAdapter;
historyStore?: HistoryStore;
localCommandStore?: LocalCommandStore;
};

constructor() {
this.cache = Object.create(null);
}

create() {
return new AppIntegrator(this.runCommand, this.clearHistoryCommand, this.createQuickCommand, vscode);
return new AppIntegrator(this.runCommand,this.runLocalCommand, this.clearHistoryCommand, this.createQuickCommand, vscode);
}

private get runCommand() {
Expand All @@ -38,6 +40,15 @@ export class AppIntegratorFactory {
));
}

private get runLocalCommand() {
return this.wrapCommand(new RunInputCommand(
this.shellCommandService,
new CommandReader(this.localCommandStore, vscode.window),
this.localCommandStore, // Actually no need to store local commands
this.workspaceAdapter
));
}

private get createQuickCommand() {
return (commandNumber: number) => this.wrapCommand(new RunQuickCommand(
this.shellCommandService,
Expand Down Expand Up @@ -65,6 +76,11 @@ export class AppIntegratorFactory {
return this.cache.historyStore;
}

private get localCommandStore() {
this.cache.localCommandStore = this.cache.localCommandStore || new LocalCommandStore(this.workspaceAdapter);
return this.cache.localCommandStore;
}

private get shellCommandService() {
return new ShellCommandService(
new ProcessRunner(),
Expand Down
5 changes: 5 additions & 0 deletions src/lib/app-integrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface CommandHandlerInfo {

export class AppIntegrator {
constructor(private readonly runCommand: CommandWrap,
private readonly runLocalCommand: CommandWrap,
private readonly clearHistoryCommand: CommandWrap,
private readonly createQuickCommand: (n: number) => CommandWrap,
private readonly vscode: any) {}
Expand Down Expand Up @@ -44,6 +45,10 @@ export class AppIntegrator {
id: `${EXTENSION_NAME}.runCommand`,
command: this.runCommand
},
{
id: `${EXTENSION_NAME}.runLocalCommand`,
command: this.runLocalCommand
},
...[1, 2, 3, 4, 5].map(n => ({
id: `${EXTENSION_NAME}.runQuickCommand${n}`,
command: this.createQuickCommand(n)
Expand Down
2 changes: 1 addition & 1 deletion src/lib/command-reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export class CommandReader {
private readonly vsWindow: typeof vscode.window) {}

async read() {
const history = this.historyStore.getAll();
const history = await this.historyStore.getAll();
if (history.length === 0) {
return this.vsWindow.showInputBox({
placeHolder: 'Enter a command',
Expand Down
4 changes: 2 additions & 2 deletions src/lib/history-store.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

export class HistoryStore {
private history: string[];
protected history: string[];

constructor() {
this.history = [];
}

getAll() {
async getAll() {
return this.history;
}

Expand Down
42 changes: 42 additions & 0 deletions src/lib/local-command-store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { HistoryStore } from "./history-store";

import {ShellSettingsResolver} from './shell-settings-resolver';
import {Workspace as WorkspaceAdapter} from './adapters/workspace';
import * as fs from 'fs';
import * as vscode from 'vscode';
import * as Path from 'path';

export class LocalCommandStore extends HistoryStore {
private readonly shellSettingsResolver: ShellSettingsResolver;
// private readonly workspace: WorkspaceAdapter;

constructor(workspace : WorkspaceAdapter) {
super();
// this.workspace = workspace;
this.shellSettingsResolver = new ShellSettingsResolver(workspace, process.platform);
}

async getAll() {
return new Promise<string[]>(require=>{

const shellEnv = this.shellSettingsResolver.shellEnv();
const pathSeparator = this.shellSettingsResolver.pathSeparator();

const workdir = vscode.workspace.workspaceFolders ? vscode.workspace.getWorkspaceFolder(vscode.workspace.workspaceFolders[0].uri)?.uri?.fsPath || "": ""

let envpath = shellEnv.PATH || shellEnv.Path;
if(envpath) {
let paths = envpath.split(pathSeparator);
for(let path of paths){
let files = fs.readdirSync(Path.join(workdir, path));
files.forEach((file) => {
this.add(file);
});

}
}

require(this.history)
});
}
}
30 changes: 29 additions & 1 deletion src/lib/shell-command-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {ShellSettingsResolver} from './shell-settings-resolver';
import {ChildProcess, SpawnOptions} from 'child_process';
import {Workspace} from './adapters/workspace';
import Process = NodeJS.Process;
import { ObjectMap } from './types/collection';

export interface SpawnWrapper {
spawn: (command: string, args?: ReadonlyArray<string>, options?: SpawnOptions) => ChildProcess;
Expand Down Expand Up @@ -31,6 +32,33 @@ export class ShellCommandService {
const options = this.getOptions(params);
const shell = this.shellSettingsResolver.shellProgramme();
const shellArgs = this.shellSettingsResolver.shellArgs();
// Why Proxy Object?
const shellEnv = this.shellSettingsResolver.shellEnv();
const pathSeparator = this.shellSettingsResolver.pathSeparator();
const system_env_path = options.env.Path || options.env.PATH;
const env_path = shellEnv.Path || shellEnv.PATH;
const env:ObjectMap<string> = {};

// linux&win use 'PATH'
options.env.PATH = system_env_path;
delete options.env.Path;
// Can't delete member
// delete shellEnv.Path
// delete shellEnv.PATH

// skip env:Path
for (let key in shellEnv){
if(key.toUpperCase() != "PATH"){
env[key] = shellEnv[key]
}
}

Object.assign(options.env, env)

if(env_path) {
options.env.PATH = env_path + pathSeparator + system_env_path;
}

const command = this.childProcess.spawn(shell, [...shellArgs, params.command], options);
return this.processRunner.run(command, params.input);
}
Expand All @@ -41,7 +69,7 @@ export class ShellCommandService {
env: {
...this.shellCommandExecContext.env,
ES_SELECTED: params.input
}
} as ObjectMap<string>
};
}
}
10 changes: 10 additions & 0 deletions src/lib/shell-settings-resolver.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {EXTENSION_NAME} from './const';
import resolveOsKind from './resolve-os-kind';
import {Workspace} from './adapters/workspace';
import { ObjectMap } from './types/collection';
import * as path from 'path';

export class ShellSettingsResolver {
constructor(private readonly workspaceAdapter: Workspace,
Expand All @@ -14,6 +16,14 @@ export class ShellSettingsResolver {
return this.workspaceAdapter.getConfig<string[]>(`${EXTENSION_NAME}.shellArgs.${this.osKind}`);
}

shellEnv(): ObjectMap<string> {
return this.workspaceAdapter.getConfig<ObjectMap<string>>(`${EXTENSION_NAME}.shellEnv`);
}

pathSeparator(): string {
return path.delimiter;
}

private get osKind() {
return resolveOsKind(this.platform);
}
Expand Down