Skip to content

chore(completion) - generate shell script in a much more automated way #3981

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

Closed
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
99b5636
Completion.sh is generated in a much more automated way. It requires…
catull Jan 13, 2017
746e964
Merge branch 'master' into enhancement-automation-of-completion-script
catull Jan 13, 2017
f9800b7
Merge from master
catull Jan 15, 2017
8045f0e
Now the completion shell script is generated out of TypeScript code e…
catull Jan 15, 2017
cab0460
Work around 100-character line length limit.
catull Jan 18, 2017
e397ff8
Merge branch 'master' into enhancement-automation-of-completion-script
catull Jan 18, 2017
293e97b
Solution for the redirection. Actually, with the new solution, there…
catull Jan 18, 2017
a459242
Merge branch 'master' into enhancement-automation-of-completion-script
catull Jan 18, 2017
a4c299c
merge from master
catull Jan 21, 2017
b249f5a
Replace console.log() with this.ui.writeLine().
catull Jan 21, 2017
0f3c82e
Rewrote comkpletion.ts, deeply inspired by help.ts.
catull Jan 22, 2017
3de15a5
Merge branch 'master' into enhancement-automation-of-completion-script
catull Jan 22, 2017
a56a1ea
Merge branch 'master' into enhancement-automation-of-completion-script
catull Jan 22, 2017
5c999a2
rawArgs are not used. this.ui.writeLine always prepends ANSI codes i…
catull Jan 22, 2017
4e10a23
Do not consider easter-egg, destroy or github-pages-deploy.
catull Jan 22, 2017
c390dab
Merge branch 'master' into enhancement-automation-of-completion-script
catull Jan 22, 2017
69d1b55
Merge branch 'master' into enhancement-automation-of-completion-script
catull Jan 22, 2017
6a840d6
Merge branch 'master' into enhancement-automation-of-completion-script
catull Jan 23, 2017
443fbed
Merge branch 'master' into enhancement-automation-of-completion-script
catull Jan 24, 2017
9f7335b
Merge branch 'master' into enhancement-automation-of-completion-script
catull Jan 27, 2017
da3d31a
Merge from master to test new options of
catull Jan 28, 2017
1739176
Merge branch 'master' into enhancement-automation-of-completion-script
catull Jan 31, 2017
ed1e303
Resolving review findings.
catull Jan 31, 2017
58a5646
Merge branch 'master' into enhancement-automation-of-completion-script
catull Jan 31, 2017
e322284
Merge branch 'master' into enhancement-automation-of-completion-script
catull Feb 1, 2017
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
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ The CLI supports routing in several ways:
- When you generate a module, you can use the `--routing` option like `ng g module my-module --routing` to create a separate file `my-module-routing.module.ts` to store the module routes.

The file includes an empty `Routes` object that you can fill with routes to different components and/or modules.

The `--routing` option also generates a default component with the same name as the module.

- You can use the `--routing` option with `ng new` or `ng init` to create a `app-routing.module.ts` file when you create or initialize a project.
Expand Down Expand Up @@ -289,19 +289,19 @@ To turn on auto completion use the following commands:

For bash:
```bash
ng completion 1>> ~/.bashrc 2>>&1
ng completion --bash 1>> ~/.bashrc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop the 1 in 1>>.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, changed it in completion.ts, too.

source ~/.bashrc
```

For zsh:
```bash
ng completion 1>> ~/.zshrc 2>>&1
ng completion --zsh 1>> ~/.zshrc
source ~/.zshrc
```

Windows users using gitbash:
```bash
ng completion 1>> ~/.bash_profile 2>>&1
ng completion --bash 1>> ~/.bash_profile
source ~/.bash_profile
```

Expand Down
198 changes: 194 additions & 4 deletions packages/angular-cli/commands/completion.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,207 @@
import * as path from 'path';
import * as fs from 'fs';
import { oneLine } from 'common-tags';

import BuildCommand from './build';
import DestroyCommand from './destroy';
import DocCommand from './doc';
import E2eCommand from './e2e';
import MakeThisAwesomeCommand from './easter-egg';
import GenerateCommand from '../commands/generate';
import GetCommand from './get';
import githubPagesDeployCommand from './github-pages-deploy';
import HelpCommand from './help';
import InitCommand from './init';
import LintCommand from './lint';
import NewCommand from './new';
import ServeCommand from './serve';
import SetCommand from './set';
import NgCliTestCommand from './test';
import VersionCommand from './version';

const Command = require('../ember-cli/lib/models/command');

function generateOptionVar(opts: any): String {
const output: String[] = [];

for (let index = 0; index < opts.length; index++) {
const element = opts[index];
output.push('--' + element.name);
if (element.aliases) {
output.push('-' + element.aliases[0]);
}
}

return output.sort().join(' ');
}

function collectCommandAndAlias(command: any): String {
const result: String[] = [];
optsNg.push(command.name);
result.push(command.name);

if (command.aliases) {
command.aliases.forEach((element: String) => {
optsNg.push(element);
result.push(element);
});
}
return result.sort().join('|');
}

const optsNg: String[] = [];

