<commit_before>from subprocess import check_output
from prompt_toolkit.completion import Completer, Completion
from fuzzyfinder import fuzzyfinder
import shlex
import json
import os
import os.path

class KubectlCompleter(Completer):

    def __init__(self):
        self.all_commands = []
        self.all_args = []
        self.all_opts = []
        self.global_opts = []
        try:
            DATA_DIR = os.path.dirname(os.path.realpath(__file__))
            DATA_PATH = os.path.join(DATA_DIR, 'data/cli.json')
            with open(DATA_PATH) as json_file:
                self.kubectl_dict = json.load(json_file)
            self.populate_cmds_args_opts(self.kubectl_dict)
        except Exception as ex:
            print "got an exception" + ex.message

    def populate_cmds_args_opts(self, key_map):
        for key in key_map.keys():
            self.all_commands.append(key)
            self.all_args.extend(key_map[key]['args'])
            if key == "kubectl":
                for opt in key_map[key]['options'].keys():
                    self.global_opts.append(opt)
            else:
                for opt in key_map[key]['options'].keys():
                    self.all_opts.append(opt)

            self.populate_cmds_args_opts(key_map[key]['subcommands'])

    # TODO: command may not have subcommands, args or flags handle the case
    # TODO: command may mutliple levels of subcommands
    def get_completions(self, document, complete_event, smart_completion=None):
        cmdline = document.text_before_cursor
        word_before_cursor = document.get_word_before_cursor(WORD=True)
        tokens = []<commit_msg>details on completion logic<commit_after>from subprocess import check_output
from prompt_toolkit.completion import Completer, Completion
from fuzzyfinder import fuzzyfinder
import shlex
import json
import os
import os.path

class KubectlCompleter(Completer):

    def __init__(self):
        self.all_commands = []
        self.all_args = []
        self.all_opts = []
        self.global_opts = []
        try:
            DATA_DIR = os.path.dirname(os.path.realpath(__file__))
            DATA_PATH = os.path.join(DATA_DIR, 'data/cli.json')
            with open(DATA_PATH) as json_file:
                self.kubectl_dict = json.load(json_file)
            self.populate_cmds_args_opts(self.kubectl_dict)
        except Exception as ex:
            print "got an exception" + ex.message

    def populate_cmds_args_opts(self, key_map):
        for key in key_map.keys():
            self.all_commands.append(key)
            self.all_args.extend(key_map[key]['args'])
            if key == "kubectl":
                for opt in key_map[key]['options'].keys():
                    self.global_opts.append(opt)
            else:
                for opt in key_map[key]['options'].keys():
                    self.all_opts.append(opt)

            self.populate_cmds_args_opts(key_map[key]['subcommands'])

    # TODO: Need cleanup to make code more readable and understandable
    #
    # Based on the logic how kubectl works, this methods uses state maching to parse token
    # We use four states to parse command, args, global flags, local flags and suggest based on that
    #
    # states:
    #   INIT: this is starting state. In this state we only expect 'kubectl' as first token
    #   KUBCTL: State when first token is 'kubectl' and need to handle second token. In this state only commands of
    #           kubectl or one or more global options can be specified
    #   KUBCTL_CMD: State represneting we have recieved 'kubeclt' and a 'command'. In this state either args, subcommands
    #           global options, or local options specifc to the commands can be specified
    #   KUBCTL_LEAF: In this state only global or local options for the commands can be specified. We will reach this
    #          state from KUBCTL_CMD when we longer have any sub-commands or args for the previous command
    #
    def get_completions(self, document, complete_event, smart_completion=None):
        cmdline = document.text_before_cursor
        word_before_cursor = document.get_word_before_cursor(WORD=True)
        tokens = []
{'fraction_non_alphanumeric': 0.08097747963584093, 'fraction_numerical': 0.0, 'mean_word_length': 2.5622866894197953, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, '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': '883416', 'n_tokens_mistral': 1229, 'n_tokens_neox': 1189, 'n_words': 341}