How to format "one line html" as a pretty document in sublime? [duplicate] - sublimetext3

This question already has answers here:
How do I reformat HTML code using Sublime Text 2?
(16 answers)
Closed 9 years ago.
I have a html source file containing only one line like the following:
<html><head>test</head><body>wow</body></html>
, and I want to format it as following:
<html>
<head>
test
</head>
<body>
wow
</body>
</html>
, I have used the command: Edit-> Line-> Reindent but it doesn't work.

In Sublime Text try this:
Highlight the last character in the first tag: ">"
Use Find > Quick Add Next (Command+D on Mac or Ctrl+D on PC)
You'll now have all occurrences highlighted in multiple selections, move the caret to the end of the tag and hit return to insert all the new lines you require.
Good luck

I was under the impression that Sublime provided this ability as well. When I found out that it wasn't, I had the idea of using regular expressions. Even though regex are usually considered inappropriate for parsing XML/HTML, I found this approach to be acceptable in this case. Sublime is also said to be highly customizable by plugins, so I think this would be a way.
Sublime Plugins
To be honest, I could have thought of tidy or at least suspect that there must be plugins out there dealing with your issue. Instead I ended up writing my first sublime plugin. I have only tested it with your input and expected output, which it satisfied, but it is most certainly far from working reliably. However, I post it here to share what I've learned and it's still an answer to the problem.
Opening a new buffer (Ctrl+n) and choosing the 'New Plugin...' entry in the Menu 'Tools' generously generates a little 'Hello World!' example plugin (as a Python module), which gives a great template for implementing a sublime_plugin.TextCommand subclass. A TextCommand provides access to an active buffer/currently open file. Like its relatives WindowCommand and ApplicationCommand, it is required to overwrite a run-method.
The official API Reference suggests learning by reading the example sources distributed with the Sublime builds and located in Packages/Default relative to the Sublime config path. Further examples can be found on the website. There's more on the internet.
Processing selected text
To get to a solution for your issue, we primarily need access to a View object which represents an active text buffer. Fortunately, the TextCommand subclass we are about to implement has one, and we can conveniently ask it for the currently selected regions and their selection contents, process selected text conforming our needs and replace the selected text with our preference afterwards.
To sum up the string operations: There are four regular expressions, each of which matches one of the element classes <start-tag>, <empty-tag/>, </close-tag> and text-node. Assuming that all of our markup text is covered by these, we did each line in selection into matching substrings. These are then realigned one-per-line. Having done this, we apply simple indentation by remembering to indent every line whose predecessor contains a start tag. Lines containing end tags are unindented immediately.
Using the group addressing features of Python regex, we can determine the indentation of every line and align the next one accordingly. This, with no further ado, will result in internally consistent indented markup, but with no consideration of the lines outside the selection. By extending the selection to an enclosing element, or at least complying with the indentation levels of the adjacent lines, one could easily improve the results. Its always possible to make use of the default commands.
Another thing to take care of is binding keys to the plugin command and contributing menu entries. It is probably possible somehow, and the default .sublime-menuand .sublime-commands files in Packages/Default at least give an idea. Anyway, here's some code. It has to be saved under Packages/User/whatever.py and can be called from the Sublime Python Console (Ctrl+`) like this: view.run_command('guess_indentation').
Code
import sublime
import sublime_plugin
import re
class GuessIndentationCommand(sublime_plugin.TextCommand):
def run(self, edit):
view = self.view
#view.begin_edit()
# patterns
start_tag = '<\w+(?:\s+[^>\/]+)*\s*>' # tag_start
node_patterns = [start_tag,
start_tag[:-1]+'\/\s*>', # tag_empty
'<\/\s?\w+\s?>', # tag_close
'[^>\s][^<>]*[^<\s]'] # text_node
patterns = '(?:{0})'.format('|'.join(node_patterns))
indentors = re.compile('[ \t]*({0})'.format('|'.join(node_patterns[:1])))
unindentors=re.compile('[ \t]*({0})'.format(node_patterns[2]))
# process selected text
for region in view.sel():
# if selection contains text:
if not region.empty():
selection = view.substr(region)
expanded = []
# divide selected lines into XML elements, if it contains more than one
for line in selection.split('\n'):
elements = re.findall(patterns, line)
if len(elements)>0:
expanded += elements
else:
expanded.append(line)
# indent output
indent=0
indented = []
for line in expanded:
match = unindentors.match(line)
if match:
indent = max(0, indent-1)
# append line to output, unindented if closing tag
indented.append('\t'*indent+line)
if match:
continue
# test for possible indentation candidate
# indentation applies to the NEXT line
match = indentors.match(line)
if match:
indent+=1
# replace selection with aligned output
view.replace(edit, region, '\n'.join(indented))

