Sublime Forum

API Suggestions

#71

Dynamic menu items

Importance: minor

Description: Fill a menu with items that are generated on the fly by plugins, like the syntax or color scheme selection, or recent files/projects in the main menu.

Motivation: Many plugins would like to add items to a menu dynamically, which is the only thing you can’t do with menus right now.

Details:

In a .sublime-menu file, you provide a { "source": "key" } entry for a menu item. If a menu is to be displayed with an entry like this, ST would go through all EventListeners and call their on_query_menu callback with the value of "source" as the first parameter, similar to completions. Plugins would then be able to provide a list of menu items of the same structure as in .sublime-menu files, including the ability to define more { "source": "key" } items.

Alternatively, the { "command": "$key" } syntax, as found in Main.sublime-menu, could be used.

Example:

Main.sublime-menu

[
    {
        "id": "preferences",
        "children": [
            {
                "caption": "Theme",
                "children": [
                    { "source": "my_menu" }
                ]
            }
        ]
    }
]

some.py

class MenuExpander(sublime_plugin.EventListener):
    def on_query_menu(self, key):
        if key != "my_menu":
            return
        theme_files = sublime.find_resources("*.sublime-theme")
        theme_names = set(path.rpartition("/")[2] for path in theme_files)
        
        return [{"command": "set_theme", "args": {"name": name}}
                for name in sorted(theme_names)]

class SetThemeCommand(sublime_plugin.ApplicationCommand):
    def description(self, name):
        return name
    
    def run(self, name):
        prefs = sublime.load_settings("Preferences.sublime-settings")
        prefs.set("theme", name)
        sublime.save_settings("Preferences.sublime-settings")
15 Likes

#72

Find out where a setting value in view.settings() was defined

Importance: minor

Description: Find out where a value in view.settings() was defined. Could also be useful for any other settings object returned by sublime.load_settings(...).

Motivation: There are a lot of places where a setting can be defined (Preferences.sublime-settings (default, user, any other package…), project, syntax.sublime-settings (also multiple possible), view) and this is specifically important when you need to know whether you are overriding a view-specific setting and whether you should re-set its old value or erase your custom setting to not make the value stick.
It would also help with debugging.

API:

source = view.settings().get_source(key)
# returns a string that could be a resource path or `"project"` or `"view"`

Corresponding github issues: #1003, #907

3 Likes

#74

Distinguish view types and get handles of special views

Importance: trivial

Description: Several API hooks get called for all view types, including the console input and output, quick panels, input panels, find panels, goto anything … There is view.settings().get('is_widget'), but it’s not documented and not a nice API.

Motivation: A way to distiguish these panels would be nice for fine-grained features such as providing completions and a properly documented API would certainly help with discoverability.

See also this issue for API ideas:

7 Likes

split this topic #75

A post was split to a new topic: API Suggestion Discussion: EventListener for Project Changes

0 Likes

#76

Please also fix this very annoying settings bug after cloning a view:

Priority for me: major

1 Like

split this topic #77

2 posts were merged into an existing topic: On after modified event

0 Likes

#79

Snippets In on_query_completions

Importance: Major

 
Another set of bugs that affect the existing API are:

I currently have an auto-completion plugin that’s about 80% done, which will allow users and developers to easily define context-sensitive completions via YAML files.  The macro-contexts are scope & location, and there is a micro-context that parses the current line’s text to allow nested completions.

 



 
Here is an example of a .custom-completions file that would add Sublime Text API completions only to python files contained within /Packages/.  It works great, with the exception that all buffer completions are overridden as mentioned in the issues above ( if certain snippet-particular characters are used ).

#▓▓▓▓▓║     Settings     ║▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

completionTrigger: "."

trailing_WhiteSpace_Enabled: false

scopeSelectors: [ "source.python" ]

locationContext_Mode: "Paths_StartWith"
locationContext_RegEx_Enabled: true
locationContexts: [ "(.*)(\\\\Sublime Text 3\\\\Packages\\\\)" ]

#▓▓▓▓▓║     completionSets     ║▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

