mbigras mbigras - 1 year ago 69
Python Question

How to insert a string on a specific line in a Sublime Text Plugin?

I have the following plugin that puts a time stamp at the top of the document on line 1 but I'd like it to insert the string on a different line, like line 6. At first I thought the insert method was 0 indexed but that doesn't seem to be the case. How would I tell the

insert
method which line to insert the
signature
string at?

import sublime, sublime_plugin
import datetime, getpass

class SignatureCommand(sublime_plugin.TextCommand):
def run(self, edit):
signature = "[%s]\n" % (datetime.datetime.now().strftime("%A, %B %d %I:%M %p"))
self.view.insert(edit, 0, signature)


Thanks for your help :)

Update: thanks to Enteleform for the wonderful answer, I added a
line_num
variable for added clarity :)

import sublime, sublime_plugin
import datetime, getpass

class SignatureOnSpecificLineCommand(sublime_plugin.TextCommand):
def run(self, edit):
line_num = 6 # line number that signature will go on
signature = "[%s]\n" % (datetime.datetime.now().strftime("%A, %B %d %I:%M %p"))
line6_column0 = self.view.text_point(line_num - 1, 0)
self.view.insert(edit, line6_column0, signature)

Answer

view.insert() takes a point as it's location argument.

Points are essentially sequential character positions within a document.


For example, in the following document:

Hello
World

a caret at the end of World would be at point 11

  • 5 characters in Hello
  • 1 NewLine character after Hello
  • 5 characters in World

In order to calculate the point of a particular row & column, use:

view.text_point(row, column)


Example:

import sublime, sublime_plugin
import datetime, getpass

class SignatureCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        signature = "[%s]\n" % (datetime.datetime.now().strftime("%A, %B %d %I:%M %p"))
        line6_column0 = self.view.text_point(6 - 1, 0)
        self.view.insert(edit, line6_column0, signature)

Note:

rows start at 0 and thus are offset from the displayed lines in SublimeText by -1, which is why I used 6 - 1 in the example rather than 6