瀏覽代碼

Vim: support specifying leader key via [editor]/vim_leader_key

Le Tan 7 年之前
父節點
當前提交
94828a65ad
共有 5 個文件被更改,包括 103 次插入0 次删除
  1. 4 0
      src/resources/vnote.ini
  2. 75 0
      src/utils/vvim.cpp
  3. 3 0
      src/utils/vvim.h
  4. 11 0
      src/vconfigmanager.cpp
  5. 10 0
      src/vconfigmanager.h

+ 4 - 0
src/resources/vnote.ini

@@ -262,6 +262,10 @@ key_mode=0
 ; Enable smart input method in Vim mode (disable IM in non-Insert modes)
 enable_smart_im_in_vim_mode=true
 
+; Leader key in Vim mode
+; Should be one character long
+vim_leader_key=" "
+
 [export]
 ; Path of the wkhtmltopdf tool
 wkhtmltopdf=wkhtmltopdf

+ 75 - 0
src/utils/vvim.cpp

@@ -83,6 +83,68 @@ static QChar keyToChar(int p_key, int p_modifiers)
     return ch;
 }
 
+#define ADDCHAR(x, y) case (x): {p_key = (y); break;}
+#define ADDCHAR_SHIFT(x, y) case (x): {p_key = (y); p_modifiers = Qt::ShiftModifier; break;}
+
+static void charToKey(const QChar &p_char, int &p_key, int &p_modifiers)
+{
+    p_modifiers = Qt::NoModifier;
+
+    ushort ucode = p_char.unicode();
+    if (ucode >= '0' && ucode <= '9') {
+        p_key = Qt::Key_0 + ucode - '0';
+        return;
+    } else if (ucode >= 'a' && ucode <= 'z') {
+        p_key = Qt::Key_A + ucode - 'a';
+        return;
+    } else if (ucode >= 'A' && ucode <= 'Z') {
+        p_key = Qt::Key_A + ucode - 'A';
+        p_modifiers = Qt::ShiftModifier;
+        return;
+    }
+
+    switch (p_char.unicode()) {
+    ADDCHAR('\t', Qt::Key_Tab);
+    ADDCHAR(' ', Qt::Key_Space);
+    ADDCHAR_SHIFT('!', Qt::Key_Exclam);
+    ADDCHAR_SHIFT('"', Qt::Key_QuoteDbl);
+    ADDCHAR_SHIFT('#', Qt::Key_NumberSign);
+    ADDCHAR_SHIFT('$', Qt::Key_Dollar);
+    ADDCHAR_SHIFT('%', Qt::Key_Percent);
+    ADDCHAR_SHIFT('&', Qt::Key_Ampersand);
+    ADDCHAR('\'', Qt::Key_Apostrophe);
+    ADDCHAR_SHIFT('(', Qt::Key_ParenLeft);
+    ADDCHAR_SHIFT(')', Qt::Key_ParenRight);
+    ADDCHAR_SHIFT('*', Qt::Key_Asterisk);
+    ADDCHAR_SHIFT('+', Qt::Key_Plus);
+    ADDCHAR(',', Qt::Key_Comma);
+    ADDCHAR('-', Qt::Key_Minus);
+    ADDCHAR('.', Qt::Key_Period);
+    ADDCHAR('/', Qt::Key_Slash);
+    ADDCHAR_SHIFT(':', Qt::Key_Colon);
+    ADDCHAR(';', Qt::Key_Semicolon);
+    ADDCHAR_SHIFT('<', Qt::Key_Less);
+    ADDCHAR('=', Qt::Key_Equal);
+    ADDCHAR_SHIFT('>', Qt::Key_Greater);
+    ADDCHAR_SHIFT('?', Qt::Key_Question);
+    ADDCHAR_SHIFT('@', Qt::Key_At);
+    ADDCHAR('[', Qt::Key_BracketLeft);
+    ADDCHAR('\\', Qt::Key_Backslash);
+    ADDCHAR(']', Qt::Key_BracketRight);
+    ADDCHAR_SHIFT('^', Qt::Key_AsciiCircum);
+    ADDCHAR_SHIFT('_', Qt::Key_Underscore);
+    ADDCHAR('`', Qt::Key_QuoteLeft);
+    ADDCHAR_SHIFT('{', Qt::Key_BraceLeft);
+    ADDCHAR_SHIFT('|', Qt::Key_Bar);
+    ADDCHAR_SHIFT('}', Qt::Key_BraceRight);
+    ADDCHAR_SHIFT('~', Qt::Key_AsciiTilde);
+
+    default:
+        p_key = -1;
+        break;
+    }
+}
+
 static QString keyToString(int p_key, int p_modifiers)
 {
     QChar ch = keyToChar(p_key, p_modifiers);
@@ -114,6 +176,8 @@ VVim::VVim(VEditor *p_editor)
 
     setMode(VimMode::Normal);
 
+    initLeaderKey();
+
     initRegisters();
 
     connect(m_editor->object(), &VEditorObject::mousePressed,
@@ -124,6 +188,17 @@ VVim::VVim(VEditor *p_editor)
             this, &VVim::handleMouseReleased);
 }
 
