diff --git a/src/analysis/Topology.jl b/src/analysis/Topology.jl index eb441f098b..d08ee7d5c0 100644 --- a/src/analysis/Topology.jl +++ b/src/analysis/Topology.jl @@ -58,12 +58,18 @@ function set_unresolved(topology::NotebookTopology, unresolved_cells::Vector{Cel end -function Base.setdiff(topology::NotebookTopology, cells::Vector{Cell}) +""" + exclude_roots(topology::NotebookTopology, roots_to_exclude)::NotebookTopology + +Returns a new topology as if `topology` was created with all code for `roots_to_exclude` +being empty, preserving disabled cells and cell order. +""" +function exclude_roots(topology::NotebookTopology, cells::Vector{Cell}) NotebookTopology( nodes=setdiffkeys(topology.nodes, cells), codes=setdiffkeys(topology.codes, cells), unresolved_cells=ImmutableSet{Cell}(setdiff(topology.unresolved_cells.c, cells); skip_copy=true), - cell_order=ImmutableVector{Cell}(setdiff(topology.cell_order.c, cells); skip_copy=true), - disabled_cells=ImmutableSet{Cell}(setdiff(topology.disabled_cells.c, cells); skip_copy=true), + cell_order=topology.cell_order, + disabled_cells=topology.disabled_cells, ) end diff --git a/src/evaluation/Run.jl b/src/evaluation/Run.jl index 29b87ccf52..e74f0d8c4d 100644 --- a/src/evaluation/Run.jl +++ b/src/evaluation/Run.jl @@ -100,8 +100,8 @@ function run_reactive_core!( cell.queued = false cell.depends_on_disabled_cells = true end - - new_topology = setdiff(new_topology, indirectly_deactivated) + + new_topology = exclude_roots(new_topology, indirectly_deactivated) # save the old topological order - we'll delete variables assigned from its # and re-evalutate its cells unless the cells have already run previously in the reactive run diff --git a/src/notebook/saving and loading.jl b/src/notebook/saving and loading.jl index b081d8c749..1dd696e72e 100644 --- a/src/notebook/saving and loading.jl +++ b/src/notebook/saving and loading.jl @@ -56,10 +56,16 @@ function save_notebook(io::IO, notebook::Notebook) println(io) cells_ordered = collect(topological_order(notebook)) - + # TODO: add test for this case + if length(cells_ordered) != length(notebook.cells) + cells = notebook.cells + updated_topo = updated_topology(notebook.topology, notebook, cells) + cells_ordered = collect(topological_order(updated_topo, cells)) + end + for c in cells_ordered println(io, _cell_id_delimiter, string(c.cell_id)) - + let metadata_toml = strip(sprint(TOML.print, get_metadata_no_default(c))) if metadata_toml != "" for line in split(metadata_toml, "\n") @@ -67,7 +73,7 @@ function save_notebook(io::IO, notebook::Notebook) end end end - + if must_be_commented_in_file(c) print(io, _disabled_prefix) print(io, replace(c.code, _cell_id_delimiter => "# ")) diff --git a/test/cell_disabling.jl b/test/cell_disabling.jl index 3c8e8f498b..8865e57f6b 100644 --- a/test/cell_disabling.jl +++ b/test/cell_disabling.jl @@ -345,3 +345,46 @@ end WorkspaceManager.unmake_workspace((🍭, notebook)) end + +@testset "Disabled cells should stay in the topology (#2676)" begin + 🍭 = ServerSession() + notebook = Notebook(Cell.([ + "using Dates", + "b = 2; December", + "b", + ])) + + disabled_cell = notebook.cells[end] + Pluto.set_disabled(disabled_cell, true) + @test is_disabled(disabled_cell) + + old_topo = notebook.topology + @test count(Pluto.is_disabled, notebook.cells) == 1 + order = update_run!(🍭, notebook, notebook.cells) + + # Disabled + @test length(order.input_topology.disabled_cells) == 1 + @test disabled_cell ∈ order.input_topology.disabled_cells + runned_cells = collect(order) + @test length(runned_cells) == 2 + @test disabled_cell ∉ runned_cells + + topo = notebook.topology + @test old_topo !== topo # topology was updated + + order = Pluto.topological_order(notebook) + + @test length(order.input_topology.disabled_cells) == 1 + @test disabled_cell ∈ order.input_topology.disabled_cells + saved_cells = collect(order) + @test length(saved_cells) == length(notebook.cells) + @test issetequal(saved_cells, notebook.cells) + + io = IOBuffer() + Pluto.save_notebook(io, notebook) + seekstart(io) + notebook2 = Pluto.load_notebook_nobackup(io, "mynotebook.jl") + @test length(notebook2.cells) == length(notebook.cells) + + WorkspaceManager.unmake_workspace((🍭, notebook)) +end