Skip to content

Commit f0b3439

Browse files
committed
Add CTags Symbol Conversion For LSP
Add a conversion path from CTags symbol output into LSP `SymbolInformation`, allowing parsed tags to be surfaced with mapped kinds, source ranges, and file locations. The CTags parser now carries the originating filename through symbol metadata so converted symbols can point back to the correct source file. Also improve LSP path conversion documentation and override declarations in the default path converter, clarifying how local, remote, and file URI paths are normalized. * CTags symbol parsing * LSP symbol mapping * Path converter docs and overrides **Generated by CodeLite** Signed-off-by: Eran Ifrah <eran@codelite.org>
1 parent 709408f commit f0b3439

File tree

6 files changed

+82
-7
lines changed

6 files changed

+82
-7
lines changed

CodeLite/CTags.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ std::optional<wxString> CTags::DoSymbolGenerate(const wxString& file, const wxSt
141141
return wxString::FromUTF8(result.out);
142142
}
143143

144-
std::vector<CTags::SymbolInfo> CTags::ParseSymbolOutput(const wxString& content)
144+
std::vector<CTags::SymbolInfo> CTags::ParseSymbolOutput(const wxString& content, const wxString& filename)
145145
{
146146
std::vector<SymbolInfo> out;
147147
wxArrayString lines = ::wxStringTokenize(content, "\n", wxTOKEN_STRTOK);
@@ -171,6 +171,7 @@ std::vector<CTags::SymbolInfo> CTags::ParseSymbolOutput(const wxString& content)
171171
info.name = name;
172172
info.kind = *mapped_kind;
173173
info.line = entry["line"].get<int>();
174+
info.file = filename;
174175
if (entry.contains("end") && entry["end"].is_number_integer()) {
175176
info.end_line = entry["end"].get<int>();
176177
}
@@ -223,7 +224,7 @@ std::vector<CTags::SymbolInfo> CTags::ParseFileSymbols(const wxString& file, con
223224
return {};
224225

225226
clDEBUG() << "Parsing symbols..." << endl;
226-
auto symbols = ParseSymbolOutput(*content);
227+
auto symbols = ParseSymbolOutput(*content, file);
227228
clDEBUG() << "Parsing symbols...done" << endl;
228229

229230
clDEBUG() << "Sorting symbols..." << endl;

CodeLite/CTags.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class WXDLLIMPEXP_CL CTags
2626

2727
struct SymbolInfo {
2828
wxString name;
29+
wxString file;
2930
SymbolKind kind = SymbolKind::kFunction;
3031
int line = 0;
3132
/**
@@ -187,7 +188,7 @@ class WXDLLIMPEXP_CL CTags
187188

188189
static std::optional<wxString> DoSymbolGenerate(const wxString& file, const wxString& ctags_exe);
189190
static bool IsSupportedSymbolLanguage(const wxString& language);
190-
static std::vector<SymbolInfo> ParseSymbolOutput(const wxString& content);
191+
static std::vector<SymbolInfo> ParseSymbolOutput(const wxString& content, const wxString& filename);
191192
static std::optional<SymbolKind>
192193
MapSymbolKind(const wxString& kind, const wxString& scope, const wxString& kind_from_ctags);
193194

CodeLite/LSP/basic_types.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,43 @@ JSONItem SymbolInformation::ToJSON() const
363363
return json;
364364
}
365365

366+
SymbolInformation SymbolInformation::From(const CTags::SymbolInfo& ctags_symbol_info)
367+
{
368+
SymbolInformation si;
369+
si.name = ctags_symbol_info.name + ctags_symbol_info.signature;
370+
switch (ctags_symbol_info.kind) {
371+
case CTags::SymbolKind::kClass:
372+
si.kind = eSymbolKind::kSK_Class;
373+
break;
374+
case CTags::SymbolKind::kFunction:
375+
si.kind = eSymbolKind::kSK_Method;
376+
break;
377+
case CTags::SymbolKind::kGlobalMethod:
378+
si.kind = eSymbolKind::kSK_Function;
379+
break;
380+
case CTags::SymbolKind::kPrototype:
381+
si.kind = eSymbolKind::kSK_Function;
382+
break;
383+
case CTags::SymbolKind::kStruct:
384+
si.kind = eSymbolKind::kSK_Struct;
385+
break;
386+
case CTags::SymbolKind::kTrait:
387+
si.kind = eSymbolKind::kSK_Interface;
388+
break;
389+
default:
390+
si.kind = eSymbolKind::kSK_Variable;
391+
break;
392+
}
393+
Range range;
394+
range.SetStart(Position{ctags_symbol_info.line, 0});
395+
if (ctags_symbol_info.end_line.has_value()) {
396+
range.SetEnd(Position{ctags_symbol_info.end_line.value(), 0});
397+
}
398+
si.location.SetRange(range);
399+
si.location.SetPath(ctags_symbol_info.file);
400+
return si;
401+
}
402+
366403
std::vector<SymbolInformation> SymbolInformation::From(const DocumentSymbol& document_symbol,
367404
const wxString& container_name)
368405
{

CodeLite/LSP/basic_types.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef JSONRPC_BASICTYPES_H
22
#define JSONRPC_BASICTYPES_H
33

4+
#include "CTags.hpp"
45
#include "JSON.h"
56
#include "JSONObject.h"
67
#include "clModuleLogger.hpp"
@@ -656,6 +657,19 @@ class WXDLLIMPEXP_CL SymbolInformation : public Serializable
656657
*/
657658
static std::vector<SymbolInformation> From(const DocumentSymbol& document_symbol,
658659
const wxString& container_name = wxEmptyString);
660+
661+
/**
662+
* @brief Creates a SymbolInformation object from a ctags symbol description.
663+
*
664+
* Converts a CTags::SymbolInfo record into the internal SymbolInformation
665+
* representation by mapping the symbol name, kind, and source range.
666+
*
667+
* @param ctags_symbol_info const CTags::SymbolInfo& The ctags symbol metadata to convert, including name,
668+
* signature, kind, and source line information.
669+
*
670+
* @return SymbolInformation The converted symbol information object.
671+
*/
672+
static SymbolInformation From(const CTags::SymbolInfo& ctags_symbol_info);
659673
};
660674

661675
enum class ProgressKind {

Plugin/LSP/PathConverterDefault.hpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,33 @@
77
class WXDLLIMPEXP_SDK PathConverterDefault : public IPathConverter
88
{
99
public:
10-
virtual LSP::FilePath ConvertFrom(const wxString& path) const;
11-
virtual LSP::FilePath ConvertTo(const wxString& path) const;
10+
/**
11+
* Convert a path string into an LSP::FilePath, normalizing URI/file URL forms and
12+
* marking remote files when appropriate.
13+
*
14+
* This method decodes any URI-encoded characters, strips a leading "file://" prefix,
15+
* and applies platform-specific adjustments. On Windows it also handles paths that
16+
* arrive in "/C:/..." form and attempts to map known SFTP editor paths back to their
17+
* local file paths. If the path does not exist locally on non-Windows systems, the
18+
* result is flagged as a remote file.
19+
*
20+
* @param path const wxString& The input path or file URI to convert.
21+
* @return LSP::FilePath The converted file path, with remote-file status set when needed.
22+
*/
23+
LSP::FilePath ConvertFrom(const wxString& path) const override;
24+
/**
25+
* Converts a local editor file path into an LSP file path or file URL.
26+
*
27+
* This method checks whether the path corresponds to an open remote editor file.
28+
* If so, it returns that editor's remote path prefixed with "file://". Otherwise,
29+
* it falls back to the default wxWidgets filename-to-URL conversion.
30+
*
31+
* @param path const wxString& The local file path to convert.
32+
* @return LSP::FilePath The converted file path or file URL.
33+
*/
34+
LSP::FilePath ConvertTo(const wxString& path) const override;
1235
PathConverterDefault() = default;
13-
virtual ~PathConverterDefault() = default;
36+
~PathConverterDefault() override = default;
1437
};
1538

1639
#endif // PATHCONVERTERDEFAULT_HPP

TODO.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ Medium:
2323
- Support auto reading `AGENTS.md` file and convert it into System-Messages.
2424
- Implement `code_symbols` tool for AI.
2525
- Add tool management configuration which allows users to trust tools permanently
26-
- Move the history out of the JSON - it is not scalable. Need a directory structure.
2726

2827
Low:
2928
----

0 commit comments

Comments
 (0)