// Copyright (C) 2014 Josh Ventura // Code is part of LateralGM and is released under the terms of // the GNU General Public License as published by the Free Software Foundation; // version 3 of the license, or any later version. private static final Pattern newline = Pattern.compile("\r\n|\r|\n"); public static LineMatch[] getMatchingLines(String code, Pattern content) { List res = new ArrayList<>(); Matcher m = content.matcher(code), nl = newline.matcher(code); int lineNum = 1, lineAt = 0, lastEnd = -1; LineMatch lastMatch = null; while (m.find()) { nl.region(lineAt, m.start()); int firstSkippedLineAt = lineAt; if (nl.find()) { firstSkippedLineAt = nl.start(); lineAt = nl.end(); ++lineNum; while (nl.find()) { ++lineNum; lineAt = nl.end(); } } if (lastMatch != null) { // We have to add the rest of the line to the old match, either way. // And if we're matching on the same line, we add that match, too. if (lineNum == lastMatch.lineNum) { lastMatch.matchedText.add(new MatchBlock(code.substring(lastEnd, m.start()), false)); lastMatch.matchedText.add(new MatchBlock(code.substring(m.start(), m.end()), true)); } else { lastMatch.matchedText.add( new MatchBlock(code.substring(lastEnd, firstSkippedLineAt), false)); } } if (lastMatch == null || lineNum != lastMatch.lineNum) { lastMatch = new LineMatch(); lastMatch.lineNum = lineNum; if (m.start() > lineAt) { lastMatch.matchedText.add(new MatchBlock(code.substring(lineAt, m.start()), false)); } lastMatch.matchedText.add(new MatchBlock(code.substring(m.start(), m.end()), false)); res.add(lastMatch); } lastEnd = m.end(); } if (lastMatch != null) { nl.region(lastEnd, code.length()); int indTo = (nl.find())? nl.start() : code.length(); lastMatch.matchedText.add(new MatchBlock(code.substring(lastEnd, indTo), false)); } return res.toArray(new LineMatch[] {}); }