if its for something simple, i was able to record a macro (tools -> record macro) indenting the tags and then save it and reuse this macro. not sure if that helps any though.

Related

Is there a quick way to delete everything between certain tags, e.g. <head> and </head>, throughout the whole project (multiple pages) in VS Code?

I am trying to find a way to remove all from a tag pair in VS Code.
I’ve been using Notepad++ for this purpose, but for some unknown reason it doesn't work all the time. So, I hope if there is such a possibility in VS Code, it’d be more reliable.
Here is the instruction for Notepad++:
Search for -
<wp:post_name>[^<>]+</wp:post_name>
and replace all with -
<wp:post_name></wp:post_name>
Is there anything like this in VS Code?
I’d really appreciate it if someone can help.
Before using what is suggested in this solution, backup your files, and run the search and replace on a small sample. Be sure to check the outcome to all the possible combinations you can have in your files.
You can achieve what you need with Notepad++ (and SublimeText 3, with RegEx search and replace), and this answer will cover that. Since I've never used Visual Studio Code, I can't say if it will work in it as well.
Consider the following regular expression.
<foo>(.*?)<\/foo>
If we were to apply it to the following text:
<foo><some special chars>!##$%^&*</foo> sure, why not
<foo>Lorem</foo>
<foo>ipsum</foo>
<foo>sit</foo>
<foo>dolor</foo>
<foo>amet</foo>
<bar>elm stuff</bar>
more stuff for you <foo> something </foo> and even more stuff <foo>yes</foo>
it would match all the parts of the text which begin with <foo> and end with </foo>, regardless of what's between them.
If you want to play around with this, I've created an example here.
As far as using this in Notepad++, open the search window, navigate to the Find in files tab, and set it up like in the following image.
You would, of course, need to change the search and replacement strings to those you plan on using, optionally set up a file extension for which to do the replacement (Filters), and set the directory in which to perform find-and-replace.
Limitations
1. Nesting
In case your text contains nested tags of the same kind, like this:
Let's deal with nesting: <foo> some text <foo> a child foo!</foo> let's close the parent</foo>
doing the suggested RegEx search and replace, will turn the previous line of text into this:
Let's deal with nesting: <foo></foo> let's close the parent</foo>
If you don't have nested tags of the same kind, you should be in the clear. Unless...
2. Newlines
The provided RegEx will not match cases where your opening tag shows up in one line, and the closing tag shows up in another line. To match those, you would need to change the original RegEx:
<foo>(.*?)<\/foo>
to this:
<foo>([\s\S]*?)<\/foo>
\s will match any whitespace character (including newlines), while \S will match any non-whitespace character.

How to create a centralized syntax file that be able to recognize multiple parts with different syntaxes?

