Sublime Forum

Need help with multiple show_input_panel

#1

Hi Guys,
This is my first try to create a plugin in Sublime 3.

Well, I’m trying to append a system command by the user input and then to make in run on my OSx.
For example: “filename.sh argv1 argv2 argv3”
So I used show_input_panel which is great but I can use it only 1 time for the first argument.

If I’m trying to make multiple (another) show_input_panel I’m getting error:

AttributeError: 'NoneType' object has no attribute 'show_input_panel'

Is there a good way to get multiple input from the user?

Thanks!!
Adir

0 Likes

#2

If you can post some code, we can likely help more. You can call subsequent input panels from the callback of another input panel.

0 Likes

#3

Sure.
Here is my code, in this example only the 2nd show_input_panel is working (skip on the first one)

import sublime, sublime_plugin, ntpath, os

view = sublime.Window.active_view(sublime.active_window())
filename = ntpath.basename(view.file_name())
command = "bash script.sh " + filename

class RunplCommand(sublime_plugin.WindowCommand):
    def run(self):
        self.window.show_input_panel("Please enter the directory name:", "something", self.on_done1, None, None)
        self.window.show_input_panel("Please enter the desired examples photo range, ex: 40-250", "", self.on_done1, None, None)

    def on_done1(self, user_input):
        global command
        command = command + " " + user_input
        print (command)

And, as you suggested, I can call it from a callback, and it’s working! but it’s a bit ugly - especially when I have 5 agrvs
for example:

mport sublime, sublime_plugin, ntpath, os
import subprocess as sub

view = sublime.Window.active_view(sublime.active_window())
filename = ntpath.basename(view.file_name())
command = "ssh script.sh " + filename

class RunplCommand(sublime_plugin.WindowCommand):
    def run(self):
        self.window.show_input_panel("Please enter the directory name:", "something", self.on_done1, None, None)

    def on_done1(self, user_input):
        global command
        command = command + " " + user_input
        self.window.show_input_panel("Please enter the desired examples photo range, ex: 40-250", "", self.on_done2, None, None)
        #print (command)

    def on_done2 ...

Is there any other way to do it? and why the first code skips to the last user input?

0 Likes

#4

The reason you only see one prompt is window#show_input_panel is non blocking. As it returns immediately, it “runs” the next input immediately. Of course, since there is already an input panel showing, it likely ignores the second call.

You can do something like the following to clean up.

[code]class TestCommand(sublime_plugin.WindowCommand):
def run(self):
self.command = “”
self.counter = 0
self.prompts = “prompt1”, “prompt2”, “prompt3”]
self.show_prompt()

def on_done(self, content):
    self.command += "%s " % content
    self.counter += 1
    if self.counter < len(self.prompts):
        self.show_prompt()
    else:
        self.input_done()

def input_done(self):
    print(self.command)

def show_prompt(self):
    self.window.show_input_panel(self.prompts[self.counter], "", self.on_done, None, None)[/code]

As a side note, you probably don’t want to derive the filename and view like that. The way you have it, if you run the plugin on a view that is different from when the plugin loaded, it will likely fail. In addition, in ST3, the entire api is not available until after plugin_loaded has been executed. From the API docs (sublimetext.com/docs/3/api_reference.html)

0 Likes

#5

Thank a lot for the explanation.
that’s much better.

0 Likes