Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Commit

Permalink
Merge pull request #136 from Alhadis/modelines
Browse files Browse the repository at this point in the history
Add support for Emacs/Vim modelines
  • Loading branch information
Wliu authored Sep 29, 2016
2 parents e31f750 + 00e6cb7 commit 46ffb55
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 1 deletion.
15 changes: 14 additions & 1 deletion grammars/html.cson
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,20 @@
'tpl'
'xhtml'
]
'firstLineMatch': '<(?i:(!DOCTYPE\\s*)?html)'
'firstLineMatch': '''(?xi)
# Document type definition
<(?:!DOCTYPE\\s*)?html
|
# Emacs modeline
-\\*-(?:\\s*(?=[^:;\\s]+\\s*-\\*-)|(?:.*?[;\\s]|(?<=-\\*-))mode\\s*:\\s*)
html
(?=[\\s;]|(?<![-*])-\\*-).*?-\\*-
|
# Vim modeline
(?:(?:\\s|^)vi(?:m[<=>]?\\d+|m)?|\\sex)(?=:(?=\\s*set?\\s[^\\n:]+:)|:(?!\\s*set?\\s))(?:(?:\\s|\\s*:\\s*)\\w*(?:\\s*=(?:[^\\n\\\\\\s]|\\\\.)*)?)*[\\s:](?:filetype|ft|syntax)\\s*=
x?html
(?=\\s|:|$)
'''
'name': 'HTML'
'patterns': [
{
Expand Down
88 changes: 88 additions & 0 deletions spec/html-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,91 @@ describe 'HTML grammar', ->
expect(tokens[3]).toEqual value: 'amp', scopes: ['text.html.basic', 'constant.character.entity.html', 'entity.name.entity.other.html']
expect(tokens[4]).toEqual value: ';', scopes: ['text.html.basic', 'constant.character.entity.html', 'punctuation.definition.entity.end.html']
expect(tokens[7]).toEqual value: 'a', scopes: ['text.html.basic', 'constant.character.entity.html', 'entity.name.entity.other.html']

describe "firstLineMatch", ->
it "recognises HTML5 doctypes", ->
expect(grammar.firstLineRegex.scanner.findNextMatchSync("<!DOCTYPE html>")).not.toBeNull()
expect(grammar.firstLineRegex.scanner.findNextMatchSync("<!doctype HTML>")).not.toBeNull()

it "recognises Emacs modelines", ->
valid = """
#-*- HTML -*-
#-*- mode: HTML -*-
/* -*-html-*- */
// -*- HTML -*-
/* -*- mode:HTML -*- */
// -*- font:bar;mode:HTML -*-
// -*- font:bar;mode:HTML;foo:bar; -*-
// -*-font:mode;mode:HTML-*-
// -*- foo:bar mode: html bar:baz -*-
" -*-foo:bar;mode:html;bar:foo-*- ";
" -*-font-mode:foo;mode:html;foo-bar:quux-*-"
"-*-font:x;foo:bar; mode : HTML; bar:foo;foooooo:baaaaar;fo:ba;-*-";
"-*- font:x;foo : bar ; mode : HtML ; bar : foo ; foooooo:baaaaar;fo:ba-*-";
"""
for line in valid.split /\n/
expect(grammar.firstLineRegex.scanner.findNextMatchSync(line)).not.toBeNull()

invalid = """
/* --*html-*- */
/* -*-- HTML -*-
/* -*- -- HTML -*-
/* -*- HTM -;- -*-
// -*- xHTML -*-
// -*- HTML; -*-
// -*- html-stuff -*-
/* -*- model:html -*-
/* -*- indent-mode:html -*-
// -*- font:mode;html -*-
// -*- HTimL -*-
// -*- mode: -*- HTML
// -*- mode: -html -*-
// -*-font:mode;mode:html--*-
"""
for line in invalid.split /\n/
expect(grammar.firstLineRegex.scanner.findNextMatchSync(line)).toBeNull()

it "recognises Vim modelines", ->
valid = """
vim: se filetype=html:
# vim: se ft=html:
# vim: set ft=HTML:
# vim: set filetype=XHTML:
# vim: ft=XHTML
# vim: syntax=HTML
# vim: se syntax=xhtml:
# ex: syntax=HTML
# vim:ft=html
# vim600: ft=xhtml
# vim>600: set ft=html:
# vi:noai:sw=3 ts=6 ft=html
# vi::::::::::noai:::::::::::: ft=html
# vim:ts=4:sts=4:sw=4:noexpandtab:ft=html
# vi:: noai : : : : sw =3 ts =6 ft =html
# vim: ts=4: pi sts=4: ft=html: noexpandtab: sw=4:
# vim: ts=4 sts=4: ft=html noexpandtab:
# vim:noexpandtab sts=4 ft=html ts=4
# vim:noexpandtab:ft=html
# vim:ts=4:sts=4 ft=html:noexpandtab:\x20
# vim:noexpandtab titlestring=hi\|there\\\\ ft=html ts=4
"""
for line in valid.split /\n/
expect(grammar.firstLineRegex.scanner.findNextMatchSync(line)).not.toBeNull()

invalid = """
ex: se filetype=html:
_vi: se filetype=HTML:
vi: se filetype=HTML
# vim set ft=html5
# vim: soft=html
# vim: clean-syntax=html:
# vim set ft=html:
# vim: setft=HTML:
# vim: se ft=html backupdir=tmp
# vim: set ft=HTML set cmdheight=1
# vim:noexpandtab sts:4 ft:HTML ts:4
# vim:noexpandtab titlestring=hi\\|there\\ ft=HTML ts=4
# vim:noexpandtab titlestring=hi\\|there\\\\\\ ft=HTML ts=4
"""
for line in invalid.split /\n/
expect(grammar.firstLineRegex.scanner.findNextMatchSync(line)).toBeNull()

0 comments on commit 46ffb55

Please sign in to comment.