From 18f4a22ea79c3cca879fdd22db157884b81792db Mon Sep 17 00:00:00 2001 From: pit-ray Date: Thu, 14 Jul 2022 23:39:17 +0900 Subject: [PATCH 01/22] add placeholder --- src/core/autocmd.cpp | 9 +++++++++ src/core/autocmd.hpp | 4 ++++ 2 files changed, 13 insertions(+) create mode 100644 src/core/autocmd.cpp create mode 100644 src/core/autocmd.hpp diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp new file mode 100644 index 00000000..d672a60f --- /dev/null +++ b/src/core/autocmd.cpp @@ -0,0 +1,9 @@ +#include "autocmd.hpp" + +namespace vind +{ + namespace core + { + + } +} diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp new file mode 100644 index 00000000..56f40c53 --- /dev/null +++ b/src/core/autocmd.hpp @@ -0,0 +1,4 @@ +#ifndef _AUTOCMD_HPP +#define _AUTOCMD_HPP + +#endif From 0b19c7476897bcc418f314e6660f05b202758a4b Mon Sep 17 00:00:00 2001 From: pit-ray Date: Fri, 15 Jul 2022 22:33:46 +0900 Subject: [PATCH 02/22] add event enum --- src/core/autocmd.hpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp index 56f40c53..4197c1d0 100644 --- a/src/core/autocmd.hpp +++ b/src/core/autocmd.hpp @@ -1,4 +1,37 @@ #ifndef _AUTOCMD_HPP #define _AUTOCMD_HPP +namespace vind +{ + namespace core + { + enum class AutocmdEvent { + WinEnter, + WinLeave, + + // GUI + GNormalEnter, + GNormalLeave, + GVisualEnter, + GVisualLeave, + + // Editor + ENormalEnter, + ENormalLeave, + EVisualEnter, + EVisualLeave, + + InsertEnter, + InsertLeave, + + ResidentEnter, + ResidentLeave, + + CmdLineEnter, + CmdLineLeave + } ; + + } +} + #endif From ee6328ebb8d8edb0dfc06288019bda580ba86b01 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Fri, 15 Jul 2022 22:52:42 +0900 Subject: [PATCH 03/22] add a function to get event enum from string event name --- src/core/autocmd.cpp | 35 ++++++++++++++++++++++++++ src/core/autocmd.hpp | 46 +++++++++++++++++------------------ tests/normal/CMakeLists.txt | 2 +- tests/normal/autocmd_test.cpp | 13 ++++++++++ 4 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 tests/normal/autocmd_test.cpp diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index d672a60f..03f8eb52 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -1,9 +1,44 @@ #include "autocmd.hpp" +#include +#include + +namespace +{ + class AutoCmd { + + } ; + + class AutoPat { + std::vector cmds_ ; + + } ; +} namespace vind { namespace core { + AutoCmdEvent get_autocmd_event(const std::string& event_name) { + static std::unordered_map names { + {"WinEnter", AutoCmdEvent::WIN_ENTER}, + {"WinLeave", AutoCmdEvent::WIN_LEAVE}, + {"GUINormalEnter", AutoCmdEvent::GUI_NORMAL_ENTER}, + {"GUINormalLeave", AutoCmdEvent::GUI_NORMAL_LEAVE}, + {"GUIVisualEnter", AutoCmdEvent::GUI_VISUAL_ENTER}, + {"GUIVisualLeave", AutoCmdEvent::GUI_VISUAL_LEAVE}, + {"EdiNormalEnter", AutoCmdEvent::EDI_NORMAL_ENTER}, + {"EdiNormalLeave", AutoCmdEvent::EDI_NORMAL_LEAVE}, + {"EdiVisualEnter", AutoCmdEvent::EDI_VISUAL_ENTER}, + {"EdiVisualLeave", AutoCmdEvent::EDI_VISUAL_LEAVE}, + {"InsertEnter", AutoCmdEvent::INSERT_ENTER}, + {"InsertLeave", AutoCmdEvent::INSERT_LEAVE}, + {"ResidentEnter", AutoCmdEvent::RESIDENT_ENTER}, + {"ResidentLeave", AutoCmdEvent::RESIDENT_LEAVE}, + {"CmdLineEnter", AutoCmdEvent::CMDLINE_ENTER}, + {"CmdLineLeave", AutoCmdEvent::CMDLINE_LEAVE} + } ; + return names.at(event_name) ; + } } } diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp index 4197c1d0..72e9acb6 100644 --- a/src/core/autocmd.hpp +++ b/src/core/autocmd.hpp @@ -1,36 +1,34 @@ #ifndef _AUTOCMD_HPP #define _AUTOCMD_HPP +#include + + namespace vind { namespace core { - enum class AutocmdEvent { - WinEnter, - WinLeave, - - // GUI - GNormalEnter, - GNormalLeave, - GVisualEnter, - GVisualLeave, - - // Editor - ENormalEnter, - ENormalLeave, - EVisualEnter, - EVisualLeave, - - InsertEnter, - InsertLeave, - - ResidentEnter, - ResidentLeave, - - CmdLineEnter, - CmdLineLeave + enum class AutoCmdEvent { + WIN_ENTER, + WIN_LEAVE, + GUI_NORMAL_ENTER, + GUI_NORMAL_LEAVE, + GUI_VISUAL_ENTER, + GUI_VISUAL_LEAVE, + EDI_NORMAL_ENTER, + EDI_NORMAL_LEAVE, + EDI_VISUAL_ENTER, + EDI_VISUAL_LEAVE, + INSERT_ENTER, + INSERT_LEAVE, + RESIDENT_ENTER, + RESIDENT_LEAVE, + CMDLINE_ENTER, + CMDLINE_LEAVE } ; + + AutoCmdEvent get_autocmd_event(const std::string& event_name) ; } } diff --git a/tests/normal/CMakeLists.txt b/tests/normal/CMakeLists.txt index c161f5ac..2a22e550 100644 --- a/tests/normal/CMakeLists.txt +++ b/tests/normal/CMakeLists.txt @@ -1,3 +1,3 @@ cmake_minimum_required(VERSION 3.0.0) -file(GLOB NORMAL_TEST_CODES LIST_DIRECTORIES false ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) +file(GLOB NORMAL_TEST_CODES LIST_DIRECTORIES false ${CMAKE_CURRENT_SOURCE_DIR}/*_test.cpp) AddTest(normal-test ${NORMAL_TEST_CODES}) diff --git a/tests/normal/autocmd_test.cpp b/tests/normal/autocmd_test.cpp new file mode 100644 index 00000000..918d4a22 --- /dev/null +++ b/tests/normal/autocmd_test.cpp @@ -0,0 +1,13 @@ +#include + +#include "core/autocmd.cpp" + + +TEST_SUITE("core/autocmd") { + TEST_CASE("get_autocmd_event") { + using namespace vind::core ; + + CHECK_EQ(get_autocmd_event("WinEnter"), AutoCmdEvent::WIN_ENTER) ; + CHECK_THROWS(get_autocmd_event("----")) ; + } +} From a7f94086ab7da309dfe1b89d15eca033776965b6 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Fri, 15 Jul 2022 23:04:38 +0900 Subject: [PATCH 04/22] add run command index --- src/core/autocmd.cpp | 3 +-- src/core/rcparser.cpp | 14 ++++++++++++++ src/core/rcparser.hpp | 2 ++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index 03f8eb52..50af5be5 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -8,9 +8,8 @@ namespace } ; - class AutoPat { + struct AutoPat { std::vector cmds_ ; - } ; } diff --git a/src/core/rcparser.cpp b/src/core/rcparser.cpp index 7a8287a8..bc12aad0 100644 --- a/src/core/rcparser.cpp +++ b/src/core/rcparser.cpp @@ -193,6 +193,20 @@ namespace vind {"sour", RunCommandsIndex::SOURCE}, {"sou", RunCommandsIndex::SOURCE}, {"so", RunCommandsIndex::SOURCE}, + + {"autocmd", RunCommandsIndex::AUTOCMD}, + {"autocm", RunCommandsIndex::AUTOCMD}, + {"autoc", RunCommandsIndex::AUTOCMD}, + {"auto", RunCommandsIndex::AUTOCMD}, + {"aut", RunCommandsIndex::AUTOCMD}, + {"au", RunCommandsIndex::AUTOCMD}, + + {"autocmd!", RunCommandsIndex::AUTOCMD_REMOVE}, + {"autocm!", RunCommandsIndex::AUTOCMD_REMOVE}, + {"autoc!", RunCommandsIndex::AUTOCMD_REMOVE}, + {"auto!", RunCommandsIndex::AUTOCMD_REMOVE}, + {"aut!", RunCommandsIndex::AUTOCMD_REMOVE}, + {"au!", RunCommandsIndex::AUTOCMD_REMOVE}, } ; for(std::size_t i = 0 ; i < mode_num() ; i ++) { diff --git a/src/core/rcparser.hpp b/src/core/rcparser.hpp index 67daf3d5..5e190cfc 100644 --- a/src/core/rcparser.hpp +++ b/src/core/rcparser.hpp @@ -86,6 +86,8 @@ namespace vind SOURCE, + AUTOCMD, + AUTOCMD_REMOVE, MASK_MODE = 0b0000'1111, From 413464bb5f5e49d0dba5bf7cad340bd70b5b29e6 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Sun, 17 Jul 2022 00:48:20 +0900 Subject: [PATCH 05/22] add autocmd singleton --- src/core/autocmd.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++-- src/core/autocmd.hpp | 26 +++++++++++++++++-- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index 50af5be5..53e0ea17 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -1,15 +1,36 @@ #include "autocmd.hpp" +#include "bind/bindedfunc.hpp" +#include "lgrparser.hpp" +#include "maptable.hpp" + +#include +#include #include #include + namespace { - class AutoCmd { + using namespace vind ; + struct SequentialCmd { + int a = 0 ; } ; struct AutoPat { - std::vector cmds_ ; + std::vector cmds_ ; + + explicit AutoPat() + : cmds_() + {} + } ; + + struct AutoEvent { + std::unordered_map pats_ ; + + explicit AutoEvent() + : pats_() + {} } ; } @@ -39,5 +60,41 @@ namespace vind return names.at(event_name) ; } + struct AutoCmd::Impl { + std::array(AutoCmdEvent::EVENT_NUM)> events_ ; + + explicit Impl() + : events_() + {} + } ; + + AutoCmd::AutoCmd() + : pimpl(std::make_unique()) + {} + + AutoCmd::~AutoCmd() noexcept = default ; + + AutoCmd& AutoCmd::get_instance() { + static AutoCmd instance{} ; + return instance ; + } + + void AutoCmd::add_autocmd( + AutoCmdEvent event, + const std::string& pattern, + const std::string& cmd) { + + } + + void AutoCmd::apply_autocmds(AutoCmdEvent event) { + auto evt = pimpl->events_[static_cast(event)] ; + + // Get the path for executable file of the foreground window. + + // Check pattern + + // Do sequential command + + } } } diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp index 72e9acb6..c7358686 100644 --- a/src/core/autocmd.hpp +++ b/src/core/autocmd.hpp @@ -1,6 +1,7 @@ #ifndef _AUTOCMD_HPP #define _AUTOCMD_HPP +#include #include @@ -8,7 +9,7 @@ namespace vind { namespace core { - enum class AutoCmdEvent { + enum class AutoCmdEvent : unsigned char { WIN_ENTER, WIN_LEAVE, GUI_NORMAL_ENTER, @@ -24,11 +25,32 @@ namespace vind RESIDENT_ENTER, RESIDENT_LEAVE, CMDLINE_ENTER, - CMDLINE_LEAVE + CMDLINE_LEAVE, + + EVENT_NUM } ; AutoCmdEvent get_autocmd_event(const std::string& event_name) ; + + class AutoCmd { + private: + struct Impl ; + std::unique_ptr pimpl ; + + explicit AutoCmd() ; + virtual ~AutoCmd() noexcept ; + + public: + static AutoCmd& get_instance() ; + + void add_autocmd( + AutoCmdEvent event, + const std::string& pattern, + const std::string& cmd) ; + + void apply_autocmds(AutoCmdEvent event) ; + } ; } } From 7e79f8f46592517866f33ea0fe185c9c0a76d72f Mon Sep 17 00:00:00 2001 From: pit-ray Date: Sun, 17 Jul 2022 23:44:29 +0900 Subject: [PATCH 06/22] add some placeholder --- src/core/autocmd.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index 53e0ea17..8b79d9b7 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -17,20 +17,24 @@ namespace int a = 0 ; } ; - struct AutoPat { - std::vector cmds_ ; - - explicit AutoPat() - : cmds_() - {} - } ; - - struct AutoEvent { - std::unordered_map pats_ ; + class AutoEvent { + private: + std::unordered_map pats_ ; + public: explicit AutoEvent() : pats_() {} + + void add_pattern_cmd(const std::string& pat, const SequentialCmd& cmd) { + } + + bool has_pattern(const std::string& pat) { + } + + const SequentialCmd& get_sequential_cmd(const std::string& pat) { + return pats_.at(pat) ; + } } ; } From 2c932f55e3a682d0731e6205fe4b699251800ecd Mon Sep 17 00:00:00 2001 From: pit-ray Date: Wed, 25 Jan 2023 23:01:08 +0900 Subject: [PATCH 07/22] fix defects --- src/core/autocmd.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index 5eb9f239..a94e9a6f 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -28,6 +28,7 @@ namespace } bool has_pattern(const std::string& pat) { + return true ; } const SequentialCmd& get_sequential_cmd(const std::string& pat) { From 76474fcb82a08d259706b0f1186808fd2c152747 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Sun, 6 Aug 2023 21:00:44 +0900 Subject: [PATCH 08/22] add AutoEvent and AutoPattern --- src/bind/mode/change_mode.cpp | 6 ++ src/bind/proc/openwin.cpp | 16 +-- src/bind/window/arrange_win.cpp | 12 ++- src/core/autocmd.cpp | 173 ++++++++++++++++++++++++++++---- src/core/autocmd.hpp | 45 ++++++++- src/core/entry.cpp | 3 + src/core/mode.cpp | 1 + src/core/path.cpp | 11 +- src/util/winwrap.cpp | 48 ++++++--- src/util/winwrap.hpp | 4 + 10 files changed, 265 insertions(+), 54 deletions(-) diff --git a/src/bind/mode/change_mode.cpp b/src/bind/mode/change_mode.cpp index 75a8073b..6767967c 100644 --- a/src/bind/mode/change_mode.cpp +++ b/src/bind/mode/change_mode.cpp @@ -1,6 +1,7 @@ #include "change_mode.hpp" #include "bind/emu/textsel.hpp" +#include "core/autocmd.hpp" #include "core/errlogger.hpp" #include "core/inputgate.hpp" #include "core/keycodedef.hpp" @@ -35,6 +36,9 @@ namespace vind return ; } + auto& ac = core::AutoCmd::get_instance() ; + ac.apply_autocmds(core::get_leave_event(m)) ; + if(m == Mode::GUI_VISUAL) { util::click(KEYCODE_MOUSE_LEFT) ; //release holding mouse } @@ -52,6 +56,8 @@ namespace vind if(vclmodeout) { opt::VCmdLine::print(opt::GeneralMessage("-- GUI NORMAL --")) ; } + + ac.apply_autocmds(core::get_enter_event(Mode::GUI_NORMAL)) ; } //ToResident diff --git a/src/bind/proc/openwin.cpp b/src/bind/proc/openwin.cpp index 5cb3427c..7a18701e 100644 --- a/src/bind/proc/openwin.cpp +++ b/src/bind/proc/openwin.cpp @@ -4,6 +4,8 @@ #include +#include + #include "core/path.hpp" #include "util/def.hpp" #include "util/winwrap.hpp" @@ -24,24 +26,24 @@ namespace vind DWORD proc_id = 0 ; GetWindowThreadProcessId(hwnd, &proc_id) ; - HANDLE hproc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, proc_id) ; - if(!hproc) { + HANDLE hproc_raw = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, proc_id) ; + if(!hproc_raw) { throw RUNTIME_EXCEPT("OpenProcess Failed.") ; } + auto close_handle = [](HANDLE handle) {CloseHandle(handle) ;} ; + std::unique_ptr hproc(hproc_raw, close_handle) ; + HMODULE hmod = NULL ; DWORD cbneed = 0 ; - if(!EnumProcessModules(hproc, &hmod, sizeof(HMODULE), &cbneed)) { - CloseHandle(hproc) ; + if(!EnumProcessModules(hproc.get(), &hmod, sizeof(HMODULE), &cbneed)) { throw RUNTIME_EXCEPT("Cannot enumerate process modules.") ; } WCHAR path[MAX_PATH] = {0} ; - if(!GetModuleFileNameExW(hproc, hmod, path, MAX_PATH)) { - CloseHandle(hproc) ; + if(!GetModuleFileNameExW(hproc.get(), hmod, path, MAX_PATH)) { throw RUNTIME_EXCEPT("Cannot get a process path of current window.") ; } - CloseHandle(hproc) ; util::create_process(core::HOME_PATH(), util::ws_to_s(path)) ; Sleep(100) ; diff --git a/src/bind/window/arrange_win.cpp b/src/bind/window/arrange_win.cpp index af9f8592..798a7056 100644 --- a/src/bind/window/arrange_win.cpp +++ b/src/bind/window/arrange_win.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -58,22 +59,23 @@ namespace DWORD proc_id = 0 ; GetWindowThreadProcessId(hwnd, &proc_id) ; - HANDLE hproc = OpenProcess( + HANDLE hproc_raw = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, proc_id) ; - if(!hproc) { + if(!hproc_raw) { return TRUE ; //has not permission } + auto close_handle = [](HANDLE handle) {CloseHandle(handle) ;} ; + std::unique_ptr hproc(hproc_raw, close_handle) ; + PROCESS_MEMORY_COUNTERS pmc ; - if(!GetProcessMemoryInfo(hproc, &pmc, sizeof(pmc))) { - CloseHandle(hproc) ; + if(!GetProcessMemoryInfo(hproc.get(), &pmc, sizeof(pmc))) { std::stringstream ss ; ss << "Could not get the memory infomation of " << hwnd ; PRINT_ERROR(ss.str()) ; return FALSE ; //break } - CloseHandle(hproc) ; //a key is unique and described the priority. auto& ordered_hwnd = g_m_ordered_hwnd[minfo.hmonitor] ; diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index a94e9a6f..639e9033 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -1,38 +1,119 @@ #include "autocmd.hpp" -#include "bind/bindedfunc.hpp" + +#include "cmdparser.hpp" +#include "cmdunit.hpp" +#include "util/winwrap.hpp" #include #include +#include #include +#include +#include #include +#include + namespace { using namespace vind ; - struct SequentialCmd { - int a = 0 ; + class AutoPattern { + private: + std::string pat_ ; + std::regex re_ ; + + public: + explicit AutoPattern() + : AutoPattern("") + {} + + explicit AutoPattern(const std::string& pat) + : pat_(pat), + re_(pat) + {} + + explicit AutoPattern(std::string&& pat) + : pat_(std::move(pat)), + re_(pat_) + {} + + // Match a query with the pattern and returns the match score. + // The higher score denotes more specified matching. + int match(const std::string& query) { + if(pat_.length() == 1 && pat_.front() == '*') { + return 1 ; + } + + if(std::regex_match(query, re_)) { + return 2 ; + } + + return 0 ; + } + + const std::string& get() const noexcept { + return pat_ ; + } } ; + using SequentialCmd = std::vector> ; + class AutoEvent { private: - std::unordered_map pats_ ; + std::vector pats_ ; + std::vector seqcmds_ ; + SequentialCmd empty_ ; + + int get_pat_index(const std::string& query) { + for(int i = 0 ; i < pats_.size() ; i ++) { + if(pats_[i].get() == query) { + return i ; + } + } + return -1 ; + } public: explicit AutoEvent() - : pats_() + : pats_(), + seqcmds_(), + empty_() {} - void add_pattern_cmd(const std::string& pat, const SequentialCmd& cmd) { + template + void add_pattern_cmd(T1&& pat, T2&& cmd) { + auto idx = get_pat_index(pat) ; + if(idx < 0) { + pats_.emplace_back(std::forward(pat)) ; + seqcmds_.push_back({std::forward(cmd)}) ; + } + else { + seqcmds_[idx].push_back(std::forward(cmd)) ; + } } - bool has_pattern(const std::string& pat) { - return true ; + int match_pattern(const std::string& query) { + int highest_index = -1 ; + int highest_score = 0 ; + for(int i = 0 ; i < pats_.size() ; i ++) { + auto score = pats_[i].match(query) ; + if(highest_score < score) { + highest_index = i ; + } + } + + return highest_index ; } - const SequentialCmd& get_sequential_cmd(const std::string& pat) { - return pats_.at(pat) ; + void call_sequential_cmd(int patidx) { + for(const auto& cmd : seqcmds_[patidx]) { + std::cout << "call: " << cmd << std::endl ; + for(const auto& unit : cmd) { + unit->execute(1) ; + } + } } } ; } @@ -57,8 +138,8 @@ namespace vind {"InsertLeave", AutoCmdEvent::INSERT_LEAVE}, {"ResidentEnter", AutoCmdEvent::RESIDENT_ENTER}, {"ResidentLeave", AutoCmdEvent::RESIDENT_LEAVE}, - {"CmdLineEnter", AutoCmdEvent::CMDLINE_ENTER}, - {"CmdLineLeave", AutoCmdEvent::CMDLINE_LEAVE} + {"CommandEnter", AutoCmdEvent::COMMAND_ENTER}, + {"CommandLeave", AutoCmdEvent::COMMAND_LEAVE} } ; return names.at(event_name) ; } @@ -83,21 +164,71 @@ namespace vind } void AutoCmd::add_autocmd( - AutoCmdEvent event, - const std::string& pattern, - const std::string& cmd) { - + AutoCmdEvent event, + const std::string& pattern, + const std::string& cmdstr) { + if(event == AutoCmdEvent::UNDEFINED) { + return ; + } + + if(pattern.empty()) { + return ; + } + + auto cmd = parse_command(cmdstr) ; + if(cmd.empty()) { + return ; + } + + pimpl->events_[static_cast(event)].add_pattern_cmd(pattern, std::move(cmd)) ; } void AutoCmd::apply_autocmds(AutoCmdEvent event) { + if(event == AutoCmdEvent::UNDEFINED) { + return ; + } + auto evt = pimpl->events_[static_cast(event)] ; // Get the path for executable file of the foreground window. - - // Check pattern - - // Do sequential command - + auto hwnd = util::get_foreground_window() ; + DWORD procid ; + GetWindowThreadProcessId(hwnd, &procid) ; + + auto h_snap_raw = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ; + if(h_snap_raw == INVALID_HANDLE_VALUE) { + return ; + } + auto close_snap = [](HANDLE handle) {CloseHandle(handle) ;} ; + std::unique_ptr h_snap(h_snap_raw, close_snap) ; + + PROCESSENTRY32 pe32 ; + pe32.dwSize = sizeof(PROCESSENTRY32) ; + if(!Process32First(h_snap.get(), &pe32)) { + return ; + } + + std::unordered_set parent_set{procid} ; + std::unordered_set pat_indices{} ; + do { + // Enumerate only child processs + if(parent_set.find(pe32.th32ParentProcessID) != parent_set.end()) { + // Check pattern and execute sequential command + auto path = util::get_module_path(pe32.th32ProcessID) ; + auto patidx = evt.match_pattern(path) ; + if(patidx >= 0) { + pat_indices.insert(patidx) ; + } + + parent_set.insert(pe32.th32ProcessID) ; + } + } while(Process32Next(h_snap.get(), &pe32)) ; + + if(!pat_indices.empty()) { + for(auto patidx : pat_indices) { + evt.call_sequential_cmd(patidx) ; + } + } } } } diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp index c7358686..49d5e1e1 100644 --- a/src/core/autocmd.hpp +++ b/src/core/autocmd.hpp @@ -1,8 +1,13 @@ #ifndef _AUTOCMD_HPP #define _AUTOCMD_HPP +#include "mode.hpp" + +#include + #include #include +#include namespace vind @@ -24,15 +29,47 @@ namespace vind INSERT_LEAVE, RESIDENT_ENTER, RESIDENT_LEAVE, - CMDLINE_ENTER, - CMDLINE_LEAVE, + COMMAND_ENTER, + COMMAND_LEAVE, - EVENT_NUM + EVENT_NUM, + UNDEFINED, } ; - AutoCmdEvent get_autocmd_event(const std::string& event_name) ; + inline AutoCmdEvent get_leave_event(Mode mode) noexcept { + static const std::unordered_map leave_events { + {Mode::GUI_NORMAL, AutoCmdEvent::GUI_NORMAL_LEAVE}, + {Mode::GUI_VISUAL, AutoCmdEvent::GUI_VISUAL_LEAVE}, + {Mode::EDI_NORMAL, AutoCmdEvent::EDI_NORMAL_LEAVE}, + {Mode::EDI_VISUAL, AutoCmdEvent::EDI_VISUAL_LEAVE}, + {Mode::INSERT, AutoCmdEvent::INSERT_LEAVE}, + {Mode::RESIDENT, AutoCmdEvent::RESIDENT_LEAVE}, + {Mode::COMMAND, AutoCmdEvent::COMMAND_LEAVE} + } ; + if(leave_events.find(mode) != leave_events.end()) { + return leave_events.at(mode) ; + } + return AutoCmdEvent::UNDEFINED ; + } + + inline AutoCmdEvent get_enter_event(Mode mode) noexcept { + static const std::unordered_map enter_events { + {Mode::GUI_NORMAL, AutoCmdEvent::GUI_NORMAL_ENTER}, + {Mode::GUI_VISUAL, AutoCmdEvent::GUI_VISUAL_ENTER}, + {Mode::EDI_NORMAL, AutoCmdEvent::EDI_NORMAL_ENTER}, + {Mode::EDI_VISUAL, AutoCmdEvent::EDI_VISUAL_ENTER}, + {Mode::INSERT, AutoCmdEvent::INSERT_ENTER}, + {Mode::RESIDENT, AutoCmdEvent::RESIDENT_ENTER}, + {Mode::COMMAND, AutoCmdEvent::COMMAND_ENTER} + } ; + if(enter_events.find(mode) != enter_events.end()) { + return enter_events.at(mode) ; + } + return AutoCmdEvent::UNDEFINED ; + } + class AutoCmd { private: struct Impl ; diff --git a/src/core/entry.cpp b/src/core/entry.cpp index 062b49c3..722a0642 100644 --- a/src/core/entry.cpp +++ b/src/core/entry.cpp @@ -61,6 +61,7 @@ SOFTWARE. #include #include +#include "autocmd.hpp" #include "background.hpp" #include "cmdmatcher.hpp" @@ -287,6 +288,8 @@ namespace vind catch(const std::out_of_range&) { handle_system_call(cm.at("i")->process()) ; } + + AutoCmd::get_instance().add_autocmd(AutoCmdEvent::GUI_NORMAL_ENTER, ".*vim.*", "") ; } void VindEntry::reconstruct() { diff --git a/src/core/mode.cpp b/src/core/mode.cpp index 54e1f463..dc25e788 100644 --- a/src/core/mode.cpp +++ b/src/core/mode.cpp @@ -31,6 +31,7 @@ namespace void set_mode(Mode mode, ModeFlags flags) noexcept { std::lock_guard scoped_lock{mtx_} ; + mode_ = mode ; flags_ = flags ; } diff --git a/src/core/path.cpp b/src/core/path.cpp index 958d51d3..3bb38ceb 100644 --- a/src/core/path.cpp +++ b/src/core/path.cpp @@ -55,18 +55,19 @@ namespace vind const std::filesystem::path& HOME_PATH() { static const auto obj = [] { - HANDLE token ; - if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { + HANDLE token_raw ; + if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token_raw)) { throw RUNTIME_EXCEPT("Could not open process token.") ; } + auto close_token = [](HANDLE token) {CloseHandle(token) ;} ; + std::unique_ptr token(token_raw, close_token) ; + WCHAR path[MAX_PATH] = {0} ; DWORD size = MAX_PATH ; - if(!GetUserProfileDirectoryW(token, path, &size)) { - CloseHandle(token) ; + if(!GetUserProfileDirectoryW(token.get(), path, &size)) { throw RUNTIME_EXCEPT("Could not get the home directory.") ; } - CloseHandle(token) ; return std::filesystem::path(path) ; } () ; diff --git a/src/util/winwrap.cpp b/src/util/winwrap.cpp index 0b15b41f..f82cb569 100644 --- a/src/util/winwrap.cpp +++ b/src/util/winwrap.cpp @@ -85,13 +85,15 @@ namespace vind + "in the current directory \"" + current_dir.u8string() + "\".") ; } + auto close_handle = [](HANDLE handle) {CloseHandle(handle) ;} ; + std::unique_ptr h_thread(pi.hThread, close_handle) ; + std::unique_ptr h_process(pi.hProcess, close_handle) ; + if(wait_until_finish) { - if(WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_FAILED) { + if(WaitForSingleObject(h_process.get(), INFINITE) == WAIT_FAILED) { PRINT_ERROR("Failed to wait until process end.") ; } } - CloseHandle(pi.hThread) ; - CloseHandle(pi.hProcess) ; } void create_process( @@ -145,19 +147,41 @@ namespace vind NULL, NULL, SW_SHOWNORMAL))) ; } - std::string get_module_filename(HWND hwnd) { - DWORD procid ; - GetWindowThreadProcessId(hwnd, &procid) ; - - auto handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, procid) ; + std::filesystem::path _get_module_path(DWORD procid) { + auto handle_raw = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, procid) ; + if(handle_raw == NULL) { + throw RUNTIME_EXCEPT("Could not open process.") ; + } + auto close_handle = [](HANDLE handle) {CloseHandle(handle) ;} ; + std::unique_ptr handle(handle_raw, close_handle) ; WCHAR fullpath[MAX_PATH] ; - if(!GetModuleFileNameExW(handle, NULL, fullpath, MAX_PATH)) { - CloseHandle(handle) ; + if(!GetModuleFileNameExW(handle.get(), NULL, fullpath, MAX_PATH)) { throw RUNTIME_EXCEPT("Could not get module filename.") ; } - CloseHandle(handle) ; - return std::filesystem::path(fullpath).filename().u8string() ; + return std::filesystem::path(fullpath) ; + } + + std::filesystem::path _get_module_path(HWND hwnd) { + DWORD procid ; + GetWindowThreadProcessId(hwnd, &procid) ; + return _get_module_path(procid) ; + } + + std::string get_module_filename(HWND hwnd) { + return _get_module_path(hwnd).filename().u8string() ; + } + + std::string get_module_filename(DWORD procid) { + return _get_module_path(procid).filename().u8string() ; + } + + std::string get_module_path(HWND hwnd) { + return _get_module_path(hwnd).u8string() ; + } + + std::string get_module_path(DWORD procid) { + return _get_module_path(procid).u8string() ; } bool is_failed(HRESULT result) noexcept { diff --git a/src/util/winwrap.hpp b/src/util/winwrap.hpp index d1a22b5a..dc5c3500 100644 --- a/src/util/winwrap.hpp +++ b/src/util/winwrap.hpp @@ -50,6 +50,10 @@ namespace vind int shell_execute(const std::filesystem::path& url) ; std::string get_module_filename(HWND hwnd) ; + std::string get_module_filename(DWORD procid) ; + + std::string get_module_path(HWND hwnd) ; + std::string get_module_path(DWORD procid) ; // Wrapper SystemParametersInfo template From 1075e38617824d9c5fc112ad7acbf10a57917e50 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Sun, 6 Aug 2023 22:54:42 +0900 Subject: [PATCH 09/22] add WinEnter and WinLeave --- src/bind/emu/deltext.cpp | 3 + src/bind/emu/puttext.cpp | 3 + src/bind/emu/replacetext.cpp | 3 + src/bind/emu/textutil.cpp | 3 + src/bind/file/explorer_util.cpp | 3 + src/bind/mode/change_mode.cpp | 43 +++++++++++-- src/bind/mode/command_mode.cpp | 9 ++- src/bind/mode/instant_mode.cpp | 7 ++ src/bind/mouse/easyclick.cpp | 4 ++ src/bind/mouse/jump_actwin.cpp | 4 ++ src/bind/proc/openwin.cpp | 3 + src/bind/syscmd/autocmd.cpp | 0 src/bind/syscmd/autocmd.hpp | 4 ++ src/bind/window/arrange_win.cpp | 3 + src/bind/window/minmax_win.cpp | 3 + src/bind/window/select_win.cpp | 3 + src/bind/window/snap_win.cpp | 3 + src/bind/window/split_win.cpp | 14 ++++ src/bind/window/winresizer.cpp | 4 ++ src/core/autocmd.cpp | 111 ++++++++++++++++++++++---------- src/core/autocmd.hpp | 5 +- src/core/entry.cpp | 20 +++++- src/opt/blockstylecaret.cpp | 4 +- src/opt/uiacachebuild.cpp | 3 + src/util/winwrap.cpp | 2 + 25 files changed, 220 insertions(+), 44 deletions(-) create mode 100644 src/bind/syscmd/autocmd.cpp create mode 100644 src/bind/syscmd/autocmd.hpp diff --git a/src/bind/emu/deltext.cpp b/src/bind/emu/deltext.cpp index 32c15a77..541bdb52 100644 --- a/src/bind/emu/deltext.cpp +++ b/src/bind/emu/deltext.cpp @@ -80,6 +80,9 @@ namespace vind if(res.str.empty()) { // clear clipboard with null auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + throw std::runtime_error("There is no foreground window.") ; + } SmartClipboard scb(hwnd) ; scb.open() ; scb.set("") ; diff --git a/src/bind/emu/puttext.cpp b/src/bind/emu/puttext.cpp index 644e4c3e..563a80e7 100644 --- a/src/bind/emu/puttext.cpp +++ b/src/bind/emu/puttext.cpp @@ -17,6 +17,9 @@ namespace // If the clipboard does not have string, return false. bool remove_crlf_in_clipboard() { auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + throw std::runtime_error("There is no foreground window.") ; + } bind::SmartClipboard scb(hwnd) ; scb.open() ; diff --git a/src/bind/emu/replacetext.cpp b/src/bind/emu/replacetext.cpp index 448ad602..7c2ec55f 100644 --- a/src/bind/emu/replacetext.cpp +++ b/src/bind/emu/replacetext.cpp @@ -265,6 +265,9 @@ namespace vind std::uint16_t count, const std::string& UNUSED(args)) { auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + throw std::runtime_error("There is no foreground window.") ; + } auto& igate = core::InputGate::get_instance() ; diff --git a/src/bind/emu/textutil.cpp b/src/bind/emu/textutil.cpp index 5ba2d158..0c3d8cc9 100644 --- a/src/bind/emu/textutil.cpp +++ b/src/bind/emu/textutil.cpp @@ -15,6 +15,9 @@ namespace vind std::function clip_func, bool backup) { auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + throw std::runtime_error("There is no foreground window.") ; + } SmartClipboard scb(hwnd) ; scb.open() ; diff --git a/src/bind/file/explorer_util.cpp b/src/bind/file/explorer_util.cpp index 3b044568..9d11c43c 100644 --- a/src/bind/file/explorer_util.cpp +++ b/src/bind/file/explorer_util.cpp @@ -19,6 +19,9 @@ namespace vind //This is based on https://devblogs.microsoft.com/oldnewthing/?p=38393 . std::filesystem::path get_current_explorer_path() { auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + throw std::runtime_error("There is no foreground window.") ; + } if(util::is_failed(CoInitialize(NULL))) { throw RUNTIME_EXCEPT("initialization failed") ; diff --git a/src/bind/mode/change_mode.cpp b/src/bind/mode/change_mode.cpp index 6767967c..28603822 100644 --- a/src/bind/mode/change_mode.cpp +++ b/src/bind/mode/change_mode.cpp @@ -69,12 +69,17 @@ namespace vind const std::string& UNUSED(args), bool vclmodeout) { auto& igate = core::InputGate::get_instance() ; + auto& ac = core::AutoCmd::get_instance() ; + ac.apply_autocmds(core::get_leave_event(core::get_global_mode())) ; + igate.close_all_ports() ; igate.unabsorb() ; core::set_global_mode(core::Mode::RESIDENT) ; if(vclmodeout) { opt::VCmdLine::print(opt::GeneralMessage("-- RESIDENT --")) ; } + + ac.apply_autocmds(core::get_enter_event(core::Mode::RESIDENT)) ; } //ToGUIVisual @@ -85,11 +90,16 @@ namespace vind std::uint16_t UNUSED(count), const std::string& UNUSED(args), bool vclmodeout) { + auto& ac = core::AutoCmd::get_instance() ; + ac.apply_autocmds(core::get_leave_event(core::get_global_mode())) ; + core::set_global_mode(core::Mode::GUI_VISUAL) ; if(vclmodeout) { opt::VCmdLine::print(opt::GeneralMessage("-- GUI VISUAL --")) ; } util::press_mousestate(KEYCODE_MOUSE_LEFT) ; + + ac.apply_autocmds(core::get_enter_event(core::Mode::GUI_VISUAL)) ; } // All instances share TextAreaScanner to keep staticity of sprocess. @@ -111,6 +121,10 @@ namespace vind if(mode == Mode::EDI_NORMAL) { return ; } + + auto& ac = core::AutoCmd::get_instance() ; + ac.apply_autocmds(core::get_leave_event(mode)) ; + if(mode == Mode::GUI_NORMAL) { util::click(KEYCODE_MOUSE_LEFT) ; } @@ -129,10 +143,13 @@ namespace vind auto& settable = core::SetTable::get_instance() ; if(settable.get("autofocus_textarea").get()) { - auto hwnd = util::get_foreground_window() ; - auto pos = util::get_cursor_pos() ; - focus_nearest_textarea(hwnd, pos, scanner_) ; + if(auto hwnd = util::get_foreground_window()) { + auto pos = util::get_cursor_pos() ; + focus_nearest_textarea(hwnd, pos, scanner_) ; + } } + + ac.apply_autocmds(core::get_enter_event(Mode::EDI_NORMAL)) ; } //ToInsert @@ -144,7 +161,13 @@ namespace vind const std::string& UNUSED(args), bool vclmodeout) { using core::Mode ; - if(core::get_global_mode() == Mode::GUI_NORMAL) { + + auto m = core::get_global_mode() ; + + auto& ac = core::AutoCmd::get_instance() ; + ac.apply_autocmds(core::get_leave_event(m)) ; + + if(m == Mode::GUI_NORMAL) { util::click(KEYCODE_MOUSE_LEFT) ; } @@ -157,6 +180,8 @@ namespace vind if(vclmodeout) { opt::VCmdLine::print(opt::GeneralMessage("-- INSERT --")) ; } + + ac.apply_autocmds(core::get_enter_event(Mode::INSERT)) ; } //ToEdiVisual @@ -167,11 +192,16 @@ namespace vind std::uint16_t UNUSED(count), const std::string& UNUSED(args), bool vclmodeout) { + auto& ac = core::AutoCmd::get_instance() ; + ac.apply_autocmds(core::get_leave_event(core::get_global_mode())) ; + select_words() ; core::set_global_mode(core::Mode::EDI_VISUAL) ; if(vclmodeout) { opt::VCmdLine::print(opt::GeneralMessage("-- EDI VISUAL --")) ; } + + ac.apply_autocmds(core::get_enter_event(core::Mode::EDI_VISUAL)) ; } //ToEdiVisualLine @@ -182,12 +212,17 @@ namespace vind std::uint16_t UNUSED(count), const std::string& UNUSED(args), bool vclmodeout) { + auto& ac = core::AutoCmd::get_instance() ; + ac.apply_autocmds(core::get_leave_event(core::get_global_mode())) ; + select_line_EOL2BOL() ; core::set_global_mode( core::Mode::EDI_VISUAL, core::ModeFlags::VISUAL_LINE) ; if(vclmodeout) { opt::VCmdLine::print(opt::GeneralMessage("-- EDI VISUAL LINE--")) ; } + + ac.apply_autocmds(core::get_enter_event(core::Mode::EDI_VISUAL)) ; } } } diff --git a/src/bind/mode/command_mode.cpp b/src/bind/mode/command_mode.cpp index 9d4aecf2..161a0515 100644 --- a/src/bind/mode/command_mode.cpp +++ b/src/bind/mode/command_mode.cpp @@ -8,6 +8,7 @@ #include #include "bind/bindedfunc.hpp" +#include "core/autocmd.hpp" #include "core/background.hpp" #include "core/errlogger.hpp" #include "core/inputgate.hpp" @@ -226,15 +227,20 @@ namespace vind const std::string& UNUSED(args)) { auto& igate = core::InputGate::get_instance() ; auto& ihub = core::InputHub::get_instance() ; + auto& ac = core::AutoCmd::get_instance() ; auto return_mode = [] (core::Mode* m) { // If the mode is changed, then do nothing. if(core::get_global_mode() == core::Mode::COMMAND) { core::set_global_mode(*m) ; + core::AutoCmd::get_instance().apply_autocmds(core::get_enter_event(*m)) ; } } ; + auto m = core::get_global_mode() ; + ac.apply_autocmds(core::get_leave_event(m)) ; + std::unique_ptr - mode_preserver(new core::Mode(core::get_global_mode()), return_mode) ; + mode_preserver(new core::Mode(m), return_mode) ; core::set_global_mode(core::Mode::COMMAND) ; core::InstantKeyAbsorber ika ; @@ -247,6 +253,7 @@ namespace vind pimpl->hist_idx_ = static_cast(pimpl->hists_.size() - 1) ; auto result = SystemCall::SUCCEEDED ; + ac.apply_autocmds(core::get_enter_event(core::Mode::COMMAND)) ; while(true) { pimpl->bg_.update() ; diff --git a/src/bind/mode/instant_mode.cpp b/src/bind/mode/instant_mode.cpp index caf87788..9d972010 100644 --- a/src/bind/mode/instant_mode.cpp +++ b/src/bind/mode/instant_mode.cpp @@ -1,6 +1,7 @@ #include "instant_mode.hpp" #include "bind/bindedfunc.hpp" +#include "core/autocmd.hpp" #include "core/background.hpp" #include "core/cmdunit.hpp" #include "core/inputgate.hpp" @@ -48,6 +49,11 @@ namespace vind std::uint16_t UNUSED(count), const std::string& UNUSED(args)) { auto& ihub = core::InputHub::get_instance() ; + auto& ac = core::AutoCmd::get_instance() ; + + auto m = core::get_global_mode() ; + ac.apply_autocmds(core::get_leave_event(m)) ; + ac.apply_autocmds(core::get_enter_event(core::Mode::GUI_NORMAL)) ; core::InputGate::get_instance().close_all_ports_with_refresh() ; core::InstantKeyAbsorber isa{} ; @@ -77,6 +83,7 @@ namespace vind break ; } opt::VCmdLine::reset() ; + ac.apply_autocmds(core::get_enter_event(m)) ; return res ; } diff --git a/src/bind/mouse/easyclick.cpp b/src/bind/mouse/easyclick.cpp index ab81e831..bd7e5f88 100644 --- a/src/bind/mouse/easyclick.cpp +++ b/src/bind/mouse/easyclick.cpp @@ -175,6 +175,10 @@ namespace vind std::vector points ; auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + return ; + } + if(!scan_ui_objects(hwnd, pimpl->scanner_, elems, points)) { return ; } diff --git a/src/bind/mouse/jump_actwin.cpp b/src/bind/mouse/jump_actwin.cpp index 290b3827..74c6e9d0 100644 --- a/src/bind/mouse/jump_actwin.cpp +++ b/src/bind/mouse/jump_actwin.cpp @@ -18,6 +18,10 @@ namespace vind std::uint16_t UNUSED(count), const std::string& UNUSED(args)) { auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + return ; + } + auto rect = util::get_window_rect(hwnd) ; util::set_cursor_pos(rect.center()) ; } diff --git a/src/bind/proc/openwin.cpp b/src/bind/proc/openwin.cpp index 7a18701e..59a723de 100644 --- a/src/bind/proc/openwin.cpp +++ b/src/bind/proc/openwin.cpp @@ -22,6 +22,9 @@ namespace vind std::uint16_t UNUSED(count), const std::string& UNUSED(args)) { auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + return ; + } DWORD proc_id = 0 ; GetWindowThreadProcessId(hwnd, &proc_id) ; diff --git a/src/bind/syscmd/autocmd.cpp b/src/bind/syscmd/autocmd.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/bind/syscmd/autocmd.hpp b/src/bind/syscmd/autocmd.hpp new file mode 100644 index 00000000..0a603b54 --- /dev/null +++ b/src/bind/syscmd/autocmd.hpp @@ -0,0 +1,4 @@ +#ifndef _AUTOCMD_BIND_HPP +#define _AUTOCMD_BIND_HPP + +#endif diff --git a/src/bind/window/arrange_win.cpp b/src/bind/window/arrange_win.cpp index 798a7056..d7efdf6f 100644 --- a/src/bind/window/arrange_win.cpp +++ b/src/bind/window/arrange_win.cpp @@ -135,6 +135,9 @@ namespace vind std::uint16_t UNUSED(count), const std::string& UNUSED(args)) { auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + return ; + } //Search visible windows g_m_ordered_hwnd.clear() ; diff --git a/src/bind/window/minmax_win.cpp b/src/bind/window/minmax_win.cpp index 94f429f2..6cec88c4 100644 --- a/src/bind/window/minmax_win.cpp +++ b/src/bind/window/minmax_win.cpp @@ -35,6 +35,9 @@ namespace vind if(count == 1) { auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + return ; + } auto before_rect = util::get_window_rect(hwnd) ; diff --git a/src/bind/window/select_win.cpp b/src/bind/window/select_win.cpp index 51529574..1d866d26 100644 --- a/src/bind/window/select_win.cpp +++ b/src/bind/window/select_win.cpp @@ -50,6 +50,9 @@ namespace T1&& is_if_target, T2&& calc_distance) { auto fg_hwnd = util::get_foreground_window() ; + if(!fg_hwnd) { + return ; + } g_rects.clear() ; if(!EnumWindows(EnumWindowsProcForNearest, diff --git a/src/bind/window/snap_win.cpp b/src/bind/window/snap_win.cpp index a98ae8f8..bccb0259 100644 --- a/src/bind/window/snap_win.cpp +++ b/src/bind/window/snap_win.cpp @@ -17,6 +17,9 @@ namespace const std::function& next_monitor_pos) { auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + return ; + } util::MonitorInfo minfo ; util::get_monitor_metrics(hwnd, minfo) ; diff --git a/src/bind/window/split_win.cpp b/src/bind/window/split_win.cpp index 1e1b9989..3ec43de6 100644 --- a/src/bind/window/split_win.cpp +++ b/src/bind/window/split_win.cpp @@ -31,9 +31,16 @@ namespace vind OpenNewWindow::sprocess(1, "") ; auto new_hwnd = util::get_foreground_window() ; + if(!new_hwnd) { + return ; + } + if(new_hwnd == fginfo.hwnd) { Sleep(500) ; new_hwnd = util::get_foreground_window() ; + if(!new_hwnd) { + return ; + } } //snap a new window to bottom @@ -63,9 +70,16 @@ namespace vind OpenNewWindow::sprocess(1, "") ; auto new_hwnd = util::get_foreground_window() ; + if(!new_hwnd) { + return ; + } + if(new_hwnd == fginfo.hwnd) { Sleep(500) ; new_hwnd = util::get_foreground_window() ; + if(!new_hwnd) { + return ; + } } //snap a new window to right diff --git a/src/bind/window/winresizer.cpp b/src/bind/window/winresizer.cpp index 6128c33f..012055cb 100644 --- a/src/bind/window/winresizer.cpp +++ b/src/bind/window/winresizer.cpp @@ -94,6 +94,10 @@ namespace vind void do_move(OperationID id) { auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + return ; + } + auto rect = util::get_window_rect(hwnd) ; auto cb_rect = util::get_combined_metrics() ; diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index 639e9033..db5f3269 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -2,6 +2,7 @@ #include "cmdparser.hpp" #include "cmdunit.hpp" +#include "errlogger.hpp" #include "util/winwrap.hpp" #include @@ -24,33 +25,45 @@ namespace std::string pat_ ; std::regex re_ ; + void init_regex() { + std::string regex ; + regex.reserve(pat_.length()) ; + + for(std::size_t i = 0 ; i < pat_.length() ; i ++) { + if(pat_[i] == '*') { + regex.append(".*") ; + } + else if(pat_[i] == '.') { + regex.append("\\.") ; + } + else { + regex.push_back(pat_[i]) ; + } + } + + re_ = std::regex(std::move(regex)) ; + } + public: explicit AutoPattern() : AutoPattern("") {} explicit AutoPattern(const std::string& pat) - : pat_(pat), - re_(pat) - {} + : pat_(util::A2a(pat)) + { + init_regex() ; + } explicit AutoPattern(std::string&& pat) - : pat_(std::move(pat)), - re_(pat_) - {} - - // Match a query with the pattern and returns the match score. - // The higher score denotes more specified matching. - int match(const std::string& query) { - if(pat_.length() == 1 && pat_.front() == '*') { - return 1 ; - } - - if(std::regex_match(query, re_)) { - return 2 ; - } + : pat_(util::A2a(std::move(pat))) + { + init_regex() ; + } - return 0 ; + // Match a query with the pattern + bool match(const std::string& query) { + return std::regex_match(query, re_) ; } const std::string& get() const noexcept { @@ -94,17 +107,12 @@ namespace } } - int match_pattern(const std::string& query) { - int highest_index = -1 ; - int highest_score = 0 ; + void match_pattern(const std::string& query, std::unordered_set& indices) { for(int i = 0 ; i < pats_.size() ; i ++) { - auto score = pats_[i].match(query) ; - if(highest_score < score) { - highest_index = i ; + if(pats_[i].match(query)) { + indices.insert(i) ; } } - - return highest_index ; } void call_sequential_cmd(int patidx) { @@ -183,15 +191,23 @@ namespace vind pimpl->events_[static_cast(event)].add_pattern_cmd(pattern, std::move(cmd)) ; } - void AutoCmd::apply_autocmds(AutoCmdEvent event) { + void AutoCmd::apply_autocmds(AutoCmdEvent event, HWND hwnd) { if(event == AutoCmdEvent::UNDEFINED) { return ; } auto evt = pimpl->events_[static_cast(event)] ; + if(!hwnd) { // set default value istead + hwnd = util::get_foreground_window() ; + } + + if(!hwnd) { + // There is no foreground window, so do nothing. + return ; + } + // Get the path for executable file of the foreground window. - auto hwnd = util::get_foreground_window() ; DWORD procid ; GetWindowThreadProcessId(hwnd, &procid) ; @@ -209,21 +225,46 @@ namespace vind } std::unordered_set parent_set{procid} ; - std::unordered_set pat_indices{} ; + + std::unordered_set pat_indices{} ; // to call indices of the pattern list + + // Check pattern of the parent process + std::string path ; + try { + path = util::A2a(util::get_module_path(procid)) ; + } + catch(const std::runtime_error&) { + // If failed to get the path of the module, skip matching. + return ; + } + std::unordered_set indices ; + evt.match_pattern(path, indices) ; + if(!indices.empty()) { + pat_indices.insert(indices.begin(), indices.end()) ; + } + do { - // Enumerate only child processs + // Check pattern of child processs if(parent_set.find(pe32.th32ParentProcessID) != parent_set.end()) { - // Check pattern and execute sequential command - auto path = util::get_module_path(pe32.th32ProcessID) ; - auto patidx = evt.match_pattern(path) ; - if(patidx >= 0) { - pat_indices.insert(patidx) ; + try { + path = util::A2a(util::get_module_path(pe32.th32ProcessID)) ; + } + catch(const std::runtime_error&) { + // If failed to get the path of the module, skip matching. + continue ; + } + + indices.clear() ; + evt.match_pattern(path, indices) ; + if(!indices.empty()) { + pat_indices.insert(indices.begin(), indices.end()) ; } parent_set.insert(pe32.th32ProcessID) ; } } while(Process32Next(h_snap.get(), &pe32)) ; + // Execute the matched sequential commands if(!pat_indices.empty()) { for(auto patidx : pat_indices) { evt.call_sequential_cmd(patidx) ; diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp index 49d5e1e1..cd238f55 100644 --- a/src/core/autocmd.hpp +++ b/src/core/autocmd.hpp @@ -86,7 +86,10 @@ namespace vind const std::string& pattern, const std::string& cmd) ; - void apply_autocmds(AutoCmdEvent event) ; + // Perform command automation. + // First argument: the event type + // Second argument: target window handle, which has default HWND. + void apply_autocmds(AutoCmdEvent event, HWND hwnd=NULL) ; } ; } } diff --git a/src/core/entry.cpp b/src/core/entry.cpp index 722a0642..04c13107 100644 --- a/src/core/entry.cpp +++ b/src/core/entry.cpp @@ -105,6 +105,8 @@ namespace vind Background bg_ ; + HWND previous_hwnd_ ; + template Impl(ExitFuncType&& exitfunc, String&& memname, std::size_t memsize) : exit_(std::forward(exitfunc)), @@ -113,7 +115,8 @@ namespace vind memsize_(memsize), subprocess_(false), memread_timer_(1000'000), //1 s - bg_(opt::all_global_options()) + bg_(opt::all_global_options()), + previous_hwnd_(NULL) {} ~Impl() noexcept { @@ -289,7 +292,10 @@ namespace vind handle_system_call(cm.at("i")->process()) ; } - AutoCmd::get_instance().add_autocmd(AutoCmdEvent::GUI_NORMAL_ENTER, ".*vim.*", "") ; + AutoCmd::get_instance().add_autocmd(AutoCmdEvent::WIN_LEAVE, "*vim*", "") ; + AutoCmd::get_instance().add_autocmd(AutoCmdEvent::WIN_ENTER, "*vim*", "") ; + AutoCmd::get_instance().add_autocmd(AutoCmdEvent::WIN_ENTER, "*notepad.exe", "") ; + AutoCmd::get_instance().add_autocmd(AutoCmdEvent::WIN_LEAVE, "*notepad.exe", "") ; } void VindEntry::reconstruct() { @@ -317,6 +323,16 @@ namespace vind void VindEntry::update() { auto& ihub = InputHub::get_instance() ; + auto& ac = AutoCmd::get_instance() ; + auto hwnd = util::get_foreground_window() ; + if(pimpl->previous_hwnd_ != hwnd) { + if(pimpl->previous_hwnd_ != NULL) { + ac.apply_autocmds(AutoCmdEvent::WIN_LEAVE, pimpl->previous_hwnd_) ; + } + pimpl->previous_hwnd_ = hwnd ; + ac.apply_autocmds(AutoCmdEvent::WIN_ENTER, hwnd) ; + } + pimpl->bg_.update() ; // TODO: It is necessary to add exclusive handling when diff --git a/src/opt/blockstylecaret.cpp b/src/opt/blockstylecaret.cpp index 0c0d8ddd..bd502b6a 100644 --- a/src/opt/blockstylecaret.cpp +++ b/src/opt/blockstylecaret.cpp @@ -41,7 +41,9 @@ namespace SPI_SETCARETWIDTH, 0, val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE) ; - update_caret(util::get_foreground_window()) ; + if(auto hwnd = util::get_foreground_window()) { + update_caret(hwnd) ; + } } /** diff --git a/src/opt/uiacachebuild.cpp b/src/opt/uiacachebuild.cpp index 6e5a14a5..5495cefa 100644 --- a/src/opt/uiacachebuild.cpp +++ b/src/opt/uiacachebuild.cpp @@ -73,6 +73,9 @@ namespace vind } auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + return ; + } if(!has_cache(hwnd)) { caches_.emplace(hwnd, hwnd) ; diff --git a/src/util/winwrap.cpp b/src/util/winwrap.cpp index f82cb569..a3c13b88 100644 --- a/src/util/winwrap.cpp +++ b/src/util/winwrap.cpp @@ -38,9 +38,11 @@ namespace vind HWND get_foreground_window() { auto hwnd = GetForegroundWindow() ; + /* if(!hwnd) { throw std::runtime_error("There is no foreground window.") ; } + */ return hwnd ; } From 985a86aab3ac5e3ee5ed1164a196128f05580b88 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Mon, 7 Aug 2023 01:40:25 +0900 Subject: [PATCH 10/22] add binding of autocmd --- res/resources/defaults/tiny.vindrc | 2 + src/bind/bindinglist.cpp | 4 + src/bind/mode/command_mode.cpp | 3 +- src/bind/syscmd/autocmd.cpp | 110 ++++++++++++++++ src/bind/syscmd/autocmd.hpp | 20 +++ src/bind/syscmd/source.cpp | 9 ++ src/core/autocmd.cpp | 197 ++++++++++++++++++++--------- src/core/autocmd.hpp | 27 +++- src/core/entry.cpp | 20 ++- src/core/inputhub.cpp | 7 + src/core/inputhub.hpp | 10 ++ 11 files changed, 331 insertions(+), 78 deletions(-) diff --git a/res/resources/defaults/tiny.vindrc b/res/resources/defaults/tiny.vindrc index 1fa31862..9b9378e7 100644 --- a/res/resources/defaults/tiny.vindrc +++ b/res/resources/defaults/tiny.vindrc @@ -142,3 +142,5 @@ command comc command comclear command so command source +command autocmd +command autocmd! diff --git a/src/bind/bindinglist.cpp b/src/bind/bindinglist.cpp index b2f7699b..23b052a5 100644 --- a/src/bind/bindinglist.cpp +++ b/src/bind/bindinglist.cpp @@ -60,6 +60,7 @@ #include "window/teleport_vdesktop.hpp" #include "window/winresizer.hpp" +#include "syscmd/autocmd.hpp" #include "syscmd/command.hpp" #include "syscmd/mapvar.hpp" #include "syscmd/set.hpp" @@ -291,6 +292,9 @@ namespace vind CNoremap::create(), CUnmap::create(), CMapclear::create(), + + AutoCmdAdd::create(), + AutoCmdRemove::create(), } ; return tmp ; } diff --git a/src/bind/mode/command_mode.cpp b/src/bind/mode/command_mode.cpp index 161a0515..06cd4e30 100644 --- a/src/bind/mode/command_mode.cpp +++ b/src/bind/mode/command_mode.cpp @@ -233,7 +233,8 @@ namespace vind // If the mode is changed, then do nothing. if(core::get_global_mode() == core::Mode::COMMAND) { core::set_global_mode(*m) ; - core::AutoCmd::get_instance().apply_autocmds(core::get_enter_event(*m)) ; + core::AutoCmd::get_instance().apply_autocmds( + core::get_leave_event(core::Mode::COMMAND)) ; } } ; auto m = core::get_global_mode() ; diff --git a/src/bind/syscmd/autocmd.cpp b/src/bind/syscmd/autocmd.cpp index e69de29b..18a6e02e 100644 --- a/src/bind/syscmd/autocmd.cpp +++ b/src/bind/syscmd/autocmd.cpp @@ -0,0 +1,110 @@ +#include "autocmd.hpp" + +#include "core/autocmd.hpp" +#include "core/errlogger.hpp" +#include "core/rcparser.hpp" +#include "opt/vcmdline.hpp" +#include "util/debug.hpp" +#include "util/def.hpp" + +#include + + +namespace vind +{ + namespace bind + { + AutoCmdAdd::AutoCmdAdd() + : BindedFuncVoid("autocmd") + {} + + void AutoCmdAdd::sprocess( + std::uint16_t UNUSED(count), + const std::string& args) { + auto [_, pargs] = core::divide_cmd_and_args(args) ; + + auto [event_str, patcmd] = core::extract_double_args(pargs) ; + auto [aupat, cmd] = core::extract_double_args(patcmd) ; + + auto event = core::get_autocmd_event(event_str) ; + if(event == core::AutoCmdEvent::UNDEFINED) { + opt::VCmdLine::print( + opt::ErrorMessage("E: Not supported event name")) ; + + core::Logger::get_instance().error( + event_str + " is an unsupported event name.") ; + return ; + } + + if(aupat.empty()) { + opt::VCmdLine::print( + opt::ErrorMessage("E: Empty autocmd pattern")) ; + + core::Logger::get_instance().error( + "The autocmd pattern must be specified.") ; + + return ; + } + + if(cmd.empty()) { + opt::VCmdLine::print( + opt::ErrorMessage("E: Empty autocmd command")) ; + + core::Logger::get_instance().error( + "autocmd must specify the command to be executed.") ; + + return ; + } + + core::AutoCmd::get_instance().add_autocmd(event, aupat, cmd) ; + } + + AutoCmdRemove::AutoCmdRemove() + : BindedFuncVoid("autocmd_del") + {} + + void AutoCmdRemove::sprocess( + std::uint16_t UNUSED(count), + const std::string& args) { + auto& ac = core::AutoCmd::get_instance() ; + + auto [_, pargs] = core::divide_cmd_and_args(args) ; + + auto [event_str, patcmd] = core::extract_double_args(pargs) ; + auto [aupat, cmd] = core::extract_double_args(patcmd) ; + + if(event_str == "*") { + if(aupat.empty()) { + opt::VCmdLine::print( + opt::ErrorMessage("E: Empty autocmd pattern")) ; + core::Logger::get_instance().error( + "autocmd patterns are required for events containing wildcards, such as *.") ; + return ; + } + + ac.remove_autocmd(aupat) ; + return ; + } + + auto event = core::get_autocmd_event(event_str) ; + if(event == core::AutoCmdEvent::UNDEFINED) { + opt::VCmdLine::print( + opt::ErrorMessage("E: Not supported event name")) ; + + core::Logger::get_instance().error( + event_str + " is an unsupported event name.") ; + return ; + } + + if(aupat.empty()) { + ac.remove_autocmd(event) ; + return ; + } + if(cmd.empty()) { + ac.remove_autocmd(event, aupat) ; + return ; + } + ac.remove_autocmd(event, aupat, cmd) ; + } + } +} diff --git a/src/bind/syscmd/autocmd.hpp b/src/bind/syscmd/autocmd.hpp index 0a603b54..d435fc7b 100644 --- a/src/bind/syscmd/autocmd.hpp +++ b/src/bind/syscmd/autocmd.hpp @@ -1,4 +1,24 @@ #ifndef _AUTOCMD_BIND_HPP #define _AUTOCMD_BIND_HPP +#include "bind/bindedfunc.hpp" + +namespace vind +{ + namespace bind + { + struct AutoCmdAdd : public BindedFuncVoid { + explicit AutoCmdAdd() ; + static void sprocess( + std::uint16_t count, const std::string& args) ; + } ; + + struct AutoCmdRemove : public BindedFuncVoid { + explicit AutoCmdRemove() ; + static void sprocess( + std::uint16_t count, const std::string& args) ; + } ; + } +} + #endif diff --git a/src/bind/syscmd/source.cpp b/src/bind/syscmd/source.cpp index 9de3f49f..5e923eb7 100644 --- a/src/bind/syscmd/source.cpp +++ b/src/bind/syscmd/source.cpp @@ -15,6 +15,7 @@ #include "util/type_traits.hpp" #include "util/winwrap.hpp" +#include "autocmd.hpp" #include "command.hpp" #include "map.hpp" #include "set.hpp" @@ -168,6 +169,14 @@ namespace return ; } + case RunCommandsIndex::AUTOCMD: { + AutoCmdAdd::sprocess(1, cmd + " " + args) ; + return ; + } + case RunCommandsIndex::AUTOCMD_REMOVE: { + AutoCmdRemove::sprocess(1, cmd + " " + args) ; + return ; + } default: { break ; } diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index db5f3269..4d94a41a 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -3,6 +3,7 @@ #include "cmdparser.hpp" #include "cmdunit.hpp" #include "errlogger.hpp" +#include "inputhub.hpp" #include "util/winwrap.hpp" #include @@ -50,13 +51,13 @@ namespace {} explicit AutoPattern(const std::string& pat) - : pat_(util::A2a(pat)) + : pat_(pat) { init_regex() ; } explicit AutoPattern(std::string&& pat) - : pat_(util::A2a(std::move(pat))) + : pat_(std::move(pat)) { init_regex() ; } @@ -77,7 +78,6 @@ namespace private: std::vector pats_ ; std::vector seqcmds_ ; - SequentialCmd empty_ ; int get_pat_index(const std::string& query) { for(int i = 0 ; i < pats_.size() ; i ++) { @@ -91,8 +91,7 @@ namespace public: explicit AutoEvent() : pats_(), - seqcmds_(), - empty_() + seqcmds_() {} template @@ -107,6 +106,45 @@ namespace } } + template + void remove_pattern(T1&& pat) { + auto idx = get_pat_index(pat) ; + if(idx < 0) { + return ; + } + + pats_.erase(pats_.begin() + idx) ; + seqcmds_.erase(seqcmds_.begin() + idx) ; + } + + template + void remove_pattern_cmd(T1&& pat, T2&& cmd) { + auto idx = get_pat_index(pat) ; + if(idx < 0) { + return ; + } + + auto& cmds = seqcmds_[idx] ; + + for(std::size_t i = 0 ; i < cmds.size() ; i ++) { + if(cmds[i].size() != cmd.size()) { + continue ; + } + + bool is_same = true ; + for(std::size_t j = 0 ; j < cmd.size() ; j ++) { + if(*(cmds[i][j]) != *(cmd[j])) { + is_same = false ; + break ; + } + } + if(is_same) { + cmds.erase(cmds.begin() + i) ; + return ; + } + } + } + void match_pattern(const std::string& query, std::unordered_set& indices) { for(int i = 0 ; i < pats_.size() ; i ++) { if(pats_[i].match(query)) { @@ -115,14 +153,25 @@ namespace } } - void call_sequential_cmd(int patidx) { + void enqueue_sequential_command(int patidx) { for(const auto& cmd : seqcmds_[patidx]) { - std::cout << "call: " << cmd << std::endl ; for(const auto& unit : cmd) { - unit->execute(1) ; + if(unit->empty()) { + // Function + core::InputHub::get_instance().enqueue(unit, 1) ; + } + else { + // Keycode + core::InputHub::get_instance().do_typing(unit) ; + } } } } + + void clear() { + pats_.clear() ; + seqcmds_.clear() ; + } } ; } @@ -130,26 +179,31 @@ namespace vind { namespace core { - AutoCmdEvent get_autocmd_event(const std::string& event_name) { + AutoCmdEvent get_autocmd_event(const std::string& event_name) noexcept { static std::unordered_map names { - {"WinEnter", AutoCmdEvent::WIN_ENTER}, - {"WinLeave", AutoCmdEvent::WIN_LEAVE}, - {"GUINormalEnter", AutoCmdEvent::GUI_NORMAL_ENTER}, - {"GUINormalLeave", AutoCmdEvent::GUI_NORMAL_LEAVE}, - {"GUIVisualEnter", AutoCmdEvent::GUI_VISUAL_ENTER}, - {"GUIVisualLeave", AutoCmdEvent::GUI_VISUAL_LEAVE}, - {"EdiNormalEnter", AutoCmdEvent::EDI_NORMAL_ENTER}, - {"EdiNormalLeave", AutoCmdEvent::EDI_NORMAL_LEAVE}, - {"EdiVisualEnter", AutoCmdEvent::EDI_VISUAL_ENTER}, - {"EdiVisualLeave", AutoCmdEvent::EDI_VISUAL_LEAVE}, - {"InsertEnter", AutoCmdEvent::INSERT_ENTER}, - {"InsertLeave", AutoCmdEvent::INSERT_LEAVE}, - {"ResidentEnter", AutoCmdEvent::RESIDENT_ENTER}, - {"ResidentLeave", AutoCmdEvent::RESIDENT_LEAVE}, - {"CommandEnter", AutoCmdEvent::COMMAND_ENTER}, - {"CommandLeave", AutoCmdEvent::COMMAND_LEAVE} + {"procenter", AutoCmdEvent::PROC_ENTER}, + {"procleave", AutoCmdEvent::PROC_LEAVE}, + {"guinormalenter", AutoCmdEvent::GUI_NORMAL_ENTER}, + {"guinormalleave", AutoCmdEvent::GUI_NORMAL_LEAVE}, + {"guivisualenter", AutoCmdEvent::GUI_VISUAL_ENTER}, + {"guivisualleave", AutoCmdEvent::GUI_VISUAL_LEAVE}, + {"edinormalenter", AutoCmdEvent::EDI_NORMAL_ENTER}, + {"edinormalleave", AutoCmdEvent::EDI_NORMAL_LEAVE}, + {"edivisualenter", AutoCmdEvent::EDI_VISUAL_ENTER}, + {"edivisualleave", AutoCmdEvent::EDI_VISUAL_LEAVE}, + {"insertenter", AutoCmdEvent::INSERT_ENTER}, + {"insertleave", AutoCmdEvent::INSERT_LEAVE}, + {"residententer", AutoCmdEvent::RESIDENT_ENTER}, + {"residentleave", AutoCmdEvent::RESIDENT_LEAVE}, + {"commandenter", AutoCmdEvent::COMMAND_ENTER}, + {"commandleave", AutoCmdEvent::COMMAND_LEAVE} } ; - return names.at(event_name) ; + auto event_name_lower = util::A2a(event_name) ; + if(names.find(event_name_lower) != names.end()) { + return names[event_name_lower] ; + } + + return AutoCmdEvent::UNDEFINED ; } struct AutoCmd::Impl { @@ -171,46 +225,24 @@ namespace vind return instance ; } - void AutoCmd::add_autocmd( - AutoCmdEvent event, - const std::string& pattern, - const std::string& cmdstr) { - if(event == AutoCmdEvent::UNDEFINED) { - return ; - } - - if(pattern.empty()) { - return ; - } - - auto cmd = parse_command(cmdstr) ; - if(cmd.empty()) { - return ; - } - - pimpl->events_[static_cast(event)].add_pattern_cmd(pattern, std::move(cmd)) ; - } - - void AutoCmd::apply_autocmds(AutoCmdEvent event, HWND hwnd) { + void AutoCmd::apply_autocmds(AutoCmdEvent event, DWORD procid) { if(event == AutoCmdEvent::UNDEFINED) { return ; } auto evt = pimpl->events_[static_cast(event)] ; - if(!hwnd) { // set default value istead - hwnd = util::get_foreground_window() ; - } + if(procid == 0) { + auto hwnd = util::get_foreground_window() ; + if(!hwnd) { + // There is no foreground window, so do nothing. + return ; + } - if(!hwnd) { - // There is no foreground window, so do nothing. - return ; + // Get the path for executable file of the foreground window. + GetWindowThreadProcessId(hwnd, &procid) ; } - // Get the path for executable file of the foreground window. - DWORD procid ; - GetWindowThreadProcessId(hwnd, &procid) ; - auto h_snap_raw = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ; if(h_snap_raw == INVALID_HANDLE_VALUE) { return ; @@ -267,9 +299,58 @@ namespace vind // Execute the matched sequential commands if(!pat_indices.empty()) { for(auto patidx : pat_indices) { - evt.call_sequential_cmd(patidx) ; + evt.enqueue_sequential_command(patidx) ; } } } + + void AutoCmd::add_autocmd( + AutoCmdEvent event, + const std::string& pattern, + const std::string& cmdstr) { + if(event == AutoCmdEvent::UNDEFINED) { + return ; + } + + if(pattern.empty()) { + return ; + } + + auto cmd = parse_command(cmdstr) ; + if(cmd.empty()) { + return ; + } + + auto& evt = pimpl->events_[static_cast(event)] ; + evt.add_pattern_cmd(util::A2a(pattern), std::move(cmd)) ; + } + + void AutoCmd::remove_autocmd(AutoCmdEvent event) { + pimpl->events_[static_cast(event)].clear() ; + } + + void AutoCmd::remove_autocmd( + AutoCmdEvent event, + const std::string& pattern) { + pimpl->events_[static_cast(event)].remove_pattern(pattern) ; + } + + void AutoCmd::remove_autocmd(const std::string& pattern) { + for(std::size_t i = 0 ; i < pimpl->events_.size() ; i ++) { + pimpl->events_[i].remove_pattern(pattern) ; + } + } + + void AutoCmd::remove_autocmd( + AutoCmdEvent event, + const std::string& pattern, + const std::string& cmdstr) { + + auto cmd = parse_command(cmdstr) ; + if(cmd.empty()) { + return ; + } + pimpl->events_[static_cast(event)].remove_pattern_cmd(pattern, cmd) ; + } } } diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp index cd238f55..970b1978 100644 --- a/src/core/autocmd.hpp +++ b/src/core/autocmd.hpp @@ -15,8 +15,8 @@ namespace vind namespace core { enum class AutoCmdEvent : unsigned char { - WIN_ENTER, - WIN_LEAVE, + PROC_ENTER, + PROC_LEAVE, GUI_NORMAL_ENTER, GUI_NORMAL_LEAVE, GUI_VISUAL_ENTER, @@ -36,7 +36,7 @@ namespace vind UNDEFINED, } ; - AutoCmdEvent get_autocmd_event(const std::string& event_name) ; + AutoCmdEvent get_autocmd_event(const std::string& event_name) noexcept ; inline AutoCmdEvent get_leave_event(Mode mode) noexcept { static const std::unordered_map leave_events { @@ -81,15 +81,28 @@ namespace vind public: static AutoCmd& get_instance() ; + // Perform command automation. + // First argument: the event type + // Second argument: target window handle, which has default HWND. + void apply_autocmds(AutoCmdEvent event, DWORD procid=0) ; + void add_autocmd( AutoCmdEvent event, const std::string& pattern, const std::string& cmd) ; - // Perform command automation. - // First argument: the event type - // Second argument: target window handle, which has default HWND. - void apply_autocmds(AutoCmdEvent event, HWND hwnd=NULL) ; + void remove_autocmd(AutoCmdEvent event) ; + + void remove_autocmd( + AutoCmdEvent event, + const std::string& pattern) ; + + void remove_autocmd(const std::string& pattern) ; + + void remove_autocmd( + AutoCmdEvent event, + const std::string& pattern, + const std::string& cmd) ; } ; } } diff --git a/src/core/entry.cpp b/src/core/entry.cpp index 04c13107..aa920b5f 100644 --- a/src/core/entry.cpp +++ b/src/core/entry.cpp @@ -105,7 +105,7 @@ namespace vind Background bg_ ; - HWND previous_hwnd_ ; + DWORD previous_procid_ ; template Impl(ExitFuncType&& exitfunc, String&& memname, std::size_t memsize) @@ -116,7 +116,7 @@ namespace vind subprocess_(false), memread_timer_(1000'000), //1 s bg_(opt::all_global_options()), - previous_hwnd_(NULL) + previous_procid_(0) {} ~Impl() noexcept { @@ -291,11 +291,6 @@ namespace vind catch(const std::out_of_range&) { handle_system_call(cm.at("i")->process()) ; } - - AutoCmd::get_instance().add_autocmd(AutoCmdEvent::WIN_LEAVE, "*vim*", "") ; - AutoCmd::get_instance().add_autocmd(AutoCmdEvent::WIN_ENTER, "*vim*", "") ; - AutoCmd::get_instance().add_autocmd(AutoCmdEvent::WIN_ENTER, "*notepad.exe", "") ; - AutoCmd::get_instance().add_autocmd(AutoCmdEvent::WIN_LEAVE, "*notepad.exe", "") ; } void VindEntry::reconstruct() { @@ -325,12 +320,13 @@ namespace vind auto& ac = AutoCmd::get_instance() ; auto hwnd = util::get_foreground_window() ; - if(pimpl->previous_hwnd_ != hwnd) { - if(pimpl->previous_hwnd_ != NULL) { - ac.apply_autocmds(AutoCmdEvent::WIN_LEAVE, pimpl->previous_hwnd_) ; + DWORD procid ; + if(hwnd && GetWindowThreadProcessId(hwnd, &procid)) { + if(pimpl->previous_procid_ != procid) { + ac.apply_autocmds(AutoCmdEvent::PROC_LEAVE, pimpl->previous_procid_) ; + pimpl->previous_procid_ = procid ; + ac.apply_autocmds(AutoCmdEvent::PROC_ENTER, procid) ; } - pimpl->previous_hwnd_ = hwnd ; - ac.apply_autocmds(AutoCmdEvent::WIN_ENTER, hwnd) ; } pimpl->bg_.update() ; diff --git a/src/core/inputhub.cpp b/src/core/inputhub.cpp index d83112c5..dc4e3c09 100644 --- a/src/core/inputhub.cpp +++ b/src/core/inputhub.cpp @@ -223,6 +223,13 @@ namespace vind return true ; } + bool InputHub::enqueue( + const CmdUnit::SPtr& unit, + std::uint16_t prefix_count) { + pimpl->waiting_queue_.enqueue(unit, prefix_count) ; + return true ; + } + bool InputHub::enqueue_mapped( const CmdUnit::SPtr& input, std::uint16_t prefix_count, diff --git a/src/core/inputhub.hpp b/src/core/inputhub.hpp index d2fa6925..3b2a1862 100644 --- a/src/core/inputhub.hpp +++ b/src/core/inputhub.hpp @@ -89,6 +89,16 @@ namespace vind Mode mode=get_global_mode(), bool parse_count=true) ; + /* + * Enqueue the unit into whe waiting queue. + * + * @param[in] (input) The trigger input of map + * @param[in] (count) The prefix number of input command. + */ + bool enqueue( + const CmdUnit::SPtr& unit, + std::uint16_t prefix_count) ; + /* * Maps input to other commands and adds the result to the input waiting * queue. The mapped commands are assumed to be input at the same time From 6cd013e1bd33030c6b238163919db44683d09c70 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Mon, 7 Aug 2023 01:43:38 +0900 Subject: [PATCH 11/22] use App instead of Proc --- src/core/autocmd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index 4d94a41a..4aa5bcf0 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -181,8 +181,8 @@ namespace vind { AutoCmdEvent get_autocmd_event(const std::string& event_name) noexcept { static std::unordered_map names { - {"procenter", AutoCmdEvent::PROC_ENTER}, - {"procleave", AutoCmdEvent::PROC_LEAVE}, + {"appenter", AutoCmdEvent::APP_ENTER}, + {"appleave", AutoCmdEvent::APP_LEAVE}, {"guinormalenter", AutoCmdEvent::GUI_NORMAL_ENTER}, {"guinormalleave", AutoCmdEvent::GUI_NORMAL_LEAVE}, {"guivisualenter", AutoCmdEvent::GUI_VISUAL_ENTER}, From 9fca6d67c157002902b531d2bfb797b5107a7bba Mon Sep 17 00:00:00 2001 From: pit-ray Date: Mon, 7 Aug 2023 01:45:52 +0900 Subject: [PATCH 12/22] change mode name --- src/core/autocmd.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index 4aa5bcf0..d1223a8a 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -181,22 +181,22 @@ namespace vind { AutoCmdEvent get_autocmd_event(const std::string& event_name) noexcept { static std::unordered_map names { - {"appenter", AutoCmdEvent::APP_ENTER}, - {"appleave", AutoCmdEvent::APP_LEAVE}, - {"guinormalenter", AutoCmdEvent::GUI_NORMAL_ENTER}, - {"guinormalleave", AutoCmdEvent::GUI_NORMAL_LEAVE}, - {"guivisualenter", AutoCmdEvent::GUI_VISUAL_ENTER}, - {"guivisualleave", AutoCmdEvent::GUI_VISUAL_LEAVE}, - {"edinormalenter", AutoCmdEvent::EDI_NORMAL_ENTER}, - {"edinormalleave", AutoCmdEvent::EDI_NORMAL_LEAVE}, - {"edivisualenter", AutoCmdEvent::EDI_VISUAL_ENTER}, - {"edivisualleave", AutoCmdEvent::EDI_VISUAL_LEAVE}, - {"insertenter", AutoCmdEvent::INSERT_ENTER}, - {"insertleave", AutoCmdEvent::INSERT_LEAVE}, - {"residententer", AutoCmdEvent::RESIDENT_ENTER}, - {"residentleave", AutoCmdEvent::RESIDENT_LEAVE}, - {"commandenter", AutoCmdEvent::COMMAND_ENTER}, - {"commandleave", AutoCmdEvent::COMMAND_LEAVE} + {"appenter", AutoCmdEvent::APP_ENTER}, + {"appleave", AutoCmdEvent::APP_LEAVE}, + {"gnormalenter", AutoCmdEvent::GUI_NORMAL_ENTER}, + {"gnormalleave", AutoCmdEvent::GUI_NORMAL_LEAVE}, + {"gvisualenter", AutoCmdEvent::GUI_VISUAL_ENTER}, + {"gvisualleave", AutoCmdEvent::GUI_VISUAL_LEAVE}, + {"enormalenter", AutoCmdEvent::EDI_NORMAL_ENTER}, + {"enormalleave", AutoCmdEvent::EDI_NORMAL_LEAVE}, + {"evisualenter", AutoCmdEvent::EDI_VISUAL_ENTER}, + {"evisualleave", AutoCmdEvent::EDI_VISUAL_LEAVE}, + {"insertenter", AutoCmdEvent::INSERT_ENTER}, + {"insertleave", AutoCmdEvent::INSERT_LEAVE}, + {"residententer", AutoCmdEvent::RESIDENT_ENTER}, + {"residentleave", AutoCmdEvent::RESIDENT_LEAVE}, + {"commandenter", AutoCmdEvent::COMMAND_ENTER}, + {"commandleave", AutoCmdEvent::COMMAND_LEAVE} } ; auto event_name_lower = util::A2a(event_name) ; if(names.find(event_name_lower) != names.end()) { From 5d8011d141000f818e9a7efd9fcce020cfa12e35 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Mon, 7 Aug 2023 01:46:14 +0900 Subject: [PATCH 13/22] fix enum --- src/core/autocmd.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp index 970b1978..b8ab243a 100644 --- a/src/core/autocmd.hpp +++ b/src/core/autocmd.hpp @@ -15,8 +15,8 @@ namespace vind namespace core { enum class AutoCmdEvent : unsigned char { - PROC_ENTER, - PROC_LEAVE, + APP_ENTER, + APP_LEAVE, GUI_NORMAL_ENTER, GUI_NORMAL_LEAVE, GUI_VISUAL_ENTER, From fa4eba6bef92bdd0c686ee8cd280cac57a12deaf Mon Sep 17 00:00:00 2001 From: pit-ray Date: Mon, 7 Aug 2023 05:20:30 +0900 Subject: [PATCH 14/22] fix defects --- src/core/autocmd.cpp | 14 ++++++++------ src/core/autocmd.hpp | 4 ++-- src/core/entry.cpp | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index d1223a8a..c270725f 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -51,13 +51,15 @@ namespace {} explicit AutoPattern(const std::string& pat) - : pat_(pat) + : pat_(pat), + re_() { init_regex() ; } explicit AutoPattern(std::string&& pat) - : pat_(std::move(pat)) + : pat_(std::move(pat)), + re_() { init_regex() ; } @@ -80,9 +82,9 @@ namespace std::vector seqcmds_ ; int get_pat_index(const std::string& query) { - for(int i = 0 ; i < pats_.size() ; i ++) { + for(std::size_t i = 0 ; i < pats_.size() ; i ++) { if(pats_[i].get() == query) { - return i ; + return static_cast(i) ; } } return -1 ; @@ -146,9 +148,9 @@ namespace } void match_pattern(const std::string& query, std::unordered_set& indices) { - for(int i = 0 ; i < pats_.size() ; i ++) { + for(std::size_t i = 0 ; i < pats_.size() ; i ++) { if(pats_[i].match(query)) { - indices.insert(i) ; + indices.insert(static_cast(i)) ; } } } diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp index b8ab243a..555453f0 100644 --- a/src/core/autocmd.hpp +++ b/src/core/autocmd.hpp @@ -38,7 +38,7 @@ namespace vind AutoCmdEvent get_autocmd_event(const std::string& event_name) noexcept ; - inline AutoCmdEvent get_leave_event(Mode mode) noexcept { + inline AutoCmdEvent get_leave_event(Mode mode) { static const std::unordered_map leave_events { {Mode::GUI_NORMAL, AutoCmdEvent::GUI_NORMAL_LEAVE}, {Mode::GUI_VISUAL, AutoCmdEvent::GUI_VISUAL_LEAVE}, @@ -54,7 +54,7 @@ namespace vind return AutoCmdEvent::UNDEFINED ; } - inline AutoCmdEvent get_enter_event(Mode mode) noexcept { + inline AutoCmdEvent get_enter_event(Mode mode) { static const std::unordered_map enter_events { {Mode::GUI_NORMAL, AutoCmdEvent::GUI_NORMAL_ENTER}, {Mode::GUI_VISUAL, AutoCmdEvent::GUI_VISUAL_ENTER}, diff --git a/src/core/entry.cpp b/src/core/entry.cpp index aa920b5f..c481a3d6 100644 --- a/src/core/entry.cpp +++ b/src/core/entry.cpp @@ -323,9 +323,9 @@ namespace vind DWORD procid ; if(hwnd && GetWindowThreadProcessId(hwnd, &procid)) { if(pimpl->previous_procid_ != procid) { - ac.apply_autocmds(AutoCmdEvent::PROC_LEAVE, pimpl->previous_procid_) ; + ac.apply_autocmds(AutoCmdEvent::APP_LEAVE, pimpl->previous_procid_) ; pimpl->previous_procid_ = procid ; - ac.apply_autocmds(AutoCmdEvent::PROC_ENTER, procid) ; + ac.apply_autocmds(AutoCmdEvent::APP_ENTER, procid) ; } } From 7a58332a0fa1aa8eed83198b27d9d1cca9e4ab17 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Fri, 11 Aug 2023 21:03:17 +0900 Subject: [PATCH 15/22] fix autocmd! behavior and support multiple events at the same time --- .gitignore | 6 ++-- src/bind/mode/change_mode.cpp | 28 ++++++++-------- src/bind/mode/command_mode.cpp | 6 ++-- src/bind/mode/instant_mode.cpp | 6 ++-- src/bind/syscmd/autocmd.cpp | 57 ++++++++++++++++++++++----------- src/core/autocmd.cpp | 58 ++++++++-------------------------- src/core/autocmd.hpp | 12 +++---- src/core/entry.cpp | 4 +-- 8 files changed, 81 insertions(+), 96 deletions(-) diff --git a/.gitignore b/.gitignore index a0006af1..3c70d1b9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,7 @@ .vimspector.json .vs .vscode -:w -:wq +:* Testing bin bin_32 @@ -24,8 +23,8 @@ debug debug_cov debugvs debugvs32 -is_initialized log +manifests release release_32 release_64 @@ -36,5 +35,4 @@ tmp venv w winget -manifests wingetcreate.exe diff --git a/src/bind/mode/change_mode.cpp b/src/bind/mode/change_mode.cpp index 28603822..a650d21c 100644 --- a/src/bind/mode/change_mode.cpp +++ b/src/bind/mode/change_mode.cpp @@ -37,7 +37,7 @@ namespace vind } auto& ac = core::AutoCmd::get_instance() ; - ac.apply_autocmds(core::get_leave_event(m)) ; + ac.apply(core::get_leave_event(m)) ; if(m == Mode::GUI_VISUAL) { util::click(KEYCODE_MOUSE_LEFT) ; //release holding mouse @@ -57,7 +57,7 @@ namespace vind opt::VCmdLine::print(opt::GeneralMessage("-- GUI NORMAL --")) ; } - ac.apply_autocmds(core::get_enter_event(Mode::GUI_NORMAL)) ; + ac.apply(core::get_enter_event(Mode::GUI_NORMAL)) ; } //ToResident @@ -70,7 +70,7 @@ namespace vind bool vclmodeout) { auto& igate = core::InputGate::get_instance() ; auto& ac = core::AutoCmd::get_instance() ; - ac.apply_autocmds(core::get_leave_event(core::get_global_mode())) ; + ac.apply(core::get_leave_event(core::get_global_mode())) ; igate.close_all_ports() ; igate.unabsorb() ; @@ -79,7 +79,7 @@ namespace vind opt::VCmdLine::print(opt::GeneralMessage("-- RESIDENT --")) ; } - ac.apply_autocmds(core::get_enter_event(core::Mode::RESIDENT)) ; + ac.apply(core::get_enter_event(core::Mode::RESIDENT)) ; } //ToGUIVisual @@ -91,7 +91,7 @@ namespace vind const std::string& UNUSED(args), bool vclmodeout) { auto& ac = core::AutoCmd::get_instance() ; - ac.apply_autocmds(core::get_leave_event(core::get_global_mode())) ; + ac.apply(core::get_leave_event(core::get_global_mode())) ; core::set_global_mode(core::Mode::GUI_VISUAL) ; if(vclmodeout) { @@ -99,7 +99,7 @@ namespace vind } util::press_mousestate(KEYCODE_MOUSE_LEFT) ; - ac.apply_autocmds(core::get_enter_event(core::Mode::GUI_VISUAL)) ; + ac.apply(core::get_enter_event(core::Mode::GUI_VISUAL)) ; } // All instances share TextAreaScanner to keep staticity of sprocess. @@ -123,7 +123,7 @@ namespace vind } auto& ac = core::AutoCmd::get_instance() ; - ac.apply_autocmds(core::get_leave_event(mode)) ; + ac.apply(core::get_leave_event(mode)) ; if(mode == Mode::GUI_NORMAL) { util::click(KEYCODE_MOUSE_LEFT) ; @@ -149,7 +149,7 @@ namespace vind } } - ac.apply_autocmds(core::get_enter_event(Mode::EDI_NORMAL)) ; + ac.apply(core::get_enter_event(Mode::EDI_NORMAL)) ; } //ToInsert @@ -165,7 +165,7 @@ namespace vind auto m = core::get_global_mode() ; auto& ac = core::AutoCmd::get_instance() ; - ac.apply_autocmds(core::get_leave_event(m)) ; + ac.apply(core::get_leave_event(m)) ; if(m == Mode::GUI_NORMAL) { util::click(KEYCODE_MOUSE_LEFT) ; @@ -181,7 +181,7 @@ namespace vind opt::VCmdLine::print(opt::GeneralMessage("-- INSERT --")) ; } - ac.apply_autocmds(core::get_enter_event(Mode::INSERT)) ; + ac.apply(core::get_enter_event(Mode::INSERT)) ; } //ToEdiVisual @@ -193,7 +193,7 @@ namespace vind const std::string& UNUSED(args), bool vclmodeout) { auto& ac = core::AutoCmd::get_instance() ; - ac.apply_autocmds(core::get_leave_event(core::get_global_mode())) ; + ac.apply(core::get_leave_event(core::get_global_mode())) ; select_words() ; core::set_global_mode(core::Mode::EDI_VISUAL) ; @@ -201,7 +201,7 @@ namespace vind opt::VCmdLine::print(opt::GeneralMessage("-- EDI VISUAL --")) ; } - ac.apply_autocmds(core::get_enter_event(core::Mode::EDI_VISUAL)) ; + ac.apply(core::get_enter_event(core::Mode::EDI_VISUAL)) ; } //ToEdiVisualLine @@ -213,7 +213,7 @@ namespace vind const std::string& UNUSED(args), bool vclmodeout) { auto& ac = core::AutoCmd::get_instance() ; - ac.apply_autocmds(core::get_leave_event(core::get_global_mode())) ; + ac.apply(core::get_leave_event(core::get_global_mode())) ; select_line_EOL2BOL() ; core::set_global_mode( @@ -222,7 +222,7 @@ namespace vind opt::VCmdLine::print(opt::GeneralMessage("-- EDI VISUAL LINE--")) ; } - ac.apply_autocmds(core::get_enter_event(core::Mode::EDI_VISUAL)) ; + ac.apply(core::get_enter_event(core::Mode::EDI_VISUAL)) ; } } } diff --git a/src/bind/mode/command_mode.cpp b/src/bind/mode/command_mode.cpp index 06cd4e30..b7e56aec 100644 --- a/src/bind/mode/command_mode.cpp +++ b/src/bind/mode/command_mode.cpp @@ -233,12 +233,12 @@ namespace vind // If the mode is changed, then do nothing. if(core::get_global_mode() == core::Mode::COMMAND) { core::set_global_mode(*m) ; - core::AutoCmd::get_instance().apply_autocmds( + core::AutoCmd::get_instance().apply( core::get_leave_event(core::Mode::COMMAND)) ; } } ; auto m = core::get_global_mode() ; - ac.apply_autocmds(core::get_leave_event(m)) ; + ac.apply(core::get_leave_event(m)) ; std::unique_ptr mode_preserver(new core::Mode(m), return_mode) ; @@ -254,7 +254,7 @@ namespace vind pimpl->hist_idx_ = static_cast(pimpl->hists_.size() - 1) ; auto result = SystemCall::SUCCEEDED ; - ac.apply_autocmds(core::get_enter_event(core::Mode::COMMAND)) ; + ac.apply(core::get_enter_event(core::Mode::COMMAND)) ; while(true) { pimpl->bg_.update() ; diff --git a/src/bind/mode/instant_mode.cpp b/src/bind/mode/instant_mode.cpp index 9d972010..c8f42faf 100644 --- a/src/bind/mode/instant_mode.cpp +++ b/src/bind/mode/instant_mode.cpp @@ -52,8 +52,8 @@ namespace vind auto& ac = core::AutoCmd::get_instance() ; auto m = core::get_global_mode() ; - ac.apply_autocmds(core::get_leave_event(m)) ; - ac.apply_autocmds(core::get_enter_event(core::Mode::GUI_NORMAL)) ; + ac.apply(core::get_leave_event(m)) ; + ac.apply(core::get_enter_event(core::Mode::GUI_NORMAL)) ; core::InputGate::get_instance().close_all_ports_with_refresh() ; core::InstantKeyAbsorber isa{} ; @@ -83,7 +83,7 @@ namespace vind break ; } opt::VCmdLine::reset() ; - ac.apply_autocmds(core::get_enter_event(m)) ; + ac.apply(core::get_enter_event(m)) ; return res ; } diff --git a/src/bind/syscmd/autocmd.cpp b/src/bind/syscmd/autocmd.cpp index 18a6e02e..218a574b 100644 --- a/src/bind/syscmd/autocmd.cpp +++ b/src/bind/syscmd/autocmd.cpp @@ -6,6 +6,7 @@ #include "opt/vcmdline.hpp" #include "util/debug.hpp" #include "util/def.hpp" +#include "util/string.hpp" #include @@ -26,14 +27,19 @@ namespace vind auto [event_str, patcmd] = core::extract_double_args(pargs) ; auto [aupat, cmd] = core::extract_double_args(patcmd) ; - auto event = core::get_autocmd_event(event_str) ; - if(event == core::AutoCmdEvent::UNDEFINED) { - opt::VCmdLine::print( - opt::ErrorMessage("E: Not supported event name")) ; + std::vector events ; + for(const auto& event_str_part : util::split(event_str, ",")) { + auto event = core::get_autocmd_event(event_str_part) ; + if(event == core::AutoCmdEvent::UNDEFINED) { + opt::VCmdLine::print( + opt::ErrorMessage("E: Not supported event name")) ; - core::Logger::get_instance().error( - event_str + " is an unsupported event name.") ; - return ; + core::Logger::get_instance().error( + event_str + " is an unsupported event name.") ; + return ; + } + + events.push_back(event) ; } if(aupat.empty()) { @@ -56,7 +62,9 @@ namespace vind return ; } - core::AutoCmd::get_instance().add_autocmd(event, aupat, cmd) ; + for(const auto event : events) { + core::AutoCmd::get_instance().add(event, aupat, cmd) ; + } } AutoCmdRemove::AutoCmdRemove() @@ -82,29 +90,40 @@ namespace vind return ; } - ac.remove_autocmd(aupat) ; + ac.remove(aupat) ; return ; } - auto event = core::get_autocmd_event(event_str) ; - if(event == core::AutoCmdEvent::UNDEFINED) { - opt::VCmdLine::print( - opt::ErrorMessage("E: Not supported event name")) ; + std::vector events ; + for(const auto& event_str_part : util::split(event_str, ",")) { + auto event = core::get_autocmd_event(event_str_part) ; + if(event == core::AutoCmdEvent::UNDEFINED) { + opt::VCmdLine::print( + opt::ErrorMessage("E: Not supported event name")) ; - core::Logger::get_instance().error( - event_str + " is an unsupported event name.") ; - return ; + core::Logger::get_instance().error( + event_str + " is an unsupported event name.") ; + return ; + } + events.push_back(event) ; } if(aupat.empty()) { - ac.remove_autocmd(event) ; + for(const auto event : events) { + ac.remove(event) ; + } return ; } if(cmd.empty()) { - ac.remove_autocmd(event, aupat) ; + for(const auto event : events) { + ac.remove(event, aupat) ; + } return ; } - ac.remove_autocmd(event, aupat, cmd) ; + + for(const auto event : events) { + ac.remove_and_add(event, aupat, cmd) ; + } } } } diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index c270725f..12088fdc 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -119,34 +119,6 @@ namespace seqcmds_.erase(seqcmds_.begin() + idx) ; } - template - void remove_pattern_cmd(T1&& pat, T2&& cmd) { - auto idx = get_pat_index(pat) ; - if(idx < 0) { - return ; - } - - auto& cmds = seqcmds_[idx] ; - - for(std::size_t i = 0 ; i < cmds.size() ; i ++) { - if(cmds[i].size() != cmd.size()) { - continue ; - } - - bool is_same = true ; - for(std::size_t j = 0 ; j < cmd.size() ; j ++) { - if(*(cmds[i][j]) != *(cmd[j])) { - is_same = false ; - break ; - } - } - if(is_same) { - cmds.erase(cmds.begin() + i) ; - return ; - } - } - } - void match_pattern(const std::string& query, std::unordered_set& indices) { for(std::size_t i = 0 ; i < pats_.size() ; i ++) { if(pats_[i].match(query)) { @@ -227,7 +199,7 @@ namespace vind return instance ; } - void AutoCmd::apply_autocmds(AutoCmdEvent event, DWORD procid) { + void AutoCmd::apply(AutoCmdEvent event, DWORD procid) { if(event == AutoCmdEvent::UNDEFINED) { return ; } @@ -306,7 +278,7 @@ namespace vind } } - void AutoCmd::add_autocmd( + void AutoCmd::add( AutoCmdEvent event, const std::string& pattern, const std::string& cmdstr) { @@ -327,32 +299,28 @@ namespace vind evt.add_pattern_cmd(util::A2a(pattern), std::move(cmd)) ; } - void AutoCmd::remove_autocmd(AutoCmdEvent event) { + void AutoCmd::remove(AutoCmdEvent event) { pimpl->events_[static_cast(event)].clear() ; } - void AutoCmd::remove_autocmd( - AutoCmdEvent event, - const std::string& pattern) { + void AutoCmd::remove( + AutoCmdEvent event, + const std::string& pattern) { pimpl->events_[static_cast(event)].remove_pattern(pattern) ; } - void AutoCmd::remove_autocmd(const std::string& pattern) { + void AutoCmd::remove(const std::string& pattern) { for(std::size_t i = 0 ; i < pimpl->events_.size() ; i ++) { pimpl->events_[i].remove_pattern(pattern) ; } } - void AutoCmd::remove_autocmd( - AutoCmdEvent event, - const std::string& pattern, - const std::string& cmdstr) { - - auto cmd = parse_command(cmdstr) ; - if(cmd.empty()) { - return ; - } - pimpl->events_[static_cast(event)].remove_pattern_cmd(pattern, cmd) ; + void AutoCmd::remove_and_add( + AutoCmdEvent event, + const std::string& pattern, + const std::string& cmdstr) { + remove(event, pattern) ; + add(event, pattern, cmdstr) ; } } } diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp index 555453f0..8c6f1982 100644 --- a/src/core/autocmd.hpp +++ b/src/core/autocmd.hpp @@ -84,22 +84,22 @@ namespace vind // Perform command automation. // First argument: the event type // Second argument: target window handle, which has default HWND. - void apply_autocmds(AutoCmdEvent event, DWORD procid=0) ; + void apply(AutoCmdEvent event, DWORD procid=0) ; - void add_autocmd( + void add( AutoCmdEvent event, const std::string& pattern, const std::string& cmd) ; - void remove_autocmd(AutoCmdEvent event) ; + void remove(AutoCmdEvent event) ; - void remove_autocmd( + void remove( AutoCmdEvent event, const std::string& pattern) ; - void remove_autocmd(const std::string& pattern) ; + void remove(const std::string& pattern) ; - void remove_autocmd( + void remove_and_add( AutoCmdEvent event, const std::string& pattern, const std::string& cmd) ; diff --git a/src/core/entry.cpp b/src/core/entry.cpp index c481a3d6..c46e8ff9 100644 --- a/src/core/entry.cpp +++ b/src/core/entry.cpp @@ -323,9 +323,9 @@ namespace vind DWORD procid ; if(hwnd && GetWindowThreadProcessId(hwnd, &procid)) { if(pimpl->previous_procid_ != procid) { - ac.apply_autocmds(AutoCmdEvent::APP_LEAVE, pimpl->previous_procid_) ; + ac.apply(AutoCmdEvent::APP_LEAVE, pimpl->previous_procid_) ; pimpl->previous_procid_ = procid ; - ac.apply_autocmds(AutoCmdEvent::APP_ENTER, procid) ; + ac.apply(AutoCmdEvent::APP_ENTER, procid) ; } } From cd96f8a2087d7f9a5f39763a17f45e3c6b5978e1 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Fri, 11 Aug 2023 21:04:57 +0900 Subject: [PATCH 16/22] fix autocmd! having multiple events --- src/bind/syscmd/autocmd.cpp | 5 ++++- src/core/autocmd.cpp | 8 -------- src/core/autocmd.hpp | 5 ----- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/bind/syscmd/autocmd.cpp b/src/bind/syscmd/autocmd.cpp index 218a574b..6379f6ce 100644 --- a/src/bind/syscmd/autocmd.cpp +++ b/src/bind/syscmd/autocmd.cpp @@ -122,7 +122,10 @@ namespace vind } for(const auto event : events) { - ac.remove_and_add(event, aupat, cmd) ; + ac.remove(event, aupat) ; + } + for(const auto event : events) { + ac.add(event, aupat, cmd) ; } } } diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index 12088fdc..058e2c1b 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -314,13 +314,5 @@ namespace vind pimpl->events_[i].remove_pattern(pattern) ; } } - - void AutoCmd::remove_and_add( - AutoCmdEvent event, - const std::string& pattern, - const std::string& cmdstr) { - remove(event, pattern) ; - add(event, pattern, cmdstr) ; - } } } diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp index 8c6f1982..5dfe7d12 100644 --- a/src/core/autocmd.hpp +++ b/src/core/autocmd.hpp @@ -98,11 +98,6 @@ namespace vind const std::string& pattern) ; void remove(const std::string& pattern) ; - - void remove_and_add( - AutoCmdEvent event, - const std::string& pattern, - const std::string& cmd) ; } ; } } From eff0c16c5b2a88d58d46270504470094a9fa2048 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Fri, 11 Aug 2023 22:46:55 +0900 Subject: [PATCH 17/22] add unit test for autocmd --- res/resources/defaults/tiny.vindrc | 2 +- src/bind/syscmd/autocmd.cpp | 2 +- src/core/autocmd.cpp | 73 +++++++------ src/core/autocmd.hpp | 31 +++--- tests/unit/alone/CMakeLists.txt | 24 +++++ tests/unit/alone/autocmd_test.cpp | 167 +++++++++++++++++++++++++++++ 6 files changed, 250 insertions(+), 49 deletions(-) create mode 100644 tests/unit/alone/autocmd_test.cpp diff --git a/res/resources/defaults/tiny.vindrc b/res/resources/defaults/tiny.vindrc index 9b9378e7..6798e8b9 100644 --- a/res/resources/defaults/tiny.vindrc +++ b/res/resources/defaults/tiny.vindrc @@ -142,5 +142,5 @@ command comc command comclear command so command source -command autocmd +command autocmd command autocmd! diff --git a/src/bind/syscmd/autocmd.cpp b/src/bind/syscmd/autocmd.cpp index 6379f6ce..3e71dc5d 100644 --- a/src/bind/syscmd/autocmd.cpp +++ b/src/bind/syscmd/autocmd.cpp @@ -16,7 +16,7 @@ namespace vind namespace bind { AutoCmdAdd::AutoCmdAdd() - : BindedFuncVoid("autocmd") + : BindedFuncVoid("autocmd_add") {} void AutoCmdAdd::sprocess( diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index 058e2c1b..db32b1ca 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -37,6 +37,9 @@ namespace else if(pat_[i] == '.') { regex.append("\\.") ; } + else if(pat_[i] == '?' && (i == 0 || (i > 0 && pat_[i - 1] != '\\'))) { + regex.append(".") ; + } else { regex.push_back(pat_[i]) ; } @@ -127,19 +130,8 @@ namespace } } - void enqueue_sequential_command(int patidx) { - for(const auto& cmd : seqcmds_[patidx]) { - for(const auto& unit : cmd) { - if(unit->empty()) { - // Function - core::InputHub::get_instance().enqueue(unit, 1) ; - } - else { - // Keycode - core::InputHub::get_instance().do_typing(unit) ; - } - } - } + const SequentialCmd& get_sequential_command(int patidx) { + return seqcmds_.at(patidx) ; } void clear() { @@ -157,14 +149,14 @@ namespace vind static std::unordered_map names { {"appenter", AutoCmdEvent::APP_ENTER}, {"appleave", AutoCmdEvent::APP_LEAVE}, - {"gnormalenter", AutoCmdEvent::GUI_NORMAL_ENTER}, - {"gnormalleave", AutoCmdEvent::GUI_NORMAL_LEAVE}, - {"gvisualenter", AutoCmdEvent::GUI_VISUAL_ENTER}, - {"gvisualleave", AutoCmdEvent::GUI_VISUAL_LEAVE}, - {"enormalenter", AutoCmdEvent::EDI_NORMAL_ENTER}, - {"enormalleave", AutoCmdEvent::EDI_NORMAL_LEAVE}, - {"evisualenter", AutoCmdEvent::EDI_VISUAL_ENTER}, - {"evisualleave", AutoCmdEvent::EDI_VISUAL_LEAVE}, + {"guinormalenter", AutoCmdEvent::GUI_NORMAL_ENTER}, + {"guinormalleave", AutoCmdEvent::GUI_NORMAL_LEAVE}, + {"guivisualenter", AutoCmdEvent::GUI_VISUAL_ENTER}, + {"guivisualleave", AutoCmdEvent::GUI_VISUAL_LEAVE}, + {"edinormalenter", AutoCmdEvent::EDI_NORMAL_ENTER}, + {"edinormalleave", AutoCmdEvent::EDI_NORMAL_LEAVE}, + {"edivisualenter", AutoCmdEvent::EDI_VISUAL_ENTER}, + {"edivisualleave", AutoCmdEvent::EDI_VISUAL_LEAVE}, {"insertenter", AutoCmdEvent::INSERT_ENTER}, {"insertleave", AutoCmdEvent::INSERT_LEAVE}, {"residententer", AutoCmdEvent::RESIDENT_ENTER}, @@ -186,6 +178,18 @@ namespace vind explicit Impl() : events_() {} + + std::string get_module_path(DWORD procid) { + // Check pattern of the parent process + std::string path ; + try { + path = util::get_module_path(procid) ; + } + catch(const std::runtime_error&) { + return "" ; + } + return util::A2a(util::replace_all(path, "\\", "/")) ; + } } ; AutoCmd::AutoCmd() @@ -231,15 +235,11 @@ namespace vind } std::unordered_set parent_set{procid} ; - std::unordered_set pat_indices{} ; // to call indices of the pattern list // Check pattern of the parent process - std::string path ; - try { - path = util::A2a(util::get_module_path(procid)) ; - } - catch(const std::runtime_error&) { + auto path = pimpl->get_module_path(procid) ; + if(path.empty()) { // If failed to get the path of the module, skip matching. return ; } @@ -252,10 +252,8 @@ namespace vind do { // Check pattern of child processs if(parent_set.find(pe32.th32ParentProcessID) != parent_set.end()) { - try { - path = util::A2a(util::get_module_path(pe32.th32ProcessID)) ; - } - catch(const std::runtime_error&) { + path = pimpl->get_module_path(pe32.th32ProcessID) ; + if(path.empty()) { // If failed to get the path of the module, skip matching. continue ; } @@ -273,7 +271,18 @@ namespace vind // Execute the matched sequential commands if(!pat_indices.empty()) { for(auto patidx : pat_indices) { - evt.enqueue_sequential_command(patidx) ; + for(const auto& cmd : evt.get_sequential_command(patidx)) { + for(const auto& unit : cmd) { + if(unit->empty()) { + // Function + core::InputHub::get_instance().enqueue(unit, 1) ; + } + else { + // Keycode + core::InputHub::get_instance().do_typing(unit) ; + } + } + } } } } diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp index 5dfe7d12..8646a33f 100644 --- a/src/core/autocmd.hpp +++ b/src/core/autocmd.hpp @@ -38,6 +38,22 @@ namespace vind AutoCmdEvent get_autocmd_event(const std::string& event_name) noexcept ; + inline AutoCmdEvent get_enter_event(Mode mode) { + static const std::unordered_map enter_events { + {Mode::GUI_NORMAL, AutoCmdEvent::GUI_NORMAL_ENTER}, + {Mode::GUI_VISUAL, AutoCmdEvent::GUI_VISUAL_ENTER}, + {Mode::EDI_NORMAL, AutoCmdEvent::EDI_NORMAL_ENTER}, + {Mode::EDI_VISUAL, AutoCmdEvent::EDI_VISUAL_ENTER}, + {Mode::INSERT, AutoCmdEvent::INSERT_ENTER}, + {Mode::RESIDENT, AutoCmdEvent::RESIDENT_ENTER}, + {Mode::COMMAND, AutoCmdEvent::COMMAND_ENTER} + } ; + if(enter_events.find(mode) != enter_events.end()) { + return enter_events.at(mode) ; + } + return AutoCmdEvent::UNDEFINED ; + } + inline AutoCmdEvent get_leave_event(Mode mode) { static const std::unordered_map leave_events { {Mode::GUI_NORMAL, AutoCmdEvent::GUI_NORMAL_LEAVE}, @@ -54,21 +70,6 @@ namespace vind return AutoCmdEvent::UNDEFINED ; } - inline AutoCmdEvent get_enter_event(Mode mode) { - static const std::unordered_map enter_events { - {Mode::GUI_NORMAL, AutoCmdEvent::GUI_NORMAL_ENTER}, - {Mode::GUI_VISUAL, AutoCmdEvent::GUI_VISUAL_ENTER}, - {Mode::EDI_NORMAL, AutoCmdEvent::EDI_NORMAL_ENTER}, - {Mode::EDI_VISUAL, AutoCmdEvent::EDI_VISUAL_ENTER}, - {Mode::INSERT, AutoCmdEvent::INSERT_ENTER}, - {Mode::RESIDENT, AutoCmdEvent::RESIDENT_ENTER}, - {Mode::COMMAND, AutoCmdEvent::COMMAND_ENTER} - } ; - if(enter_events.find(mode) != enter_events.end()) { - return enter_events.at(mode) ; - } - return AutoCmdEvent::UNDEFINED ; - } class AutoCmd { private: diff --git a/tests/unit/alone/CMakeLists.txt b/tests/unit/alone/CMakeLists.txt index ff736f4b..965b5f84 100644 --- a/tests/unit/alone/CMakeLists.txt +++ b/tests/unit/alone/CMakeLists.txt @@ -108,3 +108,27 @@ AddTest(each-hint-test ${SRCDIR}/core/keycode.cpp ${SRCDIR}/util/string.cpp ) + + +AddTest(each-autocmd-test + ${CMAKE_CURRENT_SOURCE_DIR}/autocmd_test.cpp + + ${SRCDIR}/bind/bindedfunc.cpp + ${SRCDIR}/core/cmdmatcher.cpp + ${SRCDIR}/core/cmdparser.cpp + ${SRCDIR}/core/cmdunit.cpp + ${SRCDIR}/core/errlogger.cpp + ${SRCDIR}/core/inputgate.cpp + ${SRCDIR}/core/inputhub.cpp + ${SRCDIR}/core/keycode.cpp + ${SRCDIR}/core/mapsolver.cpp + ${SRCDIR}/core/mode.cpp + ${SRCDIR}/core/path.cpp + ${SRCDIR}/core/typeemu.cpp + ${SRCDIR}/util/box2d.cpp + ${SRCDIR}/util/interval_timer.cpp + ${SRCDIR}/util/keystroke_repeater.cpp + ${SRCDIR}/util/string.cpp + ${SRCDIR}/util/winwrap.cpp +) +target_link_libraries(each-autocmd-test userenv) diff --git a/tests/unit/alone/autocmd_test.cpp b/tests/unit/alone/autocmd_test.cpp new file mode 100644 index 00000000..008828ad --- /dev/null +++ b/tests/unit/alone/autocmd_test.cpp @@ -0,0 +1,167 @@ +#include "core/autocmd.cpp" + +#include +#include + +namespace vind +{ + namespace bind + { + BindedFunc::SPtr search_func(const std::string&) { + return nullptr ; + } + } +} + + +TEST_CASE("get_autocmd_event") { + using namespace core ; + CHECK_EQ(get_autocmd_event("AppEnter"), AutoCmdEvent::APP_ENTER) ; + CHECK_EQ(get_autocmd_event("AppLeave"), AutoCmdEvent::APP_LEAVE) ; + CHECK_EQ(get_autocmd_event("GUINormalEnter"), AutoCmdEvent::GUI_NORMAL_ENTER) ; + CHECK_EQ(get_autocmd_event("GUINormalLeave"), AutoCmdEvent::GUI_NORMAL_LEAVE) ; + CHECK_EQ(get_autocmd_event("EdiNormalEnter"), AutoCmdEvent::EDI_NORMAL_ENTER) ; + CHECK_EQ(get_autocmd_event("EdiNormalLeave"), AutoCmdEvent::EDI_NORMAL_LEAVE) ; + CHECK_EQ(get_autocmd_event("GUIVisualEnter"), AutoCmdEvent::GUI_VISUAL_ENTER) ; + CHECK_EQ(get_autocmd_event("GUIVisualLeave"), AutoCmdEvent::GUI_VISUAL_LEAVE) ; + CHECK_EQ(get_autocmd_event("EdiVisualEnter"), AutoCmdEvent::EDI_VISUAL_ENTER) ; + CHECK_EQ(get_autocmd_event("EdiVisualLeave"), AutoCmdEvent::EDI_VISUAL_LEAVE) ; + CHECK_EQ(get_autocmd_event("InsertEnter"), AutoCmdEvent::INSERT_ENTER) ; + CHECK_EQ(get_autocmd_event("InsertLeave"), AutoCmdEvent::INSERT_LEAVE) ; + CHECK_EQ(get_autocmd_event("ResidentEnter"), AutoCmdEvent::RESIDENT_ENTER) ; + CHECK_EQ(get_autocmd_event("ResidentLeave"), AutoCmdEvent::RESIDENT_LEAVE) ; + CHECK_EQ(get_autocmd_event("CommandEnter"), AutoCmdEvent::COMMAND_ENTER) ; + CHECK_EQ(get_autocmd_event("CommandLeave"), AutoCmdEvent::COMMAND_LEAVE) ; + CHECK_EQ(get_autocmd_event("hjkl"), AutoCmdEvent::UNDEFINED) ; +} + +TEST_CASE("get_enter_event") { + using namespace core ; + + CHECK_EQ(get_enter_event(Mode::GUI_NORMAL), AutoCmdEvent::GUI_NORMAL_ENTER) ; + CHECK_EQ(get_enter_event(Mode::EDI_NORMAL), AutoCmdEvent::EDI_NORMAL_ENTER) ; + CHECK_EQ(get_enter_event(Mode::GUI_VISUAL), AutoCmdEvent::GUI_VISUAL_ENTER) ; + CHECK_EQ(get_enter_event(Mode::EDI_VISUAL), AutoCmdEvent::EDI_VISUAL_ENTER) ; + CHECK_EQ(get_enter_event(Mode::INSERT), AutoCmdEvent::INSERT_ENTER) ; + CHECK_EQ(get_enter_event(Mode::RESIDENT), AutoCmdEvent::RESIDENT_ENTER) ; + CHECK_EQ(get_enter_event(Mode::COMMAND), AutoCmdEvent::COMMAND_ENTER) ; + CHECK_EQ(get_enter_event(Mode::UNDEFINED), AutoCmdEvent::UNDEFINED) ; +} + +TEST_CASE("get_leave_event") { + using namespace core ; + + CHECK_EQ(get_leave_event(Mode::GUI_NORMAL), AutoCmdEvent::GUI_NORMAL_LEAVE) ; + CHECK_EQ(get_leave_event(Mode::EDI_NORMAL), AutoCmdEvent::EDI_NORMAL_LEAVE) ; + CHECK_EQ(get_leave_event(Mode::GUI_VISUAL), AutoCmdEvent::GUI_VISUAL_LEAVE) ; + CHECK_EQ(get_leave_event(Mode::EDI_VISUAL), AutoCmdEvent::EDI_VISUAL_LEAVE) ; + CHECK_EQ(get_leave_event(Mode::INSERT), AutoCmdEvent::INSERT_LEAVE) ; + CHECK_EQ(get_leave_event(Mode::RESIDENT), AutoCmdEvent::RESIDENT_LEAVE) ; + CHECK_EQ(get_leave_event(Mode::COMMAND), AutoCmdEvent::COMMAND_LEAVE) ; + CHECK_EQ(get_leave_event(Mode::UNDEFINED), AutoCmdEvent::UNDEFINED) ; +} + +TEST_CASE("AutoPattern") { + SUBCASE("Simple") { + AutoPattern ap1("*") ; + AutoPattern ap2("?") ; + AutoPattern ap3("\\?") ; + AutoPattern ap4(".") ; + AutoPattern ap5("~") ; + AutoPattern ap6("[ch]") ; + AutoPattern ap7("[^ch]") ; + + CHECK(ap1.match("abcd")) ; + CHECK(ap1.match("a")) ; + + CHECK(ap2.match("x")) ; + CHECK(ap2.match("2")) ; + CHECK_FALSE(ap2.match("ajb")) ; + + CHECK(ap3.match("?")) ; + CHECK_FALSE(ap3.match("x")) ; + + CHECK(ap4.match(".")) ; + CHECK_FALSE(ap4.match("b")) ; + + CHECK(ap5.match("~")) ; + CHECK_FALSE(ap5.match("n")) ; + + CHECK(ap6.match("c")) ; + CHECK(ap6.match("h")) ; + CHECK_FALSE(ap6.match("l")) ; + CHECK_FALSE(ap6.match("3")) ; + } + + SUBCASE("Complex") { + AutoPattern ap1("*.exe") ; + AutoPattern ap2("*vim*") ; + AutoPattern ap3("*/vim/entry.*") ; + AutoPattern ap4("?:/*/win-vind/*/*.exe") ; + AutoPattern ap5("*(vim|emacs)[0-9].[0-9]/*") ; + + CHECK(ap1.match("C:/abc/defj/x.exe")) ; + CHECK(ap1.match("C:/abc/defj/fjalkfa.exe")) ; + CHECK_FALSE(ap1.match("C:/abc/defj/x.exea")) ; + + CHECK(ap2.match("C:/Program Files (x86)/fjaklf/vim/vim.exe")) ; + CHECK(ap2.match("C:/Program Files (x86)/vim-like-something/gui.exe")) ; + CHECK_FALSE(ap2.match("C:/Program Files (x86)/like-something/gui.exe")) ; + + CHECK(ap3.match("C:/Program Files (x86)/vim/entry.exe")) ; + CHECK_FALSE(ap3.match("C:/Program Files (x86)/vim/vim.exe")) ; + + CHECK(ap4.match("C:/Program Files (x86)/win-vind/bin/win-vind.exe")) ; + CHECK(ap4.match("C:/Program Files (x86)/win-vind/bin/gui.exe")) ; + CHECK(ap4.match("D:/Program Files (x86)/win-vind/bin/win-vind.exe")) ; + CHECK_FALSE(ap4.match("D:/win-vind/bin/win-vind.exe")) ; + + CHECK(ap5.match("D:/Program Files (x86)/vim8.1/bin/vim.exe")) ; + CHECK(ap5.match("D:/Program Files (x86)/emacs1.0/bin/emacs.exe")) ; + CHECK_FALSE(ap5.match("D:/Program Files (x86)/emacs1.2.0/bin/emacs.exe")) ; + CHECK_FALSE(ap5.match("D:/Program Files (x86)/vscode1.2/bin/code.exe")) ; + } +} + +TEST_CASE("AutoEvent") { + AutoEvent evt ; + auto cmd1 = core::parse_command("hjkl") ; + evt.add_pattern_cmd("*notepad*", cmd1) ; + + auto cmd2 = core::parse_command("") ; + evt.add_pattern_cmd("*vim*", cmd2) ; + + auto cmd3 = core::parse_command("abcd") ; + evt.add_pattern_cmd("*vim*", cmd3) ; + + auto cmd4 = core::parse_command("jj") ; + evt.add_pattern_cmd("*vim-like*", cmd4) ; + + auto cmd5 = core::parse_command("FF") ; + evt.add_pattern_cmd("*edge*", cmd5) ; + + std::unordered_set indices ; + evt.match_pattern("C:/Program Files/vim-like/something.exe", indices) ; + CHECK_EQ(indices.size(), 2) ; + CHECK(indices.find(1) != indices.end()) ; + CHECK(indices.find(2) != indices.end()) ; + + const auto& cmd_list_1 = evt.get_sequential_command(1) ; + CHECK_EQ(cmd_list_1.size(), 2) ; + CHECK(cmd_list_1[0] == cmd2) ; + CHECK(cmd_list_1[1] == cmd3) ; + + const auto& cmd_list_2 = evt.get_sequential_command(2) ; + CHECK_EQ(cmd_list_2.size(), 1) ; + CHECK(cmd_list_2[0] == cmd4) ; + + indices.clear() ; + + evt.remove_pattern("*vim*") ; + evt.match_pattern("C:/Program Files/vim-like/something.exe", indices) ; + CHECK_EQ(indices.size(), 1) ; + + const auto& cmd_list_3 = evt.get_sequential_command(1) ; + CHECK_EQ(cmd_list_3.size(), 1) ; + CHECK(cmd_list_3[0] == cmd4) ; +} From c3ecd72c0a00bb11d791362df934ae0250038dcd Mon Sep 17 00:00:00 2001 From: pit-ray Date: Fri, 11 Aug 2023 23:34:42 +0900 Subject: [PATCH 18/22] update document --- docs/cheat_sheet/defaults/big/index.md | 36 ++++---- docs/cheat_sheet/defaults/normal/index.md | 40 ++++----- docs/cheat_sheet/defaults/small/index.md | 24 ++--- docs/cheat_sheet/defaults/tiny/index.md | 28 +++--- docs/cheat_sheet/functions/index.md | 104 ++++++++++++++++++++++ 5 files changed, 169 insertions(+), 63 deletions(-) diff --git a/docs/cheat_sheet/defaults/big/index.md b/docs/cheat_sheet/defaults/big/index.md index d30a9cce..320ec598 100644 --- a/docs/cheat_sheet/defaults/big/index.md +++ b/docs/cheat_sheet/defaults/big/index.md @@ -19,8 +19,8 @@ nav: Big Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| |`V`|[\]({{ site.url }}/cheat_sheet/functions/#select_all)| -|`y`, `Y`, `yy`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_copy)| -|`p`, `P`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_paste)| +|`Y`, `yy`, `y`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_copy)| +|`P`, `p`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_paste)| |`dd`, `D`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_cut)| |``, `x`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_delete)| |`X`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_backspace)| @@ -33,7 +33,7 @@ nav: Big Mappings |`s`|[\]({{ site.url }}/cheat_sheet/functions/#taskview)| |`gT`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_left_tab)| |`gt`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_right_tab)| -|`/`, `?`|[\]({{ site.url }}/cheat_sheet/functions/#search_pattern)| +|`?`, `/`|[\]({{ site.url }}/cheat_sheet/functions/#search_pattern)| |``|[\]({{ site.url }}/cheat_sheet/functions/#goto_next_page)| |``|[\]({{ site.url }}/cheat_sheet/functions/#goto_prev_page)| |``|[\]({{ site.url }}/cheat_sheet/functions/#open_startmenu)| @@ -44,7 +44,7 @@ nav: Big Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| |``|[\]({{ site.url }}/cheat_sheet/functions/#to_resident)| ### Mouse Movement @@ -53,15 +53,15 @@ nav: Big Mappings |:---:|:---:| |``, `h`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_left)| |``, `l`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_right)| -|`k`, `-`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_up)| -|`+`, ``, `j`|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_down)| +|``, `-`, `k`|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_up)| +|`+`, `j`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_down)| ### Mouse Jumping |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, `0`, `^`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_left)| -|`$`, ``|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_right)| +|`^`, `0`, ``|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_left)| +|``, `$`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_right)| |`gg`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_top)| |`G`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_bottom)| |`gm`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_hcenter)| @@ -71,8 +71,8 @@ nav: Big Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_onepage)| @@ -86,8 +86,8 @@ nav: Big Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`y`, `Y`, `yy`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_copy)| -|`p`, `P`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_paste)| +|`Y`, `yy`, `y`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_copy)| +|`P`, `p`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_paste)| |`dd`, `D`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_cut)| |``, `x`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_delete)| |`X`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_backspace)| @@ -98,7 +98,7 @@ nav: Big Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`guivisual`, `gv`|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_visual)| +|`gv`, `guivisual`|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_visual)| ### Shortcut @@ -107,14 +107,14 @@ nav: Big Mappings |`vdprev`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_left_vdesktop)| |`vdnext`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_right_vdesktop)| |`closev`|[\]({{ site.url }}/cheat_sheet/functions/#close_current_vdesktop)| -|`taskview`, `tv`, `vdesktoplist`|[\]({{ site.url }}/cheat_sheet/functions/#taskview)| +|`tv`, `taskview`, `vdesktoplist`|[\]({{ site.url }}/cheat_sheet/functions/#taskview)| |`tabprevious`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_left_tab)| |`tabnext`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_right_tab)| |`tabnew`|[\]({{ site.url }}/cheat_sheet/functions/#open_new_tab)| -|`q!`, `tabclose`, `q`|[\]({{ site.url }}/cheat_sheet/functions/#close_current_tab)| -|`ex`, `explorer`|[\]({{ site.url }}/cheat_sheet/functions/#start_explorer)| -|`start`, `win`|[\]({{ site.url }}/cheat_sheet/functions/#open_startmenu)| -|`find`, `open`|[\]({{ site.url }}/cheat_sheet/functions/#open)| +|`q!`, `q`, `tabclose`|[\]({{ site.url }}/cheat_sheet/functions/#close_current_tab)| +|`explorer`, `ex`|[\]({{ site.url }}/cheat_sheet/functions/#start_explorer)| +|`win`, `start`|[\]({{ site.url }}/cheat_sheet/functions/#open_startmenu)| +|`open`, `find`|[\]({{ site.url }}/cheat_sheet/functions/#open)| |`forward`|[\]({{ site.url }}/cheat_sheet/functions/#forward_ui_navigation)| |`backward`|[\]({{ site.url }}/cheat_sheet/functions/#backward_ui_navigation)| |`decide`|[\]({{ site.url }}/cheat_sheet/functions/#decide_focused_ui_object)| diff --git a/docs/cheat_sheet/defaults/normal/index.md b/docs/cheat_sheet/defaults/normal/index.md index 71030037..2b454917 100644 --- a/docs/cheat_sheet/defaults/normal/index.md +++ b/docs/cheat_sheet/defaults/normal/index.md @@ -18,7 +18,7 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| |``|[\]({{ site.url }}/cheat_sheet/functions/#to_resident)| |`:`|[\]({{ site.url }}/cheat_sheet/functions/#to_command)| |`i`|[\]({{ site.url }}/cheat_sheet/functions/#to_insert)| @@ -29,8 +29,8 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_onepage)| @@ -48,13 +48,13 @@ nav: Normal Mappings |`u`, `U`|[\]({{ site.url }}/cheat_sheet/functions/#undo)| |`gT`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_left_tab)| |`gt`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_right_tab)| -|`/`, `?`|[\]({{ site.url }}/cheat_sheet/functions/#search_pattern)| +|`?`, `/`|[\]({{ site.url }}/cheat_sheet/functions/#search_pattern)| ### Mode Transition on Vim Emulation |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`I`, `gI`|[\]({{ site.url }}/cheat_sheet/functions/#to_insert_bol)| +|`gI`, `I`|[\]({{ site.url }}/cheat_sheet/functions/#to_insert_bol)| |`a`|[\]({{ site.url }}/cheat_sheet/functions/#to_insert_append)| |`A`|[\]({{ site.url }}/cheat_sheet/functions/#to_insert_eol)| |`o`|[\]({{ site.url }}/cheat_sheet/functions/#to_insert_nlbelow)| @@ -66,8 +66,8 @@ nav: Normal Mappings |:---:|:---:| |``, ``, `h`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_left)| |``, `l`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_right)| -|``, `gk`, `-`, `k`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_up)| -|``, ``, ``, `gj`, `+`, ``, `j`|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_down)| +|``, `-`, ``, `k`, `gk`|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_up)| +|`gj`, `+`, ``, ``, ``, `j`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_down)| |`w`|[\]({{ site.url }}/cheat_sheet/functions/#move_fwd_word)| |`b`|[\]({{ site.url }}/cheat_sheet/functions/#move_bck_word)| |`W`|[\]({{ site.url }}/cheat_sheet/functions/#move_fwd_bigword)| @@ -81,8 +81,8 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, `0`, `g0`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_bol)| -|`$`, ``, `g$`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_eol)| +|`0`, ``, `g0`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_bol)| +|``, `g$`, `$`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_eol)| |`gg`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_bof)| |`G`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_eof)| @@ -104,7 +104,7 @@ nav: Normal Mappings |`~`|[\]({{ site.url }}/cheat_sheet/functions/#switch_char_case)| |`d`|[\]({{ site.url }}/cheat_sheet/functions/#delete_with_motion)| |`c`|[\]({{ site.url }}/cheat_sheet/functions/#change_with_motion)| -|`S`, `cc`|[\]({{ site.url }}/cheat_sheet/functions/#change_line)| +|`cc`, `S`|[\]({{ site.url }}/cheat_sheet/functions/#change_line)| |`s`|[\]({{ site.url }}/cheat_sheet/functions/#change_char)| |`C`|[\]({{ site.url }}/cheat_sheet/functions/#change_until_eol)| |`.`|[\]({{ site.url }}/cheat_sheet/functions/#repeat_last_change)| @@ -115,7 +115,7 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| |``|[\]({{ site.url }}/cheat_sheet/functions/#to_resident)| |`:`|[\]({{ site.url }}/cheat_sheet/functions/#to_command)| |``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_edi_normal)| @@ -124,8 +124,8 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_onepage)| @@ -141,8 +141,8 @@ nav: Normal Mappings |:---:|:---:| |``, ``, `h`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_left)| |``, `l`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_right)| -|``, `gk`, `-`, `k`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_up)| -|``, ``, ``, `gj`, `+`, ``, `j`|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_down)| +|``, `-`, ``, `k`, `gk`|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_up)| +|`gj`, `+`, ``, ``, ``, `j`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_down)| |`w`|[\]({{ site.url }}/cheat_sheet/functions/#move_fwd_word_simple)| |`b`|[\]({{ site.url }}/cheat_sheet/functions/#move_bck_word_simple)| @@ -150,8 +150,8 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, `0`, `g0`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_bol)| -|`$`, ``, `g$`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_eol)| +|`0`, ``, `g0`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_bol)| +|``, `g$`, `$`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_eol)| |`gg`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_bof)| |`G`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_eof)| @@ -160,8 +160,8 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| |`y`|[\]({{ site.url }}/cheat_sheet/functions/#yank_highlight_text)| -|`d`, `X`, `x`|[\]({{ site.url }}/cheat_sheet/functions/#delete_highlight_text)| -|`c`, `S`, `s`|[\]({{ site.url }}/cheat_sheet/functions/#change_highlight_text)| +|`x`, `X`, `d`|[\]({{ site.url }}/cheat_sheet/functions/#delete_highlight_text)| +|`s`, `S`, `c`|[\]({{ site.url }}/cheat_sheet/functions/#change_highlight_text)| ## Insert Mode @@ -179,7 +179,7 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`en`, `edinormal`|[\]({{ site.url }}/cheat_sheet/functions/#to_edi_normal)| +|`edinormal`, `en`|[\]({{ site.url }}/cheat_sheet/functions/#to_edi_normal)| |`edivisual`, `ev`|[\]({{ site.url }}/cheat_sheet/functions/#to_edi_visual)| |`edivisualline`, `evl`|[\]({{ site.url }}/cheat_sheet/functions/#to_edi_visual_line)| diff --git a/docs/cheat_sheet/defaults/small/index.md b/docs/cheat_sheet/defaults/small/index.md index 06d40e6c..38315686 100644 --- a/docs/cheat_sheet/defaults/small/index.md +++ b/docs/cheat_sheet/defaults/small/index.md @@ -40,7 +40,7 @@ nav: Small Mappings |`u`|[\]({{ site.url }}/cheat_sheet/functions/#maximize_current_window)| |`d`|[\]({{ site.url }}/cheat_sheet/functions/#minimize_current_window)| |``, `H`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_left)| -|`L`, ``|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_right)| +|``, `L`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_right)| |`K`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_top)| |`J`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_bottom)| |`e`|[\]({{ site.url }}/cheat_sheet/functions/#window_resizer)| @@ -51,38 +51,38 @@ nav: Small Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`close`, `cl`|[\]({{ site.url }}/cheat_sheet/functions/#close_current_window)| +|`cl`, `close`|[\]({{ site.url }}/cheat_sheet/functions/#close_current_window)| |`new`|[\]({{ site.url }}/cheat_sheet/functions/#open_new_window)| -|`sp`, `split`|[\]({{ site.url }}/cheat_sheet/functions/#open_new_window_with_hsplit)| +|`split`, `sp`|[\]({{ site.url }}/cheat_sheet/functions/#open_new_window_with_hsplit)| |`vsplit`, `vs`|[\]({{ site.url }}/cheat_sheet/functions/#open_new_window_with_vsplit)| ### Window Select |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`sw`, `switch`|[\]({{ site.url }}/cheat_sheet/functions/#switch_window)| +|`switch`, `sw`|[\]({{ site.url }}/cheat_sheet/functions/#switch_window)| ### Window Resize |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`resizer`, `winresizer`|[\]({{ site.url }}/cheat_sheet/functions/#window_resizer)| +|`winresizer`, `resizer`|[\]({{ site.url }}/cheat_sheet/functions/#window_resizer)| |`max`, `on`, `only`|[\]({{ site.url }}/cheat_sheet/functions/#maximize_current_window)| -|`hi`, `min`, `hide`|[\]({{ site.url }}/cheat_sheet/functions/#minimize_current_window)| -|`lsp`, `lsplit`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_left)| +|`hide`, `hi`, `min`|[\]({{ site.url }}/cheat_sheet/functions/#minimize_current_window)| +|`lsplit`, `lsp`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_left)| |`rsp`, `rsplit`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_right)| |`tsplit`, `tsp`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_top)| -|`bsplit`, `bsp`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_bottom)| +|`bsp`, `bsplit`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_bottom)| |`arrange`|[\]({{ site.url }}/cheat_sheet/functions/#arrange_windows)| |`reload`|[\]({{ site.url }}/cheat_sheet/functions/#reload_current_window)| |`rot`, `rotate`|[\]({{ site.url }}/cheat_sheet/functions/#rotate_windows)| -|`rerotate`, `rerot`|[\]({{ site.url }}/cheat_sheet/functions/#rotate_windows_in_reverse)| +|`rerot`, `rerotate`|[\]({{ site.url }}/cheat_sheet/functions/#rotate_windows_in_reverse)| |`exchange`|[\]({{ site.url }}/cheat_sheet/functions/#exchange_window_with_nearest)| -|`vertres`, `verticalresize`|[\]({{ site.url }}/cheat_sheet/functions/#resize_window_width)| +|`verticalresize`, `vertres`|[\]({{ site.url }}/cheat_sheet/functions/#resize_window_width)| |`verticalresize+`, `vertres+`|[\]({{ site.url }}/cheat_sheet/functions/#increase_window_width)| |`vertres-`, `verticalresize-`|[\]({{ site.url }}/cheat_sheet/functions/#decrease_window_width)| -|`resize`, `res`|[\]({{ site.url }}/cheat_sheet/functions/#resize_window_height)| -|`res+`, `resize+`|[\]({{ site.url }}/cheat_sheet/functions/#increase_window_height)| +|`res`, `resize`|[\]({{ site.url }}/cheat_sheet/functions/#resize_window_height)| +|`resize+`, `res+`|[\]({{ site.url }}/cheat_sheet/functions/#increase_window_height)| |`resize-`, `res-`|[\]({{ site.url }}/cheat_sheet/functions/#decrease_window_height)| ### Process Launcher diff --git a/docs/cheat_sheet/defaults/tiny/index.md b/docs/cheat_sheet/defaults/tiny/index.md index fc7cac78..c96a4c6d 100644 --- a/docs/cheat_sheet/defaults/tiny/index.md +++ b/docs/cheat_sheet/defaults/tiny/index.md @@ -12,7 +12,7 @@ nav: Tiny Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| |``|[\]({{ site.url }}/cheat_sheet/functions/#to_resident)| |`:`|[\]({{ site.url }}/cheat_sheet/functions/#to_command)| |`i`|[\]({{ site.url }}/cheat_sheet/functions/#to_insert)| @@ -21,17 +21,17 @@ nav: Tiny Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`h`, ``, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_left)| -|``, ``, `l`|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_right)| -|``, `k`, `-`|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_up)| -|`+`, `j`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_down)| +|``, ``, `h`|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_left)| +|`l`, ``, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_right)| +|`-`, `k`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_up)| +|``, `+`, `j`|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_down)| ### Mouse Clicking |**Trigger Commands**|**Called Commands**| |:---:|:---:| |`O`, `o`|[\]({{ site.url }}/cheat_sheet/functions/#click_left)| -|`a`, `A`|[\]({{ site.url }}/cheat_sheet/functions/#click_right)| +|`A`, `a`|[\]({{ site.url }}/cheat_sheet/functions/#click_right)| ### Mouse Scrolling @@ -43,8 +43,8 @@ nav: Tiny Mappings |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_onepage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_onepage)| -|``, `zh`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left)| -|``, `zl`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_right)| +|`zh`, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left)| +|`zl`, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_right)| |`zh`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left_halfpage)| |`zl`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_right_halfpage)| @@ -52,8 +52,8 @@ nav: Tiny Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, `0`, `^`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_left)| -|``, `$`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_right)| +|`^`, `0`, ``|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_left)| +|`$`, ``|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_right)| |`gg`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_top)| |`G`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_bottom)| |`gm`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_hcenter)| @@ -75,7 +75,7 @@ nav: Tiny Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| |``|[\]({{ site.url }}/cheat_sheet/functions/#to_instant_gui_normal)| |``|[\]({{ site.url }}/cheat_sheet/functions/#to_resident)| @@ -108,9 +108,11 @@ nav: Tiny Mappings |`{mode}unmap`|[\<{mode}unmap\>]({{ site.url }}/cheat_sheet/functions/#unmap)| |`{mode}mapclear`|[\<{mode}mapclear\>]({{ site.url }}/cheat_sheet/functions/#mapclear)| |`command`, `com`|[\]({{ site.url }}/cheat_sheet/functions/#command)| -|`delc`, `delcommand`|[\]({{ site.url }}/cheat_sheet/functions/#delcommand)| -|`comc`, `comclear`|[\]({{ site.url }}/cheat_sheet/functions/#comclear)| +|`delcommand`, `delc`|[\]({{ site.url }}/cheat_sheet/functions/#delcommand)| +|`comclear`, `comc`|[\]({{ site.url }}/cheat_sheet/functions/#comclear)| |`so`, `source`|[\]({{ site.url }}/cheat_sheet/functions/#source)| +|`autocmd`|[\]({{ site.url }}/cheat_sheet/functions/#autocmd_add)| +|`autocmd!`|[\]({{ site.url }}/cheat_sheet/functions/#autocmd_del)|

