Sublime Forum

Help needed with a simple filter plugin

#1

I’m trying to create a plugin but I’m at a loss because I’ve never written anything in python (and I also don’t know anything about the Sublime Text API). Despite these significant shortcomings, I think my plugin is rather simple and I’m hoping someone can show me what I’m doing wrong to make this work.

My intention is that this plugin can be run when a single selection is made in the document, and after having been run, all lines containing that selection will no longer be in the document. This plugin has a dependency on the grep command being available. The plugin, based on “external command” (found on this forum), should be passing the entire document through "grep -v " to perform the filter.

My current attempt looks like:

[code]import sublime
import sublime_plugin
import subprocess

view.run_command(‘selection_filter’)

class SelectionFilterCommand(sublime_plugin.TextCommand):
def run(self, edit):
regions = self.view.sel()
if len(regions) == 1 and not regions[0].empty():
self.runFilter(edit, regions[0])

def runFilter(self, edit, textToFilter):
command = "grep -v " + textToFilter
document = sublime.Region(0, self.view.size())
p = subprocess.Popen(command, shell=True, bufsize=-1,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
output, error = p.communicate(self.view.substr(document).encode(‘utf-8’))
if error:
sublime.error_message(error.decode(‘utf-8’))
else:
self.view.replace(edit, document, output.decode(‘utf-8’))[/code]

Problem #1: when I try to run this with a single word selected, I receive the following error:

[quote]Traceback (most recent call last):
File “.\sublime_plugin.py”, line 282, in run_
File “.\selection_filter.py”, line 10, in run
self.runFilter(edit, regions[0])
File “.\selection_filter.py”, line 14, in runFilter
command = "grep -v " + textToFilter
TypeError: cannot concatenate ‘str’ and ‘Region’ objects[/quote]

I’ve no idea how to address this.

Problem #2: Currently I’m not doing any sanity checking on the selection other than making sure there’s only one, and it’s not empty. Once problem#1 is solved, this will be an issue since the selection could be, for example, “word1 word2” which would create an external command of “grep -v word1 word2” and this would fail, looking for file word2 to grep in, probably destroying the current edit buffer. How to I make sure my selection (regions[0]) does not contain any space, newline, or other special characters (such as an ampersand or semi-colon)?

Thanks much…
mah

0 Likes

Fold Away Lines Not Matching A Pattern
#2

Hi meh,

When calling a method in Python with a context (eg. self.doSomething()) Python will automatically pass the context as first the parameter (self). This means you don’t need to specify it yourself so your call to self.runFilter(self, edit, regions[0]) can be changed to self.runFilter(edit, regions[0])

0 Likes

#3

Update:

I’ve got my initial problem solved, using the following:

[code]import sublime
import sublime_plugin
import subprocess

view.run_command(‘selection_filter’)

class SelectionFilterCommand(sublime_plugin.TextCommand):
def run(self, edit):
regions = self.view.sel()
if len(regions) == 1 and not regions[0].empty():
self.runFilter(edit, self.view.substr(regions[0]))

def runFilter(self, edit, textToFilter):
command = "grep -v " + textToFilter
document = sublime.Region(0, self.view.size())
p = subprocess.Popen(command, shell=True, bufsize=-1,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
output, error = p.communicate(self.view.substr(document).encode(‘utf-8’))
if error:
sublime.error_message(error.decode(‘utf-8’))
else:
self.view.replace(edit, document, output.decode(‘utf-8’))[/code]

I don’t really consider this suitable for sharing yet due to problem #2 listed above… if anyone can help I’d appreciate it (and maybe others would too). Thanks!

0 Likes

#4

Thanks jopdeklein; that’s one problem solved and now I’m functional, just without protection from a bad selection.

0 Likes

#5

Not exactly sure what you are looking for, but I believe this should allow only letters, digits, and underscores characters in your selection. You can tweak the regex to search exactly what you want to exclude from your selection.

[code]import sublime
import sublime_plugin
import subprocess
import re

view.run_command(‘selection_filter’)

class SelectionFilterCommand(sublime_plugin.TextCommand):
def run(self, edit):
regions = self.view.sel()
if len(regions) == 1 and not regions[0].empty():
target = self.view.substr(regions[0])
if re.search("\W]+", target) == None:
self.runFilter(edit, target)

def runFilter(self, edit, textToFilter):
    command = "grep -v " + textToFilter
    document = sublime.Region(0, self.view.size())
    p = subprocess.Popen(command, shell=True, bufsize=-1,
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                         stdin=subprocess.PIPE)
    output, error = p.communicate(self.view.substr(document).encode('utf-8'))
    if error:
        sublime.error_message(error.decode('utf-8'))
    else:
        self.view.replace(edit, document, output.decode('utf-8'))

[/code]

0 Likes

#6

Thanks facelessuser, that gave me enough to research further with.

0 Likes

#7

Hi. I’m very new to text editors. I’m using Sublime Text because I’m fed up with the MS Word bloat and its outline numbering insanity. I’m not sure Sublime will fit the bill on the outline numbering, but the code folding is a great feature.

I’m replying to this particular post because the ability to filter matching lines is THE main feature that is missing from Sublime Text for me. I’m using another product, Noteliner, for this feature but would like to standardize on Sublime Text.

Specifically, a search for “Mary” with below, would return rows 1,2 and 3 though a switch to just return row 3 (no ancestor) would be helpful too. Rows 4,5 and 6 would not be displayed.

1 Grandma
2 …Mom
3…Mary
4 Grandpa
5…Dad
6…Bob

I’ll keep monitoring this post and others for a solution.

Thanks,
Ryan

0 Likes

#8

http://gmh.akalias.net/Untitled\Untitled_media\Untitled.gif

It runs a regex search as you type, folding out anything that isn’t +/- $lines from the found regions, so as to only show relevant context (like grep). If you press enter to commit it’ll delete any of those red dot marked (in the gutter) lines. In either case, pressing enter or escape closes the input panel and the initial view folding/selections are restored. You can see there’s a Zebra striping pattern surrounding contexts indicating contiguous lines, without recourse to getting dirty in the gutter.

If you can somehow prove that you have a registered copy of Sublime I’ll give you access.

0 Likes

#9

Thanks, Castles. That’s exactly what I’m looking for. I sent you a private message with the Sublime license code I just purchased.

0 Likes

#10

Hey Castles_made_of_Sand, I bought the Sublime Text license and sent it to you. Can you share your grep/filter-in-place method please? Thanks.

0 Likes

#11

Hey sorry dude, I missed this, I’ll sort this out for you at lunch.

0 Likes

#12

[quote=“castles_made_of_sand”]http://gmh.akalias.net/Untitled\Untitled_media\Untitled.gif
It runs a regex search as you type, folding out anything that isn’t +/- $lines from the found regions, so as to only show relevant context (like grep). If you press enter to commit it’ll delete any of those red dot marked (in the gutter) lines. In either case, pressing enter or escape closes the input panel and the initial view folding/selections are restored. You can see there’s a Zebra striping pattern surrounding contexts indicating contiguous lines, without recourse to getting dirty in the gutter.
[/quote]

Would you consider releasing the source for this, or as a plugin? There seems to be some interest in something like this: eg.

And for people who want something like orgmode-like (of which the plugin development seems to have stalled)

0 Likes

#13

I think I lost that code in the great hard drive failure of back when. I don’t recall it being all that hard to write though. Pester me at ndudfield@gmail.com Ill see if its still somewhere.

0 Likes