Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite ftplugin structure #65

Merged
merged 29 commits into from
Dec 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c67974d
feat: Initial rewrite for all languages
kkoomen Nov 28, 2019
8960e0c
feat: Add new doge#buffer functions
kkoomen Nov 28, 2019
3312abd
feat: Use doge#buffer#register_doc_standard in all ftplugins
kkoomen Nov 29, 2019
7133b70
style: Rename match_group_names -> tokens
kkoomen Nov 29, 2019
27df1d3
feat: Validate patterns when generating
kkoomen Nov 29, 2019
9b97154
Merge branch 'master' of github.com:kkoomen/vim-doge into feature/rew…
kkoomen Nov 29, 2019
ff0ddae
docs: Update doc/doge.txt and doc/tags
kkoomen Nov 29, 2019
7db29f7
fix: Remove duplicates properly in doge#buffer#get_supported_doc_stan…
kkoomen Nov 30, 2019
03c5263
feat: Rename doge#generate#pattern() -> doge#pattern#generate()
kkoomen Nov 30, 2019
5bc5c25
Merge branch 'master' into feature/rewrite-ftplugin-structure
kkoomen Nov 30, 2019
23196a9
feat: Rebase changes from 25c64d1 v1.17.4
kkoomen Dec 1, 2019
e3251e1
fix: merge conflict feature/rewrite-ftplugin-structure <-- master
kkoomen Dec 1, 2019
880447e
feat: Rebase changes from c2f427a v1.17.5
kkoomen Dec 2, 2019
8120589
fix: merge conflict feature/rewrite-ftplugin-structure <-- master
kkoomen Dec 2, 2019
a638cd9
fix: Unlet parameters key instead of v:false
kkoomen Dec 6, 2019
efdeaeb
docs(CONTRIBUTING): Update old #() syntax with %()%
kkoomen Dec 6, 2019
b00ce96
Add DogeCreateDocStandard (command)
mg979 Dec 11, 2019
293ac4c
DogeCreateDocStandard fixes
mg979 Dec 12, 2019
4c39271
Use &showtabline
mg979 Dec 12, 2019
318367a
style: Fix linting issues; Adjust output structure of a generated doc…
kkoomen Dec 27, 2019
c9c5c45
doc: Update doc/doge.txt and doc/tags
kkoomen Dec 27, 2019
ed368a1
docs: Adjust comment in doge#pattern#custom()
kkoomen Dec 27, 2019
c1a526f
feat: Add silent! to every execute()
kkoomen Dec 27, 2019
74e0f5d
feat: Return when opening file to prevent duplicate content
kkoomen Dec 27, 2019
679f7dc
feat: Add polyfill for mkdir, see E739; Add tests
kkoomen Dec 27, 2019
98dd892
docs: Update CONTRIBUTING.md and README.md
kkoomen Dec 28, 2019
180309c
docs: Update CONTRIBUTING.md
kkoomen Dec 28, 2019
5f10f0e
Merge pull request #70 from mg979/rewrite-ftplugin-structure
kkoomen Dec 28, 2019
be18c69
Merge branch 'master' into feature/rewrite-ftplugin-structure
kkoomen Dec 28, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 82 additions & 86 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,80 +152,77 @@ noticed the buffer-local variable patterns. Below will be some explanation
about the dictionary structure per pattern.

The generation is done using the patterns as the following:
- Start by matching the given pattern.
- Extract all the tokens using the `match_group_names`.
- Extract the parameter tokens based on the `parameter` token.
- Start by matching the given pattern using the `match` key.
- Extract all the tokens using the `tokens` key.
- Extract the parameter tokens based on the `parameters` token.
- Render the tokens in the `template`.