diff --git a/docs/cheat_sheet/functions/index.md b/docs/cheat_sheet/functions/index.md index c0212883..a6cde93c 100644 --- a/docs/cheat_sheet/functions/index.md +++ b/docs/cheat_sheet/functions/index.md @@ -248,6 +248,110 @@ System Command comclear. - [\](./#map) - [\](./#noremap) +
+ +### **``** + +**Syntax** +```vim +autocmd {event} {aupat} {cmd} +``` + +It adds `{cmd}` into autocmd list for `{aupat}`, autocmd pattern, corresponding to `{event}`. +As such as Vim, this function append `{cmd}` into a list rather than overwriting it even if the same `{cmd}` has already existed in a list. +The event does not allow us to use `*`. +If you want to add a command to multiple events at the same time, `,` without after-space is available. +The rule of `{aupat}` is based on the original Vim. +The registered `{cmd}`s will execute in the order added. + +**Event** + +The following table shows the supported events. autocmd is NOT case-sensitive for events. + +|*Event*|*When does it ignite?*| +|:---|:---| +|AppEnter|Select an application| +|AppLeave|Unselect an application| +|GUINormalEnter|Enter to the GUI normal mode| +|GUINormalLeave|Leave from the GUI normal mode| +|GUIVisualEnter|Enter to the GUI visual mode| +|GUIVisualLeave|Leave from the GUI visual mode| +|EdiNormalEnter|Enter to the editor normal mode| +|EdiNormalLeave|Leave from the editor normal mode| +|EdiVisualEnter|Enter to the editor visual mode| +|EdiVisualLeave|Leave from the editor visual mode| +|InsertEnter|Enter to the insert mode| +|InsertLeave|Leave from the insert mode| +|ResidentEnter|Enter to the resident mode| +|ResidentLeave|Leave from the resident mode| +|CmdLineEnter|Enter to the command mode| +|CmdLineLeave|Leave from the command mode| + +
+ +**Pattern** + +The pattern matches against the absolute path to the executable file of the application which creates each event. + +|Pattern|Interpretation| +|:---|:---| +|`*`|Matches any character| +|`?`|Matches any single character| +|`\?`|Matches the `?` character| +|`.`|Matches the `.` character| +|`~`|Matches the `~` character| + +
+All path delimiters `\` in Windows are treated as `/` in pattern translation. +All others follow the general regex. + +**Examples** + +```vim +" Default mapping (match any applications) +autocmd AppLeave * + +" Limited mapping (match specific application) +autocmd AppEnter *notepad* +autocmd AppEnter,EdiNormalEnter *vim* +autocmd AppEnter C:/*/Zotero/zotero.exe +``` + +**See Also** +- [\](./#autocmd_del) + +
+ + +### **``** +**Syntax** +```vim +autocmd! {event} {aupat} {cmd} +``` + +It remove all autocmd matched `{event}` and `{aupat}`, then register `{cmd}` after delete. + +The following syntaxes are available. + +```vim +autocmd! {event} {aupat} {cmd} +autocmd! {event} {aupat} +autocmd! * {aupat} +autocmd! {event} +``` + +Each features are the same as the original Vim. + +**Examples** + +```vim +autocmd! * *vim* " Remove all events having the pattern *vim* +autocmd! AppLeave *notepad* " Remove old events and add a new event +``` + +**See Also** +- [\](./#autocmd_add) + ## Mouse ### **``** From bcd390458a6098bece5c54689964c51ea0015954 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Fri, 11 Aug 2023 23:40:50 +0900 Subject: [PATCH 19/22] fix autocmd apply --- src/bind/mode/instant_mode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bind/mode/instant_mode.cpp b/src/bind/mode/instant_mode.cpp index c8f42faf..a80f83e3 100644 --- a/src/bind/mode/instant_mode.cpp +++ b/src/bind/mode/instant_mode.cpp @@ -83,7 +83,7 @@ namespace vind break ; } opt::VCmdLine::reset() ; - ac.apply(core::get_enter_event(m)) ; + ac.apply(core::get_leave_event(core::Mode::GUI_NORMAL)) ; return res ; } From 734951f782e33512f1fd639554c1d6ff3c8b3fb6 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Fri, 11 Aug 2023 23:55:47 +0900 Subject: [PATCH 20/22] deprecate suppress_for_vim and dedicate_to_window --- docs/cheat_sheet/defaults/big/index.md | 36 ++++++------ docs/cheat_sheet/defaults/huge/index.md | 2 - docs/cheat_sheet/defaults/normal/index.md | 44 +++++++------- docs/cheat_sheet/defaults/small/index.md | 24 ++++---- docs/cheat_sheet/defaults/tiny/index.md | 20 +++---- docs/cheat_sheet/functions/index.md | 16 ------ docs/cheat_sheet/options/index.md | 15 ----- res/resources/defaults/huge.vindrc | 4 -- src/bind/bindinglist.cpp | 4 -- src/bind/ctrl/d2wctrl.cpp | 30 ---------- src/bind/ctrl/d2wctrl.hpp | 24 -------- src/bind/mode/instant_mode.cpp | 4 -- src/bind/mouse/jump_keybrd.cpp | 4 -- src/bind/window/switch_win.cpp | 4 -- src/bind/window/winresizer.cpp | 4 -- src/opt/dedicate_to_window.cpp | 70 ----------------------- src/opt/dedicate_to_window.hpp | 29 ---------- src/opt/optionlist.cpp | 4 -- src/opt/suppress_for_vim.cpp | 62 -------------------- src/opt/suppress_for_vim.hpp | 22 ------- 20 files changed, 62 insertions(+), 360 deletions(-) delete mode 100644 src/bind/ctrl/d2wctrl.cpp delete mode 100644 src/bind/ctrl/d2wctrl.hpp delete mode 100644 src/opt/dedicate_to_window.cpp delete mode 100644 src/opt/dedicate_to_window.hpp delete mode 100644 src/opt/suppress_for_vim.cpp delete mode 100644 src/opt/suppress_for_vim.hpp diff --git a/docs/cheat_sheet/defaults/big/index.md b/docs/cheat_sheet/defaults/big/index.md index 320ec598..fbb4fd77 100644 --- a/docs/cheat_sheet/defaults/big/index.md +++ b/docs/cheat_sheet/defaults/big/index.md @@ -19,10 +19,10 @@ nav: Big Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| |`V`|[\]({{ site.url }}/cheat_sheet/functions/#select_all)| -|`Y`, `yy`, `y`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_copy)| -|`P`, `p`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_paste)| +|`yy`, `y`, `Y`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_copy)| +|`p`, `P`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_paste)| |`dd`, `D`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_cut)| -|``, `x`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_delete)| +|`x`, ``|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_delete)| |`X`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_backspace)| |``|[\]({{ site.url }}/cheat_sheet/functions/#redo)| |`u`, `U`|[\]({{ site.url }}/cheat_sheet/functions/#undo)| @@ -33,7 +33,7 @@ nav: Big Mappings |`s`|[\]({{ site.url }}/cheat_sheet/functions/#taskview)| |`gT`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_left_tab)| |`gt`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_right_tab)| -|`?`, `/`|[\]({{ site.url }}/cheat_sheet/functions/#search_pattern)| +|`/`, `?`|[\]({{ site.url }}/cheat_sheet/functions/#search_pattern)| |``|[\]({{ site.url }}/cheat_sheet/functions/#goto_next_page)| |``|[\]({{ site.url }}/cheat_sheet/functions/#goto_prev_page)| |``|[\]({{ site.url }}/cheat_sheet/functions/#open_startmenu)| @@ -44,23 +44,23 @@ nav: Big Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| |``|[\]({{ site.url }}/cheat_sheet/functions/#to_resident)| ### Mouse Movement |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, `h`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_left)| -|``, `l`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_right)| -|``, `-`, `k`|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_up)| -|`+`, `j`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_down)| +|`h`, ``, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_left)| +|`l`, ``, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_right)| +|`-`, ``, `k`|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_up)| +|``, `+`, `j`|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_down)| ### Mouse Jumping |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`^`, `0`, ``|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_left)| +|``, `^`, `0`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_left)| |``, `$`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_right)| |`gg`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_top)| |`G`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_bottom)| @@ -71,13 +71,13 @@ nav: Big Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| |``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_onepage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_onepage)| -|``, `zh`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left)| +|`zh`, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left)| |``, `zl`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_right)| |`zH`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left_halfpage)| |`zL`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_right_halfpage)| @@ -86,10 +86,10 @@ nav: Big Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`Y`, `yy`, `y`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_copy)| -|`P`, `p`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_paste)| +|`yy`, `y`, `Y`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_copy)| +|`p`, `P`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_paste)| |`dd`, `D`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_cut)| -|``, `x`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_delete)| +|`x`, ``|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_delete)| |`X`|[\]({{ site.url }}/cheat_sheet/functions/#hotkey_backspace)| ## Command Mode @@ -107,12 +107,12 @@ nav: Big Mappings |`vdprev`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_left_vdesktop)| |`vdnext`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_right_vdesktop)| |`closev`|[\]({{ site.url }}/cheat_sheet/functions/#close_current_vdesktop)| -|`tv`, `taskview`, `vdesktoplist`|[\]({{ site.url }}/cheat_sheet/functions/#taskview)| +|`tv`, `vdesktoplist`, `taskview`|[\]({{ site.url }}/cheat_sheet/functions/#taskview)| |`tabprevious`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_left_tab)| |`tabnext`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_right_tab)| |`tabnew`|[\]({{ site.url }}/cheat_sheet/functions/#open_new_tab)| -|`q!`, `q`, `tabclose`|[\]({{ site.url }}/cheat_sheet/functions/#close_current_tab)| -|`explorer`, `ex`|[\]({{ site.url }}/cheat_sheet/functions/#start_explorer)| +|`q`, `tabclose`, `q!`|[\]({{ site.url }}/cheat_sheet/functions/#close_current_tab)| +|`ex`, `explorer`|[\]({{ site.url }}/cheat_sheet/functions/#start_explorer)| |`win`, `start`|[\]({{ site.url }}/cheat_sheet/functions/#open_startmenu)| |`open`, `find`|[\]({{ site.url }}/cheat_sheet/functions/#open)| |`forward`|[\]({{ site.url }}/cheat_sheet/functions/#forward_ui_navigation)| diff --git a/docs/cheat_sheet/defaults/huge/index.md b/docs/cheat_sheet/defaults/huge/index.md index 854968e5..3d7ce6e1 100644 --- a/docs/cheat_sheet/defaults/huge/index.md +++ b/docs/cheat_sheet/defaults/huge/index.md @@ -11,8 +11,6 @@ nav: Huge Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| |`md`, `mkdir`|[\]({{ site.url }}/cheat_sheet/functions/#makedir)| -|`target`|[\]({{ site.url }}/cheat_sheet/functions/#enable_targeting_of_dedicate_to_window)| -|`untarget`|[\]({{ site.url }}/cheat_sheet/functions/#disable_targeting_of_dedicate_to_window)|

diff --git a/docs/cheat_sheet/defaults/normal/index.md b/docs/cheat_sheet/defaults/normal/index.md index 2b454917..fb86aad8 100644 --- a/docs/cheat_sheet/defaults/normal/index.md +++ b/docs/cheat_sheet/defaults/normal/index.md @@ -10,7 +10,7 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``, `I`|[\]({{ site.url }}/cheat_sheet/functions/#to_edi_normal)| +|``, `I`, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_edi_normal)| ## Editor Normal Mode @@ -18,7 +18,7 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| |``|[\]({{ site.url }}/cheat_sheet/functions/#to_resident)| |`:`|[\]({{ site.url }}/cheat_sheet/functions/#to_command)| |`i`|[\]({{ site.url }}/cheat_sheet/functions/#to_insert)| @@ -29,13 +29,13 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| |``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_onepage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_onepage)| -|``, `zh`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left)| +|`zh`, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left)| |``, `zl`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_right)| |`zH`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left_halfpage)| |`zL`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_right_halfpage)| @@ -48,7 +48,7 @@ nav: Normal Mappings |`u`, `U`|[\]({{ site.url }}/cheat_sheet/functions/#undo)| |`gT`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_left_tab)| |`gt`|[\]({{ site.url }}/cheat_sheet/functions/#switch_to_right_tab)| -|`?`, `/`|[\]({{ site.url }}/cheat_sheet/functions/#search_pattern)| +|`/`, `?`|[\]({{ site.url }}/cheat_sheet/functions/#search_pattern)| ### Mode Transition on Vim Emulation @@ -64,10 +64,10 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``, `h`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_left)| -|``, `l`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_right)| -|``, `-`, ``, `k`, `gk`|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_up)| -|`gj`, `+`, ``, ``, ``, `j`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_down)| +|`h`, ``, ``, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_left)| +|`l`, ``, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_right)| +|`-`, ``, `k`, `gk`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_up)| +|``, ``, ``, `+`, ``, `gj`, `j`|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_down)| |`w`|[\]({{ site.url }}/cheat_sheet/functions/#move_fwd_word)| |`b`|[\]({{ site.url }}/cheat_sheet/functions/#move_bck_word)| |`W`|[\]({{ site.url }}/cheat_sheet/functions/#move_fwd_bigword)| @@ -81,7 +81,7 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`0`, ``, `g0`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_bol)| +|``, `g0`, `0`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_bol)| |``, `g$`, `$`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_eol)| |`gg`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_bof)| |`G`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_eof)| @@ -90,13 +90,13 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`Y`, `yy`|[\]({{ site.url }}/cheat_sheet/functions/#yank_line)| +|`yy`, `Y`|[\]({{ site.url }}/cheat_sheet/functions/#yank_line)| |`y`|[\]({{ site.url }}/cheat_sheet/functions/#yank_with_motion)| |`p`|[\]({{ site.url }}/cheat_sheet/functions/#put_after)| |`P`|[\]({{ site.url }}/cheat_sheet/functions/#put_before)| |`dd`|[\]({{ site.url }}/cheat_sheet/functions/#delete_line)| |`D`|[\]({{ site.url }}/cheat_sheet/functions/#delete_line_until_eol)| -|``, `x`|[\]({{ site.url }}/cheat_sheet/functions/#delete_after)| +|`x`, ``|[\]({{ site.url }}/cheat_sheet/functions/#delete_after)| |`X`|[\]({{ site.url }}/cheat_sheet/functions/#delete_before)| |`J`|[\]({{ site.url }}/cheat_sheet/functions/#join_next_line)| |`r`|[\]({{ site.url }}/cheat_sheet/functions/#replace_char)| @@ -115,7 +115,7 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| |``|[\]({{ site.url }}/cheat_sheet/functions/#to_resident)| |`:`|[\]({{ site.url }}/cheat_sheet/functions/#to_command)| |``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_edi_normal)| @@ -124,13 +124,13 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| |``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_onepage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_onepage)| -|``, `zh`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left)| +|`zh`, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left)| |``, `zl`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_right)| |`zH`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left_halfpage)| |`zL`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_right_halfpage)| @@ -139,10 +139,10 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``, `h`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_left)| -|``, `l`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_right)| -|``, `-`, ``, `k`, `gk`|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_up)| -|`gj`, `+`, ``, ``, ``, `j`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_down)| +|`h`, ``, ``, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_left)| +|`l`, ``, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_right)| +|`-`, ``, `k`, `gk`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_up)| +|``, ``, ``, `+`, ``, `gj`, `j`|[\]({{ site.url }}/cheat_sheet/functions/#move_caret_down)| |`w`|[\]({{ site.url }}/cheat_sheet/functions/#move_fwd_word_simple)| |`b`|[\]({{ site.url }}/cheat_sheet/functions/#move_bck_word_simple)| @@ -150,7 +150,7 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`0`, ``, `g0`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_bol)| +|``, `g0`, `0`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_bol)| |``, `g$`, `$`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_eol)| |`gg`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_bof)| |`G`|[\]({{ site.url }}/cheat_sheet/functions/#jump_caret_to_eof)| @@ -160,8 +160,8 @@ nav: Normal Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| |`y`|[\]({{ site.url }}/cheat_sheet/functions/#yank_highlight_text)| -|`x`, `X`, `d`|[\]({{ site.url }}/cheat_sheet/functions/#delete_highlight_text)| -|`s`, `S`, `c`|[\]({{ site.url }}/cheat_sheet/functions/#change_highlight_text)| +|`X`, `x`, `d`|[\]({{ site.url }}/cheat_sheet/functions/#delete_highlight_text)| +|`c`, `S`, `s`|[\]({{ site.url }}/cheat_sheet/functions/#change_highlight_text)| ## Insert Mode diff --git a/docs/cheat_sheet/defaults/small/index.md b/docs/cheat_sheet/defaults/small/index.md index 38315686..9b7444c4 100644 --- a/docs/cheat_sheet/defaults/small/index.md +++ b/docs/cheat_sheet/defaults/small/index.md @@ -40,7 +40,7 @@ nav: Small Mappings |`u`|[\]({{ site.url }}/cheat_sheet/functions/#maximize_current_window)| |`d`|[\]({{ site.url }}/cheat_sheet/functions/#minimize_current_window)| |``, `H`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_left)| -|``, `L`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_right)| +|`L`, ``|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_right)| |`K`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_top)| |`J`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_bottom)| |`e`|[\]({{ site.url }}/cheat_sheet/functions/#window_resizer)| @@ -51,7 +51,7 @@ nav: Small Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`cl`, `close`|[\]({{ site.url }}/cheat_sheet/functions/#close_current_window)| +|`close`, `cl`|[\]({{ site.url }}/cheat_sheet/functions/#close_current_window)| |`new`|[\]({{ site.url }}/cheat_sheet/functions/#open_new_window)| |`split`, `sp`|[\]({{ site.url }}/cheat_sheet/functions/#open_new_window_with_hsplit)| |`vsplit`, `vs`|[\]({{ site.url }}/cheat_sheet/functions/#open_new_window_with_vsplit)| @@ -60,38 +60,38 @@ nav: Small Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`switch`, `sw`|[\]({{ site.url }}/cheat_sheet/functions/#switch_window)| +|`sw`, `switch`|[\]({{ site.url }}/cheat_sheet/functions/#switch_window)| ### Window Resize |**Trigger Commands**|**Called Commands**| |:---:|:---:| |`winresizer`, `resizer`|[\]({{ site.url }}/cheat_sheet/functions/#window_resizer)| -|`max`, `on`, `only`|[\]({{ site.url }}/cheat_sheet/functions/#maximize_current_window)| -|`hide`, `hi`, `min`|[\]({{ site.url }}/cheat_sheet/functions/#minimize_current_window)| -|`lsplit`, `lsp`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_left)| -|`rsp`, `rsplit`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_right)| +|`only`, `max`, `on`|[\]({{ site.url }}/cheat_sheet/functions/#maximize_current_window)| +|`hide`, `min`, `hi`|[\]({{ site.url }}/cheat_sheet/functions/#minimize_current_window)| +|`lsp`, `lsplit`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_left)| +|`rsplit`, `rsp`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_right)| |`tsplit`, `tsp`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_top)| -|`bsp`, `bsplit`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_bottom)| +|`bsplit`, `bsp`|[\]({{ site.url }}/cheat_sheet/functions/#snap_current_window_to_bottom)| |`arrange`|[\]({{ site.url }}/cheat_sheet/functions/#arrange_windows)| |`reload`|[\]({{ site.url }}/cheat_sheet/functions/#reload_current_window)| |`rot`, `rotate`|[\]({{ site.url }}/cheat_sheet/functions/#rotate_windows)| |`rerot`, `rerotate`|[\]({{ site.url }}/cheat_sheet/functions/#rotate_windows_in_reverse)| |`exchange`|[\]({{ site.url }}/cheat_sheet/functions/#exchange_window_with_nearest)| -|`verticalresize`, `vertres`|[\]({{ site.url }}/cheat_sheet/functions/#resize_window_width)| +|`vertres`, `verticalresize`|[\]({{ site.url }}/cheat_sheet/functions/#resize_window_width)| |`verticalresize+`, `vertres+`|[\]({{ site.url }}/cheat_sheet/functions/#increase_window_width)| |`vertres-`, `verticalresize-`|[\]({{ site.url }}/cheat_sheet/functions/#decrease_window_width)| |`res`, `resize`|[\]({{ site.url }}/cheat_sheet/functions/#resize_window_height)| |`resize+`, `res+`|[\]({{ site.url }}/cheat_sheet/functions/#increase_window_height)| -|`resize-`, `res-`|[\]({{ site.url }}/cheat_sheet/functions/#decrease_window_height)| +|`res-`, `resize-`|[\]({{ site.url }}/cheat_sheet/functions/#decrease_window_height)| ### Process Launcher |**Trigger Commands**|**Called Commands**| |:---:|:---:| |`!`|[\]({{ site.url }}/cheat_sheet/functions/#start_external)| -|`e`, `edit`, `execute`|[\]({{ site.url }}/cheat_sheet/functions/#execute)| -|`shell`, `term`, `terminal`, `sh`|[\]({{ site.url }}/cheat_sheet/functions/#start_shell)| +|`execute`, `edit`, `e`|[\]({{ site.url }}/cheat_sheet/functions/#execute)| +|`term`, `shell`, `sh`, `terminal`|[\]({{ site.url }}/cheat_sheet/functions/#start_shell)|

diff --git a/docs/cheat_sheet/defaults/tiny/index.md b/docs/cheat_sheet/defaults/tiny/index.md index c96a4c6d..01cfd513 100644 --- a/docs/cheat_sheet/defaults/tiny/index.md +++ b/docs/cheat_sheet/defaults/tiny/index.md @@ -21,30 +21,30 @@ nav: Tiny Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``, `h`|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_left)| -|`l`, ``, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_right)| -|`-`, `k`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_up)| +|``, `h`, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_left)| +|`l`, ``, ``|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_right)| +|`-`, ``, `k`|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_up)| |``, `+`, `j`|[\]({{ site.url }}/cheat_sheet/functions/#move_cursor_down)| ### Mouse Clicking |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`O`, `o`|[\]({{ site.url }}/cheat_sheet/functions/#click_left)| -|`A`, `a`|[\]({{ site.url }}/cheat_sheet/functions/#click_right)| +|`o`, `O`|[\]({{ site.url }}/cheat_sheet/functions/#click_left)| +|`a`, `A`|[\]({{ site.url }}/cheat_sheet/functions/#click_right)| ### Mouse Scrolling |**Trigger Commands**|**Called Commands**| |:---:|:---:| |``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up)| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_halfpage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_up_onepage)| |``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_down_onepage)| |`zh`, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left)| -|`zl`, ``|[\]({{ site.url }}/cheat_sheet/functions/#scroll_right)| +|``, `zl`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_right)| |`zh`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_left_halfpage)| |`zl`|[\]({{ site.url }}/cheat_sheet/functions/#scroll_right_halfpage)| @@ -52,7 +52,7 @@ nav: Tiny Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|`^`, `0`, ``|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_left)| +|``, `^`, `0`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_left)| |`$`, ``|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_right)| |`gg`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_top)| |`G`|[\]({{ site.url }}/cheat_sheet/functions/#jump_cursor_to_bottom)| @@ -75,7 +75,7 @@ nav: Tiny Mappings |**Trigger Commands**|**Called Commands**| |:---:|:---:| -|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| +|``, ``|[\]({{ site.url }}/cheat_sheet/functions/#to_gui_normal)| |``|[\]({{ site.url }}/cheat_sheet/functions/#to_instant_gui_normal)| |``|[\]({{ site.url }}/cheat_sheet/functions/#to_resident)| @@ -108,7 +108,7 @@ nav: Tiny Mappings |`{mode}unmap`|[\<{mode}unmap\>]({{ site.url }}/cheat_sheet/functions/#unmap)| |`{mode}mapclear`|[\<{mode}mapclear\>]({{ site.url }}/cheat_sheet/functions/#mapclear)| |`command`, `com`|[\]({{ site.url }}/cheat_sheet/functions/#command)| -|`delcommand`, `delc`|[\]({{ site.url }}/cheat_sheet/functions/#delcommand)| +|`delc`, `delcommand`|[\]({{ site.url }}/cheat_sheet/functions/#delcommand)| |`comclear`, `comc`|[\]({{ site.url }}/cheat_sheet/functions/#comclear)| |`so`, `source`|[\]({{ site.url }}/cheat_sheet/functions/#source)| |`autocmd`|[\]({{ site.url }}/cheat_sheet/functions/#autocmd_add)| diff --git a/docs/cheat_sheet/functions/index.md b/docs/cheat_sheet/functions/index.md index a6cde93c..7f6e0850 100644 --- a/docs/cheat_sheet/functions/index.md +++ b/docs/cheat_sheet/functions/index.md @@ -1748,22 +1748,6 @@ Create a directory. If you call it with a relative path such as `:mkdir foo`, it --> -## Option - -### **``** -Disable targeting (Dedicate to One Window). - - - -
- -### **``** -Enable targeting (Dedicate to One Window). - -


diff --git a/docs/cheat_sheet/options/index.md b/docs/cheat_sheet/options/index.md index 90adf25f..391ad9bc 100644 --- a/docs/cheat_sheet/options/index.md +++ b/docs/cheat_sheet/options/index.md @@ -365,21 +365,6 @@ Mode for how to split a single Unicode character. The `grapheme` mode treats a c It is a very small cache for one character used by `x` or `X` commands. If it is enabled, the clipboard is opened per once typing. Therefore, you will get the same behavior as the original Vim, whereas the performance maybe drop a litte. -## Options - -### **`dedicate_to_window`** -**type**: bool, **default**: false -If **Dedicate to One window** enables, you can select one window with `enable_targeting_of_dedicate_to_window`. In this case, it makes the mode automatically switch to Editor Normal Mode on the targeting window. When the foreground window change to another, it makes the mode switch to Insert Mode. The targeting becomes disable with `disable_targeting_of_dedicate_to_window`. In other words, this feature transforms some normal editors to fake Vim. The computing cost is so small. - -
- -### **`suppress_for_vim`** -**type**: bool, **default**: false -It makes the mode of win-vind automatically switch to **Resident Mode** on the applications included the strings called **VIM** in an executable file name. Thus, it allows us to smoothly move from win-vind having the same key-bindings as Vim to Vim applications. - - - -


diff --git a/res/resources/defaults/huge.vindrc b/res/resources/defaults/huge.vindrc index 86e259e0..664731e0 100644 --- a/res/resources/defaults/huge.vindrc +++ b/res/resources/defaults/huge.vindrc @@ -10,7 +10,3 @@ source big.vindrc " @ command mkdir command md - -" @ -command target -command untarget diff --git a/src/bind/bindinglist.cpp b/src/bind/bindinglist.cpp index 23b052a5..5e771167 100644 --- a/src/bind/bindinglist.cpp +++ b/src/bind/bindinglist.cpp @@ -2,7 +2,6 @@ #include "bindedfunc.hpp" -#include "ctrl/d2wctrl.hpp" #include "ctrl/guictrl.hpp" #include "emu/changetext.hpp" @@ -101,11 +100,8 @@ namespace vind DeleteLineUntilEOL::create(), DeleteLineUntilEOL::create(), DeleteWithMotion::create(), - DisableTargetingOfDedicate2Window::create(), - DisableTargetingOfDedicate2Window::create(), EasyClick::create(), GridMove::create(), - EnableTargetingOfDedicate2Window::create(), ExchangeWindowWithNearest::create(), Execute::create(), ExitConfigGUI::create(), diff --git a/src/bind/ctrl/d2wctrl.cpp b/src/bind/ctrl/d2wctrl.cpp deleted file mode 100644 index 2870af45..00000000 --- a/src/bind/ctrl/d2wctrl.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "d2wctrl.hpp" - -#include "opt/dedicate_to_window.hpp" -#include "util/debug.hpp" -#include "util/def.hpp" - - -namespace vind -{ - namespace bind - { - EnableTargetingOfDedicate2Window::EnableTargetingOfDedicate2Window() - : BindedFuncVoid("enable_targeting_of_dedicate_to_window") - {} - void EnableTargetingOfDedicate2Window::sprocess( - std::uint16_t UNUSED(count), - const std::string& UNUSED(args)) { - opt::Dedicate2Window::enable_targeting() ; - } - - DisableTargetingOfDedicate2Window::DisableTargetingOfDedicate2Window() - : BindedFuncVoid("disable_targeting_of_dedicate_to_window") - {} - void DisableTargetingOfDedicate2Window::sprocess( - std::uint16_t UNUSED(count), - const std::string& UNUSED(args)) { - opt::Dedicate2Window::disable_targeting() ; - } - } -} diff --git a/src/bind/ctrl/d2wctrl.hpp b/src/bind/ctrl/d2wctrl.hpp deleted file mode 100644 index f71e1946..00000000 --- a/src/bind/ctrl/d2wctrl.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _DEDICATE_TO_WINDOW_CTRL_HPP -#define _DEDICATE_TO_WINDOW_CTRL_HPP - -#include "bind/bindedfunc.hpp" - -namespace vind -{ - namespace bind - { - struct EnableTargetingOfDedicate2Window : public BindedFuncVoid { - explicit EnableTargetingOfDedicate2Window() ; - static void sprocess( - std::uint16_t count, const std::string& args) ; - } ; - - struct DisableTargetingOfDedicate2Window : public BindedFuncVoid { - explicit DisableTargetingOfDedicate2Window() ; - static void sprocess( - std::uint16_t count, const std::string& args) ; - } ; - } -} - -#endif diff --git a/src/bind/mode/instant_mode.cpp b/src/bind/mode/instant_mode.cpp index a80f83e3..21ad6c90 100644 --- a/src/bind/mode/instant_mode.cpp +++ b/src/bind/mode/instant_mode.cpp @@ -8,9 +8,7 @@ #include "core/inputhub.hpp" #include "core/mode.hpp" #include "opt/blockstylecaret.hpp" -#include "opt/dedicate_to_window.hpp" #include "opt/optionlist.hpp" -#include "opt/suppress_for_vim.hpp" #include "opt/uiacachebuild.hpp" #include "opt/vcmdline.hpp" #include "util/debug.hpp" @@ -29,8 +27,6 @@ namespace vind : bg_(opt::ref_global_options_bynames( opt::AsyncUIACacheBuilder().name(), opt::BlockStyleCaret().name(), - opt::Dedicate2Window().name(), - opt::SuppressForVim().name(), opt::VCmdLine().name() )) {} diff --git a/src/bind/mouse/jump_keybrd.cpp b/src/bind/mouse/jump_keybrd.cpp index 61a3cc5d..a4f7b317 100644 --- a/src/bind/mouse/jump_keybrd.cpp +++ b/src/bind/mouse/jump_keybrd.cpp @@ -18,9 +18,7 @@ #include "core/keylayout.hpp" #include "core/path.hpp" #include "core/settable.hpp" -#include "opt/dedicate_to_window.hpp" #include "opt/optionlist.hpp" -#include "opt/suppress_for_vim.hpp" #include "opt/uiacachebuild.hpp" #include "opt/vcmdline.hpp" #include "util/debug.hpp" @@ -46,8 +44,6 @@ namespace vind yposs_(), bg_(opt::ref_global_options_bynames( opt::AsyncUIACacheBuilder().name(), - opt::Dedicate2Window().name(), - opt::SuppressForVim().name(), opt::VCmdLine().name() )) {} diff --git a/src/bind/window/switch_win.cpp b/src/bind/window/switch_win.cpp index afddb293..358966e1 100644 --- a/src/bind/window/switch_win.cpp +++ b/src/bind/window/switch_win.cpp @@ -10,9 +10,7 @@ #include "core/inputgate.hpp" #include "core/inputhub.hpp" #include "core/mode.hpp" -#include "opt/dedicate_to_window.hpp" #include "opt/optionlist.hpp" -#include "opt/suppress_for_vim.hpp" #include "opt/uiacachebuild.hpp" #include "opt/vcmdline.hpp" #include "util/def.hpp" @@ -28,8 +26,6 @@ namespace vind explicit Impl() : bg_(opt::ref_global_options_bynames( opt::AsyncUIACacheBuilder().name(), - opt::Dedicate2Window().name(), - opt::SuppressForVim().name(), opt::VCmdLine().name() )) {} diff --git a/src/bind/window/winresizer.cpp b/src/bind/window/winresizer.cpp index 012055cb..356d2cfe 100644 --- a/src/bind/window/winresizer.cpp +++ b/src/bind/window/winresizer.cpp @@ -16,9 +16,7 @@ #include "core/keycodedef.hpp" #include "core/mapsolver.hpp" #include "core/settable.hpp" -#include "opt/dedicate_to_window.hpp" #include "opt/optionlist.hpp" -#include "opt/suppress_for_vim.hpp" #include "opt/uiacachebuild.hpp" #include "opt/vcmdline.hpp" #include "util/def.hpp" @@ -63,8 +61,6 @@ namespace vind down_id_(MoveCursorDown().id()), bg_(opt::ref_global_options_bynames( opt::AsyncUIACacheBuilder().name(), - opt::Dedicate2Window().name(), - opt::SuppressForVim().name(), opt::VCmdLine().name() )) {} diff --git a/src/opt/dedicate_to_window.cpp b/src/opt/dedicate_to_window.cpp deleted file mode 100644 index cbfc60f5..00000000 --- a/src/opt/dedicate_to_window.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "opt/dedicate_to_window.hpp" - -#include - -#include "bind/emu/moveinsert.hpp" -#include "bind/mode/change_mode.hpp" -#include "core/errlogger.hpp" -#include "core/inputgate.hpp" -#include "core/keycodedef.hpp" -#include "core/settable.hpp" -#include "opt/vcmdline.hpp" -#include "util/mouse.hpp" -#include "util/winwrap.hpp" - - -namespace vind -{ - namespace opt - { - HWND Dedicate2Window::target_hwnd_ = NULL ; - HWND Dedicate2Window::past_hwnd_ = NULL ; - - Dedicate2Window::Dedicate2Window() - : OptionCreator("dedicate_to_window") - {} - - void Dedicate2Window::do_enable() { - } - - void Dedicate2Window::do_disable() { - } - - void Dedicate2Window::enable_targeting() { - auto& settable = core::SetTable::get_instance() ; - if(settable.get("dedicate_to_window").get()) { - target_hwnd_ = util::get_foreground_window() ; - past_hwnd_ = NULL ; - opt::VCmdLine::print(GeneralMessage("-- TARGET ON --")) ; - } - } - - void Dedicate2Window::disable_targeting() { - auto& settable = core::SetTable::get_instance() ; - if(settable.get("dedicate_to_window").get()) { - target_hwnd_ = NULL ; - past_hwnd_ = NULL ; - opt::VCmdLine::print(GeneralMessage("-- TARGET OFF --")) ; - } - } - - void Dedicate2Window::do_process() { - if(!target_hwnd_) return ; - - auto foreground_hwnd = util::get_foreground_window() ; - - //is selected window changed? - if(past_hwnd_ == foreground_hwnd) { - return ; - } - - if(target_hwnd_ == foreground_hwnd) { //other -> target - bind::ToEdiNormal::sprocess(1, "", true) ; - } - else if(past_hwnd_ == target_hwnd_) { //target -> other - bind::ToInsert::sprocess(1, "", true) ; - } - past_hwnd_ = foreground_hwnd ; - } - } -} diff --git a/src/opt/dedicate_to_window.hpp b/src/opt/dedicate_to_window.hpp deleted file mode 100644 index 47b92ff5..00000000 --- a/src/opt/dedicate_to_window.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _DEDICATE_TO_WINDOW_HPP -#define _DEDICATE_TO_WINDOW_HPP - -#include "option.hpp" - -#include - - -namespace vind -{ - namespace opt - { - class Dedicate2Window : public OptionCreator { - private: - void do_enable() override ; - void do_disable() override ; - void do_process() override ; - - static HWND target_hwnd_ ; - static HWND past_hwnd_ ; - - public: - explicit Dedicate2Window() ; - static void enable_targeting() ; - static void disable_targeting() ; - } ; - } -} -#endif diff --git a/src/opt/optionlist.cpp b/src/opt/optionlist.cpp index 65fdf8c9..7698f2ed 100644 --- a/src/opt/optionlist.cpp +++ b/src/opt/optionlist.cpp @@ -2,8 +2,6 @@ #include "opt/autotrack_popup.hpp" #include "opt/blockstylecaret.hpp" -#include "opt/dedicate_to_window.hpp" -#include "opt/suppress_for_vim.hpp" #include "opt/uiacachebuild.hpp" #include "opt/vcmdline.hpp" #include "util/def.hpp" @@ -19,8 +17,6 @@ namespace vind AsyncUIACacheBuilder::create(), AutotrackPopup::create(), BlockStyleCaret::create(), - Dedicate2Window::create(), - SuppressForVim::create(), VCmdLine::create(), } ; diff --git a/src/opt/suppress_for_vim.cpp b/src/opt/suppress_for_vim.cpp deleted file mode 100644 index 92a5ff07..00000000 --- a/src/opt/suppress_for_vim.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "opt/suppress_for_vim.hpp" - -#include - -#include - -#include "bind/mode/change_mode.hpp" -#include "core/errlogger.hpp" -#include "core/inputgate.hpp" -#include "core/mode.hpp" -#include "opt/vcmdline.hpp" -#include "util/string.hpp" -#include "util/winwrap.hpp" - - -namespace vind -{ - namespace opt - { - SuppressForVim::SuppressForVim() - : OptionCreator("suppress_for_vim") - {} - - void SuppressForVim::do_enable() { - } - - void SuppressForVim::do_disable() { - } - - void SuppressForVim::do_process() { - if(core::get_global_mode() == core::Mode::RESIDENT) { - return ; - } - - static HWND pre_hwnd = NULL ; - - auto hwnd = util::get_foreground_window() ; - if(pre_hwnd == hwnd) { - return ; - } - - pre_hwnd = hwnd ; - - auto exename = util::A2a(util::get_module_filename(hwnd)) ; - - if(exename == "win-vind.exe") return ; - - //Whether it is vim - if(exename.find("vim") != std::string::npos) { - auto& igate = core::InputGate::get_instance() ; - igate.close_all_ports() ; - igate.unabsorb() ; - core::set_global_mode(core::Mode::RESIDENT) ; - opt::VCmdLine::print(GeneralMessage("-- RESIDENT --")) ; - } - else { - if(core::get_global_mode() == core::Mode::RESIDENT) - bind::ToInsert::sprocess(1, "", true) ; - } - } - } -} diff --git a/src/opt/suppress_for_vim.hpp b/src/opt/suppress_for_vim.hpp deleted file mode 100644 index afd9ac6b..00000000 --- a/src/opt/suppress_for_vim.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _SUPPRESS_FOR_VIM_HPP -#define _SUPPRESS_FOR_VIM_HPP - -#include "option.hpp" - -namespace vind -{ - namespace opt - { - class SuppressForVim : public OptionCreator { - private: - void do_enable() override ; - void do_disable() override ; - void do_process() override ; - - public: - explicit SuppressForVim() ; - } ; - } -} - -#endif From b113787d6654658a3cf4382b8ad3785aa4f89c0e Mon Sep 17 00:00:00 2001 From: pit-ray Date: Sat, 12 Aug 2023 00:11:15 +0900 Subject: [PATCH 21/22] add usage of autocmd --- docs/usage/index.md | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/usage/index.md b/docs/usage/index.md index 8be947bc..369dddb0 100644 --- a/docs/usage/index.md +++ b/docs/usage/index.md @@ -194,6 +194,28 @@ Below are some examples of use. enmap t yyGp ``` +## Automatic command +win-vind can be configured to automatically execute commands for specific events and target filenames using the `autocmd` command. + +### Examples + +1. Default mapping for the specific event (match any applications) + ```vim + autocmd AppLeave * + ``` +1. Once notepad is selected, it will automatically switch to Editor normal mode. + ```vim + "Equivalent to conventional dedicate_to_window + autocmd AppEnter *notepad* + ``` +1. Suppress win-vind in processes named Vim. + ```vim + " Equivalent to conventional suppress_for_vim + autocmd AppEnter,EdiNormalEnter *vim* + ``` + +See [\]({{ site.url }}/cheat_sheet/functions/#autocmd_add) or [\]({{ site.url }}/cheat_sheet/functions/#autocmd_del) for more details. + ## Load remote .vindrc Inspired from many Vim plugin managers such as [vim-plug](https://github.com/junegunn/vim-plug), win-vind has a simple remote .vindrc loading capability using the `source` command. @@ -215,10 +237,10 @@ The `--command` option allows us to execute an arbitrary command from a terminal The first time you run win-vind, it will be resident in the system tray and run as a server program. The server will check shared memory at the interval specified by the `listen_interval` option and execute any requested commands in addition to the query. All new win-vinds that already have win-vind running will become clients. -For example, if you execute the following command with win-vind already running, a window-switching program will be started and the two left window will be selected. +For example, if you execute the following command with win-vind already running, a window-switching program will be started. ```sh -$ win-vind -c "hh" +$ win-vind -c "" ``` By using this, only specific functions such as EasyClick can be called from other tools such as AutoHotKey. From d215fe99e09930c6ba469d1716e7f403f1648d31 Mon Sep 17 00:00:00 2001 From: pit-ray Date: Sat, 12 Aug 2023 00:15:59 +0900 Subject: [PATCH 22/22] fix defects of coverity --- src/core/autocmd.cpp | 2 +- src/core/autocmd.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/autocmd.cpp b/src/core/autocmd.cpp index db32b1ca..2e8309ad 100644 --- a/src/core/autocmd.cpp +++ b/src/core/autocmd.cpp @@ -145,7 +145,7 @@ namespace vind { namespace core { - AutoCmdEvent get_autocmd_event(const std::string& event_name) noexcept { + AutoCmdEvent get_autocmd_event(const std::string& event_name) { static std::unordered_map names { {"appenter", AutoCmdEvent::APP_ENTER}, {"appleave", AutoCmdEvent::APP_LEAVE}, diff --git a/src/core/autocmd.hpp b/src/core/autocmd.hpp index 8646a33f..c0b0b9f5 100644 --- a/src/core/autocmd.hpp +++ b/src/core/autocmd.hpp @@ -36,7 +36,7 @@ namespace vind UNDEFINED, } ; - AutoCmdEvent get_autocmd_event(const std::string& event_name) noexcept ; + AutoCmdEvent get_autocmd_event(const std::string& event_name) ; inline AutoCmdEvent get_enter_event(Mode mode) { static const std::unordered_map enter_events {