Sublime Forum

API Suggestions

#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

#95

Testing colour schemes

re: Testing color schemes

COLOR_SCHEME_TEST "color_scheme_name"

SYNTAX "source.php"
<?php
$variable = true;
//          ^^^^ fg=#xxxxxx bg=#xxxxxx font=name font_style=none

SYNTAX "python.py"
variable = True;
//         ^^^^ fg=#xxxxxx bg=#xxxxxx font=name font_style=none

 // ...

Importance High, because it will improve the quality of colour schemes greatly. And has the side-effect of improving syntaxes by way of bug reports by colour scheme developers.
Motivation Helps with creating robust colour schemes.

4 Likes

#96

Native dialogs for getExistingFileDialog(iniDir,extensions), getExistingDirectoryDialog(iniDir), etc. With help from the forum I have a plugin that does this (but it’s a bit clunky). Also GetColorDialog(initial) (currently a plugin which starts an external .exe) etc.

ETA:
This was meant as an API suggestion. I would like my plugin to be able to ask the user for the name of an existing directory.or file. I didn’t mean, for instance, that I want file>open on the menu to open a particular kind of native dialog

Eg

myDirectory = path_to_current_file()   
deliverydir = window.getExistingDirectory( myDirectory )    #  API Call
if not deliveryDir is None: 
   defaultDest[myDirectory]  = deliveryDir
   ...

I wrote a plugin to map SQL files from different parts of my source tree to another tree of files that need to be delivered to a customer. The plugin has commands to:

  • Copy the current file to a subdirectory of my delivery tree.
    • If the base of the delivery tree has not been identifed, allow the user to locate/create a base directory whose name is then saved in my project settings.
    • If a file has already been copied from the same directory, add it to the same delivery sub-dir
      • otherwise allow the user to create a new subdir in the delivery tree (starting from the base)
  • Add a line to my install.sql each time a new file is coped
  • Check that all my delivered files are up to date etc.

ETA: fixed error in example code, The code is still not technically correct

1 Like

#97

importance: minor/“fringe”

syntax.html gives an example of a PHP heredoc in which the end of the heredoc is matched using
-match: ^\1

\1 used to match a previously captured pattern.

I tried to do something similar in order to set a scope name according to a previously matched pattern

- match: "^\\s*([a-z.]+): .* // (.*)"
  captures:
    1: scope.name
    2: \1

the idea was to have a custom syntax for a .myScheme file (from which a standard tmScheme file would be generated), The source would preview itself in the comments.::

markup.deleted:   #a1000d        
meta.diff.header: #ffffff/#4e738a  // --- D:\st3portable\Data\Packages\MyScheme\x.txt
meta.diff.range:  #888888 <i>      // @@ -34,6 +34,5 @@

The first // comment would have scope name meta.diff.header and be shown as white text on a different background and the second comment would have scope meta.diff.range and text shown in grey italics.

(BTW: my suggestion is that \1 etc be allowed in the captures: list, unless it would open up a horrible can of worms)

ETA: I just noticed the suggestion for a YAML based format for tmscheme which would make my plugin immediately redundant. However maybe the YAML-solution could benefit from such a change.

0 Likes

#98

Introduce new optional parameter in run_command() method:

def run_command(command_name, cmd_params, lock=None)):

It would be wonderful if commands executed witch run_command could be synchronized by use of threading.Lock.

Thanks

0 Likes

API Suggestions Discussion: locks for run_command
#99

I would like to see a Block Decorations API like Atom has: http://blog.atom.io/2016/02/03/introducing-block-decorations.html

The API could be as simple as this:

ref = view.add_block_decoration(after_line=12, html=html_string)
view.remove_block_decoration(ref)

Presumably this could reuse the existing HTML library that is used for tooltips (with the same type of callbacks for links), but would display persistent but passive inline information between buffer lines.

This would be useful for extended linter information (instead of one line in the status bar), inline image previews, inline latex equation previews, inline documentation, ipython-notebook-style output, just to name a few off the top of my head. There is a lot of potential here and I’m sure people will come up with more ideas, so I would rate this as major.

5 Likes

#100

#+1
 



 
As a sidenote to this - I have a plugin concept that could greatly benefit from this functionality.  The plugin essentially allows users to define arbitrary code folding points ( as opposed to the default indentation-based system ) by implementing headers, which they can also use to quickly fold/zoom code, open specific sections in new views, navigate sections via quickpanel, etc.

