Skip to content

Commit

Permalink
πŸ‘€ Sync code folds
Browse files Browse the repository at this point in the history
  • Loading branch information
fonsp committed Apr 12, 2020
1 parent f97ace4 commit 81ef356
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name = "Pluto"
uuid = "c3e4b0f8-55cb-11ea-2926-15256bba5781"
license = "MIT"
authors = ["Fons van der Plas <[email protected]>", "MikoΕ‚aj Bochenski <[email protected]>"]
version = "0.6.0"
version = "0.6.1"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Expand Down
38 changes: 26 additions & 12 deletions assets/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,21 +281,18 @@ document.addEventListener("DOMContentLoaded", () => {
// EVENT LISTENERS FOR CLICKY THINGS

newCellNode.querySelector("celloutput").onclick = (e) => {
// Do not fold if the click event was fired because the user selects text in the output.
if (window.getSelection().isCollapsed) {
// Do not fold if a link was clicked.
var newFolded = newCellNode.classList.contains("code-folded")
if (!newCellNode.querySelector("celloutput").innerHTML || newCellNode.querySelector("celloutput").innerHTML === "<pre><code></code></pre>") {
// You may not fold code if the output is empty (it would be confusing)
newFolded = false
} else if (window.getSelection().isCollapsed) {
// Do not fold if the click event was fired because the user selects text in the output.
if (e.target.tagName != "A") {
newCellNode.classList.toggle("code-folded")
// Force redraw:
if (!newCellNode.classList.contains("code-folded")) {
editor.refresh()
}
// Do not fold if a link was clicked.
newFolded = !newFolded
}
}
// You may not fold code if the output is empty (it would be confusing)
if (!newCellNode.querySelector("celloutput").innerHTML || newCellNode.querySelector("celloutput").innerHTML === "<pre><code></code></pre>") {
newCellNode.classList.remove("code-folded")
}
requestCodeFoldRemoteCell(uuid, newFolded)
}

newCellNode.querySelector(".addcell.before").onclick = (e) => {
Expand All @@ -322,6 +319,16 @@ document.addEventListener("DOMContentLoaded", () => {
return newCellNode
}

function foldLocalCell(cellNode, newFolded) {
if(newFolded) {
cellNode.classList.add("code-folded")
} else {
cellNode.classList.remove("code-folded")
// Force redraw:
editor.refresh()
}
}

function deleteLocalCell(cellNode) {
// TODO: event listeners? gc?
uuid = cellNode.id
Expand Down Expand Up @@ -404,6 +411,10 @@ document.addEventListener("DOMContentLoaded", () => {
client.send("deletecell", {}, uuid)
}

function requestCodeFoldRemoteCell(uuid, newFolded) {
client.send("foldcell", { folded: newFolded }, uuid)
}


/* SERVER CONNECTION */

Expand Down Expand Up @@ -434,6 +445,9 @@ document.addEventListener("DOMContentLoaded", () => {
// TODO: catch exception
window.localCells[update.cellID].classList.add("running")
break
case "cell_folded":
foldLocalCell(window.localCells[update.cellID], message.folded)
break
case "notebook_list":
// TODO: catch exception
updateRemoteNotebooks(message.notebooks)
Expand Down
7 changes: 5 additions & 2 deletions src/notebookserver/Cell.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ mutable struct Cell
"because Cells can be reordered, they get a UUID. The JavaScript frontend indexes cells using the UUID."
uuid::UUID
code::String
parsedcode::Any

output_repr::Union{String, Nothing}
error_repr::Union{String, Nothing}
repr_mime::MIME
runtime::Union{Missing,UInt64}
code_folded::Bool

parsedcode::Any
symstate::SymbolsState
module_usings::Set{Expr}
end

Cell(uuid, code) = Cell(uuid, code, nothing, nothing, nothing, MIME("text/plain"), missing, SymbolsState(), Set{Expr}())
Cell(uuid, code) = Cell(uuid, code, nothing, nothing, MIME("text/plain"), missing, false, nothing, SymbolsState(), Set{Expr}())
Cell(code) = Cell(uuid1(), code)
5 changes: 5 additions & 0 deletions src/notebookserver/Client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ function clientupdate_cell_running(notebook::Notebook, cell::Cell; initiator::Un
Dict(), notebook, cell, initiator)
end

function clientupdate_cell_folded(notebook::Notebook, cell::Cell, folded::Bool; initiator::Union{Initiator,Missing}=missing)
return UpdateMessage(:cell_folded,
Dict(:folded => folded), notebook, cell, initiator)
end

function clientupdate_notebook_list(notebooks; initiator::Union{Initiator,Missing}=missing)

short_paths = Dict()
Expand Down
21 changes: 13 additions & 8 deletions src/notebookserver/Notebook.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ function selectcell_byuuid(notebook::Notebook, uuid::UUID)::Union{Cell,Nothing}
end

# We use a creative delimiter to avoid accidental use in code
_uuid_delimiter = "# ╔═║ "
_order_delimited = "# β—‹ "
_cell_appendix = "\n\n"
const _uuid_delimiter = "# ╔═║ "
const _order_delimiter = "# β—‹ "
const _order_delimiter_folded = "# c "
const _cell_appendix = "\n\n"

emptynotebook(path) = Notebook(path, [Cell("")])
emptynotebook() = emptynotebook(tempname() * ".jl")
Expand Down Expand Up @@ -87,7 +88,8 @@ function save_notebook(io, notebook::Notebook)

write(io, _uuid_delimiter * "Cell order:" * "\n")
for c in notebook.cells
write(io, _order_delimited * string(c.uuid) * "\n")
delim = c.code_folded ? _order_delimiter_folded : _order_delimiter
write(io, delim * string(c.uuid) * "\n")
end
end

Expand Down Expand Up @@ -137,13 +139,16 @@ function load_notebook_nobackup(io, path)
ordered_cells = Cell[]
while !eof(io)
uuid_str = String(readline(io))
if startswith(uuid_str, _order_delimited)
o, c = startswith(uuid_str, _order_delimiter), startswith(uuid_str, _order_delimiter_folded)
if o || c
uuid = let
# Because we support Unicode, this is not just `length(_order_delimited) + 1`.
uuid_index = ncodeunits(_order_delimited) + 1
# Because we support Unicode, this is not just `length(_order_delimiter) + 1`.
uuid_index = ncodeunits(_order_delimiter) + 1
UUID(uuid_str[uuid_index:end])
end
push!(ordered_cells, collected_cells[uuid])
next_cell = collected_cells[uuid]
next_cell.code_folded = c
push!(ordered_cells, next_cell)
end
end

Expand Down
8 changes: 8 additions & 0 deletions src/webserver/Dynamic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,14 @@ responses[:changecell] = (body, notebook::Notebook, cell::Cell; initiator::Union
run_reactive_async!(notebook, cell)
end

responses[:foldcell] = (body, notebook::Notebook, cell::Cell; initiator::Union{Initiator, Missing}=missing) -> begin
newfolded = body["folded"]
cell.code_folded = newfolded
save_notebook(notebook)

putnotebookupdates!(notebook, clientupdate_cell_folded(notebook, cell, newfolded, initiator=initiator))
end

responses[:run] = (body, notebook::Notebook, cell::Cell; initiator::Union{Initiator, Missing}=missing) -> begin
run_reactive_async!(notebook, cell)
end
Expand Down

2 comments on commit 81ef356

@fonsp
Copy link
Owner Author

@fonsp fonsp commented on 81ef356 Apr 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/12832

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.6.1 -m "<description of version>" 81ef356dfc9dd233be588ad408b0a1c4e30e23c0
git push origin v0.6.1

Please sign in to comment.