예제 #1
0
    def updatedict(self):
        self.button_dictionary.update(caster_alphabet())
        self.button_dictionary.update(text_punc_dict())
        # Create function keys 1 through 13
        self.button_dictionary.update({
            "(F{}".format(i) + " | function {})".format(i): "f{}".format(i)
            for i in range(1, 13)
        })
        self.button_dictionary.update({
            "(tab | tabby)": "tab",
            "(backspace | clear)": "backspace",
            "(delete | deli)": "del",
            "(enter | shock)": "enter",
            left_spec: "left",
            right_spec: "right",
            "(up | sauce)": "up",
            "(down | dunce)": "down",
            "page (down | dunce)": "pgdown",
            "page (up | sauce)": "pgup",
            "zero": "0",
            "one": "1",
            "two": "2",
            "three": "3",
            "four": "4",
            "five": "5",
            "six": "6",
            "seven": "7",
            "eight": "8",
            "nine": "9",
            shift_spec: "shift",
            control_spec: "control",
            alt_spec: "alt",
            right_spec + " " + shift_spec: "rshift",
            right_spec + " " + control_spec: "rcontrol",
            right_spec + " " + alt_spec: "ralt",
            SymbolSpecs.CANCEL: "escape",
            "insert": "insert",
            "pause": "pause",
            windows_spec: "win",
            "(apps | popup)": "apps",
            "print screen": "printscreen",
            "scroll lock": "scrolllock",
            "num lock": "numlock",
            "caps lock": "capslock",
            "(home | lease wally | latch)": "home",
            "(end | ross wally | ratch)": "end",
            # number pad numbers deliberately left off
            # volume control deliberately left off as these are dealt with in HardwareRule and I don't think there's a use case for modifiers there
            # track control deliberately left off as these are (or will be) dealt with in HardwareRule and I don't think there's a use case for modifiers there
            # browser forward/back are deliberately left off. These functions are implemented at the browser rule level
        })

        self.button_dictionary.update({
            self.getspec(' '): "space",
            self.getspec(','): "comma",
            self.getspec('-'): "minus",
            self.getspec('/'): "slash",
            self.getspec(':'): "colon",
        })
