Skip to content

Commit

Permalink
Fixes for rtags-get-include-file-for-symbol
Browse files Browse the repository at this point in the history
Add and use rc --include-file
  • Loading branch information
Andersbakken committed Apr 7, 2015
1 parent 08d0e6e commit 749e9a4
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 22 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ add_executable(rdm
FindFileJob.cpp
FindSymbolsJob.cpp
FollowLocationJob.cpp
IncludeFileJob.cpp
IndexerJob.cpp
JobScheduler.cpp
ListSymbolsJob.cpp
Expand Down
66 changes: 66 additions & 0 deletions src/IncludeFileJob.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* This file is part of RTags.
RTags is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RTags 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with RTags. If not, see <http://www.gnu.org/licenses/>. */

#include "IncludeFileJob.h"
#include "RTags.h"
#include "Server.h"
#include "Project.h"

IncludeFileJob::IncludeFileJob(const std::shared_ptr<QueryMessage> &query, const std::shared_ptr<Project> &project)
: QueryJob(query, 0, project)
{
const uint32_t fileId = Location::fileId(query->currentFile());
mSource = project->sources(fileId).value(query->buildIndex());
if (mSource.isNull()) {
for (const uint32_t dep : project->dependencies(fileId, Project::DependsOnArg)) {
mSource = project->sources(dep).value(query->buildIndex());
if (!mSource.isNull())
break;
}
}
mSymbol = query->query();
}

int IncludeFileJob::execute()
{
if (mSource.isNull())
return 1;
const Path directory = mSource.sourceFile().parentDir();
const bool fromHeader = queryMessage()->currentFile().isHeader();
project()->findSymbols(mSymbol, [this, &directory, fromHeader](Project::SymbolMatchType type, const String &, const Set<Location> &locations) {
if (type == Project::StartsWith)
return;
for (const Location &loc : locations) {
const Path path = loc.path();
if (!path.isHeader())
continue;
const Symbol sym = project()->findSymbol(loc);
if (sym.isDefinition() || !sym.isClass()) {
if (!fromHeader && path.startsWith(directory)) {
write<256>("#include \"%s\"", path.mid(directory.size()).constData());
} else {
for (const Source::Include &inc : mSource.includePaths) {
const Path p = inc.path.ensureTrailingSlash();
if (path.startsWith(p)) {
write<256>("#include <%s>", path.mid(p.size()).constData());
}
}
}
}
}
}, queryFlags());

return 0;
}
36 changes: 36 additions & 0 deletions src/IncludeFileJob.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* This file is part of RTags.
RTags is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RTags 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with RTags. If not, see <http://www.gnu.org/licenses/>. */

#ifndef IncludeFileJob_h
#define IncludeFileJob_h

#include <rct/String.h>
#include <rct/List.h>
#include "RTags.h"
#include "QueryJob.h"
#include "Location.h"

class IncludeFileJob : public QueryJob
{
public:
IncludeFileJob(const std::shared_ptr<QueryMessage> &query, const std::shared_ptr<Project> &project);
protected:
virtual int execute() override;
private:
String mSymbol;
Source mSource;
};

#endif
1 change: 0 additions & 1 deletion src/Project.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1508,7 +1508,6 @@ Set<Symbol> Project::findSubclasses(const Symbol &symbol)
return ret;
}


