Set Text In Buffered Range - how to setup range properly


Hi guys :smile:,

I am updating my wrap package and I would like to add surround by tag. So my plan is to get range of selection, indent it and then add brackets on previous and row. I have bit problem with this bit. Right now I have

range = selection.getBufferRange()
start = range.start
end = range.end
editor.setTextInBufferRange([[start.row - 1, start.column],[start.row - 1, end.column]],"<>")
editor.setTextInBufferRange([[start.row + 1, start.column],[start.row + 1, end.column]],"</>")

Problem is that column is set to zero if previous or next line has 0 length so if the text to be surround starts at 8th column(after indentation) , brackets should be on column 4(depending on tab length) but they are on column 0

I clear don’t understand setting the range :slight_smile:


Doesn’t that code also erase the line above? I would think you want to insert new lines at the top and bottom. You should create a new first line starting with the indent text and ending with \n. Insert the new line before the line at start.row. Then do a similar thing from the bottom.

But I could be wrong.


Hi @mark_hahn, thanks for trying to help. Not sure can’t try it right now, but even if it did that I think adding new line would solve my original problem. Will try it tomorrow.


Bumb, still can’t figure this out.


You should get the indentation for the current line. You can use editor.getIndentationForBufferRow start.row. This gives you the number of (soft)tabs at the start of the first line of the selection. Then build a whitespace prefix:

indentLevel = editor.getIndentationForBufferRow start.row
prefix = ''
if editor.softTabs
  for i in [0...indentLevel]
    prefix += ' ' for j in [0...editor.getTabLength()]
  for i in [0...indentLevel]
    prefix += '\t'

Then prepend this to the tags you’re adding to the buffer:

editor.setTextInBufferRange(range, "#{prefix}<>")
editor.setTextInBufferRange(range, "#{prefix}</>")

Also I don’t think you should set the ranges to go from start.column to end.column. Any text in the range that you define will be overwritten by the setTextInBufferRange function. If I select the 4th-8th character on line 3, then the 4th-8th characters on line 2 and 4 will be deleted. You should probably use @mark_hahn’s suggestion before setting the text (note: this will bump the selected text line with +1 and the first line the selection with +2) and then put the "#{prefix}<>" on those new lines.

So as a recipe:

  1. Get selection firstLine and lastLine
  2. Insert \n at start of firstLine
  3. Insert \n at end of lastLine + 1, the +1 is because the earlier \n pushed all lines by 1
  4. Get indentLevel of firstLine
  5. Build indent prefix
  6. Indent the selection
  7. Set the opening tag on [[firstLine, 0], [firstLine, 0]]
  8. Set the closing tag on [[lastLine + 2, 0], [lastLine + 2, 0]]


Look at that, I ask for simple help and I get almost whole code with algorithm ! thanks a lot @olmokramer :slight_smile: