fakevimplugin.cpp 20 KB
Newer Older
1
/**************************************************************************
hjk's avatar
hjk committed
2
3
4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
hjk's avatar
hjk committed
6
7
8
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
9
** Commercial Usage
hjk's avatar
hjk committed
10
**
11
12
13
14
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
hjk's avatar
hjk committed
15
**
16
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17
**
18
19
20
21
22
23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
hjk's avatar
hjk committed
24
**
25
26
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
hjk's avatar
hjk committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29
30
31

#include "fakevimplugin.h"

32
#include "fakevimhandler.h"
hjk's avatar
hjk committed
33
34
#include "ui_fakevimoptions.h"

hjk's avatar
hjk committed
35

36
#include <coreplugin/actionmanager/actionmanager.h>
hjk's avatar
hjk committed
37
38
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
39
#include <coreplugin/filemanager.h>
hjk's avatar
hjk committed
40
#include <coreplugin/icore.h>
41
#include <coreplugin/ifile.h>
hjk's avatar
hjk committed
42
#include <coreplugin/dialogs/ioptionspage.h>
hjk's avatar
hjk committed
43
44
45
46
47
48
49
50
51
#include <coreplugin/messagemanager.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/uniqueidmanager.h>

#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/session.h>

#include <texteditor/basetexteditor.h>
#include <texteditor/basetextmark.h>
hjk's avatar
hjk committed
52
#include <texteditor/completionsupport.h>
hjk's avatar
hjk committed
53
54
#include <texteditor/itexteditor.h>
#include <texteditor/texteditorconstants.h>
55
56
#include <texteditor/tabsettings.h>
#include <texteditor/texteditorsettings.h>
57
#include <texteditor/textblockiterator.h>
hjk's avatar
hjk committed
58

59
60
#include <find/textfindconstants.h>

hjk's avatar
hjk committed
61
#include <utils/qtcassert.h>
hjk's avatar
hjk committed
62
#include <utils/savedaction.h>
hjk's avatar
hjk committed
63

64
65
#include <indenter.h>

hjk's avatar
hjk committed
66
#include <QtCore/QDebug>
67
#include <QtCore/QtPlugin>
hjk's avatar
hjk committed
68
69
70
71
#include <QtCore/QObject>
#include <QtCore/QPoint>
#include <QtCore/QSettings>

72
#include <QtGui/QMessageBox>
hjk's avatar
hjk committed
73
74
75
#include <QtGui/QPlainTextEdit>
#include <QtGui/QTextBlock>
#include <QtGui/QTextCursor>
76
#include <QtGui/QTextEdit>
hjk's avatar
hjk committed
77
78
79
80
81
82
83
84
85
86
87


using namespace FakeVim::Internal;
using namespace TextEditor;
using namespace Core;
using namespace ProjectExplorer;


namespace FakeVim {
namespace Constants {

88
89
const char * const INSTALL_HANDLER        = "TextEditor.FakeVimHandler";
const char * const MINI_BUFFER            = "TextEditor.FakeVimMiniBuffer";
hjk's avatar
hjk committed
90
91
92
93
94
95
const char * const INSTALL_KEY            = "Alt+V,Alt+V";

} // namespace Constants
} // namespace FakeVim


hjk's avatar
hjk committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
///////////////////////////////////////////////////////////////////////
//
// FakeVimOptionPage
//
///////////////////////////////////////////////////////////////////////

namespace FakeVim {
namespace Internal {

class FakeVimOptionPage : public Core::IOptionsPage
{
    Q_OBJECT

public:
    FakeVimOptionPage() {}

    // IOptionsPage
    QString id() const { return QLatin1String("General"); }
    QString trName() const { return tr("General"); }
    QString category() const { return QLatin1String("FakeVim"); }
    QString trCategory() const { return tr("FakeVim"); }

    QWidget *createPage(QWidget *parent);
    void apply() { m_group.apply(ICore::instance()->settings()); }
    void finish() { m_group.finish(); }

private slots:
    void copyTextEditorSettings();
    void setQtStyle();
    void setPlainStyle();

private:
    friend class DebuggerPlugin;
    Ui::FakeVimOptionPage m_ui;

    Core::Utils::SavedActionSet m_group;
};

QWidget *FakeVimOptionPage::createPage(QWidget *parent)
{
    QWidget *w = new QWidget(parent);
    m_ui.setupUi(w);

    m_group.clear();
    m_group.insert(theFakeVimSetting(ConfigUseFakeVim), 
        m_ui.checkBoxUseFakeVim);

    m_group.insert(theFakeVimSetting(ConfigExpandTab), 
        m_ui.checkBoxExpandTab);
    m_group.insert(theFakeVimSetting(ConfigHlSearch), 
        m_ui.checkBoxHlSearch);
    m_group.insert(theFakeVimSetting(ConfigShiftWidth), 
        m_ui.lineEditShiftWidth);

    m_group.insert(theFakeVimSetting(ConfigSmartTab), 
        m_ui.checkBoxSmartTab);
    m_group.insert(theFakeVimSetting(ConfigStartOfLine), 
        m_ui.checkBoxStartOfLine);
    m_group.insert(theFakeVimSetting(ConfigTabStop), 
        m_ui.lineEditTabStop);
    m_group.insert(theFakeVimSetting(ConfigBackspace), 
        m_ui.lineEditBackspace);

    m_group.insert(theFakeVimSetting(ConfigAutoIndent), 
        m_ui.checkBoxAutoIndent);

    connect(m_ui.pushButtonCopyTextEditorSettings, SIGNAL(clicked()),
hjk's avatar
hjk committed
163
        this, SLOT(copyTextEditorSettings()));
hjk's avatar
hjk committed
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
    connect(m_ui.pushButtonSetQtStyle, SIGNAL(clicked()),
        this, SLOT(setQtStyle()));
    connect(m_ui.pushButtonSetPlainStyle, SIGNAL(clicked()),
        this, SLOT(setPlainStyle()));

    return w;
}

void FakeVimOptionPage::copyTextEditorSettings()
{
    TextEditor::TabSettings ts = 
        TextEditor::TextEditorSettings::instance()->tabSettings();
    
    m_ui.checkBoxExpandTab->setChecked(ts.m_spacesForTabs);
    m_ui.lineEditTabStop->setText(QString::number(ts.m_tabSize));
    m_ui.lineEditShiftWidth->setText(QString::number(ts.m_indentSize));
    m_ui.checkBoxSmartTab->setChecked(ts.m_smartBackspace);
    m_ui.checkBoxAutoIndent->setChecked(ts.m_autoIndent);
}

void FakeVimOptionPage::setQtStyle()
{
    m_ui.checkBoxExpandTab->setChecked(true);
    m_ui.lineEditTabStop->setText("4");
    m_ui.lineEditShiftWidth->setText("4");
    m_ui.checkBoxSmartTab->setChecked(true);
    m_ui.checkBoxAutoIndent->setChecked(true);
hjk's avatar
hjk committed
191
    m_ui.lineEditBackspace->setText("indent,eol,start");
hjk's avatar
hjk committed
192
193
194
195
196
197
198
199
200
}

void FakeVimOptionPage::setPlainStyle()
{
    m_ui.checkBoxExpandTab->setChecked(false);
    m_ui.lineEditTabStop->setText("8");
    m_ui.lineEditShiftWidth->setText("8");
    m_ui.checkBoxSmartTab->setChecked(false);
    m_ui.checkBoxAutoIndent->setChecked(false);
hjk's avatar
hjk committed
201
    m_ui.lineEditBackspace->setText(QString());
hjk's avatar
hjk committed
202
203
204
205
206
207
}

} // namespace Internal
} // namespace FakeVim


hjk's avatar
hjk committed
208
209
///////////////////////////////////////////////////////////////////////
//
210
// FakeVimPluginPrivate
hjk's avatar
hjk committed
211
212
213
//
///////////////////////////////////////////////////////////////////////

214
215
216
217
namespace FakeVim {
namespace Internal {

class FakeVimPluginPrivate : public QObject
hjk's avatar
hjk committed
218
{
219
220
221
222
223
224
225
    Q_OBJECT

public:
    FakeVimPluginPrivate(FakeVimPlugin *);
    ~FakeVimPluginPrivate();
    friend class FakeVimPlugin;

226
    bool initialize();
227
228
229
230
231
    void shutdown();

private slots:
    void editorOpened(Core::IEditor *);
    void editorAboutToClose(Core::IEditor *);
232

233
    void setUseFakeVim(const QVariant &value);
234
    void quitFakeVim();
235
    void triggerCompletions();
hjk's avatar
hjk committed
236
    void windowCommand(int key);
237
    void find(bool reverse);
hjk's avatar
hjk committed
238
    void showSettingsDialog();
239
240
241
242
243

    void showCommandBuffer(const QString &contents);
    void showExtraInformation(const QString &msg);
    void changeSelection(const QList<QTextEdit::ExtraSelection> &selections);
    void writeFile(bool *handled, const QString &fileName, const QString &contents);
hjk's avatar
hjk committed
244
    void quitFile(bool forced);
245
    void quitAllFiles(bool forced);
246
    void moveToMatchingParenthesis(bool *moved, bool *forward, QTextCursor *cursor);
hjk's avatar
hjk committed
247
    void indentRegion(int *amount, int beginLine, int endLine,  QChar typedChar);
248
249
250

private:
    FakeVimPlugin *q;
hjk's avatar
hjk committed
251
    FakeVimOptionPage *m_fakeVimOptionsPage;
252
    QHash<Core::IEditor *, FakeVimHandler *> m_editorToHandler;
253
254

    void triggerAction(const QString& code);
255
256
257
258
259
260
261
262
};

} // namespace Internal
} // namespace FakeVim

FakeVimPluginPrivate::FakeVimPluginPrivate(FakeVimPlugin *plugin)
{       
    q = plugin;
hjk's avatar
hjk committed
263
    m_fakeVimOptionsPage = 0;
hjk's avatar
hjk committed
264
265
}

266
267
268
FakeVimPluginPrivate::~FakeVimPluginPrivate()
{
}
hjk's avatar
hjk committed
269

270
void FakeVimPluginPrivate::shutdown()
hjk's avatar
hjk committed
271
{
hjk's avatar
hjk committed
272
273
274
275
    q->removeObject(m_fakeVimOptionsPage);
    delete m_fakeVimOptionsPage;
    m_fakeVimOptionsPage = 0;
    theFakeVimSettings()->writeSettings(Core::ICore::instance()->settings());
hjk's avatar
hjk committed
276
277
}

278
bool FakeVimPluginPrivate::initialize()
hjk's avatar
hjk committed
279
{
hjk's avatar
hjk committed
280
    Core::ActionManager *actionManager = Core::ICore::instance()->actionManager();
hjk's avatar
hjk committed
281
282
283
284
285
    QTC_ASSERT(actionManager, return false);

    QList<int> globalcontext;
    globalcontext << Core::Constants::C_GLOBAL_ID;

hjk's avatar
hjk committed
286
287
288
    m_fakeVimOptionsPage = new FakeVimOptionPage;
    q->addObject(m_fakeVimOptionsPage);
    theFakeVimSettings()->readSettings(Core::ICore::instance()->settings());
hjk's avatar
hjk committed
289
    
con's avatar
con committed
290
    Core::Command *cmd = 0;
291
    cmd = actionManager->registerAction(theFakeVimSetting(ConfigUseFakeVim),
hjk's avatar
hjk committed
292
293
294
        Constants::INSTALL_HANDLER, globalcontext);
    cmd->setDefaultKeySequence(QKeySequence(Constants::INSTALL_KEY));

295
    ActionContainer *advancedMenu =
hjk's avatar
hjk committed
296
        actionManager->actionContainer(Core::Constants::M_EDIT_ADVANCED);
297
    advancedMenu->addAction(cmd, Core::Constants::G_EDIT_EDITOR);
hjk's avatar
hjk committed
298

299
    // EditorManager
hjk's avatar
hjk committed
300
    QObject *editorManager = Core::ICore::instance()->editorManager();
301
302
303
304
305
    connect(editorManager, SIGNAL(editorAboutToClose(Core::IEditor*)),
        this, SLOT(editorAboutToClose(Core::IEditor*)));
    connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)),
        this, SLOT(editorOpened(Core::IEditor*)));

hjk's avatar
hjk committed
306
307
    connect(theFakeVimSetting(SettingsDialog), SIGNAL(triggered()),
        this, SLOT(showSettingsDialog()));
308
309
    connect(theFakeVimSetting(ConfigUseFakeVim), SIGNAL(valueChanged(QVariant)),
        this, SLOT(setUseFakeVim(QVariant)));
hjk's avatar
hjk committed
310

hjk's avatar
hjk committed
311
312
313
    return true;
}

hjk's avatar
hjk committed
314
315
316
317
318
void FakeVimPluginPrivate::showSettingsDialog()
{
    Core::ICore::instance()->showOptionsDialog("FakeVim", "General");
}

319
320
321
322
323
324
325
326
327
328
329
void FakeVimPluginPrivate::triggerAction(const QString& code)
{
    Core::ActionManager *am = Core::ICore::instance()->actionManager();
    QTC_ASSERT(am, return);
    Core::Command *cmd = am->command(code);
    QTC_ASSERT(cmd, return);
    QAction *action = cmd->action();
    QTC_ASSERT(action, return);
    action->trigger();
}

hjk's avatar
hjk committed
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
void FakeVimPluginPrivate::windowCommand(int key)
{
    #define control(n) (256 + n)
    QString code;
    switch (key) {
        case 'c': case 'C': case control('c'):
            code = Core::Constants::CLOSE;
            break;
        case 'n': case 'N': case control('n'):
            code = Core::Constants::GOTONEXT;
            break;
        case 'o': case 'O': case control('o'):
            code = Core::Constants::REMOVE_ALL_SPLITS;
            code = Core::Constants::REMOVE_CURRENT_SPLIT;
            break;
        case 'p': case 'P': case control('p'):
            code = Core::Constants::GOTOPREV;
            break;
        case 's': case 'S': case control('s'):
            code = Core::Constants::SPLIT;
            break;
        case 'w': case 'W': case control('w'):
            code = Core::Constants::GOTO_OTHER_SPLIT;
            break;
    }
    #undef control
    qDebug() << "RUNNING WINDOW COMMAND: " << key << code;
    if (code.isEmpty()) {
        qDebug() << "UNKNOWN WINDOWS COMMAND: " << key;
        return;
    }
361
362
363
364
365
366
367
    triggerAction(code);
}

void FakeVimPluginPrivate::find(bool reverse)
{
    Q_UNUSED(reverse);  // TODO: Creator needs an action for find in reverse.
    triggerAction(Find::Constants::FIND_IN_DOCUMENT);
hjk's avatar
hjk committed
368
369
}

370
void FakeVimPluginPrivate::editorOpened(Core::IEditor *editor)
371
{
372
373
374
    if (!editor)
        return;

375
    QWidget *widget = editor->widget();
376
377
    if (!widget)
        return;
378
379
380
381

    // we can only handle QTextEdit and QPlainTextEdit
    if (!qobject_cast<QTextEdit *>(widget) && !qobject_cast<QPlainTextEdit *>(widget))
        return;
382
    
383
384
385
    //qDebug() << "OPENING: " << editor << editor->widget()
    //    << "MODE: " << theFakeVimSetting(ConfigUseFakeVim)->value();

386
    FakeVimHandler *handler = new FakeVimHandler(widget, widget);
387
    m_editorToHandler[editor] = handler;
388
389
390
391

    connect(handler, SIGNAL(extraInformationChanged(QString)),
        this, SLOT(showExtraInformation(QString)));
    connect(handler, SIGNAL(commandBufferChanged(QString)),
hjk's avatar
hjk committed
392
        this, SLOT(showCommandBuffer(QString)));
hjk's avatar
hjk committed
393
394
    connect(handler, SIGNAL(quitRequested(bool)),
        this, SLOT(quitFile(bool)), Qt::QueuedConnection);
395
396
    connect(handler, SIGNAL(quitAllRequested(bool)),
        this, SLOT(quitAllFiles(bool)), Qt::QueuedConnection);
397
398
399
400
    connect(handler, SIGNAL(writeFileRequested(bool*,QString,QString)),
        this, SLOT(writeFile(bool*,QString,QString)));
    connect(handler, SIGNAL(selectionChanged(QList<QTextEdit::ExtraSelection>)),
        this, SLOT(changeSelection(QList<QTextEdit::ExtraSelection>)));
401
402
    connect(handler, SIGNAL(moveToMatchingParenthesis(bool*,bool*,QTextCursor*)),
        this, SLOT(moveToMatchingParenthesis(bool*,bool*,QTextCursor*)));
hjk's avatar
hjk committed
403
404
    connect(handler, SIGNAL(indentRegion(int*,int,int,QChar)),
        this, SLOT(indentRegion(int*,int,int,QChar)));
405
406
    connect(handler, SIGNAL(completionRequested()),
        this, SLOT(triggerCompletions()));
hjk's avatar
hjk committed
407
408
    connect(handler, SIGNAL(windowCommandRequested(int)),
        this, SLOT(windowCommand(int)));
409
410
    connect(handler, SIGNAL(findRequested(bool)),
        this, SLOT(find(bool)));
411

hjk's avatar
hjk committed
412
    handler->setCurrentFileName(editor->file()->fileName());
413
    handler->installEventFilter();
414
415
416
417
    
    // pop up the bar
    if (theFakeVimSetting(ConfigUseFakeVim)->value().toBool())
       showCommandBuffer("");
hjk's avatar
hjk committed
418
419
}

420
void FakeVimPluginPrivate::editorAboutToClose(Core::IEditor *editor)
hjk's avatar
hjk committed
421
{
422
423
424
425
426
427
    //qDebug() << "CLOSING: " << editor << editor->widget();
    m_editorToHandler.remove(editor);
}

void FakeVimPluginPrivate::setUseFakeVim(const QVariant &value)
{
428
    //qDebug() << "SET USE FAKEVIM" << value;
429
430
431
432
433
    bool on = value.toBool();
    if (on) {
        Core::EditorManager::instance()->showEditorStatusBar( 
            QLatin1String(Constants::MINI_BUFFER), 
            "vi emulation mode. Type :q to leave. Use , Ctrl-R to trigger run.",
434
            tr("Quit FakeVim"), this, SLOT(quitFakeVim()));
435
436
437
438
439
440
441
442
        foreach (Core::IEditor *editor, m_editorToHandler.keys())
            m_editorToHandler[editor]->setupWidget();
    } else {
        Core::EditorManager::instance()->hideEditorStatusBar(
            QLatin1String(Constants::MINI_BUFFER));
        foreach (Core::IEditor *editor, m_editorToHandler.keys())
            m_editorToHandler[editor]->restoreWidget();
    }
hjk's avatar
hjk committed
443
444
}

445
446
447
448
449
450
void FakeVimPluginPrivate::triggerCompletions()
{
    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (!handler)
        return;
    if (BaseTextEditor *bt = qobject_cast<BaseTextEditor *>(handler->widget()))
hjk's avatar
hjk committed
451
452
453
        TextEditor::Internal::CompletionSupport::instance()->
            autoComplete(bt->editableInterface(), false);
   //     bt->triggerCompletions();
454
455
}

hjk's avatar
hjk committed
456
void FakeVimPluginPrivate::quitFile(bool forced)
457
458
459
460
461
462
{
    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (!handler)
        return;
    QList<Core::IEditor *> editors;
    editors.append(m_editorToHandler.key(handler));
hjk's avatar
hjk committed
463
    Core::EditorManager::instance()->closeEditors(editors, !forced);
464
465
}

466
467
468
469
470
void FakeVimPluginPrivate::quitAllFiles(bool forced)
{
    Core::EditorManager::instance()->closeAllEditors(!forced);
}

471
472
void FakeVimPluginPrivate::writeFile(bool *handled,
    const QString &fileName, const QString &contents)
473
{
474
475
    Q_UNUSED(contents);

476
477
478
479
    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (!handler)
        return;

480
    Core::IEditor *editor = m_editorToHandler.key(handler);
481
    if (editor && editor->file()->fileName() == fileName) {
hjk's avatar
hjk committed
482
        // Handle that as a special case for nicer interaction with core
483
        Core::IFile *file = editor->file();
hjk's avatar
hjk committed
484
        Core::ICore::instance()->fileManager()->blockFileChange(file);
485
        file->save(fileName);
hjk's avatar
hjk committed
486
        Core::ICore::instance()->fileManager()->unblockFileChange(file);
487
488
        *handled = true;
    } 
489
490
}

491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
void FakeVimPluginPrivate::moveToMatchingParenthesis(bool *moved, bool *forward,
        QTextCursor *cursor)
{
    *moved = false;

    bool undoFakeEOL = false;
    if (cursor->atBlockEnd() && cursor->block().length() > 1) {
        cursor->movePosition(QTextCursor::Left, QTextCursor::KeepAnchor, 1);
        undoFakeEOL = true;
    }
    TextEditor::TextBlockUserData::MatchType match
        = TextEditor::TextBlockUserData::matchCursorForward(cursor);
    if (match == TextEditor::TextBlockUserData::Match) {
        *moved = true;
        *forward = true;
   } else {
        if (undoFakeEOL)
            cursor->movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 1);
        if (match == TextEditor::TextBlockUserData::NoMatch) {
            // backward matching is according to the character before the cursor
            bool undoMove = false;
            if (!cursor->atBlockEnd()) {
                cursor->movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 1);
                undoMove = true;
            }
            match = TextEditor::TextBlockUserData::matchCursorBackward(cursor);
            if (match == TextEditor::TextBlockUserData::Match) {
                *moved = true;
                *forward = false;
            } else if (undoMove) {
                cursor->movePosition(QTextCursor::Left, QTextCursor::KeepAnchor, 1);
            }
        }
    }
}

hjk's avatar
hjk committed
527
void FakeVimPluginPrivate::indentRegion(int *amount, int beginLine, int endLine,
528
529
530
531
532
533
534
535
536
537
      QChar typedChar)
{
    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (!handler)
        return;

    BaseTextEditor *bt = qobject_cast<BaseTextEditor *>(handler->widget());
    if (!bt)
        return;

hjk's avatar
hjk committed
538
539
    TextEditor::TabSettings tabSettings = 
        TextEditor::TextEditorSettings::instance()->tabSettings();
540
541
    typedef SharedTools::Indenter<TextEditor::TextBlockIterator> Indenter;
    Indenter &indenter = Indenter::instance();
hjk's avatar
hjk committed
542
543
    indenter.setIndentSize(tabSettings.m_indentSize);
    indenter.setTabSize(tabSettings.m_tabSize);
544

hjk's avatar
hjk committed
545
546
547
    const QTextDocument *doc = bt->document();
    QTextBlock begin = doc->findBlockByNumber(beginLine);
    QTextBlock end = doc->findBlockByNumber(endLine);
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
    const TextEditor::TextBlockIterator docStart(doc->begin());
    QTextBlock cur = begin;
    do {
        if (typedChar == 0 && cur.text().simplified().isEmpty()) {
            *amount = 0;
            if (cur != end) {
                QTextCursor cursor(cur);
                while (!cursor.atBlockEnd())
                    cursor.deleteChar();
            }
        } else {
            const TextEditor::TextBlockIterator current(cur);
            const TextEditor::TextBlockIterator next(cur.next());
            *amount = indenter.indentForBottomLine(current, docStart, next, typedChar);
            if (cur != end)
hjk's avatar
hjk committed
563
                tabSettings.indentLine(cur, *amount);
564
565
566
567
568
569
        }
        if (cur != end)
           cur = cur.next();
    } while (cur != end);
}

570
void FakeVimPluginPrivate::quitFakeVim()
571
{
hjk's avatar
hjk committed
572
    theFakeVimSetting(ConfigUseFakeVim)->setValue(false);
573
574
}

575
void FakeVimPluginPrivate::showCommandBuffer(const QString &contents)
hjk's avatar
hjk committed
576
{
577
578
579
    //qDebug() << "SHOW COMMAND BUFFER" << contents;
    Core::EditorManager::instance()->showEditorStatusBar( 
        QLatin1String(Constants::MINI_BUFFER), contents,
580
        tr("Quit FakeVim"), this, SLOT(quitFakeVim()));
hjk's avatar
hjk committed
581
582
}

583
void FakeVimPluginPrivate::showExtraInformation(const QString &text)
584
{
585
586
587
    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (handler)
        QMessageBox::information(handler->widget(), tr("FakeVim Information"), text);
588
589
}

590
591
void FakeVimPluginPrivate::changeSelection
    (const QList<QTextEdit::ExtraSelection> &selection)
592
{
593
594
595
    if (FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender()))
        if (BaseTextEditor *bt = qobject_cast<BaseTextEditor *>(handler->widget()))
            bt->setExtraSelections(BaseTextEditor::FakeVimSelection, selection);
596
597
}

598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613

///////////////////////////////////////////////////////////////////////
//
// FakeVimPlugin
//
///////////////////////////////////////////////////////////////////////

FakeVimPlugin::FakeVimPlugin()
    : d(new FakeVimPluginPrivate(this))
{}

FakeVimPlugin::~FakeVimPlugin()
{
    delete d;
}

614
bool FakeVimPlugin::initialize(const QStringList &arguments, QString *errorMessage)
615
{
616
617
618
    Q_UNUSED(arguments);
    Q_UNUSED(errorMessage);
    return d->initialize();
619
620
621
622
623
624
625
626
627
628
629
630
}

void FakeVimPlugin::shutdown()
{
    d->shutdown();
}

void FakeVimPlugin::extensionsInitialized()
{
}

#include "fakevimplugin.moc"
hjk's avatar
hjk committed
631
632

Q_EXPORT_PLUGIN(FakeVimPlugin)