Skip to content

Commit

Permalink
ENH: Provide Hook for EditorConfig
Browse files Browse the repository at this point in the history
Close #8
  • Loading branch information
LucHermitte committed Aug 2, 2017
1 parent 06a9468 commit f985190
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 2 deletions.
107 changes: 107 additions & 0 deletions autoload/lh/project/editorconfig.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"=============================================================================
" File: autoload/lh/project/editorconfig.vim {{{1
" Author: Luc Hermitte <EMAIL:luc {dot} hermitte {at} gmail {dot} com>
" <URL:http://github.com/LucHermitte/lh-vim-lib>
" Version: 4.0.0.
let s:k_version = '400'
" Created: 02nd Aug 2017
" Last Update: 02nd Aug 2017
"------------------------------------------------------------------------
" Description:
" Hook for editorconfig-vim
" https://github.com/editorconfig/editorconfig-vim
"
" As editorconfig recognizes "foo: bar" as set the "foo" option to "bar" value,
" we cannot support "p:foo.bar = value". It has to be something else.
" Moreover, I'd like to keep supporting LetTo, LetIfUndef, --overwrite and
" --hide
"
" So here is the new syntax:
" p!foo.bar = value -> let_to
" p!overwrite!foo.bar = value -> let_to --overwrite
" p!hide!foo.bar = value -> let_to --hide
" p?foo.bar = value -> let_if_undef
" p#name = name -> Project --define {name}
"
" Note: the capitalization of project $ENV variable is changed by
" editorconfig-vim. I cannot do anything about it...
"------------------------------------------------------------------------
" History: «history»
" TODO: «missing features»
" }}}1
"=============================================================================

let s:cpo_save=&cpo
set cpo&vim
"------------------------------------------------------------------------
" ## Misc Functions {{{1
" # Version {{{2
function! lh#project#editorconfig#version()
return s:k_version
endfunction

" # Debug {{{2
let s:verbose = get(s:, 'verbose', 0)
function! lh#project#editorconfig#verbose(...)
if a:0 > 0 | let s:verbose = a:1 | endif
return s:verbose
endfunction

function! s:Log(expr, ...)
call call('lh#log#this',[a:expr]+a:000)
endfunction

function! s:Verbose(expr, ...)
if s:verbose
call call('s:Log',[a:expr]+a:000)
endif
endfunction

function! lh#project#editorconfig#debug(expr) abort
return eval(a:expr)
endfunction


"------------------------------------------------------------------------
" ## functions {{{1

" Function: lh#project#editorconfig#hook(config) {{{3
function! lh#project#editorconfig#hook(config) abort
call s:Verbose("editor config hook -> %1", a:config)
let qf = lh#exception#callstack_as_qf('')
call setqflist(qf)
" First of all, if there is a "p#name", it should be applied first
if has_key(a:config, 'p#name')
" Trim quotes from project name without evaluating its value with |eval()|.
let name = substitute(a:config['p#name'], '\v([''"])(.*)\1', '\2', '')
let name = escape(name, ' ')
exe 'Project --define ' . name
endif

for [k,value] in items(a:config)
if k =~ '\v^p[!?]'
let [all, scope, how, varname; dummy] = matchlist(k, '\v^(\&?p)(!.*!|[!?])(.*)')
if how == '!'
call lh#let#to(scope.':'.varname.'='.value)
elseif how == '?'
call lh#let#if_undef('p:'.varname.'='.value)
elseif how =~ '\v(hide|overwrite)'
call lh#let#to('--'.how[1:-2].' '.scope.':'.varname.'='.value)
else
call lh#common#warning_msg('Warning: '.string(how).' is an invalid way to set a project option. Use "!", "?", "!hide!", or "!overwrite!" in '.string(k.'='.value))
endif
else
call s:Verbose('Ignore %1=%2', k, value)
endif
endfor
endfunction

"------------------------------------------------------------------------
" ## Internal functions {{{1