const caseBuild = collectCommandAndAlias(BuildCommand.prototype);
optsNg.push('completion');
// const case_destroy = collectCommandAndAlias(DestroyCommand.prototype);
// const case_doc = collectCommandAndAlias(DocCommand.prototype);
// const case_e2e = collectCommandAndAlias(E2eCommand.prototype);
// const caseGenerate = collectCommandAndAlias(GenerateCommand.prototype);
const caseGenerate = 'g|generate';
// const caseGet = collectCommandAndAlias(GetCommand.prototype);
const caseGhPagesDeploy = collectCommandAndAlias(githubPagesDeployCommand.prototype);
const caseHelp = collectCommandAndAlias(HelpCommand.prototype);
const caseInit = collectCommandAndAlias(InitCommand.prototype);
const caseLint = collectCommandAndAlias(LintCommand.prototype);
// const caseMakethisawesome = collectCommandAndAlias(MakeThisAwesomeCommand.prototype);
const caseNew = collectCommandAndAlias(NewCommand.prototype);
const caseServe = collectCommandAndAlias(ServeCommand.prototype);
const caseSet = collectCommandAndAlias(SetCommand.prototype);
const caseTest = collectCommandAndAlias(NgCliTestCommand.prototype);
const caseVersion = collectCommandAndAlias(VersionCommand.prototype);

const optsHelp = optsNg.sort().join(' ');

let optsBuild = generateOptionVar(BuildCommand.prototype.availableOptions);
// let optsGenerate = generateMapVar (GenerateCommand.prototype.aliasMap);
let optsGenerate = oneLine`
cl class c component d directive e enum i interface m module p pipe r route s service`;
let optsGhPagesDeploy = generateOptionVar(githubPagesDeployCommand.prototype.availableOptions);
let optsInit = generateOptionVar(InitCommand.prototype.availableOptions);
let optsNew = generateOptionVar(NewCommand.prototype.availableOptions);
let optsServe = generateOptionVar(ServeCommand.prototype.availableOptions);
let optsSet = generateOptionVar(SetCommand.prototype.availableOptions);
let optsTest = generateOptionVar(NgCliTestCommand.prototype.availableOptions);
let optsVersion = generateOptionVar(VersionCommand.prototype.availableOptions);

function displayCaseBlock () {
console.log(`
ng|help) opts="${optsHelp}" ;;
${caseBuild}) opts="${optsBuild}" ;;
completion) opts="-a -b --all --bash --zsh" ;;
${caseGenerate}) opts="${optsGenerate}" ;;
${caseGhPagesDeploy}) opts="${optsGhPagesDeploy}" ;;
${caseInit}) opts="${optsInit}" ;;
${caseNew}) opts="${optsNew}" ;;
${caseServe}) opts="${optsServe}" ;;
${caseSet}) opts="${optsSet}" ;;
${caseTest}) opts="${optsTest}" ;;
${caseVersion}) opts="${optsVersion}" ;;
*) opts="" ;;`);
}

export interface CompletionCommandOptions {
all?: boolean;
bash?: boolean;
zsh?: boolean;
};

const CompletionCommand = Command.extend({
name: 'completion',
description: 'Adds autocomplete functionality to `ng` commands and subcommands',
works: 'everywhere',
run: function() {
const scriptPath = path.resolve(__dirname, '..', 'utilities', 'completion.sh');
const scriptOutput = fs.readFileSync(scriptPath, 'utf8');
availableOptions: [
{ name: 'all', type: Boolean, default: true, aliases: ['a'] },
{ name: 'bash', type: Boolean, default: false, aliases: ['b'] },
{ name: 'zsh', type: Boolean, default: false, aliases: ['z'] }
],

run: function (commandOptions: CompletionCommandOptions, rawArgs: string[]) {
commandOptions.all = !commandOptions.bash && !commandOptions.zsh;

console.log(`
###-begin-ng-completion###');
#

# ng command completion script
# This command supports 3 cases.
# 1. (Default case) It prints a common completion initialisation for both Bash and Zsh.
# It is the result of either calling "ng completion" or "ng completion -a".
# 2. Produce Bash-only completion: "ng completion -b" or "ng completion --bash".
# 3. Produce Zsh-only completion: "ng completion -z" or "ng completion --zsh".
#
# Installation: ng completion -b 1>> ~/.bashrc
# or ng completion -z 1>> ~/.zshrc
#`);

if (commandOptions.all && !commandOptions.bash) {
console.log(`
if test ".$(type -t complete 2>/dev/null || true)" = ".builtin"; then`);
}

if (commandOptions.all || commandOptions.bash) {
console.log(`
_ng_completion() {
local cword pword opts

COMPREPLY=()
cword=\${COMP_WORDS[COMP_CWORD]}
pword=\${COMP_WORDS[COMP_CWORD - 1]}

case \${pword} in`);

displayCaseBlock();

console.log(`
esac

COMPREPLY=( $(compgen -W '\${opts}' -- $cword) )

return 0
}

complete -o default -F _ng_completion ng`);
}

if (commandOptions.all) {
console.log(`
elif test ".$(type -w compctl 2>/dev/null || true)" = ".compctl: builtin" ; then`);
}

if (commandOptions.all || commandOptions.zsh) {
console.log(`
_ng_completion () {
local words cword opts
read -Ac words
read -cn cword
let cword-=1

case $words[cword] in`);

displayCaseBlock();

console.log(`
esac

setopt shwordsplit
reply=($opts)
unset shwordsplit
}

compctl -K _ng_completion ng`);
}

if (commandOptions.all) {
console.log(`
else
echo "Shell builtin command 'complete' or 'compctl' is redefined; cannot perform ng completion."
return 1
fi`);
}

console.log(scriptOutput);
console.log(`
###-end-ng-completion###
`);
}
});

Expand Down
85 changes: 0 additions & 85 deletions packages/angular-cli/utilities/completion.sh

This file was deleted.