Show More
@@ -20,12 +20,12 b'' | |||
|
20 | 20 | |
|
21 | 21 | import logging |
|
22 | 22 | import difflib |
|
23 | import string | |
|
24 | 23 | from itertools import groupby |
|
25 | 24 | |
|
26 | 25 | from pygments import lex |
|
27 | 26 | from pygments.formatters.html import _get_ttype_class as pygment_token_class |
|
28 | 27 | from pygments.lexers.special import TextLexer, Token |
|
28 | from pygments.lexers import get_lexer_by_name | |
|
29 | 29 | |
|
30 | 30 | from rhodecode.lib.helpers import ( |
|
31 | 31 | get_lexer_for_filenode, html_escape, get_custom_lexer) |
@@ -34,7 +34,7 b' from rhodecode.lib.vcs.nodes import File' | |||
|
34 | 34 | from rhodecode.lib.vcs.exceptions import VCSError, NodeDoesNotExistError |
|
35 | 35 | from rhodecode.lib.diff_match_patch import diff_match_patch |
|
36 | 36 | from rhodecode.lib.diffs import LimitedDiffContainer, DEL_FILENODE, BIN_FILENODE |
|
37 | from pygments.lexers import get_lexer_by_name | |
|
37 | ||
|
38 | 38 | |
|
39 | 39 | plain_text_lexer = get_lexer_by_name( |
|
40 | 40 | 'text', stripall=False, stripnl=False, ensurenl=False) |
@@ -307,7 +307,7 b' def tokens_diff(old_tokens, new_tokens, ' | |||
|
307 | 307 | |
|
308 | 308 | if use_diff_match_patch: |
|
309 | 309 | dmp = diff_match_patch() |
|
310 | dmp.Diff_EditCost = 11 # TODO: dan: extract this to a setting | |
|
310 | dmp.Diff_EditCost = 11 # TODO: dan: extract this to a setting | |
|
311 | 311 | reps = dmp.diff_main(old_string, new_string) |
|
312 | 312 | dmp.diff_cleanupEfficiency(reps) |
|
313 | 313 | |
@@ -449,7 +449,10 b' class DiffSet(object):' | |||
|
449 | 449 | target_lexer = plain_text_lexer |
|
450 | 450 | |
|
451 | 451 | if not patch['stats']['binary']: |
|
452 | if self.highlight_mode == self.HL_REAL: | |
|
452 | node_hl_mode = self.HL_NONE if patch['chunks'] == [] else None | |
|
453 | hl_mode = node_hl_mode or self.highlight_mode | |
|
454 | ||
|
455 | if hl_mode == self.HL_REAL: | |
|
453 | 456 | if (source_filename and patch['operation'] in ('D', 'M') |
|
454 | 457 | and source_filename not in self.source_nodes): |
|
455 | 458 | self.source_nodes[source_filename] = ( |
@@ -460,7 +463,7 b' class DiffSet(object):' | |||
|
460 | 463 | self.target_nodes[target_filename] = ( |
|
461 | 464 | self.target_node_getter(target_filename)) |
|
462 | 465 | |
|
463 |
elif |
|
|
466 | elif hl_mode == self.HL_FAST: | |
|
464 | 467 | source_lexer = self._get_lexer_for_filename(source_filename) |
|
465 | 468 | target_lexer = self._get_lexer_for_filename(target_filename) |
|
466 | 469 | |
@@ -510,8 +513,8 b' class DiffSet(object):' | |||
|
510 | 513 | 'hunk_ops': None, |
|
511 | 514 | 'diffset': self, |
|
512 | 515 | }) |
|
513 | ||
|
514 |
for hunk in |
|
|
516 | file_chunks = patch['chunks'][1:] | |
|
517 | for hunk in file_chunks: | |
|
515 | 518 | hunkbit = self.parse_hunk(hunk, source_file, target_file) |
|
516 | 519 | hunkbit.source_file_path = source_file_path |
|
517 | 520 | hunkbit.target_file_path = target_file_path |
@@ -519,28 +522,29 b' class DiffSet(object):' | |||
|
519 | 522 | |
|
520 | 523 | # Simulate hunk on OPS type line which doesn't really contain any diff |
|
521 | 524 | # this allows commenting on those |
|
522 | actions = [] | |
|
523 | for op_id, op_text in filediff.patch['stats']['ops'].items(): | |
|
524 | if op_id == DEL_FILENODE: | |
|
525 | actions.append(u'file was deleted') | |
|
526 | elif op_id == BIN_FILENODE: | |
|
527 | actions.append(u'binary diff hidden') | |
|
528 | else: | |
|
529 | actions.append(safe_unicode(op_text)) | |
|
530 | action_line = u'FILE WITHOUT CONTENT: ' + \ | |
|
531 | u', '.join(map(string.upper, actions)) or u'UNDEFINED_ACTION' | |
|
525 | if not file_chunks: | |
|
526 | actions = [] | |
|
527 | for op_id, op_text in filediff.patch['stats']['ops'].items(): | |
|
528 | if op_id == DEL_FILENODE: | |
|
529 | actions.append(u'file was deleted') | |
|
530 | elif op_id == BIN_FILENODE: | |
|
531 | actions.append(u'binary diff hidden') | |
|
532 | else: | |
|
533 | actions.append(safe_unicode(op_text)) | |
|
534 | action_line = u'NO CONTENT: ' + \ | |
|
535 | u', '.join(actions) or u'UNDEFINED_ACTION' | |
|
532 | 536 | |
|
533 | hunk_ops = {'source_length': 0, 'source_start': 0, | |
|
534 | 'lines': [ | |
|
535 | {'new_lineno': 0, 'old_lineno': 1, | |
|
536 | 'action': 'unmod', 'line': action_line} | |
|
537 | ], | |
|
538 | 'section_header': u'', 'target_start': 1, 'target_length': 1} | |
|
537 | hunk_ops = {'source_length': 0, 'source_start': 0, | |
|
538 | 'lines': [ | |
|
539 | {'new_lineno': 0, 'old_lineno': 1, | |
|
540 | 'action': 'unmod-no-hl', 'line': action_line} | |
|
541 | ], | |
|
542 | 'section_header': u'', 'target_start': 1, 'target_length': 1} | |
|
539 | 543 | |
|
540 | hunkbit = self.parse_hunk(hunk_ops, source_file, target_file) | |
|
541 | hunkbit.source_file_path = source_file_path | |
|
542 | hunkbit.target_file_path = target_file_path | |
|
543 | filediff.hunk_ops = hunkbit | |
|
544 | hunkbit = self.parse_hunk(hunk_ops, source_file, target_file) | |
|
545 | hunkbit.source_file_path = source_file_path | |
|
546 | hunkbit.target_file_path = target_file_path | |
|
547 | filediff.hunk_ops = hunkbit | |
|
544 | 548 | return filediff |
|
545 | 549 | |
|
546 | 550 | def parse_hunk(self, hunk, source_file, target_file): |
@@ -555,10 +559,10 b' class DiffSet(object):' | |||
|
555 | 559 | before, after = [], [] |
|
556 | 560 | |
|
557 | 561 | for line in hunk['lines']: |
|
558 | ||
|
559 |
|
|
|
562 | if line['action'] in ['unmod', 'unmod-no-hl']: | |
|
563 | no_hl = line['action'] == 'unmod-no-hl' | |
|
560 | 564 | result.lines.extend( |
|
561 | self.parse_lines(before, after, source_file, target_file)) | |
|
565 | self.parse_lines(before, after, source_file, target_file, no_hl=no_hl)) | |
|
562 | 566 | after.append(line) |
|
563 | 567 | before.append(line) |
|
564 | 568 | elif line['action'] == 'add': |
@@ -570,14 +574,18 b' class DiffSet(object):' | |||
|
570 | 574 | elif line['action'] == 'new-no-nl': |
|
571 | 575 | after.append(line) |
|
572 | 576 | |
|
577 | all_actions = [x['action'] for x in after] + [x['action'] for x in before] | |
|
578 | no_hl = {x for x in all_actions} == {'unmod-no-hl'} | |
|
573 | 579 | result.lines.extend( |
|
574 | self.parse_lines(before, after, source_file, target_file)) | |
|
580 | self.parse_lines(before, after, source_file, target_file, no_hl=no_hl)) | |
|
581 | # NOTE(marcink): we must keep list() call here so we can cache the result... | |
|
575 | 582 | result.unified = list(self.as_unified(result.lines)) |
|
576 | 583 | result.sideside = result.lines |
|
577 | 584 | |
|
578 | 585 | return result |
|
579 | 586 | |
|
580 |
def parse_lines(self, before_lines, after_lines, source_file, target_file |
|
|
587 | def parse_lines(self, before_lines, after_lines, source_file, target_file, | |
|
588 | no_hl=False): | |
|
581 | 589 | # TODO: dan: investigate doing the diff comparison and fast highlighting |
|
582 | 590 | # on the entire before and after buffered block lines rather than by |
|
583 | 591 | # line, this means we can get better 'fast' highlighting if the context |
@@ -621,9 +629,8 b' class DiffSet(object):' | |||
|
621 | 629 | before_tokens = [('nonl', before['line'])] |
|
622 | 630 | else: |
|
623 | 631 | before_tokens = self.get_line_tokens( |
|
624 | line_text=before['line'], | |
|
625 | line_number=before['old_lineno'], | |
|
626 | file=source_file) | |
|
632 | line_text=before['line'], line_number=before['old_lineno'], | |
|
633 | input_file=source_file, no_hl=no_hl) | |
|
627 | 634 | original.lineno = before['old_lineno'] |
|
628 | 635 | original.content = before['line'] |
|
629 | 636 | original.action = self.action_to_op(before['action']) |
@@ -637,13 +644,12 b' class DiffSet(object):' | |||
|
637 | 644 | else: |
|
638 | 645 | after_tokens = self.get_line_tokens( |
|
639 | 646 | line_text=after['line'], line_number=after['new_lineno'], |
|
640 | file=target_file) | |
|
647 | input_file=target_file, no_hl=no_hl) | |
|
641 | 648 | modified.lineno = after['new_lineno'] |
|
642 | 649 | modified.content = after['line'] |
|
643 | 650 | modified.action = self.action_to_op(after['action']) |
|
644 | 651 | |
|
645 | modified.get_comment_args = ( | |
|
646 | target_file, 'n', after['new_lineno']) | |
|
652 | modified.get_comment_args = (target_file, 'n', after['new_lineno']) | |
|
647 | 653 | |
|
648 | 654 | # diff the lines |
|
649 | 655 | if before_tokens and after_tokens: |
@@ -672,24 +678,25 b' class DiffSet(object):' | |||
|
672 | 678 | |
|
673 | 679 | return lines |
|
674 | 680 | |
|
675 | def get_line_tokens(self, line_text, line_number, file=None): | |
|
681 | def get_line_tokens(self, line_text, line_number, input_file=None, no_hl=False): | |
|
676 | 682 | filenode = None |
|
677 | 683 | filename = None |
|
678 | 684 | |
|
679 | if isinstance(file, basestring): | |
|
680 | filename = file | |
|
681 | elif isinstance(file, FileNode): | |
|
682 | filenode = file | |
|
683 | filename = file.unicode_path | |
|
685 | if isinstance(input_file, basestring): | |
|
686 | filename = input_file | |
|
687 | elif isinstance(input_file, FileNode): | |
|
688 | filenode = input_file | |
|
689 | filename = input_file.unicode_path | |
|
684 | 690 | |
|
685 | if self.highlight_mode == self.HL_REAL and filenode: | |
|
691 | hl_mode = self.HL_NONE if no_hl else self.highlight_mode | |
|
692 | if hl_mode == self.HL_REAL and filenode: | |
|
686 | 693 | lexer = self._get_lexer_for_filename(filename) |
|
687 | file_size_allowed = file.size < self.max_file_size_limit | |
|
694 | file_size_allowed = input_file.size < self.max_file_size_limit | |
|
688 | 695 | if line_number and file_size_allowed: |
|
689 | 696 | return self.get_tokenized_filenode_line( |
|
690 | file, line_number, lexer) | |
|
697 | input_file, line_number, lexer) | |
|
691 | 698 | |
|
692 |
if |
|
|
699 | if hl_mode in (self.HL_REAL, self.HL_FAST) and filename: | |
|
693 | 700 | lexer = self._get_lexer_for_filename(filename) |
|
694 | 701 | return list(tokenize_string(line_text, lexer)) |
|
695 | 702 | |
@@ -707,6 +714,7 b' class DiffSet(object):' | |||
|
707 | 714 | 'add': '+', |
|
708 | 715 | 'del': '-', |
|
709 | 716 | 'unmod': ' ', |
|
717 | 'unmod-no-hl': ' ', | |
|
710 | 718 | 'old-no-nl': ' ', |
|
711 | 719 | 'new-no-nl': ' ', |
|
712 | 720 | }.get(action, action) |
@@ -1136,7 +1136,7 b' class DiffLimitExceeded(Exception):' | |||
|
1136 | 1136 | |
|
1137 | 1137 | # NOTE(marcink): if diffs.mako change, probably this |
|
1138 | 1138 | # needs a bump to next version |
|
1139 |
CURRENT_DIFF_VERSION = 'v |
|
|
1139 | CURRENT_DIFF_VERSION = 'v2' | |
|
1140 | 1140 | |
|
1141 | 1141 | |
|
1142 | 1142 | def _cleanup_cache_file(cached_diff_file): |
General Comments 0
You need to be logged in to leave comments.
Login now