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

fix: update help text #608

Merged
merged 5 commits into from
Jan 31, 2024
Merged
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
4 changes: 4 additions & 0 deletions src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export abstract class AutocompleteBase extends Command {
}
}

public getSetupEnvVar(shell: string): string {
return `${this.cliBinEnvVar}_AC_${shell.toUpperCase()}_SETUP_PATH`
}

Copy link
Member Author

Choose a reason for hiding this comment

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

I was building this string multiple times (and is also used in the output script) so made it a method in the base class.

writeLogFile(msg: string) {
mkdirSync(this.config.cacheDir, {recursive: true})
const entry = `[${new Date().toISOString()}] ${msg}\n`
Expand Down
118 changes: 76 additions & 42 deletions src/commands/autocomplete/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,6 @@ import {EOL} from 'node:os'
import {AutocompleteBase} from '../../base.js'
import Create from './create.js'

const noteFromShell = (shell: string) => {
switch (shell) {
case 'zsh': {
return `After sourcing, you can run \`${chalk.cyan(
'$ compaudit -D',
)}\` to ensure no permissions conflicts are present`
}

case 'bash': {
return 'If your terminal starts as a login shell you may need to print the init script into ~/.bash_profile or ~/.profile.'
}

case 'powershell': {
return `Use the \`MenuComplete\` mode to get matching completions printed below the command line:\n${chalk.cyan(
'Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete',
)}`
}

default: {
return ''
}
}
}

export default class Index extends AutocompleteBase {
static args = {
shell: Args.string({
Expand Down Expand Up @@ -67,32 +43,90 @@ export default class Index extends AutocompleteBase {
ux.action.stop()

if (!flags['refresh-cache']) {
const {bin} = this.config
const tabStr = shell === 'bash' ? '<TAB><TAB>' : '<TAB>'
this.printShellInstructions(shell)
}
}

private printShellInstructions(shell: string): void {
const setupEnvVar = this.getSetupEnvVar(shell)
const tabStr = shell === 'bash' ? '<TAB><TAB>' : '<TAB>'
const scriptCommand = `${this.config.bin} autocomplete${this.config.topicSeparator}script ${shell}`

let instructions = `
Setup Instructions for ${this.config.bin.toUpperCase()} CLI Autocomplete ---
==============================================
`

switch (shell) {
case 'bash': {
instructions += `
1) Run this command in your terminal window:

const instructions =
shell === 'powershell'
? `New-Item -Type Directory -Path (Split-Path -Parent $PROFILE) -ErrorAction SilentlyContinue
Add-Content -Path $PROFILE -Value (Invoke-Expression -Command "${bin} autocomplete${this.config.topicSeparator}script ${shell}"); .$PROFILE`
: `$ printf "eval $(${bin} autocomplete${this.config.topicSeparator}script ${shell})" >> ~/.${shell}rc; source ~/.${shell}rc`
${chalk.cyan(`printf "eval $(${scriptCommand})" >> ~/.bashrc; source ~/.bashrc`)}

const note = noteFromShell(shell)
The previous command adds the ${chalk.cyan(setupEnvVar)} environment variable to your Bash config file and then sources the file.

this.log(`
${chalk.bold(`Setup Instructions for ${bin.toUpperCase()} CLI Autocomplete ---`)}
${chalk.bold('NOTE')}: If you’ve configured your terminal to start as a login shell, you may need to modify the command so it updates either the ~/.bash_profile or ~/.profile file. For example:

1) Add the autocomplete ${shell === 'powershell' ? 'file' : 'env var'} to your ${shell} profile and source it
${chalk.cyan(`printf "eval $(${scriptCommand}) >> ~/.bash_profile; source ~/.bash_profile`)}

Or:

${chalk.cyan(instructions)}
${chalk.cyan(`printf "eval $(${scriptCommand})" >> ~/.profile; source ~/.profile`)}

${chalk.bold('NOTE')}: ${note}
2) Start using autocomplete:

2) Test it out, e.g.:
${chalk.cyan(`$ ${bin} ${tabStr}`)} # Command completion
${chalk.cyan(`$ ${bin} command --${tabStr}`)} # Flag completion
${chalk.cyan(`sf ${tabStr}`)} # Command completion
${chalk.cyan(`sf command --${tabStr}`)} # Flag completion
`
break
}

Enjoy!
`)
case 'zsh': {
instructions += `
1) Run this command in your terminal window:

${chalk.cyan(`printf "eval $(${scriptCommand})" >> ~/.zshrc; source ~/.zshrc`)}

The previous command adds the ${chalk.cyan(setupEnvVar)} environment variable to your zsh config file and then sources the file.

2) (Optional) Run this command to ensure that you have no permissions conflicts:

${chalk.cyan('compaudit -D')}

3) Start using autocomplete:

${chalk.cyan(`sf ${tabStr}`)} # Command completion
${chalk.cyan(`sf command --${tabStr}`)} # Flag completion
`
break
}

case 'powershell': {
instructions += `
1) Run these two cmdlets in your PowerShell window in the order shown:

${chalk.cyan(`New-Item -Type Directory -Path (Split-Path -Parent $PROFILE) -ErrorAction SilentlyContinue
Add-Content -Path $PROFILE -Value (Invoke-Expression -Command "${scriptCommand}"); .$PROFILE`)}

2) (Optional) If you want matching completions printed below the command line, run this cmdlet:

${chalk.cyan('Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete')}

3) Start using autocomplete:

${chalk.cyan(`sf ${tabStr}`)} # Command completion
${chalk.cyan(`sf command --${tabStr}`)} # Flag completion
`
break
}
}

instructions += `
Every time you enter ${tabStr}, the autocomplete feature displays a list of commands (or flags if you type --), along with their summaries. Enter a letter and then ${tabStr} again to narrow down the list until you end up with the complete command that you want to execute.

Enjoy!
`
this.log(instructions)
}
}
8 changes: 2 additions & 6 deletions src/commands/autocomplete/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ export default class Script extends AutocompleteBase {
const {args} = await this.parse(Script)
const shell = args.shell ?? this.config.shell

const binUpcase = this.cliBinEnvVar
const shellUpcase = shell.toUpperCase()
if (shell === 'powershell') {
const completionFuncPath = path.join(
this.config.cacheDir,
Expand All @@ -33,12 +31,10 @@ export default class Script extends AutocompleteBase {
this.log(`. ${completionFuncPath}`)
} else {
this.log(
`${this.prefix}${binUpcase}_AC_${shellUpcase}_SETUP_PATH=${path.join(
`${this.prefix}${this.getSetupEnvVar(shell)}=${path.join(
this.autocompleteCacheDir,
`${shell}_setup`,
)} && test -f $${binUpcase}_AC_${shellUpcase}_SETUP_PATH && source $${binUpcase}_AC_${shellUpcase}_SETUP_PATH;${
this.suffix
}`,
)} && test -f $${this.getSetupEnvVar(shell)} && source $${this.getSetupEnvVar(shell)};${this.suffix}`,
)
}
}
Expand Down
35 changes: 2 additions & 33 deletions test/commands/autocomplete/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable no-useless-escape */
import {expect, test} from '@oclif/test'

// autocomplete will throw error on windows ci
Expand All @@ -9,43 +8,13 @@ skipWindows('autocomplete index', () => {
.stdout()
.command(['autocomplete', 'bash'])
.it('provides bash instructions', (ctx) => {
expect(ctx.stdout).to.contain(`
Setup Instructions for OCLIF-EXAMPLE CLI Autocomplete ---

1) Add the autocomplete env var to your bash profile and source it

$ printf \"eval $(oclif-example autocomplete:script bash)\" >> ~/.bashrc; source ~/.bashrc

NOTE: If your terminal starts as a login shell you may need to print the init script into ~/.bash_profile or ~/.profile.

2) Test it out, e.g.:
$ oclif-example <TAB><TAB> # Command completion
$ oclif-example command --<TAB><TAB> # Flag completion

Enjoy!

`)
expect(ctx.stdout).to.contain(`Setup Instructions for OCLIF-EXAMPLE CLI Autocomplete ---`)
})
Copy link
Member Author

Choose a reason for hiding this comment

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

instructions for all shells are wrapped in a single method so just made these tests look for the first line to ensure it's returning something.


test
.stdout()
.command(['autocomplete', 'zsh'])
.it('provides zsh instructions', (ctx) => {
expect(ctx.stdout).to.contain(`
Setup Instructions for OCLIF-EXAMPLE CLI Autocomplete ---

1) Add the autocomplete env var to your zsh profile and source it

$ printf \"eval $(oclif-example autocomplete:script zsh)\" >> ~/.zshrc; source ~/.zshrc

NOTE: After sourcing, you can run \`$ compaudit -D\` to ensure no permissions conflicts are present

2) Test it out, e.g.:
$ oclif-example <TAB> # Command completion
$ oclif-example command --<TAB> # Flag completion

Enjoy!

`)
expect(ctx.stdout).to.contain(`Setup Instructions for OCLIF-EXAMPLE CLI Autocomplete ---`)
})
})
Loading