<commit_before>{Range, TextEditor, CompositeDisposable, Disposable, Emitter}  = require('atom')
_ = require('underscore-plus')
minimatch = require('minimatch')
path = require('path')
ProviderManager = require('./provider-manager')
SuggestionList = require('./suggestion-list')
SuggestionListElement = require('./suggestion-list-element')

module.exports =
class AutocompleteManager
  autosaveEnabled: false
  backspaceTriggersAutocomplete: true
  buffer: null
  editor: null
  editorSubscriptions: null
  editorView: null
  providerManager: null
  ready: false
  subscriptions: null
  suggestionDelay: 50
  suggestionList: null
  shouldDisplaySuggestions: false

  constructor: ->
    @subscriptions = new CompositeDisposable
    @providerManager = new ProviderManager
    @subscriptions.add(@providerManager)
    @emitter = new Emitter

    # Register Suggestion List Model and View
    @subscriptions.add(atom.views.addViewProvider(SuggestionList, (model) ->
      new SuggestionListElement().initialize(model)
    ))
    @suggestionList = new SuggestionList

    @handleEvents()
    @handleCommands()
    @ready = true

  updateCurrentEditor: (currentPaneItem) =>
    return unless currentPaneItem?
    return if currentPaneItem is @editor

    @editorSubscriptions?.dispose()
    @editorSubscriptions = null

    # Stop tracking editor + buffer
    @editor = null
    @editorView = null
    @buffer = null

    return unless @paneItemIsValid(currentPaneItem)

    # Track the new editor, editorView, and buffer
    @editor = currentPaneItem
    @editorView = atom.views.getView(@editor)
    @buffer = @editor.getBuffer()

    @editorSubscriptions = new CompositeDisposable

    # Subscribe to buffer events:
    @editorSubscriptions.add(@buffer.onDidSave(@bufferSaved))
    @editorSubscriptions.add(@buffer.onDidChange(@bufferChanged))

    # Subscribe to editor events:
    # Close the overlay when the cursor moved without changing any text
    @editorSubscriptions.add(@editor.onDidChangeCursorPosition(@cursorMoved))

  paneItemIsValid: (paneItem) ->
    return false unless paneItem?
    # Should we disqualify TextEditors with the Grammar text.plain.null-grammar?
    return paneItem instanceof TextEditor

  handleEvents: =>
    # Track the current pane item, update current editor
    @subscriptions.add(atom.workspace.observeActivePaneItem(@updateCurrentEditor))

    # Watch config values
    @subscriptions.add(atom.config.observe('autosave.enabled', (value) => @autosaveEnabled = value))
    @subscriptions.add(atom.config.observe('autocomplete-plus.backspaceTriggersAutocomplete', (value) => @backspaceTriggersAutocomplete = value))

    # Handle events from suggestion list
    @subscriptions.add(@suggestionList.onDidConfirm(@confirm))
    @subscriptions.add(@suggestionList.onDidCancel(@hideSuggestionList))

  handleCommands: =>
    # Allow autocomplete to be triggered via keymap
    @subscriptions.add atom.commands.add 'atom-text-editor',
      'autocomplete-plus:activate': =>
        @shouldDisplaySuggestions = true
        @findSuggestions()

  # Private: Finds suggestions for the current prefix, sets the list items,
  # positions the overlay and shows it
  findSuggestions: =>
    return unless @providerManager?
    return unless @editor?
    return unless @buffer?
    return if @isCurrentFileBlackListed()
    cursor = @editor.getLastCursor()
    return unless cursor?
    cursorPosition = cursor.getBufferPosition()
    currentScope = cursor.getScopeDescriptor()
    return unless currentScope?
    currentScopeChain = currentScope.getScopeChain()
    return unless currentScopeChain?

    options =
      editor: @editor
      buffer: @buffer
      cursor: cursor
      position: cursorPosition
      scope: currentScope
      scopeChain: currentScopeChain
      prefix: @prefixForCursor(cursor)

    @getSuggestionsFromProviders(options)

  getSuggestionsFromProviders: (options) =>
    providers = @providerManager.providersForScopeChain(options.scopeChain)
    return unless providers? and providers.length
    providers = providers.map (provider) ->
      providerSuggestions = provider?.requestHandler(options)
    return unless providers? and providers.length
    @currentSuggestionsPromise = suggestionsPromise = Promise.all(providers)
      .then(_.partial(@mergeSuggestionsFromProviders, providers))
      .then((suggestions) => @displaySuggestions(suggestions, suggestionsPromise, options))

  # providerSuggestions - array of arrays of suggestions provided by all called providers
  mergeSuggestionsFromProviders: (providerSuggestions) -><commit_msg>:art: Remove dead code from getSuggestionsFromProviders<commit_after>{Range, TextEditor, CompositeDisposable, Disposable, Emitter}  = require('atom')
