diff --git a/.github/img/nvim_043_ver_020.gif b/.github/img/nvim_043_ver_020.gif
deleted file mode 100644
index 98dc2ee..0000000
Binary files a/.github/img/nvim_043_ver_020.gif and /dev/null differ
diff --git a/.github/img/nvim_043_ver_021.gif b/.github/img/nvim_043_ver_021.gif
new file mode 100644
index 0000000..4cf90eb
Binary files /dev/null and b/.github/img/nvim_043_ver_021.gif differ
diff --git a/.travis.yml b/.travis.yml
index c76b083..d879110 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,6 +18,8 @@ addons:
apt:
update: true
+cache: pip
+
install:
- pip install -r test/requirements.txt
- git clone https://github.com/junegunn/vader.vim.git
@@ -27,4 +29,4 @@ script:
- pytest -v
- nvim --startuptime nvim_bench.log -ENsu test/vimrc -c '+Vader! test/vader/*' > /dev/null
- VIM= vim --startuptime vim_bench.log -ENsu test/vimrc -c '+Vader! test/vader/*' > /dev/null
- - awk '/.*plugin\/cpywrite\.vim.*$/' nvim_bench.log vim_bench.log
+ - awk '/.*\/cpywrite\.vim.*$/{print $2 " " $3 " " $5}' *.log | sort
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f0f2bf8..ffca30d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,23 @@
+### 0.2.1
+
+- add support for these file types:
+ - Ada
+ - Assembler
+ - Coffescript
+ - Elixir
+ - Elm
+ - Erlang
+ - Kotlin
+ - Lua
+ - Objective-C
+ - Pascal
+
+- recognize `.vimrc` as VimL
+- prevent copyright notice for appearing on public domain (i.e. copyright-free) licenses, in both modes
+- fix regex that was inserting authorship at random places in full license text
+- leave one blank line after header
+- improve load time of `autoload/cpywrite.vim`
+
### 0.2.0
- extract feature tests and core functions to `autoload` directory to [improve startup time][pr2]
diff --git a/README.md b/README.md
index c203987..4b621e2 100644
--- a/README.md
+++ b/README.md
@@ -4,13 +4,13 @@
Generate copyright headers for any open source license
-
+
## Description
Mostly written in CPython, this (neo)vim plugin fetches the license of your choice directly from the [SPDX License List](https://github.com/spdx/license-list-xml). If the XML response contains a standard header, it's inserted at the top of the current buffer with your copyright info.
-When no standard header is provided, you can either insert a brief license acknowledgement, or the full license text. (See the `g:cpywrite_verbatim_mode` option [below](#quick-reference).)
+When no standard header is provided, you can either insert a brief license acknowledgement, or the full license text. (See the `g:cpywrite_verbatim_mode` option [below](#options).)
This plugin learns your name and email by invoking `git`. If that fails, the copyright line will contain your OS user and host names.
@@ -41,7 +41,7 @@ This plugin learns your name and email by invoking `git`. If that fails, the cop
| | |
|:--|:--|
|`g:cpywrite_default_license`|The SPDX identifier of the license to be fetched by the `:CPYwrite` command.|
-|`g:cpywrite_verbatim_mode`|When set to 1, the full license text will be requested -- only choose this when the license is no longer than 3-4 paragraphs (e.g. Unlicense, MIT, BSD 1- 2- 3-Clause, etc.)|
+|`g:cpywrite_verbatim_mode`|When set to a non-zero value, the full license text will be requested -- only choose this when the license is no longer than 3-4 paragraphs (e.g. Unlicense, MIT, BSD 1- 2- 3-Clause, etc.)|
## Requirements
@@ -120,8 +120,9 @@ call vundle#end()
## TODO
-- Provide a batch mode for licensing all tracked files in a working tree
-- Expand the list of [supported programming languages][lang-list]
+- [ ] Provide a batch mode for licensing all tracked files in a working tree
+- [ ] Provide the option to set user-defined authorship details
+- [x] Expand the list of [supported programming languages][lang-list]
## Improve this README
@@ -143,7 +144,7 @@ Distributed under the terms of the MIT license
[licl]: https://www.vim.org/scripts/script.php?script_id=4064
[vim-8-pkg-docs]: https://github.com/vim/vim/blob/03c3bd9fd094c1aede2e8fe3ad8fd25b9f033053/runtime/doc/repeat.txt#L515
[vim-pack-man]: https://shapeshed.com/vim-packages/#how-it-works
-[lang-list]: rplugin/pythonx/cpywrite/generator.py#L255
+[lang-list]: rplugin/pythonx/cpywrite/generator.py#L273
[travis-badge]: https://travis-ci.com/rdipardo/vim-cpywrite.svg?token=yCqYFpeQtymaztY4Spav&branch=master
[travis-builds]: https://travis-ci.com/rdipardo/vim-cpywrite
diff --git a/autoload/cpywrite.vim b/autoload/cpywrite.vim
index 00dd137..5f41612 100644
--- a/autoload/cpywrite.vim
+++ b/autoload/cpywrite.vim
@@ -13,13 +13,6 @@ if has('python3') || has('python')
if empty(get(s:, 'cpywrite_python_cmd', ''))
let s:cpywrite_python_cmd = (has('python3') ? 'py3' : 'py') . 'file'
endif
-
- if empty(get(g:, 'cpywrite_version', ''))
- exe s:cpywrite_python_cmd
- \ fnamemodify(
- \ globpath(&rtp, 'plugin/cpywrite/version.py', 0, 1)[0],
- \ ':p')
- endif
endif
func! cpywrite#PrependHeader(...) abort
diff --git a/doc/cpywrite.txt b/doc/cpywrite.txt
index c367aff..2060478 100644
--- a/doc/cpywrite.txt
+++ b/doc/cpywrite.txt
@@ -1,9 +1,19 @@
-*cpywrite.txt* Generate copyright headers for any open source license
+Generate copyright headers for any open source license *cpywrite.txt*
Maintainer: Robert Di Pardo
URL: https://github.com/rdipardo/vim-cpywrite
License: MIT
+==============================================================================
+CONTENTS *cpywrite-contents*
+
+ Introduction ................................... |cpywrite-introduction|
+ Requirements ................................... |cpywrite-requirements|
+ Attributes ....................................... |cpywrite-attributes|
+ Options ............................................. |cpywrite-options|
+ Commands ........................................... |cpywrite-commands|
+ Mappings ............................................ |cpywrite-keymaps|
+
=============================================================================
INTRODUCTION *cpywrite-introduction*
@@ -37,7 +47,7 @@ REQUIREMENTS *cpywrite-requirements*
ATTRIBUTES *cpywrite-attributes*
*g:cpywrite_version*
- `string` (set at runtime by the autoload script)
+ `string`
The current version number of this plugin.
@@ -53,9 +63,10 @@ the |:CPYwriteDefaultLicense| or |:CPYwrite| command for suggestions.
*g:cpywrite_verbatim_mode*
`number` (default: 0)
-When set to 1, the full license text will be requested, whether or not a
-standard header exists. You should only choose this when the license is no
-longer than 3-4 paragraphs (e.g. Unlicense, MIT, BSD 1- 2- 3-Clause, etc.)
+When set to a non-zero value, the full license text will be requested, whether
+or not a standard header exists. You should only choose this when the license
+is no longer than 3-4 paragraphs (e.g. Unlicense, MIT, BSD 1- 2- 3-Clause,
+etc.)
When set to 0, only standard headers are requested. Licenses with no standard
header will be briefly mentioned below your copyright line.
@@ -89,7 +100,6 @@ description of the updated state:
0 == "standard header/brief"
1 == "verbatim"
<
-
*(cpywrite)*
Quick action command for fetching the default license assigned to
|g:cpywrite_default_license|.
diff --git a/doc/tags b/doc/tags
index e05b4ae..f02df04 100644
--- a/doc/tags
+++ b/doc/tags
@@ -5,6 +5,7 @@
LH cpywrite.txt /*LH*
cpywrite-attributes cpywrite.txt /*cpywrite-attributes*
cpywrite-commands cpywrite.txt /*cpywrite-commands*
+cpywrite-contents cpywrite.txt /*cpywrite-contents*
cpywrite-introduction cpywrite.txt /*cpywrite-introduction*
cpywrite-keymaps cpywrite.txt /*cpywrite-keymaps*
cpywrite-options cpywrite.txt /*cpywrite-options*
diff --git a/plugin/cpywrite.vim b/plugin/cpywrite.vim
index 7f35b51..91af35a 100644
--- a/plugin/cpywrite.vim
+++ b/plugin/cpywrite.vim
@@ -9,6 +9,8 @@
if get(g:, 'loaded_cpywrite') | finish | endif
let g:loaded_cpywrite = 1
+let g:cpywrite_version = '0.2.1'
+
if empty(get(g:, 'cpywrite_default_license', ''))
let g:cpywrite_default_license = 'GPL-3.0-or-later'
endif
diff --git a/plugin/cpywrite/main.py b/plugin/cpywrite/main.py
index d4dc17a..782fa97 100644
--- a/plugin/cpywrite/main.py
+++ b/plugin/cpywrite/main.py
@@ -35,7 +35,7 @@ def _write_header(writer, curr_buffer):
try:
use_text_as_header = bool(int(use_text_as_header, 10))
except ValueError:
- print("'g:cpywrite_verbatim_mode' should be set to 1 or 0!",
+ print("'g:cpywrite_verbatim_mode' should be set to a number!",
file=sys.stderr)
vim.command('let g:cpywrite_verbatim_mode=0')
use_text_as_header = False
@@ -54,7 +54,7 @@ def _write_header(writer, curr_buffer):
if to_trim > 0:
del curr_buffer[0:to_trim]
- curr_buffer[0:0] = header.split('\n')[:-1]
+ curr_buffer[0:0] = header.split('\n')
except (ValueError, vim.error) as exc:
print(str(exc))
diff --git a/plugin/cpywrite/version.py b/plugin/cpywrite/version.py
deleted file mode 100644
index 36120bd..0000000
--- a/plugin/cpywrite/version.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-Expose plugin version
-"""
-import sys
-import vim
-for path in vim.eval('globpath(&rtp, "rplugin/pythonx", 1)').split('\n'):
- sys.path.append(path)
-from cpywrite import __version__
-
-
-def get_plugin_version():
- """Retrieve the version number of this plugin"""
- try:
- vim.command("let g:cpywrite_version = printf('%s', '" + \
- __version__ + "')")
- except vim.error:
- pass
-
-
-if __name__ == '__main__':
- get_plugin_version()
diff --git a/rplugin/pythonx/cpywrite/__init__.py b/rplugin/pythonx/cpywrite/__init__.py
index f01668a..c320e37 100644
--- a/rplugin/pythonx/cpywrite/__init__.py
+++ b/rplugin/pythonx/cpywrite/__init__.py
@@ -20,7 +20,7 @@
~~~~~~~~~
"""
-__version__ = '0.2.0'
+__version__ = '0.2.1'
__authors__ = ['Robert Di Pardo']
__url__ = 'https://github.com/rdipardo/vim-cpywrite'
__license__ = 'MIT'
diff --git a/rplugin/pythonx/cpywrite/generator.py b/rplugin/pythonx/cpywrite/generator.py
index bc6d580..3b145bd 100644
--- a/rplugin/pythonx/cpywrite/generator.py
+++ b/rplugin/pythonx/cpywrite/generator.py
@@ -12,7 +12,7 @@
from os import path, environ
from platform import system
from subprocess import check_output, CalledProcessError
-from cpywrite.spdx.license import License
+from cpywrite.spdx.license import License, in_pub_domain
__all__ = ['Generator', 'extensions']
@@ -38,7 +38,7 @@ def set_file_props(self, filename, rights=''):
self.lang = lang
self.tokens = tokens
- def fetch_license_header(self, use_license_body=False):
+ def fetch_license_header(self, full_text=False):
"""Return a license header, with or without standard language"""
def _continue_block_comment(dest):
try:
@@ -55,36 +55,40 @@ def _close_block_comment(dest):
if self.lang_key == 'php':
print('\n?>', file=dest)
- def _apply_format(text, pattern, copying, email):
- year = str(datetime.now())[:4]
- # - fix up copyright format and insert punctuation;
- # - wrap text if raw header has no break after author's email;
- # - catch some precularities of the older license templates
- text = re.sub(r'\)%s' % year,
- ') ' + year,
- re.sub(r'(%s).+(\w+Permission)' % self.tokens[1],
- '%sPermission' % self.tokens[1],
- re.sub(r'(?!$)<%s> ' % email,
- '<%s>. ' % email,
- pattern.sub(
- copying[14:],
- re.sub(r'(%s).+[19]*[xy]{2,} .*\n' \
- % self.tokens[1],
- '',
- text, re.IGNORECASE)))))
-
+ def _apply_format(text, pattern, author, email, year):
+ authorship = year + ' ' + author + ' <' + email + '>'
+
+ # watch out for 20^th-century year template of the older GPLs
+ text = \
+ pattern.sub(authorship,
+ re.sub(r'(%s).+[19]*[xy]{2,} .*\n' % self.tokens[1],
+ '', text, re.IGNORECASE))
+ # fix up copyright format and insert punctuation
+ if self.rights.spdx_code.startswith('GFDL'):
+ text = re.sub(r'\)%s' % year,
+ ') ' + year,
+ re.sub(r'(%s).+(\w+Permission)' % self.tokens[1],
+ '%sPermission' % self.tokens[1],
+ re.sub(r'(?!$)<%s> ' % email,
+ '<%s>. ' % email,
+ text)))
+ # wrap text if raw header has no break after author's email
if self.rights.spdx_code.startswith('ECL'):
- run_on_text = re.search(r'(%s).+\<(%s)\>\w' % (self.tokens[1],
- email),
+ run_on_text = re.search(r'(%s).+((%s)|\<(%s)\>)\w' \
+ % (self.tokens[1], author, email),
text)
if run_on_text:
- text = re.sub(r'[\*\-\"#\/]*(%s)' % run_on_text.group(),
- '%s%s\n%s%s' % (self.tokens[1].lstrip(),
- copying + \
- ". Licensed under the",
- self.tokens[1],
- run_on_text.group()[-1]),
+ one_liner = \
+ 'Copyright (c) ' + authorship + ' Licensed under the'
+ text = re.sub(r'[\*(%s)]*(%s)'
+ % (self.tokens[1], run_on_text.group()),
+ '%s%s\n%s%s'
+ % (self.tokens[1],
+ one_liner,
+ self.tokens[1],
+ run_on_text.group()[-1]),
text)
+
return text
try:
@@ -95,7 +99,7 @@ def _apply_format(text, pattern, copying, email):
'Copyright (c) ' + year + ' ' + author + ' <' + email + '>'
terms = \
self.rights.header \
- if not use_license_body \
+ if not full_text \
else self.rights.license_text
author_date = \
re.compile(r"(?!.*(http).*)[\<\[\s][YEARX]+[\>\]\s].+[\>\]]",
@@ -107,7 +111,7 @@ def _apply_format(text, pattern, copying, email):
print(self.tokens[0], file=out)
print(self.tokens[1] + path.basename(self.out_file), file=out)
- if use_license_body:
+ if full_text:
_continue_block_comment(out)
if ''.join(terms).strip(): # found a standard header
@@ -118,33 +122,38 @@ def _clean_tokens(tkn, line):
'\n'.join([_clean_tokens(self.tokens[1], ln) + ln.rstrip() \
for ln in terms])
- if not author_date.search(terms):
+ if not author_date.search(terms) and not full_text:
# probably a GFDL or older GPL with an oddball authorship
# template
author_date = \
re.compile(r"(?!.*(http).*)[\<\[\s][YEARX]+[\>\]\s].+[\>\]\.]",
re.IGNORECASE)
- terms = _apply_format(terms, author_date, copying, email)
+ terms = _apply_format(terms, author_date, author, email, year)
- if not re.findall(r'(<%s>)' % email, terms, re.MULTILINE):
- # no authorship template at all
+ if not re.findall(r'(<%s>)' % email, terms, re.MULTILINE) \
+ and not in_pub_domain(self.rights.spdx_code):
+ # no authorship template, so use our own
_continue_block_comment(out)
print(self.tokens[1] + copying, file=out)
print(terms, file=out)
else: # no standard header
- _continue_block_comment(out)
- print(self.tokens[1] + copying, file=out)
+ if not in_pub_domain(self.rights.spdx_code):
+ _continue_block_comment(out)
+ print(self.tokens[1] + copying, file=out)
# License should return the name of any recognized license,
# even if there's no header; just be sure to call __str__
# explicitly
if str(self.rights):
_continue_block_comment(out)
- print(self.tokens[1] +
- "Licensed under the terms of %s" % (self.rights),
+ print(self.tokens[1] + \
+ ('Licensed' \
+ if not in_pub_domain(self.rights.spdx_code) \
+ else 'Distributed') + \
+ " under the terms of %s" % (self.rights),
file=out)
_close_block_comment(out)
@@ -170,6 +179,16 @@ def __repr__(self):
return str((self.__class__.__name__, self.lang))
+def extensions():
+ """Return a list of file extensions recognized by the Generator type"""
+ return sorted('*' + e for e in \
+ filter(len,
+ set(itertools.chain(
+ (l.lower() for l in _SOURCE_META
+ if not l[0] == '.' for l in l),
+ (lang.lower() for lang in _SOURCE_META
+ if lang[0] == '.')))))
+
def _get_language_meta(filename):
"""Identify programming language from file extension"""
if len(filename.strip()) < 1 or \
@@ -179,9 +198,15 @@ def _get_language_meta(filename):
fname, ext = path.splitext(filename)
- if not ext or ext == '.':
+ if not ext:
+ if fname.startswith('.'):
+ if path.basename(fname).lower()[1:] == 'vimrc':
+ return ('Vimrc', '', ('""', '"" '))
+
+ return ('dot', '', ('#', '# '))
+
print('No extension; assuming shell script')
- return ('Bash', '', ('#', '# '))
+ return ('Shell script', '', ('#', '# '))
if ext.lower() == '.txt' and path.basename(fname).lower() == 'cmakelists':
return ('CMake', '.txt', ('#', '# '))
@@ -191,10 +216,12 @@ def _get_language_meta(filename):
ext = ext.lower()
for k in _SOURCE_META:
- if ext in list(k):
+ # keys of only one element will get expanded into a char sequence
+ exts = [k] if k[0] == '.' else k
+ if ext in exts:
try:
for grp in _SOURCE_META[k][0]:
- if ext in list(grp) or ext == grp:
+ if ext in grp or ext == grp:
lang = _SOURCE_META[k][0][grp]
tokens = _SOURCE_META[k][1]
break
@@ -242,27 +269,21 @@ def _get_source_author():
return (author, email)
-def extensions():
- """Return a list of file extensions recognized by the Generator type"""
- return sorted('*' + e for e in \
- filter(len,
- set(itertools.chain(
- (l.lower() for l in _SOURCE_META
- if not isinstance(l, str) for l in l),
- (lang.lower() for lang in _SOURCE_META
- if isinstance(lang, str))))))
-
-
_SOURCE_META = {
- ('', '.sh', '.pl', '.py', '.pyw', '.rb', '.cmake'):
+ ('', '.cmake', '.ex', '.exs', '.pl', '.py', '.pyw', '.rb', '.sh'):
[{
- ('', '.sh'): 'Bash',
+ ('.ex', '.exs'): 'Elixir',
+ ('', '.sh'): 'Shell script',
('.pl'): 'Perl',
('.py', '.pyw'): 'Python',
('.rb'): 'Ruby',
('.cmake'): 'CMake'
},
('#', '# ')],
+ ('.coffee', '.litcoffee'):
+ [{('.coffee', '.litcoffee'): 'CoffeeScript'}, ('###', ' ', ' ', '###')],
+ ('.asm', '.s'):
+ [{('.asm', '.s'): 'Assembly',}, (';', '; ')],
('.lisp', '.lsp', '.cl', '.scm', '.ss', '.clj', '.cljc', '.cljs'):
[{
('.lisp', '.lsp'): 'Lisp',
@@ -272,9 +293,17 @@ def extensions():
('.cljs'): 'ClojureScript',
},
(';;', ';; ')],
+ ('.erl', '.hrl'):
+ [{
+ ('.erl'): 'Erlang',
+ ('.hrl'): 'Erlang header'
+ },
+ ('%%', '%% ')],
+ ('.pas', '.pp', '.inc'):
+ [{('.pas', '.pp', '.inc'): 'Pascal'}, ('{', ' ', ' ', '}')],
('.c', '.cc', '.c++', '.cpp', '.cxx', '.cs', '.css', '.h', '.hh', '.h++',
- '.hpp', '.hxx', '.java', '.js', '.php', '.php4', '.php5', '.phtml', '.rs',
- '.ts'):
+ '.hpp', '.hxx', '.java', '.js', '.kt', '.kts', '.ktm', '.m', '.mm',
+ '.php', '.php4', '.php5', '.phtml', '.ts'):
[{
('.c'): 'C',
('.h'): 'C header',
@@ -283,20 +312,23 @@ def extensions():
('.cs'): 'C-sharp',
('.css'): 'CSS',
('.java'): 'Java',
+ ('.kt', '.kts', '.ktm'): 'Kotlin',
+ ('.m', '.mm'): 'Objective-C',
('.php', '.php4', '.php5', '.phtml'): 'PHP',
('.js'): 'JavaScript',
('.ts'): 'TypeScript'
},
('/**', ' * ', ' *', ' */')],
+ ('.elm'):
+ [{('.elm'): 'Elm'}, ('{-', ' ', ' ', '-}')],
('.ml', '.mli'):
- [{
- ('.ml', '.mli'): 'OCaml'
- },
- ('(*', ' ', ' ', '*)')],
+ [{('.ml', '.mli'): 'OCaml'}, ('(*', ' ', ' ', '*)')],
('.html', '.htm'):
[{('.html', '.htm'): 'HTML'}, ('')],
- ('.sql', '.hs', '.lhs'):
+ ('.adb', '.ads', '.lua', '.sql', '.hs', '.lhs'):
[{
+ ('.adb', '.ads'): 'Ada',
+ ('.lua'): 'Lua',
('.sql'): 'SQL',
('.hs', '.lhs'): 'Haskell',
},
@@ -309,11 +341,7 @@ def extensions():
('.scss'): 'SASS'
},
('//', '// ')],
- ('.vim', '.vimrc'):
- [{
- ('.vim', '.vimrc'): 'VimL'
- },
- ('""', '"" ')]
+ ('.vim'): [{('.vim'): 'VimL'}, ('""', '"" ')]
}
"""
Mapping of file extensions to comment markers for all programming languages
@@ -321,7 +349,7 @@ def extensions():
"""
_SCRIPT_HEADERS = {
- 'bash': '#!/usr/bin/env bash',
+ 'shell script': '#!/usr/bin/env bash',
'perl': '#!/usr/bin/env perl',
'php': '(cpywrite)"
+
+Then(Erlang file header quotes the ECL-1.0);
+ AssertEqual '%% standard.erl', getline(2)
+ AssertEqual 2, len(getline(3)), 'Allow no trailing spaces'
+ AssertEqual '%% Licensed under the Educational Community License version 1.0', getline(6)
+ AssertEqual 2, len(getline(7)), 'Allow no trailing spaces'
+
+Execute(Use :CPYwriteToggleMode to switch on verbatim mode);
+ call vader#log('===== Calling :CPYwriteToggleMode =====')
+ CPYwriteToggleMode
+
+Then(Assert that verbatim mode is now on);
+ AssertEqual 1, g:cpywrite_verbatim_mode
+
+" Tc #12
+Execute(Prepend a license verbatim to an Elixir file);
+ new! verbatim.ex
+ b verbatim.ex
+ norm LH
+
+Then(Elixir file quotes the entire ECL-1.0);
+ AssertEqual '# verbatim.ex', getline(2)
+ AssertEqual 1, len(getline(3)), 'Allow no trailing spaces'
+ AssertEqual '# The Educational Community License', getline(4)
+ AssertEqual '# The full text of the Educational Community License in a location viewable',getline(28)
+ AssertEqual '# The name and trademarks of copyright holder(s) may NOT be used in advertising', getline(47)
+ AssertEqual 1, len(getline(51)), 'Allow no trailing spaces'
+
+Execute(Use :CPYwriteToggleMode to switch off verbatim mode);
+ call vader#log('===== Calling :CPYwriteToggleMode =====')
+ CPYwriteToggleMode
+
+Then(Assert that verbatim mode is now off);
+ AssertEqual 0, g:cpywrite_verbatim_mode
diff --git a/test/vader/test_new_langs.vader b/test/vader/test_new_langs.vader
new file mode 100644
index 0000000..15390cb
--- /dev/null
+++ b/test/vader/test_new_langs.vader
@@ -0,0 +1,78 @@
+After(Clear buffers);
+ %bd!
+
+Execute(Test that plugin was loaded);
+ call vader#log('===== Pre-test environment check =====')
+ Assert exists('g:loaded_cpywrite')
+
+Execute(Use :CPYwriteDefaultLicense to set default license);
+ call vader#log('===== Calling :CPYwriteDefaultLicense =====')
+ CPYwriteDefaultLicense GPL-3.0-only
+
+Then(Assert that :CPYwriteDefaultLicense changes default license);
+ AssertEqual 'GPL-3.0-only', g:cpywrite_default_license
+
+Execute(Prepend default license header to an Assembly file);
+ new! default.s
+ b default.s
+ norm LH
+
+Then(Assembly file quotes GPLv3);
+ AssertEqual '; default.s', getline(2)
+ AssertEqual 1, len(getline(3)), 'Allow no trailing spaces'
+ AssertEqual '; as published by the Free Software Foundation, version 3.', getline(8)
+ AssertEqual 1, len(getline(18)), 'Allow no trailing spaces'
+
+Execute(Use :CPYwriteToggleMode to switch on verbatim mode);
+ call vader#log('===== Callng :CPYwriteToggleMode =====')
+ CPYwriteToggleMode
+
+Then(Assert that verbatim mode is now on);
+ AssertEqual 1, g:cpywrite_verbatim_mode
+
+Execute(Prepend a license verbatim to an Ada file);
+ new! verbatim.adb
+ b verbatim.adb
+ CPYwrite MIT
+
+Then(Ada file header quotes the entire MIT license);
+ AssertEqual '-- verbatim.adb', getline(2)
+ AssertEqual 2, len(getline(3)), 'Allow no trailing spaces'
+ AssertEqual '-- MIT License', getline(4)
+ AssertEqual '-- Permission is hereby granted, free of charge, to any person obtaining a copy', getline(8)
+ AssertEqual '-- The above copyright notice and this permission notice (including the next', getline(15)
+ AssertEqual '-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR', getline(19)
+ AssertEqual 2, len(getline(25)), 'Allow no trailing spaces'
+
+Execute(Prepend a license verbatim to a Go file);
+ new! verbatim.go
+ b verbatim.go
+ CPYwrite BSD-1-Clause
+
+Then(Go file header quotes the entire BSD-1-Clause license);
+ AssertEqual '// verbatim.go', getline(2)
+ AssertEqual 2, len(getline(3)), 'Allow no trailing spaces'
+ AssertEqual '// 1. Redistributions of source code must retain the above copyright notice,', getline(9)
+ AssertEqual '// THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. "AS IS" AND ANY', getline(12)
+ AssertEqual '// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.', getline(21)
+ AssertEqual 2, len(getline(22)), 'Allow no trailing spaces'
+
+Execute(Prepend a license verbatim to a Pascal file);
+ new! verbatim.pas
+ b verbatim.pas
+ CPYwrite X11
+
+Then(Pascal file header quotes the entire X11 license);
+ AssertEqual ' verbatim.pas', getline(2)
+ AssertEqual ' X11 License Copyright (C) 1996 X Consortium', getline(6)
+ AssertEqual ' Permission is hereby granted, free of charge, to any person obtaining a copy', getline(8)
+ AssertEqual ' Except as contained in this notice, the name of the X Consortium shall not', getline(25)
+ AssertEqual ' X Window System is a trademark of X Consortium, Inc.', getline(29)
+ AssertEqual 1, len(getline(30)), 'Allow no trailing spaces'
+
+Execute(Use :CPYwriteToggleMode to switch off verbatim mode);
+ call vader#log('===== Calling :CPYwriteToggleMode =====')
+ CPYwriteToggleMode
+
+Then(Assert that :CPYwriteToggleMode changes verbatim mode setting);
+ AssertEqual 0, g:cpywrite_verbatim_mode
diff --git a/test/vader/test_scripting_langs.vader b/test/vader/test_scripting_langs.vader
index 82aa190..a6279ab 100644
--- a/test/vader/test_scripting_langs.vader
+++ b/test/vader/test_scripting_langs.vader
@@ -154,13 +154,13 @@ Then(Vim script quotes the GPL-3.0+);
AssertEqual '""', getline(19)
" Tc #12
-Execute(Prepend a header-less license to a Vim script);
- new! brief.vim
- b brief.vim
+Execute(Prepend a header-less license to a .vimrc file);
+ new! .vimrc
+ b .vimrc
CPYwrite Vim
-Then(Vim script has brief license mention);
- AssertEqual '"" brief.vim', getline(2)
+Then(.vimrc has brief license mention);
+ AssertEqual '"" .vimrc', getline(2)
AssertEqual 2, len(getline(3)), 'Allow no trailing spaces'
AssertEqual '"" Licensed under the terms of the Vim License', getline(6)
AssertEqual 2, len(getline(7)), 'Allow no trailing spaces'
diff --git a/test/vader/test_web_langs.vader b/test/vader/test_web_langs.vader
index b849fb8..5aec039 100644
--- a/test/vader/test_web_langs.vader
+++ b/test/vader/test_web_langs.vader
@@ -125,3 +125,42 @@ Then(SASS file header has brief license mention);
AssertEqual 2, len(getline(3)), 'Allow no trailing spaces'
AssertEqual '// Licensed under the terms of the Afmparse License', getline(6)
AssertEqual '//', getline(7)
+
+" Tc #9
+Execute(Prepend a standard license header to an Elm file);
+ new! standard.elm
+ b standard.elm
+ CPYwrite BitTorrent-1.1
+
+Then(Elm file header quotes the BitTorrent-1.1);
+ AssertEqual ' standard.elm', getline(2)
+ AssertEqual ' Version 1.1 (the License). You may not copy or use this file, in either', getline(7)
+ AssertEqual ' may obtain a copy of the License at http://www.bittorrent.com/license/.', getline(9)
+ AssertEqual 2, len(getline(14)), 'Allow no trailing spaces'
+
+Execute(Use :CPYwriteToggleMode to switch on verbatim mode);
+ call vader#log('===== Calling :CPYwriteToggleMode =====')
+ CPYwriteToggleMode
+
+Then(Assert that verbatim mode is now on);
+ AssertEqual 1, g:cpywrite_verbatim_mode
+
+" Tc #10
+Execute(Prepend a license verbatim to a CoffeeScript file);
+ new! verbatim.coffee
+ b verbatim.coffee
+ CPYwrite BSD-1-Clause
+
+Then(CoffeeScript file quotes the entire BSD 1-Clause);
+ AssertEqual '###', getline(1), 'Use proper multiline comment syntax'
+ AssertEqual ' verbatim.coffee', getline(2)
+ AssertEqual ' 1. Redistributions of source code must retain the above copyright notice,', getline(9)
+ AssertEqual ' THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. "AS IS" AND ANY', getline(12)
+ AssertEqual '###', getline(22), 'Use proper multiline comment syntax'
+
+Execute(Use :CPYwriteToggleMode to switch off verbatim mode);
+ call vader#log('===== Calling :CPYwriteToggleMode =====')
+ CPYwriteToggleMode
+
+Then(Assert that verbatim mode is now off);
+ AssertEqual 0, g:cpywrite_verbatim_mode