highlight-diffpatch/src/main.cpp

87 lines
2.8 KiB
C++

/* This file is part of highlight-diffpatch.
* Copyright © 2022 tastytea <tastytea@tastytea.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <iostream>
#include <string>
#include <string_view>
// Returns string with removed ANSI color codes
std::string remove_colors(const std::string &text)
{
auto newtext{text};
size_t pos{0};
while ((pos = newtext.find("\x1b[")) != std::string::npos)
{
const auto nchars{newtext.find('m', pos) + 1 - pos};
newtext.replace(pos, nchars, "");
}
return newtext;
}
// Returns the position of the 2nd + or -
size_t get_start_pos(const std::string &line)
{
auto pos{std::min(line.find('+'), line.find('-')) + 1};
pos = std::min(line.find('+', pos), line.find('-', pos));
return pos;
}
int main()
{
static constexpr std::string_view red{"\x1b[91m"};
static constexpr std::string_view green{"\x1b[92m"};
static constexpr std::string_view reset{"\x1b[m"};
std::string line;
while (std::getline(std::cin, line))
{
const auto line_nc{remove_colors(line)};
// Only look at long enough lines starting with + or -
if (line_nc.length() >= 2 && (line_nc[0] == '+' || line_nc[0] == '-'))
{
// Don't color +++ and --- lines
if (line_nc.length() < 3
|| (line_nc[2] != '+' && line_nc[2] != '-'))
{
const auto color{[&line_nc]() -> std::string_view
{
if (line_nc[1] == '+')
{
return green;
}
if (line_nc[1] == '-')
{
return red;
}
return {};
}()};
if (!color.empty())
{
const auto pos{get_start_pos(line)};
std::cout << line.substr(0, pos) << color
<< line.substr(pos) << reset << '\n';
continue;
}
}
}
std::cout << line << '\n';
}
}