void Project::beginScope()
{
assert(!mFileMapScope);
Expand Down
1 change: 1 addition & 0 deletions src/QueryJob.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class QueryJob
void setJobFlags(unsigned int flags) { mJobFlags = flags; }
void setJobFlag(Flag flag, bool on = true) { if (on) { mJobFlags |= flag; } else { mJobFlags &= ~flag; } }
unsigned int queryFlags() const { return mQueryMessage ? mQueryMessage->flags() : 0; }
std::shared_ptr<QueryMessage> queryMessage() const { return mQueryMessage; }
unsigned int keyFlags() const { return QueryMessage::keyFlags(queryFlags()); }
bool filter(const String &val) const;
Signal<std::function<void(const String &)> > &output() { return mOutput; }
Expand Down
3 changes: 2 additions & 1 deletion src/QueryMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class QueryMessage : public RTagsMessage
public:
enum { MessageId = QueryId };
enum Type {
Invalid,
GenerateTest,
CheckReindex,
ClassHierarchy,
Expand All @@ -44,7 +45,7 @@ class QueryMessage : public RTagsMessage
FixIts,
FollowLocation,
HasFileManager,
Invalid,
IncludeFile,
IsIndexed,
IsIndexing,
JobCount,
Expand Down
10 changes: 7 additions & 3 deletions src/RClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ struct Option opts[] = {
{ RClient::RemoveFile, "remove", 'D', required_argument, "Remove file from project." },
{ RClient::FindProjectRoot, "find-project-root", 0, required_argument, "Use to check behavior of find-project-root." },
{ RClient::FindProjectBuildRoot, "find-project-build-root", 0, required_argument, "Use to check behavior of find-project-root for builds." },
{ RClient::IncludeFile, "include-file", 0, required_argument, "Use to generate include statement for symbol." },
{ RClient::Sources, "sources", 0, optional_argument, "Dump sources for source file." },
{ RClient::Dependencies, "dependencies", 0, required_argument, "Dump dependencies for source file." },
{ RClient::ReloadFileManager, "reload-file-manager", 'B', no_argument, "Reload file manager." },
Expand Down Expand Up @@ -758,7 +759,7 @@ RClient::ParseStatus RClient::parse(int &argc, char **argv)
addQuery(type, encoded, QueryMessage::HasLocation);
break; }
case CurrentFile:
mCurrentFile.append(optarg);
mCurrentFile.append(Path::resolved(optarg));
break;
case ReloadFileManager:
addQuery(QueryMessage::ReloadFileManager);
Expand Down Expand Up @@ -833,16 +834,19 @@ RClient::ParseStatus RClient::parse(int &argc, char **argv)
case ListSymbols:
case FindSymbols:
case Sources:
case IncludeFile:
case JobCount:
case Status: {
unsigned int extraQueryFlags = 0;
QueryMessage::Type type = QueryMessage::Invalid;
bool resolve = true;
switch (opt->option) {
case CheckReindex: type = QueryMessage::CheckReindex; break;
case Reindex: type = QueryMessage::Reindex; break;
case Project: type = QueryMessage::Project; break;
case FindFile: type = QueryMessage::FindFile; break;
case FindFile: type = QueryMessage::FindFile; resolve = false; break;
case Sources: type = QueryMessage::Sources; break;
case IncludeFile: type = QueryMessage::IncludeFile; resolve = false; break;
case Status: type = QueryMessage::Status; break;
case ListSymbols: type = QueryMessage::ListSymbols; break;
case FindSymbols: type = QueryMessage::FindSymbols; break;
Expand All @@ -858,7 +862,7 @@ RClient::ParseStatus RClient::parse(int &argc, char **argv)
}
if (arg) {
Path p(arg);
if (opt->option != FindFile && p.exists()) {
if (resolve && p.exists()) {
p.resolve();
addQuery(type, p, extraQueryFlags);
} else {
Expand Down
1 change: 1 addition & 0 deletions src/RClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class RClient
GenerateTest,
HasFileManager,
Help,
IncludeFile,
IMenu,
IsIndexed,
IsIndexing,
Expand Down
17 changes: 17 additions & 0 deletions src/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "VisitFileResponseMessage.h"
#include "Filter.h"
#include "FindFileJob.h"
#include "IncludeFileJob.h"
#include "RClient.h"
#include "FindSymbolsJob.h"
#include "FollowLocationJob.h"
Expand Down Expand Up @@ -505,6 +506,9 @@ void Server::handleQueryMessage(const std::shared_ptr<QueryMessage> &message, co
case QueryMessage::Sources:
sources(message, conn);
break;
case QueryMessage::IncludeFile:
includeFile(message, conn);
break;
case QueryMessage::GenerateTest:
generateTest(message, conn);
break;
Expand Down Expand Up @@ -987,6 +991,19 @@ void Server::hasFileManager(const std::shared_ptr<QueryMessage> &query, const st
conn->finish();
}

void Server::includeFile(const std::shared_ptr<QueryMessage> &query, const std::shared_ptr<Connection> &conn)
{
std::shared_ptr<Project> project = projectForQuery(query);
if (!project) {
conn->write("No project");
conn->finish();
return;
}

IncludeFileJob job(query, project);
conn->finish(job.run(conn));
}

void Server::preprocessFile(const std::shared_ptr<QueryMessage> &query, const std::shared_ptr<Connection> &conn)
{
const Path path = query->query();
Expand Down
1 change: 1 addition & 0 deletions src/Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class Server
void fixIts(const std::shared_ptr<QueryMessage> &query, const std::shared_ptr<Connection> &conn);
void followLocation(const std::shared_ptr<QueryMessage> &query, const std::shared_ptr<Connection> &conn);
void hasFileManager(const std::shared_ptr<QueryMessage> &query, const std::shared_ptr<Connection> &conn);
void includeFile(const std::shared_ptr<QueryMessage> &query, const std::shared_ptr<Connection> &conn);
void isIndexed(const std::shared_ptr<QueryMessage> &query, const std::shared_ptr<Connection> &conn);
void isIndexing(const std::shared_ptr<QueryMessage> &, const std::shared_ptr<Connection> &conn);
void jobCount(const std::shared_ptr<QueryMessage> &query, const std::shared_ptr<Connection> &conn);
Expand Down
48 changes: 31 additions & 17 deletions src/rtags.el
Original file line number Diff line number Diff line change
Expand Up @@ -2416,23 +2416,37 @@ If rtags-display-summary-as-tooltip is t, a tooltip is displayed."
(defun rtags-get-include-file-for-symbol ()
"Insert #include declaration to buffer corresponding to the input symbol"
(interactive)
(setq input (completing-read-default "Symbol: " (function rtags-symbolname-complete) nil nil nil 'rtags-symbol-history))
(setq rtags-symbol-history (cl-remove-duplicates rtags-symbol-history :from-end t :test 'equal))
(if (equal "" input) (message "You entered an empty symbol. Try again.")
(setq final-res (with-current-buffer (rtags-get-buffer "Rtags include help")
(rtags-call-rc :path (buffer-file-name) "-F" input :path-filter (buffer-file-name) :path-filter-regex nil (if rtags-symbolnames-case-insensitive "-I"))
(setq raw-include (cond ((= (point-min) (point-max))
(message "RTags: No results") nil)
((= (count-lines (point-min) (point-max)) 1)
(buffer-substring-no-properties (point-min) (point-max)))
(t
(message "Results:\n%s" (buffer-substring-no-properties (point-min) (point-max)))
(setq raw-includes-list (split-string (buffer-substring-no-properties (point-min) (point-max)) "\n"))
(completing-read "Pick definition: " raw-includes-list nil t))))
(when raw-include (car (split-string raw-include ":")))))
(when (and final-res rtags-include-prefixes) (cl-loop for prefix in rtags-include-prefixes
do (if (string-match-p prefix final-res) (setq final-res (concat prefix (car (last (split-string final-res prefix))))))))
(when final-res (insert (concat "#include \"" final-res "\"\n")))))
(let ((input (completing-read-default "Symbol: " (function rtags-symbolname-complete) nil nil nil 'rtags-symbol-history))
(current-file (buffer-file-name)))
(setq rtags-symbol-history (cl-remove-duplicates rtags-symbol-history :from-end t :test 'equal))
(if (string= "" input)
(message "You entered an empty symbol. Try again.")
(let ((include (with-temp-buffer
(rtags-call-rc :path current-file
"--include-file" input
(if rtags-symbolnames-case-insensitive "-I"))
(cond ((= (point-min) (point-max))
(message "RTags: No results") nil)
((= (count-lines (point-min) (point-max)) 1)
(buffer-substring-no-properties (point-min) (1- (point-max))))
(t
;; (message "Results:\n%s" (buffer-substring-no-properties (point-min) (point-max)))
(completing-read "Choose: " (split-string (buffer-substring-no-properties (point-min) (point-max)) "\n" t) nil t))))))
(when include
(save-excursion
(goto-char (point-min))
(if (re-search-forward include nil t)
(message "\"%s\" is already included" include)
(goto-char (point-max))
(let ((head "\n")
(tail ""))
(if (re-search-backward "^# *include\\>" nil t)
(end-of-line)
(setq head "")
(setq tail "\n")
(goto-char (point-min)))
(insert head include tail))
(message "Added %s" include))))))))

(provide 'rtags)

Expand Down

0 comments on commit 749e9a4

Please sign in to comment.