yuku-t/textcomplete

View on GitHub
src/completer.js

Summary

Maintainability
A
0 mins
Test Coverage
// @flow

import EventEmitter from "eventemitter3"

import Query from "./query"
import SearchResult from "./search_result"
import Strategy from "./strategy"

const CALLBACK_METHODS = ["handleQueryResult"]

/**
 * Complete engine.
 */
export default class Completer extends EventEmitter {
  strategies: Strategy[]

  constructor() {
    super()
    this.strategies = []

    CALLBACK_METHODS.forEach(method => {
      ;(this: any)[method] = (this: any)[method].bind(this)
    })
  }

  /**
   * @return {this}
   */
  destroy() {
    this.strategies.forEach(strategy => strategy.destroy())
    return this
  }

  /**
   * Register a strategy to the completer.
   *
   * @return {this}
   */
  registerStrategy(strategy: Strategy) {
    this.strategies.push(strategy)
    return this
  }

  /**
   * @param {string} text - Head to input cursor.
   */
  run(text: string): void {
    const query = this.extractQuery(text)
    if (query) {
      query.execute(this.handleQueryResult)
    } else {
      this.handleQueryResult([])
    }
  }

  /**
   * Find a query, which matches to the given text.
   *
   * @private
   */
  extractQuery(text: string) {
    for (let i = 0; i < this.strategies.length; i++) {
      const query = Query.build(this.strategies[i], text)
      if (query) {
        return query
      }
    }
    return null
  }

  /**
   * Callbacked by {@link Query#execute}.
   *
   * @private
   */
  handleQueryResult(searchResults: SearchResult[]) {
    this.emit("hit", { searchResults })
  }
}