Handle multiline results on the UI
MODIFY
lib/project/results-model.js
lib/project/results-model.js
@@ -5,16 +5,57 @@ const escapeHelper = require('../escape-helper')
class Result {
static create (result) {
if (result && result.matches && result.matches.length) {
- const matches = result.matches.map(m =>
- ({
- matchText: m.matchText,
- lineText: m.lineText,
+ const matches = []
+
+ for (const m of result.matches) {
+ const range = Range.fromObject(m.range)
+ const matchSplit = m.matchText.split('\n')
+ const linesSplit = m.lineText.split('\n')
+
+ // If the result spans across multiple lines, process each of
+ // them separately by creating separate `matches` objects for
+ // each line on the match.
+ for (let row = range.start.row; row <= range.end.row; row++) {
+ const lineText = linesSplit[row - range.start.row]
+ const matchText = matchSplit[row - range.start.row]
+
+ // When receiving multiline results from opened buffers, only
+ // the first result line is provided on the `lineText` property.
+ // This makes it impossible to properly render the part of the result
+ // that's part of other lines.
+ // In order to prevent an error we just need to ignore these parts.
+ if (lineText === undefined || matchText === undefined) {
+ continue
+ }
+
+ // Adapt the range column number based on which line we're at:
+ // - the first line of a multiline result will always start at the range start
+ // and will end at the end of the line.
+ // - middle lines will start at 0 and end at the end of the line
+ // - last line will start at 0 and end at the range end.
+ const startColumn = row === range.start.row ? range.start.column : 0
+ const endColumn = row === range.end.row ? range.end.column : lineText.length
+
+ matches.push({
+ matchText,
+ lineText,
lineTextOffset: m.lineTextOffset,
- range: Range.fromObject(m.range),
+ range: {
+ start: {
+ row,
+ column: startColumn
+ },
+ end: {
+ row,
+ column: endColumn
+ }
+ },
leadingContextLines: m.leadingContextLines,
trailingContextLines: m.trailingContextLines
})
- )
+ }
+ }
+
return new Result({filePath: result.filePath, matches})
} else {
return null

Handle multiline results on the UI