Sublime Forum

New Erase Blank Chars Plugin

#1

hello

I was missing a command to erase only blank chars (\n, \r, \r and nbsp).

so I did a simple plugin and assigned to ctrl+shift+delete and ctrl+shift+backspace

import sublime, sublimeplugin, re

class RightEraseBlankCharsCommand(sublimeplugin.TextCommand):
    def run(self, view, args):
        
        pt = re.compile(r" \n\r\t]");
        sz = view.size();
        
        for region in view.sel():
			p = region.begin()
			
			while pt.match(view.substr(p)) and p < sz :
				view.erase(sublime.Region(p,p+1))

class LeftEraseBlankCharsCommand(sublimeplugin.TextCommand):
    def run(self, view, args):

		pt = re.compile(r" \n\r\t]");
		sz = view.size();
		
		for region in view.sel():
			p = region.end()-1
			
			while p > 1 and pt.match(view.substr(p)) :
				view.erase(sublime.Region(p,p+1))
				p -= 1

I couldn’t think of anything better, but it works :stuck_out_tongue:

if you can, please help improving it

I hope it’s useful, at least it is for me

bye

0 Likes

Small bugs
#2

wow! I just learned about/got confused by python!

The one thing I would do differently is process view.line(region) instead of the original region.

This is what I use to remove trailing whitespaces:

for region in view.sel():
	self.processRegion(view, view.line(region))

def processRegion(self, view, region):
	s = view.substr(region)
	out = u"\n".join()
	view.replace(region, out)

Does rstrip() do the same thing as the regex?

My take on removing leading blank chars is to press Ctrl-Shift-Tab a few times. But if the indentation is very large, here’s how I do it:

  • Make a selection or press Ctrl-A to select everything
  • Press Ctrl-Shift-L to split the selection into lines
  • Press Home to go to the first non-whitespace character of each selected line
  • Press Shift-Home to select the leading whitespace
  • Press Delete to delete the whitespace

That’s a lot of keypresses but it shows of one the many wonders of multiple selection :wink:

0 Likes

#3

Hi, I made a little improvement. It’s very useful for me and I like it.

I don’t know if you got the point of my commands. Sublime’s default “ctrl+del” removes whites paces PLUS a word (\s*(\w+|^\w]+) in regex). And I want to remove the white spaces OR a word OR symbols ((\w+|\s+|^\w\s]+) in regex). And the same for ctrl+backspace.

Now I made it behave in my way. It removes according to the region’s first char(for del) or last char(for backspace). If fist char is an blank space (\s) it removes only blank spaces. And so on for word characters (\w) and for symbols (^\w\s]).

I’m not used with Python tricks, so I wrote it step by step. If someone can improve it I’ll be glad.

import sublime, sublimeplugin, re


class RightEraseByCharClassCommand(sublimeplugin.TextCommand):
    def run(self, view, args):
        
        # patterns
		pt_s = re.compile(r"\s")
		pt_w = re.compile(r"\w")
		pt_o = re.compile(r"^\w\s]")
		
		sz = view.size()
        
		for region in view.sel():
			pos = region.begin()
			
			# check first char
			if pt_w.match(view.substr(pos)) :
				pt = pt_w
			elif pt_s.match(view.substr(pos)) :
				pt = pt_s
			else :
				pt = pt_o
			
			# removes according to first char
			while pt.match(view.substr(pos)) and pos < sz :
				view.erase(sublime.Region(pos,pos+1))


class LeftEraseByCharClassCommand(sublimeplugin.TextCommand):
	def run(self, view, args):
		
		# patterns
		pt_s = re.compile(r"\s")
		pt_w = re.compile(r"\w")
		pt_o = re.compile(r"^\w\s]")
		
		for region in view.sel():
			pos = region.end()-1
			
			# check last char
			if pt_w.match(view.substr(pos)) :
				pt = pt_w
			elif pt_s.match(view.substr(pos)) :
				pt = pt_s
			else :
				pt = pt_o
			
			# removes according to last char
			while pos > 1 and pt.match(view.substr(pos)) :
				view.erase(sublime.Region(pos,pos+1))
				pos -= 1

Bindings:

	<binding key="ctrl+backspace" command="leftEraseByCharClass"/>
	<binding key="ctrl+delete" command="rightEraseByCharClass"/>

thanks and bye

0 Likes

#4

Sorry, but does this plug in strip all trailing white spaces during file saving? I’m looking for a plug in that does that and not sure if this is what I need.

0 Likes

#5

Nope, not during save. But I’m sure someone can make a plugin using onSave with findall() :smiley:

