func genOptionDesc(opt *usage.Option, opts options.Map, prefixSize int) string {
	result := strings.Repeat(" ", prefixSize)
	var isBool, isMergeble bool
	var optV *options.V
	optLong := opt.Long
	if opts != nil {
		optV = opts[getOptionFullName(opt)]
	}
	if optV != nil {
		isBool = optV.Type == options.BOOL
		isMergeble = optV.Mergeble
	}
	if !isBool {
		optLong += "="
	}
	if !isMergeble {
		var exclusion string
		if opt.Short != "" {
			exclusion = fmt.Sprintf("-%s --%s", opt.Short, optLong)
		} else {
			exclusion = fmt.Sprintf("--%s", optLong)
		}
		if optV != nil && optV.Conflicts != "" {
			exclusion += genConflictsExclusion(optV.Conflicts)
		}
		result += "'(" + exclusion + ")'"
	}
	if opt.Short != "" {
		result += fmt.Sprintf("{-%s,--%s}", opt.Short, optLong)
	} else {
		result += fmt.Sprintf("--%s", opt.Long)
	}
	result += fmt.Sprintf("'[%s]'", fmtc.Clean(opt.Desc))
	result += " \\\n"
	return result
}
genOptionDesc generates description for some option
package zsh
import (
	"fmt"
	"strings"
	"pkg.re/essentialkaos/ek.v12/fmtc"
	"pkg.re/essentialkaos/ek.v12/options"
	"pkg.re/essentialkaos/ek.v12/usage"
)
const _ZSH_TEMPLATE = `#compdef {{COMPNAME}}
# This completion is automatically generated
typeset -A opt_args
_{{COMPNAME}}() {
  _arguments \
{{GLOBAL_ARGS}}
{{COMMANDS_HANDLERS}}
{{FILES_HANDLER}}
}
{{COMMANDS_FUNC}}
_{{COMPNAME}} "$@"
`
func Generate(info *usage.Info, opts options.Map, name string, fileGlob ...string) string {
	result := _ZSH_TEMPLATE
	result = strings.Replace(result, "{{GLOBAL_ARGS}}", genGlobalOptionList(info, opts), -1)
	result = strings.Replace(result, "{{COMMANDS_HANDLERS}}", genCommandsHandlers(info, opts), -1)
	result = strings.Replace(result, "{{COMMANDS_FUNC}}", genCommandsFunc(info), -1)
	result = strings.Replace(result, "{{FILES_HANDLER}}", genFilesHandler(info, fileGlob), -1)
	result = strings.Replace(result, "{{COMPNAME}}", name, -1)
	nameSafe := strings.Replace(name, "-", "_", -1)
	result = strings.Replace(result, "{{COMPNAME_SAFE}}", nameSafe, -1)
	return result
}
func genFilesHandler(info *usage.Info, fileGlob []string) string {
	if len(info.Args) == 0 && len(fileGlob) == 0 {
		return ""
	}
	if len(fileGlob) != 0 {
		return "  _files -g \"" + fileGlob[0] + "\""
	}
	return "  _files"
}
func genGlobalOptionList(info *usage.Info, opts options.Map) string {
	var result string
	nonGlobalOptions := make(map[string]bool)
	for _, cmd := range info.Commands {
		for _, opt := range cmd.BoundOptions {
			nonGlobalOptions[opt] = true
		}
	}
	for _, opt := range info.Options {
		if nonGlobalOptions[opt.Long] {
			continue
		}
		result += genOptionDesc(opt, opts, 4)
	}
	if len(info.Commands) != 0 {
		result += "    '1: :_{{COMPNAME_SAFE}}_cmds' \\\n"
	}
	result += "    '*:: :->cmd_args' && ret=0"
	return result
}