Skip to content

Commit

Permalink
Include a quick panel sample
Browse files Browse the repository at this point in the history
For developing OverrideAudit I worked out a simple way to allow for
simple navigation in a nested hierarchy of items, so I thought I would
include a small code sample of how to do that as an illustration for
others that may want to do something similar.
  • Loading branch information
OdatNurd committed Feb 25, 2017
1 parent 2b5a370 commit e102f84
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -46,6 +46,10 @@ The layout of the files here is:
Sublime API) to stop them from getting lost in the mists of time, although
I'm sure nobody would notice if they did.

* [quick_panel](quick_panel/README.md) is a list of examples for using the
Sublime text `quick_panel` in more complex ways than just a simple list of
text.

* [build_enhancements](build_enhancements/README.md) is similar to
[plugins](plugins/README.md) except that here the commands are for modifying
how a `sublime-build` file is used. This allows for things like custom
Expand Down
33 changes: 33 additions & 0 deletions quick_panel/README.md
@@ -0,0 +1,33 @@
Quick Panel
-----------

The python files in this directory are simple code samples for using the quick
panel API in Sublime text to display a list of items to the user. Since these
are samples, they don't perform a useful task, instead pointing out how you
might go about using the panel in a particular way.

Unlike some of the other items, unless otherwise noted the code samples here
are examples I worked up for my own use. This means that they don't contain a
link to further reading and instead have more verbose comments to describe how
to use them.

Note that there is no example here on the simplest use of the quick panel (i.e.
just presenting a single list of items), as such an example is available with
Sublime Text itself in the file `Packages\Default\quick_panel.py`.

### Usage

At the time of writing, each Python file contains a single Sublime Text command
(and any other required supporting code) which shows how to present the quick
panel in a certain way.

As they are examples they only show you how to present the panel and allow a
particular use case, leaving it up to you to decide what to do with the
information on what item was eventually selected.

### What they does

* [nested_panel.py](nested_panel.py) is an example of displaying a hierarchy of
items in a quick panel. Normally the list presents itself with a single list
of items, but here each item can trigger opening a new list of sub items or
allow you to go back to a previous level.
103 changes: 103 additions & 0 deletions quick_panel/nested_panel.py
@@ -0,0 +1,103 @@
import sublime
import sublime_plugin

# The sublime plugin API includes a method for showing a quick panel, which
# allows you to select from a list of items while doing some optional filtering
# if desired using the same fuzzy matching as you can in the command palette.
#
# This file shows an example of using a quick panel to select an item from a
# (potentially) hierarchical list, allowing for seamlessly traversing the
# hierarchy of items in both directions.
#
# The command here takes a list of dictionaries that describe the items to be
# selected. Each dictionary must contain a "caption" key to provide the text
# that is to be displayed in the list, and may also optionally contain a
# "children" key which, if present is a list of similar dictionaries for the
# items below this item in the hierarchy.
#
# The "caption" key may have a value that is a single string or a list of
# strings. In the latter case, the quick list will contain multiple lines for
# each entry.
#
# The command takes an optional argument of "prior_text", which defaults to ".."
# if not given and which represents the text displayed to allow the user to go
# back up the list of selected items.

# It's important to note that if you use a "caption" key in your list items
# which contains a list of strings (i.e. a multi-line entry), you must specify a
# similar list for "prior_text" as well or Sublime will throw an error. In
# practice you could fix this situation programmaticly but this is just an
# example.
#
# When an item with children is selected from the list, the list will
# automatically open to show those child nodes, along with an option to go back
# up the hierarchy.
#
# In use your code would do something more useful than print the item that was
# selected, such as running a command or some such.
#
# An example of this command in action can be achieved using the following key
# binding (change the key in the binding to something appropriate for your
# situation).
#
# {
# "keys": ["ctrl+alt+shift+t"],
# "command": "nested_quick_panel",
# "args": {
# "items": [
# { "caption": "Level 1, Item 1" },
# { "caption": "Level 1, Item 2" },
# { "caption": "Level 1, Item 3",
# "children": [
# { "caption": "Level 2, Item 1" },
# { "caption": "Level 2, Item 2",
# "children": [
# {"caption": "Level 3, Item 1"}
# ]
# }
# ]
# }
# ]
# }
# }

class NestedQuickPanelCommand(sublime_plugin.WindowCommand):
"""
This is an example of using a quick_panel to navigate through a list of
entries, allowing for some entries to contain sub lists.
The run method expects a list of dictionaries which each have a "caption"
key to determine what shows in the list and an optional "children" key
which, if it exists, has a value that is an array of dictionaries.
"""
def select_item(self, items, prior_text, stack, index):
if index >= 0:
# When stack is not empty, first item takes us back
if index == 0 and len(stack) > 0:
items = stack.pop()
return self.display_panel(items, stack)

# Compensate for the "prior_text" entry on a non-empty stack
if len(stack) > 0:
index -= 1

entry = items[index]
children = entry.get("children", None)

if children is not None:
stack.append(items)
return self.display_panel(children, prior_text, stack)

print("Selected item %d (%s)" % (index, entry))

def display_panel(self, items, prior_text, stack):
captions = [item["caption"] for item in items]
if len(stack) > 0:
captions.insert(0, prior_text)

self.window.show_quick_panel(
captions,
on_select=lambda index: self.select_item(items, prior_text, stack, index))

def run(self, items, prior_text=".."):
self.display_panel(items, prior_text, [])

0 comments on commit e102f84

Please sign in to comment.