Here are a few other demos.

 
Some areas where I could see benefit would be - rather than headers occupying the same line-space as code, headers could be in non-code space like:

1> here is
2> some code
////////// This Is A Header /////////
3> here is some more code

I believe this would allow for faster performance by allowing headers to be queried solely within block decorations, rather than performing a RegEx search over the entirety of code.
 



 
Some implementations of block decorations that would be useful:

  • tag : used to quickly group all block decorations of a particular tag into an array via
    tagArray = view.get_decorations( "tagName" )

  • data{} : “hidden” dictionary to store associated content ( EG: in the case of my header example, "indentation_level": 3 could be a stored value )

  • callback : allows callbacks to be run upon clicking block decorations ( Some sort of method to differentiate left, right, & double clicks might be useful. Also, allow keybinding contexts to implement the tag property along with is_block_decoration )

  • decoration.begin() & decoration.end() : return the same results as their region counterparts

  • fold markers : allow text to be folded “into” block decorations manually ( +1 for automatic fold-regions in between decorations as an option )

1 Like

#101

I agree it would be very useful to be able to ask the user for a path using the standard dialogs.
Right now we have very few options like using window.show_input_panel which requires the user to have copied the path by other means beforehand.

A simple API with callbacks would be just fine:

sublime.show_open_dialog(title:string, initial_path:string, open_dir:bool, on_done:callback, on_cancel:callback)
sublime.show_save_dialog(title:string, initial_path:string, on_done:callback, on_cancel:callback)
2 Likes

split this topic #102

A post was merged into an existing topic: Interface Suggestions

0 Likes

#103

Multiple gutter with event capability

Importance: medium

Motivation: Allow plugins to integrate better with sublime

There are few plugins that I could think of that would benefit on a better gutter:

  • plugins that are wrapper around debuggers will allow you to CRUD breakpoints. For this kind of plugins events are an absolute must.
  • plugins that are merely indicators: color/brackets/git/whatever highlights. For this kind of plugins events are kind of useless.

I believe that letting plugins to create their own gutters are a good idea as long it respects the following rules:

  1. Plugin can’t create their own gutter :smiley: User must allow in settings the „blessed” plugins, so they don’t end up with gutter hell.
  • User can’t allow more than X plugins to create gutters. In other words, sublime can have max of X gutters (for the same reason as above)
  • Current gutter remains, so all unblessed plugins fight for their place in the same way as they do today.

I think this should also be here:

9 Likes

#104

It would be nice to have a serializable undo redo/history. So we can undo after closing and reopening sublime… give an api so we do this as we wish.

7 Likes

#105

More flexible scope manipulation

Importance: high

Motivation: allow painless text manipulation by scopes

Working with scopes is a pain at the moment because we can’t be specific about extracting text for a given scope selector. Instead we have to use extract_scope(point) with its ‘intelligence’ which varies by language. Or, we use find_by_selector(selector), then iterate through the list of regions to find the one that intersects the position we want. Or we move position by position back and forth and check we are in/out of scope. These workarounds are labour & CPU intensive for what should be a very simple thing. The solution:

extract_scope(point, selector)

The above proposed change will extract the region for the given selector if provided. Better still would be:

extract_scope(point, selectors)

Where selectors is a space delimited string of selectors, the largest of which (except topmost source.*) is selected.

Finally we could have a greedy flag which allows the above API to choose the least or most specific selector:

extract_scope(point, selectors, greedy, single)

And the single flag will allow an individual scope to be extracted in the case where they are back to back (like <div><div><div>)

Rounding off, it would be useful to have more flexibility with find_by_selector(selector), so that we can restrict its operation to a given region or regions. Presently it returns all matching regions in the file, a performance overhead if one needs to iterate through it repeatedly.

find_by_selector(selector, Region or [Regions])

:slight_smile:

2 Likes

#106

Extend snippet/completion scope

(I’m assuming this qualifies as an API suggestion, I’m not entirely sure though)

One of the most frequent requests for my packages is extending the scope of snippets or completions to other syntaxes. I’ve had a situation where I was asked to extend the scope for HTML completions and add support for JSX. Immediately after those changes were applied, I got complaints from other users of my package about this change. It’s not always easy to judge whether such a change makes sense, especially if you’re not familiar with the syntax.

Therefor, I would love if Sublime Text would allow users to extend/manipulate the scope in which snippets/completions are working without having them to alter the actual files, e.g. in the user settings.

0 Likes

#107

Workspace APIs (for GIT branches)

I would like to write a plugin to change workspaces based on the current Git branch.

Currently changing branches in Git can leave the current workspace in a mess:

  • Files become unsaved if they do not exist in the new branch (they are removed from disk)
  • Files open may have nothing to do with the Git branch checkout
  • Need to close the branch irrelevant files
  • Need to reopen the branch relevant files

I tend to manually create a new workspace for each branch:

GIT.[Branchname].sublime-workspace

I have to manually switch workspaces after a checkout.
I have to manually delete workspaces when I delete the branch.

I would like to be able to load workspaces, create and delete them.

  • API to get the path of the current .sublime-workspace file
  • API to load a .sublime-workspace file (“Quick Switch Workspace”)
  • API to save a .sublime-workspace file (“Save Workspace As…”)
  • API to delete a .sublime-workspace file

Additionally, unrelated to workspaces, but useful for this plugin:

  • API to monitor specific file for changes

This would allow notification of when the .git/HEAD file is modified (when a checkout occurs), to trigger the workspace switch.

5 Likes

#108

An API to hide a set of lines matching a given criteria (regex or …). When called with None, unhide all hidden lines.

Once hidden, those lines would be excluded from search and edit operations. Similar to what the ‘ALL’ command does on XEDIT and similar editors.

To illustrate, here is a simple directory listing:

Then, after hidding the lines not containing ‘dir’:

Very handy while working with log files and line-oriented files (csv exports, …).

You can still view/search/edit the non-hidden lines, add new content, and so on.

1 Like

#109
  1. Select the lines you want to hide
  2. Menu Edit -> Code Folding -> Fold

You can use RegReplace to do it using REGEXP

1 Like

#110

Menu Edit -> Code Folding -> Fold

Nope:

those lines would be excluded from search and edit operations.

1 Like

#111

More consistent output panels

Output panels have really odd behaviors currently. In exec.py, there is this code:


if not hasattr(self, 'output_view'):
    # Try not to call get_output_panel until the regexes are assigned
    self.output_view = self.window.create_output_panel("exec")

# [...]

self.output_view.settings().set("result_file_regex", file_regex)
self.output_view.settings().set("result_line_regex", line_regex)
self.output_view.settings().set("result_base_dir", working_dir)
self.output_view.settings().set("word_wrap", word_wrap)
self.output_view.settings().set("line_numbers", False)
self.output_view.settings().set("gutter", False)
self.output_view.settings().set("scroll_past_end", False)
self.output_view.assign_syntax(syntax)

# Call create_output_panel a second time after assigning the above
# settings, so that it'll be picked up as a result buffer
self.window.create_output_panel("exec")

Observations:

  1. Window.create_output_panel is run twice. But only at the first time.
  2. calling .assign_syntax on the output panel turns it from a widget into an actual view. This causes it to infer its settings from the usual Preferences.sublime-settings files (or more likely, they are not overridden from some widget-specific thing). As a result, the output panel will have its gutter and line numbers visible, which exec.py has to disable explicitly. (more on this)
  3. On each call of Window.create_output_panel, its entire contents are erased. Settings are not reset, though.

Priority: minor (it’s “always” been like this and changing behavior of create_output_panel especially wrt 3. would be a breaking change)

Related: API Suggestions

3 Likes

[BUG ST2/3] set_syntax_file() clear 'is_widget' setting
#112

Putting scopes to work

So far, scopes use is limited: syntax coloration and some limited hard-coded features (‘go to symbol’, mostly).

What about extending them, in two ways:

  1. being able to specify a scope for the search/replace api (so that we could search/replace for a given expression in comments only, or not in comments, extract all test fragments with a given scope, like we currently extract the list of symbols, jump to the next or previous string (or any scope), and so on);
  2. being able to new ‘styling’ options for scopes, with styling being ‘editable/readonly’, or ‘searchable/notsearchable’, and so on.

Priority: minor

5 Likes