VIM syntax highlighting of html nested in yaml - syntax-highlighting

Given a yaml file that contains html, like this:
template : |+
<div>Hello, world</div>
Is it possible in Vim (version 7.3.087) to highlight the html portion with html syntax highlighting?
I found the post Different syntax highlighting within regions of a file, which seems to have exactly the concept I was looking for, but I cannot get it to work as expected with yaml. I'd expect to be able to do the following (as suggested in the link):
" .vimrc
" include the code from the above link
call TextEnableCodeSnip('html' ,'#{{{html' ,'#html}}}', 'SpecialComment')
Then have the yaml as, for example:
template : |+ #{{{html
<div>Hello, world</div>
#html}}}
Unfortunately this does not work as expected i.e. the html code remains entirely highlighted with yaml. I've also noted that with my configuration (MacVim 55), this doesn't work in text files either.
I'd be grateful for your thoughts or suggestions, and thank you for reading.

check out my related question: Trouble using Vim's syn-include and syn-region to embed syntax highlighting. There I am trying to embed Python within TeX, but I think the solution might work for your case, too.
I think you want to do something like this:
let b:current_syntax = ''
unlet b:current_syntax
runtime! syntax/yaml.vim
let b:current_syntax = ''
unlet b:current_syntax
syntax include #YaML syntax/yaml.vim
let b:current_syntax = ''
unlet b:current_syntax
syntax include #HTML syntax/html.vim
syntax region htmlEmbedded matchgroup=Snip start='#{{{html' end='#html}}}' containedin=#YaML contains=#HTML
hi link Snip SpecialComment
let b:current_syntax = 'yaml.html'
The block with the runtime! command might be unnecessary if your YaML is already highlighted.

You could try to add the following in your .vimrc:
autocmd BufRead,BufNewFile *.yaml setfiletype html.yaml
A yaml file will be considered to be both of type yaml and html and both syntax color scheme should be applied but I don't really know how conflicts between the two schemes are dealt with...

It looks like you want to move the start pattern to the beginning of the next line:
template : |+
#{{{html
<div>Hello, world</div>
#html}}}
More details:
I'm on WinXP, but I saw almost the same behavior that you described.
When in a file with filetype yaml, after calling TextEnableCodeSnip I didn't see a change until I moved the start pattern down the the beginning of the next line. I was able to see the syntax highlighting work in a file with no filetype though, so this still a chance this won't work for you.

I used Maxy-B's solution. My code, in particular, is a bit different so I thought to post it for posterity:
~/.vim/after/syntax/yaml.vim
let b:current_syntax = ''
unlet b:current_syntax
syntax include #HTML syntax/html.vim
syntax region htmlCode start=#^html:#hs=e+1 end=+^\w+he=s-1,me=s-1
\ contains=#HTML
let b:current_syntax = ''
unlet b:current_syntax
syntax include #TEX syntax/tex.vim
syntax region texCode start=#^tex:#hs=e+1 end=+^\w+he=s-1,me=s-1
\ contains=#TEX
This highlights the top-level YAML nodes html and tex with those respective types of code. It's not very dynamic, but it suits my purpose and this may serve as helpful guideline for someone doing something similar. It'll highlight the following as expected (or at least, as I expect it), for example:
regular: # yaml
- yaml # yaml
html:
<b>hello</b> # html
tex:
\begin{document} # tex
\end{document} # tex
the-end: may be necessary # yaml

Related

IntelliJ Ruby warning "Cannot resolve properly, was not processed"

I have many lines in my specs that result in this IntelliJ warning:
"Cannot resolve properly, was not processed"
The vast majority of the lines have this format:
expect(result[:err]).to include('(Check the file permissions.)')
If I move the literal string to a separate variable, the warning goes away:
msg = '(Check the file permissions.)'
expect(result[:err]).to include(msg)
Is there a way to make this error go away (other than moving all my string literals to variables)?
My guess is that the RubyMine parser thinks that include is the Ruby keyword to include a module and so it emits a warning telling it cannot find the corresponding module.
The only way I found to fix this warning is to use the inclusion alias proposed by the rspec include matcher :
expect(result[:err]).to inclusion('(Check the file permissions.)')
This fixes the warning and the expectation works the same, but sadly the english sentence is bad.
There is also 3 other aliases available, but they don't give better english syntax:
alias_matcher :a_collection_including, :include
alias_matcher :a_string_including, :include
alias_matcher :a_hash_including, :include
alias_matcher :including, :include
These alias definitions can be found here
Maybe by chance this answer could lead someone to a better solution.
If you're willing to switch from using the word include to something like contain, you could simply create a custom matcher:
RSpec::Matchers.define :contain do |expected|
match do |actual|
expect(actual).to include(expected)
end
end
You could either add that code directly in your rails_helper.rb file, or better yet in a separate file. For instance, create spec/support/custom_matchers.rb and place the code there. You'll need to make sure that file gets included when running rspec. To do that, you could uncomment the following line which appears in the default spec/rails_helper.rb file:
# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
With that in place, your spec file would read:
expect(result[:err]).to contain('(Check the file permissions.)')
It can be fixed by adding this to rails_helper.rb or support/rubymine_stubs.rb:
# Rubymine IDE underlines `include` matchers with warning "Cannot resolve properly, was not processed"
# To fix this issue let's make an alias `contain` and use it instead
RSpec::Matchers.alias_matcher :contain, :include
module RubymineStubs
# create stub for `contain` so Rubymine won't underline it
def contain(*_args) end
end

