|
| 1 | +function! gnugo#InitRunner() |
| 2 | + return { |
| 3 | + \ 'output': [], |
| 4 | + \ 'job': v:null, |
| 5 | + \ 'channel': v:null, |
| 6 | + \ |
| 7 | + \ 'Start': function('gnugo#Start'), |
| 8 | + \ 'Execute': function('gnugo#Execute'), |
| 9 | + \ |
| 10 | + \ 'Expect': function('gnugo#Expect'), |
| 11 | + \ 'HandleOutput': function('gnugo#HandleOutput'), |
| 12 | + \ 'HandleError': function('gnugo#HandleError'), |
| 13 | + \ } |
| 14 | +endfunction |
| 15 | + |
| 16 | +function! gnugo#Start() dict |
| 17 | + let self.job = job_start('gnugo --mode gtp', { |
| 18 | + \ 'out_cb': function(self.HandleOutput), |
| 19 | + \ 'err_cb': function(self.HandleError), |
| 20 | + \ }) |
| 21 | + let self.channel = job_info(self.job).channel |
| 22 | +endfunction |
| 23 | + |
| 24 | +function! gnugo#Execute(move) dict |
| 25 | + call ch_sendraw(self.channel, a:move."\n") |
| 26 | + let result = self.Expect('^=', 1) |
| 27 | + let move_location = substitute(result[-1], '^= \(.*\)', '\1', '') |
| 28 | + |
| 29 | + call ch_sendraw(self.channel, "showboard\n") |
| 30 | + let board = self.Expect('A B C', 2) |
| 31 | + |
| 32 | + let output = [] |
| 33 | + call extend(output, [ |
| 34 | + \ '= Last command: '.a:move, |
| 35 | + \ '= Location: '.move_location, |
| 36 | + \ ]) |
| 37 | + call extend(output, board) |
| 38 | + |
| 39 | + normal! ggdG |
| 40 | + call setline(1, output) |
| 41 | + normal! gg |
| 42 | + set nomodified |
| 43 | +endfunction |
| 44 | + |
| 45 | +function! gnugo#HandleOutput(unused, line) dict |
| 46 | + call add(self.output, a:line) |
| 47 | +endfunction |
| 48 | + |
| 49 | +function! gnugo#HandleError(unused, line) dict |
| 50 | + echoerr "Error: ".a:line |
| 51 | +endfunction |
| 52 | + |
| 53 | +function! gnugo#Expect(pattern, count) dict |
| 54 | + let pattern = a:pattern |
| 55 | + " which encounter of the pattern to match: |
| 56 | + let encounter_count = copy(a:count) |
| 57 | + |
| 58 | + let current_offset = 0 |
| 59 | + let found_offset = -1 |
| 60 | + let result = [] |
| 61 | + |
| 62 | + while encounter_count > 0 |
| 63 | + " being updated asynchronously: |
| 64 | + let content_lines = self.output[current_offset:] |
| 65 | + |
| 66 | + let index = 0 |
| 67 | + for line in content_lines |
| 68 | + if line =~ pattern |
| 69 | + " we have a match, take everything up to the line, leave everything |
| 70 | + " afterwards |
| 71 | + let found_offset = current_offset + index |
| 72 | + let encounter_count -= 1 |
| 73 | + break |
| 74 | + endif |
| 75 | + |
| 76 | + let index += 1 |
| 77 | + endfor |
| 78 | + |
| 79 | + " for the next scan, just look at everything after the offset |
| 80 | + let current_offset = found_offset + 1 |
| 81 | + sleep 10m |
| 82 | + endwhile |
| 83 | + |
| 84 | + let result = self.output[0:found_offset] |
| 85 | + " clear what we've found |
| 86 | + let self.output = self.output[(found_offset + 1):] |
| 87 | + |
| 88 | + return result |
| 89 | +endfunction |
0 commit comments