"------------------------------------------------------------------------
" }}}1
"------------------------------------------------------------------------
let &cpo=s:cpo_save
"=============================================================================
" vim600: set fdm=marker:
50 changes: 50 additions & 0 deletions doc/Project.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* [3.1.1 and you want to define a new project](#311-and-you-want-to-define-a-new-project)
* [3.1.1.1 Automagically](#3111-automagically)
* [3.1.1.2. From your `.lvimrc` or `_vimrc_local.vim`](#3112-from-your-lvimrc-or-_vimrc_localvim)
* [3.1.1.3. From your `.editorconfig` file.](#3113-from-your-editorconfig-file)
* [3.1.2. Auto-detect the project root path](#312-auto-detect-the-project-root-path)
* [3.1.3. Default value for project options](#313-default-value-for-project-options)
* [3.1.4. Set a project option](#314-set-a-project-option)
Expand Down Expand Up @@ -207,6 +208,55 @@ plugin used.

Note that this also could be done by hand -- see power-user approaches below.

#### 3.1.1.3. From your `.editorconfig` file.
[EditorConfig project](http://editorconfig.org/) aims a rationalizing and
factorizing project configuration among multiple IDEs.

While all the _project_ settings provided by this lh-vim-lib feature cannot be
used from other IDEs, you may still be interested at maintaining only one
file, instead of one file for a local vimrc plugin, and one file for
EditorConfig.

In that `.editorconfig` file, you'll have options shared among several IDEs,
and _project_ options.

In order to use EditorConfig, I expect you have properly installed
[EditorConfig-vim](https://github.com/editorconfig/editorconfig-vim), and
registered it **before** lh-vim-lib in your plugin manager.

Then, you'll be able to maintain a `.editorconfig` file at the root of a
project. From there, you'll be able to define a _lh-vim-lib project_, and to
set options through `LetTo` and `LetIfUndef`, but with another (!) dedicated
syntax.

```dosini
[*]
# Define a new project, as with "Project --define Name"
p#name = My Project Name

# Set p:foo.bar to 42, as with ":LetTo"
p!foo.bar = 42

# Idem, as with "LetTo --overwrite" for nested projects, see below
p!overwrite!foo.bar2 = 12

# Idem, as with "LetTo --hide" for nested projects, see below
p!hide!foo.bar3 = 12

# Set p:foo.str to 'some string', if it wasn't defined, as with ":LetIfUndef"
p?foo.str = 'some string'
```

See also:
- [3.1.1.1 (You're an end-user and you want to define a new project) Automagically](#3111-automagically)
- [3.1.3. (You're an end-user and you want to) Set a default value for project options](#313-default-value-for-project-options)
- [3.1.4. (You're an end-user and you want to) Set a project option](#314-set-a-project-option)
- [3.2.8. (Set a variable in a precise project) through `:LetTo`](#328-set-a-variable-in-a-precise-project)

**Warning**: Because of editorconfig(-vim?) way of doing things, environment
variables will be changed to lowercase. This means, that `p!$FOO = 42` won't
assign 42 to `p:$FOO` but to `p:$foo`.

### 3.1.2. Auto-detect the project root path
On a project definition, we can automatically deduce the current project root
directory. This directory will then be used by other plugins like
Expand Down
7 changes: 6 additions & 1 deletion doc/lh-vim-lib.txt
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ Variable helper functions |lhvl#variable| {{{2
- |lh#let#if_undef()|
- |lh#let#to()|
- |lh#let#undef()|
Project related defintions |lhvl#project| {{{2
Project related definitions |lhvl#project| {{{2
- |p:| |project-variable|
- |:Project|
- |lh#project#define()|
Expand Down Expand Up @@ -3957,6 +3957,11 @@ Being able to toggle an option between several values, when this is a buffer
local option, quickly becomes a nightmare. This is because we don't have
`p:roject_options`.

Note, that's it's also possible to specify project settings with
[|editorconfig|](https://github.com/editorconfig/editorconfig-vim). The syntax
will be slightly different from the usual. See the related section in
doc/Project.md.

So? Let's have them then!

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand Down
7 changes: 6 additions & 1 deletion plugin/lh-project.vim
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
" Version: 4.0.0.0.
let s:k_version = '4000'
" Created: 29th Sep 2016
" Last Update: 09th Mar 2017
" Last Update: 02nd Aug 2017
"------------------------------------------------------------------------
" Description:
" :Project related commands
Expand Down Expand Up @@ -69,6 +69,11 @@ augroup LH_PROJECT
au BufWinEnter,VimEnter * call lh#project#_CheckUpdateCWD()
augroup END

" ## Register to editorconfig if found {{{1
if !empty(globpath(&rtp, 'autoload/editorconfig.vim'))
call editorconfig#AddNewHook(function('lh#project#editorconfig#hook'))
endif

" }}}1
"------------------------------------------------------------------------
let &cpo=s:cpo_save
Expand Down
8 changes: 8 additions & 0 deletions tests/lh/editorconfig/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[*]
p#name = test editorconfig
p!foo.bar = 44
p?foo.str = 'titi'
max_line_length = 70
p!&isk+=µ
&p!isk+=µ
p!$FOOBAR = 42

0 comments on commit f985190

Please sign in to comment.