#compdef ls

autoload -U is-at-least

_ls() {
    typeset -A opt_args
    typeset -a _arguments_options
    local ret=1

    if is-at-least 5.2; then
        _arguments_options=(-s -S -C)
    else
        _arguments_options=(-s -C)
    fi

    local context curcontext="$curcontext" state line
    _arguments "${_arguments_options[@]}" \
'--format=[Set the display format.]: :(long verbose single-column columns vertical across horizontal commas)' \
'-T+[Assume tab stops at each COLS instead of 8 (unimplemented)]:COLS: ' \
'--tabsize=[Assume tab stops at each COLS instead of 8 (unimplemented)]:COLS: ' \
'--hyperlink=[hyperlink file names WHEN]' \
'--quoting-style=[Set quoting style.]: :(literal shell shell-escape shell-always shell-escape-always c escape)' \
'--time=[Show time in <field>\:
	access time (-u)\: atime, access, use;
	change time (-t)\: ctime, status.
	birth time\: birth, creation;]:field:(atime ctime birth)' \
'*--hide=[do not list implied entries matching shell PATTERN (overridden by -a or -A)]:PATTERN: ' \
'*-I+[do not list implied entries matching shell PATTERN]:PATTERN: ' \
'*--ignore=[do not list implied entries matching shell PATTERN]:PATTERN: ' \
'--sort=[Sort by <field>\: name, none (-U), time (-t), size (-S), extension (-X) or width]:field:(name none time size version extension width)' \
'--block-size=[scale sizes by BLOCK_SIZE when printing them]:BLOCK_SIZE: ' \
'-w+[Assume that the terminal is COLS columns wide.]:COLS: ' \
'--width=[Assume that the terminal is COLS columns wide.]:COLS: ' \
'--color=[Color output based on file type.]' \
'--indicator-style=[Append indicator with style WORD to entry names\: none (default),  slash (-p), file-type (--file-type), classify (-F)]: :(none slash file-type classify)' \
'-F+[Append a character to each file name indicating the file type. Also, for regular files that are executable, append '\''*'\''. The file type indicators are '\''/'\'' for directories, '\''@'\'' for symbolic links, '\''|'\'' for FIFOs, '\''='\'' for sockets, '\''>'\'' for doors, and nothing for regular files. when may be omitted, or one of\:
	none - Do not classify. This is the default.
	auto - Only classify if standard output is a terminal.
	always - Always classify.
Specifying --classify and no when is equivalent to --classify=always. This will not follow symbolic links listed on the command line unless the --dereference-command-line (-H), --dereference (-L), or --dereference-command-line-symlink-to-dir options are specified.]' \
'--classify=[Append a character to each file name indicating the file type. Also, for regular files that are executable, append '\''*'\''. The file type indicators are '\''/'\'' for directories, '\''@'\'' for symbolic links, '\''|'\'' for FIFOs, '\''='\'' for sockets, '\''>'\'' for doors, and nothing for regular files. when may be omitted, or one of\:
	none - Do not classify. This is the default.
	auto - Only classify if standard output is a terminal.
	always - Always classify.
Specifying --classify and no when is equivalent to --classify=always. This will not follow symbolic links listed on the command line unless the --dereference-command-line (-H), --dereference (-L), or --dereference-command-line-symlink-to-dir options are specified.]' \
'--time-style=[time/date format with -l; see TIME_STYLE below]:TIME_STYLE: ' \
'--help[Print help information.]' \
'-C[Display the files in columns.]' \
'-l[Display detailed information.]' \
'--long[Display detailed information.]' \
'-x[List entries in rows instead of in columns.]' \
'-m[List entries separated by commas.]' \
'--zero[List entries separated by ASCII NUL characters.]' \
'-D[generate output designed for Emacs'\'' dired (Directory Editor) mode]' \
'--dired[generate output designed for Emacs'\'' dired (Directory Editor) mode]' \
'-1[List one file per line.]' \
'-o[Long format without group information. Identical to --format=long with --no-group.]' \
'-g[Long format without owner information.]' \
'-n[-l with numeric UIDs and GIDs.]' \
'--numeric-uid-gid[-l with numeric UIDs and GIDs.]' \
'-N[Use literal quoting style. Equivalent to \`--quoting-style=literal\`]' \
'--literal[Use literal quoting style. Equivalent to \`--quoting-style=literal\`]' \
'-b[Use escape quoting style. Equivalent to \`--quoting-style=escape\`]' \
'--escape[Use escape quoting style. Equivalent to \`--quoting-style=escape\`]' \
'-Q[Use C quoting style. Equivalent to \`--quoting-style=c\`]' \
'--quote-name[Use C quoting style. Equivalent to \`--quoting-style=c\`]' \
'-q[Replace control characters with '\''?'\'' if they are not escaped.]' \
'--hide-control-chars[Replace control characters with '\''?'\'' if they are not escaped.]' \
'--show-control-chars[Show control characters '\''as is'\'' if they are not escaped.]' \
'-c[If the long listing format (e.g., -l, -o) is being used, print the status change time (the '\''ctime'\'' in the inode) instead of the modification time. When explicitly sorting by time (--sort=time or -t) or when not using a long listing format, sort according to the status change time.]' \
'-u[If the long listing format (e.g., -l, -o) is being used, print the status access time instead of the modification time. When explicitly sorting by time (--sort=time or -t) or when not using a long listing format, sort according to the access time.]' \
'-B[Ignore entries which end with ~.]' \
'--ignore-backups[Ignore entries which end with ~.]' \
'-S[Sort by file size, largest first.]' \
'-t[Sort by modification time (the '\''mtime'\'' in the inode), newest first.]' \
'-v[Natural sort of (version) numbers in the filenames.]' \
'-X[Sort alphabetically by entry extension.]' \
'-U[Do not sort; list the files in whatever order they are stored in the directory.  This is especially useful when listing very large directories, since not doing any sorting can be noticeably faster.]' \
'-L[When showing file information for a symbolic link, show information for the file the link references rather than the link itself.]' \
'--dereference[When showing file information for a symbolic link, show information for the file the link references rather than the link itself.]' \
'--dereference-command-line-symlink-to-dir[Do not follow symlinks except when they link to directories and are given as command line arguments.]' \
'-H[Do not follow symlinks except when given as command line arguments.]' \
'--dereference-command-line[Do not follow symlinks except when given as command line arguments.]' \
'-G[Do not show group in long format.]' \
'--no-group[Do not show group in long format.]' \
'--author[Show author in long format. On the supported platforms, the author always matches the file owner.]' \
'-a[Do not ignore hidden files (files with names that start with '\''.'\'').]' \
'--all[Do not ignore hidden files (files with names that start with '\''.'\'').]' \
'-A[In a directory, do not ignore all file names that start with '\''.'\'', only ignore '\''.'\'' and '\''..'\''.]' \
'--almost-all[In a directory, do not ignore all file names that start with '\''.'\'', only ignore '\''.'\'' and '\''..'\''.]' \
'-d[Only list the names of directories, rather than listing directory contents. This will not follow symbolic links unless one of \`--dereference-command-line (-H)\`, \`--dereference (-L)\`, or \`--dereference-command-line-symlink-to-dir\` is specified.]' \
'--directory[Only list the names of directories, rather than listing directory contents. This will not follow symbolic links unless one of \`--dereference-command-line (-H)\`, \`--dereference (-L)\`, or \`--dereference-command-line-symlink-to-dir\` is specified.]' \
'-h[Print human readable file sizes (e.g. 1K 234M 56G).]' \
'--human-readable[Print human readable file sizes (e.g. 1K 234M 56G).]' \
'-k[default to 1024-byte blocks for file system usage; used only with -s and per directory totals]' \
'--kibibytes[default to 1024-byte blocks for file system usage; used only with -s and per directory totals]' \
'--si[Print human readable file sizes using powers of 1000 instead of 1024.]' \
'-i[print the index number of each file]' \
'--inode[print the index number of each file]' \
'-r[Reverse whatever the sorting method is e.g., list files in reverse alphabetical order, youngest first, smallest first, or whatever.]' \
'--reverse[Reverse whatever the sorting method is e.g., list files in reverse alphabetical order, youngest first, smallest first, or whatever.]' \
'-R[List the contents of all directories recursively.]' \
'--recursive[List the contents of all directories recursively.]' \
'-s[print the allocated size of each file, in blocks]' \
'--size[print the allocated size of each file, in blocks]' \
'--file-type[Same as --classify, but do not append '\''*'\'']' \
'-p[Append / indicator to directories.]' \
'--full-time[like -l --time-style=full-iso]' \
'-Z[print any security context of each file (not enabled)]' \
'--context[print any security context of each file (not enabled)]' \
'--group-directories-first[group directories before files; can be augmented with a --sort option, but any use of --sort=none (-U) disables grouping]' \
'-V[Print version]' \
'--version[Print version]' \
'::paths:_files' \
&& ret=0
}

(( $+functions[_ls_commands] )) ||
_ls_commands() {
    local commands; commands=()
    _describe -t commands 'ls commands' commands "$@"
}

if [ "$funcstack[1]" = "_ls" ]; then
    _ls "$@"
else
    compdef _ls ls
fi
