#compdef nikola

_nikola() {
    local -a commands tasks
    # format is 'completion:description'
    commands=(
        'auto: builds and serves a site; automatically detects site changes, rebuilds, and optionally refreshes a browser'
        'bootswatch_theme: given a swatch name from bootswatch.com and a parent theme, creates a custom theme'
        'build: run tasks'
        'check: check links and files in the generated site'
        'clean: clean action / remove targets'
        'console: start an interactive Python console with access to your site'
        'deploy: deploy the site'
        'doit_auto: automatically execute tasks when a dependency changes'
        'dumpdb: dump dependency DB'
        'forget: clear successful run status from internal DB'
        'github_deploy: deploy the site to GitHub Pages'
        'help: show help'
        'ignore: ignore task (skip) on subsequent runs'
        'import_wordpress: import a WordPress dump'
        'info: show info about a task'
        'init: create a Nikola site in the specified folder'
        'install_theme: install theme into current site'
        'list: list tasks from dodo file'
        'new_page: create a new page in the site'
        'new_post: create a new blog post or site page'
        'orphans: list all orphans'
        'plugin: manage plugins'
        'reset-dep: recompute and save the state of file dependencies without executing actions'
        'rst2html: compile reStructuredText to HTML files'
        'run: run tasks'
        'serve: start the test webserver'
        'status: display site status'
        'strace: use strace to list file_deps and targets'
        'tabcompletion: generate script for tab-completion'
        'version: print the Nikola version number'
    )

    # split output by lines to create an array
    tasks=(
'copy_assets: Copy theme assets into output.'
'render_posts: Build HTML fragments from metadata and text.'
'render_pages: Render pages into output.'
'render_archive: Render the post archives.'
'redirect: Generate redirections.'
'generate_rss: Generate RSS feeds.'
'render_galleries: Render image galleries.'
'scale_images: Resize images and create thumbnails for them.'
'render_indexes: Render the blog indexes.'
'render_tags: Render the tag/category pages and feeds.'
'copy_files: Copy static files into the output folder.'
'render_sources: Copy page sources into the output.'
'render_listings: Render code listings.'
'render_site: Group of tasks to render the site.'
'create_bundles: Bundle assets using WebAssets.'
'robots_file: Generate a robots.txt file.'
'_scan_locs: '
'sitemap: Generate a sitemap.'
'post_render: Group of tasks to be executed after site is rendered.'
)

    # complete command or task name
    if (( CURRENT == 2 )); then
        _arguments -A : '::cmd:(($commands))' '::task:(($tasks))'
        return
    fi

    # revome program name from $words and decrement CURRENT
    local curcontext context state state_desc line
    _arguments -C '*:: :->'

    # complete sub-command or task options
    local -a _command_args
    case "$words[1]" in
        
      (auto)
          _command_args=(
            '(-p|--port)'{-p,--port}'[Port nummber (default: 8000)]' \
            '(-a|--address)'{-a,--address}'[Address to bind (default: 127.0.0.1 – localhost)]' \
            '(-b|--browser)'{-b,--browser}'[Start a web browser]' \
            '(-6|--ipv6)'{-6,--ipv6}'[Use IPv6]' \
            '--no-server[Disable the server, automate rebuilds only]' \
            ''
        )
      ;;


      (bootswatch_theme)
          _command_args=(
            '(-n|--name)'{-n,--name}'[New theme name (default: custom)]' \
            '-s[Name of the swatch from bootswatch.com.]' \
            '(-p|--parent)'{-p,--parent}'[Parent theme name (default: bootstrap3)]' \
            ''
        )
      ;;


      (build)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            '--backend[Select dependency file backend. [default: %(default)s\]]' \
            '--check_file_uptodate[Choose how to check if files have been modified. Available options [default: %(default)s\]:   'md5': use the md5sum   'timestamp': use the timestamp ]' \
            '(-a|--always-execute)'{-a,--always-execute}'[always execute tasks even if up-to-date [default: %(default)s\]]' \
            '(-c|--continue)'{-c,--continue}'[continue executing tasks even after a failure [default: %(default)s\]]' \
            '(-v|--verbosity)'{-v,--verbosity}'[0 capture (do not print) stdout/stderr from task. 1 capture stdout only. 2 do not capture anything (print everything immediately). [default: 1\]]' \
            '(-r|--reporter)'{-r,--reporter}'[Choose output reporter. [default: %(default)s\]]' \
            '(-o|--output-file)'{-o,--output-file}'[write output into file [default: stdout\]]' \
            '(-n|--process)'{-n,--process}'[number of subprocesses [default: %(default)s\]]' \
            '(-P|--parallel-type)'{-P,--parallel-type}'[Tasks can be executed in parallel in different ways: 'process': uses python multiprocessing module 'thread': uses threads [default: %(default)s\] ]' \
            '--pdb[get into PDB (python debugger) post-mortem in case of unhandled exception]' \
            '(-s|--single)'{-s,--single}'[Execute only specified tasks ignoring their task_dep [default: %(default)s\]]' \
            '--strict[Fail on things that would normally be warnings.]' \
            '--invariant[Generate invariant output (for testing only!).]' \
            '(-q|--quiet)'{-q,--quiet}'[Run quietly.]' \
            '*::task:(($tasks))'
            ''
        )
      ;;


      (check)
          _command_args=(
            '(-l|--check-links)'{-l,--check-links}'[Check for dangling links]' \
            '(-f|--check-files)'{-f,--check-files}'[Check for unknown (orphaned and not generated) files]' \
            '--clean-files[Remove all unknown files, use with caution]' \
            '--find-sources[List possible source files for files with broken links.]' \
            '(-v|--verbose)'{-v,--verbose}'[Be more verbose.]' \
            '(-r|--remote)'{-r,--remote}'[Check that remote links work.]' \
            ''
        )
      ;;


      (clean)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            '--backend[Select dependency file backend. [default: %(default)s\]]' \
            '--check_file_uptodate[Choose how to check if files have been modified. Available options [default: %(default)s\]:   'md5': use the md5sum   'timestamp': use the timestamp ]' \
            '(-c|--clean-dep)'{-c,--clean-dep}'[clean task dependencies too]' \
            '(-a|--clean-all)'{-a,--clean-all}'[clean all task]' \
            '(-n|--dry-run)'{-n,--dry-run}'[print actions without really executing them]' \
            '*::task:(($tasks))'
            ''
        )
      ;;


      (console)
          _command_args=(
            '(-b|--bpython)'{-b,--bpython}'[Use bpython]' \
            '(-i|--plain)'{-i,--plain}'[Use IPython]' \
            '(-p|--plain)'{-p,--plain}'[Use the plain Python interpreter]' \
            ''
        )
      ;;


      (deploy)
          _command_args=(
            
            ''
        )
      ;;


      (doit_auto)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            '--backend[Select dependency file backend. [default: %(default)s\]]' \
            '--check_file_uptodate[Choose how to check if files have been modified. Available options [default: %(default)s\]:   'md5': use the md5sum   'timestamp': use the timestamp ]' \
            '(-v|--verbosity)'{-v,--verbosity}'[0 capture (do not print) stdout/stderr from task. 1 capture stdout only. 2 do not capture anything (print everything immediately). [default: 1\]]' \
            
            '*::task:(($tasks))'
            ''
        )
      ;;


      (dumpdb)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            ''
        )
      ;;


      (forget)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            '--backend[Select dependency file backend. [default: %(default)s\]]' \
            '--check_file_uptodate[Choose how to check if files have been modified. Available options [default: %(default)s\]:   'md5': use the md5sum   'timestamp': use the timestamp ]' \
            '(-s|--follow-sub)'{-s,--follow-sub}'[forget task dependencies too]' \
            '*::task:(($tasks))'
            ''
        )
      ;;


      (github_deploy)
          _command_args=(
            
            ''
        )
      ;;


      (help)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            '--backend[Select dependency file backend. [default: %(default)s\]]' \
            '--check_file_uptodate[Choose how to check if files have been modified. Available options [default: %(default)s\]:   'md5': use the md5sum   'timestamp': use the timestamp ]' \
            '*::task:(($tasks))'
            '::cmd:(($commands))'
            ''
        )
      ;;


      (ignore)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            '--backend[Select dependency file backend. [default: %(default)s\]]' \
            '--check_file_uptodate[Choose how to check if files have been modified. Available options [default: %(default)s\]:   'md5': use the md5sum   'timestamp': use the timestamp ]' \
            '*::task:(($tasks))'
            ''
        )
      ;;


      (import_wordpress)
          _command_args=(
            '(-o|--output-folder)'{-o,--output-folder}'[Location to write imported content.]' \
            '(-d|--no-drafts)'{-d,--no-drafts}'[Do not import drafts]' \
            '--exclude-privates[Do not import private posts]' \
            '--include-empty-items[Include empty posts and pages]' \
            '--squash-newlines[Shorten multiple newlines in a row to only two newlines]' \
            '--no-downloads[Do not try to download files for the import]' \
            '--download-auth[Specify username and password for HTTP authentication (separated by ':')]' \
            '--qtranslate[Look for translations generated by qtranslate plugin]' \
            '--translations_pattern[The pattern for translation files names]' \
            '--export-categories-as-categories[Export categories as categories, instead of treating them as tags]' \
            '--export-comments[Export comments as .wpcomment files]' \
            '--transform-to-html[Uses WordPress page compiler to transform WordPress posts directly to HTML during import]' \
            '--use-wordpress-compiler[Instead of converting posts to markdown, leave them as is and use the WordPress page compiler]' \
            '--install-wordpress-compiler[Automatically installs the WordPress page compiler (either locally or in the new site) if required by other options. Warning: the compiler is GPL software!]' \
            ''
        )
      ;;


      (info)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            '--backend[Select dependency file backend. [default: %(default)s\]]' \
            '--check_file_uptodate[Choose how to check if files have been modified. Available options [default: %(default)s\]:   'md5': use the md5sum   'timestamp': use the timestamp ]' \
            '*::task:(($tasks))'
            ''
        )
      ;;


      (init)
          _command_args=(
            '(-q|--quiet)'{-q,--quiet}'[Do not ask questions about config.]' \
            '(-d|--demo)'{-d,--demo}'[Create a site filled with example data.]' \
            ''
        )
      ;;


      (install_theme)
          _command_args=(
            '(-l|--list)'{-l,--list}'[Show list of available themes.]' \
            '(-u|--url)'{-u,--url}'[URL for the theme repository (default: https://themes.getnikola.com/v7/themes.json)]' \
            '(-g|--get-path)'{-g,--get-path}'[Print the path for installed theme]' \
            ''
        )
      ;;


      (list)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            '--backend[Select dependency file backend. [default: %(default)s\]]' \
            '--check_file_uptodate[Choose how to check if files have been modified. Available options [default: %(default)s\]:   'md5': use the md5sum   'timestamp': use the timestamp ]' \
            '--all[list include all sub-tasks from dodo file]' \
            '(-q|--quiet)'{-q,--quiet}'[print just task name (less verbose than default)]' \
            '(-s|--status)'{-s,--status}'[print task status (R)un, (U)p-to-date, (I)gnored]' \
            '(-p|--private)'{-p,--private}'[print private tasks (start with '_')]' \
            '--deps[print list of dependencies (file dependencies only)]' \
            '--template[display entries with template]' \
            '*::task:(($tasks))'
            ''
        )
      ;;


      (new_page)
          _command_args=(
            '(-t|--title)'{-t,--title}'[Title for the page.]' \
            '(-a|--author)'{-a,--author}'[Author of the post.]' \
            '-1[Create the page with embedded metadata (single file format)]' \
            '-2[Create the page with separate metadata (two file format)]' \
            '-e[Open the page (and meta file, if any) in $EDITOR after creation.]' \
            '(-f|--format)'{-f,--format}'[Markup format for the page (use --available-formats for list)]' \
            '(-F|--available-formats)'{-F,--available-formats}'[List all available input formats]' \
            '(-i|--import)'{-i,--import}'[Import an existing file instead of creating a placeholder]' \
            ''
        )
      ;;


      (new_post)
          _command_args=(
            '(-p|--page)'{-p,--page}'[Create a page instead of a blog post. (see also: `nikola new_page`)]' \
            '(-t|--title)'{-t,--title}'[Title for the post.]' \
            '(-a|--author)'{-a,--author}'[Author of the post.]' \
            '--tags[Comma-separated tags for the post.]' \
            '-1[Create the post with embedded metadata (single file format)]' \
            '-2[Create the post with separate metadata (two file format)]' \
            '-e[Open the post (and meta file, if any) in $EDITOR after creation.]' \
            '(-f|--format)'{-f,--format}'[Markup format for the post (use --available-formats for list)]' \
            '(-F|--available-formats)'{-F,--available-formats}'[List all available input formats]' \
            '-s[Schedule the post based on recurrence rule]' \
            '(-i|--import)'{-i,--import}'[Import an existing file instead of creating a placeholder]' \
            ''
        )
      ;;


      (orphans)
          _command_args=(
            
            ''
        )
      ;;


      (plugin)
          _command_args=(
            '(-i|--install)'{-i,--install}'[Install a plugin.]' \
            '(-r|--uninstall)'{-r,--uninstall}'[Uninstall a plugin.]' \
            '(-l|--list)'{-l,--list}'[Show list of available plugins.]' \
            '(-u|--url)'{-u,--url}'[URL for the plugin repository (default: https://plugins.getnikola.com/v7/plugins.json)]' \
            '--user[Install user-wide, available for all sites.]' \
            '--upgrade[Upgrade all installed plugins.]' \
            '--list-installed[List the installed plugins with their location.]' \
            ''
        )
      ;;


      (reset-dep)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            '--backend[Select dependency file backend. [default: %(default)s\]]' \
            '--check_file_uptodate[Choose how to check if files have been modified. Available options [default: %(default)s\]:   'md5': use the md5sum   'timestamp': use the timestamp ]' \
            '*::task:(($tasks))'
            ''
        )
      ;;


      (rst2html)
          _command_args=(
            
            ''
        )
      ;;


      (run)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            '--backend[Select dependency file backend. [default: %(default)s\]]' \
            '--check_file_uptodate[Choose how to check if files have been modified. Available options [default: %(default)s\]:   'md5': use the md5sum   'timestamp': use the timestamp ]' \
            '(-a|--always-execute)'{-a,--always-execute}'[always execute tasks even if up-to-date [default: %(default)s\]]' \
            '(-c|--continue)'{-c,--continue}'[continue executing tasks even after a failure [default: %(default)s\]]' \
            '(-v|--verbosity)'{-v,--verbosity}'[0 capture (do not print) stdout/stderr from task. 1 capture stdout only. 2 do not capture anything (print everything immediately). [default: 1\]]' \
            '(-r|--reporter)'{-r,--reporter}'[Choose output reporter. [default: %(default)s\]]' \
            '(-o|--output-file)'{-o,--output-file}'[write output into file [default: stdout\]]' \
            '(-n|--process)'{-n,--process}'[number of subprocesses [default: %(default)s\]]' \
            '(-P|--parallel-type)'{-P,--parallel-type}'[Tasks can be executed in parallel in different ways: 'process': uses python multiprocessing module 'thread': uses threads [default: %(default)s\] ]' \
            '--pdb[get into PDB (python debugger) post-mortem in case of unhandled exception]' \
            '(-s|--single)'{-s,--single}'[Execute only specified tasks ignoring their task_dep [default: %(default)s\]]' \
            '*::task:(($tasks))'
            ''
        )
      ;;


      (serve)
          _command_args=(
            '(-p|--port)'{-p,--port}'[Port number (default: 8000)]' \
            '(-a|--address)'{-a,--address}'[Address to bind (default: 0.0.0.0 – all local IPv4 interfaces)]' \
            '(-d|--detach)'{-d,--detach}'[Detach from TTY (work in the background)]' \
            '(-b|--browser)'{-b,--browser}'[Open the test server in a web browser]' \
            '(-6|--ipv6)'{-6,--ipv6}'[Use IPv6]' \
            ''
        )
      ;;


      (status)
          _command_args=(
            '(-d|--list-drafts)'{-d,--list-drafts}'[List all drafts]' \
            '(-m|--list-modified)'{-m,--list-modified}'[List all modified files since last deployment]' \
            '(-s|--list-scheduled)'{-s,--list-scheduled}'[List all scheduled posts]' \
            ''
        )
      ;;


      (strace)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            '--backend[Select dependency file backend. [default: %(default)s\]]' \
            '--check_file_uptodate[Choose how to check if files have been modified. Available options [default: %(default)s\]:   'md5': use the md5sum   'timestamp': use the timestamp ]' \
            '(-a|--all)'{-a,--all}'[display all files (not only from within CWD path)]' \
            '--keep[save strace command output into strace.txt]' \
            '*::task:(($tasks))'
            ''
        )
      ;;


      (tabcompletion)
          _command_args=(
            '--db-file[file used to save successful runs [default: %(default)s\]]' \
            '--backend[Select dependency file backend. [default: %(default)s\]]' \
            '--check_file_uptodate[Choose how to check if files have been modified. Available options [default: %(default)s\]:   'md5': use the md5sum   'timestamp': use the timestamp ]' \
            '(-s|--shell)'{-s,--shell}'[Completion code for SHELL. [default: %(default)s\]]' \
            '--hardcode-tasks[Hardcode tasks from current task list.]' \
            ''
        )
      ;;


      (version)
          _command_args=(
            '--check[Check for new versions.]' \
            ''
        )
      ;;


        # default completes task names
        (*)
           _command_args='*::task:(($tasks))'
        ;;
    esac

    # -A no options will be completed after the first non-option argument
    _arguments -A : $_command_args
    return 0
}

_nikola
