-
-
Notifications
You must be signed in to change notification settings - Fork 50
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
Conversation
…rite-ftplugin-structure
I checked out this branch and tried to make a command to create a custom doc standard.
where I get errors because fun! DogeExport(name)
let this_ft = &ft
" maybe there aren't available doc standards for this filetype
if !exists('b:doge_patterns')
let b:doge_patterns = {}
endif
" if the given name is an existing doc standard, use it as base for our
" template, otherwise create an empty one
if has_key(b:doge_patterns, a:name)
let template = deepcopy(b:doge_patterns[a:name][0])
let name = a:name . '_custom'
else
let template = {'match': '', 'tokens':'', 'template': [], 'insert': 'above', 'parameters': {'match': '', 'tokens':'', 'format': ''}}
let name = a:name
endif
" get the path for the after/ftplugin file and open it if existing
" otherwise create a new file with an appropriate path
let path = ''
for p in ['~/.vim', '~/vimfiles']
if isdirectory(expand(p))
let path = expand(p)
endif
endfor
if has('nvim') && empty(path)
let path = stdpath('config')
endif
if !empty(path)
let path .= '/after/ftplugin/' . this_ft . '.vim'
endif
if filereadable(path)
exe 'split' escape(path, ' ')
else
new
setfiletype vim
if !empty(path)
exe 'file' escape(path, ' ')
endif
endif
" generate the template and paste it at the top of the file
let doc = []
call add(doc, '" preserve existing doge settings')
call add(doc, 'let b:doge_patterns = get(b:, "doge_patterns", {})')
call add(doc, 'let b:doge_supported_doc_standards = get(b:, "doge_supported_doc_standards", [])')
call add(doc, 'if index(b:doge_supported_doc_standards, "'.name.'") < 0')
call add(doc, 'call add(b:doge_supported_doc_standards, "'.name.'")')
call add(doc, 'endif')
call add(doc, '')
call add(doc, '" set the new doc standard as default')
call add(doc, 'let b:doge_doc_standard = "'.name.'"')
call add(doc, '')
call add(doc, '" do not overwrite an existing doc standard')
call add(doc, 'if !has_key(b:doge_patterns, "'.name.'")')
call add(doc, 'let b:doge_patterns["'.name.'"] = [{')
call add(doc, '\ "match": '.string(template.match).',')
call add(doc, '\ "tokens": '.string(template.tokens).',')
if has_key(template, 'parameters')
call add(doc, '\ "parameters": {')
call add(doc, '\ "match": '.string(template.parameters.match).',')
call add(doc, '\ "tokens": '.string(template.parameters.tokens).',')
call add(doc, '\ "format": '.string(template.parameters.format).',')
call add(doc, '\ },')
endif
call add(doc, '\ "template": '.string(template.template).',')
call add(doc, '\ "insert": '.string(template.insert).',')
call add(doc, '\}]')
call add(doc, 'endif')
call add(doc, '')
call setreg('"', doc)
1
normal! P'[=']
endfun
command! -nargs=1 -complete=customlist,doge#command_complete DogeExport call DogeExport(<q-args>) |
Anyway there's a problem: every time the file is loaded with Just try to load a supported filetype and do
a couple of times and you'll see. |
We can do that and Also, what do you mean with I suggest you change if !exists('b:doge_patterns')
let b:doge_patterns = {}
endif to let b:doge_patterns = doge#buffer#get_patterns() since this will take tests into account and already adds proper fallbacks if it doesn't exists.
Fixed it, see 7db29f7 |
Yes, instead of throwing unhandled errors.
The code that command generates goes into the user's ftplugin, it doesn't need tests nor fallbacks. A custom doc standard will be created, that isn't handled by doge in any way, except that it's added to the supported doc standards and it can be used by It will neither overwrite a default doc standard, it will generate an entry like |
Clear. So your I will add a test later for Also, why name it |
Yes it's better, it was just a temporary name.
It's easier than looking for a source for the doc standard, but it will create an empty template unless you use an existing one as base (the command argument). It should be documented how to properly make a custom doc standard, what the dictionary entries do, etc. |
Agree, but documentation will come after it's done and works as expected. I also took note in the TODO list of this PR of the following: Validate pattern for required keys. I will do that right away now, since this is also something that should be done to prevent the user from creating invalid keys. |
You shouldn't be overzelous on that, the template generates all keys, if the user wants to make mistakes, let him learn from his mistakes. Instead the code should check for things that template doesn't generate, things like |
Getting a big error and figuring it out as a regular user takes more time instead of seeing 1 clear message with what to do and exit the generation early. UX-wise, it's better to catch the error. EDIT: Let's skip this part for now. |
@mg979 I renamed |
@mg979 Also, why should I take care for a fallback for |
Why would you want the user to keep that sort of stuff in their own ftplugin, only the strictly necessary stuff should go there, that variable is not. Anyway you just need to use |
They do not need to define it since it's already defined. If doge defines it already in |
Sorry for the typo, but the reason was that I was trying the command on vimL, that doesn't have that variable because it's not supported. That check is necessary for the languages that aren't supported (another good reason why it should be handled by doge, because it would be a repetition, and possibly conflicting, among ftplugins). Anyway, what can be handled by doge should be handled by doge.. users don't want obscure stuff in their ftplugins, me included. |
It would be a possible fallback, but I highly doubt whether to implement this. I don't see any reason to make this an optional variable. I want to require the variable, because if you take PHP, there are more versions of creating single line comments: There are a minimum amount of variables to create a proper doc standard and the ones I just described about the comment are one of the required ones. If Vim has more variables I am not aware of that would cover these variables, I'd more than happy to implement those to save code. |
As you wish. But I think you're hurting your own plugin, thinking like this. Those variables contain patterns that aren't so obvious and could be handled by doge, in a couple lines of code. And only for unsupported languages, because for languages that have already a doc standard in doge, this won't even matter. Edit: the command could be changed to add those variables only in the case that the filetype is unsupported, will do it maybe later. |
Fair enough. If it's for unsupported doc standards then it's up to the user in my opinion. And what about |
Understood. So you want custom patterns to be able to use preprocessors as well? And the command should assume that when a token is found that has not a key, it's handled by a preprocessor? It gets complicated if this basically requires browsing doge codebase to see what these prerocessors do. |
What do you exactly mean with |
For example I have this in " preserve existing doge settings
let b:doge_patterns = get(b:, "doge_patterns", {})
let b:doge_supported_doc_standards = get(b:, "doge_supported_doc_standards", [])
if index(b:doge_supported_doc_standards, "vimdoc1") < 0
call add(b:doge_supported_doc_standards, "vimdoc1")
endif
if index(b:doge_supported_doc_standards, "vimdoc2") < 0
call add(b:doge_supported_doc_standards, "vimdoc2")
endif
" doge uses these patterns to identify comments, change if needed
let b:doge_pattern_single_line_comment = '\V"\.\{\-\}\$'
let b:doge_pattern_multi_line_comment = '\V"\.\{\-\}\$'
" set the new doc standard as default
let b:doge_doc_standard = "vimdoc1"
let s:main_pattern = '\m^fu[ction]*!\?\s\+\([[:alnum:]_:.#]\+\)\s*(\(.\{-}\))'
let s:funcname_pattern = '\m^fu[ction]*!\?\s\+\([[:alnum:]_:.#]\+\)'
let s:parameters_pattern = '\m\([^,]\+\)'
fun! s:return_value()
return search('\C\<return\> \p\+', 'n', search('^endfu', 'n')) ?
\ '" Returns: !return' : '-'
endfun
" do not overwrite an existing doc standard
if !has_key(b:doge_patterns, "vimdoc1")
let b:doge_patterns["vimdoc1"] = [{
\ "match": s:main_pattern,
\ "tokens": ['funcname', 'parameters'],
\ 'funcname': {
\ 'match': s:funcname_pattern,
\ 'tokens': ['name'],
\ "format": '{name} !description',
\ },
\ "parameters": {
\ 'match': s:parameters_pattern,
\ 'tokens': ['name'],
\ "format": "@param {name}: !description",
\ },
\ 'template': [
\ '""'.repeat('=', 77),
\ '%(funcname|" Function: {funcname})%',
\ '" !summary',
\ "%(parameters|\" {parameters})%",
\ function('s:return_value'),
\ '""'.repeat('=', 77),
\ '""'],
\ "insert": 'above',
\}]
let b:doge_patterns["vimdoc2"] = [{
\ "match": s:main_pattern,
\ "tokens": ['funcname', 'parameters'],
\ 'funcname': {
\ 'match': s:funcname_pattern,
\ 'tokens': ['name'],
\ "format": '{name} !description',
\ },
\ "parameters": {
\ 'match': s:parameters_pattern,
\ 'tokens': ['name'],
\ "format": "@param {name}: !description",
\ },
\ 'template': [
\ '"',
\ '" !summary {{{1',
\ '" !description',
\ "%(parameters|\" {parameters})%",
\ function('s:return_value')],
\ "insert": 'below',
\}]
endif You see, in the Funcrefs woul need to be supported in doge#pattern#generate, though: - for l:line in a:pattern['template']
+ for l:Line in a:pattern['template']
+ " check the type of the current line, it could be a funcref
+ let l:line = type(l:Line) == 2 ? l:Line() : l:Line I don't know if your preprocessors serve the main purpose, but for custom doc standards, a funcref is much better, you keep it in your file and you know what it is doing. |
It looks way too complicated. I rather add a preprocess function with a few lines instead of creating all kinds of functions in my file. Every variable in the ftplugin that is added by a preprocess function is commented, so there's no problem here. How's your CreateDogeDocStandard going? Are you done already? Aiming for this PR to be merged soon. Also the regex |
Updated the command.
Funcrefs aren't for your files, but for custom doc standards: there the problem is reversed, for someone who knows nothing about doge preprocessors, and just wants a custom standard in his own ftplugin file. Edit: command fixed again |
I know but this recognizes |
Use I'll think about your suggestion. |
Updated the command. |
Can you fork the repo, create a sub-branch from Also, why is this " ...
if has_key(template, 'parameters')
call add(doc, '\ "parameters": {')
call add(doc, '\ "match": '.string(template.parameters.match).',')
call add(doc, '\ "tokens": '.string(template.parameters.tokens).',')
call add(doc, '\ "format": '.string(template.parameters.format).',')
call add(doc, '\ },')
endif
call add(doc, '\ "template": '.string(template.template).',')
call add(doc, '\ "insert": '.string(template.insert).',')
call add(doc, '\}]')
call add(doc, 'endif')
call add(doc, '')
call setreg('"', doc)
1 " <-- this .. should be here?
normal! P'[=']
endfun
command! -nargs=1 -complete=customlist,doge#command_complete DogeExport call DogeExport(<q-args>) |
|
Yes. Maybe in |
For custom template generation.
I made a PR for this command, I tested it in vimL and php and it seems to work ok.
Thinking about it again, to preserve the ability to try patterns in a defined order, one could make them like: let b:doge_pattern[doc_standard] = {
\ 'types': ['function'],
\ 'patterns': {
\ 'function': { ... }
\ }
\} and then process them in the order defined by b:doge_patterns[doc_standard].types. |
I wouldn't do that and I don't think this is a need. The array already defines the order. If you want to change them, re-order the array. |
- use new tab - check for existing but unsaved buffer - explicit register
… standard to be properly formatted
Add DogeCreateDocStandard (command)
This pull request implements the functionality of #52 where as the files in the ftplugin folder will be rewritten to a different structure that will also allow custom doc standards to be added and thus resolve issue #60.
TODO
doc/doge.txt
doc/tags