Sublime Forum

Need some help writing a plugin

#1

Hi everybody.

I have just started using Sublime Text 2 and I find it very good, light and fast!

I like to use Emacs for LaTeX editing, but because I’m Portuguese, I have to use a lot of accents.
Emacs has a plugin that automatically replaces accented characters with LaTeX control sequences on save and replaces them back to accents on open.
I would like to write such a plugin for ST2, but I have absolutely no ideia where to start.

I’d appreciate any help.

Thanks in advance

1 Like

#2

I’m sorry that I don’t have a lot of time to get very detailed, but here is a place to start:

sublimetext.com/docs/2/api_r … ntListener

and you can take a look at many plugins [1] to get an idea of how they are structured. I have one [2] that uses on_load and on_post_save that might help you. You’d want to replace on_post_save with on_pre_save for your purposes.

Good luck! If you get stuck and need help, there are many quite talented plugin developers lurking on the forums that I’m sure could get you going in the right direction.

[1] wbond.net/sublime_packages/community
[2] github.com/phillipkoebbe/DetectSyntax

0 Likes

#3

I have the following code:
import sublime, sublime_plugin

class IsotexCommand(sublime_plugin.TextCommand):
def run(self, edit):
bufferRegion = sublime.Region(0, self.view.size())
bufferContent = self.view.substr(bufferRegion)
bufferContent.replace(’{\~a}’, u’ã’)

I must be trying to do something very stupid or my understanding of the API is really messed up… :smile: Anyway, the ideia is to select the whole buffer, replace the LaTeX accent control sequence with an Unicode accented character.

Can someone tell me what I am doing wrong?

Thanks!

0 Likes

#4

Hi Antonio

Here is some code that I wrote for myself to do a multiple find and replace. I’m sorry it doesn’t have any comments (shame on me!), but I think it should be pretty self explanatory. Basically, if there is a selection, use it, if not, select the whole document. The key is to reverse the selection regions and process them backwards. When you find/replace, the offsets of the selections change and it is pretty hairy to keep them straight. Working backwards avoids that problem.

		view = self.view

		if view.has_non_empty_selection_region():
			self.operation_regions = view.sel()
		else:
			self.operation_regions = [sublime.Region(0, view.size())]

		operation_regions = ]

		for operation_region in self.operation_regions:
			operation_regions.append(operation_region)

		operation_regions.reverse()

		edit = view.begin_edit()

		for line in self.lines:
			if line.startswith('#'):
				continue

			try:
				find, replace = line.split(self.separator)
			except:
				continue
			
			find = find.strip()
			replace = replace.strip()

			for region in operation_regions:
				region_as_string = view.substr(region)
				if region_as_string.find(find) > -1:
					view.replace(edit, region, region_as_string.replace(find, replace))

		view.end_edit(edit)
		try:
			self.operation_regions.clear()
		except:
			pass
0 Likes

#5

Hi Phillip.

Thanks for your prompt and swift reply! :smile:

I have adapted your code, but I get a NameError: name ‘view’ is not defined, in the line that says: “if view.has_non_empty_selection_region():”

my command is derived from the sublime_plugin.TextCommand class, as you can see above.

0 Likes

#6

That’s very interesting. Will please post it all again (and please use a code block so it’s easier to read)? The code that I posted is from a TextCommand also, and the relevant portion prior to the line you referenced is

class MfrReplaceCommand(sublime_plugin.TextCommand):
	def run(self, win_cmd):
		view = self.view

I have to disclaim something here: I haven’t used this code in a month or two, so I don’t know if there have been any changes to the TextCommand API. Whereas the API documentation calls the first parameter “edit”, I have “self”. Not sure if there is a problem there or not.

0 Likes

#7

OK, here goes all my code:

# coding=utf8

import sublime, sublime_plugin

class IsoTeXCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		view = self.view
      	if view.has_non_empty_selection_region():
            self.operation_regions = view.sel()
      	else:
            self.operation_regions = [sublime.Region(0, view.size())]
      	operation_regions = ]
      	for operation_region in self.operation_regions:
         	operation_regions.append(operation_region)
      	operation_regions.reverse()
		operation_regions = [sublime.Region(0, view.size())]
      edit = view.begin_edit()
      for line in self.lines:
         if line.startswith('%'):
				continue
         try:
           find, replace = line.split(self.separator)
        except:
           continue
        	find = '{\\\'a}'
         replace = u'á'
         for region in operation_regions:
			region_as_string = view.substr(region)
         if region_as_string.find(find) > -1:
            view.replace(edit, region, region_as_string.replace(find, replace))
      	view.end_edit(edit)
      	try:
         	self.operation_regions.clear()
      	except:
         	pass
#		bufferRegion = sublime.Region(0, self.view.size())
#		bufferContent = self.view.substr(bufferRegion)
#		bufferContent.replace('{\\~a}', u'ã')
0 Likes

#8

After fixing some wrong indentations, ST2 does not complain any more. It reloads the plugin just fine.

But it does nothing when I invoke it (I am using Ctrl+Alt+Shift+A shortcut)…

0 Likes

#9

[quote=“Antonio.Trindade”]After fixing some wrong indentations, ST2 does not complain any more. It reloads the plugin just fine.

But it does nothing when I invoke it (I am using Ctrl+Alt+Shift+A shortcut)…[/quote]

What does your keybinding definition look like? It should be something like

{ "keys": "ctrl+alt+shift+a"], "command": "iso_te_x" }
0 Likes

#10

I added the following code:

   def __init__(self, view):
      self.view = view
      print 'Init!'

   def run(self, edit):
      print 'I am here!'
      view = self.view
      .
      .
      .

I can see ‘Init!’ printed on the console, but no ‘I am here!’… :-S Therefore I know the plugin is being loaded and init’ed, but it does not run… Even stranger than that is that ‘Init!’ is printed twice…

0 Likes

#11

As you have noticed, initialization and execution are not the same. How is your keybinding defined? I noticed that your class name is IsoTeXCommand, and given the relationship of class names to commands, you’d need to use the command “iso_te_x”. ST2 uses capitalization as a “marker” for underscores. For example, in the code I posted, the class name was MfrReplaceCommand which executed via the “mfr_replace” command.

0 Likes