😎

Livebookの新機能Smart Cellsを使ってシェルコマンドを実行できるセルを作った

2022/06/16に公開

Livebookのv0.6にSmart Cellsという機能が追加されました(v0.6: Automate and learn with smart cells - Livebook.dev - The Livebook Blog)。従来用意されていたコードやMarkdownなどのセル以外に、UIを持つような複雑なセルをユーザが作れるようになりました。

José Valimさんによる動画解説もあります。
https://www.youtube.com/watch?v=4hVIxyHxwK8

この記事では、Smart Cellsを使って簡単な例を作ってみたので紹介します。

作ったもの

コマンドを実行できるセルを作ってみました。

https://github.com/kentaro/smart_cell_command

インストールすると、以下のように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