Skip to content

Commit 2d0a924

Browse files
committed
use normal entrypoints into base's display pipeline
Base and SparseArrays had some funky action-at-a-distance stuff going on, this fully disentangles them. this also makes SparseArrays a little smarter about when to swap to braille, and actually uses the whole screen instead of just the left half. it's also theoretically doing less work now, but it's just a printing function so whatever. width of displayed zeros also doesn't depend on the type anymore, so that error goes away; added in a warning to replace it.
1 parent 751387e commit 2d0a924

1 file changed

Lines changed: 56 additions & 10 deletions

File tree

src/sparsematrix.jl

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,7 @@ function Base.isstored(A::AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}, i::Intege
334334
return false
335335
end
336336

337-
Base.replace_in_print_matrix(A::AbstractSparseMatrixCSCInclAdjointAndTranspose, i::Integer, j::Integer, s::AbstractString) =
338-
Base.isstored(A, i, j) ? s : Base.replace_with_centered_mark(s)
339-
340-
function Base.array_summary(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose, dims::Tuple{Vararg{Base.OneTo}})
337+
function Base.summary(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose)
341338
_checkbuffers(S)
342339

343340
xnnz = nnz(S)
@@ -347,12 +344,23 @@ function Base.array_summary(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTran
347344
nothing
348345
end
349346

350-
# called by `show(io, MIME("text/plain"), ::AbstractSparseMatrixCSCInclAdjointAndTranspose)`
351-
function Base.print_array(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose)
352-
if max(size(S)...) < 16
353-
Base.print_matrix(io, S)
354-
else
347+
using Base: show_circular
348+
function Base.show(io::IO, ::MIME"text/plain", S::AbstractSparseMatrixCSCInclAdjointAndTranspose)
349+
isempty(S) && get(io, :compact, false) && return show(io, S)
350+
summary(io, S)
351+
isempty(S) && return
352+
353+
screen = displaysize(io)
354+
get(io, :limit, false) && screen[1] <= 4 && return print(io, ": …")
355+
println(io, ":")
356+
357+
show_circular(io, S) && return
358+
io = IOContext(io, :compact=>true, :typeinfo=>eltype(S), :SHOWN_SET=>S)
359+
360+
if (screen[1] < size(S, 1) + 4) | (screen[2] < 3size(S, 2))
355361
_show_with_braille_patterns(io, S)
362+
else
363+
_show_with_dotted_zeros(io, S)
356364
end
357365
end
358366

@@ -399,13 +407,19 @@ end
399407

400408
const brailleBlocks = UInt16['', '', '', '', '', '', '', '']
401409
function _show_with_braille_patterns(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose)
410+
try
411+
zero(eltype(S))
412+
catch
413+
printstyled(io, "WARNING: could not find generic zero for given elements. expect errors and wrong results\n", color=:red)
414+
end
415+
402416
m, n = size(S)
403417
(m == 0 || n == 0) && return show(io, MIME("text/plain"), S)
404418

405419
# The maximal number of characters we allow to display the matrix
406420
local maxHeight::Int, maxWidth::Int
407421
maxHeight = displaysize(io)[1] - 4 # -4 from [Prompt, header, newline after elements, new prompt]
408-
maxWidth = displaysize(io)[2] ÷ 2
422+
maxWidth = displaysize(io)[2] - 2 # -2 from brackets
409423

410424
# In the process of generating the braille pattern to display the nonzero
411425
# structure of `S`, we need to be able to scale the matrix `S` to a
@@ -489,6 +503,38 @@ function _show_with_braille_patterns(io::IO, S::AbstractSparseMatrixCSCInclAdjoi
489503
foreach(c -> print(io, Char(c)), @view brailleGrid[1:end-1])
490504
end
491505

506+
using Base: alignment
507+
function _show_with_dotted_zeros(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose)
508+
rows, cols, vals = rowvals(parent(S)), ColumnIndices(parent(S)), nonzeros(parent(S))
509+
(S isa Adjoint) | (S isa Transpose) && ((rows, cols) = (cols, rows))
510+
511+
align = [alignment(io, val) for val in vals]
512+
colwidths = [max.((0, 0), align[findall(==(col), cols)]...) for col in axes(S,2)]
513+
displaysize(io)[2] < sum(sum.(colwidths) .+ 2) && return _show_with_braille_patterns(io, S)
514+
515+
try
516+
zero(eltype(S))
517+
catch
518+
printstyled(io, "WARNING: could not find generic zero for given elements. expect errors and wrong results\n", color=:red)
519+
end
520+
521+
for row in axes(S,1)
522+
for col in axes(S,2)
523+
index = findall(==(col), cols)
524+
index = index[findall(==(row), rows[index])]
525+
l, r = colwidths[col]
526+
if isempty(index) # no value here, print an aligned dot
527+
l, r = cld(l+r-1, 2) + 1, div(l+r-1, 2) + 1
528+
print(io, " "^l * "" * (col==axes(S,2)[end] ? "" : " "^r))
529+
else
530+
l, r = (l+1, r+1) .- align[index][]
531+
print(io, " "^l, vals[index][], (col==axes(S,2)[end] ? "" : " "^r))
532+
end
533+
end
534+
row == axes(S,1)[end] || println(io)
535+
end
536+
end
537+
492538
for QT in (:LinAlgLeftQs, :LQPackedQ)
493539
@eval (*)(Q::$QT, B::AbstractSparseMatrixCSC) = Q * Matrix(B)
494540
@eval (*)(Q::$QT, B::AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}) = Q * copy(B)

0 commit comments

Comments
 (0)