<commit_before>package com.github.ajalt.clikt.completion

import com.github.ajalt.clikt.completion.CompletionCandidates.Custom.ShellType
import com.github.ajalt.clikt.core.CliktCommand

internal object CompletionGenerator {
    fun generateCompletion(command: CliktCommand, zsh: Boolean = true): String {
        val commandName = command.commandName
        val (isTopLevel, funcName) = commandCompletionFuncName(command)
        val options = command._options.map { Triple(it.names, it.completionCandidates, it.nvalues) }
        val arguments = command._arguments.map { it.name to it.completionCandidates }
        val subcommands = command._subcommands.map { it.commandName }
        val fixedArgNameArray = command._arguments
                .takeWhile { it.nvalues > 0 }
                .flatMap { arg -> (1..arg.nvalues).map { "'${arg.name}'" } }
                .joinToString(" ")
        val varargName = command._arguments.find { it.nvalues < 0 }?.name.orEmpty()
        val paramsWithCandidates = (options.map { o -> o.first.maxByOrNull { it.length }!! to o.second } + arguments)

        if (options.isEmpty() && subcommands.isEmpty() && arguments.isEmpty()) return ""

        return buildString {<commit_msg>Add public functions to generate shell completion strings (#236)<commit_after>package com.github.ajalt.clikt.completion

import com.github.ajalt.clikt.completion.CompletionCandidates.Custom.ShellType
import com.github.ajalt.clikt.core.CliktCommand

object CompletionGenerator {
    fun generateBashCompletion(command: CliktCommand): String {
        return generateCompletion(command, zsh = false)
    }

    fun generateZshCompletion(command: CliktCommand): String {
        return generateCompletion(command, zsh = true)
    }

    internal fun generateCompletion(command: CliktCommand, zsh: Boolean = true): String {
        val commandName = command.commandName
        val (isTopLevel, funcName) = commandCompletionFuncName(command)
        val options = command._options.map { Triple(it.names, it.completionCandidates, it.nvalues) }
        val arguments = command._arguments.map { it.name to it.completionCandidates }
        val subcommands = command._subcommands.map { it.commandName }
        val fixedArgNameArray = command._arguments
                .takeWhile { it.nvalues > 0 }
                .flatMap { arg -> (1..arg.nvalues).map { "'${arg.name}'" } }
                .joinToString(" ")
        val varargName = command._arguments.find { it.nvalues < 0 }?.name.orEmpty()
        val paramsWithCandidates = (options.map { o -> o.first.maxByOrNull { it.length }!! to o.second } + arguments)

        if (options.isEmpty() && subcommands.isEmpty() && arguments.isEmpty()) return ""

        return buildString {
{'fraction_non_alphanumeric': 0.11103021477975973, 'fraction_numerical': 0.0032763014197306154, 'mean_word_length': 3.1447963800904977, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6276159', 'n_tokens_mistral': 780, 'n_tokens_neox': 741, 'n_words': 168}