EDIT: Looks like your in for some luck =]
STRIP TRAILING ON SAVE
viewtopic.php?p=1540#p1540

Now let’s see if sublimator wants to update it to use findall()

0 Likes

#6

I think you could do something like this:

[code]import sublime, sublimeplugin

class RemoveTrailingWhiteSpaceOnSave(sublimeplugin.Plugin):
def onPreSave(self, view):
region = sublime.Region(0L, view.size())
s = view.substr(region)
out = u"\n".join()
view.replace(region, out)[/code]

0 Likes

#7

[quote=“sublimator”]http://pastie.org/516119

The version in pastie above has an onPreSave and a run.

The run() version forcefully destroys all trailing space

The onPreSave() will use an heuristic to determine if you have recently pressed enter, and if so it won’t delete that indented space. It will also not strip any trailing space inside any regions scoped as string ( which might get annoying for some source code ) Use run() to forcefully strip all or modify onPreSave as you see fit.[/quote]

Nice one! Thx :smile:

0 Likes

#8

I tried updating the example plugin posted by eric1235711 so that it works with ST2 2.0.1/2217, and got most of it working, but am still receiving an error: TypeError: run() takes exactly 3 arguments (2 given). Here is the updated code so far:

{ "keys": "f1"], "command": "left_erase_by_char_class" }, { "keys": "f2"], "command": "right_erase_by_char_class" },

[code]import sublime, sublime_plugin, re

class RightEraseByCharClassCommand(sublime_plugin.TextCommand):
def run(self, view, args):

        # patterns
      pt_s = re.compile(r"\s")
      pt_w = re.compile(r"\w")
      pt_o = re.compile(r"^\w\s]")
      
      sz = view.size()
       
      for region in view.sel():
         pos = region.begin()
         
         # check first char
         if pt_w.match(view.substr(pos)) :
            pt = pt_w
         elif pt_s.match(view.substr(pos)) :
            pt = pt_s
         else :
            pt = pt_o
         
         # removes according to first char
         while pt.match(view.substr(pos)) and pos < sz :
            view.erase(sublime.Region(pos,pos+1))

class LeftEraseByCharClassCommand(sublime_plugin.TextCommand):
def run(self, view, args):

      # patterns
      pt_s = re.compile(r"\s")
      pt_w = re.compile(r"\w")
      pt_o = re.compile(r"^\w\s]")
      
      for region in view.sel():
         pos = region.end()-1
         
         # check last char
         if pt_w.match(view.substr(pos)) :
            pt = pt_w
         elif pt_s.match(view.substr(pos)) :
            pt = pt_s
         else :
            pt = pt_o
         
         # removes according to last char
         while pos > 1 and pt.match(view.substr(pos)) :
            view.erase(sublime.Region(pos,pos+1))
            pos -= 1

[/code]

0 Likes

#9

The API documentation only lists args to let you know that is where you add your custom args if you are not requiring it, do not add any arguments:

Here is an example of a command that has a custom argument called “option”. It is required (you can’t run the command without it):
[pre=#2D2D2D]class HexViewerOptionsCommand(sublime_plugin.WindowCommand):

def run(self, option):[/pre]

Here is an example that uses custom arguments that are optional (you can call the command without the arguments and it will still work; they are defaulted to a value if they aren’t used):
[pre=#2D2D2D]class HexViewerCommand(sublime_plugin.WindowCommand):

def run(self, bits=None, bytearray=None):[/pre]

Here is an example that can take an infinite number of arguments of any name. No need to define them you can read them from the kwargs which is a dictionary:
[pre=#2D2D2D]class ExportHtmlCommand(sublime_plugin.WindowCommand):
def run(self, **kwargs):[/pre]

0 Likes

#10

This plugin by decap is an excellent solution for deleting whitespace.

github.com/dacap/sublime-shrink-whitespaces

For whatever the reason, “super+d” aka “⌘+d” aka “find_under_expand” do not work with macros. “find_under_expand” does not appear to be a plugin. So, here is a sample select-entire-word plugin that does work with macros:

[code]import sublime, sublime_plugin

class SelectEntireWord(sublime_plugin.TextCommand):
def run(self, edit):
regions = ]
for s in self.view.sel():
word = self.view.word(sublime.Region(s.begin(), s.end()))
if word.end() == s.end():
# this next part deals with an end of line issue
word = self.view.word(sublime.Region(s.end(), s.end() + 1))
regions.append(word)
for r in regions:
self.view.sel().add®[/code]

The two plugins can be linked together with a macro, or chained with another plugin.

0 Likes