```vim
" Example taken from ftplugin/php.vim

call add(b:doge_patterns, {
" The 'match' key is the main pattern to detect the actual expression.
" The example below will match: 'public static function myFunc($p1 = NULL) {'
" NOTE: The 'match' key should always start with \m to force magic notation
" and start with ^ to make sure it's not matching in middle.
\ 'match': '\m^\%(\%(public\|private\|protected\|static\|final\)\s\+\)*function\s*\([^(]\+\)\s*(\(.\{-}\))\s*{',

" The 'match_group_names' are names for the captured groups where the index
" is equivalent to the captured groups' index. These names become tokens
" that can be used in the 'template' key.
\ 'match_group_names': ['funcName', 'parameters'],

" The 'parameters' key is an optional key, since not every expression has a
" parameter list.
\ 'parameters': {
" The 'match' key is a pattern describing a single parameter. DoGe will
" strip matches until none are found. For example:
" PHP is using the parameter syntax pattern:
" '<param-type> $<param-name> = <param-default-value>'.
" So when this ^ is your pattern, you should write the regex for that.
" NOTE: The 'match' key should start with \m to force magic notation and
" should not contain ^ at the beginning or $ at the end.
\ 'match': '\m\%(\([[:alnum:]_\\]\+\)\s\+\)\?&\?\($[[:alnum:]_]\+\)\%(\s*=\s*\%([[:alnum:]_]\+(.\{-})\|[^,]\+\)\+\)\?',

" The 'match_group_names' are names for the captured groups where the index
" is equivalent to the captured groups' index. These names become tokens
" that can be used in the 'format' key.
\ 'match_group_names': ['type', 'name'],

" The 'format' key describes how the format of each parameter should be.
" It contains a format for each supported doc standard.
" Use a list for multi-line.
" Use a tab '\t' to indent properly based on the user setting.
\ 'format': {
\ 'phpdoc': '@param {type|!type} {name} !description',
\ },
\ },

" The 'comment' key determines how to generate the final comment.
\ 'comment': {

" The 'insert' key may contain the value 'above' or 'below'.
" Examples:
" - PHP comments will be inserted above the function expression.
" - Python comments will be inserted below the function expression.
\ 'insert': 'above',

" The 'template' key is a dictonary containing a list for each doc standard.
" Each key in the template list is a new line when rendering the comment.
\ 'template': {
\ 'phpdoc': [
\ '/**',
\ ' * !description',
\ '%(parameters| *)%',
\ '%(parameters| * {parameters})%',
\ ' */',
\ ],
\ },
\ },
\})
let b:doge_patterns = {
\ 'phpdoc': [
\ {
" The 'match' key is the main pattern to detect the actual expression.
" The example below will match: 'public static function myFunc($p1 = NULL) {'
" NOTE: The 'match' key should always start with \m to force magic notation
" and start with ^ to make sure it's not matching in middle.
\ 'match': '\m^\%(\%(public\|private\|protected\|static\|final\)\s\+\)*function\s*\([^(]\+\)\s*(\(.\{-}\))\s*{',

" The 'tokens' are names for the captured groups where the index
" is equivalent to the captured groups' index. These names become tokens
" that can be used in the 'template' key.
\ 'tokens': ['funcName', 'parameters'],

" The 'parameters' key is an optional key, since not every expression has a
" parameter list.
\ 'parameters': {
" The 'match' key is a pattern describing a single parameter. DoGe will
" strip matches until none are found. For example:
" PHP is using the parameter syntax pattern:
" '<param-type> $<param-name> = <param-default-value>'.
" So when this ^ is your pattern, you should write the regex for that.
" NOTE: The 'match' key should start with \m to force magic notation and
" should not contain ^ at the beginning or $ at the end.
\ 'match': '\m\%(\([[:alnum:]_\\]\+\)\s\+\)\?&\?\($[[:alnum:]_]\+\)\%(\s*=\s*\%([[:alnum:]_]\+(.\{-})\|[^,]\+\)\+\)\?',

" The 'tokens' are names for the captured groups where the index
" is equivalent to the captured groups' index. These names become tokens
" that can be used in the 'format' key.
\ 'tokens': ['type', 'name'],

" The 'format' key describes how the format of each parameter should be.
" It contains a format for each supported doc standard.
" Use a list for multi-line.
" Use a tab '\t' to indent properly based on the user setting.
\ 'format': '@param {type|!type} {name} !description',
\ },

" The 'insert' key may contain the value 'above' or 'below'.
" Examples:
" - PHP comments will be inserted above the function expression.
" - Python comments will be inserted below the function expression.
\ 'insert': 'above',

" The 'template' key is a new line when rendering the comment.
" All the tokens (except the `parameters` tokens) can be used here.
\ 'template': {
\ '/**',
\ ' * !description',
\ '%(parameters| *)%',
\ '%(parameters| * {parameters})%',
\ ' */',
\ },
\ }
\ ],
\}
```

### Additional token formatting

Additional formatting is available when using tokens in the `template` or
`parameters.format` keys.
`parameters.format` keys. The following subsections will elaborate more on the
types of token formatting that are available.

#### Creating TODO placeholders

