<commit_before>import PropTypes from 'prop-types'
import React from 'react'
import AceEditor from 'react-ace'
import { Subscribe } from 'unstated'
import AppContainer from '../containers/AppContainer'
import 'brace/ext/searchbox'
import 'brace/mode/sql'
import 'brace/theme/sqlserver'

const noop = () => {}

class SqlEditor extends React.Component {
  componentDidMount() {
    const { config, onChange } = this.props
    const editor = this.editor

    if (editor && onChange) {
      editor.focus()

      // augment the built-in behavior of liveAutocomplete
      // built-in behavior only starts autocomplete when at least 1 character has been typed
      // In ace the . resets the prefix token and clears the completer
      // In order to get completions for 'sometable.' we need to fire the completer manually
      editor.commands.on('afterExec', e => {
        if (e.command.name === 'insertstring' && /^[\w.]$/.test(e.args)) {
          if (e.args === '.') {
            editor.execCommand('startAutocomplete')
          }
        }
      })
      if (config.editorWordWrap) {
        editor.session.setUseWrapMode(true)
      }
    }
  }

  handleSelection = selection => {
    const { onSelectionChange } = this.props
    const { editor } = this
    if (editor && editor.session) {
      const selectedText = editor.session.getTextRange(selection.getRange())
      onSelectionChange(selectedText)
    }
  }

  render() {
    const { config, onChange, readOnly, value, height } = this.props

    if (this.editor && config.editorWordWrap) {
      this.editor.session.setUseWrapMode(true)
    }

    return (
      <AceEditor
        editorProps={{ $blockScrolling: Infinity }}
        enableBasicAutocompletion
        enableLiveAutocompletion
        height={height}
        highlightActiveLine={false}
        mode="sql"
        name="query-ace-editor"
        onChange={onChange || noop}
        onSelectionChange={this.handleSelection}
        showGutter={false}
        showPrintMargin={false}
        theme="sqlserver"
        readOnly={readOnly}
        value={value}
        width="100%"
        ref={ref => {
          this.editor = ref ? ref.editor : null
        }}
      />
    )
  }
}

SqlEditor.propTypes = {
  config: PropTypes.object.isRequired,
  height: PropTypes.string,
  onChange: PropTypes.func,
  onSelectionChange: PropTypes.func,
  readOnly: PropTypes.bool,
  value: PropTypes.string
}

SqlEditor.defaultProps = {
  height: '100%',
  onSelectionChange: () => {},
  readOnly: false,
  value: ''
}

const SqlEditorContainer = props => {
  return (
    <Subscribe to={[AppContainer]}>
      {appContainer => {
        const { config } = appContainer.state
        return <SqlEditor {...props} config={config} />
      }}
    </Subscribe>
  )
}

export default SqlEditorContainer
<commit_msg>Fix ref use on functional component<commit_after>// NOTE this import 'brace' must occur before the importing of brace extensions
import 'brace'
import 'brace/ext/searchbox'
import 'brace/mode/sql'
import 'brace/theme/sqlserver'
import PropTypes from 'prop-types'
import React from 'react'
import AceEditor from 'react-ace'
import { Subscribe } from 'unstated'
import AppContainer from '../containers/AppContainer'

const noop = () => {}

class SqlEditor extends React.Component {
  componentDidMount() {
    const { config, onChange } = this.props
    const editor = this.editor

    if (editor && onChange) {
      editor.focus()

      // augment the built-in behavior of liveAutocomplete
      // built-in behavior only starts autocomplete when at least 1 character has been typed
      // In ace the . resets the prefix token and clears the completer
      // In order to get completions for 'sometable.' we need to fire the completer manually
      editor.commands.on('afterExec', e => {
        if (e.command.name === 'insertstring' && /^[\w.]$/.test(e.args)) {
          if (e.args === '.') {
            editor.execCommand('startAutocomplete')
          }
        }
      })
      if (config.editorWordWrap) {
        editor.session.setUseWrapMode(true)
      }
    }
  }

  handleSelection = selection => {
    const { onSelectionChange } = this.props
    const { editor } = this
    if (editor && editor.session) {
      const selectedText = editor.session.getTextRange(selection.getRange())
      onSelectionChange(selectedText)
    }
  }

  render() {
    const { config, onChange, readOnly, value, height } = this.props

    if (this.editor && config.editorWordWrap) {
      this.editor.session.setUseWrapMode(true)
    }

    return (
      <AceEditor
        editorProps={{ $blockScrolling: Infinity }}
        enableBasicAutocompletion
        enableLiveAutocompletion
        height={height}
        highlightActiveLine={false}
        mode="sql"
        name="query-ace-editor"
        onChange={onChange || noop}
        onSelectionChange={this.handleSelection}
        showGutter={false}
        showPrintMargin={false}
        theme="sqlserver"
        readOnly={readOnly}
        value={value}
        width="100%"
        ref={ref => {
          this.editor = ref ? ref.editor : null
        }}
      />
    )
  }
}

SqlEditor.propTypes = {
  config: PropTypes.object.isRequired,
  height: PropTypes.string,
  onChange: PropTypes.func,
  onSelectionChange: PropTypes.func,
  readOnly: PropTypes.bool,
  value: PropTypes.string
}

SqlEditor.defaultProps = {
  height: '100%',
  onSelectionChange: () => {},
  readOnly: false,
  value: ''
}

class SqlEditorContainer extends React.Component {
  render() {
    return (
      <Subscribe to={[AppContainer]}>
        {appContainer => {
          const { config } = appContainer.state
          return <SqlEditor {...this.props} config={config} />
        }}
      </Subscribe>
    )
  }
}

export default SqlEditorContainer

{'fraction_non_alphanumeric': 0.11842557579924373, 'fraction_numerical': 0.0024063251976624267, 'mean_word_length': 2.6255451713395637, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 24, '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': '6790093', 'n_tokens_mistral': 1685, 'n_tokens_neox': 1677, 'n_words': 402}