How to define default syntax on files without extension on Sublime Text 2?

I've read many posts dealing with this problem, but none has an answer to my question.
As said in the title, I would like to define a default syntax for all files which have no extension. In my case I would like to use the Shell syntax.
I've tried "View/Syntax/Open all with current extension as..." but for all files, I have to make again the manipulation.
I've tried the package "applySyntax" but it not seem to work with this configuration:
{
"name": "ShellScript/Shell-Unix-Generic",
"rules": [
{"file_name": "PRE_*$"}
]
}
All my files start with "PRE_[something]", someone know how to resolve this problem?
Thx!
I've found a Gist with a plugin to set the syntax based on the file name, I've modified it a bit to match files starting with PRE_:
import sublime_plugin
import os
class DetectFileTypeCommand(sublime_plugin.EventListener):
def on_load(self, view):
filename = view.file_name()
if not filename: # buffer has never been saved
return
name = os.path.basename(filename)
if name.startswith("PRE_"):
set_syntax(view, "Shell-Unix-Generic", "ShellScript")
def set_syntax(view, syntax, path=None):
if path is None:
path = syntax
view.settings().set('syntax', 'Packages/'+ path + '/' + syntax + '.tmLanguage')
print "Switched syntax to: " + syntax
You can go to Preferences->Browse Packages, and save it there ending with .py, I recommend creating a directory for it (e.g. DetectFileType/detect_file_type.py).

Ruby/Slim: parse Markdown from a YAML file

Been struggling for a while with some YAML parsing inside a Slim template.
my YAML file contain
shortdesc: >
markdown:
if you want to up the feelgood factor Cuban style, then this Monday night at The Buffalo Bar is for you...
But when I output the shortdesc node in my template it's displayed as a string and not interpreted. ("markdown: if you....")
Is there a way to parse the YAML output string to interpret the markdown code?
If I try
p
markdown:
= shortdesc
the template doesn't understand the call to the variable containing the YAML node.
Is that even possible?
It depends on the Markdown Library that you are using.
In BlueCloth, it would be something like this:
= BlueCloth.new(shortdesc).to_html
Yes it's possible. Just need to use interpolation:
p
markdown:
#{shortdesc}

How do I execute ruby template files (ERB) without a web server from command line?