Expand All @@ -236,11 +233,10 @@ automatically be searched for when jumping forward or backward.
Inside a DoGe pattern you can use the token format `!<context>` which will be
replaced with `[TODO:<context>]`. To give the user a clear understanding what to
add at this TODO it's recommended to add a context. You may use the following in
a context: `[a-zA-Z0-9\s]`, although it is recommended to keep it _very_ short.
a context: `[[:alpha:]-]`.

For example: some Python doc
standards require a summary at the start of the doc block followed by a
description (separated by a whiteline).
For example: some Python doc standards require a summary at the start of the doc
block followed by a description (separated by a whiteline).

If you see this:
```python
Expand Down Expand Up @@ -296,23 +292,23 @@ Example:
```vim
" Example taken from ftplugin/python.vim

call add(b:doge_patterns, {
\ " ...
\ 'comment': {
\ 'insert': 'below',
\ 'template': {
\ 'numpy': [
\ '"""',
\ '!description',
\ '%(parameters|)%', " Render an empty line if '{parameters}' is not empty
\ '%(parameters|Parameters)%', " Renders 'Parameters' if '{parameters}' is not empty
\ '%(parameters|----------)%', " Renders '----------' if '{parameters}' is not empty
\ '%(parameters|{parameters})%', " Renders '{parameters}' if '{parameters}' is not empty
\ '"""',
let b:doge_patterns = {
\ 'numpy': [
\ {
" ...
\ 'insert': 'below',
\ 'template': [
\ '"""',
\ '!description',
\ '%(parameters|)%', " Render an empty line if '{parameters}' is not empty
\ '%(parameters|Parameters)%', " Renders 'Parameters' if '{parameters}' is not empty
\ '%(parameters|----------)%', " Renders '----------' if '{parameters}' is not empty
\ '%(parameters|{parameters})%', " Renders '{parameters}' if '{parameters}' is not empty
\ '"""',
\ ],
\ }
\ },
\})
\ },
\ ],
\}
```

## Writing proper regex
Expand Down Expand Up @@ -371,12 +367,12 @@ all the necessary tokens. For example: For C and C++ there is the `libclang.py`
generator which is parsing the current file and will print a json format of the
necessary tokens.

Generators should output json format, since this can be decoded by Vim easily.
Generators should output json format, since this can be decoded by Vim.

It is also suggested to use Python because these scripts can be shipped easily
within the project. Think wisely if you want to suggest a _differrent_ language.

Generators can be used easily. The format is the same as the regex format, but
the `match` and `match_group_names` can be replaced with a `generator` key.
the `match` and `tokens` can be replaced with a `generator` key.

For an example usage, checkout the [C++](https://github.com/kkoomen/vim-doge/blob/master/ftplugin/cpp.vim) implementation.
26 changes: 22 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ on a function, press `<Leader>d`, jump quickly through `TODO` items using
+ [`g:doge_comment_jump_wrap`](#gdoge_comment_jump_wrap)
+ [`g:doge_comment_jump_modes`](#gdoge_comment_jump_modes)
- [Commands](#commands)
+ [`:DogeGenerate`](#dogegenerate)
+ [`:DogeGenerate {doc_standard}`](#dogegenerate-doc_standard)
+ [`:DogeCreateDocStandard {doc_standard}`](#dogecreatedocstandard-doc_standard)
- [FAQ](#faq)
+ [Using C / C++](#using-c--c)
- [Prerequisites](#prerequisites)
Expand Down Expand Up @@ -200,10 +201,27 @@ autocompletion in insert mode.

# Commands

### `:DogeGenerate [N] [doc_standard]`
### `:DogeGenerate {doc_standard}`

Command to generate documentation. It accepts a count or a string as argument,
and it can complete the available doc standards for the current buffer.
Command to generate documentation. The `{doc_standard}` accepts a count or a
string as argument, and it can complete the available doc standards for the
current buffer.

The numeric value should point to an index key from the
`b:doge_supported_doc_standards` variable.

The string value should point to a doc standard name listed in the
`b:doge_supported_doc_standards` variable.

### `:DogeCreateDocStandard {doc_standard}`

Command to generate a custom doc standard template. The `{doc_standard}` is a
mandatory argument which is the name of the new doc standard. If it exists, the
existing doc standard with the same name will be used as base for the custom
template. It can complete the available doc standards for the current buffer.

For more information on how to create custom doc standards you can read
[Writing your first pattern](./CONTRIBUTING.md#writing-your-first-pattern).

# FAQ

Expand Down
33 changes: 19 additions & 14 deletions autoload/doge.vim
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,23 @@ set cpoptions&vim
"
" arg: Either a count (0 by default) or a string (empty by default).
function! doge#generate(arg) abort
let l:success = 0
" Immediately validate if the doc standard is allowed.
if index(b:doge_supported_doc_standards, b:doge_doc_standard) < 0
echoerr printf(
\ '[DoGe] "%s" is not a valid %s doc standard, available doc standard are: %s',
\ b:doge_doc_standard,
\ &filetype,
\ join(b:doge_supported_doc_standards, ', ')
\)
endif

" Store old search register.
let s:oldsearch = @/

" If the command is run with a count or a string as argument, the user is
" requesting for a specific doc standard.
" If no matching standards are found, or no arg (count or string) is given,
" just use whatever is currently set
" just use whatever is currently set.
if exists('b:doge_supported_doc_standards')
if type(a:arg) ==# type(0) && a:arg != 0
if a:arg <= len(b:doge_supported_doc_standards)
Expand All @@ -29,16 +37,13 @@ function! doge#generate(arg) abort
endif

if exists('b:doge_patterns')
for l:pattern in get(b:, 'doge_patterns')
if doge#generate#pattern(l:pattern) == v:false
for l:pattern in get(b:doge_patterns, b:doge_doc_standard)
if doge#pattern#generate(l:pattern) == v:false
continue
else
let l:success = v:true
endif
if l:success == v:true
call doge#activate()
endif
return l:success

call doge#activate()
return 1
endfor
endif
endfunction
Expand All @@ -62,8 +67,8 @@ function! doge#activate() abort
\ g:doge_mapping_comment_jump_backward,
\ ]
for l:mode in g:doge_comment_jump_modes
execute(printf('%smap <nowait> <silent> <buffer> %s <Plug>(doge-comment-jump-forward)', l:mode, l:f))
execute(printf('%smap <nowait> <silent> <buffer> %s <Plug>(doge-comment-jump-backward)', l:mode, l:b))
call execute(printf('%smap <nowait> <silent> <buffer> %s <Plug>(doge-comment-jump-forward)', l:mode, l:f), 'silent!')
call execute(printf('%smap <nowait> <silent> <buffer> %s <Plug>(doge-comment-jump-backward)', l:mode, l:b), 'silent!')
endfor
endfunction

Expand Down Expand Up @@ -91,8 +96,8 @@ function! doge#deactivate() abort
\ g:doge_mapping_comment_jump_backward,
\ ]
for l:mode in g:doge_comment_jump_modes
execute(printf('%sunmap <buffer> %s', l:mode, l:f))
execute(printf('%sunmap <buffer> %s', l:mode, l:b))
call execute(printf('%sunmap <buffer> %s', l:mode, l:f), 'silent!')
call execute(printf('%sunmap <buffer> %s', l:mode, l:b), 'silent!')
endfor
endfunction

Expand Down
48 changes: 48 additions & 0 deletions autoload/doge/buffer.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
let s:save_cpo = &cpoptions
set cpoptions&vim

" The testing framework Vader is running everything inside a single buffer, so
" we disable the inheritance of some buffer-local variables to prevent extra
" work and/or failing tests.

""
" @public
" 'defaults': A list of supported doc standards that should be allowed.
" Returns a list of accepted doc standards.
function! doge#buffer#get_supported_doc_standards(defaults) abort
return get(g:, 'doge_test_env', 0)
\ ? a:defaults
\ : uniq(sort(extend(get(b:, 'doge_supported_doc_standards', []), a:defaults)))
endfunction

""
" @public
" 'filetype': The filetype where we initialized the b:doge_doc_standard.
" Returns the current active doc standard.
function! doge#buffer#get_doc_standard(filetype) abort
return get(g:, 'doge_test_env', 0)
\ ? b:doge_supported_doc_standards[0]
\ : get(b:, 'doge_doc_standard', get(g:, 'doge_doc_standard_' . a:filetype, b:doge_supported_doc_standards[0]))
endfunction

""
" @public
" Returns the b:doge_patterns variable value.
function! doge#buffer#get_patterns() abort
return get(g:, 'doge_test_env', 0)
\ ? {}
\ : get(b:, 'doge_patterns', {})
endfunction

""
" @public
" Add a doc standard to the b:doge_patterns variable.
function! doge#buffer#register_doc_standard(doc_standard, patterns) abort
if has_key(b:doge_patterns, a:doc_standard) == v:false
let b:doge_patterns[a:doc_standard] = a:patterns
endif
return b:doge_patterns
endfunction

let &cpoptions = s:save_cpo
unlet s:save_cpo
Loading