Sublime Forum

Idee for a plugin called "Yet Another Launcher" - please comment

#1

Hello,

currently I am looking for a plugin that can launch various local files or directories with the operating system file manager or the corresponding app. It should also be able to launch websites in the browser.

Ideally I would like to define various launch items (local files (e.g. office files, pdfs), local directories and web sites) in an user settings file and call the launcher either via a shortcut or command palette. After launching I can fuzzy select the thing I would like to launch.

I have looked at PackageControl but I didn’t found one. Although being a newbie myself I started to write a plugin myself.

First here is a rough sketch that outlines my idea, currently the launcher can be launched via the console with the command window.run_command("launcher").

Before I spent more time to developing it I would like to know if a similar package is already there. If not I will try to enhance it and will post it to github if it can do more.

Current tasks:

  • find out how to bind window.run_command("launcher") to a keymap (solved)
  • adding launch command to command palette & to the tools menu (solved)
  • build a correct package
  • add checks & exceptions
  • find out how to get the launch_items definition in the users package settings of the plugin and how to parse that
  • adding an addition layer to the launcher that contains a third value like file, url, file+subl (where file+subl would open the file directly in ST 3)

Any feedback or pointing to the right direction would be appreciated.

import sublime
import sublime_plugin
import os
import subprocess
import sys
import webbrowser


launch_items = {
    "Head First Python": "C:\\Users\\bine\\Dropbox\\apps\\O'Reilly Media\\Head First Python\\Head First Python.pdf",
    "Introducing Python": "C:\\Users\\bine\\Dropbox\\apps\\O'Reilly Media\\Introducing Python\\Introducing Python.pdf",
    "Python Cookbook": "C:\\Users\\bine\\Dropbox\\apps\\O'Reilly Media\\Python Cookbook\\Python Cookbook.pdf",
    "Programming Python": "C:\\Users\\bine\\Dropbox\\apps\\O'Reilly Media\\Programming Python\\Programming Python.pdf",
    "O' Reilly Apps Directory": "C:\\Users\\bine\\Dropbox\\apps\\O'Reilly Media\\",
    "Sublime Text 3 - Api Reference": "http://www.sublimetext.com/docs/3/api_reference.html"
}


class LauncherCommand(sublime_plugin.WindowCommand):

    def run(self):
        items = sorted(list(launch_items.keys()))
        self.window.show_quick_panel(items, self.on_done)

    def on_done(self, choice):
        if choice >= 0:
            items = sorted(list(launch_items.keys()))
            path = launch_items[items[choice]]
            if path.startswith('http://') or path.startswith('https://'):
                webbrowser.open(path, 2, True)
                return
            if not os.path.exists(path):
                sublime.message_dialog(
                    '"' + path + '"' +
                    "isn't a valid path and can't be opened!")
                return False
            # Windows
            if os.name == "nt":
                os.startfile(path)
            # Macintosh - not tested yet
            elif sys.platform == "darwin":
                subprocess.call(['open', path])
            # Generisches Unix (X11) - not tested yet
            else:
                subprocess.call(['xdg-open', path])
0 Likes

#2

There is the sidebarEnhancements that give the option to open a file with a fixed extension with an application. it miss an implementation for command shell

0 Likes

#3

Hi @gasp10,

I know. But I want to use ST more as a cockpit to launch various useful documents, tools or websites. I don’t want to navigate to those folders before in the sidebar.

The main reasoning is that I use a portable ST in various Windows environments (local, Terminal server) and so can I easily take the links to those files, websites with me and easily launch them.

0 Likes

#4

Wouldn’t it be nice if you could just send any string to the command? It’s pretty easy to get the string or line under the caret and you could even leverage multi-cursor to open multiple files at once. Just brainstorming here. At least with open on a mac you can just throw anything at it and it will try to open it in the appropriate app.

FYI I use a combination of Open in Default Application and Open URL for things like this and they’ll have a bunch of stuff you can steal.

0 Likes

#5

Thanks @braver for mentioning both packages. I will have a look at.

Currently I am building the package directory structure and figuring out how I can get the user setting to the package that I am building. In that way the user can define in JSON the launchable items and the package will use them.

My intend for the package is to use it as a launchpad for predefined items that are unrelated to the content of the view. :slight_smile:

0 Likes

#6

There are several ways to go depending on how you want to store the information for later retrieval.

For example, you could store your launch items like this inside of your user preferences, alongside your regular Sublime text preferences:

{
	"launch_items": {
		"API Reference": "http://place.com/page.html"
	},
	"theme": "Adaptive.sublime-theme"
}

With this in place, code such as the following allows you to get at your list of configured launch items (this is output from interactively entering the code in the Sublime console):

>>> settings = sublime.load_settings("Preferences.sublime-settings")
>>> settings.get("launch_items")
{'API Reference': 'http://place.com/page.html'}

Since the default preferences are applied to all views, if you wanted to you could also do the following (although as you noted above you don’t want to be tied to the view, so this is just for explanatory purposes):

>>> view.settings().get("launch_items")
{'API Reference': 'http://place.com/page.html'}

Alternatively, you could put your settings in your own custom settings file, such as MyLauncherPlugin.sublime-settings, which could be either in your User package, in the directory of the package that you’re creating, or both (in which case they blend together).

If you do that, you can use the load_settings code above to load this settings file instead, but you can’t query the view for them. Note also that since Sublime is blending all of the settings together, you just specify the name of the file and not the name of the package to get it from.

Another option would be to store it at a regular JSON file in your package (again, any package you want). An example of that is the following file, which here is just the actual launch items themselves as a JSON dictionary object:

####Packages/User/Launch-Items.json

{
    "API Reference": "http://place.com/page.html"
}

Now you can load and parse the JSON with this (but be wary that decode_value throws an exception if the JSON is not valid):

>>> content = sublime.load_resource("Packages/User/Launch-Items.json")
>>> dict_object = sublime.decode_value(content)
>>> dict_object
{'API Reference': 'http://place.com/page.html'}

Which method you use is entirely up to you, of course. If you decide to put the data into the regular preferences you probably want to choose a setting name that includes the name of your package (or some part of it) to provide a sort of “namespace” so that your setting doesn’t collide with something else.

2 Likes

[Solved] Is it possible to get somehow all settings keys?
#7

I would add that it’s kinda sloppy to put things in the general settings unless you need them tied to a view (e.g. if they could be syntax specific).

1 Like

#8

Indeed, as a personal preference I would also implement it by keeping the launcher settings separate from the standard user preferences. It seems cleaner to keep settings for different packages distinct in different files (to me at least).

I would also add that since your stub code looks like you want to support all Sublime platforms, as a person that uses all three platforms and keeps settings synced, a nice touch would be including platform somewhere in the configuration of launch items.

For example, I may have the same documents available but in different paths, or extra documents on one platform than another, etc.

1 Like