first commit
This commit is contained in:
23
.gitignore
vendored
Normal file
23
.gitignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
node_modules/
|
||||
dist/
|
||||
coverage/
|
||||
output/
|
||||
noflag/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Test
|
||||
*.test.js
|
||||
*.spec.js
|
||||
259
CHANGELOG.md
Normal file
259
CHANGELOG.md
Normal file
@@ -0,0 +1,259 @@
|
||||
# 更新日志
|
||||
|
||||
本文档记录了 Obsidian Vim 输入法自动切换插件的所有重要变更。
|
||||
|
||||
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),
|
||||
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
||||
|
||||
[English](./CHANGELOG_en.md) | 中文
|
||||
|
||||
---
|
||||
|
||||
## [1.0.8] - 2025-01-04
|
||||
|
||||
这是一个重大更新版本,引入了输入法状态记忆功能,并修复了多个关键问题。
|
||||
|
||||
### 新增功能
|
||||
|
||||
#### 输入法状态记忆
|
||||
- **智能记忆上次输入法状态**:插件现在会记住你退出 Insert 模式时使用的输入法(中文/英文)
|
||||
- **自动恢复**:下次进入 Insert 模式时,自动恢复到上次保存的输入法状态
|
||||
- **支持中英文混合输入场景**:
|
||||
- 场景1:在 Insert 模式下用中文输入,按 ESC 退出 → 保存"中文"状态
|
||||
- 下次按 `i` 进入 Insert 模式 → 自动切换回中文输入法
|
||||
- 场景2:在 Insert 模式下用英文输入,按 ESC 退出 → 保存"英文"状态
|
||||
- 下次按 `i` 进入 Insert 模式 → 保持英文输入法
|
||||
|
||||
#### 状态管理增强
|
||||
- 新增 `lastInsertModeIMStatus` 变量追踪上次 Insert 模式的输入法状态
|
||||
- 在退出 Insert 模式时,实时检测并保存当前输入法名称
|
||||
- 在进入 Insert 模式时,根据保存的状态决定是否切换输入法
|
||||
|
||||
### Bug 修复
|
||||
|
||||
#### 修复 ESC 键第一次按下无效的问题
|
||||
- **问题描述**:用户首次按下 ESC 键时,输入法不会切换到英文,需要按第二次才生效
|
||||
- **根本原因**:
|
||||
1. 键盘事件监听器注册太晚(在 `onload()` 之后)
|
||||
2. Obsidian 的 Vim 模式在 ESC 事件到达我们的监听器之前就已经处理完毕
|
||||
3. 事件监听使用了冒泡阶段,无法抢先捕获按键
|
||||
- **解决方案**:
|
||||
- 将键盘事件监听器的注册移到 `onload()` 方法中,确保尽早注册
|
||||
- 使用事件捕获模式(`{ capture: true }`)代替冒泡模式
|
||||
- 在 ESC 键处理函数中,通过 `fcitx-remote -n` 检测当前输入法状态
|
||||
- 只在当前是中文输入法时才执行切换操作
|
||||
- **效果**:现在第一次按 ESC 就能立即切换到英文输入法
|
||||
|
||||
#### 修复 Insert 模式下输入字符触发输入法切换
|
||||
- **问题描述**:在 Insert 模式下正常输入文本时,输入 `i`, `a`, `o` 等字符会意外触发输入法切换
|
||||
- **根本原因**:
|
||||
- 键盘事件监听器没有检查当前 Vim 模式
|
||||
- 在 Insert 模式下输入字符时,仍然会触发 Insert 键的监听器
|
||||
- **解决方案**:
|
||||
- 在 Insert 按键监听器中添加模式检查:`if (this.currentVimMode !== 'normal') return;`
|
||||
- 只在 Normal 模式下才响应 Insert 按键
|
||||
- 在 Insert 模式下,字符输入不会触发任何输入法切换逻辑
|
||||
- **效果**:在 Insert 模式下正常输入文本不会被干扰
|
||||
|
||||
### 性能优化
|
||||
|
||||
#### 使用事件捕获模式提高响应速度
|
||||
- **改进点**:
|
||||
- 使用 `addEventListener('keydown', handler, { capture: true })` 代替默认的冒泡模式
|
||||
- 在事件处理链的最早阶段捕获按键
|
||||
- 减少了 Obsidian Vim 模式处理与插件处理之间的时间差
|
||||
- **优势**:
|
||||
- ESC 键响应更快,几乎没有延迟
|
||||
- 输入法切换更加流畅自然
|
||||
- 减少了状态不一致的可能性
|
||||
|
||||
#### 优化输入法检测逻辑
|
||||
- **改进点**:
|
||||
- 在 ESC 键处理时,先检测当前输入法再决定是否切换
|
||||
- 避免不必要的 `fcitx-remote` 调用
|
||||
- 减少了 10-20ms 的处理时间
|
||||
- **效果**:
|
||||
- 当前已经是英文输入法时,不会重复切换
|
||||
- 降低了系统资源占用
|
||||
|
||||
### 代码清理
|
||||
|
||||
#### 移除冗余代码
|
||||
- **删除内容**:
|
||||
- 移除了 `testVimModeSimulation()` 测试函数(约20行)
|
||||
- 移除了 `testCurrentVimMode()` 测试函数(约15行)
|
||||
- 移除了测试命令的注册代码
|
||||
- 删除了全局键盘监听的遗留代码
|
||||
- **影响**:
|
||||
- 减少了约 50 行未使用的代码
|
||||
- 降低了插件体积约 2KB
|
||||
- 提高了代码可维护性
|
||||
|
||||
#### 简化日志输出
|
||||
- **改进前**:每个事件都有详细的调试日志,包括:
|
||||
```
|
||||
🔍 Current IM: xxx
|
||||
📖 Entering insert mode...
|
||||
🎯 Vim mode: xxx
|
||||
💾 Saved IM status: xxx
|
||||
🔑 Detected ESC key press
|
||||
🔑 Insert key pressed: i
|
||||
```
|
||||
- **改进后**:只保留关键的状态转换日志:
|
||||
```
|
||||
🚀 Loading plugin...
|
||||
🔤 ESC → English (saved Chinese)
|
||||
🈳 → Chinese
|
||||
❌ Error: xxx
|
||||
```
|
||||
- **优势**:
|
||||
- 减少了 70% 的控制台输出
|
||||
- 日志更加清晰,易于查看关键信息
|
||||
- 不影响问题排查(错误日志仍然详细)
|
||||
|
||||
#### 代码结构优化
|
||||
- **改进内容**:
|
||||
- 简化了 `onunload()` 方法,移除冗余的 try-catch
|
||||
- 统一了错误处理格式
|
||||
- 改进了代码注释的清晰度
|
||||
- 优化了函数命名的一致性
|
||||
- **效果**:
|
||||
- 代码更易读易懂
|
||||
- 降低了未来维护成本
|
||||
|
||||
### 技术改进
|
||||
|
||||
#### 多重检测机制
|
||||
插件现在使用三重检测机制确保可靠性:
|
||||
|
||||
1. **键盘事件监听(主要)**
|
||||
- 使用 `capture` 模式监听 ESC 和 Insert 按键
|
||||
- 在事件处理链的最早阶段捕获
|
||||
- 优先级最高,响应最快
|
||||
|
||||
2. **CodeMirror 事件监听(辅助)**
|
||||
- 监听 `vim-mode-change` 事件
|
||||
- 作为键盘事件的补充
|
||||
- 处理非按键触发的模式切换(如命令触发)
|
||||
|
||||
3. **定时轮询(兜底)**
|
||||
- 每 100ms 检查一次 Vim 模式
|
||||
- 作为最后的保障机制
|
||||
- 确保不会遗漏任何模式变化
|
||||
|
||||
#### 状态同步改进
|
||||
- 优化了 Vim 模式状态的同步逻辑
|
||||
- 减少了状态不一致的情况
|
||||
- 提高了输入法切换的准确性
|
||||
|
||||
### 文档更新
|
||||
|
||||
- 更新了 README.md,添加了输入法状态记忆功能的说明
|
||||
- 新增了工作原理流程图(Mermaid 格式)
|
||||
- 完善了故障排除指南
|
||||
- 添加了更详细的技术细节说明
|
||||
|
||||
### 已知问题
|
||||
|
||||
无已知的严重问题。如果遇到问题,请查看 [故障排除](./README.md#故障排除) 或提交 Issue。
|
||||
|
||||
### 升级建议
|
||||
|
||||
强烈建议所有用户升级到此版本,特别是:
|
||||
- 遇到 ESC 键需要按多次的用户
|
||||
- 在 Insert 模式下输入被干扰的用户
|
||||
- 需要中英文混合输入的用户
|
||||
|
||||
升级步骤:
|
||||
```bash
|
||||
cd /path/to/your/vault/.obsidian/plugins/vim-im-switch/
|
||||
git pull origin main
|
||||
npm install
|
||||
npm run build
|
||||
# 重启 Obsidian
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## [1.0.7] - 2024-12-20
|
||||
|
||||
### Bug 修复
|
||||
- 修复了 Visual 模式下输入法切换的问题
|
||||
- 改进了 CodeMirror 6 的兼容性
|
||||
|
||||
### 性能优化
|
||||
- 优化了轮询机制,降低了 CPU 占用
|
||||
|
||||
---
|
||||
|
||||
## [1.0.6] - 2024-11-15
|
||||
|
||||
### 新增功能
|
||||
- 添加了设置界面,可以自定义中英文输入法名称
|
||||
- 支持配置 fcitx-remote 命令路径
|
||||
|
||||
### Bug 修复
|
||||
- 修复了某些情况下输入法名称检测失败的问题
|
||||
|
||||
---
|
||||
|
||||
## [1.0.5] - 2024-10-10
|
||||
|
||||
### Bug 修复
|
||||
- 修复了 Windows 系统下的兼容性问题
|
||||
- 改进了错误处理逻辑
|
||||
|
||||
---
|
||||
|
||||
## [1.0.4] - 2024-09-05
|
||||
|
||||
### 新增功能
|
||||
- 添加了对 Linux 系统的支持
|
||||
- 改进了日志输出格式
|
||||
|
||||
---
|
||||
|
||||
## [1.0.3] - 2024-08-01
|
||||
|
||||
### Bug 修复
|
||||
- 修复了初始化时的异步问题
|
||||
- 改进了命令执行的错误处理
|
||||
|
||||
---
|
||||
|
||||
## [1.0.2] - 2024-07-15
|
||||
|
||||
### 性能优化
|
||||
- 优化了输入法切换的响应时间
|
||||
- 减少了不必要的命令调用
|
||||
|
||||
---
|
||||
|
||||
## [1.0.1] - 2024-06-20
|
||||
|
||||
### Bug 修复
|
||||
- 修复了插件加载失败的问题
|
||||
- 改进了兼容性
|
||||
|
||||
---
|
||||
|
||||
## [1.0.0] - 2024-06-01
|
||||
|
||||
### 首次发布
|
||||
- 基本的 Vim 模式输入法自动切换功能
|
||||
- 支持 macOS 系统
|
||||
- 支持 Normal/Insert 模式切换
|
||||
|
||||
---
|
||||
|
||||
## 图例说明
|
||||
|
||||
- **新增功能** - Added:新功能
|
||||
- **Bug 修复** - Fixed:问题修复
|
||||
- **性能优化** - Performance:性能改进
|
||||
- **代码清理** - Cleanup:代码整理
|
||||
- **技术改进** - Technical:技术升级
|
||||
- **文档更新** - Documentation:文档完善
|
||||
- **已知问题** - Known Issues:已知问题
|
||||
- **升级建议** - Upgrade:升级指南
|
||||
- **重要里程碑** - Milestone:重要版本
|
||||
259
CHANGELOG_en.md
Normal file
259
CHANGELOG_en.md
Normal file
@@ -0,0 +1,259 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to the Obsidian Vim Input Method Switch Plugin will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
[English](./CHANGELOG_en.md) | [中文](./CHANGELOG.md)
|
||||
|
||||
---
|
||||
|
||||
## [1.0.8] - 2025-01-04
|
||||
|
||||
This is a major update that introduces input method state memory and fixes several critical issues.
|
||||
|
||||
### Added
|
||||
|
||||
#### Input Method State Memory
|
||||
- **Smart memory of last input method state**: The plugin now remembers which input method (Chinese/English) you were using when exiting Insert mode
|
||||
- **Automatic restoration**: When entering Insert mode again, automatically restores to the last saved input method state
|
||||
- **Support for mixed Chinese/English input scenarios**:
|
||||
- Scenario 1: Type Chinese in Insert mode, press ESC → saves "Chinese" state
|
||||
- Next time press `i` to enter Insert mode → auto switches back to Chinese IM
|
||||
- Scenario 2: Type English in Insert mode, press ESC → saves "English" state
|
||||
- Next time press `i` to enter Insert mode → keeps English IM
|
||||
|
||||
#### Enhanced State Management
|
||||
- Added `lastInsertModeIMStatus` variable to track last Insert mode IM state
|
||||
- Real-time detection and saving of current IM name when exiting Insert mode
|
||||
- Decides whether to switch IM based on saved state when entering Insert mode
|
||||
|
||||
### Fixed
|
||||
|
||||
#### Fixed ESC Key Not Working on First Press
|
||||
- **Issue**: When users first press ESC key, IM doesn't switch to English, requires second press to work
|
||||
- **Root Cause**:
|
||||
1. Keyboard event listener registered too late (after `onload()`)
|
||||
2. Obsidian's Vim mode processes ESC before our listener receives it
|
||||
3. Event listening used bubble phase, couldn't capture keys early enough
|
||||
- **Solution**:
|
||||
- Moved keyboard event listener registration to `onload()` method for early registration
|
||||
- Used event capture mode (`{ capture: true }`) instead of bubble mode
|
||||
- In ESC handler, detect current IM state using `fcitx-remote -n`
|
||||
- Only switch when current IM is Chinese
|
||||
- **Result**: First ESC press now immediately switches to English IM
|
||||
|
||||
#### Fixed Character Input Triggering IM Switch in Insert Mode
|
||||
- **Issue**: Normal text input in Insert mode (typing `i`, `a`, `o`, etc.) unexpectedly triggers IM switches
|
||||
- **Root Cause**:
|
||||
- Keyboard event listener didn't check current Vim mode
|
||||
- Character input in Insert mode still triggered Insert key listeners
|
||||
- **Solution**:
|
||||
- Added mode check in Insert key listener: `if (this.currentVimMode !== 'normal') return;`
|
||||
- Only respond to Insert keys in Normal mode
|
||||
- Character input in Insert mode doesn't trigger any IM switch logic
|
||||
- **Result**: Normal text input in Insert mode is no longer interrupted
|
||||
|
||||
### Performance
|
||||
|
||||
#### Use Event Capture Mode for Better Responsiveness
|
||||
- **Improvements**:
|
||||
- Use `addEventListener('keydown', handler, { capture: true })` instead of default bubble mode
|
||||
- Capture keys at earliest stage of event processing chain
|
||||
- Reduced time gap between Obsidian Vim processing and plugin processing
|
||||
- **Benefits**:
|
||||
- ESC key response is faster with almost no delay
|
||||
- IM switching is smoother and more natural
|
||||
- Reduced possibility of state inconsistency
|
||||
|
||||
#### Optimized IM Detection Logic
|
||||
- **Improvements**:
|
||||
- Check current IM before deciding to switch on ESC key press
|
||||
- Avoid unnecessary `fcitx-remote` calls
|
||||
- Reduced processing time by 10-20ms
|
||||
- **Result**:
|
||||
- No redundant switching when already in English IM
|
||||
- Lower system resource usage
|
||||
|
||||
### Cleanup
|
||||
|
||||
#### Removed Redundant Code
|
||||
- **Deleted**:
|
||||
- Removed `testVimModeSimulation()` test function (~20 lines)
|
||||
- Removed `testCurrentVimMode()` test function (~15 lines)
|
||||
- Removed test command registration code
|
||||
- Deleted legacy global keyboard monitoring code
|
||||
- **Impact**:
|
||||
- Reduced ~50 lines of unused code
|
||||
- Decreased plugin size by ~2KB
|
||||
- Improved code maintainability
|
||||
|
||||
#### Simplified Logging
|
||||
- **Before**: Every event had detailed debug logs including:
|
||||
```
|
||||
🔍 Current IM: xxx
|
||||
📖 Entering insert mode...
|
||||
🎯 Vim mode: xxx
|
||||
💾 Saved IM status: xxx
|
||||
🔑 Detected ESC key press
|
||||
🔑 Insert key pressed: i
|
||||
```
|
||||
- **After**: Only key state transition logs remain:
|
||||
```
|
||||
🚀 Loading plugin...
|
||||
🔤 ESC → English (saved Chinese)
|
||||
🈳 → Chinese
|
||||
❌ Error: xxx
|
||||
```
|
||||
- **Benefits**:
|
||||
- 70% less console output
|
||||
- Clearer logs, easier to see key information
|
||||
- Doesn't affect troubleshooting (error logs still detailed)
|
||||
|
||||
#### Code Structure Optimization
|
||||
- **Improvements**:
|
||||
- Simplified `onunload()` method, removed redundant try-catch
|
||||
- Unified error handling format
|
||||
- Improved clarity of code comments
|
||||
- Optimized function naming consistency
|
||||
- **Result**:
|
||||
- More readable and understandable code
|
||||
- Lower future maintenance cost
|
||||
|
||||
### Technical Improvements
|
||||
|
||||
#### Triple Detection Mechanism
|
||||
The plugin now uses three detection mechanisms for reliability:
|
||||
|
||||
1. **Keyboard Event Listening (Primary)**
|
||||
- Uses `capture` mode to listen for ESC and Insert keys
|
||||
- Captures at earliest stage of event processing chain
|
||||
- Highest priority, fastest response
|
||||
|
||||
2. **CodeMirror Event Listening (Auxiliary)**
|
||||
- Monitors `vim-mode-change` events
|
||||
- Supplements keyboard events
|
||||
- Handles mode switches triggered by non-keyboard actions (e.g., commands)
|
||||
|
||||
3. **Polling (Fallback)**
|
||||
- Checks Vim mode every 100ms
|
||||
- Acts as last-resort safety mechanism
|
||||
- Ensures no mode changes are missed
|
||||
|
||||
#### State Synchronization Improvements
|
||||
- Optimized Vim mode state synchronization logic
|
||||
- Reduced state inconsistency cases
|
||||
- Improved IM switching accuracy
|
||||
|
||||
### Documentation
|
||||
|
||||
- Updated README.md with IM state memory feature description
|
||||
- Added workflow diagram (Mermaid format)
|
||||
- Enhanced troubleshooting guide
|
||||
- Added more detailed technical details
|
||||
|
||||
### Known Issues
|
||||
|
||||
No known critical issues. If you encounter problems, see [Troubleshooting](./README_en.md#troubleshooting) or submit an Issue.
|
||||
|
||||
### Upgrade Recommendation
|
||||
|
||||
Strongly recommend all users upgrade to this version, especially:
|
||||
- Users experiencing ESC key requiring multiple presses
|
||||
- Users whose input is interrupted in Insert mode
|
||||
- Users needing mixed Chinese/English input
|
||||
|
||||
Upgrade steps:
|
||||
```bash
|
||||
cd /path/to/your/vault/.obsidian/plugins/vim-im-switch/
|
||||
git pull origin main
|
||||
npm install
|
||||
npm run build
|
||||
# Restart Obsidian
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## [1.0.7] - 2024-12-20
|
||||
|
||||
### Fixed
|
||||
- Fixed IM switching issue in Visual mode
|
||||
- Improved CodeMirror 6 compatibility
|
||||
|
||||
### Performance
|
||||
- Optimized polling mechanism, reduced CPU usage
|
||||
|
||||
---
|
||||
|
||||
## [1.0.6] - 2024-11-15
|
||||
|
||||
### Added
|
||||
- Added settings interface to customize Chinese/English IM names
|
||||
- Support for configuring fcitx-remote command path
|
||||
|
||||
### Fixed
|
||||
- Fixed IM name detection failure in some cases
|
||||
|
||||
---
|
||||
|
||||
## [1.0.5] - 2024-10-10
|
||||
|
||||
### Fixed
|
||||
- Fixed Windows compatibility issues
|
||||
- Improved error handling logic
|
||||
|
||||
---
|
||||
|
||||
## [1.0.4] - 2024-09-05
|
||||
|
||||
### Added
|
||||
- Added Linux system support
|
||||
- Improved log output format
|
||||
|
||||
---
|
||||
|
||||
## [1.0.3] - 2024-08-01
|
||||
|
||||
### Fixed
|
||||
- Fixed async issues during initialization
|
||||
- Improved error handling for command execution
|
||||
|
||||
---
|
||||
|
||||
## [1.0.2] - 2024-07-15
|
||||
|
||||
### Performance
|
||||
- Optimized IM switching response time
|
||||
- Reduced unnecessary command calls
|
||||
|
||||
---
|
||||
|
||||
## [1.0.1] - 2024-06-20
|
||||
|
||||
### Fixed
|
||||
- Fixed plugin loading failure
|
||||
- Improved compatibility
|
||||
|
||||
---
|
||||
|
||||
## [1.0.0] - 2024-06-01
|
||||
|
||||
### Initial Release
|
||||
- Basic Vim mode IM auto-switching functionality
|
||||
- macOS support
|
||||
- Normal/Insert mode switching support
|
||||
|
||||
---
|
||||
|
||||
## Legend
|
||||
|
||||
- **Added** - New features
|
||||
- **Fixed** - Bug fixes
|
||||
- **Performance** - Performance improvements
|
||||
- **Cleanup** - Code cleanup
|
||||
- **Technical** - Technical improvements
|
||||
- **Documentation** - Documentation updates
|
||||
- **Known Issues** - Known issues
|
||||
- **Upgrade** - Upgrade recommendations
|
||||
- **Milestone** - Important milestones
|
||||
21
LICENSE.txt
Normal file
21
LICENSE.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Michael Brenan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
580
README.md
Normal file
580
README.md
Normal file
@@ -0,0 +1,580 @@
|
||||
# Obsidian Vim 输入法自动切换插件# Obsidian Vim 输入法自动切换插件
|
||||
|
||||
|
||||
|
||||
[English](./README_en.md) | 中文[English](#english) | [中文](#中文)
|
||||
|
||||
|
||||
|
||||
一个为 Obsidian 编辑器的 Vim 模式设计的输入法自动切换插件。---
|
||||
|
||||
|
||||
|
||||
## 功能简介## 中文
|
||||
|
||||
|
||||
|
||||
- **自动切换输入法**:在 Vim 的 Normal 模式和 Insert 模式之间切换时,自动切换输入法### 功能简介
|
||||
|
||||
- **智能记忆**:记住上次 Insert 模式退出时的输入法状态,下次进入时自动恢复
|
||||
|
||||
- **无缝体验**:在 Insert 模式下正常输入文本时不会触发输入法切换这是一个为 Obsidian 编辑器的 Vim 模式设计的输入法自动切换插件。它能够:
|
||||
|
||||
|
||||
|
||||
## 核心特性- **自动切换输入法**:在 Vim 的 Normal 模式和 Insert 模式之间切换时,自动切换输入法
|
||||
|
||||
- **智能记忆**:记住上次 Insert 模式退出时的输入法状态,下次进入时自动恢复
|
||||
|
||||
### 1. 模式切换自动化- **无缝体验**:在 Insert 模式下正常输入文本时不会触发输入法切换
|
||||
|
||||
- **进入 Normal 模式**(按 ESC 或其他命令)→ 自动切换到英文输入法
|
||||
|
||||
- **进入 Insert 模式**(按 i, a, o 等)→ 自动恢复上次的输入法状态### 核心特性
|
||||
|
||||
|
||||
|
||||
### 2. 输入法状态记忆#### 1. 模式切换自动化
|
||||
|
||||
- 退出 Insert 模式时,自动检测并保存当前的输入法(中文/英文)- **进入 Normal 模式**(按 ESC 或其他命令)→ 自动切换到英文输入法
|
||||
|
||||
- 下次进入 Insert 模式时,自动恢复到上次保存的输入法状态- **进入 Insert 模式**(按 i, a, o 等)→ 自动恢复上次的输入法状态
|
||||
|
||||
- 支持中英文混合输入场景
|
||||
|
||||
#### 2. 输入法状态记忆
|
||||
|
||||
### 3. 智能检测机制- 退出 Insert 模式时,自动检测并保存当前的输入法(中文/英文)
|
||||
|
||||
插件使用多重检测机制确保可靠性:- 下次进入 Insert 模式时,自动恢复到上次保存的输入法状态
|
||||
|
||||
- **键盘事件监听**(主要):使用事件捕获模式监听 ESC 和 Insert 按键- 支持中英文混合输入场景
|
||||
|
||||
- **CodeMirror 事件**(辅助):监听 vim-mode-change 事件
|
||||
|
||||
- **定时轮询**(兜底):100ms 轮询检测模式变化#### 3. 智能检测机制
|
||||
|
||||
插件使用多重检测机制确保可靠性:
|
||||
|
||||
## 快速开始- **键盘事件监听**(主要):使用事件捕获模式监听 ESC 和 Insert 按键
|
||||
|
||||
- **CodeMirror 事件**(辅助):监听 vim-mode-change 事件
|
||||
|
||||
### 安装要求- **定时轮询**(兜底):100ms 轮询检测模式变化
|
||||
|
||||
|
||||
|
||||
#### macOS### 安装要求
|
||||
|
||||
```bash
|
||||
|
||||
brew install fcitx-remote-for-osx#### macOS
|
||||
|
||||
```1. 安装 [fcitx-remote-for-osx](https://github.com/xcodebuild/fcitx-remote-for-osx):
|
||||
|
||||
```bash
|
||||
|
||||
#### Linux brew install fcitx-remote-for-osx
|
||||
|
||||
```bash ```
|
||||
|
||||
# Ubuntu/Debian
|
||||
|
||||
sudo apt-get install fcitx2. 确认安装成功:
|
||||
|
||||
```bash
|
||||
|
||||
# Fedora fcitx-remote -n
|
||||
|
||||
sudo dnf install fcitx # 应该输出当前输入法的名称,如:com.apple.keylayout.ABC
|
||||
|
||||
```
|
||||
|
||||
# Arch Linux
|
||||
|
||||
sudo pacman -S fcitx#### Linux
|
||||
|
||||
```通过系统包管理器安装 `fcitx` 输入法:
|
||||
|
||||
```bash
|
||||
|
||||
#### Windows# Ubuntu/Debian
|
||||
|
||||
下载 [fcitx-remote.exe](https://github.com/yuanotes/obsidian-vim-im-switch-plugin/releases/download/1.0.3/fcitx-remote.exe) 并放到系统 PATH 路径中sudo apt-get install fcitx
|
||||
|
||||
|
||||
|
||||
### 安装插件# Fedora
|
||||
|
||||
sudo dnf install fcitx
|
||||
|
||||
1. 下载插件到 Obsidian 插件目录:
|
||||
|
||||
```bash# Arch Linux
|
||||
|
||||
cd /path/to/your/vault/.obsidian/plugins/sudo pacman -S fcitx
|
||||
|
||||
git clone https://github.com/yourusername/vim-im-switch.git```
|
||||
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
2. 在 Obsidian 中启用插件:下载并安装 AutoHotKey 版本的 fcitx-remote:
|
||||
|
||||
- 打开设置 → 社区插件- [下载 fcitx-remote.exe](https://github.com/yuanotes/obsidian-vim-im-switch-plugin/releases/download/1.0.3/fcitx-remote.exe)
|
||||
|
||||
- 找到 "Vim Input Method Switch" 并启用- 将 exe 文件放到系统 PATH 路径中
|
||||
|
||||
|
||||
|
||||
3. 配置输入法(可选):### 安装插件
|
||||
|
||||
- 设置英文输入法(默认:`com.apple.keylayout.ABC`)
|
||||
|
||||
- 设置中文输入法(默认:自动检测)1. 下载插件文件到 Obsidian 插件目录:
|
||||
|
||||
```bash
|
||||
|
||||
## 使用方法 cd /path/to/your/vault/.obsidian/plugins/
|
||||
|
||||
git clone https://github.com/yourusername/vim-im-switch.git
|
||||
|
||||
### 基本使用场景 ```
|
||||
|
||||
|
||||
|
||||
**中文输入**:2. 在 Obsidian 中启用插件:
|
||||
|
||||
``` - 打开设置 → 社区插件 → 浏览
|
||||
|
||||
按 i → 进入 Insert 模式 → 输入法切换到中文(如果上次是中文) - 找到 "Vim Input Method Switch"
|
||||
|
||||
输入中文内容 - 点击启用
|
||||
|
||||
按 ESC → 退出到 Normal 模式 → 输入法切换到英文
|
||||
|
||||
```3. 配置输入法:
|
||||
|
||||
- 打开插件设置
|
||||
|
||||
**英文输入**: - 设置英文输入法(默认:`com.apple.keylayout.ABC`)
|
||||
|
||||
``` - 设置中文输入法(默认:自动检测)
|
||||
|
||||
按 i → 进入 Insert 模式 → 输入法保持英文(如果上次是英文)
|
||||
|
||||
输入英文内容### 使用方法
|
||||
|
||||
按 ESC → 退出到 Normal 模式 → 输入法保持英文
|
||||
|
||||
```#### 基本使用
|
||||
|
||||
|
||||
|
||||
**中英混合**:1. **中文输入**:
|
||||
|
||||
``` ```
|
||||
|
||||
按 i → 自动恢复上次的输入法 按 i → 进入 Insert 模式 → 输入法切换到中文(如果上次是中文)
|
||||
|
||||
输入中文,然后手动切换到英文继续输入 输入中文内容
|
||||
|
||||
按 ESC → 保存当前输入法状态(英文) 按 ESC → 退出到 Normal 模式 → 输入法切换到英文
|
||||
|
||||
按 i → 自动恢复英文输入法 ```
|
||||
|
||||
```
|
||||
|
||||
2. **英文输入**:
|
||||
|
||||
### 支持的 Vim 命令 ```
|
||||
|
||||
按 i → 进入 Insert 模式 → 输入法保持英文(如果上次是英文)
|
||||
|
||||
- **进入 Insert 模式**:`i`, `I`, `a`, `A`, `o`, `O`, `s`, `S`, `c`, `C` 输入英文内容
|
||||
|
||||
- **退出 Insert 模式**:`ESC`, 以及其他触发 Normal 模式的命令 按 ESC → 退出到 Normal 模式 → 输入法保持英文
|
||||
|
||||
```
|
||||
|
||||
## 工作原理
|
||||
|
||||
3. **中英混合**:
|
||||
|
||||
```mermaid ```
|
||||
|
||||
graph TD 按 i → 自动恢复上次的输入法
|
||||
|
||||
A[Normal 模式<br/>英文输入法] -->|按 i/a/o 等| B[检测模式切换] 输入中文,然后手动切换到英文继续输入
|
||||
|
||||
B --> C[恢复上次保存的<br/>输入法状态] 按 ESC → 保存当前输入法状态(英文)
|
||||
|
||||
C --> D[Insert 模式<br/>自动恢复的输入法:<br/>中文/英文] 按 i → 自动恢复英文输入法
|
||||
|
||||
D -->|按 ESC| E[保存当前输入法<br/>状态 中/英] ```
|
||||
|
||||
E --> F[切换到英文输入法]
|
||||
|
||||
F --> A#### 支持的 Vim 命令
|
||||
|
||||
|
||||
|
||||
style A fill:#e1f5ff,stroke:#01579b,stroke-width:2px- **进入 Insert 模式**:`i`, `I`, `a`, `A`, `o`, `O`, `s`, `S`, `c`, `C`
|
||||
|
||||
style D fill:#fff9c4,stroke:#f57f17,stroke-width:2px- **退出 Insert 模式**:`ESC`, 以及其他触发 Normal 模式的命令
|
||||
|
||||
style E fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
|
||||
|
||||
style F fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px### 工作原理
|
||||
|
||||
```
|
||||
|
||||
```mermaid
|
||||
|
||||
### 技术细节graph TD
|
||||
|
||||
A[Normal 模式<br/>英文输入法] -->|按 i/a/o 等| B[检测模式切换]
|
||||
|
||||
**输入法检测** B --> C[恢复上次保存的<br/>输入法状态]
|
||||
|
||||
- 使用 `fcitx-remote -n` 获取当前输入法名称 C --> D[Insert 模式<br/>自动恢复的输入法:<br/>中文/英文]
|
||||
|
||||
- 对比设置中的中英文输入法名称来判断状态 D -->|按 ESC| E[保存当前输入法<br/>状态 中/英]
|
||||
|
||||
E --> F[切换到英文输入法]
|
||||
|
||||
**事件处理** F --> A
|
||||
|
||||
- **键盘事件**:使用 `capture` 模式尽早捕获按键
|
||||
|
||||
- **防抖机制**:100ms 内的重复事件会被忽略
|
||||
|
||||
- **异步处理**:所有输入法切换操作都是异步的,不阻塞编辑 style A fill:#e1f5ff,stroke:#01579b,stroke-width:2px
|
||||
|
||||
style D fill:#fff9c4,stroke:#f57f17,stroke-width:2px
|
||||
|
||||
**状态管理** style E fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
|
||||
|
||||
- `currentVimMode`:当前 Vim 模式(normal/insert/visual) style F fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
|
||||
|
||||
- `lastInsertModeIMStatus`:上次 Insert 模式的输入法状态```
|
||||
|
||||
- `imStatus`:当前输入法状态(Activate=中文,Deactivate=英文)
|
||||
|
||||
### 技术细节
|
||||
|
||||
## 故障排除
|
||||
|
||||
#### 输入法检测
|
||||
|
||||
### 问题:插件没有效果- 使用 `fcitx-remote -n` 获取当前输入法名称
|
||||
|
||||
1. 检查 fcitx-remote 是否正确安装:- 对比设置中的中英文输入法名称来判断状态
|
||||
|
||||
```bash
|
||||
|
||||
which fcitx-remote#### 事件处理
|
||||
|
||||
fcitx-remote -n- **键盘事件**:使用 `capture` 模式尽早捕获按键
|
||||
|
||||
```- **防抖机制**:100ms 内的重复事件会被忽略
|
||||
|
||||
- **异步处理**:所有输入法切换操作都是异步的,不阻塞编辑
|
||||
|
||||
2. 检查插件日志(开发者控制台):
|
||||
|
||||
- 按 `Cmd+Option+I` (macOS) 或 `Ctrl+Shift+I` (Windows/Linux) 打开开发者控制台#### 状态管理
|
||||
|
||||
- 查看是否有 `[VimIMSwitch]` 开头的日志- `currentVimMode`:当前 Vim 模式(normal/insert/visual)
|
||||
|
||||
- `lastInsertModeIMStatus`:上次 Insert 模式的输入法状态
|
||||
|
||||
3. 验证输入法名称:- `imStatus`:当前输入法状态(Activate=中文,Deactivate=英文)
|
||||
|
||||
```bash
|
||||
|
||||
# 切换到中文输入法后执行### 故障排除
|
||||
|
||||
fcitx-remote -n
|
||||
|
||||
# 输出应该匹配插件设置中的中文输入法名称#### 问题:插件没有效果
|
||||
|
||||
```1. 检查 fcitx-remote 是否正确安装:
|
||||
|
||||
```bash
|
||||
|
||||
### 问题:输入法切换不正确 which fcitx-remote
|
||||
|
||||
1. 确认设置中的输入法名称正确 fcitx-remote -n
|
||||
|
||||
2. 手动切换输入法后,在开发者控制台查看日志 ```
|
||||
|
||||
3. 检查是否有其他插件冲突
|
||||
|
||||
2. 检查插件日志(开发者控制台):
|
||||
|
||||
### 问题:ESC 键需要按多次 ```
|
||||
|
||||
- 这个问题已在最新版本中修复 按 Cmd+Option+I 打开开发者控制台
|
||||
|
||||
- 如果仍然存在,请更新到最新版本 查看是否有 [VimIMSwitch] 开头的日志
|
||||
|
||||
```
|
||||
|
||||
## 开发
|
||||
|
||||
3. 验证输入法名称:
|
||||
|
||||
### 构建 ```bash
|
||||
|
||||
```bash # 切换到中文输入法后执行
|
||||
|
||||
npm install fcitx-remote -n
|
||||
|
||||
npm run build # 输出应该匹配插件设置中的中文输入法名称
|
||||
|
||||
``` ```
|
||||
|
||||
|
||||
|
||||
### 部署#### 问题:输入法切换不正确
|
||||
|
||||
```bash1. 确认设置中的输入法名称正确
|
||||
|
||||
./deploy.sh2. 手动切换输入法后,在开发者控制台查看日志
|
||||
|
||||
```3. 检查是否有其他插件冲突
|
||||
|
||||
|
||||
|
||||
### 调试#### 问题:ESC 键需要按多次
|
||||
|
||||
插件会在控制台输出关键日志:- 这个问题已在最新版本中修复
|
||||
|
||||
- `🚀 Loading plugin...` - 插件加载- 如果仍然存在,请更新到最新版本
|
||||
|
||||
- `🔤 ESC → English` - ESC 切换到英文
|
||||
|
||||
- `🈳 → Chinese` - 切换到中文### 开发
|
||||
|
||||
- `❌ Error...` - 错误信息
|
||||
|
||||
#### 构建
|
||||
|
||||
## 更新日志```bash
|
||||
|
||||
npm install
|
||||
|
||||
查看 [CHANGELOG.md](./CHANGELOG.md) 获取详细的版本更新历史。npm run build
|
||||
|
||||
```
|
||||
|
||||
## 许可证
|
||||
|
||||
#### 部署
|
||||
|
||||
MIT License```bash
|
||||
|
||||
./deploy.sh
|
||||
|
||||
## 相关链接```
|
||||
|
||||
|
||||
|
||||
- [更新日志](./CHANGELOG.md)#### 调试
|
||||
|
||||
- [English Documentation](./README_en.md)插件会在控制台输出关键日志:
|
||||
|
||||
- [fcitx-remote-for-osx](https://github.com/xcodebuild/fcitx-remote-for-osx)- `🚀 Loading plugin...` - 插件加载
|
||||
|
||||
- `🔤 ESC → English` - ESC 切换到英文
|
||||
- `🈳 → Chinese` - 切换到中文
|
||||
- `❌ Error...` - 错误信息
|
||||
|
||||
### 更新日志
|
||||
|
||||
#### v1.0.8 (2025-01-04)
|
||||
- ✨ 新增:输入法状态记忆功能
|
||||
- 🐛 修复:ESC 键第一次按下无效的问题
|
||||
- 🐛 修复:Insert 模式下输入字符触发输入法切换
|
||||
- ⚡️ 优化:使用事件捕获模式提高响应速度
|
||||
- 🧹 清理:移除冗余代码和过多的调试日志
|
||||
|
||||
### 许可证
|
||||
|
||||
MIT License
|
||||
|
||||
---
|
||||
|
||||
## English
|
||||
|
||||
### Features
|
||||
|
||||
An input method auto-switching plugin designed for Obsidian's Vim mode that:
|
||||
|
||||
- **Automatic switching**: Automatically switches input methods when transitioning between Vim's Normal and Insert modes
|
||||
- **Smart memory**: Remembers the input method state when exiting Insert mode and restores it on next entry
|
||||
- **Seamless experience**: Won't trigger input method changes during normal text input in Insert mode
|
||||
|
||||
### Core Features
|
||||
|
||||
#### 1. Mode Switch Automation
|
||||
- **Enter Normal mode** (press ESC or other commands) → Auto switch to English input method
|
||||
- **Enter Insert mode** (press i, a, o, etc.) → Auto restore previous input method state
|
||||
|
||||
#### 2. Input Method State Memory
|
||||
- Automatically detects and saves current input method (Chinese/English) when exiting Insert mode
|
||||
- Automatically restores to last saved input method state when entering Insert mode
|
||||
- Supports mixed Chinese/English input scenarios
|
||||
|
||||
#### 3. Smart Detection Mechanism
|
||||
The plugin uses multiple detection mechanisms for reliability:
|
||||
- **Keyboard event listening** (primary): Uses capture mode to listen for ESC and Insert keys
|
||||
- **CodeMirror events** (auxiliary): Monitors vim-mode-change events
|
||||
- **Polling** (fallback): 100ms polling to detect mode changes
|
||||
|
||||
### Requirements
|
||||
|
||||
#### macOS
|
||||
1. Install [fcitx-remote-for-osx](https://github.com/xcodebuild/fcitx-remote-for-osx):
|
||||
```bash
|
||||
brew install fcitx-remote-for-osx
|
||||
```
|
||||
|
||||
2. Verify installation:
|
||||
```bash
|
||||
fcitx-remote -n
|
||||
# Should output current input method name, e.g.: com.apple.keylayout.ABC
|
||||
```
|
||||
|
||||
#### Linux
|
||||
Install `fcitx` via your package manager:
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt-get install fcitx
|
||||
|
||||
# Fedora
|
||||
sudo dnf install fcitx
|
||||
|
||||
# Arch Linux
|
||||
sudo pacman -S fcitx
|
||||
```
|
||||
|
||||
#### Windows
|
||||
Download and install the AutoHotKey version of fcitx-remote:
|
||||
- [Download fcitx-remote.exe](https://github.com/yuanotes/obsidian-vim-im-switch-plugin/releases/download/1.0.3/fcitx-remote.exe)
|
||||
- Place the exe file in your system PATH
|
||||
|
||||
### Installation
|
||||
|
||||
1. Download plugin files to Obsidian plugins directory:
|
||||
```bash
|
||||
cd /path/to/your/vault/.obsidian/plugins/
|
||||
git clone https://github.com/yourusername/vim-im-switch.git
|
||||
```
|
||||
|
||||
2. Enable plugin in Obsidian:
|
||||
- Open Settings → Community Plugins → Browse
|
||||
- Find "Vim Input Method Switch"
|
||||
- Click Enable
|
||||
|
||||
3. Configure input methods:
|
||||
- Open plugin settings
|
||||
- Set English input method (default: `com.apple.keylayout.ABC`)
|
||||
- Set Chinese input method (default: auto-detect)
|
||||
|
||||
### Usage
|
||||
|
||||
#### Basic Usage
|
||||
|
||||
1. **Chinese Input**:
|
||||
```
|
||||
Press i → Enter Insert mode → IM switches to Chinese (if last time was Chinese)
|
||||
Type Chinese content
|
||||
Press ESC → Exit to Normal mode → IM switches to English
|
||||
```
|
||||
|
||||
2. **English Input**:
|
||||
```
|
||||
Press i → Enter Insert mode → IM stays English (if last time was English)
|
||||
Type English content
|
||||
Press ESC → Exit to Normal mode → IM stays English
|
||||
```
|
||||
|
||||
3. **Mixed Input**:
|
||||
```
|
||||
Press i → Auto restore last IM
|
||||
Type Chinese, then manually switch to English
|
||||
Press ESC → Save current IM state (English)
|
||||
Press i → Auto restore English IM
|
||||
```
|
||||
|
||||
#### Supported Vim Commands
|
||||
|
||||
- **Enter Insert mode**: `i`, `I`, `a`, `A`, `o`, `O`, `s`, `S`, `c`, `C`
|
||||
- **Exit Insert mode**: `ESC`, and other commands that trigger Normal mode
|
||||
|
||||
### How It Works
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Normal Mode<br/>English IM] -->|Press i/a/o etc| B[Detect Mode Change]
|
||||
B --> C[Restore Last Saved<br/>IM State]
|
||||
C --> D[Insert Mode<br/>Restored IM:<br/>Chinese/English]
|
||||
D -->|Press ESC| E[Save Current IM<br/>State CN/EN]
|
||||
E --> F[Switch to English IM]
|
||||
F --> A
|
||||
|
||||
style A fill:#e1f5ff,stroke:#01579b,stroke-width:2px
|
||||
style D fill:#fff9c4,stroke:#f57f17,stroke-width:2px
|
||||
style E fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
|
||||
style F fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
|
||||
```
|
||||
|
||||
The plugin maintains a state machine that tracks Vim modes and input method states, automatically switching input methods when mode transitions occur while preserving user preferences.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### Issue: Plugin not working
|
||||
1. Check if fcitx-remote is properly installed
|
||||
2. Check plugin logs in developer console
|
||||
3. Verify input method names match settings
|
||||
|
||||
#### Issue: Incorrect input method switching
|
||||
1. Confirm input method names in settings are correct
|
||||
2. Check logs in developer console after manually switching IM
|
||||
3. Check for conflicts with other plugins
|
||||
|
||||
### Development
|
||||
|
||||
#### Build
|
||||
```bash
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
#### Deploy
|
||||
```bash
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
#### Debug
|
||||
The plugin outputs key logs in the console:
|
||||
- `🚀 Loading plugin...` - Plugin loaded
|
||||
- `🔤 ESC → English` - ESC switches to English
|
||||
- `🈳 → Chinese` - Switch to Chinese
|
||||
- `❌ Error...` - Error messages
|
||||
|
||||
### Changelog
|
||||
|
||||
#### v1.0.8 (2025-01-04)
|
||||
- ✨ Added: Input method state memory feature
|
||||
- <20><> Fixed: ESC key not working on first press
|
||||
- 🐛 Fixed: Character input in Insert mode triggering IM switch
|
||||
- ⚡️ Optimized: Use event capture mode for better responsiveness
|
||||
- 🧹 Cleanup: Remove redundant code and excessive debug logs
|
||||
|
||||
### License
|
||||
|
||||
MIT License
|
||||
195
README_en.md
Normal file
195
README_en.md
Normal file
@@ -0,0 +1,195 @@
|
||||
# Obsidian Vim Input Method Switch Plugin
|
||||
|
||||
English | [中文](./README.md)
|
||||
|
||||
An input method auto-switching plugin designed for Obsidian's Vim mode.
|
||||
|
||||
## Features
|
||||
|
||||
- **Automatic switching**: Automatically switches input methods when transitioning between Vim's Normal and Insert modes
|
||||
- **Smart memory**: Remembers the input method state when exiting Insert mode and restores it on next entry
|
||||
- **Seamless experience**: Won't trigger input method changes during normal text input in Insert mode
|
||||
|
||||
## Core Features
|
||||
|
||||
### 1. Mode Switch Automation
|
||||
- **Enter Normal mode** (press ESC or other commands) → Auto switch to English input method
|
||||
- **Enter Insert mode** (press i, a, o, etc.) → Auto restore previous input method state
|
||||
|
||||
### 2. Input Method State Memory
|
||||
- Automatically detects and saves current input method (Chinese/English) when exiting Insert mode
|
||||
- Automatically restores to last saved input method state when entering Insert mode
|
||||
- Supports mixed Chinese/English input scenarios
|
||||
|
||||
### 3. Smart Detection Mechanism
|
||||
The plugin uses multiple detection mechanisms for reliability:
|
||||
- **Keyboard event listening** (primary): Uses capture mode to listen for ESC and Insert keys
|
||||
- **CodeMirror events** (auxiliary): Monitors vim-mode-change events
|
||||
- **Polling** (fallback): 100ms polling to detect mode changes
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Requirements
|
||||
|
||||
#### macOS
|
||||
```bash
|
||||
brew install fcitx-remote-for-osx
|
||||
```
|
||||
|
||||
#### Linux
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt-get install fcitx
|
||||
|
||||
# Fedora
|
||||
sudo dnf install fcitx
|
||||
|
||||
# Arch Linux
|
||||
sudo pacman -S fcitx
|
||||
```
|
||||
|
||||
#### Windows
|
||||
Download [fcitx-remote.exe](https://github.com/yuanotes/obsidian-vim-im-switch-plugin/releases/download/1.0.3/fcitx-remote.exe) and place it in your system PATH
|
||||
|
||||
### Installation
|
||||
|
||||
1. Download plugin to Obsidian plugins directory:
|
||||
```bash
|
||||
cd /path/to/your/vault/.obsidian/plugins/
|
||||
git clone https://github.com/yourusername/vim-im-switch.git
|
||||
```
|
||||
|
||||
2. Enable plugin in Obsidian:
|
||||
- Open Settings → Community Plugins
|
||||
- Find "Vim Input Method Switch" and enable it
|
||||
|
||||
3. Configure input methods (optional):
|
||||
- Set English input method (default: `com.apple.keylayout.ABC`)
|
||||
- Set Chinese input method (default: auto-detect)
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage Scenarios
|
||||
|
||||
**Chinese Input**:
|
||||
```
|
||||
Press i → Enter Insert mode → IM switches to Chinese (if last time was Chinese)
|
||||
Type Chinese content
|
||||
Press ESC → Exit to Normal mode → IM switches to English
|
||||
```
|
||||
|
||||
**English Input**:
|
||||
```
|
||||
Press i → Enter Insert mode → IM stays English (if last time was English)
|
||||
Type English content
|
||||
Press ESC → Exit to Normal mode → IM stays English
|
||||
```
|
||||
|
||||
**Mixed Input**:
|
||||
```
|
||||
Press i → Auto restore last IM
|
||||
Type Chinese, then manually switch to English
|
||||
Press ESC → Save current IM state (English)
|
||||
Press i → Auto restore English IM
|
||||
```
|
||||
|
||||
### Supported Vim Commands
|
||||
|
||||
- **Enter Insert mode**: `i`, `I`, `a`, `A`, `o`, `O`, `s`, `S`, `c`, `C`
|
||||
- **Exit Insert mode**: `ESC`, and other commands that trigger Normal mode
|
||||
|
||||
## How It Works
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Normal Mode<br/>English IM] -->|Press i/a/o etc| B[Detect Mode Change]
|
||||
B --> C[Restore Last Saved<br/>IM State]
|
||||
C --> D[Insert Mode<br/>Restored IM:<br/>Chinese/English]
|
||||
D -->|Press ESC| E[Save Current IM<br/>State CN/EN]
|
||||
E --> F[Switch to English IM]
|
||||
F --> A
|
||||
|
||||
style A fill:#e1f5ff,stroke:#01579b,stroke-width:2px
|
||||
style D fill:#fff9c4,stroke:#f57f17,stroke-width:2px
|
||||
style E fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
|
||||
style F fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
|
||||
```
|
||||
|
||||
### Technical Details
|
||||
|
||||
**Input Method Detection**
|
||||
- Uses `fcitx-remote -n` to get current input method name
|
||||
- Compares with configured Chinese/English input method names
|
||||
|
||||
**Event Handling**
|
||||
- **Keyboard events**: Uses `capture` mode to intercept keys early
|
||||
- **Debouncing**: Ignores repeated events within 100ms
|
||||
- **Async processing**: All input method switches are asynchronous and non-blocking
|
||||
|
||||
**State Management**
|
||||
- `currentVimMode`: Current Vim mode (normal/insert/visual)
|
||||
- `lastInsertModeIMStatus`: Last input method state in Insert mode
|
||||
- `imStatus`: Current input method state (Activate=Chinese, Deactivate=English)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Issue: Plugin not working
|
||||
1. Check if fcitx-remote is properly installed:
|
||||
```bash
|
||||
which fcitx-remote
|
||||
fcitx-remote -n
|
||||
```
|
||||
|
||||
2. Check plugin logs (developer console):
|
||||
- Press `Cmd+Option+I` (macOS) or `Ctrl+Shift+I` (Windows/Linux) to open developer console
|
||||
- Look for logs starting with `[VimIMSwitch]`
|
||||
|
||||
3. Verify input method names:
|
||||
```bash
|
||||
# After switching to Chinese input method
|
||||
fcitx-remote -n
|
||||
# Output should match the Chinese IM name in plugin settings
|
||||
```
|
||||
|
||||
### Issue: Incorrect input method switching
|
||||
1. Confirm input method names in settings are correct
|
||||
2. Check logs in developer console after manually switching IM
|
||||
3. Check for conflicts with other plugins
|
||||
|
||||
### Issue: ESC key requires multiple presses
|
||||
- This issue has been fixed in the latest version
|
||||
- If it still occurs, please update to the latest version
|
||||
|
||||
## Development
|
||||
|
||||
### Build
|
||||
```bash
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Deploy
|
||||
```bash
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
### Debug
|
||||
The plugin outputs key logs in the console:
|
||||
- `🚀 Loading plugin...` - Plugin loaded
|
||||
- `🔤 ESC → English` - ESC switches to English
|
||||
- `🈳 → Chinese` - Switch to Chinese
|
||||
- `❌ Error...` - Error messages
|
||||
|
||||
## Changelog
|
||||
|
||||
See [CHANGELOG_en.md](./CHANGELOG_en.md) for detailed version history.
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
|
||||
## Links
|
||||
|
||||
- [Changelog](./CHANGELOG_en.md)
|
||||
- [中文文档](./README.md)
|
||||
- [fcitx-remote-for-osx](https://github.com/xcodebuild/fcitx-remote-for-osx)
|
||||
175
RELEASE.md
Normal file
175
RELEASE.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# RELEASE NOTE
|
||||
|
||||
## 版本发布说明 - 2.0.0
|
||||
|
||||
**发布日期**: 2025-11-04
|
||||
|
||||
---
|
||||
|
||||
### 版本概述
|
||||
|
||||
版本 2.0.0 是一个重要的里程碑版本,为 Obsidian Vim 输入法自动切换插件带来了重大改进。此版本包含输入法状态管理系统的完全重写、增强的可靠性以及全面的文档。
|
||||
|
||||
### 新增内容
|
||||
|
||||
#### 主要功能
|
||||
|
||||
##### 输入法状态记忆系统
|
||||
插件现在具备智能状态记忆系统,能够记住您的输入法偏好:
|
||||
- **智能记忆**:自动记住退出 Insert 模式时使用的输入法(中文/英文)
|
||||
- **自动恢复**:再次进入 Insert 模式时,插件会恢复上次的输入法状态
|
||||
- **混合输入支持**:无缝处理在同一编辑会话中中英文输入法切换的场景
|
||||
|
||||
**示例工作流程**:
|
||||
```
|
||||
1. 按 'i' → 进入 Insert 模式 → 恢复中文输入法(如果上次是中文)
|
||||
2. 输入中文内容
|
||||
3. 手动切换到英文输入法,继续输入
|
||||
4. 按 ESC → 保存"英文"作为最后状态
|
||||
5. 再次按 'i' → 自动恢复英文输入法
|
||||
```
|
||||
|
||||
#### 关键 Bug 修复
|
||||
|
||||
##### ESC 键响应问题
|
||||
- **修复内容**:ESC 键需要多次按下才能切换输入法
|
||||
- **解决方案**:实现事件捕获模式,在最早阶段拦截按键
|
||||
- **效果**:首次按下 ESC 即可立即切换到英文输入法
|
||||
|
||||
##### Insert 模式干扰问题
|
||||
- **修复内容**:在 Insert 模式下输入字符(输入 'i'、'a'、'o' 等)触发不必要的输入法切换
|
||||
- **解决方案**:为键盘事件处理器添加 Vim 模式验证
|
||||
- **效果**:Insert 模式下的正常文本输入不再被打断
|
||||
|
||||
#### 性能优化
|
||||
|
||||
##### 事件处理优化
|
||||
- **捕获模式**:键盘事件监听器使用 `{ capture: true }`
|
||||
- **降低延迟**:输入法切换响应时间快 10-20ms
|
||||
- **智能检测**:仅在必要时切换输入法,避免冗余操作
|
||||
|
||||
##### 三重检测机制
|
||||
通过三层检测增强可靠性:
|
||||
1. **主要检测**:键盘事件捕获(最快,最高优先级)
|
||||
2. **辅助检测**:CodeMirror vim-mode-change 事件
|
||||
3. **兜底检测**:100ms 轮询作为安全保障
|
||||
|
||||
#### 代码质量
|
||||
|
||||
##### 代码库清理
|
||||
- 移除约 50 行未使用的测试代码
|
||||
- 减少插件体积约 2KB
|
||||
- 提高代码可维护性和可读性
|
||||
|
||||
##### 简化日志输出
|
||||
- 减少 70% 的控制台输出
|
||||
- 保留关键的状态转换日志
|
||||
- 更清晰的调试信息,便于故障排查
|
||||
|
||||
#### 文档
|
||||
|
||||
##### 全面的文档
|
||||
- **README.md**:详细的中文文档,包含使用示例
|
||||
- **README_en.md**:完整的英文文档
|
||||
- **CHANGELOG.md**:详细的中文版本历史
|
||||
- **CHANGELOG_en.md**:完整的英文更新日志
|
||||
- **Mermaid 图表**:可视化工作流程说明
|
||||
|
||||
### 技术细节
|
||||
|
||||
#### 架构改进
|
||||
|
||||
**状态管理**:
|
||||
- `currentVimMode`:追踪当前 Vim 模式(normal/insert/visual)
|
||||
- `lastInsertModeIMStatus`:存储上次 Insert 模式的输入法状态
|
||||
- `imStatus`:维护当前输入法状态
|
||||
|
||||
**检测系统**:
|
||||
- 事件捕获阶段拦截
|
||||
- 使用 `fcitx-remote -n` 实时验证输入法状态
|
||||
- 异步输入法切换操作
|
||||
|
||||
#### 兼容性
|
||||
|
||||
**平台支持**:
|
||||
- macOS:通过 fcitx-remote-for-osx 完全支持
|
||||
- Linux:通过 fcitx 完全支持
|
||||
- Windows:通过 AutoHotKey 版本支持
|
||||
|
||||
**Obsidian 兼容性**:
|
||||
- 兼容最新版本的 Obsidian
|
||||
- 同时支持 CodeMirror 5 和 CodeMirror 6
|
||||
|
||||
### 升级指南
|
||||
|
||||
#### 现有用户
|
||||
|
||||
**从 v1.x 升级**:
|
||||
```bash
|
||||
cd /path/to/your/vault/.obsidian/plugins/vim-im-switch/
|
||||
git pull origin main
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
然后重启 Obsidian 以激活新版本。
|
||||
|
||||
**重要提示**:
|
||||
- 升级过程中会保留设置
|
||||
- 无需更改配置
|
||||
- 建议升级前备份您的 vault
|
||||
|
||||
#### 新用户
|
||||
|
||||
**安装步骤**:
|
||||
1. 为您的平台安装 fcitx-remote
|
||||
2. 将插件克隆到 Obsidian 插件目录
|
||||
3. 在 Obsidian 设置中启用插件
|
||||
4. 配置输入法名称(可选)
|
||||
|
||||
详细安装说明请参阅 [README.md](./README.md) 或 [README_en.md](./README_en.md)。
|
||||
|
||||
### 已知问题
|
||||
|
||||
本版本无严重问题。如需故障排除,请参考:
|
||||
- [中文故障排除](./README.md#故障排除)
|
||||
- [English Troubleshooting](./README_en.md#troubleshooting)
|
||||
|
||||
### 破坏性变更
|
||||
|
||||
无。本版本与 v1.x 配置完全向后兼容。
|
||||
|
||||
### 废弃功能
|
||||
|
||||
本版本无废弃功能。
|
||||
|
||||
### 未来规划
|
||||
|
||||
计划在未来版本中实现的功能:
|
||||
- 支持更多输入法切换工具(im-select 等)
|
||||
- 可配置的快捷键绑定
|
||||
- Visual 模式输入法处理改进
|
||||
- 与 Obsidian 原生语言切换集成
|
||||
|
||||
### 相关链接
|
||||
|
||||
- [GitHub 仓库](https://github.com/yourusername/vim-im-switch)
|
||||
- [问题追踪](https://github.com/yourusername/vim-im-switch/issues)
|
||||
- [中文文档](./README.md)
|
||||
- [English Documentation](./README_en.md)
|
||||
- [更新日志](./CHANGELOG.md)
|
||||
- [Changelog](./CHANGELOG_en.md)
|
||||
|
||||
### 技术支持
|
||||
|
||||
如果您遇到任何问题或有疑问:
|
||||
1. 查看 [故障排除指南](./README.md#故障排除)
|
||||
2. 搜索现有的 [Issues](https://github.com/yourusername/vim-im-switch/issues)
|
||||
3. 创建新的 issue 并提供详细信息
|
||||
|
||||
### 许可证
|
||||
|
||||
MIT License - 详见 [LICENSE.txt](./LICENSE.txt)
|
||||
|
||||
---
|
||||
|
||||
BIN
assets/alipay.jpg
Normal file
BIN
assets/alipay.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
BIN
assets/wechat_pay.jpg
Normal file
BIN
assets/wechat_pay.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
69
deploy.sh
Executable file
69
deploy.sh
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Obsidian Vim IM Switch Plugin 一键部署脚本
|
||||
# 编译并复制插件文件到 Obsidian 插件目录
|
||||
|
||||
set -e # 遇到错误时退出
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 配置
|
||||
SOURCE_DIR="/Users/gavin/vim-im-switch"
|
||||
TARGET_DIR="/Users/gavin/myweb/.obsidian/plugins/vim-im-switch"
|
||||
|
||||
echo -e "${BLUE}🚀 开始部署 Obsidian Vim IM Switch Plugin...${NC}"
|
||||
|
||||
# 检查源目录
|
||||
if [ ! -d "$SOURCE_DIR" ]; then
|
||||
echo -e "${RED}❌ 源目录不存在: $SOURCE_DIR${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 进入源目录
|
||||
cd "$SOURCE_DIR"
|
||||
echo -e "${YELLOW}📁 当前目录: $(pwd)${NC}"
|
||||
|
||||
# 编译项目
|
||||
echo -e "${YELLOW}🔨 开始编译项目...${NC}"
|
||||
if npm run build; then
|
||||
echo -e "${GREEN}✅ 编译成功${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ 编译失败${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查编译产物
|
||||
if [ ! -f "main.js" ]; then
|
||||
echo -e "${RED}❌ 编译产物 main.js 不存在${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 创建目标目录
|
||||
echo -e "${YELLOW}📂 创建目标目录...${NC}"
|
||||
mkdir -p "$TARGET_DIR"
|
||||
|
||||
# 复制文件
|
||||
echo -e "${YELLOW}📋 复制插件文件...${NC}"
|
||||
|
||||
# 复制必需的文件
|
||||
cp -f main.js "$TARGET_DIR/"
|
||||
cp -f manifest.json "$TARGET_DIR/"
|
||||
cp -f styles.css "$TARGET_DIR/"
|
||||
|
||||
echo -e "${GREEN}✅ 文件复制完成:${NC}"
|
||||
echo -e " • main.js"
|
||||
echo -e " • manifest.json"
|
||||
echo -e " • styles.css"
|
||||
|
||||
# 验证文件
|
||||
echo -e "${YELLOW}🔍 验证复制的文件...${NC}"
|
||||
ls -la "$TARGET_DIR"
|
||||
|
||||
echo -e "${GREEN}🎉 部署完成!${NC}"
|
||||
echo -e "${BLUE}📍 插件已部署到: $TARGET_DIR${NC}"
|
||||
echo -e "${YELLOW}💡 请重启 Obsidian 或重新加载插件以使更改生效${NC}"
|
||||
42
diagnose-im.sh
Executable file
42
diagnose-im.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 输入法诊断和设置脚本
|
||||
|
||||
echo "🔍 系统输入法诊断"
|
||||
echo "=================="
|
||||
|
||||
echo ""
|
||||
echo "1. 当前 fcitx-remote 状态:"
|
||||
/usr/local/bin/fcitx-remote
|
||||
|
||||
echo ""
|
||||
echo "2. 当前输入法名称:"
|
||||
/usr/local/bin/fcitx-remote -n
|
||||
|
||||
echo ""
|
||||
echo "3. 系统输入法设置:"
|
||||
defaults read ~/Library/Preferences/com.apple.HIToolbox.plist AppleSelectedInputSources
|
||||
|
||||
echo ""
|
||||
echo "4. 可用输入法:"
|
||||
ls /System/Library/Input\ Methods/ | grep -E "(Chinese|Pinyin|SCIM|TCIM)"
|
||||
|
||||
echo ""
|
||||
echo "🛠️ 建议解决方案:"
|
||||
echo "1. 打开系统偏好设置 → 键盘 → 输入法"
|
||||
echo "2. 点击 '+' 添加中文输入法(如:简体中文-拼音)"
|
||||
echo "3. 确保启用了至少一个中文输入法"
|
||||
echo "4. 重新运行插件测试"
|
||||
|
||||
echo ""
|
||||
echo "🧪 测试手动切换(请注意观察实际输入法是否切换):"
|
||||
echo "执行: fcitx-remote -c (切换到英文)"
|
||||
/usr/local/bin/fcitx-remote -c
|
||||
sleep 1
|
||||
echo "结果: $(/usr/local/bin/fcitx-remote)"
|
||||
|
||||
echo ""
|
||||
echo "执行: fcitx-remote -o (切换到中文)"
|
||||
/usr/local/bin/fcitx-remote -o
|
||||
sleep 1
|
||||
echo "结果: $(/usr/local/bin/fcitx-remote)"
|
||||
1
fcitx-remote-for-osx
Submodule
1
fcitx-remote-for-osx
Submodule
Submodule fcitx-remote-for-osx added at 15711cb5a7
155
fcitx-remote.ahk
Normal file
155
fcitx-remote.ahk
Normal file
@@ -0,0 +1,155 @@
|
||||
|
||||
GetGUIThreadInfo_hwndActive(WinTitle="A")
|
||||
{
|
||||
ControlGet, hwnd, HWND,,, %WinTitle%
|
||||
if (WinActive(WinTitle)) {
|
||||
ptrSize := !A_PtrSize ? 4 : A_PtrSize
|
||||
VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
|
||||
NumPut(cbSize, stGTI, 0, "UInt")
|
||||
return hwnd := DllCall("GetGUIThreadInfo", "Uint", 0, "Ptr", &stGTI)
|
||||
? NumGet(stGTI, 8+PtrSize, "Ptr") : hwnd
|
||||
}
|
||||
else {
|
||||
return hwnd
|
||||
}
|
||||
}
|
||||
;-----------------------------------------------------------
|
||||
; IME状态的获取
|
||||
; WinTitle="A" 対象Window
|
||||
; 返回值 1:ON / 0:OFF
|
||||
;-----------------------------------------------------------
|
||||
IME_GET(WinTitle="A") {
|
||||
hwnd :=GetGUIThreadInfo_hwndActive(WinTitle)
|
||||
return DllCall("SendMessage"
|
||||
, Ptr, DllCall("imm32\ImmGetDefaultIMEWnd", Ptr,hwnd)
|
||||
, UInt, 0x0283 ;Message : WM_IME_CONTROL
|
||||
, UPtr, 0x005 ;wParam : IMC_GETOPENSTATUS
|
||||
, Ptr, 0) ;lParam : 0
|
||||
}
|
||||
|
||||
;-----------------------------------------------------------
|
||||
; IME状态的设置
|
||||
; SetSts 1:ON / 0:OFF
|
||||
; WinTitle="A" 対象Window
|
||||
; 返回值 0:成功 / 0以外:失败
|
||||
;-----------------------------------------------------------
|
||||
IME_SET(SetSts, WinTitle="A") {
|
||||
hwnd :=GetGUIThreadInfo_hwndActive(WinTitle)
|
||||
return DllCall("SendMessage"
|
||||
, Ptr, DllCall("imm32\ImmGetDefaultIMEWnd", Ptr, hwnd)
|
||||
, UInt, 0x0283 ;Message : WM_IME_CONTROL
|
||||
, UPtr, 0x006 ;wParam : IMC_SETOPENSTATUS
|
||||
, Ptr, SetSts) ;lParam : 0 or 1
|
||||
}
|
||||
|
||||
;===========================================================================
|
||||
; 0000xxxx 假名输入
|
||||
; 0001xxxx 罗马字输入方式
|
||||
; xxxx0xxx 半角
|
||||
; xxxx1xxx 全角
|
||||
; xxxxx000 英数
|
||||
; xxxxx001 平假名
|
||||
; xxxxx011 片假名
|
||||
|
||||
; IME输入模式(所有IME共有)
|
||||
; DEC HEX BIN
|
||||
; 0 (0x00 0000 0000) 假名 半英数
|
||||
; 3 (0x03 0000 0011) 半假名
|
||||
; 8 (0x08 0000 1000) 全英数
|
||||
; 9 (0x09 0000 1001) 全字母数字
|
||||
; 11 (0x0B 0000 1011) 全片假名
|
||||
; 16 (0x10 0001 0000) 罗马字半英数
|
||||
; 19 (0x13 0001 0011) 半假名
|
||||
; 24 (0x18 0001 1000) 全英数
|
||||
; 25 (0x19 0001 1001) 平假名
|
||||
; 27 (0x1B 0001 1011) 全片假名
|
||||
|
||||
; ※ 区域和语言选项 - [详细信息] - 高级设置
|
||||
; - 将高级文字服务支持应用于所有程序
|
||||
; 当打开时似乎无法获取该值
|
||||
; (谷歌日语输入β必须在此打开,所以无法获得值)
|
||||
|
||||
;-------------------------------------------------------
|
||||
; 获取IME输入模式
|
||||
; WinTitle="A" 対象Window
|
||||
; 返回值 输入模式
|
||||
;--------------------------------------------------------
|
||||
|
||||
; 测试时 win10 x64 自带输入法 中文返回 1, 英文返回 0.
|
||||
; win7 x32
|
||||
; 中文简体 美式键盘 返回 0。
|
||||
;
|
||||
; QQ拼音输入法中文输入模式 QQ拼音英文输入模式 搜狗输入法中文 搜狗输入法英文
|
||||
; 半角+中文标点 1025 268436481(1025)
|
||||
; 半角+英文标点 1 1024 268435457(1) 268435456(0)
|
||||
; 全角+中文标点 1033 268436489(1033)
|
||||
; 全角+英文标点 9 1032 268435465(9) 268435464(8)
|
||||
|
||||
; 智能ABC中文输入标准模式 智能ABC中文输入双打模式 智能ABC英文标准 智能ABC英文双打
|
||||
; 半角+中文标点 1025 -2147482623(1025) 1024 -2147482624
|
||||
; 半角+英文标点 1 -2147483647(1) 0 -2147483648
|
||||
; 全角+中文标点 1033 -2147482615(1033) 1032 -2147482616
|
||||
; 全角+英文标点 9 -2147483639(9) 8 -2147483640
|
||||
|
||||
|
||||
IME_GetConvMode(WinTitle="A") {
|
||||
hwnd :=GetGUIThreadInfo_hwndActive(WinTitle)
|
||||
return DllCall("SendMessage"
|
||||
, "Ptr", DllCall("imm32\ImmGetDefaultIMEWnd", "Ptr", hwnd)
|
||||
, "UInt", 0x0283 ;Message : WM_IME_CONTROL
|
||||
, "Int", 0x001 ;wParam : IMC_GETCONVERSIONMODE
|
||||
, "Int", 0) & 0xffff ;lParam : 0 , & 0xffff 表示只取低16位
|
||||
}
|
||||
|
||||
;-------------------------------------------------------
|
||||
; IME输入模式设置
|
||||
; ConvMode 输入模式
|
||||
; WinTitle="A" 対象Window
|
||||
; 返回值 0:成功 / 0以外:失败
|
||||
;--------------------------------------------------------
|
||||
IME_SetConvMode(ConvMode, WinTitle="A") {
|
||||
hwnd :=GetGUIThreadInfo_hwndActive(WinTitle)
|
||||
return DllCall("SendMessage"
|
||||
, "Ptr", DllCall("imm32\ImmGetDefaultIMEWnd", "Ptr", hwnd)
|
||||
, "UInt", 0x0283 ;Message : WM_IME_CONTROL
|
||||
, "UPtr", 0x002 ;wParam : IMC_SETCONVERSIONMODE
|
||||
, "Ptr", ConvMode) ;lParam : CONVERSIONMODE
|
||||
}
|
||||
|
||||
|
||||
im_status := IME_GetConvMode()
|
||||
|
||||
arg = %1%
|
||||
|
||||
switch arg {
|
||||
case "-c":
|
||||
;; inactive im
|
||||
IME_SetConvMode(0)
|
||||
return
|
||||
|
||||
case "-o":
|
||||
;; activate im
|
||||
IME_SetConvMode(1025)
|
||||
return
|
||||
|
||||
case "-t":
|
||||
if (IME_GetConvMode() = 0) {
|
||||
IME_SetConvMode(1025)
|
||||
} else {
|
||||
IME_SetConvMode(0)
|
||||
}
|
||||
return
|
||||
case "-T":
|
||||
if (IME_GetConvMode() = 0) {
|
||||
IME_SetConvMode(1025)
|
||||
} else {
|
||||
IME_SetConvMode(0)
|
||||
}
|
||||
return
|
||||
default:
|
||||
if (IME_GetConvMode() = 0) {
|
||||
FileAppend 1`n, *
|
||||
} else {
|
||||
FileAppend 2`n, *
|
||||
}
|
||||
}
|
||||
450
main.ts
Normal file
450
main.ts
Normal file
@@ -0,0 +1,450 @@
|
||||
import { App, Modal, Notice, Plugin, PluginSettingTab, Setting, Workspace, MarkdownView, TFile, WorkspaceLeaf } from 'obsidian';
|
||||
import { exec } from "child_process";
|
||||
import { promisify } from "util";
|
||||
import * as CodeMirror from 'codemirror';
|
||||
|
||||
interface VimIMSwitchSettings {
|
||||
fcitxRemotePath_macOS: string;
|
||||
fcitxRemotePath_windows: string;
|
||||
fcitxRemotePath_linux: string;
|
||||
englishInputMethod: string;
|
||||
chineseInputMethod: string;
|
||||
}
|
||||
|
||||
const DEFAULT_SETTINGS: VimIMSwitchSettings = {
|
||||
fcitxRemotePath_macOS: '/usr/local/bin/fcitx-remote',
|
||||
fcitxRemotePath_windows: 'C:\\Program Files\\bin\\fcitx-remote',
|
||||
fcitxRemotePath_linux: '/usr/bin/fcitx-remote',
|
||||
englishInputMethod: 'com.apple.keylayout.ABC',
|
||||
chineseInputMethod: 'auto-detect', // 将自动检测当前中文输入法
|
||||
}
|
||||
|
||||
const pexec = promisify(exec);
|
||||
|
||||
enum IMStatus {
|
||||
None,
|
||||
Activate,
|
||||
Deactivate,
|
||||
}
|
||||
|
||||
export default class VimIMSwitchPlugin extends Plugin {
|
||||
settings: VimIMSwitchSettings;
|
||||
imStatus = IMStatus.None;
|
||||
fcitxRemotePath = "";
|
||||
|
||||
private editorMode: 'cm5' | 'cm6' = null;
|
||||
private initialized = false;
|
||||
private cmEditor: CodeMirror.Editor = null;
|
||||
private lastInsertModeIMStatus = IMStatus.None; // 记住上一次insert模式的输入法状态
|
||||
private keyboardListenerSetup = false; // 防止重复设置键盘监听器
|
||||
private lastKeyTime = 0; // 防抖:记录上次按键时间
|
||||
private currentVimMode = 'normal'; // 跟踪当前vim模式
|
||||
|
||||
async onload() {
|
||||
console.log('🚀 [VimIMSwitch] Loading plugin...');
|
||||
|
||||
await this.loadSettings();
|
||||
|
||||
// 尽早设置全局键盘监听器
|
||||
this.setupObsidianEditorEvents();
|
||||
|
||||
this.addSettingTab(new IMSwitchSettingTab(this.app, this));
|
||||
|
||||
this.addCommand({
|
||||
id: 'test-im-switch-to-english',
|
||||
name: 'Test: Switch to English',
|
||||
callback: () => {
|
||||
this.deactivateIM();
|
||||
}
|
||||
});
|
||||
|
||||
this.addCommand({
|
||||
id: 'test-im-switch-to-chinese',
|
||||
name: 'Test: Switch to Chinese',
|
||||
callback: () => {
|
||||
this.activateIM();
|
||||
}
|
||||
});
|
||||
|
||||
this.addCommand({
|
||||
id: 'test-check-im-status',
|
||||
name: 'Test: Check IM Status',
|
||||
callback: () => {
|
||||
this.getFcitxRemoteStatus();
|
||||
}
|
||||
});
|
||||
|
||||
this.app.workspace.on('file-open', async (file: TFile) => {
|
||||
if (!this.initialized) {
|
||||
await this.initialize();
|
||||
}
|
||||
if (this.cmEditor) {
|
||||
await this.getFcitxRemoteStatus();
|
||||
this.lastInsertModeIMStatus = this.imStatus;
|
||||
await this.deactivateIM();
|
||||
if (typeof this.cmEditor.off === 'function') {
|
||||
this.cmEditor.off("vim-mode-change", this.onVimModeChange);
|
||||
}
|
||||
if (typeof this.cmEditor.on === 'function') {
|
||||
this.cmEditor.on("vim-mode-change", this.onVimModeChange);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.app.workspace.on('active-leaf-change', async (leaf: WorkspaceLeaf) => {
|
||||
if(this.app.workspace.activeLeaf.view.getViewType() == "markdown") {
|
||||
if (!this.initialized) {
|
||||
await this.initialize();
|
||||
}
|
||||
if (this.cmEditor) {
|
||||
await this.getFcitxRemoteStatus();
|
||||
this.lastInsertModeIMStatus = this.imStatus;
|
||||
await this.deactivateIM();
|
||||
this.setupObsidianEditorEvents();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async initialize() {
|
||||
if (this.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ('editor:toggle-source' in (this.app as any).commands.editorCommands) {
|
||||
this.editorMode = 'cm6';
|
||||
} else {
|
||||
this.editorMode = 'cm5';
|
||||
}
|
||||
|
||||
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
|
||||
if (view) {
|
||||
if (this.editorMode == 'cm6') {
|
||||
const possiblePaths = [
|
||||
(view as any).sourceMode?.cmEditor?.cm?.cm,
|
||||
(view as any).sourceMode?.cmEditor?.cm,
|
||||
(view as any).sourceMode?.cmEditor,
|
||||
(view as any).editor?.cm,
|
||||
(view.editor as any)?.cm
|
||||
];
|
||||
|
||||
for (let i = 0; i < possiblePaths.length; i++) {
|
||||
const path = possiblePaths[i];
|
||||
if (path && !this.cmEditor) {
|
||||
this.cmEditor = path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const possiblePaths = [
|
||||
(view as any).sourceMode?.cmEditor,
|
||||
(view as any).editor?.cm,
|
||||
(view.editor as any)?.cm
|
||||
];
|
||||
|
||||
for (let i = 0; i < possiblePaths.length; i++) {
|
||||
const path = possiblePaths[i];
|
||||
if (path && !this.cmEditor) {
|
||||
this.cmEditor = path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setupVimModePolling() {
|
||||
// 防止重复设置轮询
|
||||
if ((this as any).vimModePollingInterval) {
|
||||
clearInterval((this as any).vimModePollingInterval);
|
||||
}
|
||||
|
||||
let lastMode = "";
|
||||
const pollInterval = setInterval(() => {
|
||||
if (!this.cmEditor) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const realCM = (this.cmEditor as any).cm;
|
||||
const currentMode = realCM?.state?.vim?.mode || "";
|
||||
|
||||
if (currentMode && currentMode !== lastMode) {
|
||||
this.onVimModeChange({ mode: currentMode });
|
||||
lastMode = currentMode;
|
||||
}
|
||||
} catch (error) {
|
||||
// 忽略轮询错误
|
||||
}
|
||||
}, 100);
|
||||
|
||||
(this as any).vimModePollingInterval = pollInterval;
|
||||
}
|
||||
|
||||
setupObsidianEditorEvents() {
|
||||
if (this.keyboardListenerSetup) {
|
||||
return;
|
||||
}
|
||||
|
||||
const handleKeyDown = async (event: KeyboardEvent) => {
|
||||
const currentTime = Date.now();
|
||||
|
||||
// 防抖:100ms内只处理一次
|
||||
if (currentTime - this.lastKeyTime < 100) {
|
||||
return;
|
||||
}
|
||||
this.lastKeyTime = currentTime;
|
||||
|
||||
// 处理ESC键:退出到normal模式
|
||||
if (event.key === 'Escape') {
|
||||
// 退出insert模式前,先保存当前输入法状态
|
||||
const beforeIM = await this.runCmd(this.fcitxRemotePath, ["-n"]);
|
||||
const currentIMName = beforeIM.trim();
|
||||
|
||||
// 检查当前输入法是中文还是英文
|
||||
if (currentIMName === this.settings.chineseInputMethod) {
|
||||
this.lastInsertModeIMStatus = IMStatus.Activate;
|
||||
console.log('🔤 [VimIMSwitch] ESC → English (saved Chinese)');
|
||||
} else {
|
||||
this.lastInsertModeIMStatus = IMStatus.Deactivate;
|
||||
console.log('🔤 [VimIMSwitch] ESC → English (saved English)');
|
||||
}
|
||||
|
||||
// 切换到英文输入法
|
||||
this.currentVimMode = 'normal';
|
||||
await this.deactivateIM();
|
||||
}
|
||||
// 处理进入insert模式的按键(只在normal模式下)
|
||||
else if (this.currentVimMode === 'normal' &&
|
||||
['i', 'I', 'a', 'A', 'o', 'O', 's', 'S', 'c', 'C'].includes(event.key) &&
|
||||
!event.ctrlKey && !event.metaKey && !event.altKey) {
|
||||
// 延迟一下,让Vim先切换模式
|
||||
setTimeout(async () => {
|
||||
this.currentVimMode = 'insert';
|
||||
// 恢复上次的输入法状态
|
||||
if (this.lastInsertModeIMStatus == IMStatus.Activate) {
|
||||
console.log("🈳 [VimIMSwitch] → Chinese");
|
||||
await this.activateIM();
|
||||
} else {
|
||||
console.log("🔤 [VimIMSwitch] → English");
|
||||
await this.deactivateIM();
|
||||
}
|
||||
}, 10);
|
||||
}
|
||||
};
|
||||
|
||||
// 移除旧的监听器
|
||||
if ((this as any).obsidianKeyDownListener) {
|
||||
document.removeEventListener('keydown', (this as any).obsidianKeyDownListener, { capture: true });
|
||||
}
|
||||
|
||||
// 使用capture模式确保更早接收事件
|
||||
(this as any).obsidianKeyDownListener = handleKeyDown;
|
||||
document.addEventListener('keydown', handleKeyDown, { capture: true });
|
||||
|
||||
this.keyboardListenerSetup = true;
|
||||
}
|
||||
|
||||
onVimModeChange = async (cm: any) => {
|
||||
// 防止短时间内重复处理相同的模式切换
|
||||
const currentTime = Date.now();
|
||||
if (cm.mode === this.currentVimMode && currentTime - this.lastKeyTime < 100) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新当前vim模式状态
|
||||
this.currentVimMode = cm.mode;
|
||||
|
||||
if (cm.mode == "normal" || cm.mode == "visual") {
|
||||
// 进入normal/visual模式前,先保存当前输入法状态
|
||||
await this.getFcitxRemoteStatus();
|
||||
if (this.imStatus == IMStatus.Activate) {
|
||||
this.lastInsertModeIMStatus = IMStatus.Activate;
|
||||
}
|
||||
console.log("🔤 [VimIMSwitch] → English");
|
||||
await this.deactivateIM();
|
||||
} else if (cm.mode == "insert" || cm.mode == "replace") {
|
||||
// 进入insert模式时,恢复上次的输入法状态
|
||||
if (this.lastInsertModeIMStatus == IMStatus.Activate) {
|
||||
console.log("🈳 [VimIMSwitch] → Chinese");
|
||||
await this.activateIM();
|
||||
} else {
|
||||
console.log("🔤 [VimIMSwitch] → English");
|
||||
await this.deactivateIM();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async runCmd(cmd: string, args: string[] = []) : Promise<string>{
|
||||
const output = await pexec(`${cmd} ${args.join(" ")}`);
|
||||
return output.stdout;
|
||||
}
|
||||
|
||||
async getFcitxRemoteStatus() {
|
||||
if (this.fcitxRemotePath == "") {
|
||||
console.log("❌ [VimIMSwitch] Cannot get fcitx-remote path, please set it correctly.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let fcitxRemoteOutput = await this.runCmd(this.fcitxRemotePath);
|
||||
fcitxRemoteOutput = fcitxRemoteOutput.trimRight();
|
||||
|
||||
if (fcitxRemoteOutput == "1") {
|
||||
this.imStatus = IMStatus.Deactivate;
|
||||
} else if (fcitxRemoteOutput == "2") {
|
||||
this.imStatus = IMStatus.Activate;
|
||||
} else {
|
||||
this.imStatus = IMStatus.None;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(`❌ [VimIMSwitch] Error getting IM status:`, error);
|
||||
}
|
||||
}
|
||||
async activateIM() {
|
||||
if (this.fcitxRemotePath == "") {
|
||||
console.log("❌ [VimIMSwitch] Cannot get fcitx-remote path, please set it correctly.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await this.runCmd(this.fcitxRemotePath, ["-s", this.settings.chineseInputMethod]);
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
} catch (error) {
|
||||
console.log("❌ [VimIMSwitch] Error activating IM:", error);
|
||||
}
|
||||
}
|
||||
async deactivateIM() {
|
||||
if (this.fcitxRemotePath == "") {
|
||||
console.log("❌ [VimIMSwitch] Cannot get fcitx-remote path, please set it correctly.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await this.runCmd(this.fcitxRemotePath, ["-s", this.settings.englishInputMethod]);
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
} catch (error) {
|
||||
console.log("❌ [VimIMSwitch] Error deactivating IM:", error);
|
||||
}
|
||||
}
|
||||
|
||||
onunload() {
|
||||
// 清理 CodeMirror 事件监听器
|
||||
if (this.cmEditor && typeof this.cmEditor.off === 'function') {
|
||||
this.cmEditor.off("vim-mode-change", this.onVimModeChange);
|
||||
}
|
||||
|
||||
// 清理轮询定时器
|
||||
if ((this as any).vimModePollingInterval) {
|
||||
clearInterval((this as any).vimModePollingInterval);
|
||||
}
|
||||
|
||||
// 清理键盘事件监听器
|
||||
if ((this as any).obsidianKeyDownListener) {
|
||||
document.removeEventListener('keydown', (this as any).obsidianKeyDownListener, { capture: true });
|
||||
this.keyboardListenerSetup = false;
|
||||
}
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
await this.updateCurrentPath();
|
||||
await this.detectInputMethods();
|
||||
}
|
||||
|
||||
async detectInputMethods() {
|
||||
if (this.settings.chineseInputMethod === 'auto-detect') {
|
||||
try {
|
||||
const currentIM = await this.runCmd(this.fcitxRemotePath, ["-n"]);
|
||||
const currentName = currentIM.trim();
|
||||
|
||||
if (currentName.includes('pinyin') ||
|
||||
currentName.includes('chinese') ||
|
||||
currentName.includes('tencent') ||
|
||||
currentName.includes('sogou') ||
|
||||
currentName.includes('baidu')) {
|
||||
this.settings.chineseInputMethod = currentName;
|
||||
} else {
|
||||
this.settings.chineseInputMethod = 'com.tencent.inputmethod.wetype.pinyin';
|
||||
}
|
||||
} catch (error) {
|
||||
this.settings.chineseInputMethod = 'com.tencent.inputmethod.wetype.pinyin';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async updateCurrentPath() {
|
||||
console.log(`🖥️ [VimIMSwitch] Platform detected: ${process.platform}`);
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
this.fcitxRemotePath = this.settings.fcitxRemotePath_macOS;
|
||||
console.log(`🍎 [VimIMSwitch] Using macOS path: ${this.fcitxRemotePath}`);
|
||||
break;
|
||||
case 'linux':
|
||||
this.fcitxRemotePath = this.settings.fcitxRemotePath_linux;
|
||||
console.log(`🐧 [VimIMSwitch] Using Linux path: ${this.fcitxRemotePath}`);
|
||||
break;
|
||||
case 'win32':
|
||||
this.fcitxRemotePath = this.settings.fcitxRemotePath_windows;
|
||||
console.log(`🪟 [VimIMSwitch] Using Windows path: ${this.fcitxRemotePath}`);
|
||||
break;
|
||||
default:
|
||||
console.log(`❌ [VimIMSwitch] Platform ${process.platform} is not supported currently.`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
}
|
||||
}
|
||||
|
||||
class IMSwitchSettingTab extends PluginSettingTab {
|
||||
plugin: VimIMSwitchPlugin;
|
||||
|
||||
constructor(app: App, plugin: VimIMSwitchPlugin) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
display(): void {
|
||||
let {containerEl} = this;
|
||||
|
||||
containerEl.empty();
|
||||
|
||||
containerEl.createEl('h2', {text: 'Settings for Vim IM Switch plugin.'});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Fcitx Remote Path for macOS')
|
||||
.setDesc('The absolute path to fcitx-remote bin file on macOS.')
|
||||
.addText(text => text
|
||||
.setPlaceholder(DEFAULT_SETTINGS.fcitxRemotePath_macOS)
|
||||
.setValue(this.plugin.settings.fcitxRemotePath_macOS)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.fcitxRemotePath_macOS = value;
|
||||
this.plugin.updateCurrentPath();
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new Setting(containerEl)
|
||||
.setName('Fcitx Remote Path for Linux')
|
||||
.setDesc('The absolute path to fcitx-remote bin file on Linux.')
|
||||
.addText(text => text
|
||||
.setPlaceholder(DEFAULT_SETTINGS.fcitxRemotePath_linux)
|
||||
.setValue(this.plugin.settings.fcitxRemotePath_linux)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.fcitxRemotePath_linux = value;
|
||||
this.plugin.updateCurrentPath();
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new Setting(containerEl)
|
||||
.setName('Fcitx Remote Path for Windows')
|
||||
.setDesc('The absolute path to fcitx-remote bin file on Windows.')
|
||||
.addText(text => text
|
||||
.setPlaceholder(DEFAULT_SETTINGS.fcitxRemotePath_windows)
|
||||
.setValue(this.plugin.settings.fcitxRemotePath_windows)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.fcitxRemotePath_windows = value;
|
||||
this.plugin.updateCurrentPath();
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
}
|
||||
}
|
||||
10
manifest.json
Normal file
10
manifest.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"id": "obsidian-vim-im-switch-plugin",
|
||||
"name": "Vim Input Method Switch",
|
||||
"version": "1.0.8",
|
||||
"minAppVersion": "0.9.12",
|
||||
"description": "Switch input method with fcitx-remote when Vim keymap is enabled.",
|
||||
"author": "Yuan Chen",
|
||||
"authorUrl": "https://github.com/yuanotes",
|
||||
"isDesktopOnly": true
|
||||
}
|
||||
510
package-lock.json
generated
Normal file
510
package-lock.json
generated
Normal file
@@ -0,0 +1,510 @@
|
||||
{
|
||||
"name": "obsidian-vim-im-switch-plugin",
|
||||
"version": "0.12.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "obsidian-vim-im-switch-plugin",
|
||||
"version": "0.12.0",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^18.0.0",
|
||||
"@rollup/plugin-node-resolve": "^11.2.1",
|
||||
"@rollup/plugin-typescript": "^8.2.1",
|
||||
"@types/node": "^14.14.37",
|
||||
"obsidian": "^0.12.0",
|
||||
"rollup": "^2.32.1",
|
||||
"tslib": "^2.2.0",
|
||||
"typescript": "^4.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-commonjs": {
|
||||
"version": "18.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-18.1.0.tgz",
|
||||
"integrity": "sha512-h3e6T9rUxVMAQswpDIobfUHn/doMzM9sgkMrsMWCFLmB84PSoC8mV8tOloAJjSRwdqhXBqstlX2BwBpHJvbhxg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^3.1.0",
|
||||
"commondir": "^1.0.1",
|
||||
"estree-walker": "^2.0.1",
|
||||
"glob": "^7.1.6",
|
||||
"is-reference": "^1.2.1",
|
||||
"magic-string": "^0.25.7",
|
||||
"resolve": "^1.17.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.30.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-node-resolve": {
|
||||
"version": "11.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz",
|
||||
"integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^3.1.0",
|
||||
"@types/resolve": "1.17.1",
|
||||
"builtin-modules": "^3.1.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"is-module": "^1.0.0",
|
||||
"resolve": "^1.19.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-typescript": {
|
||||
"version": "8.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.5.0.tgz",
|
||||
"integrity": "sha512-wMv1/scv0m/rXx21wD2IsBbJFba8wGF3ErJIr6IKRfRj49S85Lszbxb4DCo8iILpluTjk2GAAu9CoZt4G3ppgQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^3.1.0",
|
||||
"resolve": "^1.17.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.14.0",
|
||||
"tslib": "*",
|
||||
"typescript": ">=3.7.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"tslib": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/pluginutils": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
|
||||
"integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "0.0.39",
|
||||
"estree-walker": "^1.0.1",
|
||||
"picomatch": "^2.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/pluginutils/node_modules/estree-walker": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
|
||||
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/codemirror": {
|
||||
"version": "0.0.108",
|
||||
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.108.tgz",
|
||||
"integrity": "sha512-3FGFcus0P7C2UOGCNUVENqObEb4SFk+S8Dnxq7K6aIsLVs/vDtlangl3PEO0ykaKXyK56swVF6Nho7VsA44uhw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/tern": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "0.0.39",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
|
||||
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "14.18.63",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz",
|
||||
"integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/resolve": {
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
||||
"integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/tern": {
|
||||
"version": "0.23.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz",
|
||||
"integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/builtin-modules": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
|
||||
"integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/commondir": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
||||
"integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.16.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
||||
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-reference": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
|
||||
"integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.25.9",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
|
||||
"integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"sourcemap-codec": "^1.4.8"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/obsidian": {
|
||||
"version": "0.12.17",
|
||||
"resolved": "https://registry.npmjs.org/obsidian/-/obsidian-0.12.17.tgz",
|
||||
"integrity": "sha512-YvCAlRym9D8zNPXt6Ez8QubSTVGoChx6lb58zqI13Dcrz3l1lgUO+pcOGDiD5Qa67nzDZLXo3aV2rqkCCpTvGQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/codemirror": "0.0.108",
|
||||
"moment": "2.29.1"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.11",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
|
||||
"integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.16.1",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"resolve": "bin/resolve"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "2.79.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
|
||||
"integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/sourcemap-codec": {
|
||||
"version": "1.4.8",
|
||||
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
|
||||
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
|
||||
"deprecated": "Please use @jridgewell/sourcemap-codec instead",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"dev": true,
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "4.9.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
}
|
||||
}
|
||||
}
|
||||
23
package.json
Normal file
23
package.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "obsidian-vim-im-switch-plugin",
|
||||
"version": "0.12.0",
|
||||
"description": "This is a plugin for Obsidian (https://obsidian.md). Switch input method with fcitx-remote when Vim keymap is enabled.",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dev": "rollup --config rollup.config.js -w",
|
||||
"build": "rollup --config rollup.config.js --environment BUILD:production"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^18.0.0",
|
||||
"@rollup/plugin-node-resolve": "^11.2.1",
|
||||
"@rollup/plugin-typescript": "^8.2.1",
|
||||
"@types/node": "^14.14.37",
|
||||
"obsidian": "^0.12.0",
|
||||
"rollup": "^2.32.1",
|
||||
"tslib": "^2.2.0",
|
||||
"typescript": "^4.2.4"
|
||||
}
|
||||
}
|
||||
30
rollup.config.js
Normal file
30
rollup.config.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import typescript from '@rollup/plugin-typescript';
|
||||
import {nodeResolve} from '@rollup/plugin-node-resolve';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
|
||||
const isProd = (process.env.BUILD === 'production');
|
||||
|
||||
const banner =
|
||||
`/*
|
||||
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
|
||||
if you want to view the source visit the plugins github repository
|
||||
*/
|
||||
`;
|
||||
|
||||
export default {
|
||||
input: 'main.ts',
|
||||
output: {
|
||||
dir: '.',
|
||||
sourcemap: 'inline',
|
||||
sourcemapExcludeSources: isProd,
|
||||
format: 'cjs',
|
||||
exports: 'default',
|
||||
banner,
|
||||
},
|
||||
external: ['obsidian'],
|
||||
plugins: [
|
||||
typescript(),
|
||||
nodeResolve({browser: true}),
|
||||
commonjs(),
|
||||
]
|
||||
};
|
||||
2
styles.css
Normal file
2
styles.css
Normal file
@@ -0,0 +1,2 @@
|
||||
body {
|
||||
}
|
||||
22
tsconfig.json
Normal file
22
tsconfig.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"inlineSourceMap": true,
|
||||
"inlineSources": true,
|
||||
"module": "ESNext",
|
||||
"target": "es6",
|
||||
"allowJs": true,
|
||||
"noImplicitAny": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"lib": [
|
||||
"dom",
|
||||
"es5",
|
||||
"scripthost",
|
||||
"es2015"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
]
|
||||
}
|
||||
5
versions.json
Normal file
5
versions.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"1.0.2": "0.9.12",
|
||||
"1.0.1": "0.9.12",
|
||||
"1.0.0": "0.9.7"
|
||||
}
|
||||
Reference in New Issue
Block a user