+void VVim::initLeaderKey()
+{
+    QChar ch = g_config->getVimLeaderKey();
+    Q_ASSERT(!ch.isNull());
+
+    int key, modifiers;
+    charToKey(ch, key, modifiers);
+    m_leaderKey = Key(key, modifiers);
+    qDebug() << "Vim leader key" << ch << key << modifiers;
+}
+
 // Set @p_cursor's position specified by @p_positionInBlock.
 // If @p_positionInBlock is bigger than the block's length, move to the end of block.
 // Need to setTextCursor() after calling this.

+ 3 - 0
src/utils/vvim.h

@@ -678,6 +678,9 @@ private:
     // of @p_cursor.
     void expandSelectionToWholeLines(QTextCursor &p_cursor);
 
+    // Init leader key from config.
+    void initLeaderKey();
+
     // Init m_registers.
     // Currently supported registers:
     // a-z, A-Z (append to a-z), ", +, _

+ 11 - 0
src/vconfigmanager.cpp

@@ -330,6 +330,17 @@ void VConfigManager::initEditorConfigs()
 
     m_enableSmartImInVimMode = getConfigFromSettings("editor",
                                                      "enable_smart_im_in_vim_mode").toBool();
+
+    QString tmpLeader = getConfigFromSettings("editor",
+                                              "vim_leader_key").toString();
+    if (tmpLeader.isEmpty()) {
+        m_vimLeaderKey = QChar(' ');
+    } else {
+        m_vimLeaderKey = tmpLeader[0];
+        if (m_vimLeaderKey.isNull()) {
+            m_vimLeaderKey = QChar(' ');
+        }
+    }
 }
 
 void VConfigManager::initSettings()

+ 10 - 0
src/vconfigmanager.h

@@ -545,6 +545,8 @@ public:
 
     const QString &getImageNamePrefix() const;
 
+    QChar getVimLeaderKey() const;
+
 private:
     // Look up a config from user and default settings.
     QVariant getConfigFromSettings(const QString &section, const QString &key) const;
@@ -979,6 +981,9 @@ private:
     // Max number of tag labels to display.
     int m_maxNumOfTagLabels;
 
+    // Vim leader key.
+    QChar m_vimLeaderKey;
+
     // The name of the config file in each directory.
     static const QString c_dirConfigFile;
 
@@ -2529,4 +2534,9 @@ inline int VConfigManager::getMaxNumOfTagLabels() const
 {
     return m_maxNumOfTagLabels;
 }
+
+inline QChar VConfigManager::getVimLeaderKey() const
+{
+    return m_vimLeaderKey;
+}
 #endif // VCONFIGMANAGER_H