Skip to content

Commit 1afabba

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 1afabba

1 file changed

Lines changed: 56 additions & 7 deletions

File tree

src/sparsematrix.jl

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ end
337337
Base.replace_in_print_matrix(A::AbstractSparseMatrixCSCInclAdjointAndTranspose, i::Integer, j::Integer, s::AbstractString) =
338338
Base.isstored(A, i, j) ? s : Base.replace_with_centered_mark(s)
339339

340-
function Base.array_summary(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose, dims::Tuple{Vararg{Base.OneTo}})
340+
function Base.summary(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose)
341341
_checkbuffers(S)
342342

343343
xnnz = nnz(S)
@@ -347,12 +347,23 @@ function Base.array_summary(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTran
347347
nothing
348348
end
349349

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
350+
using Base: show_circular
351+
function Base.show(io::IO, ::MIME"text/plain", S::AbstractSparseMatrixCSCInclAdjointAndTranspose)
352+
isempty(S) && get(io, :compact, false) && return show(io, S)
353+
summary(io, S)
354+
isempty(S) && return
355+
356+
screen = displaysize(io)
357+
get(io, :limit, false) && screen[1] <= 4 && return print(io, ": …")
358+
println(io, ":")
359+
360+
show_circular(io, S) && return
361+
io = IOContext(io, :compact=>true, :typeinfo=>eltype(S), :SHOWN_SET=>S)
362+
363+
if (screen[1] < size(S, 1) + 4) | (screen[2] < 3size(S, 2))
355364
_show_with_braille_patterns(io, S)
365+
else
366+
_show_with_dotted_zeros(io, S)
356367
end
357368
end
358369

@@ -399,13 +410,19 @@ end
399410

400411
const brailleBlocks = UInt16['', '', '', '', '', '', '', '']
401412
function _show_with_braille_patterns(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose)
413+
try
414+
zero(eltype(S))
415+
catch
416+
printstyled(io, "WARNING: could not find generic zero for given elements. expect errors and wrong results\n", color=:red)
417+
end
418+
402419
m, n = size(S)
403420
(m == 0 || n == 0) && return show(io, MIME("text/plain"), S)
404421

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

410427
# In the process of generating the braille pattern to display the nonzero
411428
# structure of `S`, we need to be able to scale the matrix `S` to a
@@ -489,6 +506,38 @@ function _show_with_braille_patterns(io::IO, S::AbstractSparseMatrixCSCInclAdjoi
489506
foreach(c -> print(io, Char(c)), @view brailleGrid[1:end-1])
490507
end
491508

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

0 commit comments

Comments
 (0)