Browse Source

vim-mode: auto disable input method in non-Insert mode

Add config "enable_smart_im_in_vim_mode".
Le Tan 8 years ago
parent
commit
c48d646a55
8 changed files with 112 additions and 23 deletions
  1. 3 0
      src/resources/vnote.ini
  2. 11 1
      src/utils/vvim.cpp
  3. 3 0
      src/vconfigmanager.cpp
  4. 22 0
      src/vconfigmanager.h
  5. 34 6
      src/vedit.cpp
  6. 10 0
      src/vedit.h
  7. 16 15
      src/veditoperations.cpp
  8. 13 1
      src/vmainwindow.cpp

+ 3 - 0
src/resources/vnote.ini

@@ -50,6 +50,9 @@ enable_trailing_space_highlight=true
 ; Enable Vim mode in edit mode
 enable_vim_mode=false
 
+; Enable smart input method in Vim mode (disable IM in non-Insert modes)
+enable_smart_im_in_vim_mode=true
+
 [session]
 tools_dock_checked=true
 

+ 11 - 1
src/utils/vvim.cpp

@@ -84,10 +84,14 @@ static QChar keyToChar(int p_key, int p_modifiers)
 
 VVim::VVim(VEdit *p_editor)
     : QObject(p_editor), m_editor(p_editor),
-      m_editConfig(&p_editor->getConfig()), m_mode(VimMode::Normal),
+      m_editConfig(&p_editor->getConfig()), m_mode(VimMode::Invalid),
       m_resetPositionInBlock(true), m_regName(c_unnamedRegister),
       m_cmdMode(false), m_leaderKey(Key(Qt::Key_Space)), m_replayLeaderSequence(false)
 {
+    Q_ASSERT(m_editConfig->m_enableVimMode);
+
+    setMode(VimMode::Normal);
+
     initRegisters();
 
     connect(m_editor, &VEdit::copyAvailable,
@@ -1969,6 +1973,12 @@ void VVim::setMode(VimMode p_mode, bool p_clearSelection)
             clearSelection();
         }
 
+        if (p_mode == VimMode::Insert) {
+            m_editor->setInputMethodEnabled(true);
+        } else if (vconfig.getEnableSmartImInVimMode()) {
+            m_editor->setInputMethodEnabled(false);
+        }
+
         m_mode = p_mode;
         resetState();
 

+ 3 - 0
src/vconfigmanager.cpp

@@ -147,6 +147,9 @@ void VConfigManager::initialize()
 
     m_enableVimMode = getConfigFromSettings("global",
                                             "enable_vim_mode").toBool();
+
+    m_enableSmartImInVimMode = getConfigFromSettings("global",
+                                                     "enable_smart_im_in_vim_mode").toBool();
 }
 
 void VConfigManager::readPredefinedColorsFromSettings()

+ 22 - 0
src/vconfigmanager.h

@@ -196,6 +196,9 @@ public:
     inline bool getEnableVimMode() const;
     inline void setEnableVimMode(bool p_enabled);
 
+    inline bool getEnableSmartImInVimMode() const;
+    inline void setEnableSmartImInVimMode(bool p_enabled);
+
     // Get the folder the ini file exists.
     QString getConfigFolder() const;
 
@@ -358,6 +361,9 @@ private:
     // Enable Vim mode.
     bool m_enableVimMode;
 
+    // Enable smart input method in Vim mode.
+    bool m_enableSmartImInVimMode;
+
     // The name of the config file in each directory, obsolete.
     // Use c_dirConfigFile instead.
     static const QString c_obsoleteDirConfigFile;
@@ -942,4 +948,20 @@ inline void VConfigManager::setEnableVimMode(bool p_enabled)
                         m_enableVimMode);
 }
 
+inline bool VConfigManager::getEnableSmartImInVimMode() const
+{
+    return m_enableSmartImInVimMode;
+}
+
+inline void VConfigManager::setEnableSmartImInVimMode(bool p_enabled)
+{
+    if (m_enableSmartImInVimMode == p_enabled) {
+        return;
+    }
+
+    m_enableSmartImInVimMode = p_enabled;
+    setConfigToSettings("global", "enable_smart_im_in_vim_mode",
+                        m_enableSmartImInVimMode);
+}
+
 #endif // VCONFIGMANAGER_H