_ = require('underscore-plus')
minimatch = require('minimatch')
path = require('path')
ProviderManager = require('./provider-manager')
SuggestionList = require('./suggestion-list')
SuggestionListElement = require('./suggestion-list-element')

module.exports =
class AutocompleteManager
  autosaveEnabled: false
  backspaceTriggersAutocomplete: true
  buffer: null
  editor: null
  editorSubscriptions: null
  editorView: null
  providerManager: null
  ready: false
  subscriptions: null
  suggestionDelay: 50
  suggestionList: null
  shouldDisplaySuggestions: false

  constructor: ->
    @subscriptions = new CompositeDisposable
    @providerManager = new ProviderManager
    @subscriptions.add(@providerManager)
    @emitter = new Emitter

    # Register Suggestion List Model and View
    @subscriptions.add(atom.views.addViewProvider(SuggestionList, (model) ->
      new SuggestionListElement().initialize(model)
    ))
    @suggestionList = new SuggestionList

    @handleEvents()
    @handleCommands()
    @ready = true

  updateCurrentEditor: (currentPaneItem) =>
    return unless currentPaneItem?
    return if currentPaneItem is @editor

    @editorSubscriptions?.dispose()
    @editorSubscriptions = null

    # Stop tracking editor + buffer
    @editor = null
    @editorView = null
    @buffer = null

    return unless @paneItemIsValid(currentPaneItem)

    # Track the new editor, editorView, and buffer
    @editor = currentPaneItem
    @editorView = atom.views.getView(@editor)
    @buffer = @editor.getBuffer()

    @editorSubscriptions = new CompositeDisposable

    # Subscribe to buffer events:
    @editorSubscriptions.add(@buffer.onDidSave(@bufferSaved))
    @editorSubscriptions.add(@buffer.onDidChange(@bufferChanged))

    # Subscribe to editor events:
    # Close the overlay when the cursor moved without changing any text
    @editorSubscriptions.add(@editor.onDidChangeCursorPosition(@cursorMoved))

  paneItemIsValid: (paneItem) ->
    return false unless paneItem?
    # Should we disqualify TextEditors with the Grammar text.plain.null-grammar?
    return paneItem instanceof TextEditor

  handleEvents: =>
    # Track the current pane item, update current editor
    @subscriptions.add(atom.workspace.observeActivePaneItem(@updateCurrentEditor))

    # Watch config values
    @subscriptions.add(atom.config.observe('autosave.enabled', (value) => @autosaveEnabled = value))
    @subscriptions.add(atom.config.observe('autocomplete-plus.backspaceTriggersAutocomplete', (value) => @backspaceTriggersAutocomplete = value))

    # Handle events from suggestion list
    @subscriptions.add(@suggestionList.onDidConfirm(@confirm))
    @subscriptions.add(@suggestionList.onDidCancel(@hideSuggestionList))

  handleCommands: =>
    # Allow autocomplete to be triggered via keymap
    @subscriptions.add atom.commands.add 'atom-text-editor',
      'autocomplete-plus:activate': =>
        @shouldDisplaySuggestions = true
        @findSuggestions()

  # Private: Finds suggestions for the current prefix, sets the list items,
  # positions the overlay and shows it
  findSuggestions: =>
    return unless @providerManager?
    return unless @editor?
    return unless @buffer?
    return if @isCurrentFileBlackListed()
    cursor = @editor.getLastCursor()
    return unless cursor?
    cursorPosition = cursor.getBufferPosition()
    currentScope = cursor.getScopeDescriptor()
    return unless currentScope?
    currentScopeChain = currentScope.getScopeChain()
    return unless currentScopeChain?

    options =
      editor: @editor
      buffer: @buffer
      cursor: cursor
      position: cursorPosition
      scope: currentScope
      scopeChain: currentScopeChain
      prefix: @prefixForCursor(cursor)

    @getSuggestionsFromProviders(options)

  getSuggestionsFromProviders: (options) =>
    providers = @providerManager.providersForScopeChain(options.scopeChain)
    providerPromises = providers?.map (provider) -> provider?.requestHandler(options)
    return unless providerPromises?.length
    @currentSuggestionsPromise = suggestionsPromise = Promise.all(providerPromises)
      .then(@mergeSuggestionsFromProviders)
      .then((suggestions) => @displaySuggestions(suggestions, suggestionsPromise, options))

  # providerSuggestions - array of arrays of suggestions provided by all called providers
  mergeSuggestionsFromProviders: (providerSuggestions) ->
{'fraction_non_alphanumeric': 0.08880139982502187, 'fraction_numerical': 0.0004374453193350831, 'mean_word_length': 4.476047904191617, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 31, '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': '3604912', 'n_tokens_mistral': 2527, 'n_tokens_neox': 2405, 'n_words': 598}