mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 23:55:08 +00:00
Fix default -resource-dir when clang -print-resource-dir contains ..
Also makes textDocument/definition in comments takes scope resolution into account, and use detailed names (for Func, without parameters) for workspace/symbol
This commit is contained in:
parent
10437aa642
commit
72e654ffed
@ -201,19 +201,20 @@ std::string LexWordAroundPos(lsPosition position, const std::string& content) {
|
|||||||
int index = GetOffsetForPosition(position, content);
|
int index = GetOffsetForPosition(position, content);
|
||||||
|
|
||||||
int start = index;
|
int start = index;
|
||||||
int end = index;
|
int end = index + 1;
|
||||||
|
|
||||||
|
// We search for : before the cursor but not after to get the qualifier.
|
||||||
while (start > 0) {
|
while (start > 0) {
|
||||||
char c = content[start - 1];
|
char c = content[start - 1];
|
||||||
if (isalnum(c) || c == '_') {
|
if (isalnum(c) || c == '_' || c == ':') {
|
||||||
--start;
|
--start;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((end + 1) < content.size()) {
|
while (end < (int)content.size()) {
|
||||||
char c = content[end + 1];
|
char c = content[end];
|
||||||
if (isalnum(c) || c == '_') {
|
if (isalnum(c) || c == '_') {
|
||||||
++end;
|
++end;
|
||||||
} else {
|
} else {
|
||||||
@ -221,7 +222,7 @@ std::string LexWordAroundPos(lsPosition position, const std::string& content) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return content.substr(start, end - start + 1);
|
return content.substr(start, end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SubsequenceMatch(std::string_view search, std::string_view content) {
|
bool SubsequenceMatch(std::string_view search, std::string_view content) {
|
||||||
|
@ -131,24 +131,18 @@ struct TextDocumentDefinitionHandler
|
|||||||
// Find the best match of the identifier at point.
|
// Find the best match of the identifier at point.
|
||||||
if (!has_symbol && db->symbols.size()) {
|
if (!has_symbol && db->symbols.size()) {
|
||||||
const std::string& buffer = working_file->buffer_content;
|
const std::string& buffer = working_file->buffer_content;
|
||||||
int start = GetOffsetForPosition(request->params.position, buffer);
|
std::string query = LexWordAroundPos(request->params.position, buffer);
|
||||||
int end = start;
|
|
||||||
while (start > 0 && isalnum(buffer[start - 1]))
|
|
||||||
start--;
|
|
||||||
while (isalnum(buffer[end]))
|
|
||||||
end++;
|
|
||||||
auto query = std::string_view(buffer).substr(start, end - start);
|
|
||||||
|
|
||||||
int best_score = kMinScore;
|
int best_score = kMinScore;
|
||||||
int best_i = 0;
|
int best_i = 0;
|
||||||
std::vector<int> score, dp;
|
std::vector<int> score, dp;
|
||||||
for (int i = 0; i < (int)db->symbols.size(); ++i) {
|
for (int i = 0; i < (int)db->symbols.size(); ++i) {
|
||||||
std::string_view short_name = db->GetSymbolShortName(i);
|
std::string_view detailed_name = db->GetSymbolDetailedName(i);
|
||||||
if (short_name.size() > score.size()) {
|
if (detailed_name.size() > score.size()) {
|
||||||
score.resize(short_name.size());
|
score.resize(detailed_name.size());
|
||||||
dp.resize(short_name.size());
|
dp.resize(detailed_name.size());
|
||||||
}
|
}
|
||||||
int t = FuzzyEvaluate(query, short_name, score, dp);
|
int t = FuzzyEvaluate(query, detailed_name, score, dp);
|
||||||
if (t > best_score) {
|
if (t > best_score) {
|
||||||
best_score = t;
|
best_score = t;
|
||||||
best_i = i;
|
best_i = i;
|
||||||
|
@ -79,12 +79,7 @@ struct WorkspaceSymbolHandler : BaseMessageHandler<Ipc_WorkspaceSymbol> {
|
|||||||
inserted_results.reserve(config->maxWorkspaceSearchResults);
|
inserted_results.reserve(config->maxWorkspaceSearchResults);
|
||||||
result_indices.reserve(config->maxWorkspaceSearchResults);
|
result_indices.reserve(config->maxWorkspaceSearchResults);
|
||||||
|
|
||||||
// We use detailed_names for exact matches and short_names for fuzzy matches
|
// We use detailed_names without parameters for matching.
|
||||||
// because otherwise the fuzzy match is likely to match on parameter names
|
|
||||||
// and the like.
|
|
||||||
// TODO: make detailed_names not include function parameter information (or
|
|
||||||
// introduce additional metadata) so that we can do fuzzy search with
|
|
||||||
// detailed_names.
|
|
||||||
|
|
||||||
// Find exact substring matches.
|
// Find exact substring matches.
|
||||||
for (int i = 0; i < db->symbols.size(); ++i) {
|
for (int i = 0; i < db->symbols.size(); ++i) {
|
||||||
@ -112,9 +107,10 @@ struct WorkspaceSymbolHandler : BaseMessageHandler<Ipc_WorkspaceSymbol> {
|
|||||||
query_without_space += c;
|
query_without_space += c;
|
||||||
|
|
||||||
for (int i = 0; i < db->symbols.size(); ++i) {
|
for (int i = 0; i < db->symbols.size(); ++i) {
|
||||||
if (SubsequenceMatch(query_without_space, db->GetSymbolShortName(i))) {
|
std::string_view detailed_name = db->GetSymbolDetailedName(i);
|
||||||
|
if (SubsequenceMatch(query_without_space, detailed_name)) {
|
||||||
// Do not show the same entry twice.
|
// Do not show the same entry twice.
|
||||||
if (!inserted_results.insert(std::string(db->GetSymbolDetailedName(i))).second)
|
if (!inserted_results.insert(std::string(detailed_name)).second)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (InsertSymbolIntoResult(db, working_files, db->symbols[i],
|
if (InsertSymbolIntoResult(db, working_files, db->symbols[i],
|
||||||
@ -131,7 +127,7 @@ struct WorkspaceSymbolHandler : BaseMessageHandler<Ipc_WorkspaceSymbol> {
|
|||||||
// Sort results with a fuzzy matching algorithm.
|
// Sort results with a fuzzy matching algorithm.
|
||||||
int longest = 0;
|
int longest = 0;
|
||||||
for (int i : result_indices)
|
for (int i : result_indices)
|
||||||
longest = std::max(longest, int(db->GetSymbolShortName(i).size()));
|
longest = std::max(longest, int(db->GetSymbolDetailedName(i).size()));
|
||||||
|
|
||||||
std::vector<int> score(longest); // score for each position
|
std::vector<int> score(longest); // score for each position
|
||||||
std::vector<int> dp(
|
std::vector<int> dp(
|
||||||
@ -139,7 +135,7 @@ struct WorkspaceSymbolHandler : BaseMessageHandler<Ipc_WorkspaceSymbol> {
|
|||||||
std::vector<std::pair<int, int>> permutation(result_indices.size());
|
std::vector<std::pair<int, int>> permutation(result_indices.size());
|
||||||
for (int i = 0; i < int(result_indices.size()); i++) {
|
for (int i = 0; i < int(result_indices.size()); i++) {
|
||||||
permutation[i] = {
|
permutation[i] = {
|
||||||
FuzzyEvaluate(query, db->GetSymbolShortName(result_indices[i]), score, dp),
|
FuzzyEvaluate(query, db->GetSymbolDetailedName(result_indices[i]), score, dp),
|
||||||
i};
|
i};
|
||||||
}
|
}
|
||||||
std::sort(permutation.begin(), permutation.end(),
|
std::sort(permutation.begin(), permutation.end(),
|
||||||
|
@ -916,6 +916,7 @@ void QueryDatabase::UpdateSymbols(Maybe<Id<void>>* symbol_idx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For Func, the returned name does not include parameters.
|
||||||
std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const {
|
std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const {
|
||||||
RawId idx = symbols[symbol_idx].id.id;
|
RawId idx = symbols[symbol_idx].id.id;
|
||||||
switch (symbols[symbol_idx].kind) {
|
switch (symbols[symbol_idx].kind) {
|
||||||
@ -926,8 +927,11 @@ std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const {
|
|||||||
return files[idx].def->path;
|
return files[idx].def->path;
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Func:
|
case SymbolKind::Func:
|
||||||
if (funcs[idx].def)
|
if (funcs[idx].def) {
|
||||||
return funcs[idx].def->detailed_name;
|
auto& def = funcs[idx].def;
|
||||||
|
return std::string_view(def->detailed_name)
|
||||||
|
.substr(0, def->short_name_offset + def->short_name_size);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Type:
|
case SymbolKind::Type:
|
||||||
if (types[idx].def)
|
if (types[idx].def)
|
||||||
|
@ -565,7 +565,7 @@ std::string GetDefaultResourceDirectory() {
|
|||||||
resource_directory =
|
resource_directory =
|
||||||
resource_directory.substr(1, resource_directory.size() - 2);
|
resource_directory.substr(1, resource_directory.size() - 2);
|
||||||
}
|
}
|
||||||
if (resource_directory.find("..") != std::string::npos) {
|
if (resource_directory.compare(0, 2, "..") == 0) {
|
||||||
std::string executable_path = GetExecutablePath();
|
std::string executable_path = GetExecutablePath();
|
||||||
size_t pos = executable_path.find_last_of('/');
|
size_t pos = executable_path.find_last_of('/');
|
||||||
result = executable_path.substr(0, pos + 1);
|
result = executable_path.substr(0, pos + 1);
|
||||||
|
4
wscript
4
wscript
@ -216,13 +216,9 @@ def configure(ctx):
|
|||||||
# Ask llvm-config for cflags and ldflags
|
# Ask llvm-config for cflags and ldflags
|
||||||
ctx.find_program(ctx.options.llvm_config, msg='checking for llvm-config', var='LLVM_CONFIG', mandatory=False)
|
ctx.find_program(ctx.options.llvm_config, msg='checking for llvm-config', var='LLVM_CONFIG', mandatory=False)
|
||||||
|
|
||||||
if len(ctx.options.llvm_config):
|
|
||||||
ctx.env.rpath = [str(subprocess.check_output(
|
ctx.env.rpath = [str(subprocess.check_output(
|
||||||
[ctx.options.llvm_config, '--libdir'],
|
[ctx.options.llvm_config, '--libdir'],
|
||||||
stderr=subprocess.STDOUT).decode()).strip()]
|
stderr=subprocess.STDOUT).decode()).strip()]
|
||||||
else:
|
|
||||||
# If `--llvm-config=` (empty)
|
|
||||||
ctx.env.rpath = []
|
|
||||||
|
|
||||||
if ctx.options.clang_prefix:
|
if ctx.options.clang_prefix:
|
||||||
ctx.start_msg('Checking for clang prefix')
|
ctx.start_msg('Checking for clang prefix')
|
||||||
|
Loading…
Reference in New Issue
Block a user