<commit_before>{Point} = require('atom')
{Emitter, Subscriber} = require('emissary')
path = require('path')
fs = require('fs')

EditorLocationStack = require('./util/editor-location-stack')

module.exports =
class Godef
  Subscriber.includeInto(this)
  Emitter.includeInto(this)

  constructor: (@dispatch) ->
    @godefCommand = "golang:godef"
    @returnCommand = "golang:godef-return"
    @name = 'def'
    @didCompleteNotification = "#{@name}-complete"
    @godefLocationStack = new EditorLocationStack()
    atom.commands.add 'atom-workspace', "golang:godef": => @gotoDefinitionForWordAtCursor()
    atom.commands.add 'atom-workspace', "golang:godef-return": => @godefReturn()
    @cursorOnChangeSubscription = null

  destroy: ->
    @unsubscribe()
    @dispatch = null

  reset: (editor) ->
    @emit('reset', @editor)
    @cursorOnChangeSubscription?.dispose()

  clearReturnHistory: ->
    @godefLocationStack.reset()

  # new pattern as per http://blog.atom.io/2014/09/16/new-event-subscription-api.html
  # (but so far unable to get event-kit subscriptions to work, so keeping emissary)
  onDidComplete: (callback) ->
    @on(@didCompleteNotification, callback)

  godefReturn: ->
    @godefLocationStack.restorePreviousLocation().then =>
      @emitDidComplete()

  gotoDefinitionForWordAtCursor: ->
    @editor = atom?.workspace?.getActiveTextEditor()
    done = (err, messages) =>
      @dispatch?.resetAndDisplayMessages(@editor, messages)

    unless @dispatch?.isValidEditor(@editor)
      @emitDidComplete()
      return
    if @editor.hasMultipleCursors()
      @bailWithWarning('Godef only works with a single cursor', done)
      return

    editorCursorUTF8Offset = (e) ->
      characterOffset = e.getBuffer().characterIndexForPosition(e.getCursorBufferPosition())
      text = e.getText().substring(0, characterOffset)
      new Buffer(text, "utf8").length

    offset = editorCursorUTF8Offset(@editor)
    @reset(@editor)
    @gotoDefinitionWithParameters(['-o', offset, '-i'], @editor.getText(), done)

  gotoDefinitionForWord: (word, callback = -> undefined) ->
    @gotoDefinitionWithParameters([word], undefined, callback)

  gotoDefinitionWithParameters: (cmdArgs, cmdInput = undefined, callback = -> undefined) ->
    message = null
    done = (exitcode, stdout, stderr, messages) =>
      unless exitcode is 0
        # little point parsing the error further, given godef bugs eg
        # "godef: cannot parse expression: <arg>:1:1: expected operand, found 'return'"
        @bailWithWarning(stderr, callback)
        return
      @visitLocation(@parseGodefLocation(stdout), callback)

    go = @dispatch.goexecutable.current()
    cmd = go.godef()<commit_msg>Use Buffer.byteLength, don't allocate a new Buffer<commit_after>{Point} = require('atom')
{Emitter, Subscriber} = require('emissary')
path = require('path')
fs = require('fs')

EditorLocationStack = require('./util/editor-location-stack')

module.exports =
class Godef
  Subscriber.includeInto(this)
  Emitter.includeInto(this)

  constructor: (@dispatch) ->
    @godefCommand = "golang:godef"
    @returnCommand = "golang:godef-return"
    @name = 'def'
    @didCompleteNotification = "#{@name}-complete"
    @godefLocationStack = new EditorLocationStack()
    atom.commands.add 'atom-workspace', "golang:godef": => @gotoDefinitionForWordAtCursor()
    atom.commands.add 'atom-workspace', "golang:godef-return": => @godefReturn()
    @cursorOnChangeSubscription = null

  destroy: ->
    @unsubscribe()
    @dispatch = null

  reset: (editor) ->
    @emit('reset', @editor)
    @cursorOnChangeSubscription?.dispose()

  clearReturnHistory: ->
    @godefLocationStack.reset()

  # new pattern as per http://blog.atom.io/2014/09/16/new-event-subscription-api.html
  # (but so far unable to get event-kit subscriptions to work, so keeping emissary)
  onDidComplete: (callback) ->
    @on(@didCompleteNotification, callback)

  godefReturn: ->
    @godefLocationStack.restorePreviousLocation().then =>
      @emitDidComplete()

  gotoDefinitionForWordAtCursor: ->
    @editor = atom?.workspace?.getActiveTextEditor()
    done = (err, messages) =>
      @dispatch?.resetAndDisplayMessages(@editor, messages)

    unless @dispatch?.isValidEditor(@editor)
      @emitDidComplete()
      return
    if @editor.hasMultipleCursors()
      @bailWithWarning('Godef only works with a single cursor', done)
      return

    editorCursorUTF8Offset = (e) ->
      characterOffset = e.getBuffer().characterIndexForPosition(e.getCursorBufferPosition())
      text = e.getText().substring(0, characterOffset)
      Buffer.byteLength(text, "utf8")

    offset = editorCursorUTF8Offset(@editor)
    @reset(@editor)
    @gotoDefinitionWithParameters(['-o', offset, '-i'], @editor.getText(), done)

  gotoDefinitionForWord: (word, callback = -> undefined) ->
    @gotoDefinitionWithParameters([word], undefined, callback)

  gotoDefinitionWithParameters: (cmdArgs, cmdInput = undefined, callback = -> undefined) ->
    message = null
    done = (exitcode, stdout, stderr, messages) =>
      unless exitcode is 0
        # little point parsing the error further, given godef bugs eg
        # "godef: cannot parse expression: <arg>:1:1: expected operand, found 'return'"
        @bailWithWarning(stderr, callback)
        return
      @visitLocation(@parseGodefLocation(stdout), callback)

    go = @dispatch.goexecutable.current()
    cmd = go.godef()
{'fraction_non_alphanumeric': 0.13258344089987092, 'fraction_numerical': 0.0055319933616079665, 'mean_word_length': 4.102539981185324, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7509971', 'n_tokens_mistral': 1642, 'n_tokens_neox': 1562, 'n_words': 342}