예제 #2
0
class Keyboard(MappingRule):
    mapping = {
        "<modifier> <button_dictionary_1>":
        R(Key("%(modifier)s%(button_dictionary_1)s"),
          rdescript="press button: %(modifier)s%(button_dictionary_1)s"),
        "<hold_release> <button_dictionary_1>":
        R(Key("%(button_dictionary_1)s:%(hold_release)s"),
          rdescript="%(hold_release)s button: %(button_dictionary_1)s"),
    }

    # These buttons can be used without using the "press" prefix.
    right_spec = "(right | ross)"
    left_spec = "(left | lease)"
    button_dictionary_1 = {
        "(F{}".format(i) + " | function {})".format(i): "f{}".format(i)
        for i in range(1, 13)
    }
    button_dictionary_1.update(caster_alphabet())
    button_dictionary_1.update(_tpd)
    shift_spec = "(shift | shin)"
    control_spec = "(control | fly)"
    alt_spec = "alt"
    windows_spec = "windows"
    # in the punctuation dictionary it uses " " which is not the correct dragonfly key name.
    del button_dictionary_1["[is] less [than] [or] equal [to]"]
    del button_dictionary_1["[is] equal to"]
    del button_dictionary_1["[is] greater [than] [or] equal [to]"]

    ace_key = list(button_dictionary_1.keys())[list(
        button_dictionary_1.values()).index(' ')]
    slash_key = list(button_dictionary_1.keys())[list(
        button_dictionary_1.values()).index('/')]
    minus_key = list(button_dictionary_1.keys())[list(
        button_dictionary_1.values()).index('-')]
    colon_key = list(button_dictionary_1.keys())[list(
        button_dictionary_1.values()).index(':')]
    comma_key = list(button_dictionary_1.keys())[list(
        button_dictionary_1.values()).index(',')]

    button_dictionary_1.update({
        "(tab | tabby)": "tab",
        "(backspace | clear)": "backspace",
        "(delete | deli)": "del",
        "(enter | shock)": "enter",
        left_spec: "left",
        right_spec: "right",
        "(up | sauce)": "up",
        "(down | dunce)": "down",
        "page (down | dunce)": "pgdown",
        "page (up | sauce)": "pgup",
        ace_key: "space",
        comma_key: "comma",
        minus_key: "minus",
        slash_key: "slash",
        colon_key: "colon",
        "zero": "0",
        "one": "1",
        "two": "2",
        "three": "3",
        "four": "4",
        "five": "5",
        "six": "6",
        "seven": "7",
        "eight": "8",
        "nine": "9",
        shift_spec: "shift",
        control_spec: "control",
        alt_spec: "alt",
        right_spec + " " + shift_spec: "rshift",
        right_spec + " " + control_spec: "rcontrol",
        right_spec + " " + alt_spec: "ralt",
        SymbolSpecs.CANCEL: "escape",
        "insert": "insert",
        "pause": "pause",
        windows_spec: "win",
        "(apps | popup)": "apps",
        "print screen": "printscreen",
        "scroll lock": "scrolllock",
        "num lock": "numlock",
        "caps lock": "capslock",
        "(home | lease wally | latch)": "home",
        "(end | ross wally | ratch)": "end",
        # number pad numbers deliberately left off
        # volume control deliberately left off as these are dealt with in HardwareRule and I don't think there's a use case for modifiers there
        # track control deliberately left off as these are (or will be) dealt with in HardwareRule and I don't think there's a use case for modifiers there
        # browser forward/back are deliberately left off. These functions are implemented at the browser rule level
    })

    modifier_choice_object = Choice(
        "modifier",
        {
            control_spec: "c-",
            shift_spec: "s-",
            alt_spec: "a-",
            cat_spec_and_reverse(control_spec, shift_spec) + " | queue": "cs-",
            cat_spec_and_reverse(control_spec, alt_spec): "ca-",
            cat_spec_and_reverse(alt_spec, shift_spec): "sa-",
            cat_spec_and_reverse_3(alt_spec, control_spec, shift_spec): "csa-",
            windows_spec: "w-",
            cat_spec_and_reverse(control_spec, windows_spec): "cw-",
            cat_spec_and_reverse_3(alt_spec, control_spec, windows_spec):
            "cwa-",
            cat_spec_and_reverse_3(shift_spec, control_spec, windows_spec):
            "cws-",
            cat_spec_and_reverse_3(alt_spec, shift_spec, windows_spec): "wsa-",
            cat_spec_and_reverse(windows_spec, shift_spec): "ws-",
            cat_spec_and_reverse(windows_spec, alt_spec): "wa-",
            # We will leave this as is as it is seldom used
            "control windows alt shift": "cwas-",
            "press": "",
        })
    extras = [
        modifier_choice_object,
        Choice("button_dictionary_1", button_dictionary_1),
        Choice("hold_release", {
            "hold": "down",
            "release": "up"
        }),
    ]

    defaults = {"modifier": ""}
