<commit_before>_ = require 'underscore-plus'
{$$$, EditorView, View} = require 'atom'
FindModel = require './find-model'
FindResultsView = require './find-results-view'
History = require './history'

module.exports =
class FindView extends View

  @content: ->
    @div tabIndex: -1, class: 'find-and-replace tool-panel panel-bottom', =>
      @div class: 'block', =>
        @span outlet: 'descriptionLabel', class: 'description', 'Find in Current Buffer'
        @span class: 'options-label pull-right', =>
          @span 'Finding with Options: '
          @span outlet: 'optionsLabel', class: 'options'

      @ul outlet: 'errorMessages', class: 'error-messages block'

      @div class: 'find-container block', =>
        @div class: 'editor-container', =>
          @subview 'findEditor', new EditorView(mini: true, placeholderText: 'Find in current buffer')

          @div class: 'find-meta-container', =>
            @span outlet: 'resultCounter', class: 'text-subtle result-counter', ''

        @div class: 'btn-group btn-group-find', =>
          @button outlet: 'previousButton', class: 'btn', 'Find Prev'
          @button outlet: 'nextButton', class: 'btn', 'Find Next'

        @div class: 'btn-group btn-toggle btn-group-options', =>
          @button outlet: 'regexOptionButton', class: 'btn', '.*'
          @button outlet: 'caseOptionButton', class: 'btn', 'Aa'
          @button outlet: 'selectionOptionButton', class: 'btn option-selection', '"'

      @div class: 'replace-container block', =>
        @div class: 'editor-container', =>
          @subview 'replaceEditor', new EditorView(mini: true, placeholderText: 'Replace in current buffer')

        @div class: 'btn-group btn-group-replace', =>
          @button outlet: 'replacePreviousButton', class: 'btn btn-prev', 'Replace Prev'
          @button outlet: 'replaceNextButton', class: 'btn btn-next', 'Replace Next'

        @div class: 'btn-group btn-group-replace-all', =>
          @button outlet: 'replaceAllButton', class: 'btn btn-all', 'Replace All'

  initialize: ({showFind, showReplace, findHistory, replaceHistory, modelState}={}) ->
    @findModel = new FindModel(modelState)
    @findHistory = new History(@findEditor, findHistory)
    @replaceHistory = new History(@replaceEditor, replaceHistory)
    @findResultsView = new FindResultsView(@findModel)
    @handleEvents()
    @updateOptionButtons()

    if showFind
      @showFind()
    else if showReplace
      @showReplace()

    @clearMessages()
    @updateOptionsLabel()

  afterAttach: ->
    unless @tooltipsInitialized
      @regexOptionButton.setTooltip("Use Regex", command: 'find-and-replace:toggle-regex-option', commandElement: @findEditor)
      @caseOptionButton.setTooltip("Match Case", command: 'find-and-replace:toggle-case-option', commandElement: @findEditor)
      @selectionOptionButton.setTooltip("Only In Selection", command: 'find-and-replace:toggle-selection-option', commandElement: @findEditor)

      @previousButton.setTooltip("Find Previous", command: 'find-and-replace:find-previous', commandElement: @findEditor)
      @nextButton.setTooltip("Find Next", command: 'find-and-replace:find-next', commandElement: @findEditor)

      @replacePreviousButton.setTooltip("Replace Previous", command: 'find-and-replace:replace-previous', commandElement: @replaceEditor)
      @replaceNextButton.setTooltip("Replace Next", command: 'find-and-replace:replace-next', commandElement: @replaceEditor)
      @replaceAllButton.setTooltip("Replace All", command: 'find-and-replace:replace-all', commandElement: @replaceEditor)
      @tooltipsInitialized = true

  hideAllTooltips: ->
    @regexOptionButton.hideTooltip()
    @caseOptionButton.hideTooltip()
    @selectionOptionButton.hideTooltip()

    @previousButton.hideTooltip()
    @nextButton.hideTooltip()

    @replacePreviousButton.hideTooltip()
    @replaceNextButton.hideTooltip()
    @replaceAllButton.hideTooltip()

  serialize: ->
    findHistory: @findHistory.serialize()
    replaceHistory: @replaceHistory.serialize()
    modelState: @findModel.serialize()

  handleEvents: ->
    @handleFindEvents()
    @handleReplaceEvents()

    @findEditor.on 'core:confirm', => @confirm()
    @replaceEditor.on 'core:confirm', => @replaceNext()

    @on 'find-and-replace:focus-next', @toggleFocus
    @on 'find-and-replace:focus-previous', @toggleFocus
    @on 'core:cancel core:close', @detach

    @command 'find-and-replace:toggle-regex-option', @toggleRegexOption
    @command 'find-and-replace:toggle-case-option', @toggleCaseOption
    @command 'find-and-replace:toggle-selection-option', @toggleSelectionOption

    @regexOptionButton.on 'click', @toggleRegexOption
    @caseOptionButton.on 'click', @toggleCaseOption
    @selectionOptionButton.on 'click', @toggleSelectionOption

    @subscribe @findModel, 'updated', @markersUpdated

    atom.workspaceView.on 'selection:changed', @setCurrentMarkerFromSelection

  handleFindEvents: ->
    @findEditor.getEditor().on 'contents-modified', => @liveSearch()
    @nextButton.on 'click', => @findNext(true)
    @previousButton.on 'click', => @findPrevious(true)
    atom.workspaceView.command 'find-and-replace:find-next', => @findNext(true)
    atom.workspaceView.command 'find-and-replace:find-previous', => @findPrevious(true)
    atom.workspaceView.command 'find-and-replace:use-selection-as-find-pattern', @setSelectionAsFindPattern

  handleReplaceEvents: ->
    @replacePreviousButton.on 'click', @replacePrevious
    @replaceNextButton.on 'click', @replaceNext
    @replaceAllButton.on 'click', @replaceAll
    atom.workspaceView.command 'find-and-replace:replace-previous', @replacePrevious
    atom.workspaceView.command 'find-and-replace:replace-next', @replaceNext
    atom.workspaceView.command 'find-and-replace:replace-all', @replaceAll

  showFind: =>
    @attach() unless @hasParent()

    selectedText = atom.workspace.getActiveEditor()?.getSelectedText?()
    if selectedText and selectedText.indexOf('\n') < 0
      @findEditor.setText(selectedText)
    @findEditor.focus()
    @findEditor.getEditor().selectAll()

  showReplace: =>
    @attach()
    @replaceEditor.redraw()
    @replaceEditor.focus()
    @replaceEditor.getEditor().selectAll()

  attach: =>
    @findResultsView.attach()
    atom.workspaceView.prependToBottom(this)

  detach: =>
    return unless @hasParent()

    @hideAllTooltips()
    @findResultsView.detach()
    atom.workspaceView.focus()
    super()

  toggleFocus: =>
    if @findEditor.find(':focus').length > 0
      @replaceEditor.focus()
    else
      @findEditor.focus()

  confirm: ->
    @findNext(atom.config.get('find-and-replace.focusEditorAfterSearch'))

  liveSearch: ->
    pattern = @findEditor.getText()
    @updateModel { pattern }

  findNext: (focusEditorAfter=false) =>
    @findAndSelectResult(@selectFirstMarkerAfterCursor, focusEditorAfter)

  findPrevious: (focusEditorAfter=false) =>
    @findAndSelectResult(@selectFirstMarkerBeforeCursor, focusEditorAfter)

  findAndSelectResult: (selectFunction, focusEditorAfter) =>
    pattern = @findEditor.getText()
    @updateModel { pattern }
    @findHistory.store()

    if @markers.length == 0
      atom.beep()
    else
      selectFunction()
      atom.workspaceView.focus() if focusEditorAfter

  replaceNext: =>
    @replace('findNext', 'firstMarkerIndexAfterCursor')

  replacePrevious: =>
    @replace('findPrevious', 'firstMarkerIndexBeforeCursor')

  replace: (nextOrPreviousFn, nextIndexFn) ->
    pattern = @findEditor.getText()
    @updateModel { pattern }
    @findHistory.store()
    @replaceHistory.store()

    if @markers.length == 0
      atom.beep()
    else
      unless currentMarker = @currentResultMarker
        markerIndex = @[nextIndexFn]()
        currentMarker = @markers[markerIndex]
