# (C) 2010 magicant

# Completion script for the "ls" command.
# Supports POSIX 2008, GNU coreutils 8.4, FreeBSD 8.1, OpenBSD 4.8, NetBSD 5.0,
# Mac OS X 10.6.3, SunOS 5.10, HP-UX 11i v3.

function completion/ls {

	case $("${WORDS[1]}" --version 2>/dev/null) in
		(*'coreutils'*) typeset type=GNU ;;
		(*)             typeset type="$(uname 2>/dev/null)" ;;
	esac
	case $type in
		(GNU) typeset long=true ;;
		(*)   typeset long= ;;
	esac

	typeset OPTIONS POSIXOPTIONS ADDOPTIONS ARGOPT PREFIX
	POSIXOPTIONS=( #>#
	"1; print files line by line"
	"A ${long:+--almost-all}; print all files but . and .."
	"a ${long:+--all}; print all files"
	"C; arrange filenames vertically"
	"c; print or sort by last status change time"
	"d ${long:+--directory}; print directory itself, not its contents"
	"F ${long:+--classify}; append symbols indicating file type"
	"f; print all files without sorting"
	"g; like -l but don't print owners"
	"H ${long:+--dereference-command-line}; follow symbolic links in operands"
	"i ${long:+--inode}; print file serial number (inode)"
	"k; print file size in kilobytes"
	"L ${long:+--dereference}; follow all symbolic links"
	"l; print in long format"
	"m; print in stream output format"
	"n ${long:+--numeric-uid-gid}; like -l but print owners and groups in numbers"
	"o; like -l but don't print group"
	"p; append slash to directory names"
	"q ${long:+--hide-control-chars}; print unprintable characters as ?"
	"R ${long:+--recursive}; print subdirectories recursively"
	"r ${long:+--reverse}; sort in reverse order"
	"S; sort by file size"
	"s ${long:+--size}; print block sizes occupied by files"
	"t; sort by last modified time"
	"u; print or sort by last access time"
	"x; arrange filenames horizontally"
	) #<#

	ADDOPTIONS=()
	case $type in (GNU|NetBSD|FreeBSD|Darwin|SunOS|HP-UX)
		ADDOPTIONS=("$ADDOPTIONS" #>#
		"b ${long:+--escape}; escape special characters like C string"
		) #<#
		case $type in (NetBSD|FreeBSD|Darwin)
			ADDOPTIONS=("$ADDOPTIONS" #>#
			"B; escape special characters as backslashed octal value"
			) #<#
		esac
	esac
	case $type in (GNU|*BSD|Darwin|SunOS)
		ADDOPTIONS=("$ADDOPTIONS" #>#
		"h ${long:+--human-readable}; print size using K, M, etc. for 1024^n"
		) #<#
	esac
	case $type in (*BSD|Darwin)
		ADDOPTIONS=("$ADDOPTIONS" #>#
		"T; print time in full (with -l)"
		) #<#
		case $type in (NetBSD|FreeBSD|Darwin)
			ADDOPTIONS=("$ADDOPTIONS" #>#
			"W; show whiteouts when scanning directories"
			"w; don't escape unprintable characters"
			) #<#
			case $type in (FreeBSD|Darwin)
				ADDOPTIONS=("$ADDOPTIONS" #>#
				"G; print filenames in color"
				"P; don't follow symbolic links"
				"U; print or sort by file creation time"
				) #<#
			esac
		esac
	esac
	case $type in
	(GNU)
		ADDOPTIONS=("$ADDOPTIONS" #>#
		"--author; print file authors (with -l)"
		"--block-size:; specify block size"
		"B --ignore-backups; don't print filenames ending with ~"
		"--color::; print filenames in color"
		"D --dired; print in emacs dired format"
		"--file-type; like -F but don't append * to executables"
		"--format:; specify output format"
		"--full-time; like -l --time-style=full-iso"
		"--group-directories-first; print directories before other files"
		"G --no-group; don't print group (with -l)"
		"--si; print size using k, M, etc. for 1000^n"
		"--dereference-command-line-symlink-to-dir; follow symbolic links to directory in operands"
		"--hide:; specify pattern to exclude from listing"
		"--indicator-style:; append symbols indicating file type"
		"I: --ignore:; specify filename pattern to exclude from listing"
		"N --literal; don't quote filenames"
		"Q --quote-name; print filenames in double-quotes"
		"--quoting-style:; specify how to quote filenames"
		"--show-control-chars; print non-graphic characters as is"
		"--sort:; specify sort key"
		"--time:; specify which time to print and sort by"
		"--time-style:; specify format to print time in"
		"T: --tabsize:; specify how many spaces a tab stands for"
		"U; don't sort"
		"v; sort by filename regarding as version number"
		"w: --width:; specify screen width"
		"X; sort by filename extension"
		"--lcontext; print in long format with security context"
		"Z --context; print in simplified long format with security context"
		"--scontext; print security context of files"
		"--help"
		"--version"
		) #<#
		;;
	(FreeBSD)
		ADDOPTIONS=("$ADDOPTIONS" #>#
		"D:; specify format to print time in"
		"I; don't assume -A for superuser"
		"Z; print MAC labels"
		) #<#
		;;
	(Darwin)
		ADDOPTIONS=("$ADDOPTIONS" #>#
		"e; print access control list"
		"O; print file flags (with -l)"
		) #<#
		;;
	(SunOS)
		ADDOPTIONS=("$ADDOPTIONS" #>#
		"E; like -l, with time in ISO 8601 format"
		"e; like -l, with time like Dec 31 13:34:56 1999"
		"V; like -l, with compact access control list info"
		"v; like -l, with verbose access control list info"
		) #<#
		;;
	(HP-UX)
		ADDOPTIONS=("$ADDOPTIONS" #>#
		"e; print extent attributes (with -l)"
		) #<#
		;;
	esac

	OPTIONS=("$POSIXOPTIONS" "$ADDOPTIONS")
	unset POSIXOPTIONS ADDOPTIONS

	command -f completion//parseoptions ${long:+-es}
	case $ARGOPT in
	(-)
		command -f completion//completeoptions
		;;
	(D)
		if command -vf completion//completestrftime >/dev/null 2>&1 ||
				. -AL completion/date; then
			command -f completion//completestrftime
		fi
		;;
	(--block-size)
		if command -vf completion//completeblocksize >/dev/null 2>&1 ||
				. -AL completion/_blocksize; then
			command -f completion//completeblocksize
		fi
		;;
	(--color) #>>#
		complete -P "$PREFIX" -D "always print in color" yes always force
		complete -P "$PREFIX" -D "print in color if output is terminal" auto tty if-tty
		complete -P "$PREFIX" -D "don't print in color" no never none
		;; #<<#
	(--format) #>>#
		complete -P "$PREFIX" -D "print files line by line" single-column
		complete -P "$PREFIX" -D "arrange filenames vertically" vertical
		complete -P "$PREFIX" -D "print permission, owner, file size, etc." long verbose
		complete -P "$PREFIX" -D "separate filenames by commas" commas
		complete -P "$PREFIX" -D "arrange filenames horizontally" horizontal across
		complete -P "$PREFIX" -D "print security context of files" context
		;; #<<#
	#(--hide)  -- complete as filename as usual
	#	;;
	(--indicator-style) #>>#
		complete -P "$PREFIX" -D "don't append symbols indicating file type" none
		complete -P "$PREFIX" -D "append slash to directory names" slash
		complete -P "$PREFIX" -D "enable all indicators but *" file-type
		complete -P "$PREFIX" -D "enable all indicators" classify
		;; #<<#
	#(I|--ignore)  -- complete as filename as usual
	#	;;
	(--quoting-style) #>>#
		complete -P "$PREFIX" -D "quote or escape nothing" literal
		complete -P "$PREFIX" -D "quote in format suitable for shell input" shell
		complete -P "$PREFIX" -D "quote all filenames in format suitable for shell input" shell-always
		complete -P "$PREFIX" -D "quote and escape like C string" c
		complete -P "$PREFIX" -D "quote and escape like C string if necessary" c-maybe
		complete -P "$PREFIX" -D "escape like C string" escape
		complete -P "$PREFIX" -D "locale-dependent quoting and escaping" locale
		complete -P "$PREFIX" -D "locale-dependent quoting and escaping" clocale
		;; #<<#
	(--sort) #>>#
		complete -P "$PREFIX" -D "don't sort" none
		complete -P "$PREFIX" -D "sort by filename extension" extension
		complete -P "$PREFIX" -D "sort by file size" size
		complete -P "$PREFIX" -D "sort by last modified time" time
		complete -P "$PREFIX" -D "sort by filename regarding as version number" version
		;; #<<#
	(--time) #>>#
		complete -P "$PREFIX" -D "print or sort by last access time" atime access use
		complete -P "$PREFIX" -D "print or sort by last status change time" ctime status
		;; #<<#
	(--time-style)
		case $TARGETWORD in
		("$PREFIX+"*)
			if command -vf completion//completestrftime >/dev/null 2>&1 ||
					. -AL completion/date; then
				command -f completion//completestrftime
			fi
			;;
		(*) #>>#
			complete -P "$PREFIX" -D "e.g. 2000-01-01 01:23:45.678901234 +0900" full-iso
			complete -P "$PREFIX" -D "e.g. 2010-06-29 00:37" long-iso
			complete -P "$PREFIX" -D "e.g. 01-23 01:23 or 2000-01-23" iso
			complete -P "$PREFIX" -D "locale-dependent time style" locale posix-locale
			complete -P "$PREFIX" -D "like full-iso, but only when not in POSIX locale" posix-full-iso
			complete -P "$PREFIX" -D "like long-iso, but only when not in POSIX locale" posix-long-iso
			complete -P "$PREFIX" -D "like iso, but only when not in POSIX locale" posix-iso
			complete -T -P "$PREFIX" -D "specify time format after +" +
			;; #<<#
		esac
		;;
	(--tabsize)
		;;
	(w|--width)
		complete -P "$PREFIX" 80 132 ${COLUMNS:+"$COLUMNS"}
		;;
	(*)
		complete -P "$PREFIX" -f
		;;
	esac

}


# vim: set ft=sh ts=8 sts=8 sw=8 noet:
