Skip to content

Commit

Permalink
Add full package
Browse files Browse the repository at this point in the history
  • Loading branch information
Nelson Yeung committed May 25, 2016
1 parent 61ed307 commit 6190e27
Show file tree
Hide file tree
Showing 6 changed files with 370 additions and 1 deletion.
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,36 @@
# twig.vim
# Twig.vim
Twig syntax highlighting, indentation and neocomplete snippets in Vim

## Installation
To install twig.vim and other Vim plug-ins it is recommended to use one of the popular package managers for Vim, rather than installing by drag and drop all required files into your .vim folder.

### Neobundle (recommended)
1. Setup the [neobundle](https://github.com/Shougo/neobundle.vim) package manager
2. Set the bundles for [twig.vim](https://github.com/nelsyeung/twig.vim)

```vim
NeoBundle 'nelsyeung/twig.vim'
```
3. Open up Vim and start installation with `:NeoBundleInstall`
### Vundle
1. Setup the [vundle](https://github.com/gmarik/vundle) package manager
2. Set the bundles for [twig.vim](https://github.com/nelsyeung/twig.vim)
```vim
Plugin 'nelsyeung/twig.vim'
```
3. Open up Vim and start installation with `:PluginInstall`
### Manual (not recommended)
1. Down the [twig.vim](https://github.com/nelsyeung/twig.vim) files
2. Put files in your Vim directory (usually `~/.vim/` or `%PROGRAMFILES%/Vim/vimfiles` on Windows)
## Snippets
This package does not include the old snipMate snippets in favour of [Neosnippet](https://github.com/Shougo/neosnippet.vim). Follow the instructions on their page to get snippets working. Although a pull request has been submitted to include the snippets from this package, it may not have the latest snippets from this repository. To have the latest snippets working, you can add to your .vimrc
```vim
let g:neosnippet#snippets_directory='~/.vim/bundle/twig.vim/neosnippets'
```
2 changes: 2 additions & 0 deletions ftdetect/twig.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
" vim: set noexpandtab:
au BufNewFile,BufRead *.twig set ft=html.twig.js.css
2 changes: 2 additions & 0 deletions ftplugin/twig.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
" vim: set noexpandtab:
setlocal comments=s:{#,ex:#}
80 changes: 80 additions & 0 deletions indent/twig.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
" vim: set noexpandtab:
" Vim indent file
" Language: Twig
" Acknowledgement: Based on lumiliet/vim-twig

if exists("b:did_indent")
finish
endif
let b:did_indent = 1

let s:baseIndentExpr=&indentexpr
setlocal indentexpr=GetTwigIndent(v:lnum)

fun! GetTwigIndent(currentLineNumber)
let currentLine = getline(a:currentLineNumber)
let previousLineNumber = prevnonblank(a:currentLineNumber - 1)
let previousLine = getline(previousLineNumber)

if (previousLine =~ s:startStructures || previousLine =~ s:middleStructures) && (currentLine !~ s:endStructures && currentLine !~ s:middleStructures)
return indent(previousLineNumber) + &shiftwidth
elseif currentLine =~ s:endStructures || currentLine =~ s:middleStructures
let previousOpenStructureNumber = s:FindPreviousOpenStructure(a:currentLineNumber)
let previousOpenStructureLine = getline(previousOpenStructureNumber)
return indent(previousOpenStructureNumber)
endif

return s:CallBaseIndent()
endf

function! s:CallBaseIndent()
exe 'redir => s:outputOfBaseIndent'
exe 'silent echo ' . s:baseIndentExpr
exe 'redir END'
return split(s:outputOfBaseIndent)[0]
endf


function! s:FindPreviousOpenStructure(lineNumber)
let countOpen = 0
let countClosed = 0
let lineNumber = a:lineNumber
while lineNumber != 1 && countOpen <= countClosed
let lineNumber -= 1
let currentLine = getline(lineNumber)

if currentLine =~ s:startStructures
let countOpen += 1
elseif currentLine =~ s:endStructures
let countClosed += 1
endif
endwhile

return lineNumber
endfunction

function! s:StartStructure(name)
return '^\s*{%\s*' . a:name . '.*%}'
endfunction

function! s:EndStructure(name)
return '^\s*{%\s*end' . a:name . '.*%}'
endfunction

function! s:Map(Fun, list)
if len(a:list) == 0
return []
else
return [a:Fun(a:list[0])] + s:Map(a:Fun, a:list[1:])
endif
endfunction

fun! s:BuildStructures()
let structures = ['if','for','block']
let mStructures = ['elseif','else']
let s:startStructures = join(s:Map(function('s:StartStructure'), structures), '\|')
let s:endStructures = join(s:Map(function('s:EndStructure'), structures), '\|')
let s:middleStructures = join(s:Map(function('s:StartStructure'), mStructures), '\|')
endfun

call s:BuildStructures()
148 changes: 148 additions & 0 deletions neosnippets/twig.snip
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
snippet autoescape
abbr {% autoescape ... %} ... {% endautoescape %}
options head
{% autoescape ${1:#:strategy} %}
${0:TARGET}
{% autoescape %}

snippet block
abbr {% block ... %} ... {% endblock %}
alias bl
options head
{% block ${1:#:name} %}
${0:TARGET}
{% endblock %}

snippet embed
abbr {% embed ... %} ... {% endembed %}
options head
{% embed '${1:template}' %}
{% block ${2} %}
${0:TARGET}
{% endblock %}
{% endembed %}

snippet extends
abbr {% extends ... %}
alias ext
options head
{% extends '${1:#:template}' %}

snippet filter
abbr {% filter ... %} ... {% endfilter %}
options head
{% filter ${1} %}
${0:TARGET}
{% endfilter %}

snippet flush
abbr {% flush %}
options head
{% flush %}

snippet for
abbr {% for ... in ... %} ... {% endfor %}
options head
{% for ${1:#:value} in ${2:#:list} %}
${0:TARGET}
{% endfor %}

snippet from
abbr {% from '...' import ... %}
options head
{% from '${1:#:module}' import ${2:#:macro}}

snippet if
abbr {% if ... %} ... {% endif %}
options head
{% if ${1} %}
${0:TARGET}
{% endif %}

snippet elseif
abbr {% elseif ... %} ...
alias elif
options head
{% elseif ${1} %}
${0:TARGET}

snippet else
abbr {% else %} ...
options head
{$ else %}
${0:TARGET}

snippet import
abbr {% import '...' as ... %}
options head
{% import '${1:#:module}' as ${2:#:namespace}}

snippet include
abbr {% include '...' %}
options head
{% include '${1:#:template}'}

snippet macro
abbr {% macro ...(...) %} ... {% endmacro %}
options head
{% macro ${1:#:name}(${2:#:args}) %}
${0:TARGET}
{% endif %}

snippet sandbox
abbr {% sandbox %} ... {% endsandbox %}
options head
{% sandbox %}
${0:TARGET}
{% endsandbox %}

snippet set
abbr {% set ... = ... %}
options head
{% set ${1:#:var} = ${2:#:value} %}

snippet setblock
abbr {% set ... %} ... {% endset %}
options head
{% set ${1:#:var} %}
${0:TARGET}
{% endset %}

snippet spaceless
abbr {% spaceless %} ... {% endspaceless %}
options head
{% spaceless %}
${0:TARGET}
{% endspaceless %}

snippet use
abbr {% use '...' %}
options head
{% use '${1:#:template}' %}

snippet verbatim
abbr {% verbatim %} ... {% endverbatim %}
options head
{% verbatim %}
${0:TARGET}
{% endverbatim %}

snippet comment
abbr {# ... #}
alias #
options head
{# ${1:comment} #}

snippet tag
abbr {% ... %}
alias %
options head
{% ${1:#:tag} %}

snippet tagblock
abbr {% ... %} ... {% end... %}
options head
{% ${1:#:tag} ${2:#:name} %}
${0:TARGET}
{% end$1 %}

103 changes: 103 additions & 0 deletions syntax/twig.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
" vim: set noexpandtab:
" Vim syntax file
" Language: Twig
" Maintainer: Nelson Yeung
" URL: https://github.com/nelsyeung/twig.vim
" Acknowledgement: Based on evidens/vim-twig

if exists('b:main_syntax')
finish
endif
if exists('b:current_syntax')
let b:main_syntax = b:current_syntax
else
let b:main_syntax = 'twig'
endif

syntax case match

" Twig template built-in tags and parameters (without filter, macro, is and raw, they have special treatment)
syn keyword twigStatement containedin=twigVarBlock,twigTagBlock,twigNested contained and if else in not or recursive as import

syn keyword twigStatement containedin=twigVarBlock,twigTagBlock,twigNested contained is filter skipwhite nextgroup=twigFilter
syn keyword twigStatement containedin=twigTagBlock contained macro skipwhite nextgroup=twigFunction
syn keyword twigStatement containedin=twigTagBlock contained block skipwhite nextgroup=twigBlockName

" Variable Names
syn match twigVariable containedin=twigVarBlock,twigTagBlock,twigNested contained skipwhite /[a-zA-Z_][a-zA-Z0-9_]*/
syn keyword twigSpecial containedin=twigVarBlock,twigTagBlock,twigNested contained false true none loop super caller varargs kwargs

" Filters
syn match twigOperator "|" containedin=twigVarBlock,twigTagBlock,twigNested contained nextgroup=twigFilter
syn match twigFilter contained skipwhite /[a-zA-Z_][a-zA-Z0-9_]*/
syn match twigFunction contained skipwhite /[a-zA-Z_][a-zA-Z0-9_]*/
syn match twigBlockName contained skipwhite /[a-zA-Z_][a-zA-Z0-9_]*/

" Twig template constants
syn region twigString containedin=twigVarBlock,twigTagBlock,twigNested contained start=/"/ skip=/\\"/ end=/"/
syn region twigString containedin=twigVarBlock,twigTagBlock,twigNested contained start=/'/ skip=/\\'/ end=/'/
syn match twigNumber containedin=twigVarBlock,twigTagBlock,twigNested contained /[0-9]\+\(\.[0-9]\+\)\?/

" Operators
syn match twigOperator containedin=twigVarBlock,twigTagBlock,twigNested contained /[+\-*\/<>=!,:]/
syn match twigPunctuation containedin=twigVarBlock,twigTagBlock,twigNested contained /[()\[\]]/
syn match twigOperator containedin=twigVarBlock,twigTagBlock,twigNested contained /\./ nextgroup=twigAttribute
syn match twigAttribute contained /[a-zA-Z_][a-zA-Z0-9_]*/

" Twig template tag and variable blocks
syn region twigNested matchgroup=twigOperator start="(" end=")" transparent display containedin=twigVarBlock,twigTagBlock,twigNested contained
syn region twigNested matchgroup=twigOperator start="\[" end="\]" transparent display containedin=twigVarBlock,twigTagBlock,twigNested contained
syn region twigNested matchgroup=twigOperator start="{" end="}" transparent display containedin=twigVarBlock,twigTagBlock,twigNested contained
syn region twigTagBlock matchgroup=twigTagDelim start=/{%-\?/ end=/-\?%}/ skipwhite containedin=ALLBUT,twigTagBlock,twigVarBlock,twigRaw,twigString,twigNested,twigComment

syn region twigVarBlock matchgroup=twigVarDelim start=/{{-\?/ end=/-\?}}/ containedin=ALLBUT,twigTagBlock,twigVarBlock,twigRaw,twigString,twigNested,twigComment

" Twig template 'raw' tag
syn region twigRaw matchgroup=twigRawDelim start="{%\s*raw\s*%}" end="{%\s*endraw\s*%}" containedin=ALLBUT,twigTagBlock,twigVarBlock,twigString,twigComment

" Twig comments
syn region twigComment matchgroup=twigCommentDelim start="{#" end="#}" containedin=ALLBUT,twigTagBlock,twigVarBlock,twigString

" Block start keywords. A bit tricker. We only highlight at the start of a
" tag block and only if the name is not followed by a comma or equals sign
" which usually means that we have to deal with an assignment.
syn match twigStatement containedin=twigTagBlock contained skipwhite /\({%-\?\s*\)\@<=\<[a-zA-Z_][a-zA-Z0-9_]*\>\(\s*[,=]\)\@!/

" and context modifiers
syn match twigStatement containedin=twigTagBlock contained /\<with\(out\)\?\s\+context\>/ skipwhite

" Define the default highlighting.
" For version 5.7 and earlier: only when not done already
" For version 5.8 and later: only when an item doesn't have highlighting yet
if version >= 508 || !exists("did_twig_syn_inits")
if version < 508
let did_twig_syn_inits = 1
command -nargs=+ HiLink hi link <args>
else
command -nargs=+ HiLink hi def link <args>
endif

HiLink twigPunctuation twigOperator
HiLink twigAttribute twigVariable
HiLink twigFunction twigFilter

HiLink twigTagDelim twigTagBlock
HiLink twigVarDelim twigVarBlock
HiLink twigCommentDelim twigComment
HiLink twigRawDelim twig

HiLink twigSpecial Special
HiLink twigOperator Normal
HiLink twigRaw Normal
HiLink twigTagBlock PreProc
HiLink twigVarBlock PreProc
HiLink twigStatement Statement
HiLink twigFilter Function
HiLink twigBlockName Function
HiLink twigVariable Identifier
HiLink twigString Constant
HiLink twigNumber Constant
HiLink twigComment Comment

delcommand HiLink
endif

0 comments on commit 6190e27

Please sign in to comment.