aboutsummaryrefslogtreecommitdiffstats
path: root/autoload/xolox/misc/option.vim
blob: fce155cf911837bf2905ac4f2c8ce34c67321143 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
" Vim and plug-in option handling.
"
" Author: Peter Odding <peter@peterodding.com>
" Last Change: May 19, 2013
" URL: http://peterodding.com/code/vim/misc/

function! xolox#misc#option#get(name, ...) " {{{1
  " Expects one or two arguments: 1. The name of a variable and 2. the default
  " value if the variable does not exist.
  "
  " Returns the value of the variable from a buffer local variable, global
  " variable or the default value, depending on which is defined.
  "
  " This is used by some of my Vim plug-ins for option handling, so that users
  " can customize options for specific buffers.
  if exists('b:' . a:name)
    " Buffer local variable.
    return eval('b:' . a:name)
  elseif exists('g:' . a:name)
    " Global variable.
    return eval('g:' . a:name)
  elseif exists('a:1')
    " Default value.
    return a:1
  endif
endfunction

function! xolox#misc#option#split(value) " {{{1
  " Given a multi-value Vim option like ['runtimepath'] [rtp] this returns a
  " list of strings. For example:
  "
  "     :echo xolox#misc#option#split(&runtimepath)
  "     ['/home/peter/Projects/Vim/misc',
  "      '/home/peter/Projects/Vim/colorscheme-switcher',
  "      '/home/peter/Projects/Vim/easytags',
  "      ...]
  "
  " [rtp]: http://vimdoc.sourceforge.net/htmldoc/options.html#'runtimepath'
  let values = split(a:value, '[^\\]\zs,')
  return map(values, 's:unescape(v:val)')
endfunction

function! s:unescape(s)
  return substitute(a:s, '\\\([\\,]\)', '\1', 'g')
endfunction

function! xolox#misc#option#join(values) " {{{1
  " Given a list of strings like the ones returned by
  " `xolox#misc#option#split()`, this joins the strings together into a
  " single value that can be used to set a Vim option.
  let values = copy(a:values)
  call map(values, 's:escape(v:val)')
  return join(values, ',')
endfunction

function! s:escape(s)
  return escape(a:s, ',\')
endfunction

function! xolox#misc#option#split_tags(value) " {{{1
  " Customized version of `xolox#misc#option#split()` with specialized
  " handling for Vim's ['tags' option] [tags].
  "
  " [tags]: http://vimdoc.sourceforge.net/htmldoc/options.html#'tags'
  let values = split(a:value, '[^\\]\zs,')
  return map(values, 's:unescape_tags(v:val)')
endfunction

function! s:unescape_tags(s)
  return substitute(a:s, '\\\([\\, ]\)', '\1', 'g')
endfunction

function! xolox#misc#option#join_tags(values) " {{{1
  " Customized version of `xolox#misc#option#join()` with specialized
  " handling for Vim's ['tags' option] [tags].
  let values = copy(a:values)
  call map(values, 's:escape_tags(v:val)')
  return join(values, ',')
endfunction

function! s:escape_tags(s)
  return escape(a:s, ', ')
endfunction

function! xolox#misc#option#eval_tags(value, ...) " {{{1
  " Evaluate Vim's ['tags' option] [tags] without looking at the file
  " system, i.e. this will report tags files that don't exist yet. Expects
  " the value of the ['tags' option] [tags] as the first argument. If the
  " optional second argument is 1 (true) only the first match is returned,
  " otherwise (so by default) a list with all matches is returned.
  let pathnames = []
  let first_only = exists('a:1') ? a:1 : 0
  for pattern in xolox#misc#option#split_tags(a:value)
    " Make buffer relative pathnames absolute.
    if pattern =~ '^\./'
      let directory = xolox#misc#escape#substitute(expand('%:p:h'))
      let pattern = substitute(pattern, '^.\ze/', directory, '')
    endif
    " Make working directory relative pathnames absolute.
    if xolox#misc#path#is_relative(pattern)
      let pattern = xolox#misc#path#merge(getcwd(), pattern)
    endif
    " Ignore the trailing `;' for recursive upwards searching because we
    " always want the most specific pathname available.
    let pattern = substitute(pattern, ';$', '', '')
    " Expand the pattern.
    call extend(pathnames, split(expand(pattern), "\n"))
    if first_only && !empty(pathnames)
      return pathnames[0]
    endif
  endfor
  return first_only ? '' : pathnames
endfunction

" vim: ts=2 sw=2 et