Module: SpaceArchitect::ShellIntegration
- Defined in:
- lib/space_architect/shell_integration.rb
Constant Summary collapse
- FISH_TEMPLATE =
<<~'FISH' # Generated by space-architect. Do not edit by hand. function __space_architect_command set -l __ps_index 1 while test $__ps_index -le (count $argv) set -l __ps_arg $argv[$__ps_index] switch "$__ps_arg" case "--" set __ps_index (math $__ps_index + 1) if test $__ps_index -le (count $argv) echo $argv[$__ps_index] end return 0 case "--color" "--colors" set __ps_index (math $__ps_index + 2) continue case "--color=*" "--colors=*" set __ps_index (math $__ps_index + 1) continue case "-*" return 0 case "*" echo $__ps_arg return 0 end end end function __space_architect_has_color_option set -l __ps_index 1 while test $__ps_index -le (count $argv) set -l __ps_arg $argv[$__ps_index] switch "$__ps_arg" case "--color" "--colors" "--color=*" "--colors=*" return 0 case "--" return 1 end set __ps_index (math $__ps_index + 1) end return 1 end function space --wraps space --description "Create and manage project spaces" if not set -q __space_architect_compat_checked set -g __space_architect_compat_checked 1 set -l __space_architect_installed_version __SPACE_ARCHITECT_VERSION__ set -l __space_architect_binary_version (command space --version 2>/dev/null) if test "$__space_architect_binary_version" != "$__space_architect_installed_version" echo "space-architect: shell integration version $__space_architect_installed_version does not match binary version $__space_architect_binary_version; re-run 'space shell fish install'" >&2 end end set -l __space_command (__space_architect_command $argv) set -l __space_args $argv if test -t 1; and not __space_architect_has_color_option $argv set __space_args --color=always $__space_args end switch "$__space_command" case new use set -l __space_output (command space $__space_args) set -l __space_status $status if test (count $__space_output) -gt 0 printf "%s\n" $__space_output end if test $__space_status -eq 0 set -l __space_target $__space_output[-1] set __space_target (string replace -r "^~(?=/|\$)" $HOME -- $__space_target) if test -d "$__space_target" cd "$__space_target" end end return $__space_status case "*" command space $__space_args return $status end end FISH
- FISH_COMPLETIONS =
<<~'FISH' # Generated by space-architect. Do not edit by hand. function __space_architect_complete_command set -l tokens (commandline -opc) set -l index 2 while test $index -le (count $tokens) set -l token $tokens[$index] switch "$token" case "--" set index (math $index + 1) if test $index -le (count $tokens) echo $tokens[$index] end return 0 case "--color" "--colors" set index (math $index + 2) continue case "--color=*" "--colors=*" set index (math $index + 1) continue case "-*" set index (math $index + 1) continue case "*" echo $token return 0 end end end function __space_architect_complete_needs_command test -z "$(__space_architect_complete_command)" end function __space_architect_complete_using_command contains -- (__space_architect_complete_command) $argv end function __space_architect_complete_first_argument_after set -l commands $argv set -l tokens (commandline -opc) set -l index 2 set -l matched_command 0 while test $index -le (count $tokens) set -l token $tokens[$index] switch "$token" case "--color" "--colors" set index (math $index + 2) continue case "--color=*" "--colors=*" "-*" set index (math $index + 1) continue end if test $matched_command -eq 0 if contains -- "$token" $commands set matched_command 1 else return 1 end else echo $token return 0 end set index (math $index + 1) end return 1 end function __space_architect_complete_has_first_argument_after set -q argv[1]; or return 1 set -l first_argument (__space_architect_complete_first_argument_after $argv) test -n "$first_argument" end function __space_architect_complete_second_argument_after set -q argv[1]; or return 1 set -l command $argv[1] set -l tokens (commandline -opc) set -l index 2 set -l matched_command 0 set -l matched_first_argument 0 while test $index -le (count $tokens) set -l token $tokens[$index] switch "$token" case "--color" "--colors" set index (math $index + 2) continue case "--color=*" "--colors=*" "-*" set index (math $index + 1) continue end if test $matched_command -eq 0 test "$token" = "$command"; or return 1 set matched_command 1 else if test $matched_first_argument -eq 0 set matched_first_argument 1 else echo $token return 0 end set index (math $index + 1) end return 1 end function __space_architect_complete_has_second_argument_after set -q argv[1]; or return 1 set -l second_argument (__space_architect_complete_second_argument_after $argv) test -n "$second_argument" end function __space_architect_complete_first_argument_is set -q argv[1]; or return 1 set -l expected $argv[1] set -e argv[1] test "$(__space_architect_complete_first_argument_after $argv)" = "$expected" end function __space_architect_complete_spaces command space shell complete spaces 2>/dev/null end function __space_architect_complete_statuses command space shell complete statuses 2>/dev/null end function __space_architect_complete_config_keys command space shell complete config-keys 2>/dev/null end function __space_architect_complete_config_set_key set -l tokens (commandline -opc) set -l index 2 set -l matched_config 0 set -l matched_set 0 while test $index -le (count $tokens) set -l token $tokens[$index] switch "$token" case "--color" "--colors" set index (math $index + 2) continue case "--color=*" "--colors=*" "-*" set index (math $index + 1) continue end if test $matched_config -eq 0 test "$token" = "config"; or return 1 set matched_config 1 else if test $matched_set -eq 0 test "$token" = "set"; or return 1 set matched_set 1 else echo $token return 0 end set index (math $index + 1) end return 1 end function __space_architect_complete_config_set_has_key test -n "$(__space_architect_complete_config_set_key)" end function __space_architect_complete_config_set_key_is test "$(__space_architect_complete_config_set_key)" = "$argv[1]" end complete -c space -f -l color -x -a "auto always never" -d "Color output" complete -c space -f -l colors -x -a "auto always never" -d "Color output" complete -c space -f -n "__space_architect_complete_using_command init shell" -l force -d "Overwrite existing files" complete -c space -f -n "__space_architect_complete_using_command new" -s r -l repo -x -d "Clone a repo into the new space" complete -c space -f -n "__space_architect_complete_needs_command" -a init -d "Create default XDG config and state files" complete -c space -f -n "__space_architect_complete_needs_command" -a new -d "Create a new project space" complete -c space -f -n "__space_architect_complete_needs_command" -a list -d "List spaces" complete -c space -f -n "__space_architect_complete_needs_command" -a ls -d "List spaces" complete -c space -f -n "__space_architect_complete_needs_command" -a show -d "Show space metadata" complete -c space -f -n "__space_architect_complete_needs_command" -a path -d "Print a space path" complete -c space -f -n "__space_architect_complete_needs_command" -a use -d "Select and cd to a space with fish integration" complete -c space -f -n "__space_architect_complete_needs_command" -a current -d "Show the current space" complete -c space -f -n "__space_architect_complete_needs_command" -a status -d "Set a space status" complete -c space -f -n "__space_architect_complete_needs_command" -a config -d "Show or update config" complete -c space -f -n "__space_architect_complete_needs_command" -a repo -d "Manage repos in the current space" complete -c space -f -n "__space_architect_complete_needs_command" -a repos -d "Manage repos in the current space" complete -c space -f -n "__space_architect_complete_needs_command" -a shell -d "Manage shell integration" complete -c space -f -n "__space_architect_complete_using_command show path use" -a "(__space_architect_complete_spaces)" -d "Space" complete -c space -f -n "__space_architect_complete_using_command status" -a "(__space_architect_complete_spaces)" -d "Space" complete -c space -f -n "__space_architect_complete_using_command status" -a "(__space_architect_complete_statuses)" -d "Status" complete -c space -f -n "__space_architect_complete_first_argument_is init shell; and not __space_architect_complete_has_second_argument_after shell" -a fish -d "Fish shell" complete -c space -f -n "__space_architect_complete_using_command repo repos; and not __space_architect_complete_has_first_argument_after repo repos" -a add -d "Clone repos into the current space" complete -c space -f -n "__space_architect_complete_using_command repo repos; and not __space_architect_complete_has_first_argument_after repo repos" -a list -d "List repos in the current space" complete -c space -f -n "__space_architect_complete_using_command repo repos; and not __space_architect_complete_has_first_argument_after repo repos" -a ls -d "List repos in the current space" complete -c space -f -n "__space_architect_complete_using_command repo repos; and not __space_architect_complete_has_first_argument_after repo repos" -a resolve -d "Resolve repo names without cloning" complete -c space -f -n "__space_architect_complete_using_command config; and not __space_architect_complete_has_first_argument_after config" -a show -d "Show config" complete -c space -f -n "__space_architect_complete_using_command config; and not __space_architect_complete_has_first_argument_after config" -a path -d "Print config path" complete -c space -f -n "__space_architect_complete_using_command config; and not __space_architect_complete_has_first_argument_after config" -a set -d "Set a config value" complete -c space -f -n "__space_architect_complete_first_argument_is set config; and not __space_architect_complete_config_set_has_key" -a "(__space_architect_complete_config_keys)" -d "Config key" complete -c space -f -n "__space_architect_complete_config_set_key_is git_clone_protocol" -a "ssh https" -d "Clone protocol" complete -c space -f -n "__space_architect_complete_config_set_key_is default_provider" -a "github.com gitlab.com" -d "Git provider" complete -c space -f -n "__space_architect_complete_using_command shell; and not __space_architect_complete_has_first_argument_after shell" -a init -d "Print shell integration" complete -c space -f -n "__space_architect_complete_using_command shell; and not __space_architect_complete_has_first_argument_after shell" -a fish -d "Manage fish integration and completions" complete -c space -f -n "__space_architect_complete_using_command shell; and not __space_architect_complete_has_first_argument_after shell" -a complete -d "Print completion candidates" complete -c space -f -n "__space_architect_complete_first_argument_is fish shell; and not __space_architect_complete_has_second_argument_after shell" -a install -d "Install fish integration and completions" complete -c space -f -n "__space_architect_complete_first_argument_is fish shell; and not __space_architect_complete_has_second_argument_after shell" -a uninstall -d "Remove fish integration and completions" complete -c space -f -n "__space_architect_complete_first_argument_is fish shell; and not __space_architect_complete_has_second_argument_after shell" -a path -d "Print fish integration paths" complete -c space -f -n "__space_architect_complete_first_argument_is complete shell; and not __space_architect_complete_has_second_argument_after shell" -a "spaces statuses config-keys config-values shells color-modes repo-subcommands config-subcommands fish-subcommands" -d "Completion kind" FISH
Class Method Summary collapse
- .completions_for(shell) ⇒ Object
- .completions_path_for(shell, env: ENV) ⇒ Object
- .for(shell) ⇒ Object
- .install(shell, env: ENV, force: false) ⇒ Object
- .managed_fish?(content) ⇒ Boolean
- .path_for(shell, env: ENV) ⇒ Object
- .remove_managed_file(path:, content:, force:, description:) ⇒ Object
- .uninstall(shell, env: ENV, force: false) ⇒ Object
- .write_managed_file(path:, content:, force:, description:) ⇒ Object
Class Method Details
.completions_for(shell) ⇒ Object
339 340 341 342 343 344 345 346 |
# File 'lib/space_architect/shell_integration.rb', line 339 def self.completions_for(shell) case shell.to_s when "fish" FISH_COMPLETIONS else raise Error, "Unsupported shell '#{shell}'. Expected: fish" end end |
.completions_path_for(shell, env: ENV) ⇒ Object
357 358 359 360 361 362 363 364 |
# File 'lib/space_architect/shell_integration.rb', line 357 def self.completions_path_for(shell, env: ENV) case shell.to_s when "fish" XDG.config_home(env: env).join("fish", "completions", "space.fish") else raise Error, "Unsupported shell '#{shell}'. Expected: fish" end end |
.for(shell) ⇒ Object
330 331 332 333 334 335 336 337 |
# File 'lib/space_architect/shell_integration.rb', line 330 def self.for(shell) case shell.to_s when "fish" FISH_TEMPLATE.gsub("__SPACE_ARCHITECT_VERSION__", VERSION) else raise Error, "Unsupported shell '#{shell}'. Expected: fish" end end |
.install(shell, env: ENV, force: false) ⇒ Object
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
# File 'lib/space_architect/shell_integration.rb', line 366 def self.install(shell, env: ENV, force: false) function_result = write_managed_file( path: path_for(shell, env:), content: self.for(shell), force: force, description: "fish function" ) completions_result = write_managed_file( path: completions_path_for(shell, env:), content: completions_for(shell), force: force, description: "fish completions" ) function_result.merge( completions_action: completions_result.fetch(:action), completions_path: completions_result.fetch(:path) ) end |
.managed_fish?(content) ⇒ Boolean
406 407 408 409 |
# File 'lib/space_architect/shell_integration.rb', line 406 def self.managed_fish?(content) content.include?("Generated by space-architect") || (content.include?("function __space_architect_command") && content.include?("function space --wraps space")) end |
.path_for(shell, env: ENV) ⇒ Object
348 349 350 351 352 353 354 355 |
# File 'lib/space_architect/shell_integration.rb', line 348 def self.path_for(shell, env: ENV) case shell.to_s when "fish" XDG.config_home(env: env).join("fish", "functions", "space.fish") else raise Error, "Unsupported shell '#{shell}'. Expected: fish" end end |
.remove_managed_file(path:, content:, force:, description:) ⇒ Object
426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/space_architect/shell_integration.rb', line 426 def self.remove_managed_file(path:, content:, force:, description:) return { action: :missing, path: path } unless path.exist? existing = path.read if existing != content && !force && !managed_fish?(existing) raise Error, "Refusing to remove existing #{description} at #{path}. Re-run with --force." end FileUtils.rm_f(path) { action: :removed, path: path } end |
.uninstall(shell, env: ENV, force: false) ⇒ Object
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 |
# File 'lib/space_architect/shell_integration.rb', line 386 def self.uninstall(shell, env: ENV, force: false) function_result = remove_managed_file( path: path_for(shell, env:), content: self.for(shell), force: force, description: "fish function" ) completions_result = remove_managed_file( path: completions_path_for(shell, env:), content: completions_for(shell), force: force, description: "fish completions" ) function_result.merge( completions_action: completions_result.fetch(:action), completions_path: completions_result.fetch(:path) ) end |
.write_managed_file(path:, content:, force:, description:) ⇒ Object
411 412 413 414 415 416 417 418 419 420 421 422 423 424 |
# File 'lib/space_architect/shell_integration.rb', line 411 def self.write_managed_file(path:, content:, force:, description:) existing = path.read if path.exist? if existing && existing != content && !force && !managed_fish?(existing) raise Error, "Refusing to overwrite existing #{description} at #{path}. Re-run with --force." end if existing == content { action: :unchanged, path: path } else AtomicWrite.write(path, content) { action: existing ? :updated : :installed, path: path } end end |