completionSets:

	view:
		sel:                 "sel()"
		line( point ):       "line( ${1:__INTEGER__Point__} )"
		line( region ):      "line( ${1:__REGION__} )"
		full_line( point ):  "full_line( ${1:__INTEGER__Point__} )"
		full_line( region ): "full_line( ${1:__REGION__} )"
		lines:               "lines( ${1:__REGION__} )"
		split_by_newlines:   "split_by_newlines( ${1:__REGION__} )"
		word( point ):       "word( ${1:__INTEGER__Point__} )"
		word( region ):      "word( ${1:__REGION__} )"

	window:
		id:                   "id()"
		new_file:             "new_file()"
		open_file:            "open_file( ${1:__STRING__File__}, ${2:»__FLAGS__} )"
		find_open_file:       "find_open_file( ${1:__STRING__File__} )"
		active_view:          "active_view()"
		active_view_in_group: "active_view_in_group( ${1:__INTEGER__GroupNumber__} )"
		views:                "views()"
		views_in_group:       "views_in_group( ${1:__INTEGER__GroupNumber__} )"
		num_groups:           "num_groups()"
		active_group:         "active_group()"
		focus_group:          "focus_group( ${1:__INTEGER__GroupNumber__} )"
		focus_view:           "focus_view( ${1:__VIEW__} )"
5 Likes

#80

I would also like the option of hiding some of the statuses that are managed by sublime or even other packages.

Sometimes the default information from sublime is redundant to something your own plugin needs to display, in my case, an emacs-like incremental search package. If I could enumerate the existing status keys and hide them, perhaps for the duration of an input panel’s visibility or something like that.

2 Likes

#81

I would like to see an API to initialize settings in the find/replace forms.
eg.:
window.find.setRegex(true)
window.find.setFind("([0-9]{2}),([0-9]{2}),([0-9]{4})")
window.find.setReplace("\2.\1.\3")

window.find_in_files.add_directory( myParentDirectory() )
window.find_in_files.exclude_directory("./OLDFILES/./")

so that I could write macros/plugins to set up commonly used searches and then use normal find next/find prev/find all commands to process them with existing commands.

or maybe a way to set up search/replace snippets collection.

5 Likes

#84

No the goal is not to completely define a command’s key mapping within a plugin. The goal is remove plugin boilerplate, complexity, duplication, and performance footprint. I’ve update the post with extra details about motivation. I’ve removed the suggestion about defining the keys within the command itself, because I agree the keys should still be defined in the keymaps file.

0 Likes

#85

on_close event listeners should be able to abort the close action

Importance: Medium

Use case: a plugin may be managing a view with special functionality.
The view may even be set as scratch but contain information edited by the user.
The plugin should be able to detect the on_close event of such view and ask the user what to do with any un-committed changes.
A dialog can be displayed but a “Cancel” option cannot be currently cleanly implemented.

(Think of a thin client of some web API: edits may need to be uploaded to be saved)

6 Likes

pinned globally #86
0 Likes

#87

Addition to this: would also be useful for on_save/on_pre_save to prevent saving actions.

Github issue: https://github.com/SublimeTextIssues/Core/issues/821

2 Likes

#88

Easy way to set contents of a view

Importance: Low (because of the easy workarounds)

Description:
Currently, many plugins define simple TextCommands just to set the text of a view to precisely the contents of a string.
This duplication exists because the commands defined by ST do not handle new lines nicely, always trying to be too smart with indentation.

4 Likes

#89

API for transient/image views

Importance: Medium

See related post.

1 Like

#90

I would classify this as a bug, honestly. Maybe the commands should receive a few arguments that enable or disable this auto-indentation, but I agree that it’s very annoying. You always have to disable the setting before adding content to a view.

1 Like

#91

More general sublime.find_resources

Importance: Medium

Use cases: you want to find a settings/keymap/sublime resource file, using the same “path-resolution” strategy that ST uses internally.
For example, you may want to examine the settings for Ruby files, which may be overwritten in many places such as your User folder.
An advantage of having an API for this is that if the mechanism changes in ST, the plugins would still pick up the right file.

Secondly, find_resources should also work with fully specified paths or patterns including folders.

6 Likes

#92

Getting the syntax file from extension/scope

Importance: Medium

Use case:
Different users may have installed different custom/plugin syntaxes for some file types.
Suppose your plugin wants to display some information in Markdown in a custom view.
Which syntax do you set? Ideally you want to ask ST to set the syntax to whichever syntax the user set for Markdown.

6 Likes

#93

Get the entire contents of a view as a string

class View(object):
    def to_str(self):
        return self.view.substr(sublime.Region(0, self.view.size()))

Importance Low

Motivation Removes boilerplate and complexity

4 Likes

#94

This would remove such boilerplate as the following which should be an unnecessary command:

class __plugin_name_view_replace(sublime_plugin.TextCommand):

    def run(self, edit, text):
        self.view.replace(edit, sublime.Region(0, self.view.size()), text)
1 Like