From 01faf6ea1ea760b75da25736c87572a4ed4ab50c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 7 Mar 2013 16:58:09 -0800 Subject: [PATCH] Create helper to buffer process lines --- .../symbols-view/lib/tag-generator.coffee | 16 +++---- src/stdlib/buffered-process.coffee | 46 +++++++++++++++++++ 2 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 src/stdlib/buffered-process.coffee diff --git a/src/packages/symbols-view/lib/tag-generator.coffee b/src/packages/symbols-view/lib/tag-generator.coffee index a5543bc3b..8367e74d6 100644 --- a/src/packages/symbols-view/lib/tag-generator.coffee +++ b/src/packages/symbols-view/lib/tag-generator.coffee @@ -1,6 +1,7 @@ Point = require 'point' ChildProcess = nodeRequire 'child_process' $ = require 'jquery' +BufferedProcess = require 'buffered-process' module.exports = class TagGenerator @@ -15,18 +16,15 @@ class TagGenerator null generate: -> + deferred = $.Deferred() + tags = [] command = "#{require.resolve('ctags')}" args = ['--fields=+KS', '-nf', '-', @path] - ctags = ChildProcess.spawn(command, args) - deferred = $.Deferred() - output = '' - ctags.stdout.setEncoding('utf8') - ctags.stdout.on 'data', (data) -> - output += data - ctags.stdout.on 'close', => - tags = [] - for line in output.split('\n') + stdout = (lines) => + for line in lines.split('\n') tag = @parseTagLine(line) tags.push(tag) if tag + exit = -> deferred.resolve(tags) + new BufferedProcess({command, args, stdout, exit}) deferred diff --git a/src/stdlib/buffered-process.coffee b/src/stdlib/buffered-process.coffee new file mode 100644 index 000000000..2c325192c --- /dev/null +++ b/src/stdlib/buffered-process.coffee @@ -0,0 +1,46 @@ +ChildProcess = nodeRequire 'child_process' + +module.exports = +class BufferedProcess + constructor: (options={}) -> + process = ChildProcess.spawn(options.command, options.args) + + stdoutClosed = true + stderrClosed = true + processExited = true + triggerExitCallback = -> + if stdoutClosed and stderrClosed and processExited + options.exit?() + + if options.stdout + stdoutClosed = false + @bufferStream process.stdout, options.stdout, -> + stdoutClosed = true + triggerExitCallback() + + if options.stderr + stderrClosed = false + @bufferStream process.stderr, options.stderr, -> + stderrClosed = true + triggerExitCallback() + + if options.exit + processExited = false + process.on 'exit', -> + processExited = true + triggerExitCallback() + + bufferStream: (stream, onLines, onDone) -> + stream.setEncoding('utf8') + buffered = '' + + stream.on 'data', (data) -> + buffered += data + lastNewlineIndex = buffered.lastIndexOf('\n') + if lastNewlineIndex isnt -1 + onLines(buffered.substring(0, lastNewlineIndex + 1)) + buffered = buffered.substring(lastNewlineIndex + 1) + + stream.on 'close', => + onLines(buffered) if buffered.length > 0 + onDone()