Packages
livebook
0.6.1
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook_web/live/output/stdout_component.ex
defmodule LivebookWeb.Output.StdoutComponent do
use LivebookWeb, :live_component
@impl true
def mount(socket) do
{:ok, assign(socket, modifiers: [], last_line: nil, last_html_line: nil),
temporary_assigns: [html_lines: []]}
end
@impl true
def update(assigns, socket) do
{text, assigns} = Map.pop(assigns, :text)
socket = assign(socket, assigns)
if text do
text = (socket.assigns.last_line || "") <> text
text = Livebook.Notebook.normalize_stdout(text)
last_line =
case Livebook.Utils.split_at_last_occurrence(text, "\n") do
:error -> text
{:ok, _, last_line} -> last_line
end
{html_lines, modifiers} =
LivebookWeb.Helpers.ANSI.ansi_string_to_html_lines_step(text, socket.assigns.modifiers)
{html_lines, [last_html_line]} = Enum.split(html_lines, -1)
{:ok,
assign(socket,
html_lines: html_lines,
last_html_line: last_html_line,
last_line: last_line,
modifiers: modifiers
)}
else
{:ok, socket}
end
end
@impl true
def render(assigns) do
~H"""
<div id={"virtualized-text-#{@id}"}
class="relative"
phx-hook="VirtualizedLines"
data-max-height="300"
data-follow="true"
data-max-lines={Livebook.Notebook.max_stdout_lines()}
data-ignore-trailing-empty-line="true">
<%# Note 1: We add a newline to each element, so that multiple lines can be copied properly as element.textContent %>
<%# Note 2: We use comments to avoid inserting unintended whitespace %>
<div data-template class="hidden" id={"virtualized-text-#{@id}-template"}><%#
%><div id={"virtualized-text-#{@id}-template-append"} phx-update="append"><%#
%><%= for html_line <- @html_lines do %><%#
%><div data-line id={Livebook.Utils.random_id()}><%= [html_line, "\n"] %></div><%#
%><% end %><%#
%></div><%#
%><div data-line><%= @last_html_line %></div><%#
%></div>
<div data-content class="overflow-auto whitespace-pre font-editor text-gray-500 tiny-scrollbar"
id={"virtualized-text-#{@id}-content"}
phx-update="ignore"></div>
<div class="absolute right-2 top-0 z-10">
<button class="icon-button bg-gray-100"
data-el-clipcopy
phx-click={JS.dispatch("lb:clipcopy", to: "#virtualized-text-#{@id}-template")}>
<.remix_icon icon="clipboard-line" class="text-lg" />
</button>
</div>
</div>
"""
end
end