Skip to content

Commit

Permalink
feat: add installation process for zsh (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
renancaraujo authored Nov 15, 2022
1 parent 8d401ab commit d7cdfd5
Show file tree
Hide file tree
Showing 18 changed files with 982 additions and 44 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@
.dart_tool/
.packages
build/
pubspec.lock
pubspec.lock

coverage/
1 change: 1 addition & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions .idea/cli_completion.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 0 additions & 11 deletions lib/cli_completion.dart

This file was deleted.

5 changes: 5 additions & 0 deletions lib/install.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// Contains the functions related to the installation file
library install;

export 'src/install/install_completion.dart';
export 'src/install/shell_completion_installation.dart';
14 changes: 0 additions & 14 deletions lib/src/cli_completion.dart

This file was deleted.

20 changes: 20 additions & 0 deletions lib/src/exceptions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/// {@template completion_installation_exception}
/// Describes an exception during the installation of completion scripts.
/// {@endtemplate}
class CompletionInstallationException implements Exception {
/// {@macro completion_installation_exception}
CompletionInstallationException({
required this.message,
required this.rootCommand,
});

/// The error message for this exception
final String message;

/// The command for which the installation failed.
final String rootCommand;

@override
String toString() => 'Could not install completion scripts for $rootCommand: '
'$message';
}
36 changes: 36 additions & 0 deletions lib/src/install/install_completion.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'package:cli_completion/src/exceptions.dart';
import 'package:cli_completion/src/install/shell_completion_installation.dart';

import 'package:mason_logger/mason_logger.dart';

/// Install completion configuration hooks for a [rootCommand] in the
/// current shell.
void installCompletion({
required Logger logger,
required String rootCommand,
bool? isWindowsOverride,
Map<String, String>? environmentOverride,
}) {
logger
..detail('Completion installation for $rootCommand started')
..detail('Identifying system shell');

final completionInstallation = ShellCompletionInstallation.fromCurrentShell(
logger: logger,
isWindowsOverride: isWindowsOverride,
environmentOverride: environmentOverride,
);

if (completionInstallation == null) {
throw CompletionInstallationException(
message: 'Unknown shell.',
rootCommand: rootCommand,
);
}

logger.detail(
'Shell identified as ${completionInstallation.configuration.name}',
);

completionInstallation.install(rootCommand);
}
70 changes: 70 additions & 0 deletions lib/src/install/shell_completion_configuration.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:meta/meta.dart';

/// A type definition for functions that creates the content of a
/// completion script given a [rootCommand]
typedef CompletionScriptTemplate = String Function(String rootCommand);

/// A type definition for functions that describes
/// the source line given a [scriptPath]
typedef SourceStringTemplate = String Function(String scriptPath);

/// {@template shell_completion_configuration}
/// Describes the configuration of a completion script in a specific shell.
///
/// See:
/// - [zshConfiguration] for zsh
@immutable
class ShellCompletionConfiguration {
/// {@macro shell_completion_configuration}
@visibleForTesting
const ShellCompletionConfiguration({
required this.name,
required this.shellRCFile,
required this.sourceLineTemplate,
required this.scriptTemplate,
});

/// A descriptive string to identify the shell among others.
final String name;

/// The location of a config file that is run upon shell start.
/// Eg: .bashrc or .zshrc
final String shellRCFile;

/// Generates a line to sources of a script file.
final SourceStringTemplate sourceLineTemplate;

/// Generates the contents of a completion script.
final CompletionScriptTemplate scriptTemplate;

/// The name for the config file for this shell.
String get completionConfigForShellFileName => '$name-config.$name';
}

/// A [ShellCompletionConfiguration] for zsh.
final zshConfiguration = ShellCompletionConfiguration(
name: 'zsh',
shellRCFile: '~/.zshrc',
sourceLineTemplate: (String scriptPath) {
return '[[ -f $scriptPath ]] && . $scriptPath || true';
},
scriptTemplate: (String rootCommand) {
// Completion script for zsh.
//
// Based on https://github.com/mklabs/tabtab/blob/master/lib/scripts/zsh.sh
return '''
if type compdef &>/dev/null; then
_${rootCommand}_completion () {
local reply
local si=\$IFS
IFS=\$'\n' reply=(\$(COMP_CWORD="\$((CURRENT-1))" COMP_LINE="\$BUFFER" COMP_POINT="\$CURSOR" $rootCommand completion -- "\${words[@]}"))
IFS=\$si
_describe 'values' reply
}
compdef _${rootCommand}_completion $rootCommand
fi
''';
},
);
Loading

0 comments on commit d7cdfd5

Please sign in to comment.