diffs: don't use highlite on the new ops lines

This commit is contained in:
Marcin Kuzminski 2018-09-24 17:49:14 +02:00
parent 4f428a0e1a
commit 01bb7220b2
3 changed files with 58 additions and 50 deletions

View file

@ -20,12 +20,12 @@
import logging
import difflib
import string
from itertools import groupby
from pygments import lex
from pygments.formatters.html import _get_ttype_class as pygment_token_class
from pygments.lexers.special import TextLexer, Token
from pygments.lexers import get_lexer_by_name
from rhodecode.lib.helpers import (
get_lexer_for_filenode, html_escape, get_custom_lexer)
@ -34,7 +34,7 @@ from rhodecode.lib.vcs.nodes import FileNode
from rhodecode.lib.vcs.exceptions import VCSError, NodeDoesNotExistError
from rhodecode.lib.diff_match_patch import diff_match_patch
from rhodecode.lib.diffs import LimitedDiffContainer, DEL_FILENODE, BIN_FILENODE
from pygments.lexers import get_lexer_by_name
plain_text_lexer = get_lexer_by_name(
'text', stripall=False, stripnl=False, ensurenl=False)
@ -307,7 +307,7 @@ def tokens_diff(old_tokens, new_tokens, use_diff_match_patch=True):
if use_diff_match_patch:
dmp = diff_match_patch()
dmp.Diff_EditCost = 11 # TODO: dan: extract this to a setting
dmp.Diff_EditCost = 11 # TODO: dan: extract this to a setting
reps = dmp.diff_main(old_string, new_string)
dmp.diff_cleanupEfficiency(reps)
@ -449,7 +449,10 @@ class DiffSet(object):
target_lexer = plain_text_lexer
if not patch['stats']['binary']:
if self.highlight_mode == self.HL_REAL:
node_hl_mode = self.HL_NONE if patch['chunks'] == [] else None
hl_mode = node_hl_mode or self.highlight_mode
if hl_mode == self.HL_REAL:
if (source_filename and patch['operation'] in ('D', 'M')
and source_filename not in self.source_nodes):
self.source_nodes[source_filename] = (
@ -460,7 +463,7 @@ class DiffSet(object):
self.target_nodes[target_filename] = (
self.target_node_getter(target_filename))
elif self.highlight_mode == self.HL_FAST:
elif hl_mode == self.HL_FAST:
source_lexer = self._get_lexer_for_filename(source_filename)
target_lexer = self._get_lexer_for_filename(target_filename)
@ -510,8 +513,8 @@ class DiffSet(object):
'hunk_ops': None,
'diffset': self,
})
for hunk in patch['chunks'][1:]:
file_chunks = patch['chunks'][1:]
for hunk in file_chunks:
hunkbit = self.parse_hunk(hunk, source_file, target_file)
hunkbit.source_file_path = source_file_path
hunkbit.target_file_path = target_file_path
@ -519,28 +522,29 @@ class DiffSet(object):
# Simulate hunk on OPS type line which doesn't really contain any diff
# this allows commenting on those
actions = []
for op_id, op_text in filediff.patch['stats']['ops'].items():
if op_id == DEL_FILENODE:
actions.append(u'file was deleted')
elif op_id == BIN_FILENODE:
actions.append(u'binary diff hidden')
else:
actions.append(safe_unicode(op_text))
action_line = u'FILE WITHOUT CONTENT: ' + \
u', '.join(map(string.upper, actions)) or u'UNDEFINED_ACTION'
if not file_chunks:
actions = []
for op_id, op_text in filediff.patch['stats']['ops'].items():
if op_id == DEL_FILENODE:
actions.append(u'file was deleted')
elif op_id == BIN_FILENODE:
actions.append(u'binary diff hidden')
else:
actions.append(safe_unicode(op_text))
action_line = u'NO CONTENT: ' + \
u', '.join(actions) or u'UNDEFINED_ACTION'
hunk_ops = {'source_length': 0, 'source_start': 0,
'lines': [
{'new_lineno': 0, 'old_lineno': 1,
'action': 'unmod', 'line': action_line}
],
'section_header': u'', 'target_start': 1, 'target_length': 1}
hunk_ops = {'source_length': 0, 'source_start': 0,
'lines': [
{'new_lineno': 0, 'old_lineno': 1,
'action': 'unmod-no-hl', 'line': action_line}
],
'section_header': u'', 'target_start': 1, 'target_length': 1}
hunkbit = self.parse_hunk(hunk_ops, source_file, target_file)
hunkbit.source_file_path = source_file_path
hunkbit.target_file_path = target_file_path
filediff.hunk_ops = hunkbit
hunkbit = self.parse_hunk(hunk_ops, source_file, target_file)
hunkbit.source_file_path = source_file_path
hunkbit.target_file_path = target_file_path
filediff.hunk_ops = hunkbit
return filediff
def parse_hunk(self, hunk, source_file, target_file):
@ -555,10 +559,10 @@ class DiffSet(object):
before, after = [], []
for line in hunk['lines']:
if line['action'] == 'unmod':
if line['action'] in ['unmod', 'unmod-no-hl']:
no_hl = line['action'] == 'unmod-no-hl'
result.lines.extend(
self.parse_lines(before, after, source_file, target_file))
self.parse_lines(before, after, source_file, target_file, no_hl=no_hl))
after.append(line)
before.append(line)
elif line['action'] == 'add':
@ -570,14 +574,18 @@ class DiffSet(object):
elif line['action'] == 'new-no-nl':
after.append(line)
all_actions = [x['action'] for x in after] + [x['action'] for x in before]
no_hl = {x for x in all_actions} == {'unmod-no-hl'}
result.lines.extend(
self.parse_lines(before, after, source_file, target_file))
self.parse_lines(before, after, source_file, target_file, no_hl=no_hl))
# NOTE(marcink): we must keep list() call here so we can cache the result...
result.unified = list(self.as_unified(result.lines))
result.sideside = result.lines
return result
def parse_lines(self, before_lines, after_lines, source_file, target_file):
def parse_lines(self, before_lines, after_lines, source_file, target_file,
no_hl=False):
# TODO: dan: investigate doing the diff comparison and fast highlighting
# on the entire before and after buffered block lines rather than by
# line, this means we can get better 'fast' highlighting if the context
@ -621,9 +629,8 @@ class DiffSet(object):
before_tokens = [('nonl', before['line'])]
else:
before_tokens = self.get_line_tokens(
line_text=before['line'],
line_number=before['old_lineno'],
file=source_file)
line_text=before['line'], line_number=before['old_lineno'],
input_file=source_file, no_hl=no_hl)
original.lineno = before['old_lineno']
original.content = before['line']
original.action = self.action_to_op(before['action'])
@ -637,13 +644,12 @@ class DiffSet(object):
else:
after_tokens = self.get_line_tokens(
line_text=after['line'], line_number=after['new_lineno'],
file=target_file)
input_file=target_file, no_hl=no_hl)
modified.lineno = after['new_lineno']
modified.content = after['line']
modified.action = self.action_to_op(after['action'])
modified.get_comment_args = (
target_file, 'n', after['new_lineno'])
modified.get_comment_args = (target_file, 'n', after['new_lineno'])
# diff the lines
if before_tokens and after_tokens:
@ -672,24 +678,25 @@ class DiffSet(object):
return lines
def get_line_tokens(self, line_text, line_number, file=None):
def get_line_tokens(self, line_text, line_number, input_file=None, no_hl=False):
filenode = None
filename = None
if isinstance(file, basestring):
filename = file
elif isinstance(file, FileNode):
filenode = file
filename = file.unicode_path
if isinstance(input_file, basestring):
filename = input_file
elif isinstance(input_file, FileNode):
filenode = input_file
filename = input_file.unicode_path
if self.highlight_mode == self.HL_REAL and filenode:
hl_mode = self.HL_NONE if no_hl else self.highlight_mode
if hl_mode == self.HL_REAL and filenode:
lexer = self._get_lexer_for_filename(filename)
file_size_allowed = file.size < self.max_file_size_limit
file_size_allowed = input_file.size < self.max_file_size_limit
if line_number and file_size_allowed:
return self.get_tokenized_filenode_line(
file, line_number, lexer)
input_file, line_number, lexer)
if self.highlight_mode in (self.HL_REAL, self.HL_FAST) and filename:
if hl_mode in (self.HL_REAL, self.HL_FAST) and filename:
lexer = self._get_lexer_for_filename(filename)
return list(tokenize_string(line_text, lexer))
@ -707,6 +714,7 @@ class DiffSet(object):
'add': '+',
'del': '-',
'unmod': ' ',
'unmod-no-hl': ' ',
'old-no-nl': ' ',
'new-no-nl': ' ',
}.get(action, action)

View file

@ -1136,7 +1136,7 @@ class DiffLimitExceeded(Exception):
# NOTE(marcink): if diffs.mako change, probably this
# needs a bump to next version
CURRENT_DIFF_VERSION = 'v1'
CURRENT_DIFF_VERSION = 'v2'
def _cleanup_cache_file(cached_diff_file):

View file

@ -653,7 +653,7 @@ def get_comments_for(diff_type, comments, filename, line_version, line_number):
%if comments_args:
<% comments = get_comments_for('unified', inline_comments, *comments_args) %>
%else:
<% comments = None%>
<% comments = None %>
%endif
% if comments: