<commit_before>// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

import { IDisplayState, ISearchProvider, IFiltersType } from './interfaces';
import { createSearchOverlay } from './searchoverlay';

import { MainAreaWidget } from '@jupyterlab/apputils';
import { IDisposable } from '@lumino/disposable';
import { ISignal, Signal } from '@lumino/signaling';
import { Widget } from '@lumino/widgets';

/**
 * Represents a search on a single widget.
 */
export class SearchInstance implements IDisposable {
  constructor(widget: Widget, searchProvider: ISearchProvider) {
    this._widget = widget;
    this._activeProvider = searchProvider;

    const initialQuery = this._activeProvider.getInitialQuery(this._widget);
    this._displayState.searchText = initialQuery || '';

    this._searchWidget = createSearchOverlay({
      widgetChanged: this._displayUpdateSignal,
      overlayState: this._displayState,
      onCaseSensitiveToggled: this._onCaseSensitiveToggled.bind(this),
      onRegexToggled: this._onRegexToggled.bind(this),
      onHightlightNext: this._highlightNext.bind(this),
      onHighlightPrevious: this._highlightPrevious.bind(this),
      onStartQuery: this._startQuery.bind(this),
      onReplaceCurrent: this._replaceCurrent.bind(this),
      onReplaceAll: this._replaceAll.bind(this),
      onEndSearch: this.dispose.bind(this),
      isReadOnly: this._activeProvider.isReadOnly,
      hasOutputs: this._activeProvider.hasOutputs || false
    });

    this._widget.disposed.connect(() => {
      this.dispose();
    });
    this._searchWidget.disposed.connect(() => {
      this._widget.activate();
      this.dispose();
    });

    // TODO: this does not update if the toolbar changes height.
    if (this._widget instanceof MainAreaWidget) {
      // Offset the position of the search widget to not cover the toolbar.
      this._searchWidget.node.style.top = `${this._widget.toolbar.node.clientHeight}px`;
    }
    this._displaySearchWidget();
  }

  /**
   * The search widget.
   */
  get searchWidget() {
    return this._searchWidget;
  }

  /**
   * The search provider.
   */
  get provider() {
    return this._activeProvider;
  }

  /**
   * Focus the search widget input.
   */
  focusInput(): void {
    this._displayState.forceFocus = true;
    this._displayState.searchInputFocused = true;

    // Trigger a rerender without resetting the forceFocus.
    this._displayUpdateSignal.emit(this._displayState);
    this._displayState.forceFocus = false;
  }

  /**
   * If there is a replace box, show it
   */
  showReplace(): void {
    this._displayState.replaceEntryShown = true;
  }
  /**
   * Updates the match index and total display in the search widget.
   */
  updateIndices(): void {
    this._displayState.totalMatches = this._activeProvider.matches.length;
    this._displayState.currentIndex = this._activeProvider.currentMatchIndex;
    this._updateDisplay();
  }

  private _updateDisplay() {
    // Reset the focus attribute to make sure we don't steal focus.
    this._displayState.forceFocus = false;

    // Trigger a rerender
    this._displayUpdateSignal.emit(this._displayState);
  }

  private async _startQuery(query: RegExp, filters: IFiltersType) {
    // save the last query (or set it to the current query if this is the first)
    if (this._activeProvider && this._displayState.query) {
      await this._activeProvider.endQuery();
    }
    this._displayState.query = query;
    this._displayState.filters = filters;<commit_msg>Update display after showing replace<commit_after>// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

import { IDisplayState, ISearchProvider, IFiltersType } from './interfaces';
import { createSearchOverlay } from './searchoverlay';

import { MainAreaWidget } from '@jupyterlab/apputils';
import { IDisposable } from '@lumino/disposable';
import { ISignal, Signal } from '@lumino/signaling';
import { Widget } from '@lumino/widgets';

/**
 * Represents a search on a single widget.
 */
export class SearchInstance implements IDisposable {
  constructor(widget: Widget, searchProvider: ISearchProvider) {
    this._widget = widget;
    this._activeProvider = searchProvider;

    const initialQuery = this._activeProvider.getInitialQuery(this._widget);
    this._displayState.searchText = initialQuery || '';

    this._searchWidget = createSearchOverlay({
      widgetChanged: this._displayUpdateSignal,
      overlayState: this._displayState,
      onCaseSensitiveToggled: this._onCaseSensitiveToggled.bind(this),
      onRegexToggled: this._onRegexToggled.bind(this),
      onHightlightNext: this._highlightNext.bind(this),
      onHighlightPrevious: this._highlightPrevious.bind(this),
      onStartQuery: this._startQuery.bind(this),
      onReplaceCurrent: this._replaceCurrent.bind(this),
      onReplaceAll: this._replaceAll.bind(this),
      onEndSearch: this.dispose.bind(this),
      isReadOnly: this._activeProvider.isReadOnly,
      hasOutputs: this._activeProvider.hasOutputs || false
    });

    this._widget.disposed.connect(() => {
      this.dispose();
    });
    this._searchWidget.disposed.connect(() => {
      this._widget.activate();
      this.dispose();
    });

    // TODO: this does not update if the toolbar changes height.
    if (this._widget instanceof MainAreaWidget) {
      // Offset the position of the search widget to not cover the toolbar.
      this._searchWidget.node.style.top = `${this._widget.toolbar.node.clientHeight}px`;
    }
    this._displaySearchWidget();
  }

  /**
   * The search widget.
   */
  get searchWidget() {
    return this._searchWidget;
  }

  /**
   * The search provider.
   */
  get provider() {
    return this._activeProvider;
  }

  /**
   * Focus the search widget input.
   */
  focusInput(): void {
    this._displayState.forceFocus = true;
    this._displayState.searchInputFocused = true;

    // Trigger a rerender without resetting the forceFocus.
    this._displayUpdateSignal.emit(this._displayState);
    this._displayState.forceFocus = false;
  }

  /**
   * If there is a replace box, show it.
   */
  showReplace(): void {
    this._displayState.replaceEntryShown = true;
    this._updateDisplay();
  }
  /**
   * Updates the match index and total display in the search widget.
   */
  updateIndices(): void {
    this._displayState.totalMatches = this._activeProvider.matches.length;
    this._displayState.currentIndex = this._activeProvider.currentMatchIndex;
    this._updateDisplay();
  }

  private _updateDisplay() {
    // Reset the focus attribute to make sure we don't steal focus.
    this._displayState.forceFocus = false;

    // Trigger a rerender
    this._displayUpdateSignal.emit(this._displayState);
  }

  private async _startQuery(query: RegExp, filters: IFiltersType) {
    // save the last query (or set it to the current query if this is the first)
    if (this._activeProvider && this._displayState.query) {
      await this._activeProvider.endQuery();
    }
    this._displayState.query = query;
    this._displayState.filters = filters;
{'fraction_non_alphanumeric': 0.10868652958455728, 'fraction_numerical': 0.0, 'mean_word_length': 3.491206030150754, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4730668', 'n_tokens_mistral': 2063, 'n_tokens_neox': 2025, 'n_words': 490}