This file is indexed.

/usr/share/nvim/runtime/autoload/vimexpect.vim is in neovim-runtime 0.2.2-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
" vimexpect.vim is a small object-oriented library that simplifies the task of
" scripting communication with jobs or any interactive program. The name
" `expect` comes from the famous tcl extension that has the same purpose.
"
" This library is built upon two simple concepts: Parsers and States.
"
" A State represents a program state and associates a set of regular
" expressions(to parse program output) with method names(to deal with parsed
" output). States are created with the vimexpect#State(patterns) function.
"
" A Parser manages data received from the program. It also manages State
" objects by storing them into a stack, where the top of the stack is the
" current State. Parsers are created with the vimexpect#Parser(initial_state,
" target) function
"
" The State methods are defined by the user, and are always called with `self`
" set as the Parser target. Advanced control flow is achieved by changing the
" current state with the `push`/`pop`/`switch` parser methods.
"
" An example of this library in action can be found in Neovim source
" code(contrib/neovim_gdb subdirectory)

let s:State = {}


" Create a new State instance with a list where each item is a [regexp, name]
" pair. A method named `name` must be defined in the created instance.
function s:State.create(patterns)
  let this = copy(self)
  let this._patterns = a:patterns
  return this
endfunction


let s:Parser = {}
let s:Parser.LINE_BUFFER_MAX_LEN = 100


" Create a new Parser instance with the initial state and a target. The target
" is a dictionary that will be the `self` of every State method call associated
" with the parser, and may contain options normally passed to
" `jobstart`(on_stdout/on_stderr will be overriden). Returns the target so it
" can be called directly as the second argument of `jobstart`:
"
" call jobstart(prog_argv, vimexpect#Parser(initial_state, {'pty': 1}))
function s:Parser.create(initial_state, target)
  let parser = copy(self)
  let parser._line_buffer = []
  let parser._stack = [a:initial_state]
  let parser._target = a:target
  let parser._target.on_stdout = function('s:JobOutput')
  let parser._target.on_stderr = function('s:JobOutput')
  let parser._target._parser = parser
  return parser._target
endfunction


" Push a state to the state stack
function s:Parser.push(state)
  call add(self._stack, a:state)
endfunction


" Pop a state from the state stack. Fails if there's only one state remaining.
function s:Parser.pop()
  if len(self._stack) == 1
    throw 'vimexpect:emptystack:State stack cannot be empty'
  endif
  return remove(self._stack, -1)
endfunction


" Replace the state currently in the top of the stack.
function s:Parser.switch(state)
  let old_state = self._stack[-1]
  let self._stack[-1] = a:state
  return old_state
endfunction


" Append a list of lines to the parser line buffer and try to match it the
" current state. This will shift old lines if the buffer crosses its
" limit(defined by the LINE_BUFFER_MAX_LEN field). During normal operation,
" this function is called by the job handler provided by this module, but it
" may be called directly by the user for other purposes(testing for example)
function s:Parser.feed(lines)
  if empty(a:lines)
    return
  endif
  let lines = a:lines
  let linebuf = self._line_buffer
  if lines[0] != "\n" && !empty(linebuf)
    " continue the previous line
    let linebuf[-1] .= lines[0]
    call remove(lines, 0)
  endif
  " append the newly received lines to the line buffer
  let linebuf += lines
  " keep trying to match handlers while the line isnt empty
  while !empty(linebuf)
    let match_idx = self.parse(linebuf)
    if match_idx == -1
      break
    endif
    let linebuf = linebuf[match_idx + 1 : ]
  endwhile
  " shift excess lines from the buffer
  while len(linebuf) > self.LINE_BUFFER_MAX_LEN
    call remove(linebuf, 0)
  endwhile
  let self._line_buffer = linebuf
endfunction


" Try to match a list of lines with the current state and call the handler if
" the match succeeds. Return the index in `lines` of the first match.
function s:Parser.parse(lines)
  let lines = a:lines
  if empty(lines)
    return -1
  endif
  let state = self.state()
  " search for a match using the list of patterns
  for [pattern, handler] in state._patterns
    let matches = matchlist(lines, pattern)
    if empty(matches)
      continue
    endif
    let match_idx = match(lines, pattern)
    call call(state[handler], matches[1:], self._target)
    return match_idx
  endfor
endfunction


" Return the current state
function s:Parser.state()
  return self._stack[-1]
endfunction


" Job handler that simply forwards lines to the parser.
function! s:JobOutput(_id, lines, _event) dict
  call self._parser.feed(a:lines)
endfunction

function vimexpect#Parser(initial_state, target)
  return s:Parser.create(a:initial_state, a:target)
endfunction


function vimexpect#State(patterns)
  return s:State.create(a:patterns)
endfunction