I need ERB (Ruby's templating system) for templating of non-HTML files.
(Instead, I want to use it for source files such as .java, .cs, ...)
How do I "execute" Ruby templates from command line?
You should have everything you need in your ruby/bin directory. On my (WinXP, Ruby 1.8.6) system, I have ruby/bin/erb.bat
erb.bat [switches] [inputfile]
-x print ruby script
-n print ruby script with line number
-v enable verbose mode
-d set $DEBUG to true
-r [library] load a library
-K [kcode] specify KANJI code-set
-S [safe_level] set $SAFE (0..4)
-T [trim_mode] specify trim_mode (0..2, -)
-P ignore lines which start with "%"
so erb your_erb_file.erb should write the result to STDOUT.
(EDIT: windows has erb.bat and just plain "erb". The .bat file is just a wrapper for erb, which I guess should make the same command work pretty much the same on any OS)
See the prag prog book discussion (starts about half-way down the page).
Note also that Jack Herrington wrote a whole book about code generation that uses Ruby/ERB.
Write a ruby script that does it. The API documentation is here:
http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/
For example:
template = ERB.new File.read("path/to/template.erb"), nil, "%"
template.result(binding)
(Where binding is a binding with the #vars that the template needs.)
Another option would be to use ruby -e, since ERB itslef is so simple.
Something like:
ruby -rerb -e "puts ERB.new(File.read(<file name here>)).result"
However, I assume you have a context you want to render the template in. How are you expecting to get that context? As an example, check out:
ruby -rerb -e "hello = 'hello'; puts ERB.new('<%= hello %> world').result(binding)"
which will print out "hello world", using the top-level, where you defined the hello variable, as the binding.
If you can switch ERB to Erubis, your problem solving is as simple as:
require 'erubis'
template = File.read("sample_file.erb")
template = Erubis::Eruby.new(template)
template.result(:your_variable => "sample")
Found this question while trying to test my Puppet templates.
Ended with this solution:
Along your foo.erb create a file foo.vars.erb
Put all your template variables into that new file, e.g.:
<% #my_param="foo bar" %>
<% #another_param=123 %>
or (equivalent):
<%
#my_param="foo bar"
#another_param=123
%>
On command line run this:
cat foo.vars.erb foo.erb | erb
Your fully rendered template should now be printed to std-out. From there you check the output by hand, or you can take diff (or other tools) to compare it to a pre-rendered output.
I tried to comment on this, but comments link not available.
I'm using this:
template = ERB.new File.new("path/to/template.erb").read, nil, "%"
template.result(binding)
From the posting above: and I found what I think it might be a problem:
I'm creating DOS BATCH files like:
%JAVA_HOME%\bin\jar -xvf <%=inputfile%>...
And I found weird thing problem - I get this when I run with the code above:
Processing Template test.txt
erb):2:in `render': compile error (SyntaxError)
erb):2: syntax error, unexpected tSTRING_BEG, expecting $end
erbout.concat "\n"
^
from DBUser.rb:49:in `render'
from DBUser.rb:43:in `each'
from DBUser.rb:43:in `render'
from DBUser.rb:81
I tried the following, and got round my particular problem - not sure if this is the right answer for everybody ...
template = ERB.new File.new("path/to/template.erb").read
template.result(binding)

A problem with folding bash functions in vim

I have a bash script file which starts with a function definition, like this:
#!/bin/bash
# .....
# .....
function test {
...
...
}
...
...
I use vim 7.2, and I have set g:sh_fold_enabled=1 such that folding is enabled with bash. The problem is that the folding of the function test is not ended correctly, i.e. it lasts until the end of file. It looks something like this:
#!/bin/bash
# .....
# .....
+-- 550 lines: function test {----------------------------------------
~
~
The function itself is just about 40 lines, and I want something that lookes like this ("images" say more than a thousend words, they say...):
#!/bin/bash
# .....
# .....
+-- 40 lines: function test {----------------------------------------
...
...
...
~
~
Does anyone know a good solution to this problem?
I have done some research, and found a way to fix the problem: To stop vim from folding functions until the end of file, I had to add a skip-statement to the syntax region for shExpr (in the file sh.vim, usually placed somewhere like /usr/share/vim/vim70/syntax/):
syn region shExpr ... start="{" skip="^function.*\_s\={" end="}" ...
This change stops the syntax file from thinking that the { and } belongs to the shExpr group, when they actually belong to the function group. Or that is how I have understood it, anyway.
Note: This fix only works for the following syntax:
function test
{
....
}
and not for this:
function test {
....
}
A quick and dirty fix for the last bug is to remove shExpr from the #shFunctionList cluster.
with vim 8.2+ the following worked for me:
syntax enable
let g:sh_fold_enabled=5
let g:is_sh=1
set filetype=on
set foldmethod=syntax
" :filteype plugin indent on
foldnestmax=3 "i use 3, change it to whatever you like.
it did not matter where i put it in my vimrc.
and this turns on syntax folding and the file type plugin for all installed file types.
It should just work, but there seems to be a bug in the syntax file. The fold region actually starts at the word 'function' and tries to continue to the closing '}', but the highlighting for the '{...}' region takes over the closing '}' and the fold continues on searching for another one. If you add another '}' you can see this in action:
function test {
...
}
}
There seems to be a simpler solution on Reddit.
To quote the author in the post:
The options I use are:
syntax=enable
filetype=sh
foldmethod=syntax
let g:sh_fold_enabled=3
g:is_sh=1
EDIT: Workaround
vim -u NONE -c 'let g:sh_fold_enabled=7' -c ':set fdm=syntax' -c 'sy
on' file.sh
g:sh_fold_enabled=4 seemed to be the agreed upon fold-level in the discussion. This solution is working perfectly for me. I did not have to edit the syntax file.
Edit: g:sh_fold_enabled=5 is actually the right one. Not 4.
Also, as the poster showed on Reddit, those commands must go before any other setting in vimrc, except the plugins.

Resources