예제 #3
0
class TextManipulation(MergeRule):
    pronunciation = "text manipulation"

    mapping = {

        # PROBLEM: sometimes Dragon thinks the variables are part of dictation.

        # replace text or character
        "replace <direction> [<number_of_lines_to_search>] [<occurrence_number>] <dictation> with <dictation2>":
        R(Function(
            text_manipulation_support.copypaste_replace_phrase_with_phrase,
            dict(dictation="replaced_phrase", dictation2="replacement_phrase"),
            dictation_versus_character="dictation"),
          rdescript=
          "Text Manipulation: replace text to the left or right of the cursor"
          ),
        "replace <direction>  [<number_of_lines_to_search>] [<occurrence_number>] <character> with <character2>":
        R(Function(
            text_manipulation_support.copypaste_replace_phrase_with_phrase,
            dict(character="replaced_phrase", character2="replacement_phrase"),
            dictation_versus_character="character"),
          rdescript=
          "Text Manipulation: replace character to the left of the cursor"),

        # remove text or character
        "remove <direction> [<number_of_lines_to_search>] [<occurrence_number>] <dictation>":
        R(Function(text_manipulation_support.copypaste_remove_phrase_from_text,
                   dict(dictation="phrase"),
                   dictation_versus_character="dictation"),
          rdescript=
          "Text Manipulation: remove chosen phrase to the left or right of the cursor"
          ),
        "remove <direction> [<number_of_lines_to_search>] [<occurrence_number>] <character>":
        R(Function(text_manipulation_support.copypaste_remove_phrase_from_text,
                   dict(character="phrase"),
                   dictation_versus_character="character"),
          rdescript=
          "Text Manipulation: remove chosen character to the left of the cursor"
          ),

        # remove until text or character
        "remove <direction> [<number_of_lines_to_search>] until [<before_after>] [<occurrence_number>] <dictation>":
        R(Function(text_manipulation_support.copypaste_delete_until_phrase,
                   dict(dictation="phrase"),
                   dictation_versus_character="dictation"),
          rdescript="Text Manipulation: delete until chosen phrase"),
        "remove <direction> [<number_of_lines_to_search>] until [<before_after>] [<occurrence_number>] <character>":
        R(Function(text_manipulation_support.copypaste_delete_until_phrase,
                   dict(character="phrase"),
                   dictation_versus_character="character"),
          rdescript="Text Manipulation: delete until chosen character"),

        # move cursor
        "(go | move) <direction> [<number_of_lines_to_search>] [<before_after>] [<occurrence_number>] <dictation>":
        R(Function(text_manipulation_support.move_until_phrase,
                   dict(dictation="phrase"),
                   dictation_versus_character="dictation"),
          rdescript=
          "Text Manipulation: move to chosen phrase to the left or right of the cursor"
          ),
        "(go | move) <direction> [<number_of_lines_to_search>] [<before_after>] [<occurrence_number>] <character_sequence> [over]":
        Function(
            lambda direction, before_after, number_of_lines_to_search,
            occurrence_number, character_sequence:
            text_manipulation_support.move_until_phrase(
                direction, before_after, "".join(character_sequence),
                number_of_lines_to_search, occurrence_number, "character")),

        # select text or character
        "grab <direction> [<number_of_lines_to_search>] [<occurrence_number>] <dictation>":
        R(Function(text_manipulation_support.select_phrase,
                   dict(dictation="phrase"),
                   dictation_versus_character="dictation"),
          rdescript="Text Manipulation: select chosen phrase"),
        "grab <direction> [<number_of_lines_to_search>] [<occurrence_number>] <character>":
        R(Function(
            text_manipulation_support.select_phrase,
            dict(character="phrase", dictation_versus_character="character")),
          rdescript="Text Manipulation: select chosen character"),

        # select until text or character
        "grab <direction> [<number_of_lines_to_search>] until [<before_after>] [<occurrence_number>] <dictation> ":
        R(Function(text_manipulation_support.select_until_phrase,
                   dict(dictation="phrase"),
                   dictation_versus_character="dictation"),
          rdescript="Text Manipulation: select until chosen phrase"),
        "grab <direction> [<number_of_lines_to_search>] until [<before_after>] [<occurrence_number>] <character>":
        R(Function(text_manipulation_support.select_until_phrase,
                   dict(character="phrase"),
                   dictation_versus_character="character"),
          rdescript="Text Manipulation: select until chosen character"),

        # capitalized 1st word of text or character
        "capital <direction> [<number_of_lines_to_search>] [<occurrence_number>] [<letter_size>] <dictation>":
        R(Function(
            text_manipulation_support.copypaste_change_phrase_capitalization,
            dict(dictation="phrase"),
            dictation_versus_character="dictation"),
          rdescript="Text Manipulation: change capitalization phrase"),
        "capital <direction> [<number_of_lines_to_search>] [<occurrence_number>] [<letter_size>] <character>":
        R(Function(
            text_manipulation_support.copypaste_change_phrase_capitalization,
            dict(character="phrase"),
            dictation_versus_character="character"),
          rdescript="Text Manipulation: change capitalization character"),
    }
    new_text_punc_dict = text_punc_dict()
    new_text_punc_dict.update(alphabet_support.caster_alphabet())
    new_text_punc_dict.update(number_dict)
    character_dict = new_text_punc_dict
    character_choice_object = Choice("character_choice", character_dict)

    extras = [
        Repetition(character_choice_object,
                   min=1,
                   max=3,
                   name="character_sequence"),
        Dictation("dict"),
        Dictation("dictation"),
        Dictation("dictation2"),
        Dictation("text"),
        IntegerRefST("n", 1, 100),
        IntegerRefST("m", 1, 100),
        IntegerRefST("wait_time", 1, 1000),
        IntegerRefST("number_of_lines_to_search", 1, 50),
        Choice("character", character_dict),
        Choice("character2", character_dict),
        Choice("single_character", character_dict),
        Choice(
            "direction",
            {
                "lease": "left",
                "ross": "right",
                "sauce": "up",
                "dunce": "down",
                # note: "sauce" (i.e. "up") will be treated the same as "lease" (i.e. "left") except that
                # the default number_of_lines_to_search will be set to 3
                # in the same way, "dunce" (i.e. "down") will be treated the same as
                # "ross" (i.e. "right")
            }),
        Choice("before_after", {
            "before": "before",
            "after": "after",
        }),
        Choice(
            "letter_size", {
                "upper": "upper",
                "upward": "upper",
                "lower": "lower",
                "lowered": "lower",
            }),
        Choice(
            "occurrence_number", {
                "first": 1,
                "second": 2,
                "third": 3,
                "fourth": 4,
                "fifth": 5,
                "sixth": 6,
                "seventh": 7,
                "eighth": 8,
                "ninth": 9,
                "tenth": 10,
            }),
    ]
    defaults = {
        "before_after": None,
        "letter_size": "upper",
        "number_of_lines_to_search":
        0,  # before changing this default, please read the function deal_with_up_down_directions
        "occurrence_number": 1,
    }  # if direction is up or down, the default number_of_lines_to_search
