<commit_before>import os from "os";

import Editor from "./editor";
import { CommandExists } from "../lib/command-exists";

const findInFiles = require("find-in-files");

interface TerminalInterface {
  exists: boolean;
  pluginInstalled?: boolean;
}

export default class Terminal extends Editor {
  private commandExists = new CommandExists();

  private availableTerminals: { [id: string]: TerminalInterface } = {};

  constructor() {
    super();
    this.getTerminals();
  }

  public static getName(): string {
    return "Terminal";
  }

  public get name(): string {
    return "Terminal";
  }

  public get icon(): string {
    return "";
  }

  public get binaries(): string[] {
    return ["bash", "zsh", "iterm", "iterm2", "fish"];
  }

  public async isEditorInstalled(): Promise<boolean> {
    return Object.keys(this.availableTerminals).length > 0;
  }

  private getTerminals() {
    this.binaries.forEach(async (binary: string) => {
      const exists: boolean = await this.commandExists.exists(binary);
      this.availableTerminals[binary] = { exists };
    });
  }

  public async isPluginInstalled(): Promise<boolean> {
    switch (os.platform()) {
      case "win32":
        return false;
      case "darwin": {
        Object.keys(this.availableTerminals).forEach(async terminal => {
          if (terminal === "zsh") {
            this.availableTerminals[
              terminal
            ].pluginInstalled = await this.isPluginInstalledForZsh();
          } else if (terminal === "bash") {
            this.availableTerminals[
              terminal
            ].pluginInstalled = await this.isPluginInstalledForBash();
          } else if (["iterm", "iterm2"].includes(terminal)) {
            this.availableTerminals[
              terminal
            ].pluginInstalled = await this.isPluginInstalledForiTerm();
          } else if (terminal === "fish") {
            this.availableTerminals[
              terminal
            ].pluginInstalled = await this.isPluginInstalledForFish();
          }
        });
        return (
          Object.keys(this.availableTerminals)
            .map(key => this.availableTerminals[key])
            .filter(x => x.pluginInstalled === true).length > 0
        );
      }
      case "linux":
      default:
        return false;
    }
  }

  private async isPluginInstalledForZsh(): Promise<boolean> {
    // Need to check also for antigen and zgen
    if (await this.isDirectory("~/.oh-my-zsh/custom/plugins/wakatime"))
      return true;
    if (await this.isDirectory("~/.oh-my-zsh/custom/plugins/zsh-wakatime"))
      return true;

    return false;
  }

  private async isPluginInstalledForBash(): Promise<boolean> {
    if (this.fileExistsSync("~/.bashrc")) {
      const find = await findInFiles.find("bash-wakatime.sh", "~/", ".bashrc$");
      return find[".bashrc"].count > 0;
    }

    return false;
  }

  private async isPluginInstalledForiTerm(): Promise<boolean> {
    // Preferences are stored as a binary file at ~/Library/Preferences/com.googlecode.iterm2.plist
    // Need to find a way on asking iTerm if WakaTime is enabled
    return false;
  }

  private async isPluginInstalledForFish(): Promise<boolean> {
    if (this.fileExistsSync("~/.config/fish/functions/fish_prompt.fish")) {
      const find = await findInFiles.find(
        "wakatime",
        "~/.config/fish/functions/",
        "fish_prompt.fish$"
      );
      return find["fish_prompt.fish"].count > 0;
    }

    return false;
  }

  public async installPlugin(): Promise<void> {
    throw new Error("Method not implemented.");
  }

  public async uninstallPlugin(): Promise<void> {
    throw new Error("Method not implemented.");
  }
}<commit_msg>is plugin installed for iterm2<commit_after>import os from "os";

import Editor from "./editor";
import { CommandExists } from "../lib/command-exists";

const findInFiles = require("find-in-files");
const util = require("util");
const exec = util.promisify(require("child_process").exec);

interface TerminalInterface {
  exists: boolean;
  pluginInstalled?: boolean;
}

export default class Terminal extends Editor {
  private commandExists = new CommandExists();

  private availableTerminals: { [id: string]: TerminalInterface } = {};

  constructor() {
    super();
    this.getTerminals();
  }

  public static getName(): string {
    return "Terminal";
  }

  public get name(): string {
    return "Terminal";
  }

  public get icon(): string {
    return "";
  }

  public get binaries(): string[] {
    return ["bash", "zsh", "iterm", "iterm2", "fish"];
  }

  public async isEditorInstalled(): Promise<boolean> {
    return Object.keys(this.availableTerminals).length > 0;
  }

  private getTerminals() {
    this.binaries.forEach(async (binary: string) => {
      const exists: boolean = await this.commandExists.exists(binary);
      this.availableTerminals[binary] = { exists };
    });
  }

  public async isPluginInstalled(): Promise<boolean> {
    switch (os.platform()) {
      case "win32":
        return false;
      case "darwin": {
        Object.keys(this.availableTerminals).forEach(async terminal => {
          if (terminal === "zsh") {
            this.availableTerminals[
              terminal
            ].pluginInstalled = await this.isPluginInstalledForZsh();
          } else if (terminal === "bash") {
            this.availableTerminals[
              terminal
            ].pluginInstalled = await this.isPluginInstalledForBash();
          } else if (["iterm", "iterm2"].includes(terminal)) {
            this.availableTerminals[
              terminal
            ].pluginInstalled = await this.isPluginInstalledForiTerm();
          } else if (terminal === "fish") {
            this.availableTerminals[
              terminal
            ].pluginInstalled = await this.isPluginInstalledForFish();
          }
        });
        return (
          Object.keys(this.availableTerminals)
            .map(key => this.availableTerminals[key])
            .filter(x => x.pluginInstalled === true).length > 0
        );
      }
      case "linux":
      default:
        return false;
    }
  }

  private async isPluginInstalledForZsh(): Promise<boolean> {
    // Need to check also for antigen and zgen
    if (await this.isDirectory("~/.oh-my-zsh/custom/plugins/wakatime"))
      return true;
    if (await this.isDirectory("~/.oh-my-zsh/custom/plugins/zsh-wakatime"))
      return true;

    return false;
  }

  private async isPluginInstalledForBash(): Promise<boolean> {
    if (this.fileExistsSync("~/.bashrc")) {
      const find = await findInFiles.find("bash-wakatime.sh", "~/", ".bashrc$");
      return find[".bashrc"].count > 0;
    }

    return false;
  }

  private async isPluginInstalledForiTerm(): Promise<boolean> {
    const { stdout, stderr } = await exec("plutil -convert xml1 -o - ~/Library/Preferences/com.googlecode.iterm2.plist");
    if (stderr) return Promise.reject(new Error(stderr));

    return stdout.includes("wakatime");
  }

  private async isPluginInstalledForFish(): Promise<boolean> {
    if (this.fileExistsSync("~/.config/fish/functions/fish_prompt.fish")) {
      const find = await findInFiles.find(
        "wakatime",
        "~/.config/fish/functions/",
        "fish_prompt.fish$"
      );
      return find["fish_prompt.fish"].count > 0;
    }

    return false;
  }

  public async installPlugin(): Promise<void> {
    throw new Error("Method not implemented.");
  }

  public async uninstallPlugin(): Promise<void> {
    throw new Error("Method not implemented.");
  }
}
{'fraction_non_alphanumeric': 0.1335711454617519, 'fraction_numerical': 0.002642356982428326, 'mean_word_length': 2.689083820662768, 'pattern_counts': {'":': 6, '<': 19, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 1}, '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': '2230595', 'n_tokens_mistral': 2248, 'n_tokens_neox': 2159, 'n_words': 503}