Sublime Forum

Simple example ListInputHandler

#1

I want to display some list items in the Command Palette and on the selection of one of the item , I wanr to run a particular function. How can I achieve it ?

0 Likes

#2

You could use window.show_quick_panel that takes a list of items (as strings) and then invoke your function in the on_done method (or whatever is the name of your callback) based on what item is selected.

import sublime
import sublime_plugin

class ExampleCommand(sublime_plugin.WindowCommand):

	def run(self):
		items = ["Item 1", "Item 2", "Item 3"]
		self.window.show_quick_panel(items, lambda id: self.on_done(id, items))

	def on_done(self, id, items):
		if id >= 0 and items[id] == "Item 2":
			# Invoke a function because Item 2 was selected
			pass

1 Like

#3

Thanks, @UltraInstinct05.
I was able to do get list. But I was trying to get another list of sub-items under one item.

for example
main_items = [“Item 1”, “Item 2”, “Item 3”]
under this each item I’m having
item1_elemnts = [“one”,“two”,]

In such way, How could I add this additional functionality

0 Likes

#4

That’s a bit more involved. Essentially you could have a list of tuples with each tuple having it’s second value as another list. Something like the following :-

import sublime
import sublime_plugin

class ExampleCommand(sublime_plugin.WindowCommand):

	def run(self):

		# We want to show a panel for each list associated with the first item for each tuple in the following list of tuples.
		items = [
			("Item 1", ["Item 11", "Item 12", "Item 13"]),
			("Item 2", ["Item 21", "Item 22", "Item 23"]),
			("Item 3", ["Item 31", "Item 32", "Item 33"])
		]

		# Collect the first item for each tuple
		first_level = [key for key, value in items]

		# Trigger the first show panel and pass on the id of the selected item & the items
		self.window.show_quick_panel(first_level, lambda id_1: self.on_done(id_1, items))

	def on_done(self, id_1, items):
		if id_1 >= 0:

			# Trigger the second show panel (with the second item of the selected tuple as the list) & pass on both id's with the list.
			self.window.show_quick_panel(items[id_1][1], lambda id_2: self.on_done2(id_2, id_1, items))

	def on_done2(self, id_2, id_1, items):
		if id_2 >= 0:

			# Print the final choice 
			print(items[id_1][1][id_2])

You can make this a bit easier by making the items global (which eliminates the need to pass it every time in successive callback functions). However this quickly gets complicated if your items structure is more complex & some kind of tracking of the items, their id etc will be required for such cases I presume.

1 Like

#5

My use case here is bit different. I have 4 items in main_items list and out of 3 can directly evoke its function but the last one is having some more sub-options and functions and here it need to show more option depending on them function should run

0 Likes

#6

Thanks @UltraInstinct05.
I was able to implement required functionality with the help of your code.

how to evoke this command on some event? I tried to call this Class but was facing issue to evoke it

0 Likes

#7

What event do you want it to be triggered for. And what issues are you facing wrt it ?

0 Likes

#8

I had value x, if x is false I need to show those items from the list

if x is False:
    ExampleCommand()

How to call this class ?

0 Likes

#9

If x is a hard coded boolean value or some expression that evaluates to a boolean, you can do something like this :-

import sublime
import sublime_plugin

class ExampleCommand(sublime_plugin.WindowCommand):

	def run(self):
		x = False
		if not x:
			items = ["Item 1", "Item 2", "Item 3"]
			self.window.show_quick_panel(items, lambda id: self.on_done(id, items))
		else:
			# Either exit silently or put some error message or do something else.
			pass

	def on_done(self, id, items):
		if id >= 0:
			print(items[id])

i.e. run the show_quick_panel code only if x is False otherwise do something else.

Note : As fas as I know, if you have a command class ExampleCommand, you don’t usually run it by instantiating it like you have tried above (you can do it of course but I haven’t see anyone doing it so far) but by doing window.run_command("example") in your code if ExampleCommand is already defined.

1 Like

#10

window.run_command("example")

I think this will work for me.

0 Likes

#11

Is it possible to provide exit option in command palette that should close command palette ? or implicitly call ESC key press event ?

0 Likes

#12

You can use the in built hide_overlay command to hide the active overlay (the command palette is an example of an overlay).
Running window.run_command("hide_overlay") from the console should hide the command palette if it’s open.

1 Like

#13
items = [
			("Item 1", ["Item 11", "Item 12", "Item 13"]),
			("Item 2", ["Item 21", "Item 22", "Item 23"]),
			("Item 3", ["Item 31", "Item 32", "Item 33"])
		]

I was able to access particular elements with above’s example. Is it possible to build this items variable dynamically.I had items 1, 2, 3 but I want to fetch the inner list of dynamically at run time depending upon which item was selected.

Initially, the user will see only item1,item2, item3. Suppose he selects item2 then I want to show him a new list of items which will be fetched from API (this list will have text to show and id to pass,a tuple)
[("text to show"),("id to pass to the code"), ....]

How could I build this into command palette?

0 Likes