mirror of
https://github.com/MaskRay/ccls.git
synced 2025-01-19 12:05:50 +00:00
Try to keep semantic highlighting colors stable across open files.
This commit is contained in:
parent
043e9a4d44
commit
d7a183c796
@ -24,6 +24,11 @@ struct LruCache {
|
|||||||
// Inserts an entry. Evicts the oldest unused entry if there is no space.
|
// Inserts an entry. Evicts the oldest unused entry if there is no space.
|
||||||
void Insert(const TKey& key, const std::shared_ptr<TValue>& value);
|
void Insert(const TKey& key, const std::shared_ptr<TValue>& value);
|
||||||
|
|
||||||
|
// Call |func| on existing entries. If |func| returns false iteration
|
||||||
|
// temrinates early.
|
||||||
|
template <typename TFunc>
|
||||||
|
void IterateValues(TFunc func);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// There is a global score counter, when we access an element we increase
|
// There is a global score counter, when we access an element we increase
|
||||||
// its score to the current global value, so it has the highest overall
|
// its score to the current global value, so it has the highest overall
|
||||||
@ -113,6 +118,15 @@ void LruCache<TKey, TValue>::Insert(const TKey& key,
|
|||||||
entries_.push_back(entry);
|
entries_.push_back(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename TKey, typename TValue>
|
||||||
|
template <typename TFunc>
|
||||||
|
void LruCache<TKey, TValue>::IterateValues(TFunc func) {
|
||||||
|
for (Entry& entry : entries_) {
|
||||||
|
if (!func(entry.value))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TKey, typename TValue>
|
template <typename TKey, typename TValue>
|
||||||
void LruCache<TKey, TValue>::IncrementScore() {
|
void LruCache<TKey, TValue>::IncrementScore() {
|
||||||
next_score_ += 1;
|
next_score_ += 1;
|
||||||
|
@ -1,31 +1,60 @@
|
|||||||
#include "semantic_highlight_symbol_cache.h"
|
#include "semantic_highlight_symbol_cache.h"
|
||||||
|
|
||||||
SemanticHighlightSymbolCache::Entry::Entry(const std::string& path)
|
SemanticHighlightSymbolCache::Entry::Entry(
|
||||||
: path(path) {}
|
SemanticHighlightSymbolCache* all_caches,
|
||||||
|
const std::string& path)
|
||||||
|
: all_caches_(all_caches), path(path) {}
|
||||||
|
|
||||||
|
optional<int> SemanticHighlightSymbolCache::Entry::TryGetStableId(
|
||||||
|
SymbolKind kind,
|
||||||
|
const std::string& detailed_name) {
|
||||||
|
TNameToId* map = GetMapForSymbol_(kind);
|
||||||
|
auto it = map->find(detailed_name);
|
||||||
|
if (it != map->end())
|
||||||
|
return it->second;
|
||||||
|
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
int SemanticHighlightSymbolCache::Entry::GetStableId(
|
int SemanticHighlightSymbolCache::Entry::GetStableId(
|
||||||
SymbolKind kind,
|
SymbolKind kind,
|
||||||
const std::string& detailed_name) {
|
const std::string& detailed_name) {
|
||||||
TNameToId* map = nullptr;
|
optional<int> id = TryGetStableId(kind, detailed_name);
|
||||||
|
if (id)
|
||||||
|
return *id;
|
||||||
|
|
||||||
|
// Create a new id. First try to find a key in another map.
|
||||||
|
all_caches_->cache_.IterateValues([&](const std::shared_ptr<Entry>& entry) {
|
||||||
|
optional<int> other_id = entry->TryGetStableId(kind, detailed_name);
|
||||||
|
if (other_id) {
|
||||||
|
id = other_id;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create a new id.
|
||||||
|
TNameToId* map = GetMapForSymbol_(kind);
|
||||||
|
if (!id)
|
||||||
|
id = all_caches_->next_stable_id_++;
|
||||||
|
return (*map)[detailed_name] = *id;
|
||||||
|
}
|
||||||
|
|
||||||
|
SemanticHighlightSymbolCache::Entry::TNameToId*
|
||||||
|
SemanticHighlightSymbolCache::Entry::GetMapForSymbol_(SymbolKind kind) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case SymbolKind::Type:
|
case SymbolKind::Type:
|
||||||
map = &detailed_type_name_to_stable_id;
|
return &detailed_type_name_to_stable_id;
|
||||||
break;
|
|
||||||
case SymbolKind::Func:
|
case SymbolKind::Func:
|
||||||
map = &detailed_func_name_to_stable_id;
|
return &detailed_func_name_to_stable_id;
|
||||||
break;
|
|
||||||
case SymbolKind::Var:
|
case SymbolKind::Var:
|
||||||
map = &detailed_var_name_to_stable_id;
|
return &detailed_var_name_to_stable_id;
|
||||||
|
case SymbolKind::File:
|
||||||
|
case SymbolKind::Invalid:
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
assert(map);
|
assert(false);
|
||||||
auto it = map->find(detailed_name);
|
return nullptr;
|
||||||
if (it != map->end())
|
|
||||||
return it->second;
|
|
||||||
return (*map)[detailed_name] = map->size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SemanticHighlightSymbolCache::SemanticHighlightSymbolCache()
|
SemanticHighlightSymbolCache::SemanticHighlightSymbolCache()
|
||||||
@ -33,5 +62,6 @@ SemanticHighlightSymbolCache::SemanticHighlightSymbolCache()
|
|||||||
|
|
||||||
std::shared_ptr<SemanticHighlightSymbolCache::Entry>
|
std::shared_ptr<SemanticHighlightSymbolCache::Entry>
|
||||||
SemanticHighlightSymbolCache::GetCacheForFile(const std::string& path) {
|
SemanticHighlightSymbolCache::GetCacheForFile(const std::string& path) {
|
||||||
return cache_.Get(path, [&]() { return std::make_shared<Entry>(path); });
|
return cache_.Get(
|
||||||
|
path, [&, this]() { return std::make_shared<Entry>(this, path); });
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,15 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
using std::experimental::nullopt;
|
||||||
|
using std::experimental::optional;
|
||||||
|
|
||||||
// Caches symbols for a single file for semantic highlighting to provide
|
// Caches symbols for a single file for semantic highlighting to provide
|
||||||
// relatively stable ids. Only supports xxx files at a time.
|
// relatively stable ids. Only supports xxx files at a time.
|
||||||
struct SemanticHighlightSymbolCache {
|
struct SemanticHighlightSymbolCache {
|
||||||
struct Entry {
|
struct Entry {
|
||||||
|
SemanticHighlightSymbolCache* all_caches_ = nullptr;
|
||||||
|
|
||||||
// The path this cache belongs to.
|
// The path this cache belongs to.
|
||||||
std::string path;
|
std::string path;
|
||||||
// Detailed symbol name to stable id.
|
// Detailed symbol name to stable id.
|
||||||
@ -18,13 +23,18 @@ struct SemanticHighlightSymbolCache {
|
|||||||
TNameToId detailed_func_name_to_stable_id;
|
TNameToId detailed_func_name_to_stable_id;
|
||||||
TNameToId detailed_var_name_to_stable_id;
|
TNameToId detailed_var_name_to_stable_id;
|
||||||
|
|
||||||
explicit Entry(const std::string& path);
|
Entry(SemanticHighlightSymbolCache* all_caches, const std::string& path);
|
||||||
|
|
||||||
|
optional<int> TryGetStableId(SymbolKind kind,
|
||||||
|
const std::string& detailed_name);
|
||||||
int GetStableId(SymbolKind kind, const std::string& detailed_name);
|
int GetStableId(SymbolKind kind, const std::string& detailed_name);
|
||||||
|
|
||||||
|
TNameToId* GetMapForSymbol_(SymbolKind kind);
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr static int kCacheSize = 10;
|
constexpr static int kCacheSize = 10;
|
||||||
LruCache<std::string, Entry> cache_;
|
LruCache<std::string, Entry> cache_;
|
||||||
|
uint32_t next_stable_id_ = 0;
|
||||||
|
|
||||||
SemanticHighlightSymbolCache();
|
SemanticHighlightSymbolCache();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user