Guest User

_tmux

a guest
May 31st, 2016
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 56.15 KB | None | 0 0
  1. #compdef tmux
  2.  
  3. # tmux <http://tmux.github.io> completion for zsh <http://zsh.sf.net>.
  4. #
  5. # Configuration:
  6. #
  7. # - On some OSs, the directory for tmux's server sockets may not be
  8. #   the default (which is /tmp/tmux-<uid>/), but say
  9. #   /var/run/tmux/tmux-<uid>, in which case the completion for
  10. #   'tmux -L <tab>' will not be able to find the sockets in the default
  11. #   location (debian does this, for instance); tell _tmux the right place
  12. #   to look:
  13. #       % zstyle ':completion:*:*:tmux:*:sockets' socketdir "/var/run/tmux/tmux-${UID}"
  14. #
  15. # - tmux knows a *lot* of sub-commands, hence 'tmux <tab>' returns a lot
  16. #   of possible completions. _tmux knows about all commands and their aliases.
  17. #   By default, both are offered. If you do not care about the aliases, do this:
  18. #       % zstyle ':completion:*:*:tmux:*:subcommands' mode 'commands'
  19. #
  20. #   The same can be done to only return aliases by setting the above style
  21. #   to 'aliases'. The default value is 'both' (but actually every value
  22. #   different from 'commands' and 'aliases' will have the same effect).
  23. #
  24. #   'lsw' is an alias for 'list-windows' for example; note that not all
  25. #   commands have aliases. So probably, either the default 'both' or
  26. #   'commands' makes most sense for this style.
  27. #
  28. # - For finer grained control over what is suggested as possible completions,
  29. #   the 'ignored-patterns' style may be used; suppose you think that only
  30. #   '*-window' or '*-windows' are worth being completed. You would get that
  31. #   behaviour like this:
  32. #       % zstyle ':completion:*:*:tmux:*:subcommands' ignored-patterns '^*-window(|s)'
  33. #
  34. #   Some tmux commands currently do not work if called from a shell prompt,
  35. #   so it would make sense to ignore them per default (at the time of writing,
  36. #   those commands are choose-{session,client,window}, confirm-before and
  37. #   find-window. This would ignore them:
  38. #       % zstyle ':completion:*:*:tmux:*:subcommands' ignored-patterns \
  39. #                'choose-*' 'confirm-before' 'find-window'
  40. #
  41. # The configuration for subcommand completions may be done in
  42. # this context: ':completion:*:*:tmux-<sub-command>:*:*'
  43. #
  44. # TODO:
  45. #
  46. #   - Implement __tmux-format
  47. #   - Implement __tmux-style (possibly using existing helpers like
  48. #     __tmux-attributes and __tmux-colours)
  49. #   - in _tmux-list-panes, use __tmux-windows or __tmux-sessions
  50. #     depending on -s is among the sub-commands current command line.
  51.  
  52. # Global variables; setup the first time _tmux is called.
  53. # For $_tmux_commands[] generation, see the very end of this file.
  54. typeset -ga _tmux_commands _tmux_aliases
  55. typeset -gA _tmux_aliasmap
  56.  
  57. _tmux_aliasmap=(
  58.     # clients and sessions
  59.     attach      attach-session
  60.     detach      detach-client
  61.     has         has-session
  62.     lockc       lock-client
  63.     locks       lock-session
  64.     lsc         list-clients
  65.     lscm        list-commands
  66.     ls          list-sessions
  67.     new         new-session
  68.     refresh     refresh-client
  69.     rename      rename-session
  70.     showmsgs    show-messages
  71.     source      source-file
  72.     start       start-server
  73.     suspendc    suspend-client
  74.     switchc     switch-client
  75.  
  76.     # windows and panes
  77.     breakp      break-pane
  78.     capturep    capture-pane
  79.     displayp    display-panes
  80.     findw       find-window
  81.     joinp       join-pane
  82.     killp       kill-pane
  83.     killw       kill-window
  84.     last        last-window
  85.     lastp       last-pane
  86.     linkw       link-window
  87.     lsp         list-panes
  88.     lsw         list-windows
  89.     movep       move-pane
  90.     movew       move-window
  91.     neww        new-window
  92.     nextl       next-layout
  93.     next        next-window
  94.     pipep       pipe-pane
  95.     prev        previous-window
  96.     prevl       previous-layout
  97.     renamew     rename-window
  98.     resizep     resize-pane
  99.     respawnp    respawn-pane
  100.     respawnw    respawn-window
  101.     rotatew     rotate-window
  102.     selectl     select-layout
  103.     selectp     select-pane
  104.     selectw     select-window
  105.     splitw      split-window
  106.     swapp       swap-pane
  107.     swapw       swap-window
  108.     unlinkw     unlink-window
  109.  
  110.     # key bindings
  111.     bind        bind-key
  112.     lsk         list-keys
  113.     send        send-keys
  114.     unbind      unbind-key
  115.  
  116.     # options
  117.     set         set-option
  118.     setw        set-window-option
  119.     show        show-options
  120.     showw       show-window-options
  121.  
  122.     # environment
  123.     setenv      set-environment
  124.     showenv     show-environment
  125.  
  126.     # status line
  127.     confirm     confirm-before
  128.     display     display-message
  129.  
  130.     # buffers
  131.     clearhist   clear-history
  132.     deleteb     delete-buffer
  133.     lsb         list-buffers
  134.     loadb       load-buffer
  135.     pasteb      paste-buffer
  136.     saveb       save-buffer
  137.     setb        set-buffer
  138.     showb       show-buffer
  139.  
  140.     # miscellaneous
  141.     if          if-shell
  142.     lock        lock-server
  143.     run         run-shell
  144.     info        server-info
  145.     wait        wait-for
  146. )
  147.  
  148. # --- Sub-command functions ---
  149. # These *must* be called _tmux-*(); The description generation relies on
  150. # them being names that way. *No* other functions may match that pattern.
  151. # Other utility functions should be named __tmux-*() (see below).
  152. #
  153. # Another thing, the description generation needs, is handling of
  154. # $tmux_describe: If that parameter is non-empty, the sub-command function
  155. # should only print a description of the sub-command it handles and return
  156. # immidiately after doing so.
  157. #
  158. # To add support for a new sub-command, you only have to add a new
  159. # _tmux-<foo>() function below (preferably alphabetically sorted), that
  160. # behaves like described above; and add a alias->command pair in the
  161. # _tmux_aliasmap associative array above (if the comand in fact has an
  162. # alias). The rest should just work[tm].
  163.  
  164. function _tmux-attach-session() {
  165.     [[ -n ${tmux_describe} ]] && print "Attach or switch to a session" && return
  166.     local -a args
  167.  
  168.     args=(
  169.         '-c[specify working directory for the session]:directory:_path_files -g "*(-/)"'
  170.         '-d[detach other clients attached to target session]'
  171.         '-r[put the client into read-only mode]'
  172.         '-t[choose a target session]:target session:__tmux-sessions'
  173.     )
  174.     _arguments ${args}
  175. }
  176.  
  177. function _tmux-bind-key() {
  178.     [[ -n ${tmux_describe} ]] && print "Bind a key to a command" && return
  179.     local curcontext="${curcontext}" state
  180.     local -a args
  181.  
  182.     args=(
  183.         '-c[bind to command mode instead of normal mode]'
  184.         '-n[make the binding work without the need for the prefix key]'
  185.         '-r[the key may repeat]'
  186.         '-t[choose a key table for the binding]:key tables:__tmux-key-tables'
  187.         '1: :->key'
  188.         '*:: :->command_and_args'
  189.     )
  190.     _arguments -C ${args} && return
  191.  
  192.     if [[ ${state} == 'key' ]]; then
  193.         _message "key"
  194.     else
  195.         # quite cool, that this works. :-)
  196.         _tmux
  197.     fi
  198. }
  199.  
  200. function _tmux-break-pane() {
  201.     [[ -n ${tmux_describe} ]] && print "Break a pane from an existing into a new window" && return
  202.     local -a args
  203.     args=(
  204.         '-d[do not make the new window become the active one]'
  205.         '-F[specify format of output]:format:__tmux-format__tmux-format'
  206.         '-P[print information of new window after it has been created]'
  207.         '-t[choose a target pane]:panes:__tmux-panes'
  208.     )
  209.     _arguments ${args}
  210. }
  211.  
  212. function _tmux-capture-pane() {
  213.     [[ -n ${tmux_describe} ]] && print "Capture the contents of a pane to a buffer" && return
  214.     local -a args
  215.     args=(
  216.         '-a[use alternate screen]'
  217.         '-b[choose target buffer]:target buffer:__tmux-buffers'
  218.         '-C[escape non-printable characters as octal \\ooo]'
  219.         '-e[include escape sequences for attributes etc]'
  220.         '-E[specify last line to capture. - means last line of pane]'
  221.         '-J[join wrapped lines and preserver trailing space]'
  222.         '-q[ignore errors when trying to access alternate screen]'
  223.         '-p[print data to stdout]'
  224.         '-P[only capture that is the beginning of an as-yet incomplete esc seq]'
  225.         '-S[specify start line to capture. - means first line of scrollback]'
  226.         '-t[choose source pane]:source pane:__tmux-panes'
  227.     )
  228.     _arguments ${args}
  229. }
  230.  
  231. function _tmux-choose-buffer() {
  232.     [[ -n ${tmux_describe} ]] && print "Put a window into buffer choice mode" && return
  233.     local -a args
  234.     args=(
  235.         '-F[specify format of output]:format:__tmux-format'
  236.         '-t[choose a target window]:sessions:__tmux-windows'
  237.         '*:: :->tmpl'
  238.     )
  239.     _arguments ${args} && return
  240. }
  241.  
  242. function _tmux-choose-client() {
  243.     [[ -n ${tmux_describe} ]] && print "Put a window into client choice mode" && return
  244.     local -a args
  245.     args=(
  246.         '-F[specify format of output]:format:__tmux-format'
  247.         '-t[choose a target window]:sessions:__tmux-windows'
  248.         '*:: :->tmpl'
  249.     )
  250.     _arguments ${args} && return
  251. }
  252.  
  253. function _tmux-choose-session() {
  254.     [[ -n ${tmux_describe} ]] && print "Put a window into session choice mode" && return
  255.     local -a args
  256.     args=(
  257.         '-F[specify format of output]:format:__tmux-format'
  258.         '-t[choose a target window]:sessions:__tmux-windows'
  259.         '*:: :->tmpl'
  260.     )
  261.     _arguments ${args} && return
  262. }
  263.  
  264. function _tmux-choose-tree() {
  265.     [[ -n ${tmux_describe} ]] && print "Put a window into tree choice mode" && return
  266.     local -a args
  267.     args=(
  268.         '-b[override default session command]:session-command:'
  269.         '-c[override default window command]:window-command:'
  270.         '-S[specify session format]:session-format:__tmux-formats'
  271.         '-s[choose among sessions]'
  272.         '-t[choose a target window]:sessions:__tmux-windows'
  273.         '-u[show generated tree uncollapsed at startup]'
  274.         '-W[specify window format]:window-format:__tmux-formats'
  275.         '-w[choose among windows]'
  276.         '*:: :->tmpl'
  277.     )
  278.     _arguments ${args} && return
  279. }
  280.  
  281. function _tmux-choose-window() {
  282.     [[ -n ${tmux_describe} ]] && print "Put a window into window choice mode" && return
  283.     local -a args
  284.     args=(
  285.         '-F[specify format of output]:format:__tmux-format'
  286.         '-t[choose a target window]:sessions:__tmux-windows'
  287.         '*:: :->tmpl'
  288.     )
  289.     _arguments ${args} && return
  290. }
  291.  
  292. function _tmux-clear-history() {
  293.     [[ -n ${tmux_describe} ]] && print "Remove and clear history for a pane" && return
  294.     local -a args
  295.     args=('-t[choose a target pane]:panes:__tmux-panes')
  296.     _arguments ${args}
  297. }
  298.  
  299. function _tmux-clock-mode() {
  300.     [[ -n ${tmux_describe} ]] && print "Enter clock mode" && return
  301.     local -a args
  302.     args=('-t[choose a target pane]:panes:__tmux-panes')
  303.     _arguments ${args}
  304. }
  305.  
  306. function _tmux-command-prompt() {
  307.     [[ -n ${tmux_describe} ]] && print "Open the tmux command prompt in a client" && return
  308.     local state
  309.     local -a args
  310.     args=(
  311.         '-I[comma separated list of initial inputs]:initial-text:->ilist'
  312.         '-p[list of prompts]:prompts:->plist'
  313.         '-t[choose a target client]:clients:__tmux-clients'
  314.         '*:: :->tmpl'
  315.     )
  316.     _arguments -C ${args} && return
  317.     if [[ ${state} == 'plist' ]]; then
  318.         _message "comma seperated list of prompts"
  319.         return
  320.     elif [[ ${state} == 'ilist' ]]; then
  321.         _message "comma seperated list of initial text"
  322.         return
  323.     fi
  324.     __tmux-lastarg ${state} 'tmpl' 1 "command template"
  325. }
  326.  
  327. function _tmux-confirm-before() {
  328.     [[ -n ${tmux_describe} ]] && print "Run a command but ask for confirmation before" && return
  329.     local state
  330.     local -a args
  331.     args=(
  332.         '-p[specify prompt]:prompt:->prompt'
  333.         '-t[choose a target client]:clients:__tmux-clients'
  334.         '*:: :->command_and_args'
  335.     )
  336.     _arguments -C ${args} && return
  337.     if [[ ${state} == 'prompt' ]]; then
  338.         _message 'prompt string'
  339.         return
  340.     fi
  341.     __tmux-lastarg ${state} 'command_and_args' 1 "command string"
  342. }
  343.  
  344. function _tmux-copy-mode() {
  345.     [[ -n ${tmux_describe} ]] && print "Enter copy mode" && return
  346.     local -a args
  347.     args=(
  348.         '-t[choose a target pane]:panes:__tmux-panes'
  349.         '-u[scroll up one page]'
  350.     )
  351.     _arguments ${args}
  352. }
  353.  
  354. function _tmux-delete-buffer() {
  355.     [[ -n ${tmux_describe} ]] && print "Delete a paste buffer" && return
  356.     local -a args
  357.     args=('-b[choose a target buffer index]:buffers:__tmux-buffers')
  358.     _arguments ${args} && return
  359. }
  360.  
  361. function _tmux-detach-client() {
  362.     [[ -n ${tmux_describe} ]] && print "Detach a client from the server" && return
  363.     local -a args
  364.     args=(
  365.         '-a[kill all clients except for the named by -t]'
  366.         '-P[send SIGHUP to parent process]'
  367.         '-s[choose a target session and kill its clients]:sessions:__tmux-sessions'
  368.         '-t[choose a target client]:clients:__tmux-clients'
  369.     )
  370.     _arguments ${args}
  371. }
  372.  
  373. function _tmux-display-message() {
  374.     [[ -n ${tmux_describe} ]] && print "Display a message in the status line" && return
  375.     local -a args
  376.     args=(
  377.         '-c[choose a target client]:clients:__tmux-clients'
  378.         '-p[print message to stdout]'
  379.         '-t[choose a target client]:clients:__tmux-clients'
  380.         '*:: :->msg'
  381.     )
  382.     _arguments ${args} && return
  383.     __tmux-lastarg ${state} 'msg' 1 "message"
  384. }
  385.  
  386. function _tmux-display-panes() {
  387.     [[ -n ${tmux_describe} ]] && print "Display an indicator for each visible pane" && return
  388.     local -a args
  389.     args=('-t[choose a target client]:clients:__tmux-clients')
  390.     _arguments ${args}
  391. }
  392.  
  393. function _tmux-find-window() {
  394.     [[ -n ${tmux_describe} ]] && print "Search for a pattern in windows" && return
  395.     local curcontext="${curcontext}" state
  396.     local -a args
  397.     args=(
  398.         '-C[match visible contents]'
  399.         '-F[specify format of output]:format:__tmux-format'
  400.         '-N[match window name]'
  401.         '-T[match window title]'
  402.         '-t[choose a target window]:windows:__tmux-windows'
  403.         '*:: :->pattern'
  404.     )
  405.     _arguments ${args} && return
  406.     __tmux-lastarg ${state} 'pattern' 1 "window search pattern"
  407. }
  408.  
  409. function _tmux-has-session() {
  410.     [[ -n ${tmux_describe} ]] && print "Check and report if a session exists on the server" && return
  411.     local -a args
  412.     args=('-t[choose a target session]:sessions:__tmux-sessions')
  413.     _arguments ${args}
  414. }
  415.  
  416. function _tmux-if-shell() {
  417.     [[ -n ${tmux_describe} ]] && print "Execute a tmux command if a shell-command succeeded" && return
  418.     local -a args
  419.     args=(
  420.         '-b[run shell command in background]'
  421.         '-F[do not execute shell command but use it as a string-value]'
  422.         '1:shell command:'
  423.         '2:tmux command:'
  424.     )
  425.     _arguments ${args}
  426. }
  427.  
  428. function _tmux-join-pane() {
  429.     [[ -n ${tmux_describe} ]] && print "Split a pane and move an existing one into the new space" && return
  430.     local -a args
  431.     args=(
  432.         '-b[join source pane left of or above target pane]'
  433.         '-d[do not make the new window become the active one]'
  434.         '-h[split horizontally]'
  435.         '-v[split vertically]'
  436.         '-l[define new pane'\''s size]: :_guard "[0-9]#" "numeric value"'
  437.         '-p[define new pane'\''s size in percent]: :_guard "[0-9]#" "numeric value"'
  438.         '-s[choose source pane]:window:__tmux-panes'
  439.         '-t[choose target pane]:window:__tmux-panes'
  440.     )
  441.     _arguments ${args} && return
  442. }
  443.  
  444. function _tmux-kill-pane() {
  445.     [[ -n ${tmux_describe} ]] && print "Destroy a given pane" && return
  446.     local -a args
  447.     args=(
  448.         '-a[kill all panes except the one specified by -t]'
  449.         '-t[choose a target pane]:panes:__tmux-panes'
  450.     )
  451.     _arguments ${args}
  452. }
  453.  
  454. function _tmux-kill-server() {
  455.     [[ -n ${tmux_describe} ]] && print "Kill clients, sessions and server" && return
  456.     __tmux-nothing-else
  457. }
  458.  
  459. function _tmux-kill-session() {
  460.     [[ -n ${tmux_describe} ]] && print "Destroy a given session" && return
  461.     local -a args
  462.     args=(
  463.         '-a[kill all session except the one specified by -t]'
  464.         '-t[choose a target session]:sessions:__tmux-sessions'
  465.     )
  466.     _arguments ${args}
  467. }
  468.  
  469. function _tmux-kill-window() {
  470.     [[ -n ${tmux_describe} ]] && print "Destroy a given window" && return
  471.     local -a args
  472.     args=(
  473.         '-a[kill all windows except the one specified by -t]'
  474.         '-t[choose a target window]:windows:__tmux-windows'
  475.     )
  476.     _arguments ${args}
  477. }
  478.  
  479. function _tmux-last-pane() {
  480.     [[ -n ${tmux_describe} ]] && print "Select the previously selected pane" && return
  481.     local -a args
  482.     args=(
  483.         '-d[disable input to the pane]'
  484.         '-e[enable input to the pane]'
  485.         '-t[choose a session]:sessions:__tmux-sessions'
  486.     )
  487.     _arguments ${args} && return
  488. }
  489.  
  490. function _tmux-last-window() {
  491.     [[ -n ${tmux_describe} ]] && print "Select the previously selected window" && return
  492.     local -a args
  493.     args=('-t[choose a session]:sessions:__tmux-sessions')
  494.     _arguments ${args} && return
  495. }
  496.  
  497. function _tmux-link-window() {
  498.     [[ -n ${tmux_describe} ]] && print "Link a window to another" && return
  499.     local -a args
  500.     args=(
  501.         '-d[do not make the new window become the active one]'
  502.         '-k[kill the target window if it exists]'
  503.         '-s[choose source window]:window:__tmux-windows'
  504.         '-t[choose destination window]:window:__tmux-windows'
  505.     )
  506.     _arguments ${args}
  507. }
  508.  
  509. function _tmux-list-buffers() {
  510.     [[ -n ${tmux_describe} ]] && print "List paste buffers of a session" && return
  511.     local -a args
  512.     args=('-F[specify format of output]:format:__tmux-format')
  513.     _arguments ${args} && return
  514. }
  515.  
  516. function _tmux-list-clients() {
  517.     [[ -n ${tmux_describe} ]] && print "List clients attached to server" && return
  518.     local -a args
  519.     args=(
  520.         '-F[specify format of output]:format:__tmux-format'
  521.         '-t[choose a session]:sessions:__tmux-sessions'
  522.     )
  523.     _arguments ${args} && return
  524. }
  525.  
  526. function _tmux-list-commands() {
  527.     [[ -n ${tmux_describe} ]] && print "List supported sub-commands" && return
  528.     __tmux-nothing-else
  529. }
  530.  
  531. function _tmux-list-keys() {
  532.     [[ -n ${tmux_describe} ]] && print "List all key-bindings" && return
  533.     local -a args
  534.     args=('-t[choose a key table]:key table:__tmux-key-tables')
  535.     _arguments ${args} && return
  536. }
  537.  
  538. function _tmux-list-panes() {
  539.     [[ -n ${tmux_describe} ]] && print "List panes of a window" && return
  540.     local -a args
  541.     args=(
  542.         '-a[list all panes the server possesses]'
  543.         '-F[specify format of output]:format:__tmux-format'
  544.         '-s[if specified, -t chooses a session]'
  545.         # TODO: Use __tmux-windows or __tmux-sessions depending on -s.
  546.         '-t[choose a window]:windows:__tmux-windows'
  547.     )
  548.     _arguments ${args} && return
  549. }
  550.  
  551. function _tmux-list-sessions() {
  552.     [[ -n ${tmux_describe} ]] && print "List sessions managed by server" && return
  553.     local -a args
  554.     args=('-F[specify format of output]:format:__tmux-format')
  555.     _arguments ${args} && return
  556. }
  557.  
  558. function _tmux-list-windows() {
  559.     [[ -n ${tmux_describe} ]] && print "List windows of a session" && return
  560.     local -a args
  561.     args=(
  562.         '-a[list all windows the tmux server possesses]'
  563.         '-F[specify format of output]:format:__tmux-format'
  564.         '-t[choose a session]:sessions:__tmux-sessions'
  565.     )
  566.     _arguments ${args} && return
  567. }
  568.  
  569. function _tmux-load-buffer() {
  570.     [[ -n ${tmux_describe} ]] && print "Load a file into a paste buffer" && return
  571.     local -a args
  572.  
  573.     args=(
  574.         '-b[choose a target buffer index]:panes:__tmux-buffers'
  575.         '1:file name:_files -g "*(-.)"'
  576.     )
  577.     _arguments ${args} && return
  578. }
  579.  
  580. function _tmux-lock-client() {
  581.     [[ -n ${tmux_describe} ]] && print "Lock a client" && return
  582.     local -a args
  583.     args=('-t[choose a client]:clients:__tmux-clients')
  584.     _arguments ${args} && return
  585. }
  586.  
  587. function _tmux-lock-server() {
  588.     [[ -n ${tmux_describe} ]] && print "Lock all clients attached to the server" && return
  589.     __tmux-nothing-else
  590. }
  591.  
  592. function _tmux-lock-session() {
  593.     [[ -n ${tmux_describe} ]] && print "Lock all clients attached to a session" && return
  594.     local -a args
  595.     args=('-t[choose a session]:sessions:__tmux-sessions')
  596.     _arguments ${args} && return
  597. }
  598.  
  599. function _tmux-move-pane() {
  600.     [[ -n ${tmux_describe} ]] && print "Move a pane into a new space" && return
  601.     local -a args
  602.     args=(
  603.         '-b[join source pane left of or above target pane]'
  604.         '-d[do not make the new window become the active one]'
  605.         '-h[split horizontally]'
  606.         '-v[split vertically]'
  607.         '-l[define new pane'\''s size]: :_guard "[0-9]#" "numeric value"'
  608.         '-p[define new pane'\''s size in percent]: :_guard "[0-9]#" "numeric value"'
  609.         '-s[choose source pane]:window:__tmux-panes'
  610.         '-t[choose target pane]:window:__tmux-panes'
  611.     )
  612.     _arguments ${args} && return
  613. }
  614.  
  615. function _tmux-move-window() {
  616.     [[ -n ${tmux_describe} ]] && print "Move a window to another" && return
  617.     local -a args
  618.     args=(
  619.         '-d[do not make the new window become the active one]'
  620.         '-k[kill the target window if it exists]'
  621.         '-s[choose source window]:window:__tmux-windows'
  622.         '-r[renumber windows in session in sequential order]'
  623.         '-t[choose destination window]:window:__tmux-windows'
  624.     )
  625.     _arguments ${args}
  626. }
  627.  
  628. function _tmux-new-session() {
  629.     [[ -n ${tmux_describe} ]] && print "Create a new session" && return
  630.     local -a args
  631.     args=(
  632.         '-A[attach to existing session if it already exists]'
  633.         '-c[specify working directory for the session]:directory:_path_files -g "*(-/)"'
  634.         '-d[do not attach new session to current terminal]'
  635.         '-D[in case of -A behave like attach-session'\''s -d]'
  636.         '-F[specify format of output]:format:__tmux-format'
  637.         '-n[name the initial window]:window name'
  638.         '-P[print information about new session after it is created]'
  639.         '-s[name the session]:session name:__tmux-sessions'
  640.         '-t[specify target session]:sessions:__tmux-sessions'
  641.         '-x[specify width]:width:_guard "[0-9]#" "numeric value"'
  642.         '-y[specify height]:height:_guard "[0-9]#" "numeric value"'
  643.         '*:: :_cmdstring'
  644.     )
  645.     _arguments -s ${args}
  646. }
  647.  
  648. function _tmux-new-window() {
  649.     [[ -n ${tmux_describe} ]] && print "Create a new window" && return
  650.     local -a args
  651.     args=(
  652.         '-a[insert new window at next free index from -t]'
  653.         '-c[specify working directory for the session]:directory:_path_files -g "*(-/)"'
  654.         '-d[do not make the new window become the active one]'
  655.         '-F[specify format of output]:format:__tmux-format'
  656.         '-k[destroy it if the specified window exists]'
  657.         '-n[specify a window name]:window name:'
  658.         '-P[print information about new window after it is created]'
  659.         '-t[specify target window]:windows:__tmux-windows'
  660.         '*:: :_cmdstring'
  661.     )
  662.     _arguments ${args}
  663. }
  664.  
  665. function _tmux-next-layout() {
  666.     [[ -n ${tmux_describe} ]] && print "Move a window to the next layout" && return
  667.     local -a args
  668.     args=('-t[choose target window]:window:__tmux-windows')
  669.     _arguments ${args}
  670. }
  671.  
  672. function _tmux-next-window() {
  673.     [[ -n ${tmux_describe} ]] && print "Move to the next window in a session" && return
  674.     local -a args
  675.     args=(
  676.         '-a[move to the next window with an alert]'
  677.         '-t[choose target session]:session:__tmux-sessions'
  678.     )
  679.     _arguments ${args}
  680. }
  681.  
  682. function _tmux-paste-buffer() {
  683.     [[ -n ${tmux_describe} ]] && print "Insert a paste buffer into the window" && return
  684.     local -a args
  685.     args=(
  686.         '-b[choose buffer]:source buffer:__tmux-buffers'
  687.         '-d[remove buffer from stack after pasting]'
  688.         '-p[use bracketed paste mode if the application requested it]'
  689.         '-r[do not replace LF with CR when pasting]'
  690.         '-s[specify separator]:separator:'
  691.         '-t[choose target window]:window:__tmux-windows'
  692.     )
  693.     _arguments ${args}
  694. }
  695.  
  696. function _tmux-pipe-pane() {
  697.     [[ -n ${tmux_describe} ]] && print "Pipe output from a pane to a shell command" && return
  698.     local state
  699.     args=(
  700.         '-o[only open a pipe if none is currently opened]'
  701.         '-t[choose target pane]:pane:__tmux-panes'
  702.         '*:: :->cmd'
  703.     )
  704.     _arguments ${args} && return
  705.     __tmux-lastarg ${state} 'cmd' 1 "command string"
  706. }
  707.  
  708. function _tmux-previous-layout() {
  709.     [[ -n ${tmux_describe} ]] && print "Move a window to the previous layout" && return
  710.     local -a args
  711.     args=('-t[choose target window]:window:__tmux-windows')
  712.     _arguments ${args}
  713. }
  714.  
  715. function _tmux-previous-window() {
  716.     [[ -n ${tmux_describe} ]] && print "Move to the previous window in a session" && return
  717.     local -a args
  718.     args=(
  719.         '-a[move to the previous window with an alert]'
  720.         '-t[choose target session]:session:__tmux-sessions'
  721.     )
  722.     _arguments ${args}
  723. }
  724.  
  725. function _tmux-refresh-client() {
  726.     [[ -n ${tmux_describe} ]] && print "Refresh a client" && return
  727.     local -a args
  728.     args=(
  729.         '-S[Only update the client'\''s status bar]'
  730.         '-t[choose target client]:client:__tmux-clients'
  731.     )
  732.     _arguments ${args}
  733. }
  734.  
  735. function _tmux-rename-session() {
  736.     [[ -n ${tmux_describe} ]] && print "Rename a session" && return
  737.     local state
  738.     args=(
  739.         '-t[choose target session]:session:__tmux-sessions'
  740.         '*:: :->name'
  741.     )
  742.     _arguments ${args} && return
  743.     __tmux-lastarg ${state} 'name' 1 "new session name"
  744. }
  745.  
  746. function _tmux-rename-window() {
  747.     [[ -n ${tmux_describe} ]] && print "Rename a window" && return
  748.     local state
  749.     args=(
  750.         '-t[choose target window]:window:__tmux-windows'
  751.         '*:: :->name'
  752.     )
  753.     _arguments ${args} && return
  754.     __tmux-lastarg ${state} 'name' 1 "new window name"
  755. }
  756.  
  757. function _tmux-resize-pane() {
  758.     [[ -n ${tmux_describe} ]] && print "Resize a pane" && return
  759.     args=(
  760.         '-D[resize downward]'
  761.         '-L[resize to the left]'
  762.         '-R[resize to the right]'
  763.         '-U[resize upward]'
  764.         '-t[choose target pane]:pane:__tmux-panes'
  765.         '-x[specify width]:width:_guard "[0-9]#" "numeric value"'
  766.         '-y[specify height]:height:_guard "[0-9]#" "numeric value"'
  767.         '-Z[toggle zoom of pane]'
  768.         '1::adjustment (defaults to one):_guard "[0-9]#" "numeric value"'
  769.     )
  770.     _arguments ${args}
  771. }
  772.  
  773. function _tmux-respawn-pane() {
  774.     [[ -n ${tmux_describe} ]] && print "Reuse a pane in which a command has exited" && return
  775.     local -a args
  776.     args=(
  777.         '-k[kill window if it is in use]'
  778.         '-t[choose target pane]:window:__tmux-pane'
  779.         '*::command:_cmdstring'
  780.     )
  781.     _arguments ${args}
  782. }
  783.  
  784. function _tmux-respawn-window() {
  785.     [[ -n ${tmux_describe} ]] && print "Reuse a window in which a command has exited" && return
  786.     local -a args
  787.     args=(
  788.         '-k[kill window if it is in use]'
  789.         '-t[choose target window]:window:__tmux-windows'
  790.         '*::command:_cmdstring'
  791.     )
  792.     _arguments ${args}
  793. }
  794.  
  795. function _tmux-rotate-window() {
  796.     [[ -n ${tmux_describe} ]] && print "Rotate positions of panes in a window" && return
  797.     local -a args
  798.     args=(
  799.         '-D[rotate downward]'
  800.         '-U[rotate upward]'
  801.         '-t[choose target window]:window:__tmux-windows'
  802.     )
  803.     _arguments ${args}
  804. }
  805.  
  806. function _tmux-run-shell() {
  807.     [[ -n ${tmux_describe} ]] && print "Execute a command without creating a new window" && return
  808.     local -a args
  809.     args=(
  810.         '-b[run shell command in background]'
  811.         '-t[choose target pane]:pane:__tmux-panes'
  812.         '*::command:_cmdstring'
  813.     )
  814.     _arguments ${args}
  815. }
  816.  
  817. function _tmux-save-buffer() {
  818.     [[ -n ${tmux_describe} ]] && print "Save a paste buffer to a file" && return
  819.     local -a args
  820.  
  821.     args=(
  822.         '-a[append to rather than overwriting file]'
  823.         '-b[choose a target buffer index]:buffer:__tmux-buffers'
  824.     )
  825.     _arguments ${args} && return
  826. }
  827.  
  828. function _tmux-select-layout() {
  829.     [[ -n ${tmux_describe} ]] && print "Choose a layout for a window" && return
  830.     args=(
  831.         '-n[behave like next-layout]'
  832.         '-p[behave like previous-layout]'
  833.         '-t[choose a target window]:target window:__tmux-windows'
  834.         '*::layout name:__tmux-layouts'
  835.     )
  836.     _arguments ${args}
  837. }
  838.  
  839. function _tmux-select-pane() {
  840.     [[ -n ${tmux_describe} ]] && print "Make a pane the active one in the window" && return
  841.     local -a args
  842.     args=(
  843.         '-D[Move to the pane down of this]'
  844.         '-d[disable input to the pane]'
  845.         '-e[enable input to the pane]'
  846.         '-l[behave like last-pane]'
  847.         '-L[Move to the pane left of this]'
  848.         '-R[Move to the pane right of this]'
  849.         '-U[Move to the pane above this]'
  850.         '-t[choose a target pane]:panes:__tmux-panes'
  851.     )
  852.     _arguments ${args} && return
  853. }
  854.  
  855. function _tmux-select-window() {
  856.     [[ -n ${tmux_describe} ]] && print "Select a window" && return
  857.     local -a args
  858.     args=(
  859.         '-l[behave like last-window]'
  860.         '-n[behave like next-window]'
  861.         '-p[behave like previous-window]'
  862.         '-T[if selected window is the current behave like last-window]'
  863.         '-t[choose a target window]:windows:__tmux-windows'
  864.     )
  865.     _arguments ${args} && return
  866. }
  867.  
  868. function _tmux-send-keys() {
  869.     [[ -n ${tmux_describe} ]] && print "Send key(s) to a window" && return
  870.     local curcontext="${curcontext}" state
  871.     local -a args
  872.     args=(
  873.         '-l[disable key name lookup and send data literally]'
  874.         '-R[reset terminal state]'
  875.         '-t[choose a target pane]:panes:__tmux-panes'
  876.         '*:: :->key'
  877.     )
  878.     _arguments ${args} && return
  879.     __tmux-lastarg ${state} 'key' 1 "key"
  880. }
  881.  
  882. function _tmux-send-prefix() {
  883.     [[ -n ${tmux_describe} ]] && print "Send the prefix key to a window" && return
  884.     local -a args
  885.     args=(
  886.         '-2[send secondary prefix key]'
  887.         '-t[choose a target pane]:panes:__tmux-panes'
  888.     )
  889.     _arguments ${args}
  890. }
  891.  
  892. function _tmux-server-info() {
  893.     [[ -n ${tmux_describe} ]] && print "Show server information" && return
  894.     __tmux-nothing-else
  895. }
  896.  
  897. function _tmux-set-buffer() {
  898.     [[ -n ${tmux_describe} ]] && print "Set contents of a paster buffer" && return
  899.     local state
  900.     local -a args
  901.     args=(
  902.         '-a[append to rather than overwriting target buffer]'
  903.         '-b[choose a target buffer index]:panes:__tmux-buffer'
  904.         '-n[specify new buffer name]:buffer-name:'
  905.         '*:: :->data'
  906.     )
  907.     _arguments ${args} && return
  908.     __tmux-lastarg ${state} 'data' 1 "data"
  909. }
  910.  
  911. function _tmux-set-environment() {
  912.     [[ -n ${tmux_describe} ]] && print "(Un)Set an environment variable" && return
  913.     local state
  914.     local -a args
  915.     args=(
  916.         '-g[modify global environment]'
  917.         '-r[remove variable before starting new processes]'
  918.         '-u[unset a variable]'
  919.         '-t[choose a target session]:target session:__tmux-sessions'
  920.         '*:: :->name_or_value'
  921.     )
  922.     _arguments -C ${args}
  923.  
  924.     case ${state} in
  925.         name_or_value)
  926.             if (( CURRENT == 1 )); then
  927.                 _message 'name'
  928.             elif (( CURRENT == 2 )); then
  929.                 _message 'value'
  930.             else
  931.                 __tmux-nothing-else
  932.             fi
  933.             ;;
  934.     esac
  935. }
  936.  
  937. function _tmux-set-option() {
  938.     [[ -n ${tmux_describe} ]] && print "Set a session option" && return
  939.     local mode
  940.     local -a args
  941.     args=(
  942.         '-a[append to string options]'
  943.         '-g[set a global session option]'
  944.         '-u[unset a non-global option]'
  945.         '-w[change window (not session) options]'
  946.         '-s[change server (not session) options]'
  947.         '-t[choose a target session]:target session:__tmux-sessions'
  948.         '*:: :->name_or_value'
  949.     )
  950.     if __tmux-got-option-already -w; then
  951.         mode=window
  952.     elif __tmux-got-option-already -s; then
  953.         mode=server
  954.     else
  955.         mode=session
  956.     fi
  957.     _arguments -C ${args}
  958.     __tmux-options-complete ${mode} ${state}
  959. }
  960.  
  961. function _tmux-set-window-option() {
  962.     [[ -n ${tmux_describe} ]] && print "Set a window option" && return
  963.     local -a args
  964.     args=(
  965.         '-a[append to string options]'
  966.         '-g[set a global window option]'
  967.         '-u[unset a non-global option]'
  968.         '-t[choose a target window]:target window:__tmux-windows'
  969.         '*:: :->name_or_value'
  970.     )
  971.     _arguments -C ${args}
  972.     __tmux-options-complete window ${state}
  973. }
  974.  
  975. function _tmux-show-buffer() {
  976.     [[ -n ${tmux_describe} ]] && print "Display the contents of a paste buffer" && return
  977.     local -a args
  978.     args=('-b[choose a target buffer index]:panes:->buffer')
  979.     _arguments ${args} && return
  980. }
  981.  
  982. function _tmux-show-environment() {
  983.     [[ -n ${tmux_describe} ]] && print "Display the environment" && return
  984.     local -a args
  985.     args=(
  986.         '-g[show global environment]'
  987.         '-t[choose a target session]:target session:__tmux-sessions'
  988.     )
  989.     _arguments ${args}
  990. }
  991.  
  992. function _tmux-show-messages() {
  993.     [[ -n ${tmux_describe} ]] && print "Show client"\'"s message log" && return
  994.     local -a args
  995.     args=(
  996.         '-I[show debugging information about the tmux server]'
  997.         '-J[show debugging information about running jobs]'
  998.         '-T[show debugging information about involved terminals]'
  999.         '-t[choose target client]:client:__tmux-clients'
  1000.     )
  1001.     _arguments ${args}
  1002. }
  1003.  
  1004. function _tmux-show-options() {
  1005.     [[ -n ${tmux_describe} ]] && print "Show session options" && return
  1006.     local -a args
  1007.     args=(
  1008.         '-g[show global options]'
  1009.         '-t[choose a target session]:target session:__tmux-sessions'
  1010.     )
  1011.     _arguments ${args}
  1012. }
  1013.  
  1014. function _tmux-show-window-options() {
  1015.     [[ -n ${tmux_describe} ]] && print "Show window options" && return
  1016.     local -a args
  1017.     args=(
  1018.         '-g[show global options]'
  1019.         '-t[choose a target window]:target window:__tmux-windows'
  1020.     )
  1021.     _arguments ${args}
  1022. }
  1023.  
  1024. function _tmux-source-file() {
  1025.     [[ -n ${tmux_describe} ]] && print "Execute tmux commands from a file" && return
  1026.     _files -g "*(-.)"
  1027. }
  1028.  
  1029. function _tmux-split-window() {
  1030.     [[ -n ${tmux_describe} ]] && print "Splits a pane into two" && return
  1031.     local -a args
  1032.     args=(
  1033.         '-b[create new pane left of or above target pane]'
  1034.         '-d[do not make the new window become the active one]'
  1035.         '-F[specify format of output]:format:__tmux-format'
  1036.         '-h[split horizontally]'
  1037.         '-v[split vertically]'
  1038.         '-l[define new pane'\''s size]: :_guard "[0-9]#" "numeric value"'
  1039.         '-p[define new pane'\''s size in percent]: :_guard "[0-9]#" "numeric value"'
  1040.         # Yes, __tmux-panes is correct here. The behaviour was changed
  1041.         # in recent tmux versions and makes more sense. Except that
  1042.         # changing the command's name might annoy users. So it stays like
  1043.         # this.
  1044.         '-t[choose target pane]:window:__tmux-panes'
  1045.         '*:: :_cmdstring'
  1046.     )
  1047.     _arguments ${args} && return
  1048. }
  1049.  
  1050. function _tmux-start-server() {
  1051.     [[ -n ${tmux_describe} ]] && print "Start a tmux server" && return
  1052.     __tmux-nothing-else
  1053. }
  1054.  
  1055. function _tmux-suspend-client() {
  1056.     [[ -n ${tmux_describe} ]] && print "Suspend a client" && return
  1057.     local -a args
  1058.     args=('-t[choose destination client]:client:__tmux-clients')
  1059.     _arguments ${args}
  1060. }
  1061.  
  1062. function _tmux-swap-pane() {
  1063.     [[ -n ${tmux_describe} ]] && print "Swap two panes" && return
  1064.     local -a args
  1065.     args=(
  1066.         '-D[move pane down]'
  1067.         '-U[move pane up]'
  1068.         '-d[do not change the active pane]'
  1069.         '-s[choose source pane]:pane:__tmux-panes'
  1070.         '-t[choose destination pane]:pane:__tmux-panes'
  1071.     )
  1072.     _arguments ${args}
  1073. }
  1074.  
  1075. function _tmux-swap-window() {
  1076.     [[ -n ${tmux_describe} ]] && print "Swap two windows" && return
  1077.     local -a args
  1078.     args=(
  1079.         '-d[do not make the new window become the active one]'
  1080.         '-s[choose source window]:window:__tmux-windows'
  1081.         '-t[choose destination window]:window:__tmux-windows'
  1082.     )
  1083.     _arguments ${args}
  1084. }
  1085.  
  1086. function _tmux-switch-client() {
  1087.     [[ -n ${tmux_describe} ]] && print "Switch the client to another session" && return
  1088.     local -a args
  1089.     args=(
  1090.         '-c[choose a target client]:client:__tmux-clients'
  1091.         '-l[move client to last session]'
  1092.         '-n[move client to next session]'
  1093.         '-p[move client to previous session]'
  1094.         '-r[toggle read-only flag of client]'
  1095.         '-t[choose a target window]:window:__tmux-windows'
  1096.     )
  1097.     _arguments ${args}
  1098. }
  1099.  
  1100. function _tmux-unbind-key() {
  1101.     [[ -n ${tmux_describe} ]] && print "Unbind a key" && return
  1102.     local state keytable
  1103.     local -a args ow
  1104.  
  1105.     ow=( "${words[@]}" )
  1106.     args=(
  1107.         '-a[Remove all key bindings]'
  1108.         '-c[kill the window if it is only in one session]'
  1109.         '-n[remove a non-prefix binding]'
  1110.         '-t[choose a key table]:key table:__tmux-key-tables'
  1111.         '*:: :->boundkeys'
  1112.     )
  1113.     _arguments ${args} && return
  1114.     [[ ${state} != 'boundkeys' ]] && return
  1115.     keytable="$(__tmux-get-optarg -t "${ow[@]}")"
  1116.     if [[ -n ${keytable} ]]; then
  1117.         __tmux-bound-keys -t ${keytable}
  1118.         return
  1119.     fi
  1120.     __tmux-bound-keys
  1121. }
  1122.  
  1123. function _tmux-unlink-window() {
  1124.     [[ -n ${tmux_describe} ]] && print "Unlink a window" && return
  1125.     local -a args
  1126.     args=(
  1127.         '-k[kill the window if it is only in one session]'
  1128.         '-t[choose a target window]:target window:__tmux-windows'
  1129.     )
  1130.     _arguments ${args}
  1131. }
  1132.  
  1133. function _tmux-wait-for() {
  1134.     [[ -n ${tmux_describe} ]] && print "Wait for an event or trigger it" && return
  1135.     local state
  1136.     local -a args
  1137.     args=(
  1138.         '-L[lock the named channel]'
  1139.         '-S[send signal to channel]'
  1140.         '-U[unlock the named channel]'
  1141.         '*:: :->channel'
  1142.     )
  1143.     _arguments ${args} && return
  1144.     __tmux-lastarg ${state} 'channel' 1 "event channel"
  1145. }
  1146.  
  1147. # --- Utility functions ---
  1148. # They should be called __tmux-*() and kept seperate from the
  1149. # sub-command functions.
  1150.  
  1151. function __tmux-attributes() {
  1152.     local -a attr already
  1153.     attr=( default bright bold dim underscore blink reverse hidden italics )
  1154.     compset -P '*,'
  1155.     already=(${(s<,>)IPREFIX})
  1156.     _describe -t tmux-attribute 'tmux attribute' attr -S, -F already -q
  1157. }
  1158.  
  1159. function __tmux-buffers() {
  1160.     local expl
  1161.     local -a buffers
  1162.  
  1163.     if [[ ${(t)bopts} != *array* ]]; then
  1164.         local -a bopts; bopts=()
  1165.     fi
  1166.  
  1167.     buffers=( ${${(f)"$(command tmux 2> /dev/null list-buffers "${bopts[@]}")"}/:[ $'\t']##/:} )
  1168.     _describe -t buffers 'buffers' buffers
  1169. }
  1170.  
  1171. function __tmux-bound-keys() {
  1172.     local expl
  1173.     local -a keys
  1174.  
  1175.     keys=( ${${${${(f)"$(command tmux 2> /dev/null list-keys "$@")"}/:[ $'\t']##/:}/(#s)[ $'\t']##/}/(#s):/\\:} )
  1176.     _describe -t keys 'keys' keys
  1177. }
  1178.  
  1179. function __tmux-clients() {
  1180.     local expl
  1181.     local -a clients
  1182.     clients=( ${${(f)"$(command tmux 2> /dev/null list-clients)"}/:[ $'\t']##/:} )
  1183.     _describe -t clients 'clients' clients
  1184. }
  1185.  
  1186. function __tmux-format() {
  1187.     _message 'not implemented yet'
  1188. }
  1189.  
  1190. function __tmux-colours() {
  1191.     local -a colnames
  1192.     colnames=( default black red green yellow blue magenta cyan white colourN:"replace N by a number between 0 and 255" )
  1193.     compset -P 'colour*'
  1194.     if [[ -z ${IPREFIX} ]]; then
  1195.         _describe -t tmux-colours 'colour' colnames
  1196.     else
  1197.         _message 'colour number 0..255'
  1198.     fi
  1199. }
  1200.  
  1201. function __tmux-get-optarg() {
  1202.     local opt="$1"
  1203.     local -i i
  1204.     shift
  1205.  
  1206.     for (( i = 1; i <= $#; i++ )); do
  1207.         if [[ ${argv[$i]} == ${opt} ]]; then
  1208.             if [[ ${argv[$(( i + 1 ))]} != -* ]]; then
  1209.                 print -- ${argv[$(( i + 1 ))]}
  1210.             fi
  1211.             return
  1212.         fi
  1213.     done
  1214. }
  1215.  
  1216. function __tmux-got-option-already() {
  1217.     [[ -n ${(M)words:#$1} ]] && return 0
  1218.     return 1
  1219. }
  1220.  
  1221. function __tmux-key-tables() {
  1222.     local expl
  1223.     local -a tables
  1224.     tables=( vi-edit emacs-edit vi-choice emacs-choice vi-copy emacs-copy )
  1225.     _wanted keytable expl 'key tables' compadd ${expl} -- ${tables}
  1226. }
  1227.  
  1228. function __tmux-lastarg() {
  1229.     local got_state="$1" want_state="$2" pos="$3" msg="$4"
  1230.  
  1231.     if [[ ${want_state} == ${got_state} ]] && (( CURRENT == ${pos} )); then
  1232.         _message ${msg}
  1233.     else
  1234.         __tmux-nothing-else
  1235.     fi
  1236. }
  1237.  
  1238. function __tmux-layouts() {
  1239.     local expl
  1240.     local -a layouts
  1241.     layouts=( even-horizontal even-vertical main-horizontal main-vertical )
  1242.     _wanted layout expl 'layouts' compadd ${expl} -- ${layouts}
  1243. }
  1244.  
  1245. function __tmux-nothing-else() {
  1246.     _message "no further arguments"
  1247. }
  1248.  
  1249. function __tmux-option-guard() {
  1250.     local mode opt guard int_guard
  1251.     mode="$1"
  1252.     opt="$2"
  1253.     shift; shift
  1254.     local -a options desc
  1255.     int_guard='_guard "[0-9]#" "'${opt}': numeric value"'
  1256.     if [[ ${mode} == 'session' ]]; then
  1257.         options=(
  1258.             'assume-paste-time:'${int_guard}
  1259.             'base-index:'${int_guard}
  1260.             'bell-action:DESC:any none current other'
  1261.             'bell-on-alert:DESC:on off'
  1262.             'default-command:MSG:command string'
  1263.             'default-shell:MSG:shell executable'
  1264.             'destroy-unattached:DESC:on off'
  1265.             'detach-on-destroy:DESC:on off'
  1266.             'display-panes-colour:__tmux-colours'
  1267.             'display-panes-active-colour:__tmux-colours'
  1268.             'display-panes-time:'${int_guard}
  1269.             'display-time:'${int_guard}
  1270.             'history-limit:'${int_guard}
  1271.             'lock-after-time:'${int_guard}
  1272.             'lock-command:MSG:command string'
  1273.             'message-command-style:__tmux-style'
  1274.             'message-style:__tmux-style'
  1275.             'mouse:DESC:on off'
  1276.             'mouse-utf8:DESC:on off'
  1277.             'prefix:MSG:primary prefix key'
  1278.             'prefix2:MSG:secondary prefix key'
  1279.             'renumber-windows:DESC:on off'
  1280.             'repeat-time:'${int_guard}
  1281.             'set-remain-on-exit:DESC:on off'
  1282.             'set-titles:DESC:on off'
  1283.             'set-titles-string:MSG:title format string'
  1284.             'status:DESC:on off'
  1285.             'status-interval:'${int_guard}
  1286.             'status-justify:DESC:left centre right'
  1287.             'status-keys:DESC:vi emacs'
  1288.             'status-left:MSG:format string'
  1289.             'status-left-length:'${int_guard}
  1290.             'status-left-style:__tmux-style'
  1291.             'status-position:DESC:top bottom'
  1292.             'status-right:MSG:format string'
  1293.             'status-right-length:'${int_guard}
  1294.             'status-right-style:__tmux-style'
  1295.             'status-style:__tmux-style'
  1296.             'status-utf8:DESC:on off'
  1297.             'update-environment:MSG:string listing env. variables'
  1298.             'visual-activity:DESC:on off'
  1299.             'visual-bell:DESC:on off'
  1300.             'visual-silence:DESC:on off'
  1301.             'word-separators:MSG:separator string'
  1302.         )
  1303.     elif [[ ${mode} == 'server' ]]; then
  1304.         options=(
  1305.             'buffer-limit:'${int_guard}
  1306.             'default-terminal:MSG:terminal string'
  1307.             'escape-time:'${int_guard}
  1308.             'exit-unattached:DESC:on off'
  1309.             'focus-events:DESC:on off'
  1310.             'history-file:_path-files -g "*(-.)"'
  1311.             'message-limit:'${int_guard}
  1312.             'quiet:DESC:on off'
  1313.             'set-clipboard:DESC:on off'
  1314.             'terminal-overrides:MSG:overrides string'
  1315.         )
  1316.     else
  1317.         options=(
  1318.             'aggressive-resize:DESC:on off'
  1319.             'allow-rename:DESC:on off'
  1320.             'alternate-screen:DESC:on off'
  1321.             'automatic-rename:DESC:on off'
  1322.             'automatic-rename-format:DESC:__tmux-format'
  1323.             'clock-mode-colour:__tmux-colours'
  1324.             'clock-mode-style:DESC:12 24'
  1325.             'force-height:'${int_guard}
  1326.             'force-width:'${int_guard}
  1327.             'main-pane-height:'${int_guard}
  1328.             'main-pane-width:'${int_guard}
  1329.             'mode-keys:DESC:vi emacs'
  1330.             'mode-style:__tmux-style'
  1331.             'monitor-activity:DESC:on off'
  1332.             'monitor-silence:DESC:on off'
  1333.             'other-pane-height:'${int_guard}
  1334.             'other-pane-width:'${int_guard}
  1335.             'pane-active-border-style:__tmux-style'
  1336.             'pane-base-index:'${int_guard}
  1337.             'pane-border-style:__tmux-style'
  1338.             'remain-on-exit:DESC:on off'
  1339.             'synchronize-panes:DESC:on off'
  1340.             'utf8:DESC:on off'
  1341.             'window-active-style:__tmux-style'
  1342.             'window-status-activity-style:__tmux-style'
  1343.             'window-status-bell-style:__tmux-style'
  1344.             'window-status-current-format:MSG:status format string'
  1345.             'window-status-current-style:__tmux-style'
  1346.             'window-status-format:MSG:status format string'
  1347.             'window-status-last-style:__tmux-style'
  1348.             'window-status-separator:MSG:separator string'
  1349.             'window-status-style:__tmux-style'
  1350.             'window-style:__tmux-style'
  1351.             'wrap-seach:DESC:on off'
  1352.             'xterm-keys:DESC:on off'
  1353.         )
  1354.     fi
  1355.  
  1356.     guard=${(M)options:#$opt:*}
  1357.     if [[ -z ${guard} ]]; then
  1358.         _message "unknown ${mode} option: ${opt}"
  1359.         return
  1360.     fi
  1361.     _message "${mode} option value"
  1362.     guard=${guard#*:}
  1363.     case ${guard} in
  1364.         ('') ;;
  1365.         (MSG:*)
  1366.             _message ${guard#*:}
  1367.             ;;
  1368.         (DESC:*)
  1369.             eval "desc=( ${guard#*:} )"
  1370.             _describe -t "tmux-${mode}-option-value" "${opt}" desc
  1371.             ;;
  1372.         (*)
  1373.             eval ${guard}
  1374.             ;;
  1375.     esac
  1376. }
  1377.  
  1378. function __tmux-session-options() {
  1379.     local -a tmux_session_options
  1380.     tmux_session_options=(
  1381.         'assume-paste-time:assume keys are pasted instead of typed if this fast'
  1382.         'base-index:define where to start numbering'
  1383.         'bell-action:set action on window bell'
  1384.         'bell-on-alert:ring the terminal bell when an alert occurs'
  1385.         'default-command:default command for new windows'
  1386.         'default-shell:default shell executable'
  1387.         'destroy-unattached:destroy session if no client is attached'
  1388.         'detach-on-destroy:detach client if attached session is destroyed'
  1389.         'display-panes-colour:colour used for display-panes'
  1390.         'display-panes-active-colour:colour for active pane in display-panes'
  1391.         'display-panes-time:time (in msecs) of display-panes output'
  1392.         'display-time:time (in msecs) messages are displayed'
  1393.         'history-limit:number of copy-mode lines per window'
  1394.         'lock-after-time:lock sessions after N seconds'
  1395.         'lock-command:command to run for locking a client'
  1396.         'message-command-style:status line message command style'
  1397.         'message-style:status line message style'
  1398.         'mouse:enable mouse support'
  1399.         'mouse-utf8:request utf8 mouse support'
  1400.         'prefix:primary prefix key'
  1401.         'prefix2:secondary prefix key'
  1402.         'renumber-windows:renumber windows if a window is closed'
  1403.         'repeat-time:time for multiple commands without prefix-key presses'
  1404.         'set-remain-on-exit:set remain-on-exit window option'
  1405.         'set-titles:try to set xterm window titles'
  1406.         'set-titles-string:format used by set-titles'
  1407.         'status:show or hide the status bar'
  1408.         'status-interval:interval (in seconds) for status bar updates'
  1409.         'status-justify:position of the window list in status bar'
  1410.         'status-keys:mode to use in status bar modes (vi/emacs)'
  1411.         'status-left:format to use left in status bar'
  1412.         'status-left-length:maximum length of the left part of the status bar'
  1413.         'status-left-style:style of left part of status line'
  1414.         'status-position:status line position'
  1415.         'status-right:format to use right in status bar'
  1416.         'status-right-length:maximum length of the right part of the status bar'
  1417.         'status-right-style:style of right part of status line'
  1418.         'status-style:style status line'
  1419.         'status-utf8:assume UTF-8 sequences to appear in status bar'
  1420.         'update-environment:list of variables to be copied to a session'\''s environment'
  1421.         'visual-activity:display status line messages upon activity'
  1422.         'visual-bell:use visual bell instead of audible'
  1423.         'visual-silence:print a message if monitor-silence is on'
  1424.         'word-separators:string of characters considered word separators'
  1425.     )
  1426.     _describe -t tmux-options 'tmux session option' tmux_session_options
  1427. }
  1428.  
  1429. function __tmux-options-complete() {
  1430.     local mode="$1" state="$2"
  1431.  
  1432.     case ${state} in
  1433.         name_or_value)
  1434.             if (( CURRENT == 1 )) && [[ ${mode} == 'session' ]]; then
  1435.                 __tmux-session-options
  1436.             elif (( CURRENT == 1 )) && [[ ${mode} == 'server' ]]; then
  1437.                 __tmux-server-options
  1438.             elif (( CURRENT == 1 )) && [[ ${mode} == 'window' ]]; then
  1439.                 __tmux-window-options
  1440.             elif (( CURRENT == 2 )); then
  1441.                 __tmux-option-guard ${mode} ${words[1]}
  1442.             else
  1443.                 __tmux-nothing-else
  1444.             fi
  1445.             ;;
  1446.     esac
  1447. }
  1448.  
  1449. function __tmux-panes() {
  1450.     local expl line
  1451.     local -i num
  1452.     local -a panes opts
  1453.  
  1454.     compset -P '*.'
  1455.     if [[ -n ${IPREFIX} ]]; then
  1456.         opts=( -t "${IPREFIX%.}" )
  1457.     else
  1458.         opts=( )
  1459.     fi
  1460.     num=0
  1461.     command tmux 2> /dev/null list-panes "${opts[@]}" | while IFS= read -r line; do
  1462.         panes+=( $(( num++ )):${line//:/} )
  1463.     done
  1464.     _describe -t panes 'panes' panes "$@"
  1465.     if [[ ${IPREFIX} != *. ]]; then
  1466.         _wanted windows expl 'windows' __tmux-windows -S.
  1467.     fi
  1468. }
  1469.  
  1470. function __tmux-server-options() {
  1471.     local -a tmux_server_options
  1472.     tmux_server_options=(
  1473.         'buffer-limit:number of buffers kept per session'
  1474.         'default-terminal:default terminal definition string'
  1475.         'escape-time:set timeout to detect single escape characters (in msecs)'
  1476.         'exit-unattached:make server exit if it has no attached clients'
  1477.         'focus-events:request focus events from terminal'
  1478.         'history-file:tmux command history file name'
  1479.         'message-limit:set size of message log per client'
  1480.         'quiet:enable/disable the display of various informational messages'
  1481.         'set-clipboard:use esc sequences to set terminal clipboard'
  1482.         'terminal-overrides:override terminal descriptions'
  1483.     )
  1484.     _describe -t tmux-server-options 'tmux server option' tmux_server_options
  1485. }
  1486.  
  1487. function __tmux-sessions() {
  1488.     local expl
  1489.     local -a sessions
  1490.     sessions=( ${${(f)"$(command tmux 2> /dev/null list-sessions)"}/:[ $'\t']##/:} )
  1491.     _describe -t sessions 'sessions' sessions "$@"
  1492. }
  1493.  
  1494. function __tmux-socket-name() {
  1495.     local expl sdir
  1496.     local curcontext="${curcontext}"
  1497.     local -a socks
  1498.     zstyle -s ":completion:${curcontext}:sockets" socketdir sdir || sdir="/tmp/tmux-${UID}"
  1499.     socks=(${sdir}/*(=:t))
  1500.     _wanted socket expl 'socket name' compadd ${expl} -- ${socks}
  1501. }
  1502.  
  1503. function __tmux-style() {
  1504.     _message 'not implemented yet'
  1505. }
  1506.  
  1507. function __tmux-window-options() {
  1508.     local -a tmux_window_options
  1509.     tmux_window_options=(
  1510.         'aggressive-resize:aggressively resize windows'
  1511.         'allow-rename:allow programs to change window titles'
  1512.         'alternate-screen:allow alternate screen feature to be used'
  1513.         'automatic-rename:attempt to automatically rename windows'
  1514.         'automatic-rename-format:format for automatic renames'
  1515.         'clock-mode-colour:set clock colour'
  1516.         'clock-mode-style:set clock hour format (12/24)'
  1517.         'force-height:force a windows to a certain height'
  1518.         'force-width:force a windows to a certain width'
  1519.         'main-pane-height:set height for main-* layouts'
  1520.         'main-pane-width:set width for main-* layouts'
  1521.         'mode-keys:mode to use in copy and choice modes (vi/emacs)'
  1522.         'mode-style:set window modes style'
  1523.         'monitor-activity:monitor window activity'
  1524.         'monitor-silence:monitor window for inactivity'
  1525.         'other-pane-height:height of other panes'
  1526.         'other-pane-width:width of other panes'
  1527.         'pane-active-border-style:style of border of active pane'
  1528.         'pane-base-index:integer at which to start indexing panes'
  1529.         'pane-border-style:style of border pane'
  1530.         'remain-on-exit:do not destroy windows after the program exits'
  1531.         'synchronize-panes:send input to all panes of a window'
  1532.         'utf8:assume UTF-8 sequences to appear in a window'
  1533.         'window-active-style:style of active window'
  1534.         'window-status-activity-style:style of status bar activity tag'
  1535.         'window-status-bell-style:style of status bar bell tag'
  1536.         'window-status-current-format:set status line format for active window'
  1537.         'window-status-current-style:style of current window in status bar'
  1538.         'window-status-format:set status line format for all but the active window'
  1539.         'window-status-last-style:style of last window in status bar'
  1540.         'window-status-separator:separator drawn between windows in status line'
  1541.         'window-status-style:general status bar style'
  1542.         'window-style:style of window'
  1543.         'wrap-search:search wrap around at the end of a pane'
  1544.         'xterm-keys:generate xterm-style function key sequences'
  1545.     )
  1546.     _describe -t tmux-window-options 'tmux window option' tmux_window_options
  1547. }
  1548.  
  1549. function __tmux-windows() {
  1550.     local expl
  1551.     local -a wins opts
  1552.  
  1553.     compset -P '*:'
  1554.     if [[ -n ${IPREFIX} ]]; then
  1555.         opts=( -t "${IPREFIX%:}" )
  1556.     else
  1557.         opts=( )
  1558.     fi
  1559.     wins=( ${${(M)${(f)"$(command tmux 2> /dev/null list-windows "${opts[@]}")"}:#<->*}/:[ $'\t']##/:} )
  1560.     _describe -t windows 'windows' wins "$@"
  1561.     if [[ ${IPREFIX} != *: ]]; then
  1562.         _wanted sessions expl 'sessions' __tmux-sessions -S:
  1563.     fi
  1564. }
  1565.  
  1566. # And here is the actual _tmux(), that puts it all together:
  1567. function _tmux() {
  1568.     local curcontext="${curcontext}"
  1569.     local mode state ret=1
  1570.     local -a args
  1571.     local tmuxcommand
  1572.     local tmux_describe=
  1573.  
  1574.     args=(
  1575.         '-2[force using 256 colours]'
  1576.         '-8[force using 88 colours]'
  1577.         '-c[execute a shell command]:command name:_command_names'
  1578.         '-C[start tmux in control mode. -CC disables echo]'
  1579.         '-f[specify configuration file]:tmux config file:_files -g "*(-.)"'
  1580.         '-l[behave like a login shell]'
  1581.         '-L[specify socket name]:socket name:__tmux-socket-name'
  1582.         '-S[specify socket path]:server socket:_path_files -g "*(=,/)"'
  1583.         '-u[force using UTF-8]'
  1584.         '-v[request verbose logging]'
  1585.         '-V[report tmux version]'
  1586.         '*:: :->subcommand_or_options'
  1587.     )
  1588.     _arguments -C -s -w ${args} && ret=0
  1589.  
  1590.     if [[ ${state} == "subcommand_or_options" ]]; then
  1591.         if (( CURRENT == 1 )) ; then
  1592.             zstyle -s ":completion:${curcontext}:subcommands" mode mode || mode='both'
  1593.             if [[ ${mode} == 'commands' ]]; then
  1594.                 _describe -t subcommands 'tmux commands' _tmux_commands && ret=0
  1595.             elif [[ ${mode} == 'aliases' ]]; then
  1596.                 _describe -t subcommands 'tmux aliases' _tmux_aliases && ret=0
  1597.             else
  1598.                 _describe -t subcommands 'tmux commands and aliases' _tmux_commands -- _tmux_aliases && ret=0
  1599.             fi
  1600.         else
  1601.             if (( ${+commands[tmux]} == 0 )); then
  1602.                 _message '`tmux'\'' not found in $path; sub-cmd completions disabled.'
  1603.                 return
  1604.             fi
  1605.             tmuxcommand="${words[1]}"
  1606.             if [[ -n ${_tmux_aliasmap[$tmuxcommand]} ]] ; then
  1607.                 tmuxcommand="${_tmux_aliasmap[$tmuxcommand]}"
  1608.             fi
  1609.             if ! (( ${+functions[_tmux-$tmuxcommand]} )); then
  1610.               local low high
  1611.               low=$_tmux_commands[(i)$tmuxcommand*]
  1612.               high=$_tmux_commands[(I)$tmuxcommand*]
  1613.               if (( low == high )); then
  1614.                 tmuxcommand=${_tmux_commands[low]%%:*}
  1615.               elif (( low < high )); then
  1616.                 _message -e "Ambiguous command $tmuxcommand"
  1617.               else
  1618.                 _message -e "Subcommand $tmuxcommand not known"
  1619.               fi
  1620.             fi
  1621.             curcontext="${curcontext%:*:*}:tmux-${tmuxcommand}:"
  1622.             _call_function ret _tmux-${tmuxcommand}
  1623.         fi
  1624.     fi
  1625.     return ret
  1626. }
  1627.  
  1628. # description generation follows; only done on 1st _tmux call.
  1629. local f desc
  1630. local -A rev
  1631. local tmux_describe
  1632. tmux_describe='yes, please'
  1633. for f in ${(k)_tmux_aliasmap} ; do
  1634.     rev+=( ${_tmux_aliasmap[$f]} $f )
  1635. done
  1636. for f in ${(M)${(k)functions}:#_tmux-*} ; do
  1637.     desc="$($f)"
  1638.     _tmux_commands+=( "${f#_tmux-}${desc:+:$desc}" )
  1639.     [[ -n ${rev[${f#_tmux-}]} ]] && _tmux_aliases+=( "${rev[${f#_tmux-}]}${desc:+:$desc}" )
  1640. done
  1641.  
  1642. _tmux "$@"
Advertisement
Add Comment
Please, Sign In to add comment