Skip to content

Commit

Permalink
feat: add composer command integration (#23)
Browse files Browse the repository at this point in the history
* feat: add composer command integration
* refactor: delete the target terminal buffer just in case
  • Loading branch information
yaegassy committed Apr 1, 2022
1 parent d2c2a08 commit 7ba14d0
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 3 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ $ node -e "console.log(os.homedir() + '/intelephense/licence.txt')"
- `intelephense.client.snippetsCompletionExclude`: Exclude specific prefix in snippet completion, e.g. `["class", "fun"]`, default: `[]`
- `intelephense.server.disableCompletion`: Disable completion only (server), default: `false`
- `intelephense.server.disableDefinition`: Disable definition only (server), default: `false`
- `intelephense.composer.path`: Path to composer command. default: `composer`
- `intelephense.composer.runCommandList`: Set the subcommand of the composer you want to execute, default: `["dump-autoload", "clear-cache", "install", "update"]`
- `intelephense.composer.runCommandPlusList`: Set the subcommand of the composer you want to execute. Additional strings can be entered and executed in the subcommand. default: `["require", "require --dev", "remove", "remove --dev", "update"]`
- `intelephense.phpunit.disableCodeLens`: Disable code lens only (client), default: `false`
- `intelephense.phpunit.codeLensTitle`: CodeLens title. Can be changed to any display, default: `">> [Run PHPUnit]"`
- `intelephense.phpunit.path`: Path to phpunit command. If there is no setting, the vendor/bin/phpunit will be used, default: `""`
Expand Down Expand Up @@ -119,11 +122,14 @@ $ node -e "console.log(os.homedir() + '/intelephense/licence.txt')"

> :CocCommand [CommandName]
>
> **e.g.**:
> :CocCommand intelephense.phpunit.projectTest
> **e.g.** :CocCommand intelephense.phpunit.projectTest
- `intelephense.index.workspace`: Index workspace
- `intelephense.cancel.indexing`: Cancel indexing
- `intelephense.composer.runCommand`: Run selected composer command
- `intelephense.composer.runCommandPlus`: Enter and run additional strings to the selected composer commands
- `intelephense.composer.runScriptsCommand`: Run selected composer script
- Select and run the script defined in the "scripts section" of `composer.json`. The `pre-...` and `post-...` event scripts are excluded from the list.
- `intelephense.phpunit.projectTest`: Run PHPUnit for current project
- `intelephense.phpunit.fileTest`: Run PHPUnit for current file
- `intelephense.phpunit.singleTest`: Run PHPUnit for single (nearest) test
Expand Down
41 changes: 41 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,32 @@
"default": false,
"description": "Disable definition only (server)."
},
"intelephense.composer.path": {
"type": "string",
"default": "composer",
"description": "Path to composer command."
},
"intelephense.composer.runCommandList": {
"type": "array",
"default": [
"dump-autoload",
"clear-cache",
"install",
"update"
],
"description": "Set the subcommand of the composer you want to execute."
},
"intelephense.composer.runCommandPlusList": {
"type": "array",
"default": [
"require",
"require --dev",
"remove",
"remove --dev",
"update"
],
"description": "Set the subcommand of the composer you want to execute. Additional strings can be entered and executed in the subcommand."
},
"intelephense.phpunit.disableCodeLens": {
"type": "boolean",
"default": false,
Expand Down Expand Up @@ -819,6 +845,21 @@
"title": "Cancel indexing",
"category": "Intelephense"
},
{
"command": "intelephense.composer.runCommand",
"title": "Run selected composer command",
"category": "Intelephense"
},
{
"command": "intelephense.composer.runCommandPlus",
"title": "Enter and run additional strings to the selected composer command",
"category": "Intelephense"
},
{
"command": "intelephense.composer.runScriptsCommand",
"title": "Run selected composer script",
"category": "Intelephense"
},
{
"command": "intelephense.phpunit.projectTest",
"title": "Run PHPUnit for current project",
Expand Down
152 changes: 152 additions & 0 deletions src/commands/composer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import { Terminal, window, workspace } from 'coc.nvim';

import cp from 'child_process';
import fs from 'fs';
import path from 'path';

let terminal: Terminal | undefined;

async function getComposerPath() {
let cmdPath = '';
const composerPath = workspace.getConfiguration('intelephense').get<string>('composer.path', 'composer');
if (await existsComposer(composerPath)) {
cmdPath = composerPath;
}
return cmdPath;
}

async function existsComposer(composerPath: string) {
return new Promise<boolean>((resolve) => {
cp.exec(`${composerPath} --version`, (err, stdout, stderr) => {
if (stdout.length > 0) {
resolve(true);
} else {
resolve(false);
}
});
});
}

function existsComposerJson() {
let exists = false;
const composerJsonPath = path.join(workspace.root, 'composer.json');
if (fs.existsSync(composerJsonPath)) {
exists = true;
}
return exists;
}

async function runComposer(composerPath: string, args: string[]) {
if (!composerPath) {
window.showErrorMessage(`composer command not found!`);
return;
}

if (terminal) {
if (terminal.bufnr) {
await workspace.nvim.command(`bd! ${terminal.bufnr}`);
}
terminal.dispose();
terminal = undefined;
}

terminal = await window.createTerminal({ name: 'composer', cwd: workspace.root });
terminal.sendText(`${composerPath} ${args.join(' ')}`);
await workspace.nvim.command('stopinsert');
}

export function runCommandCommand() {
return async () => {
const composerPath = await getComposerPath();
const args: string[] = [];

const runCommandList = workspace.getConfiguration('intelephense').get<string[]>('composer.runCommandList', []);

if (runCommandList.length === 0) {
window.showErrorMessage(`runCommandList is empty`);
return;
}

// Index of selected item, or -1 when canceled.
const choiceNumber = await window.showQuickpick(runCommandList);

if (choiceNumber !== -1) {
args.push(runCommandList[choiceNumber]);
runComposer(composerPath, args);
}
};
}

export function runCommandPlusCommand() {
return async () => {
const composerPath = await getComposerPath();
const args: string[] = [];

const runCommandPlusList = workspace
.getConfiguration('intelephense')
.get<string[]>('composer.runCommandPlusList', []);

if (runCommandPlusList.length === 0) {
window.showErrorMessage(`runCommandPlusList is empty`);
return;
}

// Index of selected item, or -1 when canceled.
const choiceNumber = await window.showQuickpick(runCommandPlusList);

if (choiceNumber !== -1) {
const input = await window.requestInput(`composer ${runCommandPlusList[choiceNumber]}`);

if (input) {
args.push(runCommandPlusList[choiceNumber]);
args.push(input);

runComposer(composerPath, args);
}
}
};
}

export function runScriptsCommand() {
return async () => {
const composerPath = await getComposerPath();
const args: string[] = [];

const existsComposerJsonFile = existsComposerJson();

if (!existsComposerJson()) {
window.showErrorMessage(`composer.json not found!`);
return;
}

const composerJson = JSON.parse(fs.readFileSync(path.join(workspace.root, 'composer.json'), 'utf8'));

let scriptsList: string[] = [];

Object.keys(composerJson).map((key) => {
if (key === 'scripts') {
const scriptsObj = composerJson[key];
Object.keys(scriptsObj).map((key) => {
if (!key.startsWith('pre-') && !key.startsWith('post-')) {
scriptsList.push(key);
}
});
}
});

if (scriptsList.length >= 1) {
// Index of selected item, or -1 when canceled.
const choiceNumber = await window.showQuickpick(scriptsList);

if (choiceNumber !== -1) {
args.push('run-script');
args.push(scriptsList[choiceNumber]);

runComposer(composerPath, args);
}
} else {
window.showWarningMessage(`scripts not found. events (pre-, post-) are excluded by default`);
return;
}
};
}
6 changes: 5 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { existsSync } from 'fs';
import { IntelephenseSnippetsCompletionProvider } from './completion/IntelephenseSnippetsCompletion';
import { IntelephenseCodeActionProvider } from './actions';
import { IntelephenseCodeLensProvider } from './lenses';
import { runCommandCommand, runCommandPlusCommand, runScriptsCommand } from './commands/composer';
import { fileTestCommand, singleTestCommand, projectTestCommand } from './commands/phpunit';

const PHP_LANGUAGE_ID = 'php';
Expand Down Expand Up @@ -98,7 +99,10 @@ export async function activate(context: ExtensionContext): Promise<void> {
context.subscriptions.push(
commands.registerCommand('intelephense.phpunit.projectTest', projectTestCommand()),
commands.registerCommand('intelephense.phpunit.fileTest', fileTestCommand()),
commands.registerCommand('intelephense.phpunit.singleTest', singleTestCommand())
commands.registerCommand('intelephense.phpunit.singleTest', singleTestCommand()),
commands.registerCommand('intelephense.composer.runCommand', runCommandCommand()),
commands.registerCommand('intelephense.composer.runCommandPlus', runCommandPlusCommand()),
commands.registerCommand('intelephense.composer.runScriptsCommand', runScriptsCommand())
);

// Add code lens by "client" side
Expand Down

0 comments on commit 7ba14d0

Please sign in to comment.