😎
Livebookの新機能Smart Cellsを使ってシェルコマンドを実行できるセルを作った
Livebookのv0.6にSmart Cellsという機能が追加されました(v0.6: Automate and learn with smart cells - Livebook.dev - The Livebook Blog)。従来用意されていたコードやMarkdownなどのセル以外に、UIを持つような複雑なセルをユーザが作れるようになりました。
José Valimさんによる動画解説もあります。
この記事では、Smart Cellsを使って簡単な例を作ってみたので紹介します。
作ったもの
コマンドを実行できるセルを作ってみました。
インストールすると、以下のようにCommandというセルを選択できるようになります。

コードやMarkdownと同じような入力ができるエディタが表示されるので、そこに適当なコマンドを書き込んでEvaluateボタンを押すと、コマンドが実行され、結果が表示されます。
引数付きコマンド:

コマンドを2つ実行:

実装
今回のコマンドは特別なUIを持たないので、実装はシンプルです。Smart Cellのバックエンドとなるプロセスを起動しておいて、評価対象のコマンド文字列が渡された際の処理を書いてやる感じ。
Let’s write an Elixir LiveBook smart cell - Rake Routesという記事がもうちょっと詳しく説明してるので、そちらもご覧ください。
defmodule SmartCellCommand do
  @moduledoc false
  use Kino.JS
  use Kino.JS.Live
  use Kino.SmartCell, name: "Command"
  @impl true
  def init(attrs, ctx) do
    {:ok, assign(ctx, command: attrs["command"] || ""), editor: [attribute: "command"]}
  end
  @impl true
  def handle_connect(ctx) do
    {:ok, %{}, ctx}
  end
  @impl true
  def to_attrs(_ctx) do
    %{}
  end
  @impl true
  def to_source(attrs) do
    quote do
      unquote(attrs["command"])
      |> String.split("\n")
      |> Enum.map(fn line ->
        [cmd | args] = line |> String.split(" ")
        {result, _} = System.cmd(cmd, args)
        result |> String.trim()
      end)
      |> Enum.join("\n\n")
      |> IO.puts()
    end
    |> Kino.SmartCell.quoted_to_string()
  end
  asset "main.js" do
    """
    export function init(ctx, payload) {
    }
    """
  end
end
他のSmart Cellは入力用のリッチなUIがありますが、上記では空にしてあるmain.jsで書いていくことができます。具体的にどんな感じに書けるのかについては、kino_db/sql_cell.exなどをのぞいてみてください。
おわりに
Smart Cellsはすごく面白い機能だと思います。今後が楽しみですね。


Discussion