From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 898532141A for ; Fri, 1 Feb 2019 08:55:09 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 2/4] viewdiff: diffstat links to diff anchors Date: Fri, 1 Feb 2019 08:55:06 +0000 Message-Id: <20190201085508.24003-3-e@80x24.org> In-Reply-To: <20190201085508.24003-1-e@80x24.org> References: <20190201085508.24003-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: This can be helpful for reviewing larger patches which span across several files on the permalink (/$MESSAGE_ID/) HTML page. More work will be needed to get this working for the /T/ and /t/ pages which show multiple emails, as the filename-based anchors will conflict at the moment. --- lib/PublicInbox/ViewDiff.pm | 51 +++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/lib/PublicInbox/ViewDiff.pm b/lib/PublicInbox/ViewDiff.pm index a804568..38cb5a1 100644 --- a/lib/PublicInbox/ViewDiff.pm +++ b/lib/PublicInbox/ViewDiff.pm @@ -12,11 +12,11 @@ use warnings; use base qw(Exporter); our @EXPORT_OK = qw(flush_diff); use URI::Escape qw(uri_escape_utf8); -use PublicInbox::Hval qw(ascii_html); +use PublicInbox::Hval qw(ascii_html to_attr from_attr); use PublicInbox::Git qw(git_unquote); sub DSTATE_INIT () { 0 } -sub DSTATE_STAT () { 1 } # TODO +sub DSTATE_STAT () { 1 } sub DSTATE_HEAD () { 2 } # /^diff --git /, /^index /, /^--- /, /^\+\+\+ / sub DSTATE_CTX () { 3 } # /^ / sub DSTATE_ADD () { 4 } # /^\+/ @@ -75,14 +75,47 @@ sub to_state ($$$) { $$dst .= qq(); } +sub anchor0 ($$$$$) { + my ($dst, $anchors, $linkify, $fn, $rest) = @_; + if (my $attr = to_attr($fn)) { + $anchors->{$attr} = 1; + $$dst .= " " . + ascii_html($fn) . ''. + to_html($linkify, $rest); + return 1; + } + undef; +} + +sub anchor1 ($$$$$) { + my ($dst, $anchors, $linkify, $pb, $s) = @_; + my $attr = to_attr($pb) or return; + my $line = to_html($linkify, $s); + + if (delete $anchors->{$attr} && $line =~ s/^diff //) { + $$dst .= "diff ".$line; + return 1; + } + undef +} + sub flush_diff ($$$$) { my ($dst, $spfx, $linkify, $diff) = @_; my $state = DSTATE_INIT; my $dctx = { Q => '' }; # {}, keys: oid_a, oid_b, path_a, path_b + my $anchors = {}; # attr => filename foreach my $s (@$diff) { - if ($s =~ /^ /) { - if ($state2class[$state]) { + if ($s =~ /^---$/) { + to_state($dst, $state, DSTATE_STAT); + $$dst .= "" . $s . ''; + } elsif ($s =~ /^ /) { + # works for common cases, but not weird/long filenames + if ($state == DSTATE_STAT && + $s =~ /^ (\S+)(\s+\|.*\z)/s) { + anchor0($dst, $anchors, $linkify, $1, $2) + and next; + } elsif ($state2class[$state]) { to_state($dst, $state, DSTATE_CTX); } $$dst .= to_html($linkify, $s); @@ -103,6 +136,8 @@ sub flush_diff ($$$$) { $dctx->{Q} .= "&a=".uri_escape_utf8($pa, UNSAFE); } + anchor1($dst, $anchors, $linkify, $pb, $s) + and next; } $$dst .= to_html($linkify, $s); } elsif ($s =~ s/^(index $OID_NULL\.\.)($OID_BLOB)\b//o) { @@ -127,16 +162,16 @@ sub flush_diff ($$$$) { } elsif ($s =~ m!^--- $PATH_A! || $s =~ m!^\+{3} $PATH_B!) { # color only (no oid link) - $state == DSTATE_INIT and + $state <= DSTATE_STAT and to_state($dst, $state, DSTATE_HEAD); $$dst .= to_html($linkify, $s); } elsif ($s =~ /^\+/) { - if ($state != DSTATE_ADD && $state != DSTATE_INIT) { + if ($state != DSTATE_ADD && $state > DSTATE_STAT) { to_state($dst, $state, DSTATE_ADD); } $$dst .= to_html($linkify, $s); } elsif ($s =~ /^-/) { - if ($state != DSTATE_DEL && $state != DSTATE_INIT) { + if ($state != DSTATE_DEL && $state > DSTATE_STAT) { to_state($dst, $state, DSTATE_DEL); } $$dst .= to_html($linkify, $s); @@ -148,7 +183,7 @@ sub flush_diff ($$$$) { $s =~ /^(?:dis)?similarity index /) { $$dst .= to_html($linkify, $s); } else { - $state == DSTATE_INIT or + $state <= DSTATE_STAT or to_state($dst, $state, DSTATE_INIT); $$dst .= to_html($linkify, $s); } -- EW