Commit 8560036d authored by nsf's avatar nsf Committed by hjk

Add EmacsKeys plugin.

A very simple non-intrusive plugin. Adds a bunch of actions typical emacs user
would expect. Doesn't contain any default key bindings.

Change-Id: Ib30fb46c577e2fdfd4c704e7f4eee7ee27a53c29
Reviewed-by: default avatarChristian Kandeler <christian.kandeler@digia.com>
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
Reviewed-by: default avatarEike Ziller <eike.ziller@digia.com>
parent faca3333
<plugin name=\"EmacsKeys\" version=\"$$QTCREATOR_VERSION\" compatVersion=\"$$QTCREATOR_COMPAT_VERSION\" experimental=\"true\">
<vendor>nsf</vendor>
<copyright>(C) nsf &lt;no.smile.face@gmail.com&gt;</copyright>
<license>
Commercial Usage
Licensees holding valid Qt Commercial licenses may use this plugin 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 Digia.
GNU Lesser General Public License Usage
Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. 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.
</license>
<description>
The main idea behind this plugin is to provide additional actions a typical emacs user would expect. It doesn&#39;t claim to provide full emacs emulation. The following actions are available:
- Movement [C-f, C-b, C-n, C-p, M-f, M-b, C-a, C-e, M-&lt;, M-&gt;]
- Mark-based selection [C-SPC, C-x C-x]
- Cut/copy/yank (doesn&#39;t provide kill ring feature) [M-w, C-w, C-y]
- Kill actions, which interact properly with clipboard [C-k, M-d, C-d]
- Scrolling (half of the screen, keeps cursor visible) [C-v, M-v]
- Insert new line and indent [C-j]
IMPORTANT: Actions are not bound to any key combinations by default. You can find them under &#39;EmacsKeys&#39; section in keyboard shortcuts settings.
Also it&#39;s worth mentioning that EmacsKeys plugin forces disabling of menu mnemonics by calling Qt&#39;s qt_set_sequence_auto_mnemonic function with false argument. Many of the english menu mnemonics get into the way of typical emacs keys, this includes: Alt+F (File), Alt+B (Build), Alt+W (Window). It&#39;s a temporary solution, it remains until there is a better one.
</description>
<url>http://nosmileface.ru</url>
$$dependencyList
</plugin>
include(../../qtcreatorplugin.pri)
SOURCES += \
emacskeysplugin.cpp \
emacskeysstate.cpp
HEADERS += \
emacskeysplugin.h \
emacskeysconstants.h \
emacskeysstate.h
import qbs.base 1.0
import QtcPlugin
QtcPlugin {
name: "EmacsKeys"
Depends { name: "Qt.widgets" }
Depends { name: "Core" }
Depends { name: "TextEditor" }
files: [
"emacskeysplugin.cpp",
"emacskeysplugin.h",
"emacskeysstate.cpp",
"emacskeysstate.h",
"emacskeysconstants.h",
]
}
QTC_PLUGIN_NAME = EmacsKeys
QTC_PLUGIN_DEPENDS += \
coreplugin \
texteditor
/**************************************************************************
**
** Copyright (c) nsf <no.smile.face@gmail.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef EMACSKEYSCONSTANTS_H
#define EMACSKEYSCONSTANTS_H
namespace EmacsKeys {
namespace Constants {
const char DELETE_CHARACTER[] = "EmacsKeys.DeleteCharacter";
const char KILL_WORD[] = "EmacsKeys.KillWord";
const char KILL_LINE[] = "EmacsKeys.KillLine";
const char INSERT_LINE_AND_INDENT[] = "EmacsKeys.InsertLineAndIndent";
const char GOTO_FILE_START[] = "EmacsKeys.GotoFileStart";
const char GOTO_FILE_END[] = "EmacsKeys.GotoFileEnd";
const char GOTO_LINE_START[] = "EmacsKeys.GotoLineStart";
const char GOTO_LINE_END[] = "EmacsKeys.GotoLineEnd";
const char GOTO_NEXT_LINE[] = "EmacsKeys.GotoNextLine";
const char GOTO_PREVIOUS_LINE[] = "EmacsKeys.GotoPreviousLine";
const char GOTO_NEXT_CHARACTER[] = "EmacsKeys.GotoNextCharacter";
const char GOTO_PREVIOUS_CHARACTER[] = "EmacsKeys.GotoPreviousCharacter";
const char GOTO_NEXT_WORD[] = "EmacsKeys.GotoNextWord";
const char GOTO_PREVIOUS_WORD[] = "EmacsKeys.GotoPreviousWord";
const char MARK[] = "EmacsKeys.Mark";
const char EXCHANGE_CURSOR_AND_MARK[] = "EmacsKeys.ExchangeCursorAndMark";
const char COPY[] = "EmacsKeys.Copy";
const char CUT[] = "EmacsKeys.Cut";
const char YANK[] = "EmacsKeys.Yank";
const char SCROLL_HALF_DOWN[] = "EmacsKeys.ScrollHalfDown";
const char SCROLL_HALF_UP[] = "EmacsKeys.ScrollHalfUp";
} // namespace EmacsKeys
} // namespace Constants
#endif // EMACSKEYSCONSTANTS_H
This diff is collapsed.
/**************************************************************************
**
** Copyright (c) nsf <no.smile.face@gmail.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef EMACSKEYS_H
#define EMACSKEYS_H
#include <extensionsystem/iplugin.h>
#include <QTextCursor>
// forward declarations
QT_FORWARD_DECLARE_CLASS(QAction)
QT_FORWARD_DECLARE_CLASS(QPlainTextEdit)
namespace Core {
class Id;
class IEditor;
}
namespace TextEditor {
class BaseTextEditorWidget;
}
namespace EmacsKeys {
namespace Internal {
class EmacsKeysState;
class EmacsKeysPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "EmacsKeys.json")
public:
EmacsKeysPlugin();
~EmacsKeysPlugin();
bool initialize(const QStringList &arguments, QString *errorString);
void extensionsInitialized();
ShutdownFlag aboutToShutdown();
private slots:
void editorAboutToClose(Core::IEditor *editor);
void currentEditorChanged(Core::IEditor *editor);
void deleteCharacter(); // C-d
void killWord(); // M-d
void killLine(); // C-k
void insertLineAndIndent(); // C-j
void gotoFileStart(); // M-<
void gotoFileEnd(); // M->
void gotoLineStart(); // C-a
void gotoLineEnd(); // C-e
void gotoNextLine(); // C-n
void gotoPreviousLine(); // C-p
void gotoNextCharacter(); // C-f
void gotoPreviousCharacter(); // C-b
void gotoNextWord(); // M-f
void gotoPreviousWord(); // M-b
void mark(); // C-SPC
void exchangeCursorAndMark(); // C-x C-x
void copy(); // M-w
void cut(); // C-w
void yank(); // C-y
void scrollHalfDown(); // C-v
void scrollHalfUp(); // M-v
private:
QAction *registerAction(const Core::Id &id, const char *slot,
const QString &title);
void genericGoto(QTextCursor::MoveOperation op, bool abortAssist = true);
void genericVScroll(int direction);
QHash<QPlainTextEdit*, EmacsKeysState*> m_stateMap;
QPlainTextEdit *m_currentEditorWidget;
EmacsKeysState *m_currentState;
TextEditor::BaseTextEditorWidget *m_currentBaseTextEditorWidget;
};
} // namespace Internal
} // namespace EmacsKeys
#endif // EMACSKEYS_H
/**************************************************************************
**
** Copyright (c) nsf <no.smile.face@gmail.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "emacskeysstate.h"
#include <QTextCursor>
#include <QPlainTextEdit>
using namespace EmacsKeys::Internal;
//---------------------------------------------------------------------------
// EmacsKeysState
//---------------------------------------------------------------------------
EmacsKeysState::EmacsKeysState(QPlainTextEdit *edit):
m_ignore3rdParty(false),
m_mark(-1),
m_lastAction(KeysAction3rdParty),
m_editorWidget(edit)
{
connect(edit, SIGNAL(cursorPositionChanged()),
this, SLOT(cursorPositionChanged()));
connect(edit, SIGNAL(textChanged()),
this, SLOT(textChanged()));
connect(edit, SIGNAL(selectionChanged()),
this, SLOT(selectionChanged()));
}
EmacsKeysState::~EmacsKeysState() {}
void EmacsKeysState::setLastAction(EmacsKeysAction action)
{
if (m_mark != -1) {
// this code can be triggered only by 3rd party actions
beginOwnAction();
QTextCursor cursor = m_editorWidget->textCursor();
cursor.clearSelection();
m_editorWidget->setTextCursor(cursor);
m_mark = -1;
endOwnAction(action);
} else {
m_lastAction = action;
}
}
void EmacsKeysState::cursorPositionChanged() {
if (!m_ignore3rdParty)
setLastAction(KeysAction3rdParty);
}
void EmacsKeysState::textChanged() {
if (!m_ignore3rdParty)
setLastAction(KeysAction3rdParty);
}
void EmacsKeysState::selectionChanged()
{
if (!m_ignore3rdParty)
setLastAction(KeysAction3rdParty);
}
/**************************************************************************
**
** Copyright (c) nsf <no.smile.face@gmail.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef EMACSKEYSSTATE_H
#define EMACSKEYSSTATE_H
#include <QObject>
QT_FORWARD_DECLARE_CLASS(QPlainTextEdit)
namespace EmacsKeys {
namespace Internal {
enum EmacsKeysAction {
KeysAction3rdParty,
KeysActionKillWord,
KeysActionKillLine,
KeysActionOther,
};
class EmacsKeysState : public QObject
{
Q_OBJECT
public:
EmacsKeysState(QPlainTextEdit *edit);
~EmacsKeysState();
void setLastAction(EmacsKeysAction action);
void beginOwnAction() { m_ignore3rdParty = true; }
void endOwnAction(EmacsKeysAction action) {
m_ignore3rdParty = false;
m_lastAction = action;
}
EmacsKeysAction lastAction() const { return m_lastAction; }
int mark() const { return m_mark; }
void setMark(int mark) { m_mark = mark; }
private slots:
void cursorPositionChanged();
void textChanged();
void selectionChanged();
private:
bool m_ignore3rdParty;
int m_mark;
EmacsKeysAction m_lastAction;
QPlainTextEdit *m_editorWidget;
};
} // namespace Internal
} // namespace EmacsKeys
#endif // EMACSKEYSSTATE_H
......@@ -27,6 +27,7 @@ SUBDIRS = \
cmakeprojectmanager \
autotoolsprojectmanager \
fakevim \
emacskeys \
designer \
resourceeditor \
genericprojectmanager \
......
......@@ -28,6 +28,7 @@ Project {
"designer/designer.qbs",
"diffeditor/diffeditor.qbs",
"fakevim/fakevim.qbs",
"emacskeys/emacskeys.qbs",
"find/find.qbs",
"genericprojectmanager/genericprojectmanager.qbs",
"git/git.qbs",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment