Sublime Forum

Command to highlight words from a set in a visible region

#1

Hi.

I am having a hard time figuring out highlighting regions and all that. I have read the API documentation and looked at many plugins, but I still don’t understand something very simple.

Let’s say I have a set containing certain strings.

stopWords = 'word1', 'word2', 'word3']

I would like to run a sublime command that will highlight all the words that are in this set.

Now the context in which I am working looks like this:

class HighlightStopWordsCommand(sublime_plugin.TextCommand):
    def __init__(self, view):
        self.view = view
        stopWords = 'word1', 'word2', 'word3']
        self.view.add_regions("inset", ???, "comment")

but I don’t know how to finish it. How can I highlight all the stopWords on running this command?

Also – how can I make a distinction between checking the entire file and only the part of the file that the user currently sees (so that the command will be run again when the user scrolls to a different portion of the text)?

I understand both of these things are simple for those who know them… hence your tips will be greatly appreciated.

All best,
Tench

0 Likes

#2

The ??? should be filled with a list of regions. Regions can be gathered in a couple different ways. There are a number of methods that return regions (view#line, view#word, etc). If you have the end points, you can manually create a region by calling “sublime.Region(start, end)”

For example, in the console enter the following (ensure that the view has some characters in it). You could also use a small plugin, but it’s pretty short and isn’t really necessary to demonstrate the usage of add_regions.

r = sublime.Region(0, view.size())
view.add_regions("test", [r], "comment")

The entire contents of the view will be highlighted. Of course, you may use something live view#find to get the regions.

0 Likes

#3

This is great, thanks so much! I think I am finally beginning to understand what regions are.

A region is a set of character offsets which can then be converted to a string, which can then be split into individual words etc.

r = sublime.Region(0, view.size())
text = self.view.substr(r)
words = text.split()

Now, to get only the visible region, one can do:

vis = self.view.visible_region()

and proceed from there.

But I have two pieces of the puzzle missing.

  1. How can I get individual words (see above) AND their individual offset points (i.e. have my cake and eat it) limited only to the visible region? I need to know individual words because I need to process them, but I need to keep an association between these individual words and the corresponding regions (offset points) so that I can edit them, replace them etc

  2. How I can keep executing my command as new regions become visible, i.e. come into view. I was hoping for an event listener to that effect, but I am not finding one.

Any advice?

Many thanks in advance.

All best,
Tench

0 Likes

#4
  1. You’ll have to manually check to see if they’re in the visible region. I believe regions support the “in” operator.
  2. There is no such callback - you’ll have to poll to see if the view changes.
0 Likes

#5

Why do you want to set up regions for only the visible portion instead of the entire file? It seems like that will substantially complicate things with no apparent benefit (to me).

0 Likes

#6

thanks for you messages guys.

i have to work with visible regions only because my files are very big and i need to do a lot of stuff with words programmatically (check spelling in different languages, lemmatize, check against different dictionaries, save individual words in different files etc…) so there is no way i can work with the whole file.

i kind of got it to work but it’s not pretty. it would be much, much better if find_all would give me the option to search only within a given scope. but i have learned a lot about sublime and python while working on this, it’s been actually a lot of fun.

by the way, does anybody have an example of a polling function in a sublime plugin? i am having a hard time pulling one together. i need to check periodically if the values of visible_region have changed (i.e. if there was any and how much scrolling done) and then execute a thread.

if you have something or can point to a link, i’d greatly appreciate it.

0 Likes

#7

You could probably just use sublime.set_timeout, and have the function just reschedule itself every time it runs.

0 Likes

#8

thanks a lot for your help!

0 Likes