diff --git a/assets/js/hooks/cell_editor/live_editor/monaco.js b/assets/js/hooks/cell_editor/live_editor/monaco.js
index c7806cbf0..bfcf0215e 100644
--- a/assets/js/hooks/cell_editor/live_editor/monaco.js
+++ b/assets/js/hooks/cell_editor/live_editor/monaco.js
@@ -5,6 +5,8 @@ import { theme, highContrast } from "./theme";
import { PieceTreeTextBufferBuilder } from "monaco-editor/esm/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder";
+import { settingsStore } from "../../../lib/settings";
+
// Force LF for line ending.
//
// Monaco infers EOL based on the text content if any, otherwise uses
@@ -132,6 +134,20 @@ export default monaco;
* Returns a promise resolving to HTML that renders as the highlighted code.
*/
export function highlight(code, language) {
+ // Currently monaco.editor.colorize doesn't support passing theme
+ // directly and uses the theme from last editor initialization, so
+ // we need to make sure there was at least one editor initialization
+ // with the configured theme.
+ //
+ // Tracked in https://github.com/microsoft/monaco-editor/issues/3302
+ if (!highlight.initialized) {
+ const settings = settingsStore.get();
+ monaco.editor.create(document.createElement("div"), {
+ theme: settings.editor_theme,
+ });
+ highlight.initialized = true;
+ }
+
return monaco.editor.colorize(code, language).then((result) => {
// `colorize` always adds additional newline, so we remove it
return result.replace(/
$/, "");
diff --git a/lib/livebook/notebook/app_settings.ex b/lib/livebook/notebook/app_settings.ex
index aeec2f1b8..3875fff33 100644
--- a/lib/livebook/notebook/app_settings.ex
+++ b/lib/livebook/notebook/app_settings.ex
@@ -8,7 +8,8 @@ defmodule Livebook.Notebook.AppSettings do
@type t :: %__MODULE__{
slug: String.t() | nil,
access_type: access_type(),
- password: String.t() | nil
+ password: String.t() | nil,
+ show_source: boolean()
}
@type access_type :: :public | :protected
@@ -18,6 +19,7 @@ defmodule Livebook.Notebook.AppSettings do
field :slug, :string
field :access_type, Ecto.Enum, values: [:public, :protected]
field :password, :string
+ field :show_source, :boolean
end
@doc """
@@ -25,7 +27,12 @@ defmodule Livebook.Notebook.AppSettings do
"""
@spec new() :: t()
def new() do
- %__MODULE__{slug: nil, access_type: :protected, password: generate_password()}
+ %__MODULE__{
+ slug: nil,
+ access_type: :protected,
+ password: generate_password(),
+ show_source: false
+ }
end
defp generate_password() do
@@ -51,8 +58,8 @@ defmodule Livebook.Notebook.AppSettings do
defp changeset(settings, attrs) do
settings
- |> cast(attrs, [:slug, :access_type])
- |> validate_required([:slug, :access_type])
+ |> cast(attrs, [:slug, :access_type, :show_source])
+ |> validate_required([:slug, :access_type, :show_source])
|> validate_format(:slug, ~r/^[a-zA-Z0-9-]+$/,
message: "slug can only contain alphanumeric characters and dashes"
)
diff --git a/lib/livebook_web/live/app_live.ex b/lib/livebook_web/live/app_live.ex
index 3f6d1b273..a2b493219 100644
--- a/lib/livebook_web/live/app_live.ex
+++ b/lib/livebook_web/live/app_live.ex
@@ -55,55 +55,90 @@ defmodule LivebookWeb.AppLive do
@impl true
def render(assigns) when assigns.app_authenticated? do
~H"""
-
+ This app is built from the following notebook source: +
+