1" netrw_gitignore#Hide: gitignore-based hiding
2"  Function returns a string of comma separated patterns convenient for
3"  assignment to `g:netrw_list_hide` option.
4"  Function can take additional filenames as arguments, example:
5"  netrw_gitignore#Hide('custom_gitignore1', 'custom_gitignore2')
6"
7" Usage examples:
8"  let g:netrw_list_hide = netrw_gitignore#Hide()
9"  let g:netrw_list_hide = netrw_gitignore#Hide() . 'more,hide,patterns'
10"
11" Copyright:    Copyright (C) 2013 Bruno Sutic {{{1
12"               Permission is hereby granted to use and distribute this code,
13"               with or without modifications, provided that this copyright
14"               notice is copied with it. Like anything else that's free,
15"               netrw_gitignore.vim is provided *as is* and comes with no
16"               warranty of any kind, either expressed or implied. By using
17"               this plugin, you agree that in no event will the copyright
18"               holder be liable for any damages resulting from the use
19"               of this software.
20function! netrw_gitignore#Hide(...)
21  let additional_files = a:000
22
23  let default_files = ['.gitignore', '.git/info/exclude']
24
25  " get existing global/system gitignore files
26  let global_gitignore = expand(substitute(system("git config --global core.excludesfile"), '\n', '', 'g'))
27  if global_gitignore !=# ''
28    let default_files = add(default_files, global_gitignore)
29  endif
30  let system_gitignore = expand(substitute(system("git config --system core.excludesfile"), '\n', '', 'g'))
31  if system_gitignore !=# ''
32    let default_files = add(default_files, system_gitignore)
33  endif
34
35  " append additional files if given as function arguments
36  if additional_files !=# []
37    let files = extend(default_files, additional_files)
38  else
39    let files = default_files
40  endif
41
42  " keep only existing/readable files
43  let gitignore_files = []
44  for file in files
45    if filereadable(file)
46      let gitignore_files = add(gitignore_files, file)
47    endif
48  endfor
49
50  " get contents of gitignore patterns from those files
51  let gitignore_lines = []
52  for file in gitignore_files
53    for line in readfile(file)
54      " filter empty lines and comments
55      if line !~# '^#' && line !~# '^$'
56        let gitignore_lines = add(gitignore_lines, line)
57      endif
58    endfor
59  endfor
60
61  " convert gitignore patterns to Netrw/Vim regex patterns
62  let escaped_lines = []
63  for line in gitignore_lines
64    let escaped = line
65    let escaped = substitute(escaped, '\*\*', '*', 'g')
66    let escaped = substitute(escaped, '\.', '\\.', 'g')
67    let escaped = substitute(escaped, '\$', '\\$', 'g')
68    let escaped = substitute(escaped, '*', '.*', 'g')
69    " correction: dot, dollar and asterisks chars shouldn't be escaped when
70    " within regex matching groups.
71    let escaped = substitute(escaped, '\(\[[^]]*\)\zs\\\.', '\.', 'g')
72    let escaped = substitute(escaped, '\(\[[^]]*\)\zs\\\$', '\$', 'g')
73    let escaped = substitute(escaped, '\(\[[^]]*\)\zs\.\*', '*', 'g')
74    let escaped_lines = add(escaped_lines, escaped)
75  endfor
76
77  return join(escaped_lines, ',')
78endfunction
79