Home Download Buy Blog Forum Support

Starting a new plugin

Starting a new plugin

Postby khrizt on Sat Mar 03, 2012 4:32 pm

Hi,

After switching to Sublime last week I wanted to start developing my own plugins so here I am asking for some advice ... Needs saying that I'm new to Sublime API and Python, so please be benevolent ;)

I'm trying to develop a plugin that would allow user to go back to the last editing position in the current view (a feature I found very interesting in NetBeans) and using only the current line I got stuck here:

Code: Select all
import sublime_plugin


last_line = 0


def setLastLine(line):
    last_line = line


def getLastLine():
    return last_line


class LastEditPositionCommand(sublime_plugin.TextCommand):
    def run_(self, action):
        self.view.show(getLastLine())


class CaptureEditing(sublime_plugin.EventListener):
    def on_modified(self, view):
        sel = view.sel()[0]
        setLastLine(view.line(sel))


This is probably very wrong but if you could tell me what I did wrong would be very helpful for me.

Thanks
khrizt
 
Posts: 14
Joined: Thu Feb 23, 2012 8:08 am

Re: Starting a new plugin

Postby agibsonsw on Sat Mar 03, 2012 10:41 pm

Hello. I'm quite new to this as well. Part of the problem is that last_line is a number/integer. In this:

Code: Select all
setLastLine(view.line(sel))

view.line(sel) is a Region. You could amend it to

Code: Select all
setLastLine(sel.begin())

Use 'print last_line' at various points and then view the Console window (Ctrl-' apostrophe) to see the results. The Console window will also display any error messages.
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
agibsonsw
 
Posts: 901
Joined: Fri Jan 27, 2012 9:11 pm

Re: Starting a new plugin

Postby agibsonsw on Sat Mar 03, 2012 10:48 pm

The following seems to be working for me:

Code: Select all
import sublime, sublime_plugin

class LastEditLineCommand(sublime_plugin.TextCommand):
   def run(self, edit):
      self.view.show(CaptureEditing.last_line)

class CaptureEditing(sublime_plugin.EventListener):
   last_line = 0
   def on_modified(self, view):
      sel = view.sel()[0]
      CaptureEditing.last_line = sel.begin()

This makes 'last_line' an attribute of the class CaptureEditing, which the TextCommand can read by referring to the class: CaptureEditing.last_line
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
agibsonsw
 
Posts: 901
Joined: Fri Jan 27, 2012 9:11 pm

Re: Starting a new plugin

Postby agibsonsw on Sat Mar 03, 2012 11:16 pm

Out of interest ;) this version allows us to go back to previous edit positions:

Code: Select all
import sublime, sublime_plugin

class LastEditLineCommand(sublime_plugin.TextCommand):
   def run(self, edit):
      self.view.show(CaptureEditing.last_line.pop())

class CaptureEditing(sublime_plugin.EventListener):
   last_line = []
   def on_modified(self, view):
      sel = view.sel()[0]
      CaptureEditing.last_line.append(sel.begin())
      # print CaptureEditing.last_line

To explain, it maintains the editing position in a list and uses append() to keep adding to this list. It then uses pop() to extract the last position from the list.

I might play with this a little so that I can navigate back and forward.
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
agibsonsw
 
Posts: 901
Joined: Fri Jan 27, 2012 9:11 pm

Re: Starting a new plugin

Postby agibsonsw on Sun Mar 04, 2012 12:44 am

With apologies, but I've extended this example a bit, as it's helping me to study Python:

It cycles through the last five edit positions;
It won't cause an error if there isn't a position to navigate to;
It only stores an edit position if it's on a different line from the previous edit;
It only remembers the last 10 edit positions (so that the list doesn't grow continuously).

It could be extended to go forward through edit positions as well..

Code: Select all
import sublime, sublime_plugin

class LastEditLineCommand(sublime_plugin.TextCommand):
   posn = 0
   def run(self, edit):
      if len(CaptureEditing.last_line) > self.posn:
         self.view.show(CaptureEditing.last_line[-(self.posn+1)])
         self.posn = (self.posn + 1) % 5
      else: self.posn = 0

class CaptureEditing(sublime_plugin.EventListener):
   last_line = []
   prev_line = -1
   def on_modified(self, view):
      sel = view.sel()[0]
      curr_line, _ = view.rowcol(sel.begin())
      CE = CaptureEditing
      if CE.prev_line == -1 or curr_line != CE.prev_line:
         CE.prev_line = curr_line
         CE.last_line.append(sel.begin())
         if len(CE.last_line) > 10: CE.last_line.pop(0)
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
agibsonsw
 
Posts: 901
Joined: Fri Jan 27, 2012 9:11 pm

Re: Starting a new plugin

Postby khrizt on Sun Mar 04, 2012 10:14 am

Wow! That is quite nice, I've got so much to learn. Thanks for the python lesson :)

You should publish that in github or something like that, a lot of people will find it useful.
khrizt
 
Posts: 14
Joined: Thu Feb 23, 2012 8:08 am

Re: Starting a new plugin

Postby agibsonsw on Sun Mar 04, 2012 10:43 am

khrizt wrote:You should publish that in github or something like that, a lot of people will find it useful.


Hello. This is interesting in terms of learning Python, and the ST API. But on further investigation my example is of restricted use. Most significantly, because the last position(s) are stored in a class attribute (rather than an instance attribute), editing in two different tabs will cause mayhem :lol:. I'm not sure how to get around this at the moment, although one way might be to store a reference to the current view with each edit position - but this sounds messy.

But many other discrepancies will arise: pressing Enter a few times, deleting text, copying, editing the same line again - all of these actions will make the code less useful.

I notice that someone has already created an editing history plug-in in a recent thread of this forum. Andy.
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
agibsonsw
 
Posts: 901
Joined: Fri Jan 27, 2012 9:11 pm

Re: Starting a new plugin

Postby khrizt on Sun Mar 04, 2012 11:08 am

It'd great if besides from scrolling to the last position, the plugin placed the cursor in the line from the last position. I'm trying to modify the code from

Code: Select all
self.view.show(CaptureEditing.last_line[-(self.posn+1)])


to

Code: Select all
self.view.sel().clear()
self.view.sel().add(self.view.line(CaptureEditing.last_line[-(self.posn + 1)]))


But it doesn't work, add method should place the cursor in the line specified... but I think I misunderstood something
khrizt
 
Posts: 14
Joined: Thu Feb 23, 2012 8:08 am

Re: Starting a new plugin

Postby agibsonsw on Sun Mar 04, 2012 11:49 am

@khritz That works for me :)
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
agibsonsw
 
Posts: 901
Joined: Fri Jan 27, 2012 9:11 pm

Re: Starting a new plugin

Postby khrizt on Sun Mar 04, 2012 12:40 pm

Uops! :D

Ok, now it works for me too, I've missed something. I'll try to improve the code to learn a little bit more about ST API, specially for the different files problem you mentioned.

BTW, do you remember the thread where the plugin was posted?

Thanks
khrizt
 
Posts: 14
Joined: Thu Feb 23, 2012 8:08 am

Next

Return to Technical Support

Who is online

Users browsing this forum: Google [Bot], Yahoo [Bot] and 26 guests