~ubuntu-branches/ubuntu/vivid/kate/vivid-proposed

« back to all changes in this revision

Viewing changes to addons/project/kateprojectindex.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2014-12-04 16:49:41 UTC
  • mfrom: (1.6.6)
  • Revision ID: package-import@ubuntu.com-20141204164941-l3qbvsly83hhlw2v
Tags: 4:14.11.97-0ubuntu1
* New upstream release
* Update build-deps and use pkg-kde v3 for Qt 5 build
* kate-data now kate5-data for co-installability

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  This file is part of the Kate project.
 
2
 *
 
3
 *  Copyright (C) 2012 Christoph Cullmann <cullmann@kde.org>
 
4
 *
 
5
 *  This library is free software; you can redistribute it and/or
 
6
 *  modify it under the terms of the GNU Library General Public
 
7
 *  License as published by the Free Software Foundation; either
 
8
 *  version 2 of the License, or (at your option) any later version.
 
9
 *
 
10
 *  This library is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 *  Library General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU Library General Public License
 
16
 *  along with this library; see the file COPYING.LIB.  If not, write to
 
17
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
18
 *  Boston, MA 02110-1301, USA.
 
19
 */
 
20
 
 
21
#include "kateprojectindex.h"
 
22
 
 
23
#include <QProcess>
 
24
#include <QDir>
 
25
 
 
26
/**
 
27
 * include ctags reading
 
28
 */
 
29
#include "ctags/readtags.c"
 
30
 
 
31
KateProjectIndex::KateProjectIndex(const QStringList &files)
 
32
    : m_ctagsIndexFile(QDir::tempPath() + QStringLiteral("/kate.project.ctags"))
 
33
    , m_ctagsIndexHandle(0)
 
34
{
 
35
    /**
 
36
     * load ctags
 
37
     */
 
38
    loadCtags(files);
 
39
}
 
40
 
 
41
KateProjectIndex::~KateProjectIndex()
 
42
{
 
43
    /**
 
44
     * delete ctags handle if any
 
45
     */
 
46
    if (m_ctagsIndexHandle) {
 
47
        tagsClose(m_ctagsIndexHandle);
 
48
        m_ctagsIndexHandle = 0;
 
49
    }
 
50
}
 
51
 
 
52
void KateProjectIndex::loadCtags(const QStringList &files)
 
53
{
 
54
    /**
 
55
     * create temporary file
 
56
     * if not possible, fail
 
57
     */
 
58
    if (!m_ctagsIndexFile.open()) {
 
59
        return;
 
60
    }
 
61
 
 
62
    /**
 
63
     * close file again, other process will use it
 
64
     */
 
65
    m_ctagsIndexFile.close();
 
66
 
 
67
    /**
 
68
     * try to run ctags for all files in this project
 
69
     * output to our ctags index file
 
70
     */
 
71
    QProcess ctags;
 
72
    QStringList args;
 
73
    args << QStringLiteral("-L") << QStringLiteral("-") << QStringLiteral("-f") << m_ctagsIndexFile.fileName() << QStringLiteral("--fields=+K+n");
 
74
    ctags.start(QStringLiteral("ctags"), args);
 
75
    if (!ctags.waitForStarted()) {
 
76
        return;
 
77
    }
 
78
 
 
79
    /**
 
80
     * write files list and close write channel
 
81
     */
 
82
    ctags.write(files.join(QStringLiteral("\n")).toLocal8Bit());
 
83
    ctags.closeWriteChannel();
 
84
 
 
85
    /**
 
86
     * wait for done
 
87
     */
 
88
    if (!ctags.waitForFinished()) {
 
89
        return;
 
90
    }
 
91
 
 
92
    /**
 
93
     * file not openable, bad
 
94
     */
 
95
    if (!m_ctagsIndexFile.open()) {
 
96
        return;
 
97
    }
 
98
 
 
99
    /**
 
100
     * get size
 
101
     */
 
102
    qint64 size = m_ctagsIndexFile.size();
 
103
 
 
104
    /**
 
105
     * close again
 
106
     */
 
107
    m_ctagsIndexFile.close();
 
108
 
 
109
    /**
 
110
     * empty file, bad
 
111
     */
 
112
    if (!size) {
 
113
        return;
 
114
    }
 
115
 
 
116
    /**
 
117
     * try to open ctags file
 
118
     */
 
119
    tagFileInfo info;
 
120
    memset(&info, 0, sizeof(tagFileInfo));
 
121
    m_ctagsIndexHandle = tagsOpen(m_ctagsIndexFile.fileName().toLocal8Bit().constData(), &info);
 
122
}
 
123
 
 
124
void KateProjectIndex::findMatches(QStandardItemModel &model, const QString &searchWord, MatchType type)
 
125
{
 
126
    /**
 
127
     * abort if no ctags index
 
128
     */
 
129
    if (!m_ctagsIndexHandle) {
 
130
        return;
 
131
    }
 
132
 
 
133
    /**
 
134
     * word to complete
 
135
     * abort if empty
 
136
     */
 
137
    QByteArray word = searchWord.toLocal8Bit();
 
138
    if (word.isEmpty()) {
 
139
        return;
 
140
    }
 
141
 
 
142
    /**
 
143
     * try to search entry
 
144
     * fail if none found
 
145
     */
 
146
    tagEntry entry;
 
147
    if (tagsFind(m_ctagsIndexHandle, &entry, word.constData(), TAG_PARTIALMATCH  | TAG_OBSERVECASE) != TagSuccess) {
 
148
        return;
 
149
    }
 
150
 
 
151
    /**
 
152
     * set to show words only once for completion matches
 
153
     */
 
154
    QSet<QString> guard;
 
155
 
 
156
    /**
 
157
     * loop over all found tags
 
158
     * first one is filled by above find, others by find next
 
159
     */
 
160
    do {
 
161
        /**
 
162
         * skip if no name
 
163
         */
 
164
        if (!entry.name) {
 
165
            continue;
 
166
        }
 
167
 
 
168
        /**
 
169
         * get name
 
170
         */
 
171
        QString name(QString::fromLocal8Bit(entry.name));
 
172
 
 
173
        /**
 
174
         * construct right items
 
175
         */
 
176
        switch (type) {
 
177
        case CompletionMatches:
 
178
            /**
 
179
             * add new completion item, if new name
 
180
             */
 
181
            if (!guard.contains(name)) {
 
182
                model.appendRow(new QStandardItem(name));
 
183
                guard.insert(name);
 
184
            }
 
185
            break;
 
186
 
 
187
        case FindMatches:
 
188
            /**
 
189
             * add new find item, contains of multiple columns
 
190
             */
 
191
            QList<QStandardItem *> items;
 
192
            items << new QStandardItem(name);
 
193
            items << new QStandardItem(entry.kind ? QString::fromLocal8Bit(entry.kind) : QString());
 
194
            items << new QStandardItem(entry.file ? QString::fromLocal8Bit(entry.file) : QString());
 
195
            items << new QStandardItem(QString::number(entry.address.lineNumber));
 
196
            model.appendRow(items);
 
197
            break;
 
198
        }
 
199
    } while (tagsFindNext(m_ctagsIndexHandle, &entry) == TagSuccess);
 
200
}
 
201