From 4f67b02a9f43b0996ad85ee600b468399e1477e5 Mon Sep 17 00:00:00 2001 From: José Camelo Freitas Date: Tue, 26 Oct 2021 07:07:46 -0700 Subject: feat(mix): update `mix` commands and descriptions (#10273) --- plugins/mix/README.md | 16 ++++++++-------- plugins/mix/_mix | 43 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 16 deletions(-) (limited to 'plugins') diff --git a/plugins/mix/README.md b/plugins/mix/README.md index 878f370f2..f0258fe88 100644 --- a/plugins/mix/README.md +++ b/plugins/mix/README.md @@ -9,11 +9,11 @@ plugins=(... mix) ``` ## Supported Task Types -| Task Type | Documentation | -|-------------------------|----------------------------------------------------------| -| Elixir | [Elixir Lang](https://elixir-lang.org/) | -| Phoenix v1.2.1 and below| [Phoenix](https://hexdocs.pm/phoenix/1.2.1/Phoenix.html) | -| Phoenix v1.3.0 and above| [Phoenix](https://hexdocs.pm/phoenix/Phoenix.html) | -| Ecto | [Ecto](https://hexdocs.pm/ecto/Ecto.html) | -| Hex | [Hex](https://hex.pm/) | -| Nerves | [Nerves](https://nerves-project.org/) | +| Task Type | Documentation | +|--------------------------|----------------------------------------------------------| +| Elixir | [Elixir Lang](https://elixir-lang.org/) | +| Phoenix v1.2.1 and below | [Phoenix](https://hexdocs.pm/phoenix/1.2.1/Phoenix.html) | +| Phoenix v1.3.0 and above | [Phoenix](https://hexdocs.pm/phoenix/Phoenix.html) | +| Ecto | [Ecto](https://hexdocs.pm/ecto/Ecto.html) | +| Hex | [Hex](https://hex.pm/) | +| Nerves | [Nerves](https://nerves-project.org/) | diff --git a/plugins/mix/_mix b/plugins/mix/_mix index c0fe68c91..7940ff1c9 100644 --- a/plugins/mix/_mix +++ b/plugins/mix/_mix @@ -5,8 +5,10 @@ local -a _1st_arguments _1st_arguments=( + 'app.config:Configures all registered apps' 'app.start:Start all registered apps' - 'archive:List all archives' + 'app.tree:Prints the application tree' + 'archive:Lists installed archives' 'archive.build:Archive this project into a .ez file' 'archive.install:Install an archive locally' 'archive.uninstall:Uninstall archives' @@ -18,6 +20,7 @@ _1st_arguments=( "deps.clean:Remove the given dependencies' files" 'deps.compile:Compile dependencies' 'deps.get:Get all out of date dependencies' + 'deps.tree:Prints the dependency tree' 'deps.unlock:Unlock the given dependencies' 'deps.update:Update the given dependencies' 'do:Executes the tasks separated by comma' @@ -30,27 +33,39 @@ _1st_arguments=( 'ecto.migrate:Runs Ecto migration' 'ecto.migrations:Displays the up / down migration status' 'ecto.rollback:Reverts applied migrations' + 'escript:Lists installed escripts' 'escript.build:Builds an escript for the project' + 'escript.install:Installs an escript locally' + 'escript.uninstall:Uninstalls escripts' 'firmware:Nerves - Build a firmware image for the selected target platform' 'firmware.burn:Nerves - Writes the generated firmware image to an attached SDCard or file' 'firmware.image:Nerves - Create a firmware image file that can be copied byte-for-byte' 'format:Formats the given files and patterns' 'help:Print help information for tasks' 'hex:Print hex help information' - 'hex.config:Read or update hex config' - 'hex.docs:Publish docs for package' + 'hex.audit:Shows retired Hex deps for the current project' + 'hex.build:Builds a new package version locally' + 'hex.config:Reads, updates or deletes local Hex config' + 'hex.docs:Fetches or opens documentation of a package' 'hex.info:Print hex information' + 'hex.organization:Manages Hex.pm organizations' 'hex.key:Hex API key tasks' - 'hex.outdated:Shows outdated hex deps for the current project' - 'hex.owner:Hex package ownership tasks' + 'hex.outdated:Shows outdated Hex deps for the current project' + 'hex.owner:Manages Hex package ownership' + 'hex.package:Fetches or diffs packages' 'hex.publish:Publish a new package version' + 'hex.registry:Manages local Hex registries' + 'hex.repo:Manages Hex repositories' + 'hex.retire:Retires a package version' 'hex.search:Search for package names' - 'hex.user:Hex user tasks' + 'hex.sponsor:Show Hex packages accepting sponsorships' + 'hex.user:Manages your Hex user account' 'loadconfig:Loads and persists the given configuration' 'local:List local tasks' 'local.hex:Install hex locally' 'local.phoenix:Updates Phoenix locally' 'local.phx:Updates the Phoenix project generator locally' + 'local.public_keys:Manages public keys' 'local.rebar:Install rebar locally' 'nerves.artifact:Create an artifact for a specified Nerves package' 'nerves.artifact.get:Nerves get artifacts' @@ -69,21 +84,33 @@ _1st_arguments=( 'phoenix.server:Starts applications and their servers' 'phx.digest:Digests and compresses static files' 'phx.digest.clean:Removes old versions of static assets.' + 'phx.gen.auth:Generates authentication logic for a resource' + 'phx.gen.cert:Generates a self-signed certificate for HTTPS testing' 'phx.gen.channel:Generates a Phoenix channel' 'phx.gen.context:Generates a context with functions around an Ecto schema' 'phx.gen.embedded:Generates an embedded Ecto schema file' 'phx.gen.html:Generates controller, views, and context for an HTML resource' 'phx.gen.json:Generates controller, views, and context for a JSON resource' + 'phx.gen.live:Generates LiveView, templates, and context for a resource' + 'phx.gen.notifier:Generates a notifier that delivers emails by default' 'phx.gen.presence:Generates a Presence tracker' 'phx.gen.schema:Generates an Ecto schema and migration file' 'phx.gen.secret:Generates a secret' - 'phx.new:Creates a new Phoenix v1.3.0 application' + 'phx.gen.socket:Generates a Phoenix socket handler' + 'phx.new:Creates a new Phoenix application' 'phx.new.ecto:Creates a new Ecto project within an umbrella project' 'phx.new.web:Creates a new Phoenix web project within an umbrella project' 'phx.routes:Prints all routes' 'phx.server:Starts applications and their servers' + 'profile.cprof:Profiles the given file or expression with cprof' + 'profile.eprof:Profiles the given file or expression with eprof' + 'profile.fprof:Profiles the given file or expression with fprof' + 'release:Assembles a self-contained release' + 'release.init:Generates sample files for releases' 'run:Run the given file or expression' "test:Run a project's tests" + 'test.coverage:Build report from exported test coverage' + 'xref:Prints cross reference information' '--help:Describe available tasks' '--version:Prints the Elixir version information' ) @@ -93,7 +120,7 @@ __task_list () local expl declare -a tasks - tasks=(app.start archive archive.build archive.install archive.uninstall clean cmd compile compile.protocols deps deps.clean deps.compile deps.get deps.unlock deps.update do escript.build format help hex hex.config hex.docs hex.info hex.key hex.outdated hex.owner hex.publish hex.search hex.user loadconfig local local.hex local.rebar new phoenix.digest phoenix.gen.channel phoenix.gen.html phoenix.gen.json phoenix.gen.model phoenix.gen.secret phoenix.new phoenix.routes phoenix.server phx.digest phx.digest.clean phx.gen.channel phx.gen.context phx.gen.embedded phx.gen.html phx.gen.json phx.gen.presence phx.gen.schema phx.gen.secret phx.new phx.new.ecto phx.new.web phx.routes phx.server run test) + tasks=(app.config app.start app.tree archive archive.build archive.install archive.uninstall clean cmd compile compile.protocols deps deps.clean deps.compile deps.get deps.tree deps.unlock deps.update do ecto.create ecto.drop ecto.dump ecto.gen.migration ecto.gen.repo ecto.load ecto.migrate ecto.migrations ecto.rollback escript escript.build escript.install escript.uninstall firmware firmware.burn firmware.image format help hex hex.audit hex.build hex.config hex.docs hex.info hex.organization hex.key hex.outdated hex.owner hex.package hex.publish hex.registry hex.repo hex.retire hex.search hex.sponsor hex.user loadconfig local local.hex local.phoenix local.phx local.public_keys local.rebar nerves.artifact nerves.artifact.get nerves.info nerves.new nerves.release.init new phoenix.digest phoenix.gen.channel phoenix.gen.html phoenix.gen.json phoenix.gen.model phoenix.gen.secret phoenix.new phoenix.routes phoenix.server phx.digest phx.digest.clean phx.gen.auth phx.gen.cert phx.gen.channel phx.gen.context phx.gen.embedded phx.gen.html phx.gen.json phx.gen.live phx.gen.notifier phx.gen.presence phx.gen.schema phx.gen.secret phx.gen.socket phx.new phx.new.ecto phx.new.web phx.routes phx.server profile.cprof profile.eprof profile.fprof release release.init run test test.coverage xref) _wanted tasks expl 'help' compadd $tasks } -- cgit v1.2.3-70-g09d2 From 2e46b2a2dcb96cadd94283bdce95eca75bef1433 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Wed, 27 Oct 2021 11:40:09 +0200 Subject: feat(fzf): support getting fzf from nix-darwin (#10355) --- plugins/fzf/fzf.plugin.zsh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/fzf/fzf.plugin.zsh b/plugins/fzf/fzf.plugin.zsh index a979fe222..aabd62cb1 100644 --- a/plugins/fzf/fzf.plugin.zsh +++ b/plugins/fzf/fzf.plugin.zsh @@ -20,7 +20,9 @@ function setup_using_base_dir() { done if [[ -z "${fzf_base}" ]]; then - if (( ${+commands[brew]} )) && dir="$(brew --prefix fzf 2>/dev/null)"; then + if (( ${+commands[fzf-share]} )) && dir="$(fzf-share)" && [[ -d "${dir}" ]]; then + fzf_base="${dir}" + elif (( ${+commands[brew]} )) && dir="$(brew --prefix fzf 2>/dev/null)"; then if [[ -d "${dir}" ]]; then fzf_base="${dir}" fi -- cgit v1.2.3-70-g09d2 From 1861b5f175dc8f6d6408772b707c9d6deb28a53f Mon Sep 17 00:00:00 2001 From: YR Chen Date: Fri, 29 Oct 2021 23:40:23 +0800 Subject: feat(xcode): support `Package.swift` as project file in `xc` (#10358) --- plugins/xcode/README.md | 2 +- plugins/xcode/xcode.plugin.zsh | 28 +++++++++------------------- 2 files changed, 10 insertions(+), 20 deletions(-) (limited to 'plugins') diff --git a/plugins/xcode/README.md b/plugins/xcode/README.md index 37f882638..664a063a3 100644 --- a/plugins/xcode/README.md +++ b/plugins/xcode/README.md @@ -26,7 +26,7 @@ plugins=(... xcode) ### `xc` -Opens the current directory in Xcode as an Xcode project. This will open one of the `.xcworkspace` and `.xcodeproj` files that it can find in the current working directory. You can also specify a directory to look in for the Xcode files. +Opens the current directory in Xcode as an Xcode project or a Swift package. This will open one of the `.xcworkspace`, `.xcodeproj` and `Package.swift` files that it can find in the current working directory. You can also specify a directory to look in for the Xcode files. Returns 1 if it didn't find any relevant files. ### `xx` diff --git a/plugins/xcode/xcode.plugin.zsh b/plugins/xcode/xcode.plugin.zsh index 89703fe3c..41b9e37e4 100644 --- a/plugins/xcode/xcode.plugin.zsh +++ b/plugins/xcode/xcode.plugin.zsh @@ -6,28 +6,18 @@ alias xcsel='sudo xcode-select --switch' # original author: @subdigital # source: https://gist.github.com/subdigital/5420709 function xc { - local xcode_proj - if [[ $# == 0 ]]; then - xcode_proj=(*.{xcworkspace,xcodeproj}(N)) - else - xcode_proj=($1/*.{xcworkspace,xcodeproj}(N)) - fi - + local xcode_files + xcode_files=(${1:-.}/{*.{xcworkspace,xcodeproj},Package.swift}(N)) - if [[ ${#xcode_proj} -eq 0 ]]; then - if [[ $# == 0 ]]; then - echo "No xcworkspace/xcodeproj file found in the current directory." - else - echo "No xcworkspace/xcodeproj file found in $1." - fi + if [[ ${#xcode_files} -eq 0 ]]; then + echo "No Xcode files found in ${1:-the current directory}." >&2 return 1 - else - local active_path - active_path=$(xcode-select -p) - active_path=${active_path%%/Contents/Developer*} - echo "Found ${xcode_proj[1]}. Opening with ${active_path}" - open -a "$active_path" "${xcode_proj[1]}" fi + + local active_path + active_path=${"$(xcode-select -p)"%%/Contents/Developer*} + echo "Found ${xcode_files[1]}. Opening with ${active_path}" + open -a "$active_path" "${xcode_files[1]}" } # Opens a file or files in the Xcode IDE. Multiple files are opened in multi-file browser -- cgit v1.2.3-70-g09d2 From 49458b872d1bab1aa8338e319f27c9b3705c9fd7 Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Fri, 29 Oct 2021 18:21:13 +0200 Subject: docs(dirhistory): document OPT key alternative for macOS and fix style Fixes #10350 --- plugins/dirhistory/README.md | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) (limited to 'plugins') diff --git a/plugins/dirhistory/README.md b/plugins/dirhistory/README.md index 602fc8284..ede9b5410 100644 --- a/plugins/dirhistory/README.md +++ b/plugins/dirhistory/README.md @@ -12,19 +12,27 @@ plugins=(... dirhistory) | Shortcut | Description | |-----------------------------------|-----------------------------------------------------------| -| alt + left | Go to previous directory | -| alt + right | Undo alt + left | -| alt + up | Move into the parent directory | -| alt + down | Move into the first child directory by alphabetical order | +| Alt + Left | Go to previous directory | +| Alt + Right | Go to next directory | +| Alt + Up | Move into the parent directory | +| Alt + Down | Move into the first child directory by alphabetical order | -NOTE: some terminals might override the ALT+Arrows key bindings (Windows Terminal, for example). -If these don't work check your terminal settings and change them to a different keyboard shortcut. +**For macOS: use the Option key () instead of Alt**. + +> NOTE: some terminals might override the Alt + Arrows key bindings (e.g. Windows Terminal). +> If these don't work check your terminal settings and change them to a different keyboard shortcut. ## Usage -This plugin allows you to navigate the history of previous current-working-directories using ALT-LEFT and ALT-RIGHT. ALT-LEFT moves back to directories that the user has changed to in the past, and ALT-RIGHT undoes ALT-LEFT. MAC users may alternately use OPT-LEFT and OPT-RIGHT. +This plugin allows you to navigate the history of previous working directories using Alt + Left +and Alt + Right. Alt + Left moves to past directories, and +Alt + Right goes back to recent directories. + +**NOTE: the maximum directory history size is 30.** -Also, navigate directory **hierarchy** using ALT-UP and ALT-DOWN. (mac keybindings not yet implemented). ALT-UP moves to higher hierarchy (shortcut for 'cd ..'). ALT-DOWN moves into the first directory found in alphabetical order (useful to navigate long empty directories e.g. java packages) +You can also navigate **directory hierarchies** using Alt + Up and Alt + Down. +Alt + Up moves to the parent directory, while Alt + Down moves into the first +child directory found in alphabetical order (useful to navigate long empty directories, e.g. Java packages). For example, if the shell was started, and the following commands were entered: @@ -35,8 +43,20 @@ cd share cd doc ``` -Then entering ALT-LEFT at the prompt would change directory from /usr/share/doc to /usr/share, then if pressed again to /usr/, then ~. If ALT-RIGHT were pressed the directory would be changed to /usr/ again. +the directory stack (`dirs -v`) would look like this: + +```console +$ dirs -v +0 /usr/share/doc +1 /usr/share +2 /usr +3 ~ +``` -After that, ALT-DOWN will probably go to /usr/bin (depends on your /usr structure), ALT-UP will return to /usr, then ALT-UP will get you to / +then entering Alt + Left at the prompt would change directory from `/usr/share/doc` to `/usr/share`, +then if pressed again to `/usr`, then `~`. If Alt + Right were pressed the directory would be changed +to `/usr` again. -**Currently the max history size is 30**. The navigation should work for xterm, PuTTY xterm mode, GNU screen, and on MAC with alternate keys as mentioned above. +After that, Alt + Down will probably go to `/usr/bin` if `bin` is the first directory in alphabetical +order (depends on your `/usr` folder structure). Alt + Up will return to `/usr`, and once more will get +you to the root folder (`/`). -- cgit v1.2.3-70-g09d2 From 7f494944e6e8047b49fdbd42977b4eb4670381fe Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Fri, 29 Oct 2021 18:22:35 +0200 Subject: fix(dirhistory): fix ALT+Up/Down key bindings for Terminal.app --- plugins/dirhistory/dirhistory.plugin.zsh | 76 ++++++++++++++------------------ 1 file changed, 32 insertions(+), 44 deletions(-) (limited to 'plugins') diff --git a/plugins/dirhistory/dirhistory.plugin.zsh b/plugins/dirhistory/dirhistory.plugin.zsh index cbac84600..d949064d8 100644 --- a/plugins/dirhistory/dirhistory.plugin.zsh +++ b/plugins/dirhistory/dirhistory.plugin.zsh @@ -121,35 +121,24 @@ function dirhistory_zle_dirhistory_future() { } zle -N dirhistory_zle_dirhistory_back -# xterm in normal mode -bindkey "\e[3D" dirhistory_zle_dirhistory_back -bindkey "\e[1;3D" dirhistory_zle_dirhistory_back -# Terminal.app -if [[ "$TERM_PROGRAM" == "Apple_Terminal" ]]; then - bindkey "^[b" dirhistory_zle_dirhistory_back -fi -# iTerm2 -if [[ "$TERM_PROGRAM" == "iTerm.app" ]]; then - bindkey "^[^[[D" dirhistory_zle_dirhistory_back -fi -# Putty: -bindkey "\e\e[D" dirhistory_zle_dirhistory_back -# GNU screen: -bindkey "\eO3D" dirhistory_zle_dirhistory_back +bindkey "\e[3D" dirhistory_zle_dirhistory_back # xterm in normal mode +bindkey "\e[1;3D" dirhistory_zle_dirhistory_back # xterm in normal mode +bindkey "\e\e[D" dirhistory_zle_dirhistory_back # Putty +bindkey "\eO3D" dirhistory_zle_dirhistory_back # GNU screen +case "$TERM_PROGRAM" in +iTerm.app) bindkey "^[^[[D" dirhistory_zle_dirhistory_back ;; # iTerm2 +Apple_Terminal) bindkey "^[b" dirhistory_zle_dirhistory_back ;; # Terminal.app +esac zle -N dirhistory_zle_dirhistory_future -bindkey "\e[3C" dirhistory_zle_dirhistory_future -bindkey "\e[1;3C" dirhistory_zle_dirhistory_future -# Terminal.app -if [[ "$TERM_PROGRAM" == "Apple_Terminal" ]]; then - bindkey "^[f" dirhistory_zle_dirhistory_future -fi -# iTerm2 -if [[ "$TERM_PROGRAM" == "iTerm.app" ]]; then - bindkey "^[^[[C" dirhistory_zle_dirhistory_future -fi -bindkey "\e\e[C" dirhistory_zle_dirhistory_future -bindkey "\eO3C" dirhistory_zle_dirhistory_future +bindkey "\e[3C" dirhistory_zle_dirhistory_future # xterm in normal mode +bindkey "\e[1;3C" dirhistory_zle_dirhistory_future # xterm in normal mode +bindkey "\e\e[C" dirhistory_zle_dirhistory_future # Putty +bindkey "\eO3C" dirhistory_zle_dirhistory_future # GNU screen +case "$TERM_PROGRAM" in +iTerm.app) bindkey "^[^[[C" dirhistory_zle_dirhistory_future ;; # iTerm2 +Apple_Terminal) bindkey "^[f" dirhistory_zle_dirhistory_future ;; # Terminal.app +esac # @@ -181,22 +170,21 @@ function dirhistory_zle_dirhistory_down() { } zle -N dirhistory_zle_dirhistory_up -# xterm in normal mode -bindkey "\e[3A" dirhistory_zle_dirhistory_up -bindkey "\e[1;3A" dirhistory_zle_dirhistory_up -if [[ "$TERM_PROGRAM" == "Apple_Terminal" || "$TERM_PROGRAM" == "iTerm.app" ]]; then - bindkey "^[[A" dirhistory_zle_dirhistory_up -fi -# Putty: -bindkey "\e\e[A" dirhistory_zle_dirhistory_up -# GNU screen: -bindkey "\eO3A" dirhistory_zle_dirhistory_up +bindkey "\e[3A" dirhistory_zle_dirhistory_up # xterm in normal mode +bindkey "\e[1;3A" dirhistory_zle_dirhistory_up # xterm in normal mode +bindkey "\e\e[A" dirhistory_zle_dirhistory_up # Putty +bindkey "\eO3A" dirhistory_zle_dirhistory_up # GNU screen +case "$TERM_PROGRAM" in +iTerm.app) bindkey "^[^[[A" dirhistory_zle_dirhistory_up ;; # iTerm2 +Apple_Terminal) bindkey "^[OA" dirhistory_zle_dirhistory_up ;; # Terminal.app +esac zle -N dirhistory_zle_dirhistory_down -bindkey "\e[3B" dirhistory_zle_dirhistory_down -bindkey "\e[1;3B" dirhistory_zle_dirhistory_down -if [[ "$TERM_PROGRAM" == "Apple_Terminal" || "$TERM_PROGRAM" == "iTerm.app" ]]; then - bindkey "^[[B" dirhistory_zle_dirhistory_down -fi -bindkey "\e\e[B" dirhistory_zle_dirhistory_down -bindkey "\eO3B" dirhistory_zle_dirhistory_down +bindkey "\e[3B" dirhistory_zle_dirhistory_down # xterm in normal mode +bindkey "\e[1;3B" dirhistory_zle_dirhistory_down # xterm in normal mode +bindkey "\e\e[B" dirhistory_zle_dirhistory_down # Putty +bindkey "\eO3B" dirhistory_zle_dirhistory_down # GNU screen +case "$TERM_PROGRAM" in +iTerm.app) bindkey "^[^[[B" dirhistory_zle_dirhistory_down ;; # iTerm2 +Apple_Terminal) bindkey "^[OB" dirhistory_zle_dirhistory_down ;; # Terminal.app +esac -- cgit v1.2.3-70-g09d2 From 79cf4b3ceb9bf981ce05adc1db3f01aa551efce8 Mon Sep 17 00:00:00 2001 From: Michael Peick Date: Sun, 10 Nov 2019 15:32:41 +0100 Subject: feat(dirhistory): support urxvt terminal key binding (#8370) Closes #8370 --- plugins/dirhistory/dirhistory.plugin.zsh | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'plugins') diff --git a/plugins/dirhistory/dirhistory.plugin.zsh b/plugins/dirhistory/dirhistory.plugin.zsh index d949064d8..26ef07494 100644 --- a/plugins/dirhistory/dirhistory.plugin.zsh +++ b/plugins/dirhistory/dirhistory.plugin.zsh @@ -1,7 +1,7 @@ -## -# Navigate directory history using ALT-LEFT and ALT-RIGHT. ALT-LEFT moves back to directories +## +# Navigate directory history using ALT-LEFT and ALT-RIGHT. ALT-LEFT moves back to directories # that the user has changed to in the past, and ALT-RIGHT undoes ALT-LEFT. -# +# # Navigate directory hierarchy using ALT-UP and ALT-DOWN. # ALT-UP moves to higher hierarchy (cd ..) # ALT-DOWN moves into the first directory found in alphabetical order @@ -14,8 +14,8 @@ export dirhistory_future export DIRHISTORY_SIZE=30 -# Pop the last element of dirhistory_past. -# Pass the name of the variable to return the result in. +# Pop the last element of dirhistory_past. +# Pass the name of the variable to return the result in. # Returns the element if the array was not empty, # otherwise returns empty string. function pop_past() { @@ -32,7 +32,7 @@ function pop_future() { fi } -# Push a new element onto the end of dirhistory_past. If the size of the array +# Push a new element onto the end of dirhistory_past. If the size of the array # is >= DIRHISTORY_SIZE, the array is shifted function push_past() { if [[ $#dirhistory_past -ge $DIRHISTORY_SIZE ]]; then @@ -76,7 +76,7 @@ function dirhistory_back() { local d="" # Last element in dirhistory_past is the cwd. - pop_past cw + pop_past cw if [[ "" == "$cw" ]]; then # Someone overwrote our variable. Recover it. dirhistory_past=($PWD) @@ -129,6 +129,9 @@ case "$TERM_PROGRAM" in iTerm.app) bindkey "^[^[[D" dirhistory_zle_dirhistory_back ;; # iTerm2 Apple_Terminal) bindkey "^[b" dirhistory_zle_dirhistory_back ;; # Terminal.app esac +if (( ${+terminfo[kcub1]} )); then + bindkey "^[${terminfo[kcub1]}" dirhistory_zle_dirhistory_back # urxvt +fi zle -N dirhistory_zle_dirhistory_future bindkey "\e[3C" dirhistory_zle_dirhistory_future # xterm in normal mode @@ -139,11 +142,14 @@ case "$TERM_PROGRAM" in iTerm.app) bindkey "^[^[[C" dirhistory_zle_dirhistory_future ;; # iTerm2 Apple_Terminal) bindkey "^[f" dirhistory_zle_dirhistory_future ;; # Terminal.app esac +if (( ${+terminfo[kcuf1]} )); then + bindkey "^[${terminfo[kcuf1]}" dirhistory_zle_dirhistory_future # urxvt +fi -# +# # HIERARCHY Implemented in this section, in case someone wants to split it to another plugin if it clashes bindings -# +# # Move up in hierarchy function dirhistory_up() { @@ -178,6 +184,9 @@ case "$TERM_PROGRAM" in iTerm.app) bindkey "^[^[[A" dirhistory_zle_dirhistory_up ;; # iTerm2 Apple_Terminal) bindkey "^[OA" dirhistory_zle_dirhistory_up ;; # Terminal.app esac +if (( ${+terminfo[kcuu1]} )); then + bindkey "^[${terminfo[kcuu1]}" dirhistory_zle_dirhistory_up # urxvt +fi zle -N dirhistory_zle_dirhistory_down bindkey "\e[3B" dirhistory_zle_dirhistory_down # xterm in normal mode @@ -188,3 +197,6 @@ case "$TERM_PROGRAM" in iTerm.app) bindkey "^[^[[B" dirhistory_zle_dirhistory_down ;; # iTerm2 Apple_Terminal) bindkey "^[OB" dirhistory_zle_dirhistory_down ;; # Terminal.app esac +if (( ${+terminfo[kcud1]} )); then + bindkey "^[${terminfo[kcud1]}" dirhistory_zle_dirhistory_down # urxvt +fi -- cgit v1.2.3-70-g09d2 From 9a02515c7c8eee90909fe72d59d2e3169cb5ed28 Mon Sep 17 00:00:00 2001 From: amnore Date: Wed, 3 Nov 2021 20:17:23 +0800 Subject: fix(command-not-found): pass arguments correctly in NixOS (#10381) --- plugins/command-not-found/command-not-found.plugin.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/command-not-found/command-not-found.plugin.zsh b/plugins/command-not-found/command-not-found.plugin.zsh index 3ec13429c..cb96fe063 100644 --- a/plugins/command-not-found/command-not-found.plugin.zsh +++ b/plugins/command-not-found/command-not-found.plugin.zsh @@ -50,7 +50,7 @@ fi # NixOS: https://github.com/NixOS/nixpkgs/tree/master/nixos/modules/programs/command-not-found if [[ -x /run/current-system/sw/bin/command-not-found ]]; then command_not_found_handler() { - /run/current-system/sw/bin/command-not-found -- "$@" + /run/current-system/sw/bin/command-not-found "$@" } fi -- cgit v1.2.3-70-g09d2 From b2f35a7b98455b2bb8c7c3b11db6aa587e1d28bf Mon Sep 17 00:00:00 2001 From: Jonathan Batchelor Date: Fri, 5 Nov 2021 23:40:38 +0000 Subject: refactor(osx): Rename osx plugin to macos (#10341) Apple changed the name of their operating system from OS X to macOS a number of years ago. This was overdue! As per issue #10311 * refactor(osx): rename `osx` plugin to `macos` * refactor(macos): Add symbolic link from old `osx` plugin name. --- README.md | 2 +- plugins/macos/README.md | 63 ++++++ plugins/macos/_security | 90 ++++++++ plugins/macos/macos.plugin.zsh | 269 +++++++++++++++++++++++ plugins/macos/music | 170 +++++++++++++++ plugins/macos/osx.plugin.zsh | 1 + plugins/macos/spotify | 478 +++++++++++++++++++++++++++++++++++++++++ plugins/osx | 1 + plugins/osx/README.md | 63 ------ plugins/osx/_security | 90 -------- plugins/osx/music | 170 --------------- plugins/osx/osx.plugin.zsh | 263 ----------------------- plugins/osx/spotify | 478 ----------------------------------------- 13 files changed, 1073 insertions(+), 1065 deletions(-) create mode 100644 plugins/macos/README.md create mode 100644 plugins/macos/_security create mode 100644 plugins/macos/macos.plugin.zsh create mode 100644 plugins/macos/music create mode 120000 plugins/macos/osx.plugin.zsh create mode 100644 plugins/macos/spotify create mode 120000 plugins/osx delete mode 100644 plugins/osx/README.md delete mode 100644 plugins/osx/_security delete mode 100644 plugins/osx/music delete mode 100644 plugins/osx/osx.plugin.zsh delete mode 100644 plugins/osx/spotify (limited to 'plugins') diff --git a/README.md b/README.md index 907248beb..5712c1701 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ plugins=( git bundler dotenv - osx + macos rake rbenv ruby diff --git a/plugins/macos/README.md b/plugins/macos/README.md new file mode 100644 index 000000000..1bc4244a4 --- /dev/null +++ b/plugins/macos/README.md @@ -0,0 +1,63 @@ +# MacOS plugin + +This plugin provides a few utilities to make it more enjoyable on macOS (previously named OSX). + +To start using it, add the `macos` plugin to your plugins array in `~/.zshrc`: + +```zsh +plugins=(... macos) +``` + +Original author: [Sorin Ionescu](https://github.com/sorin-ionescu) + +## Commands + +| Command | Description | +| :------------ | :------------------------------------------------------- | +| `tab` | Open the current directory in a new tab | +| `split_tab` | Split the current terminal tab horizontally | +| `vsplit_tab` | Split the current terminal tab vertically | +| `ofd` | Open the current directory in a Finder window | +| `pfd` | Return the path of the frontmost Finder window | +| `pfs` | Return the current Finder selection | +| `cdf` | `cd` to the current Finder directory | +| `pushdf` | `pushd` to the current Finder directory | +| `pxd` | Return the current Xcode project directory | +| `cdx` | `cd` to the current Xcode project directory | +| `quick-look` | Quick-Look a specified file | +| `man-preview` | Open a specified man page in Preview app | +| `showfiles` | Show hidden files in Finder | +| `hidefiles` | Hide the hidden files in Finder | +| `itunes` | _DEPRECATED_. Use `music` from macOS Catalina on | +| `music` | Control Apple Music. Use `music -h` for usage details | +| `spotify` | Control Spotify and search by artist, album, track… | +| `rmdsstore` | Remove .DS_Store files recursively in a directory | +| `btrestart` | Restart the Bluetooth daemon | +| `freespace` | Erases purgeable disk space with 0s on the selected disk | + +## Acknowledgements + +This application makes use of the following third party scripts: + +[shpotify](https://github.com/hnarayanan/shpotify) + +Copyright (c) 2012–2019 [Harish Narayanan](https://harishnarayanan.org/). + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/macos/_security b/plugins/macos/_security new file mode 100644 index 000000000..e4ed585ac --- /dev/null +++ b/plugins/macos/_security @@ -0,0 +1,90 @@ +#compdef security + +local -a _1st_arguments +_1st_arguments=( + 'help:Show all commands, or show usage for a command' + 'list-keychains:Display or manipulate the keychain search list' + 'default-keychain:Display or set the default keychain' + 'login-keychain:Display or set the login keychain' + 'create-keychain:Create keychains and add them to the search list' + 'delete-keychain:Delete keychains and remove them from the search list' + 'lock-keychain:Lock the specified keychain' + 'lock-keychain:Unlock the specified keychain' + 'set-keychain-settings:Set settings for a keychain' + 'set-keychain-password:Set password for a keychain' + 'show-keychain-info:Show the settings for keychain' + 'dump-keychain:Dump the contents of one or more keychains' + 'create-keypair:Create an asymmetric key pair' + 'add-generic-password:Add a generic password item' + 'add-internet-password:Add an internet password item' + 'add-certificates:Add certificates to a keychain' + 'find-generic-password:Find a generic password item' + 'delete-generic-password:Delete a generic password item' + 'find-internet-password:Find an internet password item' + 'delete-internet-password:Delete an internet password item' + 'find-certificate:Find a certificate item' + 'find-identity:Find an identity certificate + private key' + 'delete-certificate:Delete a certificate from a keychain' + 'set-identity-preference:Set the preferred identity to use for a service' + 'get-identity-preference:Get the preferred identity to use for a service' + 'create-db:Create a db using the DL' + 'export:Export items from a keychain' + 'import:Import items into a keychain' + 'cms:Encode or decode CMS messages' + 'install-mds:MDS database' + 'add-trusted-cert:Add trusted certificates:' + 'remove-trusted-cert:Remove trusted certificates:' + 'dump-trust-settings:Display contents of trust settings' + 'user-trust-settings-enable:Display or manipulate user-level trust settings' + 'trust-settings-export:Export trust settings' + 'trust-settings-import:Import trust settings' + 'verify-cert:Verify certificates:' + 'authorize:Perform authorization operations' + 'authorizationdb:Make changes to the authorization policy database' + 'execute-with-privileges:Execute tool with privileges' + 'leaks:Run /usr/bin/leaks on this process' + 'error:Display a descriptive message for the given error codes:' + 'create-filevaultmaster-keychain:"Create a keychain containing a key pair for FileVault recovery use' +) +_arguments '*:: :->command' + +if (( CURRENT == 1 )); then + _describe -t commands "security command" _1st_arguments + return +fi + +case "$words[1]" in + find-(generic|internet)-password) + _values \ + 'Usage: find-[internet/generic]-password [-a account] [-s server] [options...] [-g] [keychain...]' \ + '-a[Match "account" string]' \ + '-c[Match "creator" (four-character code)]' \ + '-C[Match "type" (four-character code)]' \ + '-D[Match "kind" string]' \ + '-G[Match "value" string (generic attribute)]' \ + '-j[Match "comment" string]' \ + '-l[Match "label" string]' \ + '-s[Match "service" string]' \ + '-g[Display the password for the item found]' \ + '-w[Display only the password on stdout]' ;; + add-(generic|internet)-password) + _values \ + 'Usage: add-[internet/generic]-password [-a account] [-s server] [-w password] [options...] [-A|-T appPath] [keychain]]' \ + '-a[Specify account name (required)]' \ + '-c[Specify item creator (optional four-character code)]' \ + '-C[Specify item type (optional four-character code)]' \ + '-d[Specify security domain string (optional)]' \ + '-D[Specify kind (default is "Internet password")]' \ + '-j[Specify comment string (optional)]' \ + '-l[Specify label (if omitted, server name is used as default label)]' \ + '-p[Specify path string (optional)]' \ + '-P[Specify port number (optional)]' \ + '-r[Specify protocol (optional four-character SecProtocolType, e.g. "http", "ftp ")]' \ + '-s[Specify server name (required)]' \ + '-t[Specify authentication type (as a four-character SecAuthenticationType, default is "dflt")]' \ + '-w[Specify password to be added]' \ + '-A[Allow any application to access this item without warning (insecure, not recommended!)]' \ + '-T[Specify an application which may access this item (multiple -T options are allowed)]' \ + '-U[Update item if it already exists (if omitted, the item cannot already exist) ]' \ + 'utils)]' ;; +esac diff --git a/plugins/macos/macos.plugin.zsh b/plugins/macos/macos.plugin.zsh new file mode 100644 index 000000000..4bcbbaead --- /dev/null +++ b/plugins/macos/macos.plugin.zsh @@ -0,0 +1,269 @@ +# Check if 'osx' is still in the plugins list and prompt to change to 'macos' +if [[ -n "${plugins[(r)osx]}" ]]; then + print ${(%):-"%F{yellow}The \`osx\` plugin is deprecated and has been renamed to \`macos\`."} + print ${(%):-"Please update your .zshrc to use the \`%Bmacos%b\` plugin instead.%f"} +fi + +# Open the current directory in a Finder window +alias ofd='open_command $PWD' + +# Show/hide hidden files in the Finder +alias showfiles="defaults write com.apple.finder AppleShowAllFiles -bool true && killall Finder" +alias hidefiles="defaults write com.apple.finder AppleShowAllFiles -bool false && killall Finder" + +# Bluetooth restart +function btrestart() { + sudo kextunload -b com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport + sudo kextload -b com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport +} + +function _omz_macos_get_frontmost_app() { + osascript 2>/dev/null < 0 )) && command="${command}; $*" + + local the_app=$(_omz_macos_get_frontmost_app) + + if [[ "$the_app" == 'Terminal' ]]; then + # Discarding stdout to quash "tab N of window id XXX" output + osascript >/dev/null </dev/null <&2 + return 1 + fi +} + +function vsplit_tab() { + local command="cd \\\"$PWD\\\"; clear" + (( $# > 0 )) && command="${command}; $*" + + local the_app=$(_omz_macos_get_frontmost_app) + + if [[ "$the_app" == 'iTerm' ]]; then + osascript </dev/null <&2 + return 1 + fi +} + +function split_tab() { + local command="cd \\\"$PWD\\\"; clear" + (( $# > 0 )) && command="${command}; $*" + + local the_app=$(_omz_macos_get_frontmost_app) + + if [[ "$the_app" == 'iTerm' ]]; then + osascript 2>/dev/null </dev/null <&2 + return 1 + fi +} + +function pfd() { + osascript 2>/dev/null </dev/null </dev/null < 0 )) && qlmanage -p $* &>/dev/null & +} + +function man-preview() { + # Don't let Preview.app steal focus if the man page doesn't exist + man -w "$@" &>/dev/null && man -t "$@" | open -f -a Preview || man "$@" +} +compdef _man man-preview + +function vncviewer() { + open vnc://$@ +} + +# Remove .DS_Store files recursively in a directory, default . +function rmdsstore() { + find "${@:-.}" -type f -name .DS_Store -delete +} + +# Erases purgeable disk space with 0s on the selected disk +function freespace(){ + if [[ -z "$1" ]]; then + echo "Usage: $0 " + echo "Example: $0 /dev/disk1s1" + echo + echo "Possible disks:" + df -h | awk 'NR == 1 || /^\/dev\/disk/' + return 1 + fi + + echo "Cleaning purgeable files from disk: $1 ...." + diskutil secureErase freespace 0 $1 +} + +_freespace() { + local -a disks + disks=("${(@f)"$(df | awk '/^\/dev\/disk/{ printf $1 ":"; for (i=9; i<=NF; i++) printf $i FS; print "" }')"}") + _describe disks disks +} + +compdef _freespace freespace + +# Music / iTunes control function +source "${0:h:A}/music" + +# Spotify control function +source "${0:h:A}/spotify" diff --git a/plugins/macos/music b/plugins/macos/music new file mode 100644 index 000000000..50566797b --- /dev/null +++ b/plugins/macos/music @@ -0,0 +1,170 @@ +#!/usr/bin/env zsh + +function music itunes() { + local APP_NAME=Music sw_vers=$(sw_vers -productVersion 2>/dev/null) + + autoload is-at-least + if [[ -z "$sw_vers" ]] || is-at-least 10.15 $sw_vers; then + if [[ $0 = itunes ]]; then + echo >&2 The itunes function name is deprecated. Use \'music\' instead. + return 1 + fi + else + APP_NAME=iTunes + fi + + local opt=$1 playlist=$2 + (( $# > 0 )) && shift + case "$opt" in + launch|play|pause|stop|rewind|resume|quit) + ;; + mute) + opt="set mute to true" + ;; + unmute) + opt="set mute to false" + ;; + next|previous) + opt="$opt track" + ;; + vol) + local new_volume volume=$(osascript -e "tell application \"$APP_NAME\" to get sound volume") + if [[ $# -eq 0 ]]; then + echo "Current volume is ${volume}." + return 0 + fi + case $1 in + up) new_volume=$((volume + 10 < 100 ? volume + 10 : 100)) ;; + down) new_volume=$((volume - 10 > 0 ? volume - 10 : 0)) ;; + <0-100>) new_volume=$1 ;; + *) echo "'$1' is not valid. Expected <0-100>, up or down." + return 1 ;; + esac + opt="set sound volume to ${new_volume}" + ;; + playlist) + # Inspired by: https://gist.github.com/nakajijapan/ac8b45371064ae98ea7f + if [[ -n "$playlist" ]]; then + osascript 2>/dev/null </dev/null 2>&1 </dev/null 2>&1 <" + echo "option:" + echo "\t-h|--help\tShow this message and exit" + echo "\tlaunch|play|pause|stop|rewind|resume|quit" + echo "\tmute|unmute\tMute or unmute $APP_NAME" + echo "\tnext|previous\tPlay next or previous track" + echo "\tshuf|shuffle [on|off|toggle]\tSet shuffled playback. Default: toggle. Note: toggle doesn't support the MiniPlayer." + echo "\tvol [0-100|up|down]\tGet or set the volume. 0 to 100 sets the volume. 'up' / 'down' increases / decreases by 10 points. No argument displays current volume." + echo "\tplaying|status\tShow what song is currently playing in Music." + echo "\tplaylist [playlist name]\t Play specific playlist" + return 0 + ;; + *) + print "Unknown option: $opt" + return 1 + ;; + esac + osascript -e "tell application \"$APP_NAME\" to $opt" +} + +function _music() { + local app_name + case "$words[1]" in + itunes) app_name="iTunes" ;; + music|*) app_name="Music" ;; + esac + + local -a cmds subcmds + cmds=( + "launch:Launch the ${app_name} app" + "play:Play ${app_name}" + "pause:Pause ${app_name}" + "stop:Stop ${app_name}" + "rewind:Rewind ${app_name}" + "resume:Resume ${app_name}" + "quit:Quit ${app_name}" + "mute:Mute the ${app_name} app" + "unmute:Unmute the ${app_name} app" + "next:Skip to the next song" + "previous:Skip to the previous song" + "vol:Change the volume" + "playlist:Play a specific playlist" + {playing,status}":Show what song is currently playing" + {shuf,shuff,shuffle}":Set shuffle mode" + {-h,--help}":Show usage" + ) + + if (( CURRENT == 2 )); then + _describe 'command' cmds + elif (( CURRENT == 3 )); then + case "$words[2]" in + vol) subcmds=( 'up:Raise the volume' 'down:Lower the volume' ) + _describe 'command' subcmds ;; + shuf|shuff|shuffle) subcmds=('on:Switch on shuffle mode' 'off:Switch off shuffle mode' 'toggle:Toggle shuffle mode (default)') + _describe 'command' subcmds ;; + esac + elif (( CURRENT == 4 )); then + case "$words[2]" in + playlist) subcmds=('play:Play the playlist (default)' 'stop:Stop the playlist') + _describe 'command' subcmds ;; + esac + fi + + return 0 +} + +compdef _music music itunes diff --git a/plugins/macos/osx.plugin.zsh b/plugins/macos/osx.plugin.zsh new file mode 120000 index 000000000..73d718d43 --- /dev/null +++ b/plugins/macos/osx.plugin.zsh @@ -0,0 +1 @@ +macos.plugin.zsh \ No newline at end of file diff --git a/plugins/macos/spotify b/plugins/macos/spotify new file mode 100644 index 000000000..663215a74 --- /dev/null +++ b/plugins/macos/spotify @@ -0,0 +1,478 @@ +#!/usr/bin/env bash + +function spotify() { +# Copyright (c) 2012--2019 Harish Narayanan +# +# Contains numerous helpful contributions from Jorge Colindres, Thomas +# Pritchard, iLan Epstein, Gabriele Bonetti, Sean Heller, Eric Martin +# and Peter Fonseca. + +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: + +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +USER_CONFIG_DEFAULTS="CLIENT_ID=\"\"\nCLIENT_SECRET=\"\""; +USER_CONFIG_FILE="${HOME}/.shpotify.cfg"; +if ! [[ -f "${USER_CONFIG_FILE}" ]]; then + touch "${USER_CONFIG_FILE}"; + echo -e "${USER_CONFIG_DEFAULTS}" > "${USER_CONFIG_FILE}"; +fi +source "${USER_CONFIG_FILE}"; + +showAPIHelp() { + echo; + echo "Connecting to Spotify's API:"; + echo; + echo " This command line application needs to connect to Spotify's API in order to"; + echo " find music by name. It is very likely you want this feature!"; + echo; + echo " To get this to work, you need to sign up (or in) and create an 'Application' at:"; + echo " https://developer.spotify.com/my-applications/#!/applications/create"; + echo; + echo " Once you've created an application, find the 'Client ID' and 'Client Secret'"; + echo " values, and enter them into your shpotify config file at '${USER_CONFIG_FILE}'"; + echo; + echo " Be sure to quote your values and don't add any extra spaces!"; + echo " When done, it should look like this (but with your own values):"; + echo ' CLIENT_ID="abc01de2fghijk345lmnop"'; + echo ' CLIENT_SECRET="qr6stu789vwxyz"'; +} + +showHelp () { + echo "Usage:"; + echo; + echo " `basename $0` "; + echo; + echo "Commands:"; + echo; + echo " play # Resumes playback where Spotify last left off."; + echo " play # Finds a song by name and plays it."; + echo " play album # Finds an album by name and plays it."; + echo " play artist # Finds an artist by name and plays it."; + echo " play list # Finds a playlist by name and plays it."; + echo " play uri # Play songs from specific uri."; + echo; + echo " next # Skips to the next song in a playlist."; + echo " prev # Returns to the previous song in a playlist."; + echo " replay # Replays the current track from the beginning."; + echo " pos