Sublime Forum

Raising a Text Input Handler with a Key binding

#1

I suspect I’ve missed something fundamental here.

I’ve got a TextCommand that uses a TextInputHandler as its input and works fine from the command palette (as it is declared in the sublime-commands file).

How do I call this command with a key binding? When I try to do so I get an error that indicates that the TextCommand's run() function is running before the input() function and the InputHandler it returns. Using print() for debugging more or less confirms this.

This prior thread seems to indicate that what I’m doing should be possible, so I guesseither I’m missing something in my implementation or I’ve run into a bug.

Relevant code extracted below.

class OpenNoteCommand(sublime_plugin.TextCommand):
    def run(self, edit, **kwargs):
        if not kwargs['note_select']:
            return

        open_selected_note(self.view, kwargs['note_select'])

    def input(self, args):
        return NoteSearchInputHandler()

class NoteSearchInputHandler(sublime_plugin.TextInputHandler):

    def placeholder(self) -> str:
        return 'Search query'

    def next_input(self, args):
        return NoteSelectInputHandler(query = args['note_search'])


class NoteSelectInputHandler(sublime_plugin.ListInputHandler):

    def __init__(self, query):

        self.results = sp.check_output([
            ZKL_COM, 'q', query])

    def list_items(self):

        values = get_note_id_title(self.results)
        return values

config:

// commands
{"caption": "Open Note", "command": "open_note"},

// key binding
	{
		"keys": ["super+t"],
		"command": "open_note"
	},

0 Likes

#2

As a follow up I thought I’d put together a simple prototype of what I’m trying to test this.

Plugin code is below. As a command palette command it works fine. The final effect is to print the input values to the console. But when used through a key binding, no input quick panel appears and the print out to the console is an empty dictionary. It’s feeling to me more like a bug now ???

I’m on sublime 4136.

class RandomTestInputCommand(sublime_plugin.TextCommand):
    def run(self, edit, **args):
        print(f'random test command {args}')
    def input(self, args):
        return RandomTestInputHandler()

class RandomTestInputHandler(sublime_plugin.TextInputHandler):

    def next_input(self, args):
        return RandomTestListInputHandler(args['random_test'])

class RandomTestListInputHandler(sublime_plugin.ListInputHandler):
    def __init__(self, word):
        self.list_values = list(word)
    def list_items(self):
        return self.list_values

Command:

	{"caption": "Random command test", "command": "random_test_input"},

Result in the console when free text input is “hello” and then from the individual characters in the list input “h” is selected:

random test command {'random_test': 'hello', 'random_test_list': 'h'}

Keybinding config:

	{
		"keys": ["super+k", "t", "i"],
		"command": "random_test_input"
	},

Output to the console (where no input panels appear):

random test command {}
0 Likes

#3

A possible work around used in some of the common built in key-bindings is to use the show_overlay command to bring up the command palette with the required text already entered. The user then only needs to press enter to run the commnd … which is OK i guess.

Example key binding:

	{
		"keys": ["super+k", "t", "i"],
		"command": "show_overlay",
		"args": {"overlay": "command_palette", "text": "random input test"}
	},

0 Likes

#4

What you want is a key binding like the one you specified here, only instead of passing it the text argument, pass it the command argument and specify the name of the command you want it to invoke.

1 Like

#5

Huh! I hope that’s documented somewhere! If not … how did you know?

Thanks!!!

For future reference, @OdatNurd is talking about something like this (adapted from the keybinding above):

	{
		"keys": ["super+k", "t", "i"],
		"command": "show_overlay",
		"args": {"overlay": "command_palette", "command": "random_test_input"}
	},

1 Like

#6

There’s not any official documentation for any of the commands in Sublime other than their usage in key bindings and in the command palette.

As to how I know that, I can’t say exactly. Could be a key binding or command palette entry that currently exists (not at a PC to check) or failing that if I had to guess it was specifically stated in the discord or on the forum by one of the developers.

Living and breathing Sublime as much as I have for the past 7 years, I’ve amassed somewhat of a knowledge without remembering where it came from. :smiley:

1 Like

#7

Do you have any more information or references on this "command" trick?

I’m trying to use it again and it just isn’t picking up on the command and I can’t for the life of me work out why it isn’t working for this particular command (which is working just fine in all the other ways).

I might need to wade into the discourse server on this … hoping I see my dumb mistake before then though.

0 Likes

#8

A common reason for this is the command not being mentioned anywhere in a sublime-commands file so that Sublime knows to put it into the command palette. Without that, you can’t ask the overlay to open on that command because it’s not in the list.

Apart from that, the other reasons why this might not work would be that the command has decided to disable itself or render itself invisible.

Commands that respond to the is_enabled() method by saying that they are not enabled can’t be triggered by keys, their menu entries would be disabled, and you also hide themselves from the command palette since you can’t execute them anyway.

Similarly for is_visible(), which a command can use to hide itself from view in the menu and command palette.

Such things are often context based, which can occasionally make it appear as if they are missing.

Not sure of any of this is the reason for the issue you’re seeing here, but I would definitely double check all of them first.

0 Likes