Commit d3d8a384 authored by Jonathan L. Verner's avatar Jonathan L. Verner Committed by Igor Kushnir
Browse files

Fix goto source for summary diffs

Previously, the goto source shortcut for summary diffs (e.g. diffs showing
all staged changes) would not work. The reason was that
the view data structure member url contained only the path to the project
root. This commit changes

  1. modifies the vcsDiff api diffLineToSource/Target
     to return relative source paths together with source lines
  2. uses the result together with the project root to compute
     the url to the path in the shortcut handler.
parent 2702258d
Pipeline #97954 passed with stage
in 34 minutes and 25 seconds
......@@ -128,11 +128,11 @@ yadayadayada 10 5
>>>>>>> commit 11
- second deletion 12 3
)diff");
QCOMPARE(conflictDiff.diffLineToSourceLine(8), 2);
QCOMPARE(conflictDiff.diffLineToTargetLine(10), 5);
QCOMPARE(conflictDiff.diffLineToSourceLine(7), -1);
QCOMPARE(conflictDiff.diffLineToSourceLine(9), -1);
QCOMPARE(conflictDiff.diffLineToSourceLine(11), -1);
QCOMPARE(conflictDiff.diffLineToSource(8).line, 2);
QCOMPARE(conflictDiff.diffLineToTarget(10).line, 5);
QCOMPARE(conflictDiff.diffLineToSource(7).line, -1);
QCOMPARE(conflictDiff.diffLineToSource(9).line, -1);
QCOMPARE(conflictDiff.diffLineToSource(11).line, -1);
}
......@@ -141,15 +141,20 @@ void TestVcsDiff::testLineMapping()
VcsDiff diff;
diff.setDiff(sampleDiff);
auto src = QStringLiteral("kdevplatform/vcs/vcsdiff.cpp");
auto tgt = QStringLiteral("kdevplatform/vcs/vcsdiff.h");
QCOMPARE(diff.diffLineToSource(15-1).path, src);
QCOMPARE(diff.diffLineToTarget(147-1).path, tgt);
// We have no way to map the headings
QCOMPARE(diff.diffLineToSourceLine(169-1), -1);
QCOMPARE(diff.diffLineToTargetLine(169-1), -1);
QCOMPARE(diff.diffLineToSource(169-1).line, -1);
QCOMPARE(diff.diffLineToTarget(169-1).line, -1);
QCOMPARE(diff.diffLineToSourceLine(15-1), 42-1);
QCOMPARE(diff.diffLineToTargetLine(15-1), -1);
QCOMPARE(diff.diffLineToSource(15-1).line, 42-1);
QCOMPARE(diff.diffLineToTarget(15-1).line, -1);
QCOMPARE(diff.diffLineToTargetLine(147-1), 180-1);
QCOMPARE(diff.diffLineToSourceLine(147-1), 150-1);
QCOMPARE(diff.diffLineToTarget(147-1).line, 180-1);
QCOMPARE(diff.diffLineToSource(147-1).line, 150-1);
}
......
......@@ -302,9 +302,11 @@ public:
* @param line a 0-based line position in the diff
* @param dest specifies the destination file to map to:
* either SRC (the source file, '-') or TGT (the target file, '+')
* @returns the 0-based line position in the destination file or -1 if no such position exists.
* @returns a @ref VcsDiff::SourceLocation whose path is the (relative to diff root)
* destination file path and line the 0-based line position in the
* destination file or {"", -1} if no such position exists.
*/
int mapDiffLine ( const uint line, const Dest dest ) const
VcsDiff::SourceLocation mapDiffLine ( const uint line, const Dest dest ) const
{
const QLatin1Char skipChar = (dest == SRC) ? QLatin1Char(TGT) : QLatin1Char(SRC);
for(auto h: hunks) {
......@@ -313,7 +315,7 @@ public:
// The line refers to the heading line
if (hunkPos < 0)
return -1;
return {};
// Any lines in the diff hunk which come before line and come from the opposite
// of dest should not be counted (they are not present in the dest)
......@@ -356,21 +358,21 @@ public:
// This works around the fact that inConflict is set even if hunkPos
// ends up hitting a conflict marker
if (CONFLICT_RE->match(ln).hasMatch())
return -1;
return {};
if (ln.startsWith(dest) || ln.startsWith(QLatin1Char(' ')) || ln.isEmpty() || inConflict) {
if (dest == SRC)
// The -1 accounts for the fact that srcStart is 1-based
// but we need to return 0-based line numbers
return h->srcStart-1+hunkPos-skipCount;
return {h->srcFile, static_cast<int>(h->srcStart-1+hunkPos-skipCount)};
else
// The -1 accounts for the fact that srcStart is 1-based
// but we need to return 0-based line numbers
return h->tgtStart-1+hunkPos-skipCount;
} else return -1;
return {h->tgtFile, static_cast<int>(h->tgtStart-1+hunkPos-skipCount)};
} else return {};
}
}
return -1;
return {};
}
};
......@@ -528,12 +530,12 @@ const QVector<VcsDiff::FilePair> VcsDiff::fileNames() const
}
int VcsDiff::diffLineToSourceLine ( const uint line ) const
VcsDiff::SourceLocation VcsDiff::diffLineToSource ( const uint line ) const
{
return d->mapDiffLine(line, VcsDiffPrivate::SRC);
}
int VcsDiff::diffLineToTargetLine ( const uint line ) const
VcsDiff::SourceLocation VcsDiff::diffLineToTarget ( const uint line ) const
{
return d->mapDiffLine(line, VcsDiffPrivate::TGT);
}
......
......@@ -148,21 +148,38 @@ public:
*/
VcsDiff subDiffHunk(const uint line, DiffDirection dir = Normal) const;
/**
* A struct representing a position in a source file.
*
* @note This should eventually be replaced with a @ref KDevelop::DocumentCursor,
* which, however, currently cannot be used in this file.
*/
struct SourceLocation {
/* Path to the source file (may be relative) */
QString path = {};
/* 0-based line number in the source file */
int line = -1;
};
/**
* Maps a line position in the diff to a corresponding line position in the source file.
*
* @param line a 0-based line position in the diff
* @returns the 0-based line position in the source file or -1 if no such position exists.
* @returns a @ref SourceLocation whose path is the target file path (relative to diff root)
* and line the 0-based line position in the target file or {"", -1} if no such
* position exists.
*/
int diffLineToSourceLine (const uint line) const;
SourceLocation diffLineToSource (const uint line) const;
/**
* Maps a line position in the diff to a corresponding line position in the source file.
* Maps a line position in the diff to a corresponding line position in the target file.
*
* @param line a 0-based line position in the diff
* @returns the 0-based line position in the source file or -1 if no such position exists.
* @returns a @ref SourceLocation whose path is the source file path (relative to diff root)
* and line the 0-based line position in the source file or {"", -1} if no such
* position exists.
*/
int diffLineToTargetLine (const uint line) const;
SourceLocation diffLineToTarget (const uint line) const;
/**
* Represents a pair of files which are compared
......
......@@ -404,11 +404,12 @@ void DiffViewsCtrl::gotoSrcLine()
auto last_line = vData.ktDoc->documentEnd().line();
int delta = 0;
while(diffLn - delta >= 1 || diffLn + delta < last_line) {
auto srcLn = diff.diffLineToTargetLine(diffLn-delta);
if ( srcLn < 0 ) srcLn = diff.diffLineToTargetLine(diffLn+delta);
if ( srcLn >= 0 ) {
if (auto* srcDoc = docCtrl->openDocument(vData.url)) {
srcDoc->setCursorPosition(KTextEditor::Cursor(srcLn, diffCol-1));
auto src = diff.diffLineToTarget(diffLn-delta);
if ( src.line < 0 ) src = diff.diffLineToTarget(diffLn+delta);
if ( src.line >= 0 ) {
auto path = KDevelop::Path(vData.project->path(), src.path);
if (auto* srcDoc = docCtrl->openDocument(path.toUrl())) {
srcDoc->setCursorPosition(KTextEditor::Cursor(src.line, diffCol-1));
docCtrl->activateDocument(srcDoc);
}
return;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment