{ ... }: {
	text = ''
		# Rename dirs to `snake_case` and files to `PascalCase`. Careful with structured file names like archives!
		# Usage: name [FILES]
		function name() {
			local IFS=$'\n'
			local targets=(''${@})
			[[ "''${targets}" = "" ]] && targets=($(ls))

			process() {
				# Skip archive.
				if $(_is_archive "''${target}"); then
					_iterate_skip "File is an archive, skip."
					return 0
				fi

				if [[ -d "''${target}" ]]; then
					local new_name=$(parse_snake ''${target})
					[[ -e "''${new_name}" ]] && return 0

					mv -- ''${target} ''${new_name} && echo ''${new_name}
				else
					local ext=".''${target##*.}"
					local name=''${target%.*}
					[[ "''${ext}" = ".''${target}" ]] && ext=""

					local new_name="$(parse_pascal ''${name})''${ext}"
					[[ -e "''${new_name}" ]] && return 0

					mv -- ''${target} ''${new_name} && echo ''${new_name}
				fi
			}

			_iterate_targets process ''${targets[@]}
		}

		# Rename files with provided parser, i.e. `parse_simple`.
		# All files by default.
		# Usage: name_parse <PARSER> [FILES]
		function name_parse() {
			local IFS=$'\n'
			local parser=''${1}
			local targets=(''${@:2})
			[[ "''${targets}" = "" ]] && targets=([^.]*)

			if [[ "''${parser}" = "" ]]; then
				help name_parse
				return 2
			fi

			process() {
				# Skip archive.
				if $(_is_archive "''${target}"); then
					_iterate_skip "File is an archive, skip."
					return 0
				fi

				# parse new name.
				local ext=""
				local name="''${target}"

				# ext only for files.
				if [[ -f "''${target}" ]]; then
					ext=".''${target##*.}"
					name="''${target%.*}"
				fi

				# Files w/o extension support.
				[[ "''${ext#.}" = "''${name}" ]] && ext=""

				# Get new name.
				local new_name=$(''${parser} "''${name}")''${ext,,}

				# check if same name.
				[[ "''${target}" = "''${new_name}" ]] && return 0

				# check if target name already exists.
				if [[ -f "''${new_name}" ]]; then
					_error "''${new_name}: Already exists!"
					return 1
				fi

				# rename target.
				mv -- "''${target}" "''${new_name}" && echo "''${new_name}"
			}

			_iterate_targets process ''${targets[@]}
		}

		# Rename all files to their hashes while keeping extensions.
		# All files by default.
		# Usage: name_hash [FILES]
		function name_hash() {
			local IFS=$'\n'
			local targets=(''${@})
			[[ "''${targets}" = "" ]] && targets=($(_ls_file))

			process() {
				# extract extension.
				local extension="''${target##*.}"
				if [[ "''${extension}" = "''${target}" ]]; then
					extension=""
				else
					extension=".''${extension}"
				fi

				# hash the new name.
				local hash=$(pv "''${target}" | sha1sum | cut -d\  -f1)
				new_name="''${hash,,}''${extension,,}"

				# check if same name.
				[[ "''${target}" = "''${new_name}" ]] && return 0

				# rename target.
				mv -- ''${target} ''${new_name} && echo ''${new_name}
			}

			_iterate_targets process ''${targets[@]}
		}

		# Check hashes for previously renamed files.
		# All files by default.
		# Usage: name_hash_check [FILES]
		function name_hash_check() {
			local IFS=$'\n'
			local targets=(''${@})
			[[ "''${targets}" = "" ]] && targets=([^.]*)

			process() {
				# extract hashes.
				local stored="''${target%%.*}"
				local actual=$(pv "''${target}" | sha1sum | cut -d\  -f1)

				# compare hashes.
				if [[ "''${stored}" != "''${actual}" ]]; then
					_error "Failed."
					return 1
				fi
			}

			_iterate_targets process ''${targets[@]}
		}

		# Rename files for Jellyfin shows, i.e. `Episode S01E01.mkv`
		# All files by default.
		# Usage: name_show [FILES]
		function name_show() {
			local IFS=$'\n'
			local season="$(realpath .)"; season="''${season##*\ }"
			local episode=0
			local targets=(''${@})
			[[ "''${targets}" = "" ]] && targets=($(_ls_file))

			# Error when no season number specified.
			if [[ "''${season}" = "" ]]; then
				_error "Could not determine season number."
				return 2
			fi

			process() {
				((episode++))

				# extract new name.
				local new_name="Episode S''${season}E$(printf %02d ''${episode}).''${target##*.}"

				# Skip on no change.
				[[ "''${target}" = "''${new_name}" ]] && return 0

				# rename target.
				mv -- ''${target} ''${new_name} && echo ''${new_name}
			}

			_iterate_targets process ''${targets[@]}
		}

		# Rename files for Kavita manga format.
		# All files by default.
		# Usage: name_manga <SEASON> [FILES]
		function name_manga() {
			local IFS=$'\n'
			local manga=''${PWD##*/}
			local season=''${1}
			local episode=0
			local targets=(''${@:2})
			[[ "''${targets}" = "" ]] && targets=($(_ls_file))

			# Error when no season number specified.
			if [[ "''${season}" = "" ]]; then
				help name_manga
				return 2
			fi

			process() {
				((episode++))

				# Extract new name.
				local new_name="''${manga} Vol.''${season} Ch.''${episode}.''${target##*.}"

				# Skip on no change.
				[[ "''${target}" = "''${new_name}" ]] && return 0

				# Rename target.
				mv -- ''${target} ''${new_name} && echo ''${new_name}
			}

			_iterate_targets process ''${targets[@]}
		}

		# Rename files for ffmpeg_music_meta format.
		# All files by default.
		# Usage: name_music [FILES]
		function name_music() {
			local IFS=$'\n'
			local targets=(''${@})
			[[ "''${targets}" = "" ]] && targets=($(ls))

			process() {
				# Extract new name.
				local ext=''${target##*.}

				if [[ -d "''${target}" ]]; then
					local new_name="$(parse_startcase $(parse_simple ''${target%.*}))"
				else
					local new_name="$(parse_startcase $(parse_simple ''${target%.*})).''${ext}"
				fi

				# Skip on no change.
				[[ "''${target%/}" = "''${new_name}" ]] && return 0

				# Rename target.
				mv -- ''${target} ''${new_name} && echo ''${new_name}
			}

			_iterate_targets process ''${targets[@]}
		}

		# Rename files with new extension.
		# All files by default.
		# Usage: name_ext <EXTENSION> [FILES]
		function name_ext() {
			local IFS=$'\n'
			local extension=''${1}
			local targets=(''${@:2})
			[[ "''${targets}" = "" ]] && targets=($(_ls_file))

			# Error when no new extension specified.
			if [[ "''${extension}" = "" ]]; then
				help name_ext
				return 2
			fi

			process() {
				# Extract new name.
				local new_name="''${target%.*}"."''${extension}"

				# Skip on no change.
				[[ "''${target}" = "''${new_name}" ]] && return 0

				# Rename target.
				mv -- ''${target} ''${new_name} && echo ''${new_name}
			}

			_iterate_targets process ''${targets[@]}
		}

		# Change file name prefix.
		# All matching files by default.
		# Usage: name_prefix <OLD> <NEW> [FILES]
		function name_prefix() {
			local IFS=$'\n'
			local old=''${1}
			local new=''${2}
			local targets=(''${@:3})
			[[ "''${targets}" = "" ]] && targets=(''${old}*)

			process() {
				# Create new name.
				local new_name="''${new}''${target#$old}"

				# Skip on no change.
				[[ "''${target}" = "''${new_name}" ]] && return 0

				# Rename.
				mv -- ''${target} ''${new_name} && echo ''${new_name}
			}

			_iterate_targets process ''${targets[@]}
		}

		# Change file name postfix.
		# All matching files by default.
		# Usage: name_postfix <OLD> <NEW> [FILES]
		function name_postfix() {
			local IFS=$'\n'
			local old=''${1}
			local new=''${2}
			local targets=(''${@:3})
			[[ "''${targets}" = "" ]] && targets=(*''${old})

			process() {
				# Create new name.
				local new_name="''${target%$old}''${new}"

				# Skip on no change.
				[[ "''${target}" = "''${new_name}" ]] && return 0

				# Rename.
				mv -- ''${target} ''${new_name} && echo ''${new_name}
			}

			_iterate_targets process ''${targets[@]}
		}

		# Replace part of the name.
		# All matching files by default.
		# Usage: name_replace <OLD> <NEW> [FILES]
		function name_replace() {
			local IFS=$'\n'
			local old=''${1}
			local new=''${2}
			local targets=(''${@:3})
			[[ "''${targets}" = "" ]] && targets=(*''${old}*)

			process() {
				# Create new name.
				local new_name="''${target//$old/$new}"

				# Skip on no change.
				[[ "''${target}" = "''${new_name}" ]] && return 0

				# Rename.
				mv -- ''${target} ''${new_name} && echo ''${new_name}
			}

			_iterate_targets process ''${targets[@]}
		}

		# Fix numbering for numbered files. I.e if there are 10 items and some of them start without zero, then append zero to it. 1..10 -> 01..10.
		# Usage: name_fix_numbering [FILES]
		function name_fix_numbering() {
			local IFS=$'\n'
			local highest=0
			local power=0
			local targets=(''${@})
			[[ "''${targets}" = "" ]] && targets=($(ls | grep "^[0-9]"))

			# Count leading zeroes.
			for target in "''${targets[@]}"; do
				# Check that starts with a digit.
				[[ "''${target}" =~ ^[0-9] ]] || continue

				local digits=($(parse_ints "''${target}"))
				local digit="''${digits[0]}"
				digit=$((10#''${digit}))

				[[ "''${digit}" -gt "''${highest}" ]] && highest="''${digit}"
			done

			local i=''${highest}
			while [[ i -gt 0 ]]; do
				((power++))
				i=$((''${i}/10))
			done

			process() {
				# Check that starts with a digit.
				if [[ ! "''${target}" =~ ^[0-9] ]]; then
					_error "Does not start with a digit!"
					return 1
				fi

				# Prepare new name.
				local digits=($(parse_ints "''${target}"))
				local digit="''${digits[0]}"
				digit=$((10#''${digit}))
				local new_name=$(printf "%0''${power}d" "''${digit}")"''${target#''${digits[0]}}"

				# Skip if the same name.
				[[ "''${target}" = "''${new_name}" ]] && return 0

				# Check that file does not exist.
				if [[ -e "''${new_name}" ]]; then
					_error "''${new_name}: File exists!"
					return 1
				fi

				mv -- ''${target} ''${new_name} && echo ''${new_name}
			}

			_iterate_targets process ''${targets[@]}
		}

		function _comp_name_parse() {
			_autocomplete_first_ls $(find_function | grep ^parse)
		}

		complete -o filenames -F _comp_name_parse name_parse
	'';
}