Hi
When I try to use the long-tag I am getting a formatting issue. I have included screenshots to show.
I would love to be able to add divs around my selected text easily without it shoving my div over like 6 spaces. Am I doing something wrong?
Hi
When I try to use the long-tag I am getting a formatting issue. I have included screenshots to show.
I don’t think you’re doing anything wrong, it seems to be a bug with the indentation behavior which somehow gets triggered by this snippet
With the simple reproduction steps, tested on build 4083:
html
Tab
<title>\n\t\n</title>
Some Title Here
Some Title Here
is selected)<title>\n\tSome Title Here\n</title>
is selected)<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<p><title>
Some title here
</title></p>
</head>
<body>
</body>
</html>
we can see that the tag is wrapped on the same line, which looks like it causes the decreaseIndentPattern
rule for </title>
to not apply, so it gets indented one level.
But, that pattern has no end anchor, so it should work, and indeed, selecting all text and using the reindent
command gives an output that it isn’t indented more than the open tag. So I think to work around it for now, you’d want to use a plugin instead of a snippet.
I’ll see if I can draw one up in a minute.
you could try this - it will just issue a reindent
command to the lines that were in the selection when the long-tag snippet is inserted (without affecting the snippet fields, so you can still type a new tag name):
(I originally experimented with turning off auto_indent
and smart_indent
temporarily, but it had no effect on the bug)
To use it, go to the Tools menu -> Developer -> New Plugin and replace the buffer with this one, and save it as something like long_tag_snippet_fixer.py
(in the folder ST suggests - Packages/User
) - only extension is important
import sublime
import sublime_plugin
class InsertLongTagSnippetWatcher(sublime_plugin.EventListener):
def on_text_command(self, view, command, args):
if command == 'insert_snippet':
if args.get('name', None) == 'Packages/XML/Snippets/xml-long-tag.sublime-snippet':
#self.prev_auto_indent = view.settings().get('auto_indent', None)
#view.settings().set('auto_indent', False)
self.sel_pos = [region for region in view.sel()]
def on_post_text_command(self, view, command, args):
if command == 'insert_snippet':
if args.get('name', None) == 'Packages/XML/Snippets/xml-long-tag.sublime-snippet':
#view.settings().set('auto_indent', self.prev_auto_indent)
correct_sel = [region for region in view.sel()]
view.sel().clear()
view.sel().add_all(self.sel_pos)
view.run_command('reindent')
view.sel().clear()
view.sel().add_all(correct_sel)
Thanks so much for taking the time to create this. I did what you said and created the long_tag_snippet_fixer.py in the packages/User.
long_tag_snippet_fixer.py file:
import sublime
import sublime_plugin
class InsertLongTagSnippetWatcher(sublime_plugin.EventListener):
def on_text_command(self, view, command, args):
if command == 'insert_snippet':
if args.get('name', None) == 'Packages/XML/Snippets/xml-long-tag.sublime-snippet':
#self.prev_auto_indent = view.settings().get('auto_indent', None)
#view.settings().set('auto_indent', False)
self.sel_pos = [region for region in view.sel()]
def on_post_text_command(self, view, command, args):
if command == 'insert_snippet':
if args.get('name', None) == 'Packages/XML/Snippets/xml-long-tag.sublime-snippet':
#view.settings().set('auto_indent', self.prev_auto_indent)
correct_sel = [region for region in view.sel()]
view.sel().clear()
view.sel().add_all(self.sel_pos)
view.run_command('reindent')
view.sel().clear()
view.sel().add_all(correct_sel)
Then I restarted sublime. I am still getting the indentation issue though. Do I need to change something somewhere else?
Which ST build are you using? It may be that your XML package doesn’t have a separate snippets folder
It looks like the Snippets folder exists, but the snippet is just called long-tag.sublime-snippet
, which probably I should have guessed from your forum post title, sorry.
import sublime
import sublime_plugin
from os import path
def is_long_tag_snippet(args):
name = args.get('name', None)
if not name:
return
folder = path.dirname(name)
file_name = path.basename(name)
return folder == 'Packages/XML/Snippets' and file_name.endswith('long-tag.sublime-snippet')
class InsertLongTagSnippetWatcher(sublime_plugin.EventListener):
def on_text_command(self, view, command, args):
if command == 'insert_snippet':
if is_long_tag_snippet(args):
#self.prev_auto_indent = view.settings().get('auto_indent', None)
#view.settings().set('auto_indent', False)
self.sel_pos = [region for region in view.sel()]
def on_post_text_command(self, view, command, args):
if command == 'insert_snippet':
if is_long_tag_snippet(args):
#view.settings().set('auto_indent', self.prev_auto_indent)
correct_sel = [region for region in view.sel()]
view.sel().clear()
view.sel().add_all(self.sel_pos)
view.run_command('reindent')
view.sel().clear()
view.sel().add_all(correct_sel)
Hi kingKeith,
Thank you so much for all you are doing to help! That removed the indent. This may be asking you to go above and beyond but I figured I would ask anyways. What happens now when I add the snippet is if I have this as my original code
<div>
<p>Text Here</p>
</div>
When I add the new snippet it does
<p><div>
<p>Add New Event</p>
</div></p>
This is good that it no longer shoves over the text but what would be ideal in my perfect world would be
<p>
<div>
<p>Add New Event</p>
</div>
</p>
I don’t suppose that is a easy change?
if you’ve got the OverrideAudit plugin installed, you can:
OA:
OverrideAudit: Create Override
long-tag.sublime-snippet
<snippet>
<content><![CDATA[<${1:p}>
${0:$SELECTION}
</${1/([^ ]+).*/$1/}>]]></content>
<tabTrigger>lt</tabTrigger>
<scope>text.xml - meta.tag - comment - string</scope>
<description>Long Tag</description>
</snippet>
That worked and Its almost there!!!
If I just have
<p>Test words</p>
when I do the snippet I get
<p>
<p>Test words</p>
</p>
Wooooo! The only catch now is if I try to do something like
<p>
<p>Test words</p>
</p>
I get
<p>
<p>
<p>Test words</p>
</p>
</p>
I haven’t been able to replicate that behaviour yet… Does it make a difference if you reindent the whole file first?
I did some testing on my end and it is definitely an issue with different files. I must have some weird indentation issues. When I use a clean file it works great.
Thank you sooo much for all of your help with this, you have been amazing!
okay, for a plugin solution instead of a snippet - such that this bug isn’t triggered, and it doesn’t affect indentation at all:
import sublime
import sublime_plugin
from os import path
def is_long_tag_snippet(args):
name = args.get('name', None)
if not name:
return
folder = path.dirname(name)
file_name = path.basename(name)
return folder == 'Packages/XML/Snippets' and file_name.endswith('long-tag.sublime-snippet')
class InsertLongTagSnippetWatcher(sublime_plugin.EventListener):
def on_text_command(self, view, command, args):
if command == 'insert_snippet':
if is_long_tag_snippet(args):
return ('insert_xml_tag', { 'tag': 'p' })
class InsertXmlTagCommand(sublime_plugin.TextCommand):
def run(self, edit, **args):
tag = args.get('tag', 'p')
for sel in reversed(self.view.sel()):
self.view.insert(edit, sel.end(), '</' + tag + '>')
self.view.insert(edit, sel.begin(), '<' + tag + '>')
#self.view.sel().add(sublime.Region(sel.begin(), sel.end() + ((len(tag) + 2) * 2) + 1))
self.view.sel().add(sublime.Region(sel.begin() + 1, sel.begin() + 1 + len(tag)))
self.view.sel().add(sublime.Region(sel.end() + len('<' + tag + '></'), sel.end() + len('<' + tag + '></') + len(tag)))
self.view.sel().subtract(sublime.Region(sel.begin() + len('<' + tag + '>'), sel.end() + len('<' + tag + '>')))
however, it currently loses the ability to press Tab to go to the contents of the tag (i.e. the selection that got wrapped).
EDIT: and I just realised it also doesn’t cater for putting the wrapped selection on a new line and indenting it…