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

Add vim.shell setting for custom ! shell #7255

Merged
merged 2 commits into from
Nov 27, 2021
Merged
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
35 changes: 18 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -404,23 +404,24 @@ Configuration settings that have been copied from vim. Vim settings are loaded i
3. VS Code settings
4. VSCodeVim default values

| Setting | Description | Type | Default Value |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------------- |
| vim.autoindent | Copy indent from current line when starting a new line | Boolean | true |
| vim.gdefault | When on, the `:substitute` flag `g` is default on. This means that all matches in a line are substituted instead of one. When a `g` flag is given to a `:substitute` command, this will toggle the substitution of all or one match. | Boolean | false |
| vim.hlsearch | Highlights all text matching current search | Boolean | false |
| vim.ignorecase | Ignore case in search patterns | Boolean | true |
| vim.incsearch | Show the next match while entering a search | Boolean | true |
| vim.joinspaces | Add two spaces after '.', '?', and '!' when joining or reformatting | Boolean | true |
| vim.leader | Defines key for `<leader>` to be used in key remappings | String | `\` |
| vim.showcmd | Show (partial) command in status bar | Boolean | true |
| vim.showmodename | Show name of current mode in status bar | Boolean | true |
| vim.smartcase | Override the 'ignorecase' setting if search pattern contains uppercase characters | Boolean | true |
| vim.textwidth | Width to word-wrap when using `gq` | Number | 80 |
| vim.timeout | Timeout in milliseconds for remapped commands | Number | 1000 |
| vim.maxmapdepth | Maximum number of times a mapping is done without resulting in a character to be used. This normally catches endless mappings, like ":map x y" with ":map y x". It still does not catch ":map g wg", because the 'w' is used before the next mapping is done. | Number | 1000 |
| vim.whichwrap | Allow specified keys that move the cursor left/right to move to the previous/next line when the cursor is on the first/last character in the line. See [:help whichwrap](https://vimhelp.org/options.txt.html#%27whichwrap%27). | String | `b,s` |
| vim.report | Threshold for reporting number of lines changed. | Number | 2 |
| Setting | Description | Type | Default Value |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------- |
| vim.autoindent | Copy indent from current line when starting a new line | Boolean | true |
| vim.gdefault | When on, the `:substitute` flag `g` is default on. This means that all matches in a line are substituted instead of one. When a `g` flag is given to a `:substitute` command, this will toggle the substitution of all or one match. | Boolean | false |
| vim.hlsearch | Highlights all text matching current search | Boolean | false |
| vim.ignorecase | Ignore case in search patterns | Boolean | true |
| vim.incsearch | Show the next match while entering a search | Boolean | true |
| vim.joinspaces | Add two spaces after '.', '?', and '!' when joining or reformatting | Boolean | true |
| vim.leader | Defines key for `<leader>` to be used in key remappings | String | `\` |
| vim.maxmapdepth | Maximum number of times a mapping is done without resulting in a character to be used. This normally catches endless mappings, like ":map x y" with ":map y x". It still does not catch ":map g wg", because the 'w' is used before the next mapping is done. | Number | 1000 |
| vim.report | Threshold for reporting number of lines changed. | Number | 2 |
| vim.shell | Path to the shell to use for `!` and `:!` commands. | String | `/bin/sh` on Unix, `%COMSPEC%` environment variable on Windows |
| vim.showcmd | Show (partial) command in status bar | Boolean | true |
| vim.showmodename | Show name of current mode in status bar | Boolean | true |
| vim.smartcase | Override the 'ignorecase' setting if search pattern contains uppercase characters | Boolean | true |
| vim.textwidth | Width to word-wrap when using `gq` | Number | 80 |
| vim.timeout | Timeout in milliseconds for remapped commands | Number | 1000 |
| vim.whichwrap | Allow specified keys that move the cursor left/right to move to the previous/next line when the cursor is on the first/last character in the line. See [:help whichwrap](https://vimhelp.org/options.txt.html#%27whichwrap%27). | String | `b,s` |

## .vimrc support

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1100,6 +1100,11 @@
"type": "boolean",
"description": "Show the currently set mark(s) in the gutter.",
"default": false
},
"vim.shell": {
"type": "string",
"description": "Path to the shell to use for `!` and `:!` commands.",
"default": ""
}
}
},
2 changes: 2 additions & 0 deletions src/configuration/configuration.ts
Original file line number Diff line number Diff line change
@@ -211,6 +211,8 @@ class Configuration implements IConfiguration {

useSystemClipboard = false;

shell = '';

useCtrlKeys = false;

overrideCopy = true;
5 changes: 5 additions & 0 deletions src/configuration/iconfiguration.ts
Original file line number Diff line number Diff line change
@@ -418,4 +418,9 @@ export interface IConfiguration {
* Show the currently set mark(s) in the gutter.
*/
showMarksInGutter: boolean;

/**
* Path to the shell to use for `!` and `:!` commands.
*/
shell: string;
}
8 changes: 7 additions & 1 deletion src/util/externalCommand.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { VimError, ErrorCode } from '../error';
import { exec } from '../util/child_process';
import { configuration } from '../configuration/configuration';

class ExternalCommand {
private previousExternalCommand: string | undefined;
@@ -42,9 +43,12 @@ class ExternalCommand {
*/
private async execute(command: string, stdin: string): Promise<string> {
const output: string[] = [];
const options = {
shell: configuration.shell || undefined,
};

try {
const promise = exec(command);
const promise = exec(command, options);
const process = promise.child;

if (process.stdin !== null) {
@@ -80,6 +84,8 @@ class ExternalCommand {
public async run(command: string, stdin: string = ''): Promise<string> {
command = this.expandCommand(command);
this.previousExternalCommand = command;
// combines stdout and stderr (compatible for all platforms)
command += ' 2>&1';

let output = await this.execute(command, stdin);
// vim behavior, trim newlines
42 changes: 42 additions & 0 deletions test/cmd_line/bang.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Configuration } from '../../test/testConfiguration';
import { newTest } from '../../test/testSimplifier';
import { getAndUpdateModeHandler } from '../../extension';
import { ModeHandler } from '../../src/mode/modeHandler';
import { assertEqualLines, cleanUpWorkspace, setupWorkspace } from './../testUtils';
@@ -101,3 +103,43 @@ suite('bang (!) cmd_line', () => {
});
});
});

suite('custom bang shell', () => {
if (process.platform === 'win32') {
return;
}

suite('sh', () => {
setup(async () => {
const configuration = new Configuration();
configuration.shell = '/bin/sh';
await setupWorkspace(configuration);
});

teardown(cleanUpWorkspace);

newTest({
title: '! supports /bin/sh',
start: ['|'],
keysPressed: '<Esc>:.!echo $0\n',
end: ['|/bin/sh'],
});
});

suite('bash', () => {
setup(async () => {
const configuration = new Configuration();
configuration.shell = '/bin/bash';
await setupWorkspace(configuration);
});

teardown(cleanUpWorkspace);

newTest({
title: '! supports /bin/bash',
start: ['|'],
keysPressed: '<Esc>:.!echo $0\n',
end: ['|/bin/bash'],
});
});
});
1 change: 1 addition & 0 deletions test/testConfiguration.ts
Original file line number Diff line number Diff line change
@@ -134,4 +134,5 @@ export class Configuration implements IConfiguration {
scroll = 20;
startofline = true;
showMarksInGutter = true;
shell = '';
}