For i.e: I'd like to have a custom syntax file, may be called sugar.vim that includes multiple other syntax files(?) to have the ability to highlight, maybe a paragraph as python.vim and another paragraph as javascript.vim, may be separated by newline (paragraphs often distinct by newline)
The real case that I often catch myself writing a document (non-extension file) other than real config a specific filetype (specific extension file), but for clear readability in the document filetype (we called sugar above). I'm thinking about a mechanism to recognize and highlight different parts of a filetype as different syntaxes.
To narrow down this case. How would it be to have a syntax file called sugar.vim that would be able to recognize python syntax and javascript syntax in files that have an extension of .sugar then the recognized python text should have highlights applied as a normal python file, same for javascript part. All recognized text must be separated by newline (at least one before and one after that text)
Sample:
# this is a sample text for this question
# i'm writing a document that has an extension of `.sugar`
def py_func1(arg1, arg2) # python.vim and its highlights applied here.
print("bello world!")
square = function(x) { # javascript.vim and its highlights applied here.
return x * x;
};
System: gvim 8.1 / windows10
Thanks in advances.
Vim supports that with the :help :syn-include command. As it's intended for syntax script writers leveraging other syntaxes, its use is somewhat complicated, and it's not really suited for interactive, on-demand use.
My SyntaxRange plugin provides commands and functions to set up regions in the current buffer that either use a syntax different from the buffer's 'filetype', or completely ignore the syntax. With it, it's trivial to dynamically add a particular syntax highlighting for a range of lines, and public API functions also make the programmatic definition easier.
You're looking for :help :syn-include.
Excerpt from vim help :
If top-level syntax items in the included syntax file are to be
contained within a region in the including syntax, you can use the
":syntax include" command:
:sy[ntax] include [#{grouplist-name}] {file-name}
All syntax items declared in the included file will have the
"contained" flag added. In addition, if a group list is specified,
all top-level syntax items in the included file will be added to
that list. >
" In perl.vim:
:syntax include #Pod :p:h/pod.vim
:syntax region perlPOD start="^=head" end="^=cut" contains=#Pod
When {file-name} is an absolute path (starts with "/", "c:", "$VAR"
or "") that file is sourced. When it is a relative path
(e.g., "syntax/pod.vim") the file is searched for in 'runtimepath'.
All matching files are loaded. Using a relative path is
recommended, because it allows a user to replace the included file
with his own version, without replacing the file that does the ":syn
include".
As long as you can clearly define boundaries for your embedded language regions it is fairly straight forward to achieve this.
You can also refer to https://github.com/tpope/vim-markdown/blob/master/syntax/markdown.vim for reference on how tpope embeds other syntax definitions within the markdown syntax, driven by configuration to minimise the number of language syntax's that need embedding for optimal performance.

Sublime Text Tab Indentation Indenting Entire Paragraph?

I've recently discovered Sublime Text and since I'm new to using text editors like this, I had a question about indentation. When I'm not using Sublime for code, I type up my writing with it before taking it to a word processor for further processing. I've been having a little bit of trouble with the indentation regarding paragraphs. When I tab a paragraph, it seems to tab the entire paragraph rather than just the first line. It looks like the first paragraph in this picture.
I've tried using the wrap paragraph function which seems to allow me to tab just the first line but when I paste it in Microsoft Word, it retains its wrap setting. Is there anyway that I can just indent just the first line without having to wrap it? Or am I approaching it all wrong?
For a global effect you can add this to Preferences > Settings-User:
"indent_subsequent_lines": false
Because I code too, I add it to Preferences > Settings-More > Syntax Specific-User.
To do this properly, open a .txt file (or your preferred file type) and it will open/create a settings file for the specific file type. Then paste in this and save:
{
"indent_subsequent_lines": false,
"tab_size": 4,
"translate_tabs_to_spaces": false
}
Sublime is a code editor, not a word processor. Although you may use it to type any kind of (plain) text, it's focused on editing code.
Sublime indents lines in a way that makes sense for a programming language. If you're looking for a tool to write anything like a report or a novel, maybe you should consider another tool.

VIM: Respect only current code block

I have started working on a huge PHP application that has thousands of lines of code in each file, with lots of huge if blocks, classes, and functions all existing in the same file. I'm not the only dev working on it, so I cannot refactor!
I have tried using the Tags List plugin but it does not really help. Is there any way to have VIM respect only a particular code block, and ignore the rest of the file? I am hoping for some or all of these features:
Enable line numbering only for the current code block, starting from 1 at the line containing the opening {, and showing no numbering for lines preceding it or after the closing }.
Searching with / would be restricted only to the block in question.
I am thinking along the lines of selecting the current block and editing it in a new buffer when enabling the mode, then replacing the existing block with the edited block when exiting the mode. However, I am having trouble actually implementing this feature. My current version is this:
map <F7> <Esc>mO<C-V>aBy:new<Return>p:set nu<Return>:set ft=php<Return>ggi<?php<Return><Esc>
map <F8> <Esc>ggdd<C-V>aBx:bp<Return>`O<C-V>aBp
However, this has several issues, such as the inability to perform incremental saves.
I would be very surprised if Vim allows the kind of line numbering you ask for.
This plugin (and 1 or 2 similar ones IIRC) allows you to visually select a region of your current file, work on it in another buffer and put everything back in its place in the original file on :w.
Even if it's not the solution you are wanting, I think the following can help you to solve your problem.
You can use phpfolding plugin, which folds by PHP syntax (functions, classes, methods, PhpDoc...)
You can then select a fold by pressing v$ over the closed fold and execute whatever you want with :whatever. For example, :s/this/self/g to substitute all this for self in the fold. When you press :, vim will automatically add '<,'> to denote following command it's only for the visually selected text.

Vim Surround: Create new tag but don't indent/new line

I would like to mimic Textmates CTRL+ALT+w, which creates a new pair of opening and closing HTML tags on the same line.
In VIM Surround I'm using CTRL+st in Edit mode for this, but it always indents and creates a new line after setting the tag, so that it looks like this (* = cursor position):
<p>
*
</p>
Is there a way to achieve this? :
<p>*</p>
I guess your problem is that the selected area is "line wise". For example, if you select a few lives with V and surround it with tags, the tags will be placed one line above and one bellow the selected lines.
You probably want to create a "character wise" selection, with v before surrounding it.
Anyway, please post the map you created, so we can help debugging this.
Update
After some clarification in the comments, I would tell you that the surround plugin is not the best option. As its name describes, it was created to deal with surrounded content. So you may need content to surround.
In your case, I recommend taking a look in HTML AutoCloseTag. This plugin closes the html tag once you type the >. It is certainly more appropriated, and uses less keystrokes than surround.
<p <--- Now when you type ">", if becomes:
<p>|</p> <--- Where "|" is the cursor.
Obviously, you will get this behavior to every tag. But that may be handy if you like it.
From normal mode, type vstp> to enter visual mode and output an opening and closing <p> tag on the same line at the current cursor position. Use a capital S to maintain the current indent level.
This doesn't place the cursor in between the tags as you describe, but neither does Textmate's CtrlW shortcut (I think you meant CTRL+Shift+w, not CTRL+ALT+w, as the latter just outputs a diamond sign.)
My answer is probably coming to late, but I'll try to help.
I had similar problem with Vimsurround plugin. Every time I select sentence (one line) using ctrl+V and try to surround it with something I get this:
{
var myVar
}
instead of this:
{ var myVar } // what I wanted
I found easy solution: From a normal mode I choose a line with vis command and then I type capital C (my vim surround mapping ) and choose brackets to surround.Then I get one line nicely surrounded.
The question title is technically mislabeled based on what the author was actually looking for, but since I was actually looking for the answer to the question asked in the title, I figure I should provide an answer to it as well.
To create a new tag surrounding an element without the automatic indentation Vim Surround uses when using a block wise selection (ie: VysS), you can instead do something like:
^ys$
This command will move your cursor to the first non-blank character of the line, issue the command that you want to utilize You Surround, and move to the end of the line. Then, simply start entering your tag.
The result is this:
<input type="email" name="email">
Could become something like this:
<li><input type="email" name="email"></li>
The command is repeatable as well with . and all the normal other Vim goodness.
Stumbled upon this question because I was wondering this as well - I believe the simplest way to do this is just:
yss<p>
(yss surrounds a line with something without indenting - see here: http://www.catonmat.net/blog/vim-plugins-surround-vim/)
You can accomplish this by selecting the relevant text object: :h text-objects
...and surrounding that instead of surrounding a Visual Line selection.
The most common example I found myself running into was when trying to surround one tag with another. In that situation, the it and at text objects are quite useful:
*v_at* *at*
at "a tag block", select [count] tag blocks, from the
[count]'th unmatched "<aaa>" backwards to the matching
"</aaa>", including the "<aaa>" and "</aaa>".
See |tag-blocks| about the details.
When used in Visual mode it is made characterwise.
*v_it* *it*
it "inner tag block", select [count] tag blocks, from the
[count]'th unmatched "<aaa>" backwards to the matching
"</aaa>", excluding the "<aaa>" and "</aaa>".
See |tag-blocks| about the details.
When used in Visual mode it is made characterwise.
For example, if you had your cursor in a paragraph and you wanted to surround it with a div on the same line, ysat<div> would accomplish that.

Resources