예제 #4
0
파일: nav.py 프로젝트: tlappas/Caster
class Navigation(MergeRule):
    pronunciation = "navigation"

    mapping = {
        # "periodic" repeats whatever comes next at 1-second intervals until "terminate"
        # or "escape" (or your SymbolSpecs.CANCEL) is spoken or 100 tries occur
        "periodic":
        ContextSeeker(forward=[
            L(
                S(["cancel"], lambda: None),
                S(["*"],
                  lambda fnparams: UntilCancelled(
                      Mimic(*filter(lambda s: s != "periodic", fnparams)), 1).
                  execute(),
                  use_spoken=True))
        ]),
        # VoiceCoder-inspired -- these should be done at the IDE level
        "fill <target>":
        R(Key("escape, escape, end"), show=False) + AsynchronousAction(
            [L(S(["cancel"], Function(context.fill_within_line)))],
            time_in_seconds=0.2,
            repetitions=50),
        "jump in":
        AsynchronousAction(
            [L(S(["cancel"], context.nav, ["right", "(~[~{~<"]))],
            time_in_seconds=0.1,
            repetitions=50),
        "jump out":
        AsynchronousAction(
            [L(S(["cancel"], context.nav, ["right", ")~]~}~>"]))],
            time_in_seconds=0.1,
            repetitions=50),
        "jump back":
        AsynchronousAction(
            [L(S(["cancel"], context.nav, ["left", "(~[~{~<"]))],
            time_in_seconds=0.1,
            repetitions=50),
        "jump back in":
        AsynchronousAction(
            [L(S(["cancel"], context.nav, ["left", "(~[~{~<"]))],
            finisher=Key("right"),
            time_in_seconds=0.1,
            repetitions=50),

        # keyboard shortcuts
        'save':
        R(Key("c-s"), rspec="save"),
        'shock [<nnavi50>]':
        R(Key("enter"), rspec="shock") * Repeat(extra="nnavi50"),
        # "(<mtn_dir> | <mtn_mode> [<mtn_dir>]) [(<nnavi500> | <extreme>)]":
        #     R(Function(text_utils.master_text_nav)), # this is now implemented below
        "shift click":
        R(Key("shift:down") + Mouse("left") + Key("shift:up")),
        "stoosh [<nnavi500>]":
        R(Function(navigation.stoosh_keep_clipboard), rspec="stoosh"),
        "cut [<nnavi500>]":
        R(Function(navigation.cut_keep_clipboard), rspec="cut"),
        "spark [<nnavi500>] [(<capitalization> <spacing> | <capitalization> | <spacing>) [(bow|bowel)]]":
        R(Function(navigation.drop_keep_clipboard), rspec="spark"),
        "splat [<splatdir>] [<nnavi10>]":
        R(Key("c-%(splatdir)s"), rspec="splat") * Repeat(extra="nnavi10"),
        "deli [<nnavi50>]":
        R(Key("del/5"), rspec="deli") * Repeat(extra="nnavi50"),
        "clear [<nnavi50>]":
        R(Key("backspace/5:%(nnavi50)d"), rspec="clear"),
        SymbolSpecs.CANCEL:
        R(Key("escape"), rspec="cancel"),
        "shackle":
        R(Key("home/5, s-end"), rspec="shackle"),
        "(tell | tau) <semi>":
        R(Function(navigation.next_line), rspec="tell dock"),
        "duple [<nnavi50>]":
        R(Function(navigation.duple_keep_clipboard), rspec="duple"),
        "Kraken":
        R(Key("c-space"), rspec="Kraken"),
        "undo [<nnavi10>]":
        R(Key("c-z")) * Repeat(extra="nnavi10"),
        "redo [<nnavi10>]":
        R(
            ContextAction(
                default=Key("c-y") * Repeat(extra="nnavi10"),
                actions=[
                    (AppContext(executable=["rstudio", "foxitreader"]),
                     Key("cs-z") * Repeat(extra="nnavi10")),
                ])),

        # text formatting
        "set [<big>] format (<capitalization> <spacing> | <capitalization> | <spacing>) [(bow|bowel)]":
        R(Function(textformat.set_text_format)),
        "clear castervoice [<big>] formatting":
        R(Function(textformat.clear_text_format)),
        "peek [<big>] format":
        R(Function(textformat.peek_text_format)),
        "(<capitalization> <spacing> | <capitalization> | <spacing>) [(bow|bowel)] <textnv> [brunt]":
        R(Function(textformat.master_format_text)),
        "[<big>] format <textnv>":
        R(Function(textformat.prior_text_format)),
        "<word_limit> [<big>] format <textnv>":
        R(Function(textformat.partial_format_text)),
        "hug <enclosure>":
        R(Function(text_utils.enclose_selected)),
        "dredge [<nnavi10>]":
        R(Key("alt:down, tab/20:%(nnavi10)d, alt:up"),
          rdescript="Core: switch to most recent Windows"),

        # Ccr Mouse Commands
        "kick [<nnavi3>]":
        R(Function(navigation.left_click)) * Repeat(extra="nnavi3"),
        "psychic":
        R(Function(navigation.right_click)),
        "(kick double|double kick)":
        R(Function(navigation.left_click) * Repeat(2)),
        "squat":
        R(Function(navigation.left_down)),
        "bench":
        R(Function(navigation.left_up)),

        # keystroke commands
        "<direction> [<nnavi500>]":
        R(Key("%(direction)s") * Repeat(extra='nnavi500'),
          rdescript="arrow keys"),
        "(lease wally | latch) [<nnavi10>]":
        R(Key("home:%(nnavi10)s")),
        "(ross wally | ratch) [<nnavi10>]":
        R(Key("end:%(nnavi10)s")),
        "sauce wally [<nnavi10>]":
        R(Key("c-home:%(nnavi10)s")),
        "dunce wally [<nnavi10>]":
        R(Key("c-end:%(nnavi10)s")),
        "bird [<nnavi500>]":
        R(Key("c-left:%(nnavi500)s")),
        "firch [<nnavi500>]":
        R(Key("c-right:%(nnavi500)s")),
        "brick [<nnavi500>]":
        R(Key("s-left:%(nnavi500)s")),
        "frick [<nnavi500>]":
        R(Key("s-right:%(nnavi500)s")),
        "blitch [<nnavi500>]":
        R(Key("cs-left:%(nnavi500)s")),
        "flitch [<nnavi500>]":
        R(Key("cs-right:%(nnavi500)s")),
        "<modifier> <button_dictionary_500> [<nnavi500>]":
        R(Key("%(modifier)s%(button_dictionary_500)s") *
          Repeat(extra='nnavi500'),
          rdescript=
          "press modifier keys plus buttons from button_dictionary_500"),
        "<modifier> <button_dictionary_10> [<nnavi10>]":
        R(Key("%(modifier)s%(button_dictionary_10)s") *
          Repeat(extra='nnavi10'),
          rdescript="press modifier keys plus buttons from button_dictionary_10"
          ),
        "<modifier> <button_dictionary_1>":
        R(Key("%(modifier)s%(button_dictionary_1)s"),
          rdescript=
          "press modifiers plus buttons from button_dictionary_1, non-repeatable"
          ),

        # "key stroke [<modifier>] <combined_button_dictionary>":
        #     R(Text('Key("%(modifier)s%(combined_button_dictionary)s")')),

        # "key stroke [<modifier>] <combined_button_dictionary>":
        #     R(Text('Key("%(modifier)s%(combined_button_dictionary)s")')),
    }
    tell_commands_dict = {
        "dock": ";",
        "doc": ";",
        "sink": "",
        "com": ",",
        "deck": ":"
    }
    tell_commands_dict.update(_tpd)

    # I tried to limit which things get repeated how many times in hopes that it will help prevent the bad grammar error
    # this could definitely be changed. perhaps some of these should be made non-CCR
    button_dictionary_500 = {
        "(tab | tabby)": "tab",
        "(backspace | clear)": "backspace",
        "(delete|deli)": "del",
        "(escape | cancel)": "escape",
        "(enter | shock)": "enter",
        "(left | lease)": "left",
        "(right | ross)": "right",
        "(up | sauce)": "up",
        "(down | dunce)": "down",
        "page (down | dunce)": "pgdown",
        "page (up | sauce)": "pgup",
        "space": "space"
    }
    button_dictionary_10 = {
        "(F{}".format(i) + " | function {})".format(i): "f{}".format(i)
        for i in range(1, 13)
    }
    button_dictionary_10.update(caster_alphabet())
    button_dictionary_10.update(_tpd)
    longhand_punctuation_names = {
        "minus": "hyphen",
        "hyphen": "hyphen",
        "comma": "comma",
        "deckle": "colon",
        "colon": "colon",
        "slash": "slash",
        "backslash": "backslash"
    }
    button_dictionary_10.update(longhand_punctuation_names)
    button_dictionary_1 = {
        "(home | lease wally | latch)": "home",
        "(end | ross wally | ratch)": "end",
        "insert": "insert",
        "zero": "0",
        "one": "1",
        "two": "2",
        "three": "3",
        "four": "4",
        "five": "5",
        "six": "6",
        "seven": "7",
        "eight": "8",
        "nine": "9"
    }
    combined_button_dictionary = {}
    for dictionary in [
            button_dictionary_1, button_dictionary_10, button_dictionary_500
    ]:
        combined_button_dictionary.update(dictionary)

    modifier_choice_object = Choice(
        "modifier",
        {
            "(control | fly)": "c-",  #TODO: make DRY
            "(shift | shin)": "s-",
            "alt": "a-",
            "(control shift | que)": "cs-",
            "control alt": "ca-",
            "(shift alt | alt shift)": "sa-",
            "(control alt shift | control shift alt)":
            "csa-",  # control must go first
            "windows": "w-",  # windows should go before alt/shift
            "control windows": "cw-",
            "control windows alt": "cwa-",
            "control windows shift": "cws-",
            "windows shift alt": "wsa-",
            "windows alt shift": "was-",
            "windows shift": "ws-",
            "windows alt": "wa-",
            "control windows alt shift": "cwas-",
            "hit": "",
        })
    extras = [
        IntegerRefST("nnavi10", 1, 11),
        IntegerRefST("nnavi3", 1, 4),
        IntegerRefST("nnavi50", 1, 50),
        IntegerRefST("nnavi500", 1, 500),
        Dictation("textnv"),
        Choice("enclosure", _dtpd),
        Choice("direction", {
            "dunce": "down",
            "sauce": "up",
            "lease": "left",
            "ross": "right",
        }),
        modifier_choice_object,
        Choice("button_dictionary_1", button_dictionary_1),
        Choice("button_dictionary_10", button_dictionary_10),
        Choice("button_dictionary_500", button_dictionary_500),
        Choice("combined_button_dictionary", combined_button_dictionary),
        Choice(
            "capitalization", {
                "yell": 1,
                "tie": 2,
                "gerrish": 3,
                "sing": 4,
                "laws": 5,
                "say": 6,
                "cop": 7,
                "slip": 8,
            }),
        Choice(
            "spacing", {
                "gum": 1,
                "gun": 1,
                "spine": 2,
                "snake": 3,
                "pebble": 4,
                "incline": 5,
                "dissent": 6,
                "descent": 6,
            }),
        Choice("semi", tell_commands_dict),
        Choice("word_limit", {
            "single": 1,
            "double": 2,
            "triple": 3,
            "Quadra": 4
        }),
        navigation_support.TARGET_CHOICE,
        navigation_support.get_direction_choice("mtn_dir"),
        Choice("mtn_mode", {
            "shin": "s",
            "queue": "cs",
            "fly": "c",
        }),
        Choice("extreme", {
            "Wally": "way",
        }),
        Choice("big", {
            "big": True,
        }),
        Choice("splatdir", {
            "lease": "backspace",
            "ross": "delete",
        }),
    ]

    defaults = {
        "nnavi500": 1,
        "nnavi50": 1,
        "nnavi10": 1,
        "nnavi3": 1,
        "textnv": "",
        "capitalization": 0,
        "spacing": 0,
        "mtn_mode": None,
        "mtn_dir": "right",
        "extreme": None,
        "big": False,
        "splatdir": "backspace",
        "modifier": "",
    }