💅

Denoで@cliffy/promptを色々試したサンプルメモ

に公開


DenoでCLIを作成する際に@clack/promptsのようなものを探してみたところ、@cliffy/promptが使用できそうでした。公式サイトを見ると基本的な使い方は理解できるのですが、カスタマイズ例が十分に紹介されておらず、使用した結果がどのように見えるかもわかりませんでした。そのあたりを試した結果の備忘メモです。

前提

  • @cliffy/promptのバージョン@1.0.0-rc.7で確認
  • @cliffy/ansi/colorsを使用する場合、事前に以下コマンド実行が必要
    • deno add jsr:@cliffy/ansi@^1.0.0-rc.7

主な共通オプション

サンプルとしてInputを使用しているが、全種類のプロンプトで使用可能(のはず)。

import { Input, type InputOptions } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<string> {
  const args: InputOptions = {
    message: "general options",
    default: "default text",
    // hideDefault: true,  don't show indicated default value
    hint: "prompt description",
    info: true,
    suggestions: ["foo", "bar"],
    transform: (value) => value.toUpperCase(),
  };
  return await Input.prompt(args);
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_options1
  2. arrow upキー押下
    img_options2
  3. tabキー押下
    img_options3
  4. 入力クリア後、enterキー押下
    img_options4
  • foo入力後、enterキー押下
    img_options5

単一選択

Toggle

シンプルな使用

import { Toggle } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<boolean> {
  return await Toggle.prompt({ message: "simple toggle message" });
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_toggle_simple1
  2. enterキー押下
    img_toggle_simple2
  3. yキー押下
    img_toggle_simple3
  4. enterキー押下
    img_toggle_simple4

全体的なカスタム

import { Toggle, type ToggleOptions } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<boolean> {
  const args: ToggleOptions = {
    message: "custom toggle message",
    active: "hello",
    inactive: "goodbye",
  };
  return await Toggle.prompt(args);
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_toggle_custom1
  2. gキー押下
    img_toggle_custom2
  3. enterキー押下
    img_toggle_custom3

Confirm

単一選択に分類したが、自由入力に近い。

シンプルな使用

import { Confirm } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<boolean> {
  return await Confirm.prompt({ message: "simple confirm message" });
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_confirm_simple1
  2. enterキー押下
    img_confirm_simple2
  3. yキー押下
    img_confirm_simple3
  4. enterキー押下
    img_confirm_simple4

全体的なカスタム

import { Confirm, type ConfirmOptions } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<boolean> {
  const args: ConfirmOptions = {
    message: "custom confirm message",
    active: "hello",
    inactive: "goodbye",
  };
  return await Confirm.prompt(args);
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_confirm_custom1
  2. gキー押下
    img_confirm_custom2
  3. enterキー押下
    img_confirm_custom3

Select

シンプルな使用

import { Select, type SelectOptions } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<string> {
  const message = "simple select message";
  const options = ["foo", "bar", "baz"];
  const args: SelectOptions<string> = { message, options };
  return await Select.prompt(args);
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_select_simple1
  2. enterキー押下
    img_select_simple2

選択肢のカスタム

import { Select, type SelectOptions } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<string | number> {
  const message = "complex select message";
  const options = [{
    name: "alfa",
    value: 1,
  }, {
    name: "bravo",
    value: 2,
  }, {
    name: "group charlie",
    options: ["delta", "echo", "foxtrot"],
  }];
  const args: SelectOptions<string | number> = { message, options };
  return await Select.prompt(args);
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_select_complex1
  2. group charlieまで移動後、arrow rightキー押下
    img_select_complex2
  3. deltaまで移動後、enterキー押下
    img_select_complex3

複数選択

Checkbox

シンプルな使用

import { Checkbox, type CheckboxOptions } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<string[]> {
  const message = "simple checkbox message";
  const options = ["foo", "bar", "baz"];
  const args: CheckboxOptions<string> = { message, options };
  return await Checkbox.prompt(args);
}
const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_check_simple1
  2. spaceキー押下
    img_check_simple2
  3. enterキー押下
    img_check_simple3
  4. enterキー押下
    img_check_simple4

選択肢のカスタム

import { Checkbox, type CheckboxOptions } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<(string | number)[]> {
  const message = "complex checkbox message";
  const options = [{
    name: "alfa",
    value: 1,
  }, {
    name: "bravo",
    value: 2,
    checked: true,
  }, {
    name: "charlie",
    value: 3,
    icon: false,
  }, {
    name: "group delta",
    options: ["echo", "foxtrot"],
  }, {
    name: "group golf",
    options: ["hotel", "india"],
    // checked: true,  no effect
    icon: false,
  }];
  const args: CheckboxOptions<string | number> = { message, options };
  return await Checkbox.prompt(args);
}
const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_check_complex1
  2. group deltaまで移動後、spaceキー押下
    img_check_complex2
  3. arrow rightキー押下
    img_check_complex3
  4. echoまで移動後、spaceキー押下
    img_check_complex4
  5. arrow leftキー2回押下
    img_check_complex5
  6. group golfまで移動後、spaceキー押下
    img_check_complex6
  7. hotelまで移動後、spaceキー押下
    img_check_complex7
  8. arrow leftキー2回押下後、enterキー押下
    img_check_complex8
  9. enterキー押下
    img_check_complex9

全体的なカスタム

import { Checkbox, type CheckboxOptions } from "jsr:@cliffy/prompt@1.0.0-rc.7";
import { colors } from "@cliffy/ansi/colors";

async function showPrompt(): Promise<string[]> {
  const args: CheckboxOptions<string> = {
    message: "custom checkbox message",
    options: [{ name: "group", options: ["foo", "bar", "baz"] }],
    confirmSubmit: false,
    check: colors.green("☑"),
    uncheck: "☐",
    partialCheck: colors.rgb24("▣", 0x8fbc8f),
    minOptions: 1,
    maxOptions: 2,
    keys: {
      check: ["space", "y"],
      // checkAll: ["a"],  no effect?
    },
  };
  return await Checkbox.prompt(args);
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_check_custom1
  2. enterキー押下
    img_check_custom2
  3. spaceキー押下後、enterキー押下
    img_check_custom3
  4. arrow rightキーを押下しfooまで移動後、yキー押下
    img_check_custom4
  5. enterキー押下
    img_check_custom5

自由入力

Input

シンプルな使用

import { Input } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<string> {
  return await Input.prompt({ message: "simple input message" });
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_input_simple1
  2. foo,barを入力
    img_input_simple2
  3. enterキー押下
    img_input_simple3

全体的なカスタム

import { Input, type InputOptions } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<string> {
  const args: InputOptions = {
    message: "custom input message",
    minLength: 3,
    maxLength: 4,
  };
  return await Input.prompt(args);
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_input_custom1
  2. enterキー押下
    img_input_custom2
  3. fooを入力
    img_input_custom3
  4. enterキー押下
    img_input_custom4

Number

シンプルな使用

import { Number } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<number> {
  return await Number.prompt({ message: "simple number message" });
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_number_simple1
  2. fooを入力
    img_number_simple2
  3. 123を入力
    img_number_simple3
  4. enterキー押下
    img_number_simple4

全体的なカスタム

import { Number, type NumberOptions } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<number> {
  const args: NumberOptions = {
    message: "custom number message",
    float: true,
    round: 2,
    min: -1,
    max: 1,
  };
  return await Number.prompt(args);
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_number_custom1
  2. enterキー押下
    img_number_custom2
  3. 3を入力後、enterキー押下
    img_number_custom3
  4. 入力をクリアし-0.111を入力後、enterキー押下
    img_number_custom4

Secret

シンプルな使用

import { Secret } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<string> {
  return await Secret.prompt({ message: "simple secret message" });
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_secret_simple1
  2. fooを入力
    img_secret_simple2
  3. enterキー押下
    img_secret_simple3

全体的なカスタム

async function showPrompt(): Promise<string> {
  const args: SecretOptions = {
    message: "custom secret message",
    label: "xxx",
    hidden: true,
    minLength: 3,
    maxLength: 4,
  };
  return await Secret.prompt(args);
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_secret_custom1
  2. enterキー押下
    img_secret_custom2
  3. fooを入力
    img_secret_custom3
  4. enterキー押下
    img_secret_custom4

複数自由入力

List

シンプルな使用

import { List } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<string[]> {
  return await List.prompt({ message: "simple list message" });
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_list_simple1
  2. foo,bar,bazを入力
    img_list_simple2
  3. enterキー押下
    img_list_simple3

全体的なカスタム

import { List, type ListOptions } from "jsr:@cliffy/prompt@1.0.0-rc.7";

async function showPrompt(): Promise<string[]> {
  const args: ListOptions = {
    message: "custom toggle message",
    separator: ";",
    minLength: 3,
    maxLength: 3,
    minTags: 1,
    maxTags: 2,
  };
  return await List.prompt(args);
}

const result = await showPrompt();
console.log("---------- values ----------");
console.log(result);
  1. 実行直後
    img_list_custom1
  2. enterキー押下
    img_list_custom2
  3. aを入力後、enterキー押下
    img_list_custom3
  4. backspace,foo;barを入力後、enterキー押下
    img_list_custom4

雑記

今後spinnerが同梱されることを期待してます。

参考文献

Discussion