Store the buffer timestamp in line flags options respect it for highlighting
Option content is auto updated to match current buffer, so that line flags are updated according to buffer modifications.
This commit is contained in:
parent
70250fc1e3
commit
4cb74623bb
|
@ -2,7 +2,7 @@ decl str clang_options
|
||||||
|
|
||||||
decl -hidden str clang_tmp_dir
|
decl -hidden str clang_tmp_dir
|
||||||
decl -hidden str-list clang_completions
|
decl -hidden str-list clang_completions
|
||||||
decl -hidden line-flag-list clang_flags
|
decl -hidden line-flags clang_flags
|
||||||
decl -hidden str clang_errors
|
decl -hidden str clang_errors
|
||||||
|
|
||||||
def clang-parse -params 0..1 -docstring "Parse the contents of the current buffer with clang" %{
|
def clang-parse -params 0..1 -docstring "Parse the contents of the current buffer with clang" %{
|
||||||
|
@ -85,7 +85,7 @@ def clang-parse -params 0..1 -docstring "Parse the contents of the current buffe
|
||||||
|
|
||||||
sed -e "s|<stdin>|${kak_bufname}|g" < ${dir}/stderr > ${dir}/fifo
|
sed -e "s|<stdin>|${kak_bufname}|g" < ${dir}/stderr > ${dir}/fifo
|
||||||
|
|
||||||
echo "set 'buffer=${kak_buffile}' clang_flags %{${flags}}
|
echo "set 'buffer=${kak_buffile}' clang_flags %{${kak_timestamp}:${flags}}
|
||||||
set 'buffer=${kak_buffile}' clang_errors '${errors}'" | kak -p ${kak_session}
|
set 'buffer=${kak_buffile}' clang_errors '${errors}'" | kak -p ${kak_session}
|
||||||
) > /dev/null 2>&1 < /dev/null &
|
) > /dev/null 2>&1 < /dev/null &
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ def -allow-override -hidden clang-show-error-info %{ %sh{
|
||||||
} }
|
} }
|
||||||
|
|
||||||
def clang-enable-diagnostics -docstring "Activate automatic diagnostics of the code by clang" %{
|
def clang-enable-diagnostics -docstring "Activate automatic diagnostics of the code by clang" %{
|
||||||
addhl flag_lines default clang_flags
|
addhl flag_lines default clang_flags'
|
||||||
hook window -group clang-diagnostics NormalIdle .* %{ clang-show-error-info }
|
hook window -group clang-diagnostics NormalIdle .* %{ clang-show-error-info }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ hook global WinSetOption filetype=(?!git-status).* %{
|
||||||
rmhl git-status-highlight
|
rmhl git-status-highlight
|
||||||
}
|
}
|
||||||
|
|
||||||
decl line-flag-list git_blame_flags
|
decl line-flags git_blame_flags
|
||||||
decl line-flag-list git_diff_flags
|
decl line-flags git_diff_flags
|
||||||
|
|
||||||
face GitBlame default,magenta
|
face GitBlame default,magenta
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ def -params 1.. \
|
||||||
(
|
(
|
||||||
echo "eval -client '$kak_client' %{
|
echo "eval -client '$kak_client' %{
|
||||||
try %{ addhl flag_lines GitBlame git_blame_flags }
|
try %{ addhl flag_lines GitBlame git_blame_flags }
|
||||||
set buffer=$kak_bufname git_blame_flags ''
|
set buffer=$kak_bufname git_blame_flags '$kak_timestamp'
|
||||||
}" | kak -p ${kak_session}
|
}" | kak -p ${kak_session}
|
||||||
git blame "$@" --incremental ${kak_buffile} | awk -e '
|
git blame "$@" --incremental ${kak_buffile} | awk -e '
|
||||||
function send_flags(text, flag, i) {
|
function send_flags(text, flag, i) {
|
||||||
|
@ -75,7 +75,7 @@ def -params 1.. \
|
||||||
flag=flag ":" line+i "|default|" text
|
flag=flag ":" line+i "|default|" text
|
||||||
}
|
}
|
||||||
cmd = "kak -p " ENVIRON["kak_session"]
|
cmd = "kak -p " ENVIRON["kak_session"]
|
||||||
print "set -add buffer=" ENVIRON["kak_bufname"] " git_blame_flags %{" flag "}" | cmd
|
print "set -add buffer=" ENVIRON["kak_bufname"] " git_blame_flags %{:" flag "}" | cmd
|
||||||
close(cmd)
|
close(cmd)
|
||||||
}
|
}
|
||||||
/^([0-9a-f]{40}) ([0-9]+) ([0-9]+) ([0-9]+)/ {
|
/^([0-9a-f]{40}) ([0-9]+) ([0-9]+) ([0-9]+)/ {
|
||||||
|
@ -97,7 +97,7 @@ def -params 1.. \
|
||||||
git diff -U0 $kak_buffile | awk -e '
|
git diff -U0 $kak_buffile | awk -e '
|
||||||
BEGIN {
|
BEGIN {
|
||||||
line=0
|
line=0
|
||||||
flags="0|red|."
|
flags=ENVIRON["kak_timestamp"]
|
||||||
}
|
}
|
||||||
/^---.*/ {}
|
/^---.*/ {}
|
||||||
/^@@ -[0-9]+(,[0-9]+)? \+[0-9]+(,[0-9]+)? @@.*/ {
|
/^@@ -[0-9]+(,[0-9]+)? \+[0-9]+(,[0-9]+)? @@.*/ {
|
||||||
|
|
|
@ -1104,7 +1104,7 @@ const CommandDesc declare_option_cmd = {
|
||||||
" regex: regular expression\n"
|
" regex: regular expression\n"
|
||||||
" int-list: list of integers\n"
|
" int-list: list of integers\n"
|
||||||
" str-list: list of character strings\n"
|
" str-list: list of character strings\n"
|
||||||
" line-flag-list: list of line flags\n",
|
" line-flags: list of line flags\n",
|
||||||
ParameterDesc{
|
ParameterDesc{
|
||||||
{ { "hidden", { false, "do not display option name when completing" } },
|
{ { "hidden", { false, "do not display option name when completing" } },
|
||||||
{ "docstring", { true, "specify option description" } } },
|
{ "docstring", { true, "specify option description" } } },
|
||||||
|
@ -1136,8 +1136,8 @@ const CommandDesc declare_option_cmd = {
|
||||||
opt = ®.declare_option<Vector<int, MemoryDomain::Options>>(parser[1], docstring, {}, flags);
|
opt = ®.declare_option<Vector<int, MemoryDomain::Options>>(parser[1], docstring, {}, flags);
|
||||||
else if (parser[0] == "str-list")
|
else if (parser[0] == "str-list")
|
||||||
opt = ®.declare_option<Vector<String, MemoryDomain::Options>>(parser[1], docstring, {}, flags);
|
opt = ®.declare_option<Vector<String, MemoryDomain::Options>>(parser[1], docstring, {}, flags);
|
||||||
else if (parser[0] == "line-flag-list")
|
else if (parser[0] == "line-flags")
|
||||||
opt = ®.declare_option<Vector<LineAndFlag, MemoryDomain::Options>>(parser[1], docstring, {}, flags);
|
opt = ®.declare_option<TimestampedList<LineAndFlag>>(parser[1], docstring, {}, flags);
|
||||||
else
|
else
|
||||||
throw runtime_error(format("unknown type {}", parser[0]));
|
throw runtime_error(format("unknown type {}", parser[0]));
|
||||||
|
|
||||||
|
|
|
@ -904,13 +904,44 @@ HighlighterAndId create_flag_lines_highlighter(HighlighterParameters params)
|
||||||
get_face(default_face); // validate param
|
get_face(default_face); // validate param
|
||||||
|
|
||||||
// throw if wrong option type
|
// throw if wrong option type
|
||||||
GlobalScope::instance().options()[option_name].get<Vector<LineAndFlag, MemoryDomain::Options>>();
|
GlobalScope::instance().options()[option_name].get<TimestampedList<LineAndFlag>>();
|
||||||
|
|
||||||
auto func = [=](const Context& context, HighlightFlags flags,
|
auto func = [=](const Context& context, HighlightFlags flags,
|
||||||
DisplayBuffer& display_buffer, BufferRange)
|
DisplayBuffer& display_buffer, BufferRange)
|
||||||
{
|
{
|
||||||
auto& lines_opt = context.options()[option_name];
|
auto& line_flags = context.options()[option_name].get_mutable<TimestampedList<LineAndFlag>>();
|
||||||
auto& lines = lines_opt.get<Vector<LineAndFlag, MemoryDomain::Options>>();
|
auto& lines = line_flags.list;
|
||||||
|
|
||||||
|
auto& buffer = context.buffer();
|
||||||
|
if (line_flags.timestamp != buffer.timestamp())
|
||||||
|
{
|
||||||
|
std::sort(lines.begin(), lines.end(),
|
||||||
|
[](const LineAndFlag& lhs, const LineAndFlag& rhs)
|
||||||
|
{ return std::get<0>(lhs) < std::get<0>(rhs); });
|
||||||
|
|
||||||
|
auto modifs = compute_line_modifications(buffer, line_flags.timestamp);
|
||||||
|
auto ins_pos = lines.begin();
|
||||||
|
for (auto it = lines.begin(); it != lines.end(); ++it)
|
||||||
|
{
|
||||||
|
auto& line = std::get<0>(*it); // that line is 1 based as it comes from user side
|
||||||
|
auto modif_it = std::upper_bound(modifs.begin(), modifs.end(), line-1,
|
||||||
|
[](const LineCount& l, const LineModification& c)
|
||||||
|
{ return l < c.old_line; });
|
||||||
|
if (modif_it != modifs.begin())
|
||||||
|
{
|
||||||
|
auto& prev = *(modif_it-1);
|
||||||
|
if (line-1 < prev.old_line + prev.num_removed)
|
||||||
|
continue; // line removed
|
||||||
|
|
||||||
|
line += prev.diff();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ins_pos != it)
|
||||||
|
*ins_pos = std::move(*it);
|
||||||
|
++ins_pos;
|
||||||
|
}
|
||||||
|
line_flags.timestamp = buffer.timestamp();
|
||||||
|
}
|
||||||
|
|
||||||
auto def_face = get_face(default_face);
|
auto def_face = get_face(default_face);
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
virtual ~Option() = default;
|
virtual ~Option() = default;
|
||||||
|
|
||||||
template<typename T> const T& get() const;
|
template<typename T> const T& get() const;
|
||||||
|
template<typename T> T& get_mutable();
|
||||||
template<typename T> void set(const T& val, bool notify=true);
|
template<typename T> void set(const T& val, bool notify=true);
|
||||||
template<typename T> bool is_of_type() const;
|
template<typename T> bool is_of_type() const;
|
||||||
|
|
||||||
|
@ -122,6 +123,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const T& get() const { return m_value; }
|
const T& get() const { return m_value; }
|
||||||
|
T& get_mutable() { return m_value; }
|
||||||
|
|
||||||
String get_as_string() const override
|
String get_as_string() const override
|
||||||
{
|
{
|
||||||
|
@ -167,6 +169,11 @@ template<typename T> const T& Option::get() const
|
||||||
return typed_opt->get();
|
return typed_opt->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T> T& Option::get_mutable()
|
||||||
|
{
|
||||||
|
return const_cast<T&>(get<T>());
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T> void Option::set(const T& val, bool notify)
|
template<typename T> void Option::set(const T& val, bool notify)
|
||||||
{
|
{
|
||||||
auto* typed_opt = dynamic_cast<TypedOption<T>*>(this);
|
auto* typed_opt = dynamic_cast<TypedOption<T>*>(this);
|
||||||
|
|
|
@ -223,6 +223,45 @@ constexpr Array<EnumDesc<DebugFlags>, 3> enum_desc(DebugFlags)
|
||||||
} };
|
} };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct TimestampedList
|
||||||
|
{
|
||||||
|
size_t timestamp;
|
||||||
|
Vector<T, MemoryDomain::Options> list;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline bool operator==(const TimestampedList<T>& lhs, const TimestampedList<T>& rhs)
|
||||||
|
{
|
||||||
|
return lhs.timestamp == rhs.timestamp and lhs.list == rhs.list;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline bool operator!=(const TimestampedList<T>& lhs, const TimestampedList<T>& rhs)
|
||||||
|
{
|
||||||
|
return not (lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline String option_to_string(const TimestampedList<T>& opt)
|
||||||
|
{
|
||||||
|
return format("{}:{}", opt.timestamp, option_to_string(opt.list));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void option_from_string(StringView str, TimestampedList<T>& opt)
|
||||||
|
{
|
||||||
|
auto it = find(str, ':');
|
||||||
|
opt.timestamp = str_to_int({str.begin(), it});
|
||||||
|
option_from_string({it+1, str.end()}, opt.list);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline bool option_add(TimestampedList<T>& opt, StringView str)
|
||||||
|
{
|
||||||
|
return option_add(opt.list, str);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // option_types_hh_INCLUDED
|
#endif // option_types_hh_INCLUDED
|
||||||
|
|
Loading…
Reference in New Issue
Block a user