summary refs log tree commit diff
path: root/Completion/Unix/Command/_luarocks
blob: 363cedc8dabda08fa9b7fa0087fc30cf265471c3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
#compdef luarocks

# Start of options' arguments' helpers
(( $+functions[__luarocks_command] )) ||
__luarocks_command(){
  local -a commands=(
    build:'build/compile a rock'
    config:'query information about the LuaRocks configuration'
    doc:'show documentation for an installed rock'
    download:'download a specific rock file from a rocks server'
    help:'help on commands'
    install:'install a rock'
    lint:'check syntax of a rockspec'
    list:'list currently installed rocks'
    make:'compile package in current directory using a rockspec'
    new_version:'auto-write a rockspec for a new version of a rock'
    pack:'create a rock, packing sources or binaries'
    path:'return the currently configured package path'
    purge:'remove all installed rocks from a tree'
    remove:'uninstall a rock'
    search:'query the LuaRocks servers'
    show:'show information about an installed rock'
    unpack:'unpack the contents of a rock'
    upload:'upload a rockspec to the public rocks repository'
    write_rockspec:'write a template for a rockspec file'
  )
  _describe -t commands 'command' commands "$@"
}
local option_deps_modes='--deps-mode=[specify how to handle dependencies]:mode:__luarocks_deps_modes'
(( $+functions[__luarocks_deps_modes] )) ||
__luarocks_deps_modes(){
  local modes=(
    'all:use all trees from the rocks_trees list for finding dependencies'
    'one:use only the current tree (possibly set with --tree)'
    'order:use trees based on order (use the current tree and all trees below it on the rocks_trees list)'
    'none:ignore dependencies altogether'
  )
  _describe 'dependencies mode' modes
}
(( $+functions[__luarocks_rock_version] )) ||
__luarocks_rock_version(){
  local i=2
  while [[ -n "${words[$i]}" ]]; do
    if [[ ! "${words[$i]}" =~ '^-' ]]; then
      case "$1" in
        "external_or_local")
          if [[ ! -f "${words[$i]}" ]]; then
            _message -e "version for external rock ${words[$i]}"
            return
          else
            _message -e "version for local rock ${words[$i]}"
          fi
          ;;
        "installed")
          # TODO: actually complete versions of installed rocks using the cache
          # How does luarocks handles multiple versions of the same package?
          # If anybody knows, please write something beautiful here
          tree="$2"
          if [[ -z "${tree}" ]]; then
            _message -e "version for installed rock ${words[$i]}"
          else
            _message -e "version for installed rock ${words[$i]} on tree ${tree}"
          fi
          return
          ;;
        "new_version")
          if [[ -f "${words[$i]}" ]]; then
            _message -e "new version for rock ${words[$i]}"
            return
          fi
          ;;
        "new_rock")
          _message -e "version for new rock ${words[$i]}"
          return
          ;;
      esac
    fi
    i=$(( i + 1 ))
  done
}
(( $+functions[__luarocks_lua_versions] )) ||
__luarocks_lua_versions(){
  _values -s , 5.3 5.2 5.1
}
(( $+functions[___luarocks_manually_store_cache_configs_paths] )) ||
___luarocks_manually_store_cache_configs_paths(){
  user_config_path="$(_call_program user_config_path luarocks config --user-config)"
  system_config_path="$(_call_program system_config_path luarocks config --system-config)"
  {
    print -r user_config_path=${(qq)user_config_path}
    print -r system_config_path=${(qq)system_config_path}
  } >! ${cache_dir}/luarocks_configs_paths
}
(( $+functions[___luarocks_manually_store_cache_configured_values] )) ||
___luarocks_manually_store_cache_configured_values(){
  local default_trees=($(_call_program rock_trees luarocks config --rock-trees))
  # The following command usually gives somethins like this
  #
  #   /home/me/.luarocks	user
  #   /usr	system
  #
  # We'll just use the 1st and 3rd elements in the array for the default trees
  configured_user_tree="${default_trees[1]}"
  configured_system_tree="${default_trees[3]}"
  configured_lua_version="$(_call_program lua_ver luarocks config --lua-ver)"
  {
    print -r configured_lua_version=${(qq)configured_lua_version}
    print -r configured_user_tree=${(qq)configured_user_tree}
    print -r configured_system_tree=${(qq)configured_system_tree}
  } >! ${cache_dir}/luarocks_configured_values
}
(( $+functions[___luarocks_installed_rocks_cache_policy] )) ||
___luarocks_installed_rocks_cache_policy(){
  local cache_file="$1"
  # Before checking the modification date of the manifests files vs the
  # installed rocks cache files, we need to perform the following checks:
  # - luarocks executable modification date vs modification date of cache file
  #   holding the default configuration files' locations
  # ) if configuration files' locations were possibly changed, we need to:
  #   * set and cache the *possibly* new locations of the configuration files
  # ) else:
  #   * retrieve from cache the configuration files' locations
  # ) end if
  # - configuration files' modification date vs modification date of cache file
  #   holding the values from `luarocks config --lua-ver` and `luarocks config
  #   --rock-trees`
  # ) if the configuration files' locations were changed:
  #   * set and cache the values from the commands above
  # ) else:
  #   ) if configuration files are newer:
  #     * set and cache the values from the commands above
  #   ) else:
  #     * retrive from cache the values of the commands above
  #   ) end if
  # ) end if

  # Decide which directory to retrieve cache from, and ensure it exists
  local cache_dir
  zstyle -s ":completion:${curcontext}:" cache-path cache_dir
  : ${cache_dir:=${ZDOTDIR:-$HOME}/.zcompcache}
  if [[ ! -d "$cache_dir" ]]; then
    [[ -e "$cache_dir" ]] &&
      _message "cache-dir ($cache_dir) isn't a directory\!"
  fi
  local where_luarocks="${commands[luarocks]}"
  # luarocks_configured_values
  local configured_lua_version configured_user_tree configured_system_tree
  # luarocks_configs_paths
  local user_config_path system_config_path
  if [[ -e ${cache_dir}/luarocks_configs_paths ]]; then
    if [[ ${where_luarocks} -nt ${cache_dir}/luarocks_configs_paths ]]; then
      ___luarocks_manually_store_cache_configs_paths
    else
      . ${cache_dir}/luarocks_configs_paths
    fi
  else
    ___luarocks_manually_store_cache_configs_paths
  fi
  if [[ -e ${cache_dir}/luarocks_configured_values ]]; then
    if [[ ${user_config_path} -nt ${cache_dir}/luarocks_configured_values ]] || [[ ${system_config_path} -nt ${cache_dir}/luarocks_configured_values ]]; then
      ___luarocks_manually_store_cache_configured_values
    else
      . ${cache_dir}/luarocks_configured_values
    fi
  else
    ___luarocks_manually_store_cache_configured_values
  fi

  local user_manifest_file="${configured_user_tree}/lib/luarocks/rocks-${configured_lua_version}/manifest"
  local system_manifest_file="${configured_system_tree}/lib/luarocks/rocks-${configured_lua_version}/manifest"
  local cache_status=1
  if [[ -f ${cache_file} ]]; then
    if [[ -f ${user_manifest_file} ]]; then
      if [[ ${user_manifest_file} -nt ${cache_file} ]]; then
        cache_status=0
      fi
    fi
    if [[ -f ${system_manifest_file} ]]; then
      if [[ ${system_manifest_file} -nt ${cache_file} ]]; then
        cache_status=0
      fi
    fi
  fi
  return cache_status
}
(( $+functions[__luarocks_installed_rocks] )) ||
__luarocks_installed_rocks(){
  # This function optionally recieves one argument of the tree in which
  # installed rocks are searched for. If this argument is used, the installed
  # rocks which will be completed by this function will not use the cache which
  # is valid only for installed rocks on default trees like /usr/lib/luarocks
  # and ~/.luarocks
  local tree="$1"
  if [[ -z ${tree} ]]; then
    local update_policy
    zstyle -s ":completion:${curcontext}:" cache-policy update_policy
    if [[ -z "$update_policy" ]]; then
      zstyle ":completion:${curcontext}:" cache-policy ___luarocks_installed_rocks_cache_policy
    fi
    if _cache_invalid luarocks_installed_list; then
      rocks_list=($(luarocks list --porcelain))
      _store_cache luarocks_installed_list rocks_list
    else
      _retrieve_cache luarocks_installed_list
    fi
    if [[ -z ${rocks_list} ]]; then
      _message -r "no installed rocks"
      return
    fi
    if _cache_invalid luarocks_installed_names; then
      rocks_names=()
      for i in {1.."${#rocks_list[@]}"..4}; do
        rocks_names+=("${rocks_list[$i]}")
      done
      _store_cache luarocks_installed_names rocks_names
    else
      _retrieve_cache luarocks_installed_names
    fi
    if _cache_invalid luarocks_installed_versions; then
      rocks_versions=()
      for i in {2.."${#rocks_list[@]}"..4}; do
        rocks_versions+=("${rocks_list[$i]}")
      done
      _store_cache luarocks_installed_versions rocks_versions
    else
      _retrieve_cache luarocks_installed_versions
    fi
    if _cache_invalid luarocks_installed_descriptions; then
      rocks_descriptions=()
      for i in {1.."${#rocks_names[@]}"}; do
        name_version_description="$(luarocks show ${rocks_names[$i]} 2>/dev/null | head -2 | tail -1)"
        total_length=${#name_version_description}
        garbage_length="$((${#rocks_names[$i]} + ${#rocks_versions[$i]} + 5))"
        description="${name_version_description[${garbage_length},${total_length}]}"
        rocks_descriptions+=("${description}")
      done
      _store_cache luarocks_installed_descriptions rocks_descriptions
    else
      _retrieve_cache luarocks_installed_descriptions
    fi
    if _cache_invalid luarocks_installed_names_and_descriptions; then
      rocks_names_and_descriptions=()
      for i in {1.."${#rocks_names[@]}"}; do
        name_and_description=${rocks_names[$i]}:${rocks_descriptions[$i]}
        rocks_names_and_descriptions+=(${name_and_description})
      done
    else
      _store_cache luarocks_installed_names_and_descriptions rocks_names_and_descriptions
    fi
  else
    rocks_list=($(luarocks --tree="${tree}" list --porcelain 2> /dev/null))
    if [[ -z ${rocks_list} ]]; then
      _message "no installed rocks in the specified tree"
      return
    fi
    rocks_names=()
    for i in {1.."${#rocks_list[@]}"..4}; do
      rocks_names+=("${rocks_list[$i]}")
    done
    rocks_versions=()
    for i in {2.."${#rocks_list[@]}"..4}; do
      rocks_versions+=("${rocks_list[$i]}")
    done
    rocks_descriptions=()
    for i in {1.."${#rocks_names[@]}"}; do
      name_version_description="$(luarocks show ${rocks_names[$i]} 2> /dev/null | head -2 | tail -1)"
      total_length=${#name_version_description}
      garbage_length="$((${#rocks_names[$i]} + ${#rocks_versions[$i]} + 5))"
      description="${name_version_description[${garbage_length},${total_length}]}"
      rocks_descriptions+=("${description}")
    done
    rocks_names_and_descriptions=()
    for i in {1.."${#rocks_names[@]}"}; do
      name_and_description=${rocks_names[$i]}:${rocks_descriptions[$i]}
      rocks_names_and_descriptions+=(${name_and_description})
    done
  fi
  _describe 'installed rocks' rocks_names_and_descriptions
}
# Used to complete one or more of the followings:
# - .rockspec file
# - .src.rock file
# - external rock
(( $+functions[__luarocks_rock] )) ||
__luarocks_rock(){
  local -a alts=()
  while [[ $# -gt 0 ]]; do
    arg="$1"
    case "$arg" in
      (rockspec)
        alts+=('files:rock file:_files -g "*.rockspec(-.)"')
        shift 1
        continue
        ;;
      (rockpack)
        alts+=(':rock file:{_files -g "*.src.rock(-.)"}')
        shift 1
        continue
        ;;
      (external)
        alts+=(':external rock:')
        shift 1
        continue
        ;;
      (installed)
        tree="$2"
        alts+=(":local rock:{__luarocks_installed_rocks ${tree}}")
        if [[ -z "${tree}" ]]; then
          shift
        else
          shift 2
        fi
        continue
        ;;
    esac
    shift
    continue
  done
  _alternative ${alts[@]}
}
(( $+functions[__luarocks_git_tags] )) ||
__luarocks_git_tags(){
  # Copied straight from definition of _git
  local expl
  declare -a tags
  tags=(${${(f)"$(_call_program tagrefs git for-each-ref --format='"%(refname)"' refs/tags 2>/dev/null)"}#refs/tags/})
  __git_command_successful $pipestatus || return 1
  _wanted tags expl tag compadd -M 'r:|/=**' "$@" -a - tags
}

# End of options' arguments' helpers & Start of sub commands helpers

# arguments:
# - must: .rockspec file / external rock
# - optional: version (only when chossing external rock)
local make_command_options=(
  '--pack-binary-rock[produce a .rock file with the contents of compilation inside the current directory instead of installing it]'
  '--keep[do not remove previously installed versions of the rock after building a new one]'
  '--branch=[override the `source.branch` field in the loaded rockspec]:NAME:{_message "branch name"}'
)
local build_command_options=(
  "${make_command_options[@]}"
  '--only-deps[installs only the dependencies of the rock]'
  $option_deps_modes
)
(( $+functions[_luarocks_build] )) ||
_luarocks_build(){
  _arguments -A "-*" \
    "${build_command_options[@]}" \
    '1: :{__luarocks_rock "rockspec" "external"}' \
    '2:: :{__luarocks_rock_version "external_or_local"}'
}
# arguments:
# - must: option
local config_command_options=(
  '--lua-incdir[path to Lua header files]'
  '--lua-libdir[path to Lua library files]'
  '--lua-ver[lua version (in major.minor format)]'
  '--system-config[location of the system config file]'
  '--user-config[location of the user config file]'
  '--rock-trees[rocks trees in useFirst the user tree, then the system tree]'
)
(( $+functions[_luarocks_config] )) ||
_luarocks_config(){
  _arguments "${config_command_options[@]}"
}
# arguments:
# - must: installed rock
local doc_command_options=(
  '--home[open the home page of project]'
  '--list[list documentation files only]'
)
(( $+functions[_luarocks_doc] )) ||
_luarocks_doc(){
  _arguments \
    "${doc_command_options[@]}" \
    '1: :{__luarocks_rock "installed" '"${opt_args[--tree]}"'}'
}
# arguments:
# - must: external only rockspec
local download_command_options=(
  '--all[download all files if there are multiple matches]'
  '--source[download .src.rock if available]'
  '--rockspec[download .rockspec if available]'
  '--arch=[download rock for a specific architecture]:ARCH:'
)
(( $+functions[_luarocks_download] )) ||
_luarocks_download(){
  _arguments -A "-*" \
    "${download_command_options[@]}" \
    '1: :{__luarocks_rock "external"}' \
    '2:: :{__luarocks_rock_version "external_or_local"}'
}
# arguments:
# must: luarocks sub command
(( $+functions[_luarocks_help] )) ||
_luarocks_help(){
  _arguments '1: :__luarocks_command'
}
# arguments:
# - must: .rockspec file / external rock
# - optional: version
# NOTE: it receives the same argument as the build command and it accepts the same options as well
(( $+functions[_luarocks_install] )) ||
_luarocks_install(){
  _luarocks_build
}
# arguments:
# - must: rockspec file (first and last)
(( $+functions[_luarocks_lint] )) ||
_luarocks_lint(){
  _arguments '1:: :{__luarocks_rock "rockspec"}'
}
# arguments:
# NOTE: receives only options
local list_command_options=(
  '--outdated[list only rocks for which there is a higher version available in the rocks server]'
  '--porcelain[produce machine-friendly output]'
)
(( $+functions[_luarocks_list] )) ||
_luarocks_list(){
  _arguments "${list_command_options[@]}"
}
# arguments:
# - optional: rockspec file
# NOTE: it's options were already described above.
(( $+functions[_luarocks_make] )) ||
_luarocks_make(){
  _arguments '1:: :{__luarocks_rock "rockspec"}'
}
# arguments:
# - optional: .rockspec file / external rock
# - optional: version (unless a --tag was given)
# - optional: URL
local new_version_command_options=(
  '--tag=[if no version is specified, this option'"'"'s argument is used instead]:tag:__luarocks_git_tags'
)
(( $+functions[_luarocks_new_version] )) ||
_luarocks_new_version(){
  _arguments -A "-*" \
    "${new_version_command_options[@]}" \
    '1:: :{__luarocks_rock "external" "rockspec"}' \
    '2:: :{__luarocks_rock_version "external_or_local"}' \
    '3:: :_urls'
}
# arguments:
# - must: .rockspec file / external rock
# - optional: version
(( $+functions[_luarocks_pack] )) ||
_luarocks_pack(){
  _luarocks_build
}
# arguments:
# NOTE: receives only options
local path_command_options=(
  '--bin[adds the system path to the output]'
  '--append[appends the paths to the existing paths]'
  '--lr-path[exports the Lua path (not formatted as shell command)]'
  '--lr-cpath[exports the Lua cpath (not formatted as shell command)]'
  '--lr-bin[exports the system path (not formatted as shell command)]'
)
(( $+functions[_luarocks_path] )) ||
_luarocks_path(){
  _arguments "${path_command_options[@]}"
}
# NOTE: receives only options yet --tree is mandatory
# NOTE: --force can be used only in conjunction with --old-versions
local option_force='--force[force removing old versions when]'
local purge_command_options=(
  '--old-versions[keep the highest-numbered version of each rock and remove the other ones]'
  $option_force
)
(( $+functions[_luarocks_purge] )) ||
_luarocks_purge(){
  _arguments "${purge_command_options[@]}"
}
# arguments:
# - must: locally installed rock
# - optional: version
local option_force_fast='--force-fast[works like --force but doesn'"'"'t reports forced removals]'
local remove_command_options=(
  $option_deps_modes
  $option_force
  $option_force_fast
)
(( $+functions[_luarocks_remove] )) ||
_luarocks_remove(){
  _arguments -A "-*" \
    "${remove_command_options[@]}" \
    '1: :{__luarocks_rock "installed" '"${opt_args[--tree]}"'}' \
    '2:: :{__luarocks_rock_version "installed" '"${opt_args[--tree]}"'}'
}
# arguments:
# - must: string as a search query
local search_command_options=(
  '--source[return only rockspecs and source rocks]'
  '--binary[return only pure Lua and binary rocks (rocks that can be used with the "install" command without requiring a C toolchain)]'
  '--all[list all contents of the server that are suitable to this platform, do not filter by name]'
)
(( $+functions[_luarocks_search] )) ||
_luarocks_search(){
  _arguments \
    "${search_command_options[@]}" \
    '*:SEARCH QUERY:'
}
# arguments:
# - must: installed rock
local show_command_options=(
  '--home[home page of project]'
  '--modules[all modules provided by this package as used by require()]'
  '--deps[packages this package depends on]'
  '--rockspec[the full path of the rockspec file]'
  '--mversion[the package version]'
  '--rock-tree[local tree where rock is installed]'
  '--rock-dir[data directory of the installed rock]'
)
(( $+functions[_luarocks_show] )) ||
_luarocks_show(){
  _arguments \
    "${show_command_options[@]}" \
    "1: :{__luarocks_rock 'installed' "${opt_args[--tree]}"}"
}
# arguments:
# - must: rockpack file / external rock
# - optional: version (only when chossing external rock)
local unpack_command_options=(
  '--force[unpack files even if the output directory already exists]'
)
(( $+functions[_luarocks_unpack] )) ||
_luarocks_unpack(){
  _arguments \
    "${unpack_command_options[@]}" \
    '1: :{__luarocks_rock "rockpack" "external"}'
}
# arguments:
# - must: rockspec file
local upload_command_options=(
  '--skip-pack[do not pack and send source rock]'
  '--api-key=[give it an API key]:KEY:{_message "api key"}'
  '--force[replace existing rockspec if the same revision of a module already exists]'
)
(( $+functions[_luarocks_upload] )) ||
_luarocks_upload(){
  _arguments \
    "${upload_command_options[@]}" \
    '1: :{__luarocks_rock "rockspec"}'
}
# arguments:
# - optional: name
# - optional: version
# - optional: URL / PATH
# receives as an argument a name and a version with optionally a URL/PATH
local write_rockspec_command_options=(
  '--output=[write the rockspec with the given filename]:FILE:_files'
  '--license=[specify a license string]:license (e.g. "MIT/X11" or "GNU GPL v3")'
  '--summary=[a short one-line description summary]:summary:{_message -e "short summary of the rock"}'
  '--detailed=[a longer description string]:detailed_text:{_message -e "detailed description of the rock"}'
  '--homepage=[project homepage]:URL:_urls'
  '--lua-version=[supported Lua versions]:LUA_VER:__luarocks_lua_versions'
  '--rockspec-format=[rockspec format version, such as "1.0" or "1.1"]:VER: '
  '--tag=[tag to use. Will attempt to extract version number from it]:tag:__git_tag'
  '--lib=[comma separated list of C library files to link to]:library files'
)
(( $+functions[_luarocks_write_rockspec] )) ||
_luarocks_write_rockspec(){
  _arguments -A "-*" \
    "${write_rockspec_command_options[@]}" \
    '1:: :{_message "new rock name"}' \
    '2:: :{__luarocks_rock_version "new_rock"}' \
    '3:: :_urls'
}

# The real thing
_arguments -C \
  '(--server --only-server)--server=[fetch rocks/rockspecs from this server]:HOST:_hosts' \
  '(--server --only-server)--only-server=[fetch rocks/rockspecs from this server only]:HOST:_hosts' \
  '--only-sources=[restrict downloads to paths matching the given URL]:URL:_urls' \
  '--tree=[which tree to operate on]:TREE:{_files -/}' \
  '--local[use the tree in the user'"'"'s home directory]' \
  '--verbose[display verbose output of commands executed]' \
  '--timeout=[timeout on network operations]:SECONDS:{_message "timeout (seconds)"}' \
  '1: :__luarocks_command' \
  '*::arg:->args'

case "$state" in
  (args)
    curcontext="${curcontext%:*:*}:luarocks-${words[1]}:"
    if [[ $? != 1 ]]; then
      _call_function ret _luarocks_${words[1]}
    fi
esac