Sublime Forum

[SOLVED] [st3] Edit object, outside run method has return: How to?

#1

Hi everybody !
I just made the jump: ST2 to ST3, and I like make my own plugin, small ones, but it make coding a lot easier for me, so I don’t want to stop. The problem is that there is some differrance between 2 and 3. Indeed, I have this error (that didn’t exist when I was on ST2):

ValueError: Edit objects may not be used after the TextCommand's run method has returned

So, I understand that we can’t use a function that need the edit arg outside of the run() function of my plugin.
But I just can’t because I want to replace some text with the user input, as you can see:

self.window = self.view.window()
self.window.show_input_panel('Name of the function:', 'function_name', self.replaceText, self.replaceText, None)

You guess, I use view.replace in my replaceText() method. So I’m really confused :confused:

But I’m pretty sure there is a solution, I just can’t see it… :worried:

Thank in advance

Math2001

0 Likes

#3

##See:
#This Post

 



 
The Edit.py module that @tito posted allows you to dynamically get an edit object from a view object.

1 Like

#4

Hi !
Oh… Yes Here’s my full code

class WrapWithFunctionCommand(sublime_plugin.TextCommand):
	def m(self, t, s="md"):
		t = str(t)
		if s == "md":
			sublime.message_dialog(t)
		elif s == "sm":
			sublime.status_message(t)
		elif s == "em":
			sublime.error_message(t)
		else:
			sublime.error_message('s is not valid')
	def md(self, *t):
		t = ' '.join([str(el) for el in t])
		sublime.message_dialog(t)
	def sm(self, *t):
		t = ' '.join([str(el) for el in t])
		sublime.status_message(t)

	def replaceText(func_name):
		edit =
		for pos in self.view.sel():
			self.sm('called', func_name)
			text = self.view.substr(pos)
			text = '(' + text + ')'
			self.view.replace(edit, pos, str(func_name) + text)
		return True

	def run(self, edit):
		print('-' * 50)


		# self.edit = edit
		self.window = self.view.window()

		self.all_text = [self.view.substr(pos) for pos in self.view.sel()]
		self.window.show_input_panel('Name of the function:', 'function_name', self.replaceText, self.replaceText, None)
		return False

I tested you solution fico, but I get:
ImportError: No module named 'Edit' :confused:

0 Likes

#5

 
Did you save the script that @Tito posted?

It has to be saved in your plugin’s directory as Edit.py

1 Like

#6

Hi !

No, I didn’t sorry, i’m really stupid… But now I’ve done it, and it’s working now ! (not the plugin, but the replace()) Thank you so much !

1 Like

#7

You could also do this simple task with a snippet and invoke that with a key binding:

  { "keys": ["ctrl+shift+h"],
    "command": "insert_snippet",
    "args": {"contents": "$1($SELECTION)"}
  },
1 Like

#8

Hey!
Your solution @FichteFoll is way better in fact… :smiley:

But, about the edit problem, here’s an other solutions, without dependencies:

class ReplaceTextCommand(sublime_plugin.TextCommand):
	def run(self, edit, region, text):
                region = sublime.Region(*region)
		self.view.replace(edit, region, text)
# and use
view.run_command('replace_text', { "region": [20, 25], "text": "some super stuff" } )

Hope it helped :slightly_smiling:

Mathieu

0 Likes

#9

The command you wrote in Python is exactly the same as what the insert command provides, excluding specification of a region.

Instead, you would modify the selection (view.sel().clear(); view.sel().add(...)), then run the command view.run_command("insert", {"characters": ...}).

0 Likes

#10

Yeah, it’s the same, only that you don’t need to worry about the Edit object.

0 Likes