+ 34 - 6
src/vedit.cpp

@@ -14,6 +14,15 @@ extern VConfigManager vconfig;
 extern VNote *g_vnote;
 
 void VEditConfig::init(const QFontMetrics &p_metric)
+{
+    update(p_metric);
+
+    m_enableVimMode = vconfig.getEnableVimMode();
+
+    m_highlightWholeBlock = m_enableVimMode;
+}
+
+void VEditConfig::update(const QFontMetrics &p_metric)
 {
     if (vconfig.getTabStopWidth() > 0) {
         m_tabStopWidth = vconfig.getTabStopWidth() * p_metric.width(' ');
@@ -29,15 +38,12 @@ void VEditConfig::init(const QFontMetrics &p_metric)
         m_tabSpaces = "\t";
     }
 
-    m_enableVimMode = vconfig.getEnableVimMode();
-
     m_cursorLineBg = QColor(vconfig.getEditorCurrentLineBg());
-
-    m_highlightWholeBlock = m_enableVimMode;
 }
 
 VEdit::VEdit(VFile *p_file, QWidget *p_parent)
-    : QTextEdit(p_parent), m_file(p_file), m_editOps(NULL)
+    : QTextEdit(p_parent), m_file(p_file),
+      m_editOps(NULL), m_enableInputMethod(true)
 {
     const int labelTimerInterval = 500;
     const int extraSelectionHighlightTimer = 500;
@@ -70,6 +76,7 @@ VEdit::VEdit(VFile *p_file, QWidget *p_parent)
 
     updateFontAndPalette();
 
+    m_config.init(QFontMetrics(font()));
     updateConfig();
 
     connect(this, &VEdit::cursorPositionChanged,
@@ -89,7 +96,7 @@ VEdit::~VEdit()
 
 void VEdit::updateConfig()
 {
-    m_config.init(QFontMetrics(font()));
+    m_config.update(QFontMetrics(font()));
 
     if (m_config.m_tabStopWidth > 0) {
         setTabStopWidth(m_config.m_tabStopWidth);
@@ -798,3 +805,24 @@ bool VEdit::jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat)
     Q_UNUSED(p_repeat);
     return false;
 }
+
+QVariant VEdit::inputMethodQuery(Qt::InputMethodQuery p_query) const
+{
+    if (p_query == Qt::ImEnabled) {
+        return m_enableInputMethod;
+    }
+
+    return QTextEdit::inputMethodQuery(p_query);
+}
+
+void VEdit::setInputMethodEnabled(bool p_enabled)
+{
+    if (m_enableInputMethod != p_enabled) {
+        m_enableInputMethod = p_enabled;
+
+        QInputMethod *im = QGuiApplication::inputMethod();
+        im->reset();
+        // Ask input method to query current state, which will call inputMethodQuery().
+        im->update(Qt::ImEnabled);
+    }
+}

+ 10 - 0
src/vedit.h

@@ -35,6 +35,9 @@ public:
 
     void init(const QFontMetrics &p_metric);
 
+    // Only update those configs which could be updated online.
+    void update(const QFontMetrics &p_metric);
+
     // Width in pixels.
     int m_tabStopWidth;
 
@@ -85,6 +88,10 @@ public:
     // Request to update Vim status.
     void requestUpdateVimStatus();
 
+    QVariant inputMethodQuery(Qt::InputMethodQuery p_query) const Q_DECL_OVERRIDE;
+
+    void setInputMethodEnabled(bool p_enabled);
+
 signals:
     // Request VEditTab to save and exit edit mode.
     void saveAndRead();
@@ -164,6 +171,9 @@ private:
     int m_oriMouseX;
     int m_oriMouseY;
 
+    // Whether enable input method.
+    bool m_enableInputMethod;
+
     void showWrapLabel();
 
     // Trigger the timer to request highlight.

+ 16 - 15
src/veditoperations.cpp

@@ -10,18 +10,21 @@ extern VConfigManager vconfig;
 
 VEditOperations::VEditOperations(VEdit *p_editor, VFile *p_file)
     : QObject(p_editor), m_editor(p_editor), m_file(p_file),
-      m_editConfig(&p_editor->getConfig())
+      m_editConfig(&p_editor->getConfig()), m_vim(NULL)
 {
-    m_vim = new VVim(m_editor);
-
     connect(m_editor, &VEdit::configUpdated,
             this, &VEditOperations::handleEditConfigUpdated);
-    connect(m_vim, &VVim::modeChanged,
-            this, &VEditOperations::handleVimModeChanged);
-    connect(m_vim, &VVim::vimMessage,
-            this, &VEditOperations::statusMessage);
-    connect(m_vim, &VVim::vimStatusUpdated,
-            this, &VEditOperations::vimStatusUpdated);
+
+    if (m_editConfig->m_enableVimMode) {
+        m_vim = new VVim(m_editor);
+
+        connect(m_vim, &VVim::modeChanged,
+                this, &VEditOperations::handleVimModeChanged);
+        connect(m_vim, &VVim::vimMessage,
+                this, &VEditOperations::statusMessage);
+        connect(m_vim, &VVim::vimStatusUpdated,
+                this, &VEditOperations::vimStatusUpdated);
+    }
 }
 
 void VEditOperations::insertTextAtCurPos(const QString &p_text)
@@ -70,7 +73,9 @@ void VEditOperations::updateCursorLineBg()
 void VEditOperations::handleEditConfigUpdated()
 {
     // Reset to Normal mode.
-    m_vim->setMode(VimMode::Normal);
+    if (m_vim) {
+        m_vim->setMode(VimMode::Normal);
+    }
 
     updateCursorLineBg();
 }
@@ -85,9 +90,5 @@ void VEditOperations::handleVimModeChanged(VimMode p_mode)
 
 void VEditOperations::requestUpdateVimStatus()
 {
-    if (m_editConfig->m_enableVimMode) {
-        emit vimStatusUpdated(m_vim);
-    } else {
-        emit vimStatusUpdated(NULL);
-    }
+    emit vimStatusUpdated(m_vim);
 }

+ 13 - 1
src/vmainwindow.cpp

@@ -661,11 +661,20 @@ void VMainWindow::initEditMenu()
 
     // Vim Mode.
     QAction *vimAct = new QAction(tr("Vim Mode"), this);
-    vimAct->setToolTip(tr("Enable Vim mode for editing (re-enter edit mode to make it work)"));
+    vimAct->setToolTip(tr("Enable Vim mode for editing (re-open current tabs to make it work)"));
     vimAct->setCheckable(true);
     connect(vimAct, &QAction::triggered,
             this, &VMainWindow::changeVimMode);
 
+    // Smart input method in Vim mode.
+    QAction *smartImAct = new QAction(tr("Smart Input Method In Vim Mode"), this);
+    smartImAct->setToolTip(tr("Disable input method when leaving Insert mode in Vim mode"));
+    smartImAct->setCheckable(true);
+    connect(smartImAct, &QAction::triggered,
+            this, [this](bool p_checked){
+                vconfig.setEnableSmartImInVimMode(p_checked);
+            });
+
     // Highlight current cursor line.
     QAction *cursorLineAct = new QAction(tr("Highlight Cursor Line"), this);
     cursorLineAct->setToolTip(tr("Highlight current cursor line"));
@@ -751,6 +760,9 @@ void VMainWindow::initEditMenu()
     editMenu->addAction(vimAct);
     vimAct->setChecked(vconfig.getEnableVimMode());
 
+    editMenu->addAction(smartImAct);
+    smartImAct->setChecked(vconfig.getEnableSmartImInVimMode());
+
     editMenu->addSeparator();
 
     initEditorStyleMenu(editMenu);