<commit_msg>keep focus on findEditor when focusEditorAfter is false<commit_after>_ = require 'underscore-plus'
{$$$, EditorView, View} = require 'atom'
FindModel = require './find-model'
FindResultsView = require './find-results-view'
History = require './history'

module.exports =
class FindView extends View

  @content: ->
    @div tabIndex: -1, class: 'find-and-replace tool-panel panel-bottom', =>
      @div class: 'block', =>
        @span outlet: 'descriptionLabel', class: 'description', 'Find in Current Buffer'
        @span class: 'options-label pull-right', =>
          @span 'Finding with Options: '
          @span outlet: 'optionsLabel', class: 'options'

      @ul outlet: 'errorMessages', class: 'error-messages block'

      @div class: 'find-container block', =>
        @div class: 'editor-container', =>
          @subview 'findEditor', new EditorView(mini: true, placeholderText: 'Find in current buffer')

          @div class: 'find-meta-container', =>
            @span outlet: 'resultCounter', class: 'text-subtle result-counter', ''

        @div class: 'btn-group btn-group-find', =>
          @button outlet: 'previousButton', class: 'btn', 'Find Prev'
          @button outlet: 'nextButton', class: 'btn', 'Find Next'

        @div class: 'btn-group btn-toggle btn-group-options', =>
          @button outlet: 'regexOptionButton', class: 'btn', '.*'
          @button outlet: 'caseOptionButton', class: 'btn', 'Aa'
          @button outlet: 'selectionOptionButton', class: 'btn option-selection', '"'

      @div class: 'replace-container block', =>
        @div class: 'editor-container', =>
          @subview 'replaceEditor', new EditorView(mini: true, placeholderText: 'Replace in current buffer')

        @div class: 'btn-group btn-group-replace', =>
          @button outlet: 'replacePreviousButton', class: 'btn btn-prev', 'Replace Prev'
          @button outlet: 'replaceNextButton', class: 'btn btn-next', 'Replace Next'

        @div class: 'btn-group btn-group-replace-all', =>
          @button outlet: 'replaceAllButton', class: 'btn btn-all', 'Replace All'

  initialize: ({showFind, showReplace, findHistory, replaceHistory, modelState}={}) ->
    @findModel = new FindModel(modelState)
    @findHistory = new History(@findEditor, findHistory)
    @replaceHistory = new History(@replaceEditor, replaceHistory)
    @findResultsView = new FindResultsView(@findModel)
    @handleEvents()
    @updateOptionButtons()

    if showFind
      @showFind()
    else if showReplace
      @showReplace()

    @clearMessages()
    @updateOptionsLabel()

  afterAttach: ->
    unless @tooltipsInitialized
      @regexOptionButton.setTooltip("Use Regex", command: 'find-and-replace:toggle-regex-option', commandElement: @findEditor)
      @caseOptionButton.setTooltip("Match Case", command: 'find-and-replace:toggle-case-option', commandElement: @findEditor)
      @selectionOptionButton.setTooltip("Only In Selection", command: 'find-and-replace:toggle-selection-option', commandElement: @findEditor)

      @previousButton.setTooltip("Find Previous", command: 'find-and-replace:find-previous', commandElement: @findEditor)
      @nextButton.setTooltip("Find Next", command: 'find-and-replace:find-next', commandElement: @findEditor)

      @replacePreviousButton.setTooltip("Replace Previous", command: 'find-and-replace:replace-previous', commandElement: @replaceEditor)
      @replaceNextButton.setTooltip("Replace Next", command: 'find-and-replace:replace-next', commandElement: @replaceEditor)
      @replaceAllButton.setTooltip("Replace All", command: 'find-and-replace:replace-all', commandElement: @replaceEditor)
      @tooltipsInitialized = true

  hideAllTooltips: ->
    @regexOptionButton.hideTooltip()
    @caseOptionButton.hideTooltip()
    @selectionOptionButton.hideTooltip()

    @previousButton.hideTooltip()
    @nextButton.hideTooltip()

    @replacePreviousButton.hideTooltip()
    @replaceNextButton.hideTooltip()
    @replaceAllButton.hideTooltip()

  serialize: ->
    findHistory: @findHistory.serialize()
    replaceHistory: @replaceHistory.serialize()
    modelState: @findModel.serialize()

  handleEvents: ->
    @handleFindEvents()
    @handleReplaceEvents()

    @findEditor.on 'core:confirm', => @confirm()
    @replaceEditor.on 'core:confirm', => @replaceNext()

    @on 'find-and-replace:focus-next', @toggleFocus
    @on 'find-and-replace:focus-previous', @toggleFocus
    @on 'core:cancel core:close', @detach

    @command 'find-and-replace:toggle-regex-option', @toggleRegexOption
    @command 'find-and-replace:toggle-case-option', @toggleCaseOption
    @command 'find-and-replace:toggle-selection-option', @toggleSelectionOption

    @regexOptionButton.on 'click', @toggleRegexOption
    @caseOptionButton.on 'click', @toggleCaseOption
    @selectionOptionButton.on 'click', @toggleSelectionOption

    @subscribe @findModel, 'updated', @markersUpdated

    atom.workspaceView.on 'selection:changed', @setCurrentMarkerFromSelection

  handleFindEvents: ->
    @findEditor.getEditor().on 'contents-modified', => @liveSearch()
    @nextButton.on 'click', => @findNext(true)
    @previousButton.on 'click', => @findPrevious(true)
    atom.workspaceView.command 'find-and-replace:find-next', => @findNext(true)
    atom.workspaceView.command 'find-and-replace:find-previous', => @findPrevious(true)
    atom.workspaceView.command 'find-and-replace:use-selection-as-find-pattern', @setSelectionAsFindPattern

  handleReplaceEvents: ->
    @replacePreviousButton.on 'click', @replacePrevious
    @replaceNextButton.on 'click', @replaceNext
    @replaceAllButton.on 'click', @replaceAll
    atom.workspaceView.command 'find-and-replace:replace-previous', @replacePrevious
    atom.workspaceView.command 'find-and-replace:replace-next', @replaceNext
    atom.workspaceView.command 'find-and-replace:replace-all', @replaceAll

  showFind: =>
    @attach() unless @hasParent()

    selectedText = atom.workspace.getActiveEditor()?.getSelectedText?()
    if selectedText and selectedText.indexOf('\n') < 0
      @findEditor.setText(selectedText)
    @findEditor.focus()
    @findEditor.getEditor().selectAll()

  showReplace: =>
    @attach()
    @replaceEditor.redraw()
    @replaceEditor.focus()
    @replaceEditor.getEditor().selectAll()

  attach: =>
    @findResultsView.attach()
    atom.workspaceView.prependToBottom(this)

  detach: =>
    return unless @hasParent()

    @hideAllTooltips()
    @findResultsView.detach()
    atom.workspaceView.focus()
    super()

  toggleFocus: =>
    if @findEditor.find(':focus').length > 0
      @replaceEditor.focus()
    else
      @findEditor.focus()

  confirm: ->
    @findNext(atom.config.get('find-and-replace.focusEditorAfterSearch'))

  liveSearch: ->
    pattern = @findEditor.getText()
    @updateModel { pattern }

  findNext: (focusEditorAfter=false) =>
    @findAndSelectResult(@selectFirstMarkerAfterCursor, focusEditorAfter)

  findPrevious: (focusEditorAfter=false) =>
    @findAndSelectResult(@selectFirstMarkerBeforeCursor, focusEditorAfter)

  findAndSelectResult: (selectFunction, focusEditorAfter) =>
    pattern = @findEditor.getText()
    @updateModel { pattern }
    @findHistory.store()

    if @markers.length == 0
      atom.beep()
    else
      selectFunction()
      if focusEditorAfter
        atom.workspaceView.focus()
      else
        @findEditor.focus()

  replaceNext: =>
    @replace('findNext', 'firstMarkerIndexAfterCursor')

  replacePrevious: =>
    @replace('findPrevious', 'firstMarkerIndexBeforeCursor')

  replace: (nextOrPreviousFn, nextIndexFn) ->
    pattern = @findEditor.getText()
    @updateModel { pattern }
    @findHistory.store()
    @replaceHistory.store()

    if @markers.length == 0
      atom.beep()
    else
      unless currentMarker = @currentResultMarker
        markerIndex = @[nextIndexFn]()
        currentMarker = @markers[markerIndex]

{'fraction_non_alphanumeric': 0.13610634102906569, 'fraction_numerical': 0.0006360109393881574, 'mean_word_length': 4.0903204920686305, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 85, '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': '3472931', 'n_tokens_mistral': 4588, 'n_tokens_neox': 4485, 'n_words': 917}