<commit_before>_ = require 'underscore-plus'
{CompositeDisposable} = require 'atom'
settings = require './settings'

{
  getVisibleEditors
  matchScope
} = require './utils'

module.exports =
  class QuickHighlightView

    constructor: (@editor, {@keywordManager, @statusBarManager}) ->
      @keywordToMarkerLayer = Object.create(null)
      @decorationStyle = settings.get('decorate')

      @disposables = new CompositeDisposable

      highlightSelection = null
      updateHighlightSelection = (delay) =>
        highlightSelection = _.debounce(@highlightSelection.bind(this), delay)

      @disposables.add(
        settings.observe('highlightSelectionDelay', updateHighlightSelection)
        settings.onDidChange('decorate', @onChangeDecorationStyle.bind(this))
        @editor.onDidDestroy(@destroy.bind(this))

        # Don't pass function directly since we UPDATE highlightSelection on config change
        @editor.onDidChangeSelectionRange(({selection}) -> highlightSelection(selection))

        @keywordManager.onDidChangeKeyword(@refresh.bind(this))
        @editor.onDidStopChanging(@reset.bind(this))
      )

    onChangeDecorationStyle: ({newValue}) ->
      @decorationStyle = newValue
      @reset()

    needSelectionHighlight: (selection) ->
      editorElement = @editor.element
      scopes = settings.get('highlightSelectionExcludeScopes')
      switch
        when (not settings.get('highlightSelection'))
            , selection.isEmpty()
            , (scopes.some (scope) -> matchScope(editorElement, scope))
            , not selection.getBufferRange().isSingleLine()
            , selection.getText().length < settings.get('highlightSelectionMinimumLength')
            , /[^\S]/.test(selection.getText())
          false
        else
          true

    highlightSelection: (selection) ->
      @markerLayerForSelectionHighlight?.destroy()
      return unless @needSelectionHighlight(selection)
      if keyword = selection.getText()
        @markerLayerForSelectionHighlight = @highlight(keyword, 'box-selection')

    highlight: (keyword, color) ->
      markerLayer = @editor.addMarkerLayer()
      decorationOptions = {type: 'highlight', class: "quick-highlight #{color}"}
      @editor.decorateMarkerLayer(markerLayer, decorationOptions)
      markerOptions = {invalidate: 'inside'}

      pattern = ///#{_.escapeRegExp(keyword)}///g
      @editor.scan pattern, ({range}) ->
        markerLayer.markBufferRange(range, markerOptions)
      markerLayer

    clear: ->
      for keyword, markerLayer of @keywordToMarkerLayer
        markerLayer.destroy()
      @keywordToMarkerLayer = Object.create(null)

    render: ->
      {keywordToColor} = @keywordManager
      masterKeywords = _.keys(keywordToColor)
      currentKeywords = _.keys(@keywordToMarkerLayer)
      keywordsToAdd = _.without(masterKeywords, currentKeywords...)
      keywordsToDelete = _.without(currentKeywords, masterKeywords...)

      # Delete
      for keyword in keywordsToDelete
        @keywordToMarkerLayer[keyword].destroy()
        delete @keywordToMarkerLayer[keyword]

      # Add<commit_msg>DONE: fix space only exclusion for selection HL<commit_after>_ = require 'underscore-plus'
{CompositeDisposable} = require 'atom'
settings = require './settings'

{
  getVisibleEditors
  matchScope
} = require './utils'

module.exports =
  class QuickHighlightView

    constructor: (@editor, {@keywordManager, @statusBarManager}) ->
      @keywordToMarkerLayer = Object.create(null)
      @decorationStyle = settings.get('decorate')

      @disposables = new CompositeDisposable

      highlightSelection = null
      updateHighlightSelection = (delay) =>
        highlightSelection = _.debounce(@highlightSelection.bind(this), delay)

      @disposables.add(
        settings.observe('highlightSelectionDelay', updateHighlightSelection)
        settings.onDidChange('decorate', @onChangeDecorationStyle.bind(this))
        @editor.onDidDestroy(@destroy.bind(this))

        # Don't pass function directly since we UPDATE highlightSelection on config change
        @editor.onDidChangeSelectionRange(({selection}) -> highlightSelection(selection))

        @keywordManager.onDidChangeKeyword(@refresh.bind(this))
        @editor.onDidStopChanging(@reset.bind(this))
      )

    onChangeDecorationStyle: ({newValue}) ->
      @decorationStyle = newValue
      @reset()

    needSelectionHighlight: (selection) ->
      editorElement = @editor.element
      excludeScopes = settings.get('highlightSelectionExcludeScopes')
      switch
        when (not settings.get('highlightSelection'))
            , selection.isEmpty()
            , (excludeScopes.some (scope) -> matchScope(editorElement, scope))
            , not selection.getBufferRange().isSingleLine()
            , selection.getText().length < settings.get('highlightSelectionMinimumLength')
            , (not /\S/.test(selection.getText()))
          false
        else
          true

    highlightSelection: (selection) ->
      @markerLayerForSelectionHighlight?.destroy()
      return unless @needSelectionHighlight(selection)
      if keyword = selection.getText()
        @markerLayerForSelectionHighlight = @highlight(keyword, 'box-selection')

    highlight: (keyword, color) ->
      markerLayer = @editor.addMarkerLayer()
      @editor.decorateMarkerLayer(markerLayer, type: 'highlight', class: "quick-highlight #{color}")
      @editor.scan ///#{_.escapeRegExp(keyword)}///g, ({range}) ->
        markerLayer.markBufferRange(range, invalidate: 'inside')
      markerLayer

    clear: ->
      for keyword, markerLayer of @keywordToMarkerLayer
        markerLayer.destroy()
      @keywordToMarkerLayer = Object.create(null)

    render: ->
      {keywordToColor} = @keywordManager
      masterKeywords = _.keys(keywordToColor)
      currentKeywords = _.keys(@keywordToMarkerLayer)
      keywordsToAdd = _.without(masterKeywords, currentKeywords...)
      keywordsToDelete = _.without(currentKeywords, masterKeywords...)

      # Delete
      for keyword in keywordsToDelete
        @keywordToMarkerLayer[keyword].destroy()
        delete @keywordToMarkerLayer[keyword]

      # Add
{'fraction_non_alphanumeric': 0.11174180992539734, 'fraction_numerical': 0.0, 'mean_word_length': 3.3706591070163006, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 25, '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': '7636122', 'n_tokens_mistral': 1634, 'n_tokens_neox': 1553, 'n_words': 301}