mirror of
https://github.com/d0zingcat/rime_wanxiang.git
synced 2026-05-13 15:10:03 +00:00
chore:新的根节点
This commit is contained in:
36
.github/workflows/release-build.yml
vendored
Normal file
36
.github/workflows/release-build.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: Wanxiang Schema Builds
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
inputs:
|
||||
tag:
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
release-build:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
- name: Release build
|
||||
run: bash .github/workflows/scripts/release-build.sh
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: rime-wanxiang-dist-${{ github.ref_name }}
|
||||
if-no-files-found: error
|
||||
path: dist/rime-wanxiang-*.zip
|
||||
73
.github/workflows/release.yml
vendored
Normal file
73
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- wanxiang
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
issues: write
|
||||
|
||||
name: Release
|
||||
|
||||
jobs:
|
||||
release-please:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: googleapis/release-please-action@v4
|
||||
id: release
|
||||
|
||||
- name: Checkout repository
|
||||
if: ${{ steps.release.outputs.release_created }}
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Release edit to draft
|
||||
if: ${{ steps.release.outputs.release_created }}
|
||||
run: |
|
||||
gh release edit ${TAG_VERSION} --draft
|
||||
env:
|
||||
TAG_VERSION: ${{ steps.release.outputs.tag_name }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
|
||||
outputs:
|
||||
release_created: ${{ steps.release.outputs.release_created }}
|
||||
release_tag_name: ${{ steps.release.outputs.tag_name }}
|
||||
|
||||
release-build:
|
||||
needs: [release-please]
|
||||
if: needs.release-please.outputs.release_created == 'true'
|
||||
name: Release build
|
||||
uses: ./.github/workflows/release-build.yml
|
||||
permissions:
|
||||
contents: write
|
||||
secrets: inherit
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [release-please, release-build]
|
||||
name: Release
|
||||
env:
|
||||
TAG_VERSION: ${{ needs.release-please.outputs.release_tag_name }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download build
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: rime-wanxiang-dist-${{ github.ref_name }}
|
||||
path: ~/artifact
|
||||
|
||||
- name: Update release
|
||||
run: |
|
||||
# 更新 release title
|
||||
gh release edit ${TAG_VERSION} --title "${TAG_VERSION} Rime万象拼音输入方案"
|
||||
# 更新 release note
|
||||
bash .github/workflows/scripts/generate-release-note.sh
|
||||
gh release edit ${TAG_VERSION} --notes-file ./release_notes.md
|
||||
# 更新 Assets
|
||||
gh release upload ${TAG_VERSION} ~/artifact/rime-wanxiang-*.zip
|
||||
# 正式发布
|
||||
gh release edit ${TAG_VERSION} --draft=false --latest
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
295
.github/workflows/releases-napshot.yml
vendored
Normal file
295
.github/workflows/releases-napshot.yml
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
name: Build release branch snapshot
|
||||
|
||||
on:
|
||||
workflow_dispatch: # 手动触发
|
||||
push:
|
||||
branches:
|
||||
- wanxiang
|
||||
|
||||
concurrency:
|
||||
group: release-branch
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-release:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
- name: Release build
|
||||
run: bash .github/workflows/scripts/release-build.sh
|
||||
|
||||
# 1. 用 dist/ 里的产物拼出 snapshot 目录
|
||||
- name: Prepare snapshot tree from dist
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
rm -rf snapshot
|
||||
mkdir -p snapshot
|
||||
|
||||
# 使用 dist/ 里的目录构建 snapshot
|
||||
if ls dist/rime-wanxiang-* 1> /dev/null 2>&1; then
|
||||
for d in dist/rime-wanxiang-*; do
|
||||
[ -d "$d" ] || continue
|
||||
name="$(basename "$d")"
|
||||
echo "Copying directory $d -> snapshot/$name"
|
||||
mkdir -p "snapshot/$name"
|
||||
cp -a "$d"/. "snapshot/$name"/
|
||||
done
|
||||
else
|
||||
echo "Error: no dist/rime-wanxiang-* directories found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Snapshot tree after prepare:"
|
||||
ls -R snapshot || true
|
||||
|
||||
# 2. 检查这次提交是否修改了 dicts 相关文件(控制 3/4/5 是否执行)
|
||||
- name: Check if dicts changed
|
||||
id: dicts_changed
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
# 手动触发(workflow_dispatch)直接视为「有变动」,强制跑
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 找到上一条提交(第一次提交可能没有 HEAD^,单独处理)
|
||||
if git rev-parse HEAD^ >/dev/null 2>&1; then
|
||||
RANGE="HEAD^ HEAD"
|
||||
else
|
||||
echo "Only one commit, treat as changed."
|
||||
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 检查本次改动的文件里有没有命中 dicts 目录
|
||||
if git diff --name-only $RANGE | grep -E '(^dicts/|^rime-wanxiang-.*/dicts/)' >/dev/null 2>&1; then
|
||||
echo "dicts changed."
|
||||
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "dicts not changed."
|
||||
echo "changed=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
# 3. 从 dist 中打出每夜词库 zip(不套文件夹,只打 dicts/**)
|
||||
- name: Pack nightly dict zips
|
||||
if: steps.dicts_changed.outputs.changed == 'true'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
mkdir -p dist
|
||||
|
||||
pack_dict() {
|
||||
local src="$1"
|
||||
local zip_name="$2"
|
||||
if [[ -d "$src" ]]; then
|
||||
echo "Packing $src -> dist/${zip_name}"
|
||||
(cd "$src" && zip -r -q "../../${zip_name}" .)
|
||||
else
|
||||
echo "Warning: $src does not exist, skipped."
|
||||
fi
|
||||
}
|
||||
|
||||
pack_dict "dist/rime-wanxiang-moqi-fuzhu/dicts" "pro-moqi-fuzhu-dicts.zip"
|
||||
pack_dict "dist/rime-wanxiang-flypy-fuzhu/dicts" "pro-flypy-fuzhu-dicts.zip"
|
||||
pack_dict "dist/rime-wanxiang-zrm-fuzhu/dicts" "pro-zrm-fuzhu-dicts.zip"
|
||||
pack_dict "dist/rime-wanxiang-tiger-fuzhu/dicts" "pro-tiger-fuzhu-dicts.zip"
|
||||
pack_dict "dist/rime-wanxiang-wubi-fuzhu/dicts" "pro-wubi-fuzhu-dicts.zip"
|
||||
pack_dict "dist/rime-wanxiang-hanxin-fuzhu/dicts" "pro-hanxin-fuzhu-dicts.zip"
|
||||
pack_dict "dist/rime-wanxiang-shouyou-fuzhu/dicts" "pro-shouyou-fuzhu-dicts.zip"
|
||||
pack_dict "dist/rime-wanxiang-base/dicts" "base-dicts.zip"
|
||||
|
||||
echo "Nightly dict zips in dist/:"
|
||||
ls -1 dist/*.zip || true
|
||||
|
||||
# 4. 删除旧的 Nightly Release 和 Tag
|
||||
- name: Delete existing Nightly Release and Tag
|
||||
if: steps.dicts_changed.outputs.changed == 'true'
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const tag = "dict-nightly";
|
||||
try {
|
||||
const releases = await github.rest.repos.listReleases({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo
|
||||
});
|
||||
const existingRelease = releases.data.find(r => r.tag_name === tag);
|
||||
if (existingRelease) {
|
||||
console.log(`Deleting existing Release with ID: ${existingRelease.id}`);
|
||||
await github.rest.repos.deleteRelease({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
release_id: existingRelease.id
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`Deleting tag: ${tag}`);
|
||||
await github.rest.git.deleteRef({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
ref: `tags/${tag}`
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(`Error deleting Release or Tag: ${error.message}`);
|
||||
}
|
||||
|
||||
- name: Wait for cleanup
|
||||
if: steps.dicts_changed.outputs.changed == 'true'
|
||||
run: sleep 10
|
||||
|
||||
# 5. 创建新的 Nightly Release,上传词库 zips
|
||||
- name: Create dict-nightly Release
|
||||
if: steps.dicts_changed.outputs.changed == 'true'
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag_name: dict-nightly
|
||||
name: "实时提交的词库更新"
|
||||
body: |
|
||||
- **base-dicts.zip**:最新的标准版原始中文词库文件
|
||||
- **pro-moqi-fuzhu-dicts.zip**:携带了墨奇辅助码的词库文件
|
||||
- **pro-flypy-fuzhu-dicts.zip**:携带了小鹤辅助码的词库文件
|
||||
- **pro-zrm-fuzhu-dicts.zip**:携带了自然码辅助码的词库文件
|
||||
- **pro-tiger-fuzhu-dicts.zip**:携带了虎码辅助码的词库文件
|
||||
- **pro-wubi-fuzhu-dicts.zip**:携带了五笔辅助码的词库文件
|
||||
- **pro-hanxin-fuzhu-dicts.zip**:携带了汉心辅助码的词库文件
|
||||
- **pro-shouyou-fuzhu-dicts.zip**:携带了首右辅助码的词库文件
|
||||
- **[wanxiang-lts-zh-hans.gram](https://github.com/amzxyz/RIME-LMDG/releases/download/LTS/wanxiang-lts-zh-hans.gram)**:与词库同步更新的语法模型
|
||||
files: |
|
||||
dist/pro-moqi-fuzhu-dicts.zip
|
||||
dist/pro-flypy-fuzhu-dicts.zip
|
||||
dist/pro-zrm-fuzhu-dicts.zip
|
||||
dist/pro-tiger-fuzhu-dicts.zip
|
||||
dist/pro-wubi-fuzhu-dicts.zip
|
||||
dist/pro-hanxin-fuzhu-dicts.zip
|
||||
dist/pro-shouyou-fuzhu-dicts.zip
|
||||
dist/base-dicts.zip
|
||||
draft: false
|
||||
prerelease: false
|
||||
make_latest: true
|
||||
|
||||
# 6. 为每个方案生成独立分支:wanxiang-base / wanxiang-moqi-fuzhu / ...
|
||||
- name: Commit and force push per-scheme snapshots
|
||||
env:
|
||||
GIT_AUTHOR_NAME: ci-bot
|
||||
GIT_AUTHOR_EMAIL: ci@example.com
|
||||
GIT_COMMITTER_NAME: ci-bot
|
||||
GIT_COMMITTER_EMAIL: ci@example.com
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
# 当前开发分支(通常是 wanxiang)
|
||||
ORIG_BRANCH="$(git rev-parse --abbrev-ref HEAD || echo 'wanxiang')"
|
||||
|
||||
# 方案列表
|
||||
schemes=("base" "shouyou-fuzhu" "zrm-fuzhu" "tiger-fuzhu" "moqi-fuzhu" "flypy-fuzhu" "wubi-fuzhu" "hanxin-fuzhu")
|
||||
|
||||
# 每个方案公共文件清单(在分支根目录使用)
|
||||
COMMON_FILES=(
|
||||
"dicts/*.*"
|
||||
"opencc/*.*"
|
||||
"custom/*.*"
|
||||
"lua/*.*"
|
||||
"lua/lib/*.*"
|
||||
"lua/tips/*.*"
|
||||
"default.yaml"
|
||||
"weasel.yaml"
|
||||
"wanxiang*.*yaml"
|
||||
"README.md"
|
||||
"简纯+.trime.yaml"
|
||||
"custom_phrase.txt"
|
||||
)
|
||||
|
||||
TAG_NAME="${{ github.event_name == 'release' && github.event.release.tag_name || 'manual-build' }}"
|
||||
|
||||
for scheme in "${schemes[@]}"; do
|
||||
branch="wanxiang-${scheme}" # 分支名:wanxiang-moqi-fuzhu
|
||||
src_dir="snapshot/rime-wanxiang-${scheme}" # 每个方案的源码目录(来自 snapshot)
|
||||
|
||||
echo "=== Building branch ${branch} from ${src_dir} ==="
|
||||
|
||||
if [ ! -d "${src_dir}" ]; then
|
||||
echo "Warning: ${src_dir} not found, skip ${branch}."
|
||||
continue
|
||||
fi
|
||||
|
||||
# 切换/创建分支
|
||||
if git show-ref --verify --quiet "refs/heads/${branch}"; then
|
||||
git checkout "${branch}"
|
||||
else
|
||||
git checkout --orphan "${branch}"
|
||||
fi
|
||||
|
||||
# 清空当前工作区(仅保留 .git 和 snapshot)
|
||||
find . -mindepth 1 -maxdepth 1 ! -name ".git" ! -name "snapshot" -exec rm -rf {} +
|
||||
|
||||
# 把这个方案的内容「拍扁」到分支根目录(不保留 rime-wanxiang-xxx 那一层)
|
||||
cp -a "${src_dir}"/. .
|
||||
|
||||
# 在这个分支里生成自己的 plum 配方
|
||||
mkdir -p plum
|
||||
|
||||
#################################
|
||||
# 生成 plum/full.recipe.yaml
|
||||
#################################
|
||||
{
|
||||
echo "# encoding: utf-8"
|
||||
echo "---"
|
||||
echo "recipe:"
|
||||
echo " Rx: plum/full"
|
||||
echo " args:"
|
||||
echo " description: >-"
|
||||
echo " 万象拼音 ${scheme} 版(整个方案目录)- 分支 ${branch}"
|
||||
echo "install_files: >-"
|
||||
for path in "${COMMON_FILES[@]}"; do
|
||||
echo " ${path}"
|
||||
done
|
||||
} > "plum/full.recipe.yaml"
|
||||
|
||||
#################################
|
||||
# 生成 plum/dicts.recipe.yaml
|
||||
#################################
|
||||
{
|
||||
echo "# encoding: utf-8"
|
||||
echo "---"
|
||||
echo "recipe:"
|
||||
echo " Rx: plum/dicts"
|
||||
echo " args:"
|
||||
echo " description: >-"
|
||||
echo " 万象拼音 ${scheme} 版,仅词库(dicts-only)- 分支 ${branch}"
|
||||
echo "install_files: >-"
|
||||
echo " dicts/*.*"
|
||||
} > "plum/dicts.recipe.yaml"
|
||||
|
||||
git status
|
||||
|
||||
# 注意:不要把 snapshot/ 提交进去
|
||||
git add .
|
||||
git reset snapshot || true
|
||||
git rm -r --cached snapshot 2>/dev/null || true
|
||||
|
||||
git commit -m "chore(${branch}): snapshot for ${TAG_NAME}" \
|
||||
|| echo "Nothing to commit for ${branch}."
|
||||
|
||||
git push -f origin "${branch}"
|
||||
done
|
||||
|
||||
# 回到原来的开发分支,并清掉 snapshot(只删 CI 本地)
|
||||
git checkout "${ORIG_BRANCH}" || true
|
||||
rm -rf snapshot
|
||||
197
.github/workflows/scripts/aux_go.py
vendored
Normal file
197
.github/workflows/scripts/aux_go.py
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
import os
|
||||
import re
|
||||
|
||||
# ---------- 在第一个点前插入后缀(例:base.dict.yaml -> base.pro.dict.yaml) ----------
|
||||
def add_suffix_before_extensions(filename: str, suffix: str) -> str:
|
||||
if not suffix:
|
||||
return filename
|
||||
i = filename.find('.')
|
||||
return (filename + suffix) if i == -1 else (filename[:i] + suffix + filename[i:])
|
||||
|
||||
# ========== 1) 从“单个 aux 文件”加载 字 -> 辅助码段列表 ==========
|
||||
# 行格式:字<TAB>;段1;段2;... (保留空段,不偏移;段内逗号原样保留)
|
||||
def load_aux_table(aux_file_path):
|
||||
if not os.path.isfile(aux_file_path):
|
||||
raise FileNotFoundError(f"aux 文件不存在:{aux_file_path}")
|
||||
aux_map = {}
|
||||
print(f'加载辅助码表文件: {os.path.basename(aux_file_path)}')
|
||||
with open(aux_file_path, 'r', encoding='utf-8') as f:
|
||||
for raw in f:
|
||||
line = raw.strip()
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
parts = line.split('\t')
|
||||
if len(parts) < 2:
|
||||
continue
|
||||
ch = parts[0]
|
||||
aux_list = parts[1].split(';') # 保留空串占位(分号才是边界)
|
||||
aux_map[ch] = aux_list
|
||||
return aux_map
|
||||
|
||||
# ========== 2) 区间选择(严格:第 N 段 = aux_list[N];N 从 1 起)==========
|
||||
# 不处理逗号:分号窗口原样拼接
|
||||
def select_aux_segment(aux_list, start_idx, end_idx=None):
|
||||
if not aux_list:
|
||||
return ''
|
||||
s = max(1, start_idx)
|
||||
e = end_idx if end_idx is not None else len(aux_list)
|
||||
e = max(s, min(e, len(aux_list)))
|
||||
window = aux_list[s:e] # 允许空段
|
||||
return ''.join(window) if window else ''
|
||||
|
||||
DIGIT_RE = re.compile(r'^\d+$')
|
||||
|
||||
# ========== 3) 处理单个词库(流式;空也占位“拼音;”)==========
|
||||
def process_file_for_range_streaming(in_file, out_file, aux_map, start_idx, end_idx, sep=';'):
|
||||
os.makedirs(os.path.dirname(out_file), exist_ok=True)
|
||||
try:
|
||||
fin = open(in_file, 'r', encoding='utf-8')
|
||||
except Exception as e:
|
||||
print(f'读取失败 {in_file}: {e}')
|
||||
return
|
||||
try:
|
||||
fout = open(out_file, 'w', encoding='utf-8')
|
||||
except Exception as e:
|
||||
fin.close()
|
||||
print(f'写入失败 {out_file}: {e}')
|
||||
return
|
||||
|
||||
passthrough_set = {
|
||||
"的\td\t1000",
|
||||
"了\tl\t999",
|
||||
"吗\tm\t999",
|
||||
"吧\tb\t999",
|
||||
}
|
||||
|
||||
processing = False
|
||||
for line in fin:
|
||||
if not processing:
|
||||
fout.write(line)
|
||||
if '...' in line:
|
||||
processing = True
|
||||
continue
|
||||
|
||||
raw = line.rstrip('\n')
|
||||
if (not raw) or raw.lstrip().startswith('#'):
|
||||
fout.write(line)
|
||||
continue
|
||||
|
||||
parts = raw.split('\t')
|
||||
if len(parts) == 1:
|
||||
fout.write(line)
|
||||
continue
|
||||
|
||||
han = parts[0]
|
||||
col2 = parts[1] if len(parts) > 1 else ''
|
||||
col3 = parts[2] if len(parts) > 2 else ''
|
||||
col4 = parts[3] if len(parts) > 3 else ''
|
||||
|
||||
# 第二列若是频率(全数字),挪到第三列
|
||||
if DIGIT_RE.fullmatch(col2 or ''):
|
||||
col3, col2 = col2, ''
|
||||
|
||||
# 特定行直通
|
||||
if raw.strip() in passthrough_set:
|
||||
fout.write(raw + '\n')
|
||||
continue
|
||||
|
||||
pinyins = col2.split(' ') if col2 else []
|
||||
if len(pinyins) != len(han):
|
||||
warn = f"# 警告: 拼音数与字数不匹配({in_file}) => {raw}"
|
||||
print(warn)
|
||||
fout.write(warn + '\n')
|
||||
continue
|
||||
|
||||
_get = aux_map.get
|
||||
new_cols = []
|
||||
for i, ch in enumerate(han):
|
||||
aux_list = _get(ch)
|
||||
piece = select_aux_segment(aux_list, start_idx, end_idx) if aux_list is not None else ''
|
||||
new_cols.append(pinyins[i] + sep + piece) # 空也占位:拼音;片段
|
||||
|
||||
new_col2 = ' '.join(new_cols)
|
||||
if col4:
|
||||
fout.write(f"{han}\t{new_col2}\t{col3}\t{col4}\n" if col3 else f"{han}\t{new_col2}\t\t{col4}\n")
|
||||
else:
|
||||
fout.write(f"{han}\t{new_col2}\t{col3}\n" if col3 else f"{han}\t{new_col2}\n")
|
||||
|
||||
fin.close()
|
||||
fout.close()
|
||||
print(f'已处理: {out_file}')
|
||||
|
||||
# ========== 4) 扫目录 + 六套区间(按白名单)==========
|
||||
def process_batch(input_dir, aux_file_path, base_out_dir, index_mapping, files_whitelist=None,
|
||||
sep=';', output_suffix=""):
|
||||
aux_map = load_aux_table(aux_file_path)
|
||||
print(f'已加载辅助码条目:{len(aux_map)}')
|
||||
|
||||
# 收集要处理的文件
|
||||
to_process = []
|
||||
for entry in os.scandir(input_dir):
|
||||
if not entry.is_file():
|
||||
continue
|
||||
name = entry.name
|
||||
if files_whitelist and name not in files_whitelist:
|
||||
continue
|
||||
if not (name.endswith('.yaml') or name.endswith('.yml') or name.endswith('.txt')):
|
||||
continue
|
||||
to_process.append(entry.path)
|
||||
|
||||
if not to_process:
|
||||
print("输入目录内没有匹配文件")
|
||||
return
|
||||
|
||||
for s_idx, e_idx, subdir in index_mapping:
|
||||
out_dir = os.path.join(base_out_dir, subdir)
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
print(f'\n=== 区间 ({s_idx}, {e_idx}) → {subdir} ===')
|
||||
for in_file in to_process:
|
||||
fn = os.path.basename(in_file)
|
||||
out_name = add_suffix_before_extensions(fn, output_suffix)
|
||||
out_file = os.path.join(out_dir, out_name)
|
||||
process_file_for_range_streaming(in_file, out_file, aux_map, s_idx, e_idx, sep=sep)
|
||||
|
||||
# ========== 5) 入口 ==========
|
||||
if __name__ == '__main__':
|
||||
# 六套区间(第 N 段,从 1 起)
|
||||
index_mapping = [
|
||||
(1, 2, "pro-moqi-fuzhu-dicts"),
|
||||
(2, 3, "pro-flypy-fuzhu-dicts"),
|
||||
(3, 4, "pro-zrm-fuzhu-dicts"),
|
||||
(4, 5, "pro-tiger-fuzhu-dicts"),
|
||||
(5, 6, "pro-wubi-fuzhu-dicts"),
|
||||
(6, 7, "pro-hanxin-fuzhu-dicts"),
|
||||
(7, None, "pro-shouyou-fuzhu-dicts"),
|
||||
]
|
||||
|
||||
# 路径
|
||||
AUX_FILE = "custom/aux_code.txt" # ← 单个 aux 文件
|
||||
INPUT_DIR = "dicts" # ← 词库文件夹
|
||||
OUT_ROOT = "." # ← 输出根目录
|
||||
|
||||
# 仅处理这些文件
|
||||
FILES = [
|
||||
"jichu.dict.yaml",
|
||||
"zi.dict.yaml",
|
||||
"duoyin.dict.yaml",
|
||||
"cuoyin.dict.yaml",
|
||||
"diming.dict.yaml",
|
||||
"shici.dict.yaml",
|
||||
"lianxiang.dict.yaml",
|
||||
"renming.dict.yaml",
|
||||
"wuzhong.dict.yaml",
|
||||
"shuxue.dict.yaml",
|
||||
"dikuang.dict.yaml",
|
||||
"wu-hua-sheng-yi-yao.dict.yaml",
|
||||
]
|
||||
|
||||
# 输出文件在第一个点前插这个后缀(如 ".pro";设为空串则不加)
|
||||
OUTPUT_SUFFIX = ".pro"
|
||||
|
||||
process_batch(
|
||||
INPUT_DIR, AUX_FILE, OUT_ROOT,
|
||||
index_mapping,
|
||||
files_whitelist=FILES,
|
||||
sep=';',
|
||||
output_suffix=OUTPUT_SUFFIX
|
||||
)
|
||||
78
.github/workflows/scripts/generate-release-note.sh
vendored
Normal file
78
.github/workflows/scripts/generate-release-note.sh
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# 声明辅助码 zip 包类型显示名
|
||||
declare -A display_names=(
|
||||
[zrm]="自然码"
|
||||
[moqi]="墨奇"
|
||||
[flypy]="小鹤"
|
||||
[hanxin]="汉心"
|
||||
[wubi]="五笔前2"
|
||||
[tiger]="虎码首末"
|
||||
[shouyou]="首右"
|
||||
)
|
||||
|
||||
# 仓库和下载地址定义
|
||||
REPO_URL=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}
|
||||
DOWNLOAD_URL=${REPO_URL}/releases/download/${TAG_VERSION}
|
||||
|
||||
# 获取 changelog(标题相同的 commit 合并链接)
|
||||
CHANGES=$(
|
||||
gh release view --json body -t "{{.body}}" "${TAG_VERSION}" | sed '1d; /./,$!d'
|
||||
)
|
||||
|
||||
{
|
||||
echo "## 📝 更新日志"
|
||||
echo ""
|
||||
echo "${CHANGES}"
|
||||
echo ""
|
||||
echo "## 🚀 下载引导"
|
||||
echo ""
|
||||
echo "### 1. 标准版输入方案"
|
||||
echo ""
|
||||
echo "✨**适用类型:** 支持全拼、各种双拼"
|
||||
echo ""
|
||||
echo "✨**下载地址:** [rime-wanxiang-base.zip](${DOWNLOAD_URL}/rime-wanxiang-base.zip)"
|
||||
echo ""
|
||||
echo "### 2. 双拼辅助码增强版输入方案"
|
||||
echo ""
|
||||
echo "✨**适用类型:** 支持各种双拼+辅助码的自由组合"
|
||||
|
||||
for type in "${!display_names[@]}"; do
|
||||
name="${display_names[$type]}"
|
||||
echo " - **${name}辅助版本:** [rime-wanxiang-${type}-fuzhu.zip](${DOWNLOAD_URL}/rime-wanxiang-${type}-fuzhu.zip)"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "### 3. 语法模型"
|
||||
echo ""
|
||||
echo "✨**适用类型:** 所有版本皆可用"
|
||||
echo ""
|
||||
echo "✨**下载地址:** [wanxiang-lts-zh-hans.gram](https://github.com/amzxyz/RIME-LMDG/releases/download/LTS/wanxiang-lts-zh-hans.gram)"
|
||||
echo ""
|
||||
echo "## 📘 使用说明(QQ群:11033572 参与讨论)"
|
||||
echo ""
|
||||
echo "1. **不使用辅助码的用户:**"
|
||||
echo ""
|
||||
echo " 请直接下载标准版,按仓库中的 [README.md](${REPO_URL}/blob/wanxiang/README.md) 配置使用。"
|
||||
echo ""
|
||||
echo "2. **使用增强版的用户:**"
|
||||
echo " - PRO 每一个 zip 是**完整独立配置包**,其差异仅在于词库是否带有特定辅助码。"
|
||||
echo ' - zrm 仅表示“词库中包含zrm辅助码”,并**不代表这是自然码双拼方案,万象支持任意双拼与任意辅助码组合使用**。'
|
||||
echo " - 若已有目标辅助码类型,只需下载对应 zip,解压后根据 README 中提示修改表头(例如双拼方案)即可使用。"
|
||||
echo ""
|
||||
echo "3. **语法模型需单独下载**,并放入输入法用户目录根目录(与方案文件放一起),**无需配置**。"
|
||||
echo ""
|
||||
echo "4. 💾 飞机盘下载地址(最快更新):[点击访问](https://share.feijipan.com/s/xiGvXdKz)"
|
||||
echo ""
|
||||
echo "5. Arch Linux 用户推荐 [启用 Arch Linux CN 仓库](https://www.archlinuxcn.org/archlinux-cn-repo-and-mirror/) 或通过 [AUR](https://aur.archlinux.org/pkgbase/rime-wanxiang),按需安装。"
|
||||
echo " - 基础版包名:\`rime-wanxiang-[拼写方案名]\`,如:自然码方案:\`rime-wanxiang-zrm\`"
|
||||
echo " - 双拼辅助码增强版包名:\`rime-wanxiang-pro-[拼写方案名]\`,如:自然码方案:\`rime-wanxiang-pro-zrm\`"
|
||||
echo "6. Deepin Linux v25 用户亦可以通过仓库进行安装。"
|
||||
echo "### 4. 周边推荐"
|
||||
echo " - [高度适配万象拼音的仓输入法皮肤](https://github.com/BlackCCCat/ResourceforHamster/tree/main/Skin_Keyboard/)"
|
||||
echo ""
|
||||
echo " - [好用的更新脚本,助你优雅管理版本](https://github.com/rimeinn/rime-wanxiang-update-tools)"
|
||||
echo ""
|
||||
echo " - [万象cnb仓库,无需梯子的类GitHub仓库国内平台](https://cnb.cool/amzxyz/rime-wanxiang)"
|
||||
} >release_notes.md
|
||||
152
.github/workflows/scripts/release-build.sh
vendored
Normal file
152
.github/workflows/scripts/release-build.sh
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
#!/bin/bash
|
||||
# 打包对用方案到 zip 文件,放到 dist 目录
|
||||
set -e
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/../../../" && pwd)"
|
||||
DIST_DIR="$ROOT_DIR/dist"
|
||||
CUSTOM_DIR="$ROOT_DIR/custom"
|
||||
|
||||
# 成成 PRO 分包文件
|
||||
echo "▶️ PRO 分包开始"
|
||||
python3 "$ROOT_DIR/.github/workflows/scripts/aux_go.py"
|
||||
echo "✅ PRO 分包完毕"
|
||||
echo
|
||||
|
||||
package_schema_base() {
|
||||
OUT_DIR=$1
|
||||
rm -rf "$OUT_DIR"
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
# 1) custom/:仅拷贝 yaml/md/jpg/png,排除指定文件(保留目录结构)
|
||||
mkdir -p "$OUT_DIR/custom"
|
||||
rsync -av --prune-empty-dirs \
|
||||
--include='*/' \
|
||||
--exclude='wanxiang_chaifen_*.dict.yaml' \
|
||||
--exclude='wanxiang_chaifen.schema.yaml' \
|
||||
--exclude='wanxiang_pro.custom.yaml' \
|
||||
--exclude='wanxiang_pro.dict.yaml' \
|
||||
--exclude='wanxiang_pro.schema.yaml' \
|
||||
--include='*.yaml' --include='*.md' --include='*.jpg' --include='*.png' \
|
||||
--exclude='*' \
|
||||
"$CUSTOM_DIR/" "$OUT_DIR/custom/"
|
||||
|
||||
# 2) 根目录 → $OUT_DIR(不排 dicts/),排除若干
|
||||
OUT_BASE="$(basename "$OUT_DIR")"
|
||||
rsync -av --ignore-existing \
|
||||
--exclude='/.*' \
|
||||
--exclude='/dist/' \
|
||||
--exclude='/release-please-config.json' \
|
||||
--exclude='/pro-*-fuzhu-dicts' \
|
||||
--exclude='/chaifen' \
|
||||
--exclude='/CHANGELOG.md' \
|
||||
--exclude='/custom' \
|
||||
--exclude='/LICENSE' \
|
||||
--exclude="/$OUT_BASE" \
|
||||
"$ROOT_DIR/" "$OUT_DIR/"
|
||||
}
|
||||
|
||||
package_schema_pro() {
|
||||
SCHEMA_NAME="$1"
|
||||
OUT_DIR="$2"
|
||||
rm -rf "$OUT_DIR"
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
# 1) 移动分包后的 dicts
|
||||
if [[ -d "$ROOT_DIR/pro-$SCHEMA_NAME-fuzhu-dicts" ]]; then
|
||||
mv "$ROOT_DIR/pro-$SCHEMA_NAME-fuzhu-dicts" "$OUT_DIR/dicts"
|
||||
fi
|
||||
# 1.1) 补充必要的附加文件
|
||||
for f in en.dict.yaml "cn&en.dict.yaml" chengyu.txt people.dict.yaml; do
|
||||
if [[ -f "$ROOT_DIR/dicts/$f" ]]; then
|
||||
cp "$ROOT_DIR/dicts/$f" "$OUT_DIR/dicts/"
|
||||
fi
|
||||
done
|
||||
|
||||
# 2) 复制拆分表并重命名,同时拷贝 schema
|
||||
src="$ROOT_DIR/custom/wanxiang_chaifen_${SCHEMA_NAME}.dict.yaml"
|
||||
dst="$OUT_DIR/wanxiang_chaifen.dict.yaml"
|
||||
[[ -f "$src" ]] && cp "$src" "$dst"
|
||||
|
||||
for f in \
|
||||
wanxiang_pro.dict.yaml \
|
||||
wanxiang_pro.schema.yaml \
|
||||
wanxiang_chaifen.schema.yaml
|
||||
do
|
||||
src="$ROOT_DIR/custom/$f"
|
||||
dst="$OUT_DIR/$f"
|
||||
[[ -f "$src" ]] && cp "$src" "$dst"
|
||||
done
|
||||
|
||||
# 3) custom/:仅拷贝 yaml/md/jpg/png,排除若干(保留目录结构)
|
||||
mkdir -p "$OUT_DIR/custom"
|
||||
rsync -av --prune-empty-dirs \
|
||||
--include='*/' \
|
||||
--exclude='wanxiang.custom*' \
|
||||
--exclude='wanxiang_chaifen_*.dict.yaml' \
|
||||
--exclude='wanxiang_chaifen.schema.yaml' \
|
||||
--exclude='wanxiang_pro.dict.yaml' \
|
||||
--exclude='wanxiang_pro.schema.yaml' \
|
||||
--include='*.yaml' --include='*.md' --include='*.jpg' --include='*.png' \
|
||||
--exclude='*' \
|
||||
"$ROOT_DIR/custom/" "$OUT_DIR/custom/"
|
||||
|
||||
# 4) 根目录 → $OUT_DIR(排除若干)
|
||||
OUT_BASE="$(basename "$OUT_DIR")"
|
||||
rsync -av --ignore-existing \
|
||||
--exclude='/.*' \
|
||||
--exclude='/dist/' \
|
||||
--exclude='/dicts' \
|
||||
--exclude='release-please-config.json' \
|
||||
--exclude='pro-*-fuzhu-dicts' \
|
||||
--exclude='wanxiang_t9.schema.yaml' \
|
||||
--exclude='CHANGELOG.md' \
|
||||
--exclude='wanxiang.dict.yaml' \
|
||||
--exclude='wanxiang.schema.yaml' \
|
||||
--exclude='custom' \
|
||||
--exclude='LICENSE' \
|
||||
--exclude="/$OUT_BASE" \
|
||||
"$ROOT_DIR/" "$OUT_DIR/"
|
||||
|
||||
# 5) default.yaml: - schema: wanxiang -> - schema: wanxiang_pro
|
||||
sed -i -E 's/^([[:space:]]*)-\s*schema:\s*wanxiang\s*$/\1- schema: wanxiang_pro/' "$OUT_DIR/default.yaml"
|
||||
}
|
||||
|
||||
|
||||
|
||||
package_schema() {
|
||||
SCHEMA_NAME="$1"
|
||||
echo "▶️ 开始打包方案:$SCHEMA_NAME"
|
||||
|
||||
if [[ "$SCHEMA_NAME" == "base" ]]; then
|
||||
OUT_DIR="$DIST_DIR/rime-wanxiang-base"
|
||||
package_schema_base "$OUT_DIR"
|
||||
|
||||
ZIP_NAME=rime-wanxiang-"$SCHEMA_NAME".zip
|
||||
else
|
||||
OUT_DIR="$DIST_DIR/rime-wanxiang-$SCHEMA_NAME-fuzhu"
|
||||
package_schema_pro "$SCHEMA_NAME" "$OUT_DIR"
|
||||
|
||||
fi
|
||||
|
||||
ZIP_NAME=$(basename "$OUT_DIR").zip
|
||||
(cd "$OUT_DIR" && zip -r -9 -q ../"$ZIP_NAME" . && cd ..)
|
||||
echo "✅ 完成打包: $ZIP_NAME"
|
||||
echo
|
||||
}
|
||||
|
||||
SCHEMA_LIST=("base" "flypy" "hanxin" "moqi" "tiger" "wubi" "zrm" "shouyou")
|
||||
|
||||
# 如果没有传入参数,则循环 package 所有的
|
||||
if [[ -z "$SCHEMA_NAME" ]]; then
|
||||
for name in "${SCHEMA_LIST[@]}"; do
|
||||
package_schema "$name"
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ! " ${SCHEMA_LIST[*]} " =~ ${SCHEMA_NAME} ]]; then
|
||||
echo "参数错误: 只支持 ${SCHEMA_LIST[*]}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
package_schema "$SCHEMA_NAME"
|
||||
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# lua 目录下动态生成的记录文件,不应被 git 追踪
|
||||
lua/input_stats.lua
|
||||
lua/seq_words.lua
|
||||
# 本地测试打包时的临时文件
|
||||
dist
|
||||
pro-*-fuzhu-dicts
|
||||
release_notes.md
|
||||
1
.release-please-manifest.json
Normal file
1
.release-please-manifest.json
Normal file
@@ -0,0 +1 @@
|
||||
{".":"13.6.3"}
|
||||
2159
CHANGELOG.md
Normal file
2159
CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
395
LICENSE
Normal file
395
LICENSE
Normal file
@@ -0,0 +1,395 @@
|
||||
Attribution 4.0 International
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||
does not provide legal services or legal advice. Distribution of
|
||||
Creative Commons public licenses does not create a lawyer-client or
|
||||
other relationship. Creative Commons makes its licenses and related
|
||||
information available on an "as-is" basis. Creative Commons gives no
|
||||
warranties regarding its licenses, any material licensed under their
|
||||
terms and conditions, or any related information. Creative Commons
|
||||
disclaims all liability for damages resulting from their use to the
|
||||
fullest extent possible.
|
||||
|
||||
Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and
|
||||
conditions that creators and other rights holders may use to share
|
||||
original works of authorship and other material subject to copyright
|
||||
and certain other rights specified in the public license below. The
|
||||
following considerations are for informational purposes only, are not
|
||||
exhaustive, and do not form part of our licenses.
|
||||
|
||||
Considerations for licensors: Our public licenses are
|
||||
intended for use by those authorized to give the public
|
||||
permission to use material in ways otherwise restricted by
|
||||
copyright and certain other rights. Our licenses are
|
||||
irrevocable. Licensors should read and understand the terms
|
||||
and conditions of the license they choose before applying it.
|
||||
Licensors should also secure all rights necessary before
|
||||
applying our licenses so that the public can reuse the
|
||||
material as expected. Licensors should clearly mark any
|
||||
material not subject to the license. This includes other CC-
|
||||
licensed material, or material used under an exception or
|
||||
limitation to copyright. More considerations for licensors:
|
||||
wiki.creativecommons.org/Considerations_for_licensors
|
||||
|
||||
Considerations for the public: By using one of our public
|
||||
licenses, a licensor grants the public permission to use the
|
||||
licensed material under specified terms and conditions. If
|
||||
the licensor's permission is not necessary for any reason--for
|
||||
example, because of any applicable exception or limitation to
|
||||
copyright--then that use is not regulated by the license. Our
|
||||
licenses grant only permissions under copyright and certain
|
||||
other rights that a licensor has authority to grant. Use of
|
||||
the licensed material may still be restricted for other
|
||||
reasons, including because others have copyright or other
|
||||
rights in the material. A licensor may make special requests,
|
||||
such as asking that all changes be marked or described.
|
||||
Although not required by our licenses, you are encouraged to
|
||||
respect those requests where reasonable. More considerations
|
||||
for the public:
|
||||
wiki.creativecommons.org/Considerations_for_licensees
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Attribution 4.0 International Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution 4.0 International Public License ("Public License"). To the
|
||||
extent this Public License may be interpreted as a contract, You are
|
||||
granted the Licensed Rights in consideration of Your acceptance of
|
||||
these terms and conditions, and the Licensor grants You such rights in
|
||||
consideration of benefits the Licensor receives from making the
|
||||
Licensed Material available under these terms and conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
d. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
e. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
f. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
g. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
h. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
i. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
j. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
k. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
4. If You Share Adapted Material You produce, the Adapter's
|
||||
License You apply must not prevent recipients of the Adapted
|
||||
Material from complying with this Public License.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material; and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public
|
||||
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||
its public licenses to material it publishes and in those instances
|
||||
will be considered the “Licensor.” The text of the Creative Commons
|
||||
public licenses is dedicated to the public domain under the CC0 Public
|
||||
Domain Dedication. Except for the limited purpose of indicating that
|
||||
material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the
|
||||
public licenses.
|
||||
|
||||
Creative Commons may be contacted at creativecommons.org.
|
||||
615
README.md
Normal file
615
README.md
Normal file
@@ -0,0 +1,615 @@
|
||||
---
|
||||
|
||||
# 万象系列方案 [](https://deepwiki.com/amzxyz/rime_wanxiang)
|
||||
|
||||
---------------------
|
||||
|
||||
## 万象拼音——基于深度优化的词库和语法模型
|
||||
|
||||
[万象词库与万象语言模型](https://github.com/amzxyz/RIME-LMDG) 是一种带声调的词库,经过AI和大基数语料筛选、加频,结合语言模型获得更准确的整句输出。
|
||||
|
||||
### 优势
|
||||
|
||||
1. 在这里你能找到最为全面的拼音标注数据库,词库词语全部加音调。可应用于多种带声调输入方案,也可将声调作为注释,输入码位置显示,也可直接上屏,是唯一一个支持整句拼音串上屏的方案;
|
||||
|
||||
2. 长期死磕首选权重最优解、分词片段最优解,大量应用错位构词法,让语句行云流水,结合语法模型,维护词库与维护模型同时进行,形成完美搭配;
|
||||
|
||||
3. 在这里你能找到最为全面的反查数据库,现已支持到U17:支持两分、多分、笔画三种打法,在生僻字输入、反查的场景中发挥重要作用;
|
||||
|
||||
4. 在这里你能找到最为有趣的Lua扩展功能,如成对符号包裹首选、tips多类型扩展显示与上屏、手动实时排序以及无感造词不调频的新鲜用法;
|
||||
|
||||
5. 维护了来自圈内的6种辅助码,头部使用全拼编码,可以转化为任何双拼编码,辅助码有:墨奇码;鹤形;自然码;虎码首末;五笔前2;汉心码,因此,万象拼音支持拼音和辅助码任意两两组合
|
||||
|
||||
6. 万象总结下来,从里到外,是一场翻天覆地的巨变,所涉及之处无不要求做到最优、最精。 这是我们持续的追求!
|
||||
|
||||
**万象词库中的带声调拼音标注+词组构成+词频是整个万象项目的核心,是使用体验的基石,方案的其它功能皆可自定义,我希望使用者可以基于词库+转写的方式获得输入体验** [万象词库问题收集反馈表](https://docs.qq.com/smartsheet/DWHZsdnZZaGh5bWJI?viewId=vUQPXH&tab=BB08J2)
|
||||
|
||||
---------------------
|
||||
|
||||
**效果大赏**
|
||||
|
||||

|
||||
|
||||
---------------------
|
||||
|
||||
|版本差异|标准版|增强版|
|
||||
|--- | ---- | --- |
|
||||
|方案文件|wanxiang.schema.yaml|wanxiang_pro.schema.yaml|
|
||||
|支持类型|全拼、任何双拼|只支持双拼|
|
||||
|是否调频|默认开启|默认关闭|
|
||||
|用户词记录|无差别自动记录,词库混乱|需手动造词``引导,词库可控|
|
||||
|用户词位置|wanxiang.userdb|zc.userdb|
|
||||
|辅助码|有基于声调的辅助|有7种辅助码可选,同时兼容声调辅助|
|
||||
|简码|全拼开启基于转写的简码,双拼未开启|有携带部分数据但未配置(自己设置的才是自己的)|
|
||||
|词库格式|你➩nǐ➩1000|你➩nǐ;re➩1000|
|
||||
|
||||
### 新手快速入门
|
||||
|
||||
不了解rime基础的可以参考友情链接,初步了解rime运行的些许特性:
|
||||
|
||||
[oh my rime](https://www.mintimate.cc/zh/guide/installRime.html)
|
||||
|
||||
[rime参数配置](https://xishansnow.github.io/posts/41ac964d.html)
|
||||
|
||||
整个rime配置生态都是通的,里面有非常完整的使用方法,(诸如放到哪里、换个皮肤、什么是用户目录。。。)
|
||||
|
||||
**友情提示:** *如果你是第一次使用万象,可以不要用你过往经验来定义万象,按如下的步骤将万象跑起来后,体验一下万象的功能,然后学习一下万象的各项内容之后再考虑。*
|
||||
|
||||
#### ①快速运行:
|
||||
|
||||
1. 将方案文件置于用户目录中,直接部署,等待部署完成后,
|
||||
|
||||
2. 输入以下指令(斜杠引导)切换为对应的双拼/全拼,切换后按照提示重新部署,完成。
|
||||
3. 这样的指令能帮你一次性完成4个补丁文件的输入类型修改,运行逻辑:根目录无自定义文件则复制custom文件夹相关文件出来并修改为对应的输入方案,如果根目录存在则只修改输入方案,不进行复制,因此不会被覆盖。
|
||||
4. ios仓输入法,平台特殊,需要额外去:方案文件管理-使用键盘文件覆盖应用文件,才能完成文件变更,具体操作如下:
|
||||
- 仓设置首页 -> 输入方案设置 -> 点击右上角 "+" -> 方案下载 -> 下载一套万象输入法方案, 如: 万象拼音标准版
|
||||
- 仓设置首页 -> 体验输入法 (或者随便找一个可以唤起输入法的场景) - 长按键盘输入"/" (不要上划输入), 然后接想要的方案, 比如 "/flypy", 此时输入法会提示已切换至相应方案
|
||||
- 仓设置首页 -> 文件管理 -> 拷贝键盘词库至应用
|
||||
- 仓设置首页 -> RIME -> 重新部署
|
||||
5. ios元书输入法:使用万象改双拼方案的方法:从RimeSharedSupport中复制include_keyboard_rime_files.txt到万象方案目录下,修改include_keyboard_rime_files.txt在底部新增```^.*[.]custom.*$```的正则表达式,然后重新部署即可实现自动复制键盘文件包含custom字符串文件到应用文件
|
||||
|
||||
```
|
||||
/flypy → 小鹤双拼
|
||||
/mspy → 微软双拼
|
||||
/zrm → 自然码
|
||||
/sogou → 搜狗双拼
|
||||
/znabc → 智能ABC
|
||||
/ziguang → 紫光双拼
|
||||
/pyjj → 拼音加加
|
||||
/gbpy → 国标双拼
|
||||
/lxsq → 乱序17
|
||||
/pinyin → 全拼
|
||||
/wxsp → 万象双拼
|
||||
/zrlong → 自然龙(反查是全拼)
|
||||
/hxlong → 汉心龙(反查是全拼)
|
||||
/jjf → 间接辅助
|
||||
/zjf → 直接辅助
|
||||
```
|
||||
5. 下载语法模型,放置于用户文件夹,无需配置。
|
||||
⚠️但要注意个别安卓前端,如小企鹅它的数据位于data,这个是受到安卓权限限制的,你需要通过安卓文件框架去迁移文件到内部,而不是使用MT文件管理迁移,这会导致权限异常部署报错(现实表现为:是不是太大了,是不是特别占内存,卡成这样。。。),如果你清楚Linux权限逻辑,实际上不是MT不能用,而是是否root并具备修改权限的能力,单纯的复制不会与data数据的权限保持一致,修改成一致的权限就能用了。
|
||||
|
||||
郑重说明:模型是一个优秀的大数据遍历能力的模块,他能方便的扩展词库数据的不足,非100%外显,它只消耗一些cpu的算力,占用极少的内存,而且他是不增大的固定的二进制数据,请区别于小而美的热加载数据看待。
|
||||
|
||||
#### ②东风破plum:
|
||||
|
||||
安装环境可用plum命令简单安装与更新,在保证安装小狼毫、中州韵、鼠须管等前端的前提下
|
||||
|
||||
```
|
||||
macOS / Linux 已内置 bash,无需处理
|
||||
Windows 需要 Git Bash(安装 Git for Windows 时自动提供,)
|
||||
```
|
||||
注意:
|
||||
Windows 的 PowerShell / CMD 不能直接运行东风破,必须用 Git Bash。
|
||||
|
||||
<details> <summary><strong>点击展开 / 收起 万象全部安装命令(可一键复制)</strong></summary>
|
||||
|
||||
|
||||
1. 先安装plum,这是维护在万象仓库plum分支的版本,去掉了默认方案,修改了默认路径,直接复制2个命令粘贴终端直接执行,打开终端的目录由你决定
|
||||
```base
|
||||
git clone -b plum --depth 1 https://github.com/amzxyz/rime_wanxiang.git
|
||||
cd plum
|
||||
```
|
||||
2. 配置用户目录变量,检查状态是否正常:
|
||||
对于小狼毫、鼠须管、Fcitx5已经默认配置了变量
|
||||
```base
|
||||
export rime_frontend='rime/weasel'
|
||||
export rime_frontend='rime/squirrel'
|
||||
export rime_frontend='fcitx5/fcitx5-rime'
|
||||
```
|
||||
但对于Linux、Mac使用ibus、fcitx前端就需要自己设置变量,这个变量可以终端执行,但最好直接写入~/.zshrc
|
||||
```base
|
||||
export rime_frontend=rime/ibus-rime
|
||||
export rime_frontend=fcitx/fcitx-rime
|
||||
```
|
||||
3. 有了上面的工具后你可以切换到刚刚拉取下来的脚本所在目录,执行以下对应的安装目录,即可实现安装和更新
|
||||
|
||||
##### 基础版(完整)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-base:plum/full
|
||||
```
|
||||
|
||||
##### 基础版(仅词库)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-base:plum/dicts
|
||||
```
|
||||
##### 自然码辅助版(完整)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-zrm-fuzhu:plum/full
|
||||
```
|
||||
|
||||
##### 自然码辅助版(仅词库)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-zrm-fuzhu:plum/dicts
|
||||
```
|
||||
##### 墨奇辅助版(完整)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-moqi-fuzhu:plum/full
|
||||
```
|
||||
|
||||
##### 墨奇辅助版(仅词库)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-moqi-fuzhu:plum/dicts
|
||||
```
|
||||
##### 小鹤辅助版(完整)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-flypy-fuzhu:plum/full
|
||||
```
|
||||
|
||||
##### 小鹤辅助版(仅词库)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-flypy-fuzhu:plum/dicts
|
||||
```
|
||||
|
||||
##### 虎码辅助版(完整)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-tiger-fuzhu:plum/full
|
||||
```
|
||||
|
||||
##### 虎码辅助版(仅词库)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-tiger-fuzhu:plum/dicts
|
||||
```
|
||||
|
||||
##### 五笔辅助版(完整)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-wubi-fuzhu:plum/full
|
||||
```
|
||||
|
||||
##### 五笔辅助版(仅词库)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-wubi-fuzhu:plum/dicts
|
||||
```
|
||||
#### 汉心辅助版(完整)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-hanxin-fuzhu:plum/full
|
||||
```
|
||||
|
||||
##### 汉心辅助版(仅词库)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-hanxin-fuzhu:plum/dicts
|
||||
```
|
||||
##### 首右辅助版(完整)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-shouyou-fuzhu:plum/full
|
||||
```
|
||||
|
||||
##### 首右辅助版(仅词库)
|
||||
```bash
|
||||
bash rime-install amzxyz/rime_wanxiang@wanxiang-shouyou-fuzhu:plum/dicts
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
**③进阶custom patch法(已经尽量为你简化)强烈推荐,适用于长期稳定使用:**
|
||||
|
||||
其实快速运行中我们已经完成了custom patch的部署,里面还预设了一些示例,这些例子只是例子,请务必详细阅读每一行,保留有用的删除无用的,千万不要改完双拼就万事大吉了,每一行详细查阅、理解、修改。custom是对对应方案文件的最后一道补丁,是真正属于你自己的配置文件,他不会被升级所覆盖。
|
||||
|
||||
方案提供了custom文件夹,预设了一些文件与教程,请不要删除相关文件,根据文件夹中内容进行相关修改变更:
|
||||
|
||||
**不要在default.custom写东西,任何patch都要对方案文件进行patch,default.custom留给前端操作请务必悉知!**
|
||||
|
||||
```
|
||||
wanxiang.custom.yaml是对wanxiang.schema.yaml的补丁以此类推
|
||||
可以打补丁的类型:
|
||||
schema,default,weasel,squirrel
|
||||
```
|
||||
|
||||
注意不要删除和变更每一个custom的表头。
|
||||
|
||||
更详细参照:[🚀 Rime 万象拼音输入方案 新手安装配置指南](https://docs.qq.com/doc/DQ0FqSXBmYVpWVFpy?rtkey=)
|
||||
|
||||
**④第三方脚本更新:**
|
||||
|
||||
脚本的下载地址 [万象方案更新脚本](https://github.com/rimeinn/rime-wanxiang-update-tools)。这里以win版本的小狼毫为例,如果你是**中文系统**请下载更新脚本的 powershell **非utf-8版本**,具体文件名:`rime-wanxiang-update-windows.ps1` 。在使用万象之前,请安装小狼毫,安装小狼毫的过程中,请一切保持默认即可,等你熟悉之后可以自定义。本入门最终会带你一步步设置使用**小鹤双拼+墨奇辅助码**的方案。
|
||||
|
||||
1. 下载更新脚本:直接点击上面地址首页右边最新 release 链接,然后下载对应的 `rime-wanxiang-update-windows.ps1` 文件即可。下载完成后,直接双击运行刚刚下载的ps1脚本。如果杀毒报错,请将你下载的文件恢复后,添加到信任文件。如果执行一闪而过、或者遇到乱码再尝试下载 utf-8 版本,具体文件名:`rime-wanxiang-update-windows-utf-8.ps1`。如果提示权限不足,可以在 powershell 终端中执行 `Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser` 再尝试运行下载的 ps1 脚本。
|
||||
|
||||
2. 脚本执行后,需要你确认你使用的是全拼还是双拼用户,如果你是全拼用户,请根据提示输入 0 后回车。如果你双拼用户,需要你确认你使用的辅助码类型,默认的万象方案支持汉心、简单鹤、墨奇、虎码、五笔、自然码共计6种辅助码类型。如果没有你想要的辅助码类型,也不要着急,可在熟悉万象之后自定义。根据提示输入你使用的辅助码类型的数字后回车即可。这里我按墨奇辅助码输入。更不要着急怎么选择双拼方案,后面会告诉你的。
|
||||
|
||||
3. 脚本继续执行,提示选择是否全部更新,不要管,你是新手,直接选全部更新,输入 0 回车。然后就默默的等待脚本执行完后,按任意键退出即可。默认情况下,万象的双拼方案为自然码。
|
||||
|
||||
4. 在使用脚本更新之前,务必使用进阶custom patch法维护好你的配置,更新不会覆盖custom.yaml类文件
|
||||
|
||||
**⑤自定义数据获取:**
|
||||
|
||||
在线custom目录随有三个数据源提供,按自己需求自行整理取用,这部分数据没有随zip方案包一起供应,需在线下载。
|
||||
|
||||
- jm_flypy.txt 用于提供小鹤类型的简码,下载后复制到根目录custom_phrase.txt自定义库即可使用;
|
||||
|
||||
- jm_zrm.txt 用于提供自然码类型的简码,下载后复制到根目录custom_phrase.txt自定义库即可使用;
|
||||
|
||||
- tips_user.txt tips用到的“翻译”类型的数据,下载后放置于lua/tips里面重新部署。
|
||||
|
||||
### 答疑
|
||||
|
||||
[为什么PRO版本默认关闭调频的说明](https://github.com/amzxyz/RIME-LMDG/wiki/%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E5%85%B3%E9%97%AD%E8%B0%83%E9%A2%91%E4%BB%A5%E5%8F%8A%E4%B8%8E%E4%B9%8B%E5%85%B3%E8%81%94%E7%9A%84%E6%8E%AA%E6%96%BD%E6%9C%89%E5%93%AA%E4%BA%9B) ```enable_user_dict: false # 是否开启自动调频,true为开启```
|
||||
|
||||
### 功能一览
|
||||
|
||||
#### 辅助码
|
||||
|
||||
辅助码可以在输入一个确定得拼音后面继续输入一个部首的读音,使得这个字出现在靠前甚至第一位。这种方式易于理解,无须记忆字根,一切基于拼音得基础上。例如:
|
||||
|
||||

|
||||
|
||||
**功能1** **(仅PRO)** 直接辅助--如果想要 `镇` 字显示在前面 那么在本方案下提供两种方式,第一种就是辅助码声母,`vf`继续输入`j` 也就是金字旁得声母即可出现结果,如果还是出现不了你要的结果,可以输入另外主体字的声母来继续缩小范围。
|
||||
|
||||

|
||||
|
||||
句子中间或者单字输入时需要输入全位辅助码时由于与双拼词语重码,因为我们设计的基本辅助码是2位,加上双拼共4位,由于在整句中我们为了整句输入的顺畅,不会将4码聚拢作为优先级较高的选择,这样会在很多时候造成你想打的句子缩成一团变成全辅助码的词汇。此时可以通过追加/的方式使其聚拢,这种方式是由于我们是直接辅助码导致的,如果我们通过一个符号引导辅助码,那么在输入时要每一个都用到符号,而采用这种方式我们只需要在必要的时候使用/节省了输入的按键开支,下面由两个图片说明问题:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
**功能2** **(仅PRO)** 间接辅助--除以上直接使用辅助外,我们还支持中间加入/来引导辅助码的输入,即:功能1是"nire/" 在有需求的时候末尾增加斜杠能让系统侧重于单字,平时则永远在动态切分,这个模式也是比较吃词库的,当你的词组完整,遇到的异常就少,当词组不完整,你想输入三个字2+2=2编码结构,恰好辅助码与双拼编码重合就会出现3+3的聚拢,此时将你想输入的三个字放入词库中,这个问题就得到了解决,还有得项目通过Lua重新切分来解决,看似巧妙,实际上比较吃操作,影响节奏,无疑万象在很多选择上面选择了更加难的路线,用词库的全面性来托举.
|
||||
而在功能2中是"ni/re",也就是说辅助码必须经过/来引导,如果你不输入/它将与普通双拼无异,优点是类似vsg能够派生出"中国",更适用于新手辅助码或者叫辅助码轻量使用者.
|
||||
|
||||
**功能3** 第二种方式是通过反查字库来定位,只是通过不同的方案实现,在输入主要拼音后,通过符号``` ` ``` 来引导进入反查状态,引导后继续输入`jn`金 则包含金的字就会被选出来;
|
||||
|
||||

|
||||
|
||||
引导后继续输入`mu 木`则带`木`的字就会被选出来
|
||||
|
||||

|
||||
|
||||
如果你输入的是词汇,则会按照第一个字来辅助反查,因此在开关中有:[词组优先、单字优先],例如:"```nihk`r```" 候选会有:你好 你,如果单字优先就是 你 你好,此时上屏“你” 整个编码的视觉就是 "```你hk` ```",此时可以继续输入n来筛选出”好“,这样你好就完成了上屏,当然一般用于输入一些生僻词组
|
||||
|
||||
实际上我们同时支持,```两分:你(ni`rfer,ni`re)、多分:莫(mu`ckrida)、笔画:你ni`pspzhpd```
|
||||
|
||||
**功能4** 通过 拼音状态下``` `〔反查:部件|笔画〕``` 来引导拆字模式 举例 ```震``` 假设你不认识,你可以通过`雨和辰` 来合并输入,拼音状态输入后,继续输入其它字符字母az会消失如下图,输入 ```yu if``` 即雨 辰,结果出现了我们要的震字,且给出了辅助码 ```y``` 和 ```i``` ,```y```是雨的声母```y```,```i```是辰的声母```ch```,同时兼容通过hspnz代表横竖撇捺折五笔画。功能3是功能4的另一种表现形式,或者叫用法。这个功能依赖wanxiang_reverse.schema.yaml方案,可以通过custom配置成任意全拼双拼以匹配主方案一致的输入方式,因此是不是输入jn=jin需要看你具体的双拼类型。
|
||||
|
||||

|
||||
|
||||
**功能5** 句子中间或者单字输入时需要可以使用更精确的聚拢方式"声调辅助",7890数字按键代表1234声,轻声归并到4声,在功能4中我们可以在双拼两码后面3个编码的位置任意插入声调与两位辅助码混合使用,就是除了不用斜杠了,我们还顺序自由了,下面由两个图片说明问题,其实在键盘上想要安排四个按键是很难得,不是占用这个按键就是占用另外的,还有得朋友觉得离得远,还有得更是不需要声调,要把候选做成9个。这些都是存在的情况,现在的处理也是妥协后的结果,要想完全不占用按键类似的办法可以改成大写字母来代表,像地球拼音则是使用大于小于号这一片的符号来表示,我们的词库有声调这个基础,一定程度上还是要利用起来:
|
||||
|
||||
<img src="https://storage.deepin.org/thread/202505120222182012_截图_选择区域_20250512101814.png" height="130" width="520">
|
||||
|
||||
<img src="https://storage.deepin.org/thread/20250512022217432_截图_选择区域_20250512101752.png" height="130" width="520">
|
||||
|
||||
<img src="https://storage.deepin.org/thread/202505120222163619_截图_选择区域_20250512101713.png" height="130" width="520">
|
||||
|
||||
|
||||
**功能6** 混合输入:字母、汉字、数字、用于连接的特殊符号等组合,以及英文混输,我们统一放在了wanxiang_mixedcode.schema.yaml混合编码方案里,此功能无需引导,直接输入,不参与组句,类似:1000wclips、AD钙奶、PN结、Type-C以及纯英文,同样可以通过custom来定义你所使用的双拼。
|
||||
|
||||

|
||||
|
||||
**整合说明** 万象方案整合度很高,我们不希望使用户文件夹变得复杂,功能5中我们将两类习惯的五笔画和多分拆字和两分拆字整合到了一起,可以认为是4个挂接方案;在功能6中,我们将 英文输入、中英混合编码、以及一些其他混合编码整合到了一起,共享方案转写,两个功能都保证了可配置性,都能与你所使用的双拼契合,
|
||||
对于词库也都整合到了dicts里面,为了能更好的统一更新和分发,仓库中我们支持基础版本词库、携带pro的辅助码版本词库、英文词库、混合词库4个类别,在release中各自归类,最终做到了根目录15个文件、4个文件夹示人,其中的custom目录还携带了用户自定义的法宝秘籍,能称得上简约而不简单。
|
||||
#### 其他亮点功能
|
||||
|
||||
**日期、时间、节日、节气、问候模板:**
|
||||
可以在按键配置的地方定制引导前缀
|
||||
|
||||
```key_binder/shijian_keys: ["/", "o"]``` 这样的配置以为你你可以/sj也可以osj,某些方案o有别的作用时候可以去掉o,灵活处理。
|
||||
|
||||
输入后N0101四位数模式下可以采用qwerty...依次代表123456上屏,也可以按下方向键上下进行候选的选择。如果输入完整的八个数字则还是使用数字就能选择上屏
|
||||
|
||||
还有他强大的自定义能力,类型、格式、顺序、候选数,每一样都可以自定义,安全的占位逻辑和转译方式
|
||||
|
||||
```yaml
|
||||
#shijian:仅仅作为提示使用,编码已经写死,引导键可以在key_binder下修改前缀
|
||||
#时间:osj 或者 /sj
|
||||
#日期:orq 或者 /rq
|
||||
#农历:onl 或者 /nl
|
||||
#星期:oxq 或者 /xq
|
||||
#今年第几周:oww 或者 /ww
|
||||
#节气:ojq 或者 /jq
|
||||
#日期+时间:odt 或者 /dt
|
||||
#时间戳:ott 或者 /tt
|
||||
#大写N日期:N20250315 或者N0312不带年
|
||||
#节日:ojr 或者 /jr
|
||||
#问候模板:/day 或者 oday
|
||||
# 通用日期时间格式化函数(供 /rq、/sj、/dt、N0101、N20150101 场景复用)
|
||||
# 支持转义:
|
||||
# \X —— 转义单个字符 X,按字面量输出(如 \Y \m \H 等)
|
||||
# [[...]] —— 区块整体按字面量输出
|
||||
#
|
||||
# 约定占位符:
|
||||
# 【日期】
|
||||
# Y 四位年份 0000-9999 例:2025
|
||||
# y 两位年份 00-99 例:25
|
||||
# m 月(前导零) 01-12 例:02
|
||||
# n 月(不带前导零) 1-12 例:2
|
||||
# d 日(前导零) 01-31 例:09
|
||||
# j 日(不带前导零) 1-31 例:9
|
||||
#
|
||||
# 【时间】
|
||||
# H 24小时(前导零) 00-23 例:08
|
||||
# G 24小时(不带零) 0-23 例:8
|
||||
# I 12小时(前导零) 01-12 例:08
|
||||
# l 12小时(不带零) 1-12 例:8 (注意是小写 L)
|
||||
# M 分钟(前导零) 00-59 例:05
|
||||
# S 秒(前导零) 00-59 例:09
|
||||
# p am/pm(小写) am / pm
|
||||
# P AM/PM(大写) AM / PM
|
||||
# 【时区】
|
||||
# O 带冒号格式 +08:00、-04:30、+05:45
|
||||
# o 不带冒号格式 +0800、-0430、+0545
|
||||
date_formats:
|
||||
- "Y年m月d日"
|
||||
- "Y-m-d"
|
||||
- "Y/m/d"
|
||||
- "Y.m.d"
|
||||
- "Ymd"
|
||||
- "Y年n月j日"
|
||||
- "y年n月j日"
|
||||
- "n月j日"
|
||||
time_formats:
|
||||
- "H:M"
|
||||
- "H点M分"
|
||||
- "H:M:S"
|
||||
- "H时M分S秒"
|
||||
- "下午I:M"
|
||||
- "I:M P"
|
||||
datetime_formats:
|
||||
- "Y-m-d H:M:S"
|
||||
- "Y-m-dTH:M:S O"
|
||||
- "YmdHMS"
|
||||
- "Y年m月d日 H点M分"
|
||||
- "y/m/d I:M p"
|
||||
```
|
||||
<img src="https://storage.deepin.org/thread/202509260107542641_N20250102.jpg" height="80">
|
||||
<img src="https://storage.deepin.org/thread/202509260108069991_N0102.jpg" height="80">
|
||||
|
||||
**Unicode:** 大写 U 开头,如 U62fc 得到「拼」。
|
||||
|
||||
<img src="https://storage.deepin.org/thread/202509260111366093_U码.jpg" height="80">
|
||||
|
||||
**数字、金额大写:** 大写 R 开头,如 R1234 得到「一千二百三十四、壹仟贰佰叁拾肆元整」。输入后该模式下可以采用qwerty...依次代表123456上屏,也可以按下方向键上下进行候选的选择。
|
||||
|
||||
<img src="https://storage.deepin.org/thread/202509260124573417_金额大写.jpg" height="80">
|
||||
|
||||
**/引导模式:** 通过输入 /sx 快捷输入关于“数学”的特殊符号,具体能输入什么可以打开 symbols.yaml学习。以及前述提到的日期时间等的引导都共用斜杠开头,可以理解为一种命令模式。
|
||||
|
||||
<img src="https://storage.deepin.org/thread/202509260126183029_符号数学.jpg" height="80">
|
||||
<img src="https://storage.deepin.org/thread/202509260126173818_符号大于.jpg" height="80">
|
||||
<img src="https://storage.deepin.org/thread/202509260126167252_符号圆点.jpg" height="80">
|
||||
|
||||
**计算器:** 通过输入大写V引导继续输入如:V3+5 候选框就会有8和3+5=8,基础功能 `+ - * / % ^` 还支持 `sin(x) cos(x)` 等众多运算方式,打开super_calculator.lua阅读相关用法。
|
||||
|
||||
<img src="https://storage.deepin.org/thread/202509260127113759_计算器1.png" height="80">
|
||||
<img src="https://storage.deepin.org/thread/202509260127126065_计算器2.jpg" height="80">
|
||||
|
||||
**自动上屏:** 例如:三位、四位简码唯一时,自动上屏如`jjkw岌岌可危` `zmhu怎么回事` 。默认未开启,方案文件中`speller:`字段下取消注释这两句开启 `# auto_select: true # auto_select_pattern: ^[a-z]+/|^[a-df-zA-DF-Z]\w{3}|^e\w{4}`
|
||||
|
||||
**错音错字提示:** 例如:输入`gei yu给予`,获得`jǐ yǔ`提示,此功能与全拼、双拼类型无关全部支持;
|
||||
|
||||
<img src="https://storage.deepin.org/thread/202509260127525844_错音给予.jpg" height="80"> <img src="https://storage.deepin.org/thread/202509260127524705_错音崩溃.jpg" height="80">
|
||||
|
||||
**快符Lua:** 例如通过 ```a/``` ,快速自动上屏“!”符号或者定义为任意字符,享受26字母的扩展。其中值设置为`repeat`则意味着按下对应按键能否重复上一次上屏的内容。位于方案中quick_symbol_text段落是可以自定义映射关系的,对于特殊需求用户还可以修改正则表达式让引导策略发生变化,如首字符引导;
|
||||
|
||||
**超级tips:** 支持将表情、化学式、翻译、简码 提示等等你能想到得数据获得提示显示并将通过一个自定义按键直接上屏,默认为“,” 也表现为逗号,避免了这类内容占用候选框,轻量化提示与上屏的能力。如果你设置逗号句号为翻页,逗号翻页如果正好是首选匹配,句号作为下一页则不干扰,当想要回到第一页,此时已经不匹配tips,此时逗号就不被tips占用了,就可以用于翻页。也可以将触发键变更为其他,位于key_binder/tips_key: "comma"。对于加载的类型可以屏蔽某一种,位于tips/disabled_types: [],括号内填入# 可选项为:偏旁,符号,化学式,时间,符号,组字,翻译,表情,货币,车牌等禁用类型。通过Control+t 进行开关。
|
||||
⚠️仓输入法、超越输入法设置按键交由rime去处理,没有特殊需求应该一律交给rime,如需关闭将tips开关reset 0即可;
|
||||
⚠️某些前端开启嵌入与窗口交互有bug,在开启tips的时候可能会造成异常的编码上屏,此时可以关闭tips在这些窗口使用输入法。
|
||||
|
||||
化学式:<img src="https://storage.deepin.org/thread/202509260128462735_tips化学式.jpg" height="80">符号:<img src="https://storage.deepin.org/thread/202509260128454675_tips符号.jpg" height="80">表情:<img src="https://storage.deepin.org/thread/202509260128457494_tips表情.jpg" height="80">
|
||||
|
||||
**首选格式化:** 将自定义短语中,诸如\n \s \t 等行中标识符转换为实际的换行、空格、制表符等等,使得类似输入jys可以打出一首带格式的《静夜思》,这将成为类似书名号输入场景的利器。
|
||||
|
||||
例:```静夜思\n\s\s李白\n床前明月光\n疑似地上霜\n举头望明月\n低头思故乡 jys```
|
||||
|
||||
<img src="https://storage.deepin.org/thread/202509260129305342_格式化.jpg" height="260">
|
||||
|
||||
**首选加成对符号:** 将输入中的短语通过输入追加\a 这样的末尾编码,触发相对于a这个字母映射的成对符号,例如:``` sj mk lq lh ji\l=《三毛流浪记》```可以通过custom自定义符号和触发方式。
|
||||
|
||||
工作逻辑:输入词汇编码 > 按下锁定按钮\ > 按下映射字符\a > 《候选包裹成对符号》
|
||||
|
||||
<img src="https://storage.deepin.org/thread/202509260130219621_首选成对符号1.jpg" height="80"> <img src="https://storage.deepin.org/thread/202509260130208277_首选成对符号2.jpg" height="80"> <img src="https://storage.deepin.org/thread/202509260130199763_首选成对符号3.jpg" height="80">
|
||||
|
||||
**英文候选格式化:** 输入hello则得到hello,输入首字母大写Hello则得到Hello和一众首字母大写的联想词,输入前两码大写HEllo则得到全为大写的HELLO和一众大写英文。
|
||||
|
||||
<img src="https://storage.deepin.org/thread/202509260133175234_首字母大写.jpg" height="80">
|
||||
<img src="https://storage.deepin.org/thread/202509260133175362_双字母大写.jpg" height="80">
|
||||
|
||||
**辅助码提示(仅PRO):** 任意长度候选词的辅助码提示能力,默认开启1个字的辅助码,可以在方案文件中定义更长的长度。Ctrl+a可以实时在开启辅助码提示、开启声调全拼提示、关闭注释 三个状态循环,Ctrl+c开启拆分辅助提示,优先级高于普通辅助提示;
|
||||
|
||||
<img src="https://storage.deepin.org/thread/202509260134283927_辅助码提示.jpg" height="80">
|
||||
<img src="https://storage.deepin.org/thread/202509260134278003_声调提示.jpg" height="80">
|
||||
<img src="https://storage.deepin.org/thread/202509260134284782_拆分提示.jpg" height="80">
|
||||
|
||||
|
||||
**输入码音调显示:** 通过Ctrl+s可以使得输入码实时动态显示全拼并加音调,这是万象特色功能;
|
||||
|
||||
**用户按需造词(仅PRO):** 默认通过``` `` ```引导的方式进入用户词自造词模式,继续输入则``` `` ```前缀消失,后面打出来的字上屏后完成造词。 pro版本讲究自主可控,由于辅助码的使用在很多时候不熟悉的时候可能会上屏更加异常的词汇或者生僻字,有的用户还不会使用Esc退出输入,而是选择直接敲下空格。按需造词可以有效把控造出的词是有意义的,而且默认靠后,原因简单基本上有意义的高频词万象已经提供,你应该使用辅助码将其前置。**重点**:在此基础上我们还支持“后触发”当你输入编码后发现没有你要的行业词汇,此时在后面双击``` `` ``` 就可以在不删除编码的情况下完成造词。还有一个是次选造词,如果次选是你想要的,并且是词库组合成的,上屏就会记录下来。
|
||||
|
||||
总结一下,造词功能由:①``` `` ```起始的主动造词,②``` `` ```在编码后面的主动造词,③次选造词。三个特性构成
|
||||
|
||||
**中文无感造词(仅PRO):** 在关闭调频的情况下,通过逐步选字选词的方式上屏将为你记录整段,且不会产生小碎片,所造词汇与db用户词是一回事,遵循用户词管理的相关逻辑,其中直接上屏不造词。相比按需造词更加不打断输入。
|
||||
|
||||
**英文造词:** 例如当输入scx的时候没有任何候选,此时可以追加\,```scx\```可以触发创建候选,但是有的时候我们想要任意编码进行英文造词,但是又有汉字在前面怎么办,本着一次不行就来两次的原则```nihao\\```末尾输入两个就可以了。然后空格上屏他就记录到了en.userdb,导出和同步与用户词逻辑一致。
|
||||
|
||||
**用户词删除:** 使用Ctrl+del是rime系统删除用户词,就可以将用户词标记为c<=0,这在rime系统中就表现为不使用,假性删除。
|
||||
|
||||
**输入模式切换:** 使用Ctrl+q来进行中文候选词、英文候选词、混合候选词之间切换,默认为混合编码输入模式。
|
||||
|
||||
**手动排序(Lua):** ①词典候选类型:对选中的候选词操作,使用Ctrl+j向左一步,Ctrl+k向右一步,Ctrl+l(零)移除选中排序信息,Ctrl+p 置顶选中候选。其作用于当时编码与候选词;②动态生成的Lua候选,很多时候我们对日期、时间等输出格式首选有着自己的追求,复杂的配置又往往提升了使用难度,于是我们基于排序Lua实现了动态内容的按序号索引的排序,也就是说该序号下原本生成的格式整个发生了位置变化,使用方法一致。信息储存于Lua文件夹下排序数据库中sequence.userdb,支持导出导入数据便于多设备共用。
|
||||
|
||||
排序信息同步:
|
||||
|
||||
A 先点击同步,多见于右键菜单,保证创建了相应的同步目录,如没有自定义则位于用户目录下/sync
|
||||
|
||||
1. 打开用户目录,会有installation.yaml文件,打开后会有如下信息,我们将installation_id认为是设备id,初次会创建自动串号,你也可以将其修改为当前设备名称
|
||||
```
|
||||
distribution_code_name: "fcitx-rime"
|
||||
distribution_name: Rime
|
||||
distribution_version: 5.1.9
|
||||
install_time: "Mon Jun 23 18:47:55 2025"
|
||||
installation_id: "ff9b2823-8733-44bb-a497-daf382b74ca5" #这里可以随意编辑,比如修改为windows
|
||||
rime_version: 1.13.1
|
||||
update_time: "Sat Sep 6 16:08:56 2025"
|
||||
```
|
||||
得到这个id后我们就可以下一步构建出同步文件的名称sequence_设备id.txt
|
||||
|
||||
2. 首先确定一个主要管理设备,在/sync中创建一个描述设备清单的文件 `sequence_device_list.txt`,这个清单告诉程序要读取同目录下哪些文件进行合并
|
||||
```内部内容为:
|
||||
sequence_deepin.txt
|
||||
sequence_windows.txt
|
||||
sequence_iPhone.txt
|
||||
```
|
||||
3. 按「部署」,会进行以下几步:
|
||||
|
||||
①、自动导出数据到 `sequence_deepin.txt` 文件(假设为当前设备),因此这个当前设备文件会被覆盖,请不要手动修改避免丢失;
|
||||
|
||||
②、读取列表中列出的文件,按时序以保留最新动作为依据进行去重合并,合并后数据将会回写到 `sequence_deepin.txt` 文件;
|
||||
|
||||
③、将合并后的文件导入db数据库,完成数据合并,注意p=0的重置后的编码不会导入数据库,如数据库原本有对应的词汇,将删除对应的键。
|
||||
|
||||
4. 通过云同步将/sync完成同步到windows设备,同步后,编辑 `sequence_device_list.txt`将sequence_windows.txt写入文件,让同步程序再次完成多端同步
|
||||
|
||||
此时目录中已经存在如下文件,此时重新部署,稍作等待将会完成`sequence_windows.txt`的输出
|
||||
|
||||
`sequence_device_list.txt`
|
||||
|
||||
`sequence_deepin.txt`
|
||||
|
||||
`sequence_windows.txt` #同步后新增
|
||||
|
||||
再次手动完成手动云同步,及时让文件对齐。
|
||||
|
||||
B 重复以上操作完成更多设备的添加和同步
|
||||
|
||||
由于此流程为模拟rime同步的方式,rime的同步本质上就是多端的数据合并的过程,可靠性可能相较于原生较弱一些,尤其是iPhone可能遇到更多问题。
|
||||
|
||||
**声调辅助回退(Lua):** 万象是将7890用来代表1234声,轻声归并到了4,我们支持在例如输入ni9后发现我可能要4声,ni0,此时我们无需删除数字9而是直接输入对的0,类似手动在7890之间轮巡,能有效快速提升声调辅助的效率,减少使用负担,也是万象独创功能。
|
||||
|
||||
**小键盘有妙用(Lua):** auto模式:可配置输入中数字跟在字母后面不上屏。compose模式:可配置数字持续不上屏,不用区分先后。
|
||||
|
||||
**删除键限制(Lua):** 可以在输入中当持续按下删除编码为0时会卡住,抬起重新按下才能继续删除已经上屏内容,避免误删除上屏内容。目前仅PC可用,也是万象独创功能。
|
||||
|
||||
**输入长度限制(Lua):** 对两类场景进行限制,避免数据并发卡顿:1、重复输入8个连续相同的字母,aaaaaaaa会提示:已超最大重复声母。因为连续多个的重复字母会造成严重的卡顿;2、分词片段限制在30个,也就是30个字,过长的语句价值不大还会造成卡顿。
|
||||
|
||||
**Tab循环切换音节:** 当输入多个字词时想要给前面补充辅助码,可以多次按下tab循环切换,这种可能比那些复杂的快捷键好用一些,同样逻辑的按键还包含ctrl+tab相当于逐字确认,错了可以补充编码,对了继续按下直到全部上屏;
|
||||
|
||||
**“候选切割机”(Lua):** 这个功能是有候选的时候,通过按下ctrl+1~0中的10组组合键直接上屏首选前N个字,编码按现有音节分割后续编码保留,一般来说在输入句子的时候由于读音和构词的相似性,以及模型数据的偏差可能会出现错误的连续,这个时候恰当的切割让前面正确的直接上屏,残留的编码一般自动变为首选正确的选项了,此时上屏或继续切割或者使用tab补充编码。这个功能在base双拼中具备更高的确定性,而在pro版本中如果遇到直接辅助码的聚拢,那么此时候选估计与你初心不一致,此时可以考虑借助多次按下单引号来循环分词或许能得到你要的候选,如未得到直接esc重新输入更为高效。更为激进的用法直接上屏正确的部分,后面的编码直接遗弃,现在没有写进去,或许可以作为一个选项,如果你也像这样可以issue告诉我,我们可以改造成布尔选项;
|
||||
|
||||
**翻译模式:** 输入状态按下Ctrl+E快捷键进入翻译模式,原理是opencc查表进行中英文互译,能否翻译取决于词表的丰富度;
|
||||
|
||||
**字符集过滤(Lua):** 默认开启过滤,写在charset.dict.yaml的就是可以通过的字表,默认为8105+𰻞𰻞,如果你想什么字在小字集模式可以通过可以写在这里,配套开关【小字集、大字集】,快捷键Ctrl+g
|
||||
|
||||
**万能键斜杠/:**
|
||||
* 符号扩展输入: rime(大部分前端)是一种最小化ui的输入法,除了输入界面几乎看不到ui设置界面及符号表情面板的组件,因此我们在想要输入一些符号表情等特殊内容的时候会根据类型,设计一个触发条件,这个条件类似以什么编码开始作为标识、或者是某种tag状态。万象又是一个兼容多种输入类型的方案,我们无法找到一个绝对的空码字母作为触发条件,或多或少会冲突,因此我们选择了斜杠作为引导条件,例如/sx可以打出加减乘除等等,/yd可以打出圆点集合等等;
|
||||
* 辅助码聚拢: 我们在转写中将四个字母+/作为高权重的编码,意思就是侧重输入单字,而四个字母则采用abbrev,这种情况有词的情况有限出词,没词才会变成单字,毕竟我们是一个语句流方案,核心还是想输入多长输入多长的类大厂习惯的输入法,因此单字就不能像字词音形方案那样四码定位一个字;
|
||||
* 间接辅助码引导: 直接辅助码我们是在四个编码末尾追加斜杠/,而间接辅助是在两个编码即双拼后面加斜杠,意思就是后面继续输入编码就能用辅助码对这个单字进行筛选,如果不加斜杠,就与正常的双拼无异,这时vs g=中国就能被打出来,不习惯直接辅助的可以选用这种方式;
|
||||
* 短码英文前置: 对于英文词典中我们常常遇到us以及United States这种缩写,那么在你水平一般的情况下输入两个字母前面可能是一大堆重要的中文词汇和单字,那么这个例子就显得不恰当了,不重要,这个时候输入us/就可以让us编码相关的英文词条前置,此时次选就是United States,有的时候是能输出对应大写,支持1-3个字母,因为但凡输入四个字母以上基本上会获得直接的前置了;
|
||||
* 快符: 输入一个单字母+/完成对应映射上屏,a/这样,还能定义某个按键是用来重复上屏之前的内容例如q/最终形成自己的习惯,原本分号引导包括数字都能用,但是分号太过珍贵,方案层面就不占用了;
|
||||
* 上屏斜杠自己: 通过双击斜杠直接上屏他自己;
|
||||
|
||||
**按键设置思考:**
|
||||
* 我们说有舍有得,如何合理安排这些按键是一个重要课题,很多新手上来就要遵循自己以前的习惯,但那些习惯又何尝不是其他软件灌输给你的,我们何曾思考过合理性,对于rime不思考就定义不好,定义不好不如继续用大厂。对于万象斜杠/是不可能被挪作他用的,因此莫要针对这件事提问,修改的地方过多没有精力教学。反斜杠是顿号、分号有次选需求、引号要分词,中括号要以词定字,逗号句号在没有tips的时候更倾向于随语句一起上屏,节约按键,在有tips的时候句号在手机电脑上任何键盘大概率都能直接按,因此默认-=作为翻页,这与老祖宗ABC时期用法一样,某种程度7890代表的1234声调与-=凑在一起构成了一个筛选区,在重新选择rime作为输入法的时候我还是建议重新思考一下自己所谓的习惯
|
||||
|
||||
**自定义短语:** 将根目录中的custom_phrase.txt文本以表导入到rime,实现实际的编码对应你想要的输出,床前明月光\tcqm,其中\t代表制表符,不能输入的复制前面的行修改可见字符,尽量不要使用记事本编辑,换一个更高级的文本编辑器。这个功能主要用来短编码输入长短语、符号数字串等等各种需要置顶的内容,一定要根据万象的初始化在wanxiang.custom中修改名称避免更新被覆盖丢失数据。
|
||||
|
||||
**自定义词库:** 自定义词库首先要利用工具将你自己的词库刷成与万象同类型的声调、或者声调+辅助码的形态,因为主词库要参与转写。对于custom_phrase则需要手动编辑编码为实际输入的编码。
|
||||
|
||||
要保证每个字编码与chars完全一致,这是基础,不再赘述。
|
||||
|
||||
##### 固定词库:
|
||||
#packs法,要保证外部名称`userxx.dict.yaml`与里面`name: userxx`一致,
|
||||
```
|
||||
patch:
|
||||
translator/packs/+:
|
||||
- userxx
|
||||
```
|
||||
|
||||
#重命名法,重命名用户根目录`wanxiang.dict.yaml`为`wanxianguser.dict.yaml`,避免更新被覆盖
|
||||
|
||||
#所有主方案文件中使用了这个固定词库的位置都要变更
|
||||
```
|
||||
patch:
|
||||
translator/dictionary: wanxianguser
|
||||
radical_reverse_lookup/dictionary: wanxianguser
|
||||
user_dict_set/dictionary: wanxianguser
|
||||
add_user_dict/dictionary: wanxianguser
|
||||
```
|
||||
##### 用户词库迁移:
|
||||
|
||||
一个前置知识:同步是将用户词按时序合并导入导出的本地操作。
|
||||
|
||||
⚠️请不要将这个rime文件夹部署到同步软件下面,这将造成数据库被同步锁定无法正常工作,同步的最高级目录为/sync
|
||||
|
||||
确认你的同步目录,默认用户目录下面的/sync,如果自定义在installation.yaml文件中写入
|
||||
|
||||
linux\mac\android这样写:
|
||||
```
|
||||
sync_dir: "/home/amz/sync"
|
||||
```
|
||||
windows这样写:
|
||||
```
|
||||
sync_dir: "D:\\home\\amz\\sync" #双引号
|
||||
sync_dir: 'D:\home\amz\sync' #单引号
|
||||
```
|
||||
|
||||
你还可以将installation_id字段改成一个可辨识的名称如按系统命名
|
||||
|
||||
知道了这些以后你可以创建以下文件夹,他们的名称来自installation_id字段
|
||||
```
|
||||
xxx/sync/windows
|
||||
xxx/sync/linux
|
||||
xxx/sync/ios
|
||||
```
|
||||
|
||||
你完全可以在用户目录看到wanxiang.userdb,他就是你实时工作的数据库PRO版本是zc.userdb,当你点击右键菜单,同步用户数据时
|
||||
|
||||
系统将会将用户词库以txt方式释放到`xxx/sync/windows/wanxiang.userdb.txt`
|
||||
|
||||
每一个wanxiang.userdb.txt表头都有一个表头
|
||||
|
||||
```
|
||||
# Rime user dictionary
|
||||
#@/db_name zc
|
||||
#@/db_type userdb
|
||||
#@/rime_version 1.13.1
|
||||
#@/tick 793
|
||||
#@/user_id ff9b2823-8733-44bb-a497-daf382b74ca5
|
||||
```
|
||||
关注db_name必须与用户词典文件名一致,且不管多个设备不同设备文件夹下面的文件名称都应该一致,看起来都是wanxiang.userdb.txt
|
||||
|
||||
关注user_id=windows(设备文件夹名称)=installation_id字段必须保持一致
|
||||
|
||||
如果只有一个设备,你完全可以在同步后删除用户目录的`userdb`,手动编辑`xxx/sync/windows/wanxiang.userdb.txt`
|
||||
|
||||
注意这里的编辑必须是经过预处理格式与万象编码完全一致的情形下,万象提供的工具就可以完成声调标注和辅助码标注
|
||||
|
||||
编辑好文件,确保放入设备目录,点击同步即可导入数据库
|
||||
|
||||
你还可以将你迁移的数据txt内部设备名称都修改成linux,并将文件放入xxx/sync/linux
|
||||
|
||||
此时点击同步也能将用户词与windows文件夹下面的合并一起导入数据库,模拟多设备同步,这也是未来真正的多设备同步逻辑
|
||||
|
||||
- [用于Linux Mac的词库刷拼音辅助码工具](https://github.com/amzxyz/RIME-LMDG/releases/download/tools/wanxiang-dicts-tools-linux-mac)
|
||||
|
||||
- [用于Windows的词库刷拼音辅助码工具](https://github.com/amzxyz/RIME-LMDG/releases/download/tools/wanxiang-dicts-tools.exe)
|
||||
|
||||
|
||||
<img alt="pay" src="./custom/万象输入方案.png">
|
||||
|
||||
## 鸣谢
|
||||
|
||||
- 感谢网友的热情提报问题,使得模型和词库体验进一步提升。
|
||||
|
||||
## 赞赏
|
||||
|
||||
如果觉得项目好用,可以请AMZ喝咖啡
|
||||
|
||||
<img alt="pay" src="./custom/赞赏.jpg" height="312" width="446">
|
||||
46238
custom/aux_code.txt
Normal file
46238
custom/aux_code.txt
Normal file
File diff suppressed because it is too large
Load Diff
17756
custom/jm_flypy.txt
Normal file
17756
custom/jm_flypy.txt
Normal file
File diff suppressed because it is too large
Load Diff
1766
custom/jm_zrm.txt
Normal file
1766
custom/jm_zrm.txt
Normal file
File diff suppressed because it is too large
Load Diff
151
custom/patch方法论.md
Normal file
151
custom/patch方法论.md
Normal file
@@ -0,0 +1,151 @@
|
||||
|
||||
# Rime YAML Custom Patch 语法指南
|
||||
|
||||
## 语法表格
|
||||
|
||||
| 操作类型 | 语法 | 说明 |
|
||||
| -------------- | ------------------------- | ---------------------------- |
|
||||
| **新增** | `key/+:` | 在某个列表中追加值,自动加在末尾 |
|
||||
| **删除** | `key/-:`(不可用) | 从列表中移除值(不可用) |
|
||||
| **全局替换** | `key: new_value` | 替换整个键的值 |
|
||||
| **部分替换** | `key/index/subkey: value` | 修改列表中的特定项,不影响其他项 |
|
||||
| **特定行替换** | engine/filters/@12 | 替换列表中第13行的值 |
|
||||
| **末尾行替换** | engine/processors/@last | 替换列表中最后一行的值 |
|
||||
| **特定行追加** | engine/filters/@before 5 | 在第6行插入新值,原值后移一行 |
|
||||
|
||||
注意:在进行有关特定行的操作时,请注意列表的计数是从0开始的。例如,如果想在第5行插入一个值,应该使用`@before 4`。如果要替换第5行的值,应该使用`@4`。
|
||||
|
||||
---
|
||||
|
||||
## 1. **新增值 (`/+`)**
|
||||
|
||||
```yaml
|
||||
patch:
|
||||
schema_list/+:
|
||||
- luna_pinyin # 这是正确的例子:追加这个方案列表为启用状态,多个值列表即可
|
||||
schema_list/-: wubi # 这是一个错误的例子:/-不可被使用
|
||||
engine/filters/-:
|
||||
- lua_filter@*en_spacer #这是一个错误的例子:/-不可被使用
|
||||
menu/page_size: 10 # 这是正确的例子:单独替换最下层具体的值 page_size 值,不影响其他值
|
||||
|
||||
|
||||
更多方式参考rime文档
|
||||
|
||||
```
|
||||
|
||||
# Rime YAML Patch 机制解析
|
||||
|
||||
## 为什么 `menu/page_size: 10` 和 `menu: { page_size: 10 }` 结果不同?
|
||||
|
||||
在 **Rime YAML Patch 机制** 下,`menu/page_size: 10` 和 `menu: { page_size: 10 }` **看似等价**,但 **行为是不同的**,主要原因在于 **Patch 机制的覆盖策略**。
|
||||
|
||||
- **`menu/page_size: 10`** 仅修改 `menu` 下的 `page_size`,不会影响 `menu` 里的其他键值。
|
||||
- **`menu: { page_size: 10 }`** **会直接覆盖** `menu`,即 **清空 `menu` 下原有的所有内容**,只留下 `page_size`。
|
||||
|
||||
---
|
||||
|
||||
**假设一个段落:**
|
||||
|
||||
```yaml
|
||||
menu:
|
||||
page_size: 10
|
||||
settings:
|
||||
font_size: 14
|
||||
color: blue
|
||||
|
||||
```
|
||||
|
||||
**正确写法(不会删除 `settings`)就是局部修改值:**
|
||||
|
||||
```yaml
|
||||
patch:
|
||||
menu/page_size: 10
|
||||
```
|
||||
|
||||
**错误写法(会删除 `settings`)就是全局替换:**
|
||||
|
||||
```yaml
|
||||
patch:
|
||||
menu:
|
||||
- page_size: 10
|
||||
```
|
||||
|
||||
**以下是常用的三种情况:**
|
||||
|
||||
```yaml
|
||||
#整体替换
|
||||
patch:
|
||||
engine:
|
||||
translators:
|
||||
- table_translator@custom_phrase #此例会替换整个engine模块的值,只保留translators下的table_translator@custom_phrase,其他值全部删除
|
||||
|
||||
```
|
||||
|
||||
```yaml
|
||||
#部分替换
|
||||
patch:
|
||||
engine/translators:
|
||||
- table_translator@custom_phrase #此例只会替换engine下的translators模块的值为table_translator@custom_phrase,translators模块的其他值全部删除,而engine其他模块的值不受影响
|
||||
|
||||
```
|
||||
|
||||
```yaml
|
||||
#追加新的内容
|
||||
patch:
|
||||
engine/translators/+:
|
||||
- table_translator@custom_phrase #此例只在engine下的translators模块下新增table_translator@custom_phrase,translators模块的其他值不变,engine其他模块的值也不受影响
|
||||
|
||||
```
|
||||
|
||||
也就是说不能用/-,如果想要删除某一行
|
||||
|
||||
下面再用两个实际的例子来巩固一下:
|
||||
|
||||
```yaml
|
||||
#由于下面列表值,所以你想删除某一行只能在这里注释掉,还要观察主方案是否提供了新的值,删除某一个单独的值确实是个难点
|
||||
patch:
|
||||
engine/filters:
|
||||
- lua_filter@*chars_filter
|
||||
- lua_filter@*cold_word_drop.filter
|
||||
- lua_filter@*assist_sort
|
||||
- lua_filter@*autocap_filter
|
||||
- reverse_lookup_filter@radical_reverse_lookup
|
||||
- lua_filter@*pro_preedit_format
|
||||
- simplifier@emoji
|
||||
- simplifier@traditionalize
|
||||
- simplifier@mars
|
||||
- simplifier@chinese_english
|
||||
- simplifier@zrm_chaifen
|
||||
- lua_filter@*search@radical_pinyin
|
||||
#- lua_filter@*en_spacer
|
||||
- lua_filter@*pro_comment_format
|
||||
- uniquifier
|
||||
```
|
||||
|
||||
```yaml
|
||||
#但是如果你想删除某一行携带值的整行,有办法了,用如下的表示即可,将现有的值清空,部署的时候整行也就不会生效了,这一行就不存在了
|
||||
patch:
|
||||
custom_phrase/user_dict:
|
||||
custom_phrase/initial_quality:
|
||||
```
|
||||
|
||||
最后还要注意一点,非常重要:
|
||||
|
||||
在engine模块下面的选项是有顺序的,所以想要新增一个行,需要判断添加到末尾是否可用,如果是一个引导器就不能下面这样添加,这会导致这一行排列在最后,导致功能不能使用
|
||||
|
||||
```yaml
|
||||
#追加新的内容
|
||||
patch:
|
||||
engine/translators/+: #这种方式将把新增值自动加在列表末尾,导致功能失效
|
||||
- table_translator@custom_phrase
|
||||
```
|
||||
|
||||
应该使用**特定行追加** engine/translator/@before 5 意思就是放到translator下面的第6行,而原来第6行的值会移到第7行,其他的依次后移
|
||||
|
||||
```yaml
|
||||
patch:
|
||||
engine/translator/@before 5: #这种方式将在第5行后面新增一行,后面的行后移
|
||||
table_translator@custom_phrase #注意前面不能加短线了,这样才是一个值,而不是一个表
|
||||
engine/translator/@5: #这种方式将替换第6行的值
|
||||
table_translator@custom_phrase #注意前面不能加短线了,这样才是一个值,而不是一个表
|
||||
```
|
||||
41742
custom/tips_user.txt
Normal file
41742
custom/tips_user.txt
Normal file
File diff suppressed because it is too large
Load Diff
272
custom/wanxiang.custom.yaml
Normal file
272
custom/wanxiang.custom.yaml
Normal file
@@ -0,0 +1,272 @@
|
||||
#使用之前请详细遍历每一行,都注释了功能点,看清楚是不是你要的,需不需要修改参数,哪些该留,哪些该删除,够语重心长了吧😄
|
||||
patch:
|
||||
speller/algebra:
|
||||
__patch:
|
||||
#- 模糊音 # 这里启用后,本文件末尾可配置具体条目
|
||||
- wanxiang_algebra:/base/全拼 # 可选输入方案名称:全拼,自然码, 自然龙, 汉心龙,小鹤双拼, 搜狗双拼, 微软双拼, 智能ABC, 紫光双拼, 国标双拼,拼音加加,乱序17
|
||||
##########################以上格式受指令初始化控制,最好保持格式不变,如果发生变更请不要使用指令修改相关数据#####################################
|
||||
#custom_phrase/user_dict: custom_phrasexx # 这里改成什么就需要手动创建同名的 custom_phrasexx.txt 文件在用户目录,这个文件主要用于置顶,编码为自定义编码的词汇
|
||||
#translator/packs/+:
|
||||
#- userxx #导入根目录下名称为userxx.dict.yaml的自定义固定词典,编码要与固定词库一致,编码权重都不要少,形如姓名、专有名词公司名称等等
|
||||
#下面是候选数量
|
||||
menu/page_size: 6 #不要超过6,7890用于代表声调1234,6个管够你用了,如果你非要10个,不要问我😜。
|
||||
#下面是超级注释相关
|
||||
super_comment: # 超级注释模块,子项配置 true 开启,false 关闭
|
||||
candidate_length: 1 # 候选词辅助码提醒的生效长度,0为关闭 但同时清空其它,应当使用上面开关来处理
|
||||
corrector_type: "〔comment〕" # 错音措字,随意更换左右括号,比如"〔comment〕" 不加括号为无括号,comment占位不能动
|
||||
chaifen: "〔chaifen〕" # 拆分显示,随意更换左右括号,比如"〔chaifen〕" 不加括号为无括号,chaifen占位不能动
|
||||
|
||||
#在8105基础上你可以通过黑白名单微调你自己的字符集过滤清单,主数据库位于lua/charset.bin不可编辑
|
||||
charsetlist: [你]
|
||||
charsetblacklist: [鹵, 彔]
|
||||
|
||||
#小键盘数字处理逻辑
|
||||
# "compose" : 小键盘数字始终参与编码
|
||||
# "auto" : 输入中 push,空闲时 commit(默认)
|
||||
kp_number_mode: auto
|
||||
|
||||
#下面用于对/rq和N20250101这样的日期候选自定义(顺序、类型、候选个数)由你完全掌控,前面是对于公历后面默认携带农历
|
||||
# 通用日期时间格式化函数(供 /rq、/sj、/dt、N0101、N20150101 场景复用)
|
||||
# 支持转义:
|
||||
# \X —— 转义单个字符 X,按字面量输出(如 \Y \m \H 等)
|
||||
# [[...]] —— 区块整体按字面量输出
|
||||
#
|
||||
# 约定占位符:
|
||||
# 【日期】
|
||||
# Y 四位年份 0000-9999 例:2025
|
||||
# y 两位年份 00-99 例:25
|
||||
# m 月(前导零) 01-12 例:02
|
||||
# n 月(不带前导零) 1-12 例:2
|
||||
# d 日(前导零) 01-31 例:09
|
||||
# j 日(不带前导零) 1-31 例:9
|
||||
#
|
||||
# 【时间】
|
||||
# H 24小时(前导零) 00-23 例:08
|
||||
# G 24小时(不带零) 0-23 例:8
|
||||
# I 12小时(前导零) 01-12 例:08
|
||||
# l 12小时(不带零) 1-12 例:8 (注意是小写 L)
|
||||
# M 分钟(前导零) 00-59 例:05
|
||||
# S 秒(前导零) 00-59 例:09
|
||||
# p am/pm(小写) am / pm
|
||||
# P AM/PM(大写) AM / PM
|
||||
# 【时区】
|
||||
# O 带冒号格式 +08:00、-04:30、+05:45
|
||||
# o 不带冒号格式 +0800、-0430、+0545
|
||||
date_formats:
|
||||
- "Y年m月d日"
|
||||
- "Y-m-d"
|
||||
- "Y/m/d"
|
||||
- "Y.m.d"
|
||||
- "Ymd"
|
||||
- "Y年n月j日"
|
||||
- "y年n月j日"
|
||||
- "n月j日"
|
||||
time_formats:
|
||||
- "H:M"
|
||||
- "H点M分"
|
||||
- "H:M:S"
|
||||
- "H时M分S秒"
|
||||
- "下午I:M"
|
||||
- "I:M P"
|
||||
datetime_formats:
|
||||
- "Y-m-d H:M:S"
|
||||
- "Y-m-dTH:M:S O"
|
||||
- "YmdHMS"
|
||||
- "Y年m月d日 H点M分"
|
||||
- "y/m/d I:M p"
|
||||
#下面用来改变你的windows小狼毫右下角软件图标
|
||||
#schema/+:
|
||||
# icon: "icons/zhong.ico"
|
||||
# ascii_icon: "icons/ying.ico"
|
||||
#下面这个可以改变tips上屏的按键
|
||||
key_binder/tips_key: "comma" #修改时候去default找,默认是逗号
|
||||
key_binder/sequence: # Lua 配置:手动排序的快捷键 super_sequence.lua,不要用方向键,各种冲突,一定要避免冲突
|
||||
up: "Control+j" # 上移
|
||||
down: "Control+k" # 下移
|
||||
reset: "Control+l" # 重置
|
||||
pin: "Control+p" # 置顶
|
||||
# 快符功能:
|
||||
# a/、单字母组合,触发预设编码自动上屏快符,支持将值设为"repeat" 以支持对应按键重复上屏功能,custom>schema>lua最终合并键值
|
||||
# 现在就支持26字母快符,结合成对符号输入,这边的压力小一些
|
||||
quick_symbol_text:
|
||||
trigger: "^([a-z])/$"
|
||||
symkey:
|
||||
q: "repeat"
|
||||
w: "?"
|
||||
e: "("
|
||||
r: ")"
|
||||
t: "~"
|
||||
y: "·"
|
||||
u: "『"
|
||||
i: "』"
|
||||
o: "〖"
|
||||
p: "〗"
|
||||
a: "!"
|
||||
s: "……"
|
||||
d: "、"
|
||||
f: "“"
|
||||
g: "”"
|
||||
h: "‘"
|
||||
j: "’"
|
||||
k: "【"
|
||||
l: "】"
|
||||
z: "。”"
|
||||
x: "?”"
|
||||
c: "!”"
|
||||
v: "——"
|
||||
b: "%"
|
||||
n: "《"
|
||||
m: "》"
|
||||
|
||||
#通过在有候选的情况下,通过末尾检测到形如\a来触发为第一候选进行成对符号包裹例如nihao\c 候选[你好]
|
||||
#trigger只能设置为单符号,因为按下一次锁定第一候选,按下映射开始包裹符号pro用户不能设置为/
|
||||
#两个字符可以不用|默认前后分割,需要明确区分前后的使用|分割,可以有一侧为空,不可以使用多个||
|
||||
paired_symbols:
|
||||
#sort_window: 10
|
||||
trigger: "\\" #(注意反斜杠这是转义写法\\使用时\单反斜杠即可)
|
||||
mirror: true #包裹后完全替换第一候选true,原候选后移到第二false
|
||||
symkey:
|
||||
# ===== 基本括号与引号 =====
|
||||
a: "[]" # 方括号
|
||||
b: "【】" # 黑方头括号
|
||||
c: "❲❳" # 双大括号 / 装饰括号
|
||||
d: "〔〕" # 方头括号
|
||||
e: "⟮⟯" # 小圆括号 / 装饰括号
|
||||
f: "⟦⟧" # 双方括号 / 数学集群括号
|
||||
g: "「」" # 直角引号
|
||||
# h: 预留用于 Markdown 一级标题
|
||||
i: "『』" # 双直角引号
|
||||
j: "<>" # 尖括号
|
||||
k: "《》" # 书名号(双)
|
||||
l: "〈〉" # 书名号(单)
|
||||
m: "‹›" # 法文单书名号
|
||||
n: "«»" # 法文双书名号
|
||||
o: "⦅⦆" # 白圆括号
|
||||
p: "⦇⦈" # 白方括号
|
||||
q: "()" # 圆括号
|
||||
r: "|儿" #儿化候选
|
||||
s: "[]" # 全角方括号
|
||||
t: "⟨⟩" # 数学角括号
|
||||
u: "〈〉" # 数学尖括号
|
||||
v: "〖〗" # 装饰花括号
|
||||
w: "()" # 全角圆括号
|
||||
x: "{}" # 全角花括号
|
||||
y: "⟪⟫" # 双角括号
|
||||
z: "{}" # 花括号
|
||||
|
||||
# ===== 扩展括号族 / 引号 =====
|
||||
dy: "''" # 英文单引号
|
||||
sy: "\"\"" # 英文双引号
|
||||
zs: "“”" # 中文弯双引号
|
||||
zd: "‘’" # 中文弯单引号
|
||||
fy: "``" # 反引号
|
||||
|
||||
# ===== 双字母括号族 =====
|
||||
aa: "〚〛" # 双中括号
|
||||
bb: "〘〙" # 双中括号(小)
|
||||
cc: "〚〛" # 双中括号(重复,可用于 Lua 匹配)
|
||||
dd: "❨❩" # 小圆括号装饰
|
||||
ee: "❪❫" # 小圆括号装饰
|
||||
ff: "❬❭" # 小尖括号装饰
|
||||
gg: "⦉⦊" # 双弯方括号
|
||||
ii: "⦍⦎" # 双弯方括号
|
||||
jj: "⦏⦐" # 双弯方括号
|
||||
kk: "⦑⦒" # 双弯方括号
|
||||
ll: "❮❯" # 小尖括号装饰
|
||||
mm: "⌈⌉" # 上取整 / 数学符号
|
||||
nn: "⌊⌋" # 下取整 / 数学符号
|
||||
oo: "⦗⦘" # 双方括号装饰(补齐)
|
||||
pp: "⦙⦚" # 双方括号装饰(补齐)
|
||||
qq: "⟬⟭" # 小双角括号
|
||||
rr: "❴❵" # 花括号装饰
|
||||
ss: "⌜⌝" # 数学上角符号
|
||||
tt: "⌞⌟" # 数学下角符号
|
||||
uu: "⸢⸣" # 装饰方括号
|
||||
vv: "⸤⸥" # 装饰方括号
|
||||
ww: "﹁﹂" # 中文书名号 / 注释引号
|
||||
xx: "﹃﹄" # 中文书名号 / 注释引号
|
||||
yy: "⌠⌡" # 数学 / 程序符号
|
||||
zz: "⟅⟆" # 数学 / 装饰括号
|
||||
|
||||
# ===== Markdown / 标记 =====
|
||||
md: "**|**" # Markdown 粗体
|
||||
jc: "**|**" # 加粗
|
||||
it: "__|__" # 斜体
|
||||
st: "~~|~~" # 删除线
|
||||
eq: "==|==" # 高亮
|
||||
ln: "`|`" # 行内代码
|
||||
cb: "```|```" # 代码块
|
||||
qt: "> |" # 引用
|
||||
ul: "- |" # 无序列表项
|
||||
ol: "1. |" # 有序列表项
|
||||
lk: "[|](url)" # 链接
|
||||
im: "" # 图片
|
||||
h: "# |" # 一级标题
|
||||
hh: "## |" # 二级标题
|
||||
hhh: "### |" # 三级标题
|
||||
hhhh: "#### |" # 四级标题
|
||||
sp: "\\|" # 反斜杠转义
|
||||
br: "| " # 换行
|
||||
cm: "<!--|-->" # 注释
|
||||
|
||||
# ===== 运算与标记符 =====
|
||||
pl: "++"
|
||||
mi: "--"
|
||||
sl: "//"
|
||||
bs: "\\\\"
|
||||
at: "@@"
|
||||
dl: "$$"
|
||||
pc: "%%"
|
||||
an: "&&"
|
||||
cr: "^^"
|
||||
cl: "::"
|
||||
sc: ";;"
|
||||
ex: "!!"
|
||||
qu: "??"
|
||||
sb: "sb"
|
||||
|
||||
#translator/enable_user_dict: true # 是否开启自动调频用户词,如果你希望使用下面``造词功能,请保持false,因为两个跨翻译器会造成词汇不能正常记录
|
||||
|
||||
#以下恢复``造词功能,也就是平时不记录,引导才记录,按需造词,如果你想恢复这个功能,请取消注释----
|
||||
#recognizer/patterns/add_user_dict: "^``[A-Za-z/`']*$" #自造词引导方式
|
||||
#user_dict_set/enable_user_dict: true
|
||||
#add_user_dict/enable_user_dict: true
|
||||
# 取消注释以开启自动无词频造词
|
||||
#add_user_dict/enable_auto_phrase: true
|
||||
#按需造词全功能段落结束---------------------------------------------------------------
|
||||
|
||||
模糊音:
|
||||
__append:
|
||||
# n - l
|
||||
- derive/^l/n
|
||||
- derive/^n/l
|
||||
# r - y 开头
|
||||
- derive/^y/r
|
||||
- derive/^r/y
|
||||
# h - f 开头
|
||||
- derive/^h/f
|
||||
- derive/^f/h
|
||||
# r - l 开头
|
||||
- derive/^r/l
|
||||
- derive/^l/r
|
||||
# k - g 开头
|
||||
- derive/^k/g
|
||||
- derive/^g/k
|
||||
# an - ang
|
||||
- derive/([ui]?)([āáǎàa])ng(.*)$/$1$2n$3
|
||||
- derive/([ui]?)([āáǎàa])n(.*)$/$1$2ng$3
|
||||
# en - eng
|
||||
- derive/([ēéěèe])ng(.*)$/$1n$2
|
||||
- derive/([ēéěèe])n(.*)$/$1ng$2
|
||||
# in - ing
|
||||
- derive/([īíǐìi])ng(.*)$/$1n$2
|
||||
- derive/([īíǐìi])n(.*)$/$1ng$2
|
||||
# c - ch
|
||||
- derive/^c([^h]*)/ch$1
|
||||
- derive/^ch/c
|
||||
# z - zh
|
||||
- derive/^z([^h]*)/zh$1
|
||||
- derive/^zh/z
|
||||
# s - sh
|
||||
- derive/^s([^h]*)/sh$1
|
||||
- derive/^sh/s
|
||||
12
custom/wanxiang_chaifen.schema.yaml
Normal file
12
custom/wanxiang_chaifen.schema.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
# Rime schema settings
|
||||
# encoding: utf-8
|
||||
|
||||
schema:
|
||||
schema_id: wanxiang_chaifen
|
||||
name: 万象:拆分注释滤镜
|
||||
version: "1.0"
|
||||
|
||||
engine:
|
||||
|
||||
translator:
|
||||
dictionary: wanxiang_chaifen
|
||||
8115
custom/wanxiang_chaifen_flypy.dict.yaml
Normal file
8115
custom/wanxiang_chaifen_flypy.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
8339
custom/wanxiang_chaifen_hanxin.dict.yaml
Normal file
8339
custom/wanxiang_chaifen_hanxin.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
40512
custom/wanxiang_chaifen_moqi.dict.yaml
Normal file
40512
custom/wanxiang_chaifen_moqi.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
20910
custom/wanxiang_chaifen_shouyou.dict.yaml
Normal file
20910
custom/wanxiang_chaifen_shouyou.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
81236
custom/wanxiang_chaifen_tiger.dict.yaml
Normal file
81236
custom/wanxiang_chaifen_tiger.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
81235
custom/wanxiang_chaifen_wubi.dict.yaml
Normal file
81235
custom/wanxiang_chaifen_wubi.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
81568
custom/wanxiang_chaifen_zrm.dict.yaml
Normal file
81568
custom/wanxiang_chaifen_zrm.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
4
custom/wanxiang_mixedcode.custom.yaml
Normal file
4
custom/wanxiang_mixedcode.custom.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
patch:
|
||||
speller/algebra:
|
||||
__include: wanxiang_algebra:/mixed/通用派生规则
|
||||
__patch: wanxiang_algebra:/mixed/全拼 #可选的选项有(全拼, 自然码, 小鹤双拼, 微软双拼, 搜狗双拼, 智能ABC, 紫光双拼, 拼音加加, 自然龙, 汉心龙)
|
||||
280
custom/wanxiang_pro.custom.yaml
Normal file
280
custom/wanxiang_pro.custom.yaml
Normal file
@@ -0,0 +1,280 @@
|
||||
patch:
|
||||
speller/algebra:
|
||||
__patch:
|
||||
#- 模糊音 # 这里启用后,本文件末尾可配置具体条目
|
||||
- wanxiang_algebra:/pro/自然码 # 可选输入方案名称:自然码, 自然龙, 小鹤双拼, 搜狗双拼, 微软双拼, 智能ABC, 紫光双拼, 国标双拼,龙三
|
||||
- wanxiang_algebra:/pro/直接辅助 #辅助码升级为:直接辅助和间接辅助两种类型,都是句中任意,不同点在于直接辅助是nire=你 而间接则需要/引导 ni/re=你 ,在这个基础上直接辅助支持拼音后任意位置数字声调参与,间接辅助声调在/引导前参与
|
||||
#- 自然码提权 #本文件末尾,有自然码和小鹤的可以用
|
||||
##########################以上格式受指令初始化控制,最好保持格式不变,如果发生变更请不要使用指令修改相关数据#####################################
|
||||
#通过下面的设置可以让你自己的文件引入而与仓库custom_phrase.txt不同,防止更新时被仓库文件覆盖
|
||||
#custom_phrase/user_dict: custom_phrasexx # 这里改成什么就需要手动创建同名的 custom_phrasexx.txt 文件在用户目录,这个文件主要用于置顶,编码为自定义编码的词汇
|
||||
#translator/packs/+:
|
||||
#- userxx #导入根目录下名称为userxx.dict.yaml的自定义固定词典,编码要与固定词库一致,编码权重都不要少,形如姓名、专有名词公司名称等等
|
||||
#下面是候选数量,未来7890分别代表1234声,请候选长度不要大于6避免冲突
|
||||
menu/page_size: 6
|
||||
#下面是超级注释相关
|
||||
super_comment: # 超级注释模块,子项配置 true 开启,false 关闭
|
||||
candidate_length: 1 # 候选词辅助码提醒的生效长度,0为关闭 但同时清空其它,应当使用上面开关来处理
|
||||
corrector_type: "〔comment〕" # 错音措字,随意更换左右括号,比如"〔comment〕" 不加括号为无括号,comment占位不能动
|
||||
chaifen: "〔chaifen〕" # 拆分显示,随意更换左右括号,比如"〔chaifen〕" 不加括号为无括号,chaifen占位不能动
|
||||
|
||||
#在8105基础上你可以通过黑白名单微调你自己的字符集过滤清单,主数据库位于lua/charset.bin不可编辑
|
||||
charsetlist: [你]
|
||||
charsetblacklist: [鹵, 彔]
|
||||
|
||||
#小键盘数字处理逻辑
|
||||
# "compose" : 小键盘数字始终参与编码
|
||||
# "auto" : 输入中 push,空闲时 commit(默认)
|
||||
kp_number_mode: auto
|
||||
|
||||
#下面用于对/rq和N20250101这样的日期候选自定义(顺序、类型、候选个数)由你完全掌控,前面是对于公历后面默认携带农历
|
||||
# 通用日期时间格式化函数(供 /rq、/sj、/dt、N0101、N20150101 场景复用)
|
||||
# 支持转义:
|
||||
# \X —— 转义单个字符 X,按字面量输出(如 \Y \m \H 等)
|
||||
# [[...]] —— 区块整体按字面量输出
|
||||
#
|
||||
# 约定占位符:
|
||||
# 【日期】
|
||||
# Y 四位年份 0000-9999 例:2025
|
||||
# y 两位年份 00-99 例:25
|
||||
# m 月(前导零) 01-12 例:02
|
||||
# n 月(不带前导零) 1-12 例:2
|
||||
# d 日(前导零) 01-31 例:09
|
||||
# j 日(不带前导零) 1-31 例:9
|
||||
#
|
||||
# 【时间】
|
||||
# H 24小时(前导零) 00-23 例:08
|
||||
# G 24小时(不带零) 0-23 例:8
|
||||
# I 12小时(前导零) 01-12 例:08
|
||||
# l 12小时(不带零) 1-12 例:8 (注意是小写 L)
|
||||
# M 分钟(前导零) 00-59 例:05
|
||||
# S 秒(前导零) 00-59 例:09
|
||||
# p am/pm(小写) am / pm
|
||||
# P AM/PM(大写) AM / PM
|
||||
# 【时区】
|
||||
# O 带冒号格式 +08:00、-04:30、+05:45
|
||||
# o 不带冒号格式 +0800、-0430、+0545
|
||||
date_formats:
|
||||
- "Y年m月d日"
|
||||
- "Y-m-d"
|
||||
- "Y/m/d"
|
||||
- "Y.m.d"
|
||||
- "Ymd"
|
||||
- "Y年n月j日"
|
||||
- "y年n月j日"
|
||||
- "n月j日"
|
||||
time_formats:
|
||||
- "H:M"
|
||||
- "H点M分"
|
||||
- "H:M:S"
|
||||
- "H时M分S秒"
|
||||
- "下午I:M"
|
||||
- "I:M P"
|
||||
datetime_formats:
|
||||
- "Y-m-d H:M:S"
|
||||
- "Y-m-dTH:M:S O"
|
||||
- "YmdHMS"
|
||||
- "Y年m月d日 H点M分"
|
||||
- "y/m/d I:M p"
|
||||
#下面用来改变你的windows小狼毫右下角软件图标
|
||||
#schema/+:
|
||||
# icon: "icons/zhong.ico"
|
||||
# ascii_icon: "icons/ying.ico"
|
||||
#下面这个可以改变tips上屏的按键
|
||||
key_binder/tips_key: "comma" #修改时候去default找,默认是逗号
|
||||
key_binder/sequence: # Lua 配置:手动排序的快捷键 super_sequence.lua,不要用方向键,各种冲突,一定要避免冲突
|
||||
up: "Control+j" # 上移
|
||||
down: "Control+k" # 下移
|
||||
reset: "Control+l" # 重置
|
||||
pin: "Control+p" # 置顶
|
||||
# 快符功能:
|
||||
# a/、单字母组合,触发预设编码自动上屏快符,支持将值设为"repeat" 以支持对应按键重复上屏功能,custom>schema>lua最终合并键值
|
||||
# 现在就支持26字母快符,结合成对符号输入,这边的压力小一些
|
||||
quick_symbol_text:
|
||||
trigger: "^([a-z])/$"
|
||||
symkey:
|
||||
q: "repeat"
|
||||
w: "?"
|
||||
e: "("
|
||||
r: ")"
|
||||
t: "~"
|
||||
y: "·"
|
||||
u: "『"
|
||||
i: "』"
|
||||
o: "〖"
|
||||
p: "〗"
|
||||
a: "!"
|
||||
s: "……"
|
||||
d: "、"
|
||||
f: "“"
|
||||
g: "”"
|
||||
h: "‘"
|
||||
j: "’"
|
||||
k: "【"
|
||||
l: "】"
|
||||
z: "。”"
|
||||
x: "?”"
|
||||
c: "!”"
|
||||
v: "——"
|
||||
b: "%"
|
||||
n: "《"
|
||||
m: "》"
|
||||
|
||||
#通过在有候选的情况下,通过末尾检测到形如\a来触发为第一候选进行成对符号包裹例如nihao\c 候选[你好]
|
||||
#trigger只能设置为单符号,因为按下一次锁定第一候选,按下映射开始包裹符号pro用户不能设置为/
|
||||
#两个字符可以不用|默认前后分割,需要明确区分前后的使用|分割,可以有一侧为空,不可以使用多个||
|
||||
paired_symbols:
|
||||
#sort_window: 10
|
||||
trigger: "\\" #(注意反斜杠这是转义写法\\使用时\单反斜杠即可)
|
||||
mirror: true #包裹后完全替换第一候选true,原候选后移到第二false
|
||||
symkey:
|
||||
# ===== 基本括号与引号 =====
|
||||
a: "[]" # 方括号
|
||||
b: "【】" # 黑方头括号
|
||||
c: "❲❳" # 双大括号 / 装饰括号
|
||||
d: "〔〕" # 方头括号
|
||||
e: "⟮⟯" # 小圆括号 / 装饰括号
|
||||
f: "⟦⟧" # 双方括号 / 数学集群括号
|
||||
g: "「」" # 直角引号
|
||||
# h: 预留用于 Markdown 一级标题
|
||||
i: "『』" # 双直角引号
|
||||
j: "<>" # 尖括号
|
||||
k: "《》" # 书名号(双)
|
||||
l: "〈〉" # 书名号(单)
|
||||
m: "‹›" # 法文单书名号
|
||||
n: "«»" # 法文双书名号
|
||||
o: "⦅⦆" # 白圆括号
|
||||
p: "⦇⦈" # 白方括号
|
||||
q: "()" # 圆括号
|
||||
r: "|儿" #儿化候选
|
||||
s: "[]" # 全角方括号
|
||||
t: "⟨⟩" # 数学角括号
|
||||
u: "〈〉" # 数学尖括号
|
||||
v: "〖〗" # 装饰花括号
|
||||
w: "()" # 全角圆括号
|
||||
x: "{}" # 全角花括号
|
||||
y: "⟪⟫" # 双角括号
|
||||
z: "{}" # 花括号
|
||||
|
||||
# ===== 扩展括号族 / 引号 =====
|
||||
dy: "''" # 英文单引号
|
||||
sy: "\"\"" # 英文双引号
|
||||
zs: "“”" # 中文弯双引号
|
||||
zd: "‘’" # 中文弯单引号
|
||||
fy: "``" # 反引号
|
||||
|
||||
# ===== 双字母括号族 =====
|
||||
aa: "〚〛" # 双中括号
|
||||
bb: "〘〙" # 双中括号(小)
|
||||
cc: "〚〛" # 双中括号(重复,可用于 Lua 匹配)
|
||||
dd: "❨❩" # 小圆括号装饰
|
||||
ee: "❪❫" # 小圆括号装饰
|
||||
ff: "❬❭" # 小尖括号装饰
|
||||
gg: "⦉⦊" # 双弯方括号
|
||||
ii: "⦍⦎" # 双弯方括号
|
||||
jj: "⦏⦐" # 双弯方括号
|
||||
kk: "⦑⦒" # 双弯方括号
|
||||
ll: "❮❯" # 小尖括号装饰
|
||||
mm: "⌈⌉" # 上取整 / 数学符号
|
||||
nn: "⌊⌋" # 下取整 / 数学符号
|
||||
oo: "⦗⦘" # 双方括号装饰(补齐)
|
||||
pp: "⦙⦚" # 双方括号装饰(补齐)
|
||||
qq: "⟬⟭" # 小双角括号
|
||||
rr: "❴❵" # 花括号装饰
|
||||
ss: "⌜⌝" # 数学上角符号
|
||||
tt: "⌞⌟" # 数学下角符号
|
||||
uu: "⸢⸣" # 装饰方括号
|
||||
vv: "⸤⸥" # 装饰方括号
|
||||
ww: "﹁﹂" # 中文书名号 / 注释引号
|
||||
xx: "﹃﹄" # 中文书名号 / 注释引号
|
||||
yy: "⌠⌡" # 数学 / 程序符号
|
||||
zz: "⟅⟆" # 数学 / 装饰括号
|
||||
|
||||
# ===== Markdown / 标记 =====
|
||||
md: "**|**" # Markdown 粗体
|
||||
jc: "**|**" # 加粗
|
||||
it: "__|__" # 斜体
|
||||
st: "~~|~~" # 删除线
|
||||
eq: "==|==" # 高亮
|
||||
ln: "`|`" # 行内代码
|
||||
cb: "```|```" # 代码块
|
||||
qt: "> |" # 引用
|
||||
ul: "- |" # 无序列表项
|
||||
ol: "1. |" # 有序列表项
|
||||
lk: "[|](url)" # 链接
|
||||
im: "" # 图片
|
||||
h: "# |" # 一级标题
|
||||
hh: "## |" # 二级标题
|
||||
hhh: "### |" # 三级标题
|
||||
hhhh: "#### |" # 四级标题
|
||||
sp: "\\|" # 反斜杠转义
|
||||
br: "| " # 换行
|
||||
cm: "<!--|-->" # 注释
|
||||
|
||||
# ===== 运算与标记符 =====
|
||||
pl: "++"
|
||||
mi: "--"
|
||||
sl: "//"
|
||||
bs: "\\\\"
|
||||
at: "@@"
|
||||
dl: "$$"
|
||||
pc: "%%"
|
||||
an: "&&"
|
||||
cr: "^^"
|
||||
cl: "::"
|
||||
sc: ";;"
|
||||
ex: "!!"
|
||||
qu: "??"
|
||||
sb: "sb"
|
||||
|
||||
#开启自动无词频造词(默认已经开了)
|
||||
#add_user_dict/enable_auto_phrase: true
|
||||
|
||||
#下面的数据有需要的可以patch引用
|
||||
#特殊优化:部分音节字极少,几乎不参与构词,则提升对应四码字的优先级,仅对小鹤双拼有效,其他双拼方案需作对应修改)
|
||||
小鹤双拼提权:
|
||||
__append:
|
||||
- derive/^(.*?)(\d?);(bl|dx|df|eg|fn|kw|ny|tw|vw|yd|rx|fs|ix)$/$1$3/
|
||||
- derive/^(.*?)(\d?);.*?,(bl|dx|df|eg|fn|kw|ny|tw|vw|yd|rx|fs|ix)$/$1$3/
|
||||
|
||||
#特殊优化:部分音节字极少,几乎不参与构词,则提升对应四码字的优先级,仅对自然码有效,其他双拼方案需作对应修改)
|
||||
自然码提权:
|
||||
__append:
|
||||
- derive/^(.*?)(\d?);(jb|wq|aq|av|dn|xh|bv|jz|hm|sn|cd|iw|xl|ak|zy|fy|uz|yx|wb|wr|yw|dz|qz|ms|at|xf|gi|gn|or|ux|ww|nw|fs|qk|rl|cq|sw|jv|cy|sq|dd|fp|ae|ix|td|ep|ar|wm|pd|et|yz|eh|ct|os|hx|zq|ew|fm|ab|kc|tf|fx|we|sz|wx|bq|ic|ez|bs|ej|oh|ps|pw|fr|pq|au|wc|wp|dt|qf|zc|vx|im|br|mw|un|qb|fi|zm|vn|oz|kt|rq|ay|fn|yc|um|eq|eu|cz|yq|tq|oi|ek|az|fv|zx|ut|vz|ry|ac|ws|af|qv|ea|qj|al|ol|on|sx|ap|df|eg|rz|ey|em|ag|hi|iz|ki|xz|xj|ad|ft|pt|op|vt|oj|kn|pr|hq|eb|ev|cx|zd|am|ov|oq|ym|ef|ot|mr|rd|sy|oc|rc|oe|fq|cn|ok|rn|bp|yv|uc|wk|oy|bt|je|ow|xg|jj|rw|pp|ja|wt|lf|xe|wy|kx|sm|qe|fw|gc|xa|cw|zn|tn|cc|jo|md|sd|ql|kq|it|bd|sc|wv|fc|dw|ob|vm|ed|jl|xo|fl|gq|gt|of|pv|wd|qa|xk|yd|fe|og|iq|oa|uq|om|xv|mv|as|ox|km|zt|od|ht|el|hn|st|wn|mt|wi|tz|aj|yg|bw|jf|jg|kz|es|xb|ax|rt|gx|bb|qo|yf|ex|rx|tt|us|qg|pe|zw|mp|qh|rm|hc|np|jh|cm|yl|eo|ra|vc|aw|tw|fk|gm|ec|be|vq|fd|jk|in)$/$1$3/
|
||||
- derive/^(.*?)(\d?);.*?,(jb|wq|aq|av|dn|xh|bv|jz|hm|sn|cd|iw|xl|ak|zy|fy|uz|yx|wb|wr|yw|dz|qz|ms|at|xf|gi|gn|or|ux|ww|nw|fs|qk|rl|cq|sw|jv|cy|sq|dd|fp|ae|ix|td|ep|ar|wm|pd|et|yz|eh|ct|os|hx|zq|ew|fm|ab|kc|tf|fx|we|sz|wx|bq|ic|ez|bs|ej|oh|ps|pw|fr|pq|au|wc|wp|dt|qf|zc|vx|im|br|mw|un|qb|fi|zm|vn|oz|kt|rq|ay|fn|yc|um|eq|eu|cz|yq|tq|oi|ek|az|fv|zx|ut|vz|ry|ac|ws|af|qv|ea|qj|al|ol|on|sx|ap|df|eg|rz|ey|em|ag|hi|iz|ki|xz|xj|ad|ft|pt|op|vt|oj|kn|pr|hq|eb|ev|cx|zd|am|ov|oq|ym|ef|ot|mr|rd|sy|oc|rc|oe|fq|cn|ok|rn|bp|yv|uc|wk|oy|bt|je|ow|xg|jj|rw|pp|ja|wt|lf|xe|wy|kx|sm|qe|fw|gc|xa|cw|zn|tn|cc|jo|md|sd|ql|kq|it|bd|sc|wv|fc|dw|ob|vm|ed|jl|xo|fl|gq|gt|of|pv|wd|qa|xk|yd|fe|og|iq|oa|uq|om|xv|mv|as|ox|km|zt|od|ht|el|hn|st|wn|mt|wi|tz|aj|yg|bw|jf|jg|kz|es|xb|ax|rt|gx|bb|qo|yf|ex|rx|tt|us|qg|pe|zw|mp|qh|rm|hc|np|jh|cm|yl|eo|ra|vc|aw|tw|fk|gm|ec|be|vq|fd|jk|in)$/$1$3/
|
||||
|
||||
模糊音:
|
||||
__append:
|
||||
# n - l
|
||||
- derive/^l/n
|
||||
- derive/^n/l
|
||||
# r - y 开头
|
||||
- derive/^y/r
|
||||
- derive/^r/y
|
||||
# h - f 开头
|
||||
- derive/^h/f
|
||||
- derive/^f/h
|
||||
# r - l 开头
|
||||
- derive/^r/l
|
||||
- derive/^l/r
|
||||
# k - g 开头
|
||||
- derive/^k/g
|
||||
- derive/^g/k
|
||||
# an - ang
|
||||
- derive/([ui]?)([āáǎàa])ng(.*)$/$1$2n$3
|
||||
- derive/([ui]?)([āáǎàa])n(.*)$/$1$2ng$3
|
||||
# en - eng
|
||||
- derive/([ēéěèe])ng(.*)$/$1n$2
|
||||
- derive/([ēéěèe])n(.*)$/$1ng$2
|
||||
# in - ing
|
||||
- derive/([īíǐìi])ng(.*)$/$1n$2
|
||||
- derive/([īíǐìi])n(.*)$/$1ng$2
|
||||
# c - ch
|
||||
- derive/^c([^h]*)/ch$1
|
||||
- derive/^ch/c
|
||||
# z - zh
|
||||
- derive/^z([^h]*)/zh$1
|
||||
- derive/^zh/z
|
||||
# s - sh
|
||||
- derive/^s([^h]*)/sh$1
|
||||
- derive/^sh/s
|
||||
24
custom/wanxiang_pro.dict.yaml
Normal file
24
custom/wanxiang_pro.dict.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
# Rime dictionary
|
||||
# encoding: utf-8
|
||||
#
|
||||
# rime配置的部署位置:
|
||||
# ~/.local/share/fcitx5/rime 或者 ~/.config/ibus/rime (Linux)
|
||||
# ~/Library/Rime (Mac OS)
|
||||
# %APPDATA%\Rime (Windows)
|
||||
#
|
||||
#
|
||||
|
||||
---
|
||||
name: wanxiang_pro
|
||||
version: "LTS"
|
||||
sort: by_weight #字典初始排序,可選original或by_weight
|
||||
use_preset_vocabulary: false
|
||||
import_tables:
|
||||
- dicts/zi.pro #字表,包含了所有带拼音的汉字
|
||||
- dicts/jichu.pro #基础词库,2-3字词汇
|
||||
- dicts/lianxiang.pro #联想词库,5字以上词汇,多用于输入前半段第二候选可以出来整段
|
||||
- dicts/cuoyin.pro #错音错字,支持错音和错字输入的兼容,同时供超级注释lua使用会在输入错误音节打出的时候给予提示
|
||||
- dicts/duoyin.pro #兼容词库,是基础词库的扩充,收录了多场景多种读音的词组
|
||||
- dicts/shici.pro #诗词
|
||||
- dicts/diming.pro #地名
|
||||
...
|
||||
645
custom/wanxiang_pro.schema.yaml
Normal file
645
custom/wanxiang_pro.schema.yaml
Normal file
@@ -0,0 +1,645 @@
|
||||
# Rime schema
|
||||
# encoding: utf-8
|
||||
# 方案说明
|
||||
schema:
|
||||
schema_id: wanxiang_pro
|
||||
name: 万象拼音PRO
|
||||
version: "LTS"
|
||||
author:
|
||||
- amzxyz
|
||||
description: |
|
||||
请勾选【万象拼音PRO】以启用,万象拼音 支持常见双拼方案和全拼输入,辅助码同时支持 全拼拼音、墨奇码、鹤形、自然码、虎码首末、五笔前2、汉心码、首右,拥有超越大厂的输入体验!带声调的词库,支持语法模型,全拼、简拼、整句、声调辅助筛选
|
||||
【文本框输入:/pinyin全拼,/zrm自然码,/flypy小鹤,/mspy,/sogou,/pyjj等,详见README.md】
|
||||
dependencies:
|
||||
- wanxiang_mixedcode #中英文混合词汇
|
||||
- wanxiang_reverse # 部件拆字,反查及辅码
|
||||
- wanxiang_chaifen #辅助码拆分注释、翻译注释、行政区划匹配、车牌、等等注释类显示滤镜,Lua专用:super_comment
|
||||
|
||||
|
||||
# 开关
|
||||
# reset: 默认状态。注释掉后,切换窗口时不会重置到默认状态。
|
||||
# states: 方案选单显示的名称。可以注释掉,仍可以通过快捷键切换。
|
||||
# abbrev: 默认的缩写取 states 的第一个字符,abbrev 可自定义一个字符
|
||||
switches:
|
||||
- name: ascii_mode # 中英输入状态
|
||||
states: [ 中文, 英文 ]
|
||||
- name: ascii_punct # 中英标点
|
||||
states: [ 中标, 英标 ]
|
||||
- name: full_shape #全角、半角字符输出
|
||||
states: [ 半角, 全角 ]
|
||||
- name: emoji #候选出现emoji滤镜,会显示在相应的候选后面,万象侧重于tips提示,避免候选被占用,因此默认为reset: 0,归属opencc emoji滤镜
|
||||
states: [ 表情关, 表情开 ]
|
||||
- name: chinese_english #候选进入翻译模式滤镜,会显示在相应的候选后面,万象侧重于tips提示,避免候选被占用,快捷键配套ctrl+e,归属opencc 翻译滤镜
|
||||
states: [ 翻译关, 翻译开 ]
|
||||
- name: chaifen_switch #开启后在候选的注释里面实时显示辅助码的拆分提醒优先级高于普通辅助提醒,不开启则采用系统配置,快捷键配套ctrl+c,影响的是comment_format,归属:super_comment.lua
|
||||
states: [ 拆分关, 拆分开 ]
|
||||
- name: charset_filter #字符集过滤,默认开启8105通规显示,即小字集,可通过开关实时开启全字集,快捷键配套ctrl+g,归属:super_filter.lua
|
||||
states: [ 小字集, 大字集 ]
|
||||
- name: super_tips #开启后在输入编码后面的提示区显示实时的提示数据,受tips数据库影响,表情、翻译、车牌、符号等对应关系数据,并可实现句号上屏,不开启则默认,影响的是segment.prompt参数,归属:super_tips.lua
|
||||
states: [ 提示关, 提示开 ]
|
||||
reset: 1
|
||||
- options: [ raw_input, tone_display, full_pinyin ] #开启后在输入编码的位置实时转换为带声调全拼或者不带声调全拼,不开启则采用系统配置原始编码,影响的是preedit_format,归属:super_preedit.lua
|
||||
states: [ 原编码, 有声调, 无声调 ]
|
||||
# reset: 2 #对于开关组从0开始数,第几个就reset几可设为默认
|
||||
- options: [ comment_off, fuzhu_hint, tone_hint ] #开启后在候选的注释里面实时显示辅助码或者全拼声调,不开启则采用系统配置,影响的是comment_format,快捷键配套ctrl+a,归属:super_comment.lua
|
||||
states: [ 注释关, 辅助开, 读音开 ]
|
||||
- options: [ s2s, s2t, s2hk, s2tw ] # 简繁转换开关组,可以在一个空选项和多个实际“- simplifier@s2hk”引入的项目之前切换,这是一个开关组,你可以将其中任意一个s2s等设置为toggle快捷键,多次按下将轮询
|
||||
states: [ 简体, 通繁, 港繁, 臺繁 ]
|
||||
- name: char_priority #多体现在编码重合但候选有单字或者多字的情况`引导的辅码查词时是否单字优先,全拼常见,类似于特定编码情况下、反查状态下的调序能力。归属:super_lookup.lua
|
||||
states: [词组先, 单字先]
|
||||
- options: [ mixed, zh_only, en_only ]
|
||||
states: [ 混合输入, 仅中文, 仅英文 ]
|
||||
|
||||
# 输入引擎
|
||||
engine:
|
||||
processors:
|
||||
- lua_processor@*select_character #以词定字,默认左中括号上屏一个词的前一个字,右中括号上屏一个词的后一个字
|
||||
- lua_processor@*partial_commit #通过ctrl+1~0局部提交10个字以内的句子的前几个字(一般为正确的前几个)使用时要遵循合理的分词结构能促进后续编码打出正确的词汇
|
||||
- lua_processor@*letter_selector #在N模式R模式下输入数字被视为编码,那么如何上屏呢,现在除了方向键还提供qwertyuio对照1-9来选词
|
||||
- lua_processor@*tone_fallback #声调辅助回退,当你输入声调数字错误时,继续输入正确的而不用回退删除
|
||||
- lua_processor@*super_sequence*P #手动排序,高亮候选 ctrl+j左移动 ctrl+k 右移动 ctrl+l 移除位移 ctrl+p 置顶
|
||||
- lua_processor@*quick_symbol_text #快符引导以及重复上屏,配合quick_symbol_text顶层配置清单定义扩展按键
|
||||
- lua_processor@*super_tips #超级提示模块:表情、简码、翻译、化学式、等等靠你想象
|
||||
- lua_processor@*limit_repeated #用于限制最大候选长度以及最大重复输入声母编码长度,避免性能异常
|
||||
- lua_processor@*backspace_limit #防止连续 Backspace 在编码为空时删除已上屏内容
|
||||
- lua_processor@*kp_number_processor #管理小键盘的处理逻辑,有输入中数字不上屏和数字一直不上屏设置可选
|
||||
- lua_processor@*super_segmentation #通过双击分词符号触发重新分词,并在持续输入分词符号时,能在预设方式之间循环,用于应对类似自然码:必输 必须是 为相同编码导致的必输前置的问题
|
||||
- ascii_composer #处理英文模式及中英文切换
|
||||
- recognizer #与 matcher 搭配,处理符合特定规则的输入码,如网址、反查等 tags
|
||||
- key_binder #在特定条件下将按键绑定到其他按键,如重定义逗号、句号为候选翻页、开关快捷键等
|
||||
- lua_processor@*key_binder #绑定按键扩展能力,支持正则扩展将按键生效情景更加细化
|
||||
- speller #拼写处理器,接受字符按键,编辑输入
|
||||
- punctuator #符号处理器,将单个字符按键直接映射为标点符号或文字
|
||||
- selector #选字处理器,处理数字选字键〔可以换成别的哦〕、上、下候选定位、换页
|
||||
- navigator #处理输入栏内的光标移动
|
||||
- express_editor #编辑器,处理空格、回车上屏、回退键
|
||||
segmentors:
|
||||
- ascii_segmentor #标识英文段落〔譬如在英文模式下〕字母直接上屛
|
||||
- matcher #配合 recognizer 标识符合特定规则的段落,如网址、反查等,加上特定 tag
|
||||
- abc_segmentor #标识常规的文字段落,加上 abc 这个 tag
|
||||
- affix_segmentor@wanxiang_reverse #反查 tag
|
||||
- affix_segmentor@add_user_dict #自造词加词 tag
|
||||
- punct_segmentor #标识符号段落〔键入标点符号用〕加上 punct 这个 tag
|
||||
- fallback_segmentor #标识其他未标识段落,必须放在最后帮助tag模式切换后回退重新处理
|
||||
translators:
|
||||
- punct_translator #配合 punct_segmentor 转换标点符号
|
||||
- script_translator #脚本翻译器,用于拼音、粤拼等基于音节表的输入方案
|
||||
- lua_translator@*version_display #输入'/wx',显示万象项目网址和当前版本号
|
||||
- lua_translator@*set_schema #输入'/zrm',快速切换为自然码双拼, /flypy→小鹤双拼 /mspy→微软双拼 /zrm→自然码 /sogou→搜狗双拼 /abc→智能ABC /ziguang→紫光双拼 /pyjj→拼音加加 /gbpy→国标双拼 /lxsq→乱序17 /pinyin→全拼
|
||||
- lua_translator@*shijian #农历、日期、节气、节日、时间、周、问候模板等等,触发清单看下文
|
||||
- lua_translator@*unicode #通过输入大写U引导,并输入Unicode编码获得汉字输出
|
||||
- lua_translator@*number_translator #数字、金额大写,通过输入大写R1234获得候选输出
|
||||
- lua_translator@*super_calculator #超级计算器,Lua内查看高级用法
|
||||
- lua_translator@*input_statistics #一个输入统计的脚本,以日、周、月、年等维度的统计
|
||||
- table_translator@custom_phrase #自定义短语 custom_phrase.txt,用于置顶自定义编码候选词
|
||||
- table_translator@chengyu #简码成语词汇表导入
|
||||
- table_translator@wanxiang_mixedcode #中英等混合词汇表导入
|
||||
- table_translator@wanxiang_reverse #挂接部件组字和笔画反查
|
||||
- script_translator@user_dict_set #自造词之使用词汇入口
|
||||
- script_translator@add_user_dict #自造词之制造词汇入口
|
||||
filters:
|
||||
- reverse_lookup_filter@radical_reverse_lookup #部件拆字滤镜,放在super_comment前面,进一步被超级注释处理以获得拼音编码的提示
|
||||
- lua_filter@*auto_phrase #无感造词,关闭调频的时候将汉字写入次翻译器,当没有英文候选的时候追加\上屏可完成英文造词
|
||||
- lua_filter@*super_comment_preedit #超级注释模块、超级preedit,支持错词提示、辅助码显示,部件组字读音注释,有声调、无声调全拼编码的转换,支持个性化配置和关闭相应的功能,详情搜索super_comment_preedit进行详细配置
|
||||
- simplifier@emoji #Emoji滤镜
|
||||
- simplifier@s2t #简繁切换通繁
|
||||
- simplifier@s2tw #简繁切换台繁
|
||||
- simplifier@s2hk #简繁切换港繁
|
||||
- simplifier@chinese_english #中英翻译滤镜
|
||||
- lua_filter@*super_sequence*F #手动排序,对高亮候选 ctrl+j左移动 ctrl+k 右移动 ctrl+0 移除位移
|
||||
- lua_filter@*super_filter #功能太多详见Lua文件
|
||||
- lua_filter@*super_lookup #字词输入中反查辅助筛选
|
||||
- uniquifier #去重
|
||||
|
||||
grammar:
|
||||
language: wanxiang-lts-zh-hans
|
||||
collocation_max_length: 8 #命中的最长词组
|
||||
collocation_min_length: 2 #命中的最短词组,搭配词频健全的词库时候应当最小值设为3避开2字高频词
|
||||
collocation_penalty: -10 #默认-12 对常见搭配词组施加的惩罚值。较高的负值会降低这些搭配被选中的概率,防止过于频繁地出现某些固定搭配。
|
||||
non_collocation_penalty: -17 #默认-12 对非搭配词组施加的惩罚值。较高的负值会降低非搭配词组被选中的概率,避免不合逻辑或不常见的词组组合。
|
||||
weak_collocation_penalty: -24 #默认-24 对弱搭配词组施加的惩罚值。保持默认值通常是为了有效过滤掉不太常见但仍然合理的词组组合。
|
||||
rear_penalty: -18 #默认-18 对词组中后续词语的位置施加的惩罚值。较高的负值会降低某些词语在句子后部出现的概率,防止句子结构不自然。
|
||||
|
||||
super_comment: # 超级注释模块,子项配置 true 开启,false 关闭
|
||||
candidate_length: 1 # 候选词辅助码提醒的生效长度,0为关闭 但同时清空其它,应当使用上面开关来处理
|
||||
corrector_type: "〔comment〕" # 随意更换左右括号,比如"〔comment〕" 不加括号为无括号,comment占位不能动
|
||||
chaifen: "〔chaifen〕" # 随意更换左右括号,比如"〔chaifen〕" 不加括号为无括号,chaifen占位不能动
|
||||
|
||||
# Tips 配置项
|
||||
tips:
|
||||
# 禁用的 tips 类型,初始化 tips 数据库的时候会直接忽略相关规则,修改部署后生效
|
||||
# 可选项为:偏旁,符号,化学式,时间,符号,组字,翻译,表情,货币,车牌
|
||||
disabled_types: []
|
||||
|
||||
#在8105基础上你可以通过黑白名单微调你自己的字符集过滤清单,主数据库位于lua/charset.bin不可编辑
|
||||
charsetlist: []
|
||||
charsetblacklist: []
|
||||
|
||||
#shijian:仅仅作为提示使用,编码已经写死,引导键可以在key_binder下修改前缀
|
||||
#时间:osj 或者 /sj
|
||||
#日期:orq 或者 /rq
|
||||
#农历:onl 或者 /nl
|
||||
#星期:oxq 或者 /xq
|
||||
#今年第几周:oww 或者 /ww
|
||||
#节气:ojq 或者 /jq
|
||||
#日期+时间:odt 或者 /dt
|
||||
#时间戳:ott 或者 /tt
|
||||
#大写N日期:N20250315 或者N0312不带年
|
||||
#节日:ojr 或者 /jr
|
||||
#问候模板:/day 或者 oday
|
||||
# 通用日期时间格式化函数(供 /rq、/sj、/dt、N0101、N20150101 场景复用)
|
||||
# 支持转义:
|
||||
# \X —— 转义单个字符 X,按字面量输出(如 \Y \m \H 等)
|
||||
# [[...]] —— 区块整体按字面量输出
|
||||
#
|
||||
# 约定占位符:
|
||||
# 【日期】
|
||||
# Y 四位年份 0000-9999 例:2025
|
||||
# y 两位年份 00-99 例:25
|
||||
# m 月(前导零) 01-12 例:02
|
||||
# n 月(不带前导零) 1-12 例:2
|
||||
# d 日(前导零) 01-31 例:09
|
||||
# j 日(不带前导零) 1-31 例:9
|
||||
#
|
||||
# 【时间】
|
||||
# H 24小时(前导零) 00-23 例:08
|
||||
# G 24小时(不带零) 0-23 例:8
|
||||
# I 12小时(前导零) 01-12 例:08
|
||||
# l 12小时(不带零) 1-12 例:8 (注意是小写 L)
|
||||
# M 分钟(前导零) 00-59 例:05
|
||||
# S 秒(前导零) 00-59 例:09
|
||||
# p am/pm(小写) am / pm
|
||||
# P AM/PM(大写) AM / PM
|
||||
# 【时区】
|
||||
# O 带冒号格式 +08:00、-04:30、+05:45
|
||||
# o 不带冒号格式 +0800、-0430、+0545
|
||||
date_formats:
|
||||
- "Y年m月d日"
|
||||
- "Y-m-d"
|
||||
- "Y/m/d"
|
||||
- "Y.m.d"
|
||||
- "Ymd"
|
||||
- "Y年n月j日"
|
||||
- "y年n月j日"
|
||||
- "n月j日"
|
||||
time_formats:
|
||||
- "H:M"
|
||||
- "H点M分"
|
||||
- "H:M:S"
|
||||
- "H时M分S秒"
|
||||
- "下午I:M"
|
||||
- "I:M P"
|
||||
datetime_formats:
|
||||
- "Y-m-d H:M:S"
|
||||
- "Y-m-dTH:M:S O"
|
||||
- "YmdHMS"
|
||||
- "Y年m月d日 H点M分"
|
||||
- "y/m/d I:M p"
|
||||
|
||||
#常规状态下数字转换成相应的字符,由超级preedit接管
|
||||
tone_preedit:
|
||||
"7": "¹"
|
||||
"8": "²"
|
||||
"9": "³"
|
||||
"0": "⁴"
|
||||
|
||||
# a/、单字母组合,触发预设编码自动上屏快符,支持将值设为"repeat" 以支持对应按键重复上屏功能,custom>schema>lua最终合并键值
|
||||
# 现在就支持26字母快符,结合成对符号输入,这边的压力小一些
|
||||
quick_symbol_text:
|
||||
trigger: "^([a-z])/$"
|
||||
symkey:
|
||||
q: "repeat"
|
||||
w: "?"
|
||||
e: "("
|
||||
r: ")"
|
||||
t: "~"
|
||||
y: "·"
|
||||
u: "『"
|
||||
i: "』"
|
||||
o: "〖"
|
||||
p: "〗"
|
||||
a: "!"
|
||||
s: "……"
|
||||
d: "、"
|
||||
f: "“"
|
||||
g: "”"
|
||||
h: "‘"
|
||||
j: "’"
|
||||
k: "【"
|
||||
l: "】"
|
||||
z: "。”"
|
||||
x: "?”"
|
||||
c: "!”"
|
||||
v: "——"
|
||||
b: "%"
|
||||
n: "《"
|
||||
m: "》"
|
||||
|
||||
#通过在有候选的情况下,通过末尾检测到形如\a来触发为第一候选进行成对符号包裹例如nihao\c 候选[你好]
|
||||
#trigger只能设置为单符号,因为按下一次锁定第一候选,按下映射开始包裹符号pro用户不能设置为/
|
||||
#两个字符可以不用|默认前后分割,需要明确区分前后的使用|分割,可以有一侧为空,不可以使用多个||
|
||||
paired_symbols:
|
||||
#sort_window: 10
|
||||
trigger: "\\" #(注意反斜杠这是转义写法\\使用时\单反斜杠即可)
|
||||
mirror: true #包裹后完全替换第一候选true,原候选后移到第二false
|
||||
symkey:
|
||||
# ===== 基本括号与引号 =====
|
||||
a: "[]" # 方括号
|
||||
b: "【】" # 黑方头括号
|
||||
c: "❲❳" # 双大括号 / 装饰括号
|
||||
d: "〔〕" # 方头括号
|
||||
e: "⟮⟯" # 小圆括号 / 装饰括号
|
||||
f: "⟦⟧" # 双方括号 / 数学集群括号
|
||||
g: "「」" # 直角引号
|
||||
# h: 预留用于 Markdown 一级标题
|
||||
i: "『』" # 双直角引号
|
||||
j: "<>" # 尖括号
|
||||
k: "《》" # 书名号(双)
|
||||
l: "〈〉" # 书名号(单)
|
||||
m: "‹›" # 法文单书名号
|
||||
n: "«»" # 法文双书名号
|
||||
o: "⦅⦆" # 白圆括号
|
||||
p: "⦇⦈" # 白方括号
|
||||
q: "()" # 圆括号
|
||||
r: "|儿" #儿化候选
|
||||
s: "[]" # 全角方括号
|
||||
t: "⟨⟩" # 数学角括号
|
||||
u: "〈〉" # 数学尖括号
|
||||
v: "〖〗" # 装饰花括号
|
||||
w: "()" # 全角圆括号
|
||||
x: "{}" # 全角花括号
|
||||
y: "⟪⟫" # 双角括号
|
||||
z: "{}" # 花括号
|
||||
|
||||
# ===== 扩展括号族 / 引号 =====
|
||||
dy: "''" # 英文单引号
|
||||
sy: "\"\"" # 英文双引号
|
||||
zs: "“”" # 中文弯双引号
|
||||
zd: "‘’" # 中文弯单引号
|
||||
fy: "``" # 反引号
|
||||
|
||||
# ===== 双字母括号族 =====
|
||||
aa: "〚〛" # 双中括号
|
||||
bb: "〘〙" # 双中括号(小)
|
||||
cc: "〚〛" # 双中括号(重复,可用于 Lua 匹配)
|
||||
dd: "❨❩" # 小圆括号装饰
|
||||
ee: "❪❫" # 小圆括号装饰
|
||||
ff: "❬❭" # 小尖括号装饰
|
||||
gg: "⦉⦊" # 双弯方括号
|
||||
fa: "⦋⦌" # 双弯方括号
|
||||
ii: "⦍⦎" # 双弯方括号
|
||||
jj: "⦏⦐" # 双弯方括号
|
||||
kk: "⦑⦒" # 双弯方括号
|
||||
ll: "❮❯" # 小尖括号装饰
|
||||
mm: "⌈⌉" # 上取整 / 数学符号
|
||||
nn: "⌊⌋" # 下取整 / 数学符号
|
||||
oo: "⦗⦘" # 双方括号装饰(补齐)
|
||||
pp: "⦙⦚" # 双方括号装饰(补齐)
|
||||
qq: "⟬⟭" # 小双角括号
|
||||
rr: "❴❵" # 花括号装饰
|
||||
ss: "⌜⌝" # 数学上角符号
|
||||
tt: "⌞⌟" # 数学下角符号
|
||||
uu: "⸢⸣" # 装饰方括号
|
||||
vv: "⸤⸥" # 装饰方括号
|
||||
ww: "﹁﹂" # 中文书名号 / 注释引号
|
||||
xx: "﹃﹄" # 中文书名号 / 注释引号
|
||||
yy: "⌠⌡" # 数学 / 程序符号
|
||||
zz: "⟅⟆" # 数学 / 装饰括号
|
||||
|
||||
# ===== Markdown / 标记 =====
|
||||
md: "**|**" # Markdown 粗体
|
||||
jc: "**|**" # 加粗
|
||||
it: "__|__" # 斜体
|
||||
st: "~~|~~" # 删除线
|
||||
eq: "==|==" # 高亮
|
||||
ln: "`|`" # 行内代码
|
||||
cb: "```|```" # 代码块
|
||||
qt: "> |" # 引用
|
||||
ul: "- |" # 无序列表项
|
||||
ol: "1. |" # 有序列表项
|
||||
lk: "[|](url)" # 链接
|
||||
im: "" # 图片
|
||||
h: "# |" # 一级标题
|
||||
hh: "## |" # 二级标题
|
||||
hhh: "### |" # 三级标题
|
||||
hhhh: "#### |" # 四级标题
|
||||
sp: "\\|" # 反斜杠转义
|
||||
br: "| " # 换行
|
||||
cm: "<!--|-->" # 注释
|
||||
|
||||
# ===== 运算与标记符 =====
|
||||
pl: "++"
|
||||
mi: "--"
|
||||
sl: "//"
|
||||
bs: "\\\\"
|
||||
at: "@@"
|
||||
dl: "$$"
|
||||
pc: "%%"
|
||||
an: "&&"
|
||||
cr: "^^"
|
||||
cl: "::"
|
||||
sc: ";;"
|
||||
ex: "!!"
|
||||
qu: "??"
|
||||
sb: "sb"
|
||||
|
||||
# Lua 配置:计算器触发关键字
|
||||
calculator:
|
||||
trigger: "V"
|
||||
|
||||
# 主翻译器,拼音
|
||||
translator:
|
||||
dictionary: wanxiang_pro # 挂载词库 wanxiang.dict.yaml
|
||||
# packs: user #导入根目录下名称为user.dict.yaml的自定义固定词典
|
||||
# prism: double_pinyin # 多方案共用一个词库时,为避免冲突,需要用 prism 指定一个名字。
|
||||
enable_completion: true # 启用候选词补全
|
||||
# user_dict: zrm.userdb # 用户词典的文件名称
|
||||
# db_class: tabledb #开启后就不会产生zrm.userdb这样的文件夹,会直接输出文本zrm.txt同时无法使用同步能力
|
||||
enable_user_dict: false # 是否开启自动调频
|
||||
contextual_suggestions: false #模型用来开启词组权重预测,效果一般关闭
|
||||
max_homophones: 5
|
||||
max_homographs: 5
|
||||
# disable_user_dict_for_patterns:
|
||||
# - "^[a-z]{1,6}" #基本的6码3字不调频
|
||||
enable_correction: false #是否开启自动纠错
|
||||
initial_quality: 4 # 初始质量拼音的权重应该比英文大
|
||||
spelling_hints: 50 # 将注释以词典字符串形式完全暴露,通过super_comment.lua完全接管,灵活配置。
|
||||
always_show_comments: true # Rime 默认在 preedit 等于 comment 时取消显示 comment,这里强制一直显示,供super_comment_preedit.lua做判断用。
|
||||
comment_format: {comment} #将注释以词典字符串形式完全暴露,通过super_comment.lua完全接管,灵活配置。
|
||||
|
||||
# 自定义短语
|
||||
custom_phrase:
|
||||
dictionary: ""
|
||||
user_dict: custom_phrase # 需要手动创建 custom_phrase.txt 文件
|
||||
db_class: stabledb
|
||||
enable_completion: false # 补全提示
|
||||
enable_sentence: false # 禁止造句
|
||||
initial_quality: 99 # custom_phrase 的权重应该比 pinyin 和 wanxiang_en 大
|
||||
|
||||
|
||||
# 简码词库导入位于dicts得txt文件词库
|
||||
chengyu:
|
||||
dictionary: ""
|
||||
user_dict: dicts/chengyu
|
||||
db_class: stabledb
|
||||
enable_sentence: false
|
||||
enable_completion: false
|
||||
initial_quality: 1.2 #本表词和系统词重码居后
|
||||
|
||||
# 中文、英文、数字、符号等混合词汇
|
||||
wanxiang_mixedcode:
|
||||
dictionary: wanxiang_mixedcode
|
||||
user_dict: en
|
||||
enable_completion: true
|
||||
enable_sentence: false
|
||||
initial_quality: 2
|
||||
comment_format:
|
||||
- xform/^.+$//
|
||||
|
||||
# Emoji
|
||||
emoji:
|
||||
option_name: emoji
|
||||
opencc_config: emoji.json
|
||||
tags: [abc]
|
||||
inherit_comment: false
|
||||
|
||||
#中文转英文
|
||||
chinese_english:
|
||||
option_name: chinese_english
|
||||
opencc_config: chinese_english.json
|
||||
tips: char
|
||||
inherit_comment: false
|
||||
|
||||
# 简繁切换
|
||||
s2t:
|
||||
option_name: s2t
|
||||
opencc_config: s2t.json # s2t.json | s2hk.json | s2tw.json | s2twp.json
|
||||
tips: none # 转换提示: all 都显示 | char 仅单字显示 | none 不显示。
|
||||
tags: [ abc ] # 限制在对应 tag,不对其他如反查的内容做简繁转换
|
||||
|
||||
s2hk:
|
||||
opencc_config: s2hk.json
|
||||
option_name: s2hk
|
||||
tags: [abc]
|
||||
|
||||
s2tw:
|
||||
opencc_config: s2tw.json
|
||||
option_name: s2tw
|
||||
tags: [abc]
|
||||
|
||||
# 部件拆字反查
|
||||
wanxiang_reverse:
|
||||
tag: wanxiang_reverse
|
||||
dictionary: wanxiang_reverse
|
||||
db_class: stabledb
|
||||
enable_user_dict: false
|
||||
enable_sentence: false
|
||||
prefix: "`" # 反查前缀(反查时前缀会消失),与 recognizer/patterns/wanxiang_reverse 匹配
|
||||
tips: "〔反查:拆分|笔画〕"
|
||||
|
||||
# 部件拆字滤镜
|
||||
radical_reverse_lookup:
|
||||
tags: [ wanxiang_reverse ] #起作用tag范围
|
||||
overwrite_comment: true #是否覆盖其他提示
|
||||
dictionary: wanxiang_pro #带音调的词典
|
||||
|
||||
wanxiang_lookup: #设置归属于super_lookup.lua
|
||||
tags: [ abc ] # 检索当前tag的候选
|
||||
key: "`" # 输入中反查引导符,要添加到 speller/alphabet
|
||||
lookup: [ wanxiang_reverse ] #反查滤镜数据库,万象都合并为一个了
|
||||
|
||||
# 处理符合特定规则的输入码,如网址、反查
|
||||
recognizer:
|
||||
import_preset: default # 从 default.yaml 继承通用的
|
||||
patterns: # 再增加方案专有的:
|
||||
punct: "^/([0-9]|10|[A-Za-z]+)$" # 响应 symbols.yaml 的 symbols
|
||||
wanxiang_reverse: "^`[A-Za-z]*$" # 响应部件拆字与笔画的反查,与 radical_lookup/prefix 匹配
|
||||
add_user_dict: "^``[A-Za-z/`']*$" #自造词
|
||||
unicode: "^U[a-f0-9]+" # 脚本将自动获取第 2 个字符 U 作为触发前缀,响应 lua_translator@unicode,输出 Unicode 字符
|
||||
number: "^R[0-9]+[.]?[0-9]*" # 脚本将自动获取第 2 个字符 R 作为触发前缀,响应 lua_translator@number_translator,数字金额大写
|
||||
yr1: "^N0[1-9]?0?[1-9]?"
|
||||
yr2: "^N1[02]?0?[1-9]?"
|
||||
yr3: "^N0[1-9]?[1-2]?[1-9]?"
|
||||
yr4: "^N1[02]?[1-2]?[1-9]?"
|
||||
yr5: "^N0[1-9]?3?[01]?"
|
||||
yr6: "^N1[02]?3?[01]?"
|
||||
nyr1: "^N19?[0-9]?[0-9]?[0-9]?[0-9]?[0-9]?[0-9]?"
|
||||
nyr2: "^N20?[0-9]?[0-9]?[0-9]?[0-9]?[0-9]?[0-9]?"
|
||||
calculator: "^V.*$" #计算器功能引导
|
||||
email: "^[A-Za-z][-_.0-9A-Za-z]*@.*$" # email @ 之后不上屏
|
||||
url: "^(www[.]|https?:|ftp[.:]|mailto:|file:).*$|^[a-z]+[.].+$" # URL
|
||||
# 给 kp_number_processor 用的“命令模式 Lua 正则集合”
|
||||
# 能够细化哪些情况数字是用来当作输入编码的,不在正则范围的将用于上屏
|
||||
# 直接加载上面的正则会遇到不符合预期的情况,毕竟Lua正则逻辑与之不同
|
||||
kp_number:
|
||||
#小键盘数字处理逻辑
|
||||
# "compose" : 小键盘数字始终参与编码
|
||||
# "auto" : 输入中 push,空闲时 commit(默认)
|
||||
kp_number_mode: auto
|
||||
patterns:
|
||||
# /符号引导模式
|
||||
- "^/[0-9]$"
|
||||
- "^/10$"
|
||||
- "^/[A-Za-z]+$"
|
||||
# U模式
|
||||
- "^U[%da-f]+$"
|
||||
# R模式
|
||||
- "^R[0-9]+%.?[0-9]*$"
|
||||
# N模式
|
||||
# Lua 不支持 {1,8},改成等价写法:N 后 1~8 个数字
|
||||
- "^N0[1-9]?0?[1-9]?$"
|
||||
- "^N1[02]?0?[1-9]?$"
|
||||
- "^N0[1-9]?[1-2]?[1-9]?$"
|
||||
- "^N1[02]?[1-2]?[1-9]?$"
|
||||
- "^N0[1-9]?3?[01]?$"
|
||||
- "^N1[02]?3?[01]?$"
|
||||
- "^N19?[0-9]?[0-9]?[01]?[0-2]?[0-3]?[0-9]?$"
|
||||
- "^N20?[0-9]?[0-9]?[01]?[0-2]?[0-3]?[0-9]?$"
|
||||
# 计算器模式
|
||||
- "^V.*$"
|
||||
# email
|
||||
- "^[A-Za-z][-_.0-9A-Za-z]*@.*$"
|
||||
# URL 前缀几种:
|
||||
- "^www[.].*$"
|
||||
- "^https?:.*$"
|
||||
- "^ftp[.:].*$"
|
||||
- "^mailto:.*$"
|
||||
- "^file:.*$"
|
||||
- "^webdav:.*$"
|
||||
# 标点符号
|
||||
# punctuator 下面有三个子项:
|
||||
# 设置为一个映射,就自动上屏;设置为多个映射,如 '/' : [ '/', ÷ ] 则进行复选。
|
||||
# full_shape: 全角没改,使用预设值
|
||||
# half_shape: 标点符号全部直接上屏,和 macOS 自带输入法的区别是
|
||||
# '|' 是半角的,
|
||||
# '~' 是半角的,
|
||||
# '`'(反引号)没有改成 '·'(间隔号)。
|
||||
# symbols Rime 的预设配置是以 '/' 前缀开头输出一系列字符,自定义的修改 symbols.yaml
|
||||
punctuator:
|
||||
digit_separators: ":,." #数字分隔符
|
||||
__include: wanxiang_symbols:/symbol_table # 从 symbols.yaml 导入配置
|
||||
|
||||
# 从 default 继承快捷键
|
||||
key_binder:
|
||||
import_preset: default # 从 default.yaml 继承通用的
|
||||
# Lua 配置: 以词定字(上屏当前词句的第一个或最后一个字),和中括号翻页有冲突
|
||||
select_first_character: "bracketleft" # 左中括号 [
|
||||
select_last_character: "bracketright" # 右中括号 ]
|
||||
sequence: # Lua 配置:手动排序的快捷键 super_sequence.lua,不要用方向键,各种冲突,一定要避免冲突
|
||||
up: "Control+j" # 上移
|
||||
down: "Control+k" # 下移
|
||||
reset: "Control+l" # 重置
|
||||
pin: "Control+p" # 置顶
|
||||
# Lua 配置: shijian.lua 的引导符,涉及:日期、时间、节日、节气、生日、问候模板等功能
|
||||
shijian_keys: ["/", "o"]
|
||||
# Lua 配置: 超级tips上屏按键
|
||||
tips_key: "comma" #修改时候去default找
|
||||
bindings: # 也可以再增加方案专有的
|
||||
# 通过按下/发送/+1节约一个按键,不冲突的时候可以开启
|
||||
#- { match: "[a-z]{1,4}", accept: "/", send_sequence: "/1" }
|
||||
# 翻页 , .
|
||||
# - { when: paging, accept: comma, send: Page_Up }
|
||||
# - { when: has_menu, accept: period, send: Page_Down }
|
||||
# 翻页 [ ]
|
||||
# - { when: paging, accept: bracketleft, send: Page_Up }
|
||||
# - { when: has_menu, accept: bracketright, send: Page_Down }
|
||||
# 翻页 - =
|
||||
- { when: has_menu, accept: minus, send: Page_Up }
|
||||
- { when: has_menu, accept: equal, send: Page_Down }
|
||||
# Option/Alt + ←/→ 切换光标至下/上一个拼音
|
||||
- { when: always, toggle: ascii_punct, accept: Control+Shift+3 } # 切换中英标点
|
||||
- { when: always, toggle: ascii_punct, accept: Control+Shift+numbersign } # 切换中英标点
|
||||
- { when: always, toggle: s2t, accept: Control+Shift+4 } # 切换简繁
|
||||
- { when: always, toggle: s2t, accept: Control+Shift+dollar } # 切换简繁
|
||||
- { when: composing, accept: Alt+Left, send: Shift+Left }
|
||||
- { when: composing, accept: Alt+Right, send: Shift+Right }
|
||||
- { when: composing, accept: Control+w, send: Control+BackSpace }
|
||||
# 分号用于次选,微软、搜狗双拼不可启用
|
||||
#- { when: has_menu, accept: semicolon, send: 2 }
|
||||
# 使用Control+e进入翻译模式
|
||||
- { when: has_menu, accept: "Control+e", toggle: chinese_english }
|
||||
# 使用快捷键Control+c拆分显示
|
||||
- { when: has_menu, accept: "Control+c", toggle: chaifen_switch }
|
||||
# 使用快捷键Control+a开启和关闭辅助码显示
|
||||
- { when: has_menu, accept: "Control+a", toggle: fuzhu_hint }
|
||||
# 通过快捷键Control+s使得输入码显示音调
|
||||
- { when: has_menu, accept: "Control+s", toggle: tone_display }
|
||||
# 通过快捷键Control+t开启超级tips
|
||||
- { when: has_menu, accept: "Control+t", toggle: super_tips }
|
||||
# 通过快捷键Control+g开启字符集过滤
|
||||
- { when: has_menu, accept: "Control+g", toggle: charset_filter }
|
||||
#通过快捷键Control+q切换中文、英文、混合模式
|
||||
- { when: has_menu, accept: "Control+q", toggle: zh_only }
|
||||
# 使用 tab 在不同音节之间跳转
|
||||
- { when: has_menu, accept: "Tab", send: "Control+Right" }
|
||||
- { when: composing, accept: "Tab", send: "Control+Right" }
|
||||
# 当tab第一个字补码正确后,可以使用Ctrl+tab进行上屏并依次补码
|
||||
- { when: composing, accept: "Control+Tab", send_sequence: '{Home}{Shift+Right}{1}{Shift+Right}' }
|
||||
# 当输入编码后发现没有词,则通过双击``进入造词模式而且不需要删除编码,这个功能与``直接引导相呼应相配合
|
||||
- { match: "^.*`$", accept: "`", send_sequence: '{BackSpace}{Home}{`}{`}{End}' }
|
||||
# 斜杠被占用引导符号,因此输入本身设置为双击
|
||||
- { match: "^/$", accept: "/", send_sequence: '{space}' }
|
||||
|
||||
editor:
|
||||
bindings:
|
||||
space: confirm # 空格键:上屏候选项
|
||||
Return: commit_raw_input # 回车键:上屏原始输入
|
||||
Control+Return: commit_script_text # Ctrl+回车键:上屏变换后输入(经过 preedit转换的)
|
||||
Control+Shift+Return: commit_comment # Ctrl+Shift+回车键:上屏 comment
|
||||
BackSpace: revert # 退格键:向前删除(撤消上次输入)
|
||||
Delete: delete # Delete 键:向后删除
|
||||
Control+BackSpace: back_syllable # Ctrl+退格键:删除一个音节
|
||||
Control+Delete: delete_candidate # Ctrl+Delete键:删除或降权候选项
|
||||
Escape: cancel # Esc 键:取消输入
|
||||
|
||||
# 拼写设定
|
||||
speller:
|
||||
# table_translator翻译器,支持自动上屏。例如 “zmhu”可以自动上屏“怎么回事”
|
||||
# auto_select: true
|
||||
# auto_select_pattern: ^[a-z]+/|^[a-df-zA-DF-Z]\w{3}|^e\w{4}
|
||||
# 如果不想让什么标点直接上屏,可以加在 alphabet,或者编辑标点符号为两个及以上的映射
|
||||
alphabet: zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA1234567890`;/\
|
||||
# initials 定义仅作为始码的按键,排除 ` 让单个的 ` 可以直接上屏
|
||||
initials: zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA/
|
||||
delimiter: " '" # 第一位<空格>是拼音之间的分隔符;第二位<'>表示可以手动输入单引号来分割拼音。
|
||||
visual_delimiter: " " # super_preedit.lua配置:是否让分隔符号跟着一起转换,例如nǐ'hǎo 在实际使用中表现出视觉拥挤,我们可以让delimiter平时是'转换为拼音的时候使用空格nǐ hǎo,更符合实际。
|
||||
algebra:
|
||||
__patch:
|
||||
#- 模糊音 #模糊音选择性开启
|
||||
- wanxiang_algebra:/pro/自然码 #拼音转双拼码
|
||||
- wanxiang_algebra:/pro/直接辅助 #辅助码部分
|
||||
|
||||
###############################以下是拼写运算规则中全拼转双拼码以及形码的过程,按照不同的方案规则划分段落###########################
|
||||
|
||||
|
||||
user_dict_set:
|
||||
dictionary: wanxiang_pro
|
||||
initial_quality: 2.5
|
||||
enable_completion: false
|
||||
enable_sentence: false
|
||||
core_word_length: 4 # >0 启用,按段学词 + 相邻段拼接
|
||||
max_word_length: 7 # >0 启用,过长短语不记整词,只加元素权重
|
||||
contextual_suggestions: false
|
||||
max_homophones: 5
|
||||
max_homographs: 5
|
||||
spelling_hints: 50
|
||||
comment_format:
|
||||
enable_user_dict: true
|
||||
user_dict: zc
|
||||
|
||||
|
||||
# 自定义词典加词(ac引导)
|
||||
add_user_dict:
|
||||
tag: add_user_dict
|
||||
dictionary: wanxiang_pro
|
||||
initial_quality: -1
|
||||
user_dict: zc
|
||||
enable_completion: true # 提前显示尚未输入完整码的字〔仅 table_translator 有效〕
|
||||
enable_user_dict: true
|
||||
spelling_hints: 50
|
||||
enable_auto_phrase: true # lua造词功能,在custom开启,相关功能位于auto_phrase.lua,开启后:模型能造的句子不造词,现有的词不造词,只造词库没有的,选词可造词
|
||||
comment_format:
|
||||
prefix: "``"
|
||||
tips: "〔开始造词〕"
|
||||
|
||||
|
||||
5
custom/wanxiang_reverse.custom.yaml
Normal file
5
custom/wanxiang_reverse.custom.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
patch:
|
||||
# 只修改下面配置中的输入方案名称,名称与wanxiang.custom.yaml保持一致,这个用于反查
|
||||
speller/algebra:
|
||||
__include: wanxiang_algebra:/reverse/全拼 #可选的选项有(全拼, 自然码, 小鹤双拼, 微软双拼, 搜狗双拼, 智能ABC, 紫光双拼, 拼音加加)
|
||||
__patch: wanxiang_algebra:/reverse/hspzn #笔画类型有hspzn,hupvd及hslzy(适配乱序17)可选
|
||||
BIN
custom/万象输入方案.png
Normal file
BIN
custom/万象输入方案.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 976 KiB |
BIN
custom/万象键位映射.jpg
Normal file
BIN
custom/万象键位映射.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
BIN
custom/赞赏.jpg
Normal file
BIN
custom/赞赏.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
3
custom_phrase.txt
Normal file
3
custom_phrase.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
#给自定义用户词扩展一个换行:\n, 制表符:\t, 回车符:\r, 空格:\s
|
||||
吧 b 50
|
||||
静夜思\n\s\s李白\n床前明月光\n疑似地上霜\n举头望明月\n低头思故乡 jys 50
|
||||
256
default.yaml
Normal file
256
default.yaml
Normal file
@@ -0,0 +1,256 @@
|
||||
# Rime default settings
|
||||
# encoding: utf-8
|
||||
|
||||
|
||||
# 要比共享目录的同名文件的 config_version 大才可以生效
|
||||
config_version: 'LTS'
|
||||
|
||||
|
||||
# 方案列表
|
||||
schema_list:
|
||||
- schema: wanxiang
|
||||
|
||||
# - schema: wanxiang_t9
|
||||
# 菜单
|
||||
menu:
|
||||
page_size: 6 # 候选词个数,不得超过6个,7890代表声调
|
||||
alternative_select_labels: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] # 修改候选项标签,Windows用这行会自动加点
|
||||
#alternative_select_labels: [ ⒈, ⒉, ⒊, ⒋, ⒌, ⒍, ⒎, ⒏, ⒐, ⒑ ] # 修改候选项标签,Linux用这行用了加点字符
|
||||
#alternative_select_keys: ASDFGHJKL # 这里战略性占用选字按键,如编码字符占用数字键,则需另设选字键
|
||||
|
||||
|
||||
# 方案选单相关
|
||||
switcher:
|
||||
caption: 「方案选单」
|
||||
hotkeys:
|
||||
- Control+grave
|
||||
# - Alt+grave
|
||||
save_options: # 开关记忆(方案中的 switches),从方案选单(而非快捷键)切换时会记住的选项,需要记忆的开关不能设定 reset
|
||||
- ascii_punct
|
||||
- s2t
|
||||
- s2hk
|
||||
- s2tw
|
||||
- emoji
|
||||
- full_shape
|
||||
- prediction
|
||||
- super_tips
|
||||
- charset_filter
|
||||
- chaifen_switch
|
||||
- tone_display
|
||||
- fuzhu_hint
|
||||
- tone_hint
|
||||
- full_pinyin
|
||||
- chinese_english
|
||||
- search_single_char
|
||||
fold_options: true # 呼出时是否折叠,多方案时建议折叠 true ,一个方案建议展开 false
|
||||
abbreviate_options: true # 折叠时是否缩写选项
|
||||
option_list_separator: ' / ' # 折叠时的选项分隔符
|
||||
|
||||
|
||||
# 中西文切换
|
||||
#
|
||||
# good_old_caps_lock:
|
||||
# true 切换大写
|
||||
# false 切换中英
|
||||
# macOS 偏好设置的优先级更高,如果勾选【使用大写锁定键切换“ABC”输入法】则始终会切换输入法。
|
||||
#
|
||||
# 切换中英:
|
||||
# 不同的选项表示:打字打到一半时按下了 CapsLock、Shift、Control 后:
|
||||
# commit_code 上屏原始的编码,然后切换到英文
|
||||
# commit_text 上屏拼出的词句,然后切换到英文
|
||||
# clear 清除未上屏内容,然后切换到英文
|
||||
# inline_ascii 切换到临时英文模式,按回车上屏后回到中文状态
|
||||
# noop 屏蔽快捷键,不切换中英,但不要屏蔽 CapsLock
|
||||
ascii_composer:
|
||||
good_old_caps_lock: true # true | false
|
||||
switch_key:
|
||||
Caps_Lock: clear # commit_code | commit_text | clear
|
||||
Shift_L: commit_code # commit_code | commit_text | inline_ascii | clear | noop
|
||||
Shift_R: commit_code # commit_code | commit_text | inline_ascii | clear | noop
|
||||
Control_L: noop # commit_code | commit_text | inline_ascii | clear | noop
|
||||
Control_R: noop # commit_code | commit_text | inline_ascii | clear | noop
|
||||
|
||||
|
||||
# 处理符合特定规则的输入码,如网址、反查
|
||||
# 此处配置较为通用的选项,各方案中另增加了和方案功能绑定的 patterns。
|
||||
recognizer:
|
||||
patterns:
|
||||
email: "^[A-Za-z][-_.0-9A-Za-z]*@.*$" # email @ 之后不上屏
|
||||
url: "^(www[.]|https?:|ftp[.:]|mailto:|file:).*$|^[a-z]+[.].+$" # URL
|
||||
underscore: "^[A-Za-z]+_.*" # 下划线不上屏
|
||||
# url_2: "^[A-Za-z]+[.].*" # 句号不上屏,支持 google.com abc.txt 等网址或文件名,使用句号翻页时需要注释掉
|
||||
# colon: "^[A-Za-z]+:.*" # 冒号不上屏
|
||||
|
||||
|
||||
# 快捷键
|
||||
key_binder:
|
||||
bindings:
|
||||
# Tab / Shift+Tab 切换光标至下/上一个拼音
|
||||
#- { when: composing, accept: Shift+Tab, send: Shift+Left }
|
||||
#- { when: composing, accept: Tab, send: Shift+Right }
|
||||
# Tab / Shift+Tab 翻页
|
||||
# - { when: has_menu, accept: Shift+Tab, send: Page_Up }
|
||||
# - { when: has_menu, accept: Tab, send: Page_Down }
|
||||
|
||||
# numbered_mode_switch:
|
||||
# - { when: always, select: .next, accept: Control+Shift+1 } # 在最近的两个方案之间切换
|
||||
# - { when: always, select: .next, accept: Control+Shift+exclam } # 在最近的两个方案之间切换
|
||||
# - { when: always, toggle: ascii_mode, accept: Control+Shift+2 } # 切换中英
|
||||
# - { when: always, toggle: ascii_mode, accept: Control+Shift+at } # 切换中英
|
||||
# - { when: always, toggle: full_shape, accept: Control+Shift+5 } # 切换全半角
|
||||
# - { when: always, toggle: full_shape, accept: Control+Shift+percent } # 切换全半角
|
||||
|
||||
# emacs_editing:
|
||||
# - { when: composing, accept: Control+p, send: Up }
|
||||
# - { when: composing, accept: Control+n, send: Down }
|
||||
# - { when: composing, accept: Control+b, send: Left }
|
||||
# - { when: composing, accept: Control+f, send: Right }
|
||||
# - { when: composing, accept: Control+a, send: Home }
|
||||
# - { when: composing, accept: Control+e, send: End }
|
||||
# - { when: composing, accept: Control+d, send: Delete }
|
||||
- { when: composing, accept: Control+k, toggle: xxxxx } #释放Ctrl+k=ctrl+del 万象用来调序,且删除属于低频场景,建议双手操作
|
||||
# - { when: composing, accept: Control+h, send: BackSpace }
|
||||
# - { when: composing, accept: Control+g, send: Escape }
|
||||
# - { when: composing, accept: Control+bracketleft, send: Escape }
|
||||
# - { when: composing, accept: Control+y, send: Page_Up }
|
||||
# - { when: composing, accept: Alt+v, send: Page_Up }
|
||||
# - { when: composing, accept: Control+v, send: Page_Down }
|
||||
|
||||
# optimized_mode_switch:
|
||||
# - { when: always, accept: Control+Shift+space, select: .next }
|
||||
# - { when: always, accept: Shift+space, toggle: ascii_mode }
|
||||
# - { when: always, accept: Control+comma, toggle: full_shape }
|
||||
# - { when: always, accept: Control+period, toggle: ascii_punct }
|
||||
# - { when: always, accept: Control+slash, toggle: traditionalization }
|
||||
|
||||
# 将小键盘 0~9 . 映射到主键盘,数字金额大写的 Lua 如 R1234.5678 可使用小键盘输入
|
||||
- {accept: KP_0, send: 0, when: composing}
|
||||
- {accept: KP_1, send: 1, when: composing}
|
||||
- {accept: KP_2, send: 2, when: composing}
|
||||
- {accept: KP_3, send: 3, when: composing}
|
||||
- {accept: KP_4, send: 4, when: composing}
|
||||
- {accept: KP_5, send: 5, when: composing}
|
||||
- {accept: KP_6, send: 6, when: composing}
|
||||
- {accept: KP_7, send: 7, when: composing}
|
||||
- {accept: KP_8, send: 8, when: composing}
|
||||
- {accept: KP_9, send: 9, when: composing}
|
||||
- {accept: KP_Decimal, send: period , when: composing}
|
||||
- {accept: KP_Multiply, send: asterisk, when: composing}
|
||||
- {accept: KP_Add, send: plus, when: composing}
|
||||
- {accept: KP_Subtract, send: minus, when: composing}
|
||||
- {accept: KP_Divide, send: slash, when: composing}
|
||||
- {accept: KP_Enter, send: Return, when: composing}
|
||||
|
||||
# 按键速查
|
||||
# https://github.com/LEOYoon-Tsaw/Rime_collections/blob/master/Rime_description.md
|
||||
# (没有 Command 键,不支持)
|
||||
# accept 和 send 可用字段除 A-Za-z0-9 外,还包含以下键盘上实际有的键:
|
||||
# (区分大小写)
|
||||
# BackSpace 退格
|
||||
# Tab 水平定位符
|
||||
# Linefeed 换行
|
||||
# Clear 清除
|
||||
# Return 回车
|
||||
# Pause 暂停
|
||||
# Sys_Req 印屏
|
||||
# Escape 退出
|
||||
# Delete 删除
|
||||
# Home 原位
|
||||
# Left 左箭头
|
||||
# Up 上箭头
|
||||
# Right 右箭头
|
||||
# Down 下箭头
|
||||
# Prior、Page_Up 上翻
|
||||
# Next、Page_Down 下翻
|
||||
# End 末位
|
||||
# Begin 始位
|
||||
# Shift_L 左Shift
|
||||
# Shift_R 右Shift
|
||||
# Control_L 左Ctrl
|
||||
# Control_R 右Ctrl
|
||||
# Meta_L 左Meta
|
||||
# Meta_R 右Meta
|
||||
# Alt_L 左Alt
|
||||
# Alt_R 右Alt
|
||||
# Super_L 左Super
|
||||
# Super_R 右Super
|
||||
# Hyper_L 左Hyper
|
||||
# Hyper_R 右Hyper
|
||||
# Caps_Lock 大写锁
|
||||
# Shift_Lock 上档锁
|
||||
# Scroll_Lock 滚动锁
|
||||
# Num_Lock 小键板锁
|
||||
# Select 选定
|
||||
# Print 打印
|
||||
# Execute 运行
|
||||
# Insert 插入
|
||||
# Undo 还原
|
||||
# Redo 重做
|
||||
# Menu 菜单
|
||||
# Find 搜寻
|
||||
# Cancel 取消
|
||||
# Help 帮助
|
||||
# Break 中断
|
||||
# space 空格
|
||||
# exclam !
|
||||
# quotedbl "
|
||||
# numbersign #
|
||||
# dollar $
|
||||
# percent %
|
||||
# ampersand &
|
||||
# apostrophe '
|
||||
# parenleft (
|
||||
# parenright )
|
||||
# asterisk *
|
||||
# plus +
|
||||
# comma ,
|
||||
# minus -
|
||||
# period .
|
||||
# slash /
|
||||
# colon :
|
||||
# semicolon ;
|
||||
# less <
|
||||
# equal =
|
||||
# greater >
|
||||
# question ?
|
||||
# at @
|
||||
# bracketleft [
|
||||
# backslash \
|
||||
# bracketright ]
|
||||
# asciicircum ^
|
||||
# underscore _
|
||||
# grave `
|
||||
# braceleft {
|
||||
# bar |
|
||||
# braceright }
|
||||
# asciitilde ~
|
||||
# KP_Space 小键板空格
|
||||
# KP_Tab 小键板水平定位符
|
||||
# KP_Enter 小键板回车
|
||||
# KP_Delete 小键板删除
|
||||
# KP_Home 小键板原位
|
||||
# KP_Left 小键板左箭头
|
||||
# KP_Up 小键板上箭头
|
||||
# KP_Right 小键板右箭头
|
||||
# KP_Down 小键板下箭头
|
||||
# KP_Prior、KP_Page_Up 小键板上翻
|
||||
# KP_Next、KP_Page_Down 小键板下翻
|
||||
# KP_End 小键板末位
|
||||
# KP_Begin 小键板始位
|
||||
# KP_Insert 小键板插入
|
||||
# KP_Equal 小键板等于
|
||||
# KP_Multiply 小键板乘号
|
||||
# KP_Add 小键板加号
|
||||
# KP_Subtract 小键板减号
|
||||
# KP_Divide 小键板除号
|
||||
# KP_Decimal 小键板小数点
|
||||
# KP_0 小键板0
|
||||
# KP_1 小键板1
|
||||
# KP_2 小键板2
|
||||
# KP_3 小键板3
|
||||
# KP_4 小键板4
|
||||
# KP_5 小键板5
|
||||
# KP_6 小键板6
|
||||
# KP_7 小键板7
|
||||
# KP_8 小键板8
|
||||
# KP_9 小键板9
|
||||
19411
dicts/chengyu.txt
Normal file
19411
dicts/chengyu.txt
Normal file
File diff suppressed because it is too large
Load Diff
1904
dicts/cn&en.dict.yaml
Normal file
1904
dicts/cn&en.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
155
dicts/cuoyin.dict.yaml
Normal file
155
dicts/cuoyin.dict.yaml
Normal file
@@ -0,0 +1,155 @@
|
||||
# Rime dictionary
|
||||
# encoding: utf-8
|
||||
#https://github.com/amzxyz/RIME-LMDG
|
||||
#错音错字对照表
|
||||
---
|
||||
name: cuoyin
|
||||
version: "LTS"
|
||||
sort: by_weight
|
||||
...
|
||||
株木琅玛 zhū mù láng mǎ 1 有声
|
||||
衾何以堪 qīn hé yǐ kān 36 小说
|
||||
墨明棋妙 mò míng qí miào 38 乐队
|
||||
压力山大 yā lì shān dà 19 网络语
|
||||
鸭梨山大 yā lí shān dà 48 网络语
|
||||
麻麻赖赖 má má lài lài 16 网络语
|
||||
绝代双椒 jué dài shuāng jiāo 30 网络语
|
||||
毁人不倦 huǐ rén bú juàn 43 歌曲名
|
||||
佛教胜地 fó jiào shèng dì 1 佛教(圣)地
|
||||
杉杉来吃 shān shān lái chī 42 书名
|
||||
食话食说 shí huà shí shuō 25 节目
|
||||
零零总总 ling ling zong zong 6 林林总总
|
||||
文绉绉 wen zou zou 16 zhōu
|
||||
大栅栏 da zha lan 23 dà shí làn
|
||||
粘贴 nian tie 382 粘(zhān)贴
|
||||
曝光 pu guang 410 曝(bào)光
|
||||
东庠岛 dong yang dao 10 东庠(xiáng)岛
|
||||
视频 shi ping 490 视频(pín)
|
||||
剖腹产 pao fu chan 170 剖(pōu)腹产
|
||||
阻塞 zu sai 20 阻塞(sè)
|
||||
着想 zhao xiang 370 着(zhuó)想
|
||||
崩溃 ben kui 480 崩(bēng)溃
|
||||
句芒 ju mang 320 句(gōu)芒
|
||||
烘焙 hong pei 400 hōng bèi
|
||||
谄媚 xian mei 300 chǎn mèi
|
||||
着落 zhao luo 470 zhuó luò
|
||||
胁差 lei cha 430 xié chā
|
||||
刚劲 gang jin 420 gāng jìng
|
||||
井陉 jing jing 420 jǐng xíng
|
||||
猇亭 hu ting 340 xiāo tíng
|
||||
猇亭区 hu ting qu 130 猇(xiāo)亭区
|
||||
屎溺 shi ni 320 shǐ niào
|
||||
东庠 dong yang 230 dōng xiáng
|
||||
莒县 lü xian 440 jǔ xiàn
|
||||
浚县 jun xian 390 xùn xiàn
|
||||
郯城 ye cheng 390 tán chéng
|
||||
丽水 lì shuǐ 530 lí shuǐ
|
||||
珲春 hui chun 460 hún chūn
|
||||
甪直 yong zhi 440 lù zhí
|
||||
五厍 wu ku 360 wú shè
|
||||
台州 tái zhōu 400 tāi zhōu
|
||||
膻中 shan zhong 360 膻(dàn)中
|
||||
渑池 yin chi 400 miǎn chí
|
||||
渑池 sheng chi 400 miǎn chí
|
||||
铅山 qian shan 350 yán shān
|
||||
铅山县 qian shan xian 180 铅(yán)山县
|
||||
按耐 an nai 30 按捺(nà)
|
||||
甭介 béng jie 60 甭价(jie)
|
||||
别介 bié jie 30 别价(jie)
|
||||
槟榔 bin lang 630 bīng láng
|
||||
脖颈 bo jing 480 bó gěng
|
||||
草薙 cao zhi 90 cǎo tì
|
||||
掺和 chan he 440 chān huo
|
||||
称职 cheng zhi 90 chèn zhí
|
||||
龇牙 ci ya 60 zī yá
|
||||
凑活 còu huo 250 凑合(he)
|
||||
道行 dao hang 270 dào héng
|
||||
给予 gei yu 350 jǐ yǔ
|
||||
厚朴 hou pu 50 hòu pò
|
||||
馄饨 hun dun 400 hún tun
|
||||
角色 jiao se 200 jué sè
|
||||
结扎 jie zha 130 jié zā
|
||||
钜惠 jù huì 550 (巨)惠
|
||||
六安 liu an 110 lù ān
|
||||
女主角 nv zhu jiao 200 女主角(jué)
|
||||
埋怨 mai yuan 140 mán yuàn
|
||||
模板 mo ban 467 mú bǎn
|
||||
模具 mo ju 194 mú jù
|
||||
模样 mo yang 519 mú yàng
|
||||
木讷 mu na 470 mù nè
|
||||
弄堂 nong tang 130 lòng táng
|
||||
暖和 nuan he 590 nuǎn huo
|
||||
偌大 nuo da 680 偌(ruò)大
|
||||
强劲 qiang jin 281 qiáng jìng
|
||||
说服 shui fu 564 shuō fú
|
||||
似的 si de 700 似(shì)的
|
||||
藤蔓 teng man 320 téng wàn
|
||||
调换 tiao huan 620 diào huàn
|
||||
胴体 tong ti 80 dòng tǐ
|
||||
荨麻 xun ma 70 qián má
|
||||
亳州 hao zhou 500 bó zhōu
|
||||
天秤座 tian ping zuo 100 秤(chèng)
|
||||
戛然而止 ga ran er zhi 590 戛(jiá)然而止
|
||||
自怨自艾 zi yuan zi ai 520 自怨自艾(yì)
|
||||
洪洞 hong dong 420 hóng tóng
|
||||
蔚县 wei xian 430 yù xiàn
|
||||
嵊州 cheng zhou 440 shèng zhōu
|
||||
吱声 zhi sheng 220 zī shēng
|
||||
主角 zhu jiao 541 zhǔ jué
|
||||
脖颈儿 bo jing er 10 bó gěng er
|
||||
草薙剑 cao zhi jian 20 cǎo tì jiàn
|
||||
草薙京 cao zhi jing 140 cǎo tì jīng
|
||||
龇着牙 ci zhe ya 10 zī zhe yá
|
||||
大宛马 da wan ma 10 dà yuān mǎ
|
||||
独乐乐 du le le 10 dú yuè lè
|
||||
海参崴 hai shen wei 300 hǎi shēn wǎi
|
||||
贾平凹 jia ping ao 250 jià píng wā
|
||||
卡脖子 ka bo zi 310 qiǎ bó zi
|
||||
六安市 liu an shi 20 lù ān shì
|
||||
六安县 liu an xian 10 lù ān xiàn
|
||||
六合区 liu he qū 10 lù hé qū
|
||||
螺蛳粉 luo shi fen 650 luó sī fěn
|
||||
温庭筠 wen ting jun 210 温庭筠(yún)
|
||||
关卡 guan ka 640 guān qiǎ
|
||||
牛皮癣 niu pi xian 289 (癣)xuǎn
|
||||
三昧真火 san wei zhen huo 440 三昧(mèi)真火
|
||||
优惠券 you hui juan 420 优惠券(quàn)
|
||||
没食子 mei shi zi 70 没(mò)食子
|
||||
魔蝎座 mó xiē zuò 10 摩羯(jié)座
|
||||
鄱阳湖 pan yang hu 134 pó yáng hú
|
||||
契科夫 qī kē fū 10 契诃(hē)夫
|
||||
荨麻疹 qian ma zhen 200 xún má zhěn
|
||||
太行山 tai xing shan 390 tài háng shān
|
||||
头皮屑 tou pi xue 530 tóu pi xiè
|
||||
万柏林 wàn bó lín 10 万柏(bǎi)林
|
||||
雪佛兰 xue fo lan 370 xuě fú lán
|
||||
鸭绿江 ya lv jiang 150 yā lù jiāng
|
||||
张柏芝 zhang bai zhi 75 zhāng bó zhī
|
||||
众乐乐 zhong le le 20 zhòng yuè lè
|
||||
阿弥陀佛 a mi tuo fo 37 ē mí tuó fó
|
||||
安徽六安 an hui liu an 2 ān huī lù ān
|
||||
按耐不住 àn nài bú zhù 1 按捺(nà)不住
|
||||
龇牙咧嘴 ci ya lie zui 17 zī yá liě zuǐ
|
||||
大腹便便 da fu bian bian 15 dà fù pián pián
|
||||
歇斯底里 jie si di li 88 xiē sī dǐ lǐ
|
||||
力能扛鼎 li neng kang ding 3 lì néng gāng dǐng
|
||||
模棱两可 mo ling liang ke 85 mó léng liǎng kě
|
||||
南京六合 nan jing liu he 1 nán jīng lù hé
|
||||
人模狗样 ren mo gou yang 15 rén mú góu yàng
|
||||
心宽体胖 xin kuan ti pang 4 xīn kūan tǐ pán
|
||||
虚与委蛇 xu yu wei she 9 xū yǔ wēi yí
|
||||
血脉偾张 xuè mài fèn zhāng 1 血脉贲(bēn)张 | 血脉偾(fèn)张
|
||||
血脉喷张 xuè mài pēn zhāng 1 血脉贲(bēn)张 | 血脉偾(fèn)张
|
||||
一模一样 yi mo yi yang 508 yì mú yí yàng
|
||||
饮鸩解渴 yin jiu jie ke 1 饮鸩(zhèn)解渴
|
||||
饮鸩止渴 yin jiu zhi ke 34 饮鸩(zhèn)止渴
|
||||
饮鸩解渴 yin zhen jie ke 1 饮鸩(zhèn)解渴
|
||||
有模有样 you mo you yang 28 yǒu mú yǒu yàng
|
||||
装模作样 zhuang mo zuo yang 49 zhuāng mú zuò yàng
|
||||
安徽六安市 an hui liu an shi 1 ān huī lù ān shì
|
||||
南京六合区 nan jing liu he qu 1 nán jīng lù hé qū
|
||||
安徽省六安市 an hui sheng liu an shi 1 ān huī shěng lù ān shì
|
||||
南无阿弥陀佛 na mo a mi tuo fo 4 nā mó ē mí tuó fó
|
||||
南京市六合区 nan jing shi liu he qu 1 nán jīng shì lù hé qū
|
||||
南无阿弥陀佛 nan wu a mi tuo fo 4 nā mó ē mí tuó fó
|
||||
南无阿弥陀佛 nan wu e mi tuo fo 4 nā mó ē mí tuó fó
|
||||
40571
dicts/diming.dict.yaml
Normal file
40571
dicts/diming.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
5314
dicts/duoyin.dict.yaml
Normal file
5314
dicts/duoyin.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
51910
dicts/en.dict.yaml
Normal file
51910
dicts/en.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
1530646
dicts/jichu.dict.yaml
Normal file
1530646
dicts/jichu.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
317009
dicts/lianxiang.dict.yaml
Normal file
317009
dicts/lianxiang.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
327961
dicts/shici.dict.yaml
Normal file
327961
dicts/shici.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
70240
dicts/wuzhong.dict.yaml
Normal file
70240
dicts/wuzhong.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
51047
dicts/zi.dict.yaml
Normal file
51047
dicts/zi.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
231
lua/auto_phrase.lua
Normal file
231
lua/auto_phrase.lua
Normal file
@@ -0,0 +1,231 @@
|
||||
-- @amzxyz https://github.com/amzxyz/rime_wanxiang
|
||||
-- 自动造词
|
||||
local AP = {}
|
||||
|
||||
-- 注释缓存:text -> comment(只给中文造词用)
|
||||
local comment_cache = {}
|
||||
|
||||
-- 工具:是否纯英文(ASCII 且至少 1 个字母)
|
||||
local function is_ascii_word(text)
|
||||
if not text or text == "" then
|
||||
return false
|
||||
end
|
||||
local has_alpha = false
|
||||
for i = 1, #text do
|
||||
local b = text:byte(i)
|
||||
if b > 127 then
|
||||
return false
|
||||
end
|
||||
if (b >= 65 and b <= 90) or (b >= 97 and b <= 122) then
|
||||
has_alpha = true
|
||||
end
|
||||
end
|
||||
return has_alpha
|
||||
end
|
||||
|
||||
-- 判断字符是否为汉字(原逻辑)
|
||||
function AP.is_chinese_only(text)
|
||||
local non_chinese_pattern = "[%w%p]"
|
||||
|
||||
if not text or text == "" then
|
||||
return false
|
||||
end
|
||||
|
||||
if text:match(non_chinese_pattern) then
|
||||
return false
|
||||
end
|
||||
|
||||
for _, cp in utf8.codes(text) do
|
||||
-- 常用汉字区 + 扩展 A/B/C/D/E/F/G
|
||||
if not (
|
||||
(cp >= 0x4E00 and cp <= 0x9FFF) or -- CJK Unified Ideographs
|
||||
(cp >= 0x3400 and cp <= 0x4DBF) or -- CJK Ext-A
|
||||
(cp >= 0x20000 and cp <= 0x2EBEF) -- CJK Ext-B~G
|
||||
) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function AP.init(env)
|
||||
local config = env.engine.schema.config
|
||||
local ctx = env.engine.context
|
||||
|
||||
-- 中文自动造词的开关(只控制 add_user_dict)
|
||||
local enable_auto_phrase =
|
||||
config:get_bool("add_user_dict/enable_auto_phrase") or false
|
||||
local enable_user_dict =
|
||||
config:get_bool("add_user_dict/enable_user_dict") or false
|
||||
|
||||
-- 中文:add_user_dict(受 add_* 开关影响)
|
||||
if enable_auto_phrase and enable_user_dict then
|
||||
env.memory = Memory(env.engine, env.engine.schema, "add_user_dict")
|
||||
else
|
||||
env.memory = nil
|
||||
end
|
||||
|
||||
-- 英文:enuser(不受 add_* 开关影响,始终尝试启用)
|
||||
env.en_memory = Memory(env.engine, env.engine.schema, "wanxiang_mixedcode")
|
||||
|
||||
-- 只要有一边需要,就挂上 commit/delete 通知
|
||||
if env.en_memory or env.memory then
|
||||
env._commit_conn = ctx.commit_notifier:connect(function(c)
|
||||
AP.commit_handler(c, env)
|
||||
end)
|
||||
|
||||
env._delete_conn = ctx.delete_notifier:connect(function(_)
|
||||
comment_cache = {}
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function AP.fini(env)
|
||||
if env._commit_conn then
|
||||
env._commit_conn:disconnect()
|
||||
env._commit_conn = nil
|
||||
end
|
||||
|
||||
if env._delete_conn then
|
||||
env._delete_conn:disconnect()
|
||||
env._delete_conn = nil
|
||||
end
|
||||
|
||||
if env.memory then
|
||||
env.memory:disconnect()
|
||||
env.memory = nil
|
||||
end
|
||||
|
||||
if env.en_memory then
|
||||
env.en_memory:disconnect()
|
||||
env.en_memory = nil
|
||||
end
|
||||
end
|
||||
|
||||
function AP.save_comment_cache(cand)
|
||||
local comment = cand.comment
|
||||
local comment_text = cand.text
|
||||
|
||||
if comment_text and comment_text ~= "" and comment and comment ~= "" then
|
||||
comment_cache[comment_text] = comment
|
||||
end
|
||||
end
|
||||
|
||||
-- 入口(lua_filter)
|
||||
function AP.func(input, env)
|
||||
local config = env.engine.schema.config
|
||||
local context = env.engine.context
|
||||
|
||||
local use_comment_cache = env.memory ~= nil -- 只有中文造词才需要缓存注释
|
||||
|
||||
for cand in input:iter() do
|
||||
local genuine_cand = cand:get_genuine()
|
||||
local preedit = genuine_cand.preedit or ""
|
||||
local initial_comment = genuine_cand.comment
|
||||
|
||||
if use_comment_cache then
|
||||
AP.save_comment_cache(cand)
|
||||
end
|
||||
|
||||
yield(cand)
|
||||
end
|
||||
end
|
||||
|
||||
-- 造词(原逻辑 + 新增 '\' 英文造词)
|
||||
function AP.commit_handler(ctx, env)
|
||||
if not ctx or not ctx.composition then
|
||||
comment_cache = {}
|
||||
return
|
||||
end
|
||||
|
||||
local segments = ctx.composition:toSegmentation():get_segments()
|
||||
local segments_count = #segments
|
||||
local commit_text = ctx:get_commit_text() or ""
|
||||
local raw_input = ctx.input or ""
|
||||
|
||||
---------------------------------------------------
|
||||
-- ① 英文 + '\' 造词 —— 始终启用,只依赖 env.en_memory
|
||||
-- 条件:
|
||||
-- - raw_input 末尾为 '\'
|
||||
-- - commit_text 为“ASCII 且至少 1 字母”的英文
|
||||
-- 行为:
|
||||
-- - text = commit_text
|
||||
-- - custom_code = 编码去掉末尾 '\' + 空格
|
||||
---------------------------------------------------
|
||||
if raw_input ~= "" and raw_input:sub(-1) == "\\" and is_ascii_word(commit_text) then
|
||||
local code_body = raw_input:gsub("\\+$", "") -- 去掉末尾连续 '\'
|
||||
code_body = code_body:gsub("%s+$", "") -- 去掉尾部空白
|
||||
|
||||
if code_body ~= "" and env.en_memory then
|
||||
local entry = DictEntry()
|
||||
entry.text = commit_text -- 上屏英文本身
|
||||
entry.weight = 1
|
||||
entry.custom_code = code_body .. " " -- 真实编码(无 '\') + 空格
|
||||
|
||||
env.en_memory:update_userdict(entry, 1, "")
|
||||
-- log.info(string.format("[auto_phrase] EN 造词:[%s], code=[%s]", entry.text, entry.custom_code))
|
||||
end
|
||||
|
||||
comment_cache = {}
|
||||
return
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
-- ② 中文自动造词:只在 env.memory 存在时工作
|
||||
---------------------------------------------------
|
||||
if not env.memory then
|
||||
-- 中文造词功能被关掉时,直接跳过这一段
|
||||
comment_cache = {}
|
||||
return
|
||||
end
|
||||
|
||||
-- 检查是否符合最小造词单元要求
|
||||
if segments_count <= 1 or utf8.len(commit_text) <= 1 then
|
||||
comment_cache = {}
|
||||
return
|
||||
end
|
||||
|
||||
-- 检查是否符合造词内容要求
|
||||
if not AP.is_chinese_only(commit_text) or comment_cache[commit_text] then
|
||||
comment_cache = {}
|
||||
return
|
||||
end
|
||||
|
||||
local preedits_table = {}
|
||||
local config = env.engine.schema.config
|
||||
local delimiter = config:get_string("speller/delimiter") or " '"
|
||||
local escaped_delimiter =
|
||||
utf8.char(utf8.codepoint(delimiter)):gsub("(%W)", "%%%1")
|
||||
|
||||
for i = 1, segments_count do
|
||||
local seg = segments[i]
|
||||
local cand = seg:get_selected_candidate()
|
||||
|
||||
if cand then
|
||||
local cand_text = cand.text
|
||||
local preedit = comment_cache[cand_text]
|
||||
|
||||
if preedit and preedit ~= "" then
|
||||
for part in preedit:gmatch("[^" .. escaped_delimiter .. "]+") do
|
||||
table.insert(preedits_table, part)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if #preedits_table == 0 then
|
||||
comment_cache = {}
|
||||
return
|
||||
end
|
||||
|
||||
local dictEntry = DictEntry()
|
||||
dictEntry.text = commit_text
|
||||
dictEntry.weight = 1
|
||||
dictEntry.custom_code = table.concat(preedits_table, " ") .. " "
|
||||
|
||||
env.memory:update_userdict(dictEntry, 1, "")
|
||||
|
||||
comment_cache = {}
|
||||
end
|
||||
|
||||
return AP
|
||||
55
lua/backspace_limit.lua
Normal file
55
lua/backspace_limit.lua
Normal file
@@ -0,0 +1,55 @@
|
||||
-- backspace_limiter.lua
|
||||
-- 防止连续 Backspace 在编码为空时删除已上屏内容,虽然我更推荐拍下esc。
|
||||
-- 这个功能依赖按键事件的处理,运行逻辑的问题在手机上无法得到好的效果,其中macOS特非常特殊,它的按键事件等同于手机逻辑,因此手机和Mac都屏蔽了这一功能
|
||||
-- @author amzxyz
|
||||
local M = {}
|
||||
local ACCEPT, PASS = 1, 2
|
||||
|
||||
-- 引入移动设备检测模块
|
||||
local wanxiang = require("wanxiang")
|
||||
|
||||
-- 状态标志说明:
|
||||
-- env.prev_input_len: 上一次按键前的输入长度
|
||||
-- env.bs_sequence: 当前是否处于连续 Backspace 序列中
|
||||
|
||||
function M.init(env)
|
||||
env.prev_input_len = -1 -- 初始化为无效值
|
||||
env.bs_sequence = false
|
||||
end
|
||||
|
||||
function M.func(key, env)
|
||||
local ctx = env.engine.context
|
||||
local kc = key.keycode
|
||||
-- 非 Backspace 键或按键释放事件:重置状态
|
||||
if kc ~= 0xFF08 or key:release() then
|
||||
env.bs_sequence = false
|
||||
env.prev_input_len = -1
|
||||
return PASS
|
||||
end
|
||||
|
||||
-- 获取当前输入长度
|
||||
local current_len = #ctx.input
|
||||
|
||||
-- 处于连续 Backspace 序列中
|
||||
if env.bs_sequence then
|
||||
-- 移动设备由于运行逻辑的问题不能实现友好的逻辑
|
||||
if wanxiang.is_mobile_device() then
|
||||
return PASS -- 直接放行
|
||||
-- PC设备保持原有逻辑:长度1变0时拦截
|
||||
else
|
||||
if env.prev_input_len == 1 and current_len == 0 then
|
||||
return ACCEPT -- 拦截:PC设备上从1变为0的情况
|
||||
end
|
||||
end
|
||||
-- 更新状态
|
||||
env.prev_input_len = current_len
|
||||
return PASS
|
||||
end
|
||||
-- 开始新的 Backspace 序列
|
||||
env.bs_sequence = true
|
||||
env.prev_input_len = current_len
|
||||
-- 首次按键总是允许
|
||||
return PASS
|
||||
end
|
||||
|
||||
return M
|
||||
BIN
lua/charset.bin
Normal file
BIN
lua/charset.bin
Normal file
Binary file not shown.
262
lua/input_statistics.lua
Normal file
262
lua/input_statistics.lua
Normal file
@@ -0,0 +1,262 @@
|
||||
-- github.com/amzxyz
|
||||
-- 一个用于统计输入字数和其他时间维度的统计。先搭起一个框架,有志之士看看如何优化,统计什么数据,什么维度,构建一个有效的统计信息
|
||||
-- 硬编码输入方案信息
|
||||
local schema_name = "万象拼音"
|
||||
local software_name = rime_api.get_distribution_code_name()
|
||||
local software_version = rime_api.get_distribution_version()
|
||||
|
||||
-- 初始化统计表(若未加载)
|
||||
input_stats = input_stats or {
|
||||
daily = {count = 0, length = 0, fastest = 0, ts = 0},
|
||||
weekly = {count = 0, length = 0, fastest = 0, ts = 0},
|
||||
monthly = {count = 0, length = 0, fastest = 0, ts = 0},
|
||||
yearly = {count = 0, length = 0, fastest = 0, ts = 0},
|
||||
lengths = {},
|
||||
daily_max = 0,
|
||||
recent = {}
|
||||
}
|
||||
|
||||
-- 时间戳工具函数
|
||||
local function start_of_day(t)
|
||||
return os.time{year=t.year, month=t.month, day=t.day, hour=0}
|
||||
end
|
||||
local function start_of_week(t)
|
||||
local d = t.wday == 1 and 6 or (t.wday - 2)
|
||||
return os.time{year=t.year, month=t.month, day=t.day - d, hour=0}
|
||||
end
|
||||
local function start_of_month(t)
|
||||
return os.time{year=t.year, month=t.month, day=1, hour=0}
|
||||
end
|
||||
local function start_of_year(t)
|
||||
return os.time{year=t.year, month=1, day=1, hour=0}
|
||||
end
|
||||
|
||||
-- 判断是否是统计命令
|
||||
local function is_summary_command(text)
|
||||
return text == "/rtj" or text == "/ztj" or text == "/ytj" or text == "/ntj" or text == "/tj"
|
||||
end
|
||||
|
||||
-- 更新统计数据
|
||||
local function update_stats(input_length)
|
||||
local now = os.date("*t")
|
||||
local now_ts = os.time(now)
|
||||
|
||||
local day_ts = start_of_day(now)
|
||||
local week_ts = start_of_week(now)
|
||||
local month_ts = start_of_month(now)
|
||||
local year_ts = start_of_year(now)
|
||||
|
||||
if input_stats.daily.ts ~= day_ts then
|
||||
input_stats.daily = {count = 0, length = 0, fastest = 0, ts = day_ts}
|
||||
input_stats.daily_max = 0
|
||||
input_stats.recent = {}
|
||||
end
|
||||
if input_stats.weekly.ts ~= week_ts then
|
||||
input_stats.weekly = {count = 0, length = 0, fastest = 0, ts = week_ts}
|
||||
end
|
||||
if input_stats.monthly.ts ~= month_ts then
|
||||
input_stats.monthly = {count = 0, length = 0, fastest = 0, ts = month_ts}
|
||||
end
|
||||
if input_stats.yearly.ts ~= year_ts then
|
||||
input_stats.yearly = {count = 0, length = 0, fastest = 0, ts = year_ts}
|
||||
end
|
||||
|
||||
-- 更新记录
|
||||
local update = function(stat)
|
||||
stat.count = stat.count + 1
|
||||
stat.length = stat.length + input_length
|
||||
end
|
||||
update(input_stats.daily)
|
||||
update(input_stats.weekly)
|
||||
update(input_stats.monthly)
|
||||
update(input_stats.yearly)
|
||||
|
||||
if input_length > input_stats.daily_max then
|
||||
input_stats.daily_max = input_length
|
||||
end
|
||||
|
||||
input_stats.lengths[input_length] = (input_stats.lengths[input_length] or 0) + 1
|
||||
|
||||
-- 最近一分钟统计
|
||||
local ts = os.time()
|
||||
table.insert(input_stats.recent, {ts = ts, len = input_length})
|
||||
local threshold = ts - 60
|
||||
local total = 0
|
||||
local new_recent = {}
|
||||
for _, item in ipairs(input_stats.recent) do
|
||||
if item.ts >= threshold then
|
||||
total = total + item.len
|
||||
table.insert(new_recent, item)
|
||||
end
|
||||
end
|
||||
input_stats.recent = new_recent
|
||||
if total > input_stats.daily.fastest then input_stats.daily.fastest = total end
|
||||
if total > input_stats.weekly.fastest then input_stats.weekly.fastest = total end
|
||||
if total > input_stats.monthly.fastest then input_stats.monthly.fastest = total end
|
||||
if total > input_stats.yearly.fastest then input_stats.yearly.fastest = total end
|
||||
end
|
||||
|
||||
-- 表序列化工具(请自行根据实际添加到环境中)
|
||||
table.serialize = function(tbl)
|
||||
local lines = {"{"}
|
||||
for k, v in pairs(tbl) do
|
||||
local key = (type(k) == "string") and ("[\"" .. k .. "\"]") or ("[" .. k .. "]")
|
||||
local val
|
||||
if type(v) == "table" then
|
||||
val = table.serialize(v)
|
||||
elseif type(v) == "string" then
|
||||
val = '"' .. v .. '"'
|
||||
else
|
||||
val = tostring(v)
|
||||
end
|
||||
table.insert(lines, string.format(" %s = %s,", key, val))
|
||||
end
|
||||
table.insert(lines, "}")
|
||||
return table.concat(lines, "\n")
|
||||
end
|
||||
|
||||
-- 保存至文件
|
||||
local function save_stats()
|
||||
local path = rime_api.get_user_data_dir() .. "/lua/input_stats.lua"
|
||||
local file = io.open(path, "w")
|
||||
if not file then return end
|
||||
file:write("input_stats = " .. table.serialize(input_stats) .. "\n")
|
||||
file:close()
|
||||
end
|
||||
|
||||
-- 显示函数(以日统计为例)
|
||||
local function format_daily_summary()
|
||||
local s = input_stats.daily
|
||||
if s.count == 0 then return "※ 今天没有任何记录。" end
|
||||
return string.format(
|
||||
"※ 今天的统计:\n%s\n◉ 今天\n共上屏[%d]次\n共输入[%d]字\n最快一分钟输入了[%d]字\n%s\n◉ 方案:%s\n◉ 平台:%s %s\n%s",
|
||||
string.rep("─", 14), s.count, s.length, s.fastest,
|
||||
string.rep("─", 14), schema_name, software_name, software_version,
|
||||
string.rep("─", 14))
|
||||
end
|
||||
|
||||
-- 显示函数(周统计)
|
||||
local function format_weekly_summary()
|
||||
local s = input_stats.weekly
|
||||
if s.count == 0 then return "※ 本周没有任何记录。" end
|
||||
return string.format(
|
||||
"※ 本周的统计:\n%s\n◉ 本周共上屏[%d]次\n共输入[%d]字\n最快一分钟输入了[%d]字\n周内单日最多一次输入[%d]字\n%s\n◉ 方案:%s\n◉ 平台:%s %s\n%s",
|
||||
string.rep("─", 14), s.count, s.length, s.fastest, input_stats.daily_max,
|
||||
string.rep("─", 14), schema_name, software_name, software_version,
|
||||
string.rep("─", 14))
|
||||
end
|
||||
|
||||
-- 显示函数(月统计)
|
||||
local function format_monthly_summary()
|
||||
local s = input_stats.monthly
|
||||
if s.count == 0 then return "※ 本月没有任何记录。" end
|
||||
return string.format(
|
||||
"※ 本月的统计:\n%s\n◉ 本月共上屏[%d]次\n共输入[%d]字\n最快一分钟输入了[%d]字\n%s\n◉ 方案:%s\n◉ 平台:%s %s\n%s",
|
||||
string.rep("─", 14), s.count, s.length, s.fastest,
|
||||
string.rep("─", 14), schema_name, software_name, software_version,
|
||||
string.rep("─", 14))
|
||||
end
|
||||
|
||||
-- 显示函数(年统计)
|
||||
local function format_yearly_summary()
|
||||
local s = input_stats.yearly
|
||||
if s.count == 0 then return "※ 本年没有任何记录。" end
|
||||
local length_counts = {}
|
||||
for length, count in pairs(input_stats.lengths) do
|
||||
table.insert(length_counts, {length = length, count = count})
|
||||
end
|
||||
table.sort(length_counts, function(a, b) return a.count > b.count end)
|
||||
local fav = length_counts[1] and length_counts[1].length or 0
|
||||
return string.format(
|
||||
"※ 本年的统计:\n%s\n◉ 本年共上屏[%d]次\n共输入[%d]字\n最快一分钟输入了[%d]字\n您最常输入长度为[%d]的词组\n%s\n◉ 方案:%s\n◉ 平台:%s %s\n%s",
|
||||
string.rep("─", 14), s.count, s.length, s.fastest, fav,
|
||||
string.rep("─", 14), schema_name, software_name, software_version,
|
||||
string.rep("─", 14))
|
||||
end
|
||||
-- 转换器函数:处理命令 /rtj /ztj /ytj /ntj
|
||||
local function translator(input, seg, env)
|
||||
if input:sub(1, 1) ~= "/" then return end
|
||||
local summary = ""
|
||||
if input == "/rtj" then
|
||||
summary = format_daily_summary()
|
||||
elseif input == "/ztj" then
|
||||
summary = format_weekly_summary()
|
||||
elseif input == "/ytj" then
|
||||
summary = format_monthly_summary()
|
||||
elseif input == "/ntj" then
|
||||
summary = format_yearly_summary()
|
||||
elseif input == "/tj" then
|
||||
summary = format_daily_summary() .. "\n\n" .. format_weekly_summary() .. "\n\n" .. format_monthly_summary() .. "\n\n" .. format_yearly_summary()
|
||||
elseif input == "/tjql" then
|
||||
input_stats = {
|
||||
daily = {count = 0, length = 0, fastest = 0, ts = 0},
|
||||
weekly = {count = 0, length = 0, fastest = 0, ts = 0},
|
||||
monthly = {count = 0, length = 0, fastest = 0, ts = 0},
|
||||
yearly = {count = 0, length = 0, fastest = 0, ts = 0},
|
||||
lengths = {},
|
||||
daily_max = 0,
|
||||
recent = {}
|
||||
}
|
||||
save_stats()
|
||||
summary = "※ 所有统计数据已清空。"
|
||||
end
|
||||
|
||||
if summary ~= "" then
|
||||
yield(Candidate("stat", seg.start, seg._end, summary, ""))
|
||||
end
|
||||
end
|
||||
-- 加载保存的统计数据(input_stats.lua)
|
||||
local function load_stats_from_lua_file()
|
||||
local path = rime_api.get_user_data_dir() .. "/lua/input_stats.lua"
|
||||
local ok, result = pcall(function()
|
||||
local env = {}
|
||||
local f = loadfile(path, "t", env)
|
||||
if f then f() end
|
||||
return env.input_stats
|
||||
end)
|
||||
if ok and type(result) == "table" then
|
||||
input_stats = result
|
||||
else
|
||||
-- 保底初始化,防止错误
|
||||
input_stats = {
|
||||
daily = {count = 0, length = 0, fastest = 0, ts = 0},
|
||||
weekly = {count = 0, length = 0, fastest = 0, ts = 0},
|
||||
monthly = {count = 0, length = 0, fastest = 0, ts = 0},
|
||||
yearly = {count = 0, length = 0, fastest = 0, ts = 0},
|
||||
lengths = {},
|
||||
daily_max = 0,
|
||||
recent = {}
|
||||
}
|
||||
end
|
||||
end
|
||||
local function init(env)
|
||||
local ctx = env.engine.context
|
||||
|
||||
-- 加载历史统计数据
|
||||
load_stats_from_lua_file()
|
||||
|
||||
-- 注册提交通知回调
|
||||
ctx.commit_notifier:connect(function()
|
||||
local commit_text = ctx:get_commit_text()
|
||||
if not commit_text or commit_text == "" then return end
|
||||
|
||||
-- 排除统计命令(如 /rtj、/tj 等)
|
||||
if is_summary_command(commit_text) then return end
|
||||
|
||||
-- 排除统计候选上屏内容(例如 "※ 今天..." 或 "◉ 本年...")
|
||||
if commit_text:match("^[※◉]") then return end
|
||||
|
||||
-- 排除我们自己生成的统计候选(comment 是 "input_stats_summary")
|
||||
-- local cand = ctx:get_selected_candidate()
|
||||
-- if cand and cand.comment == "input_stats_summary" then return end
|
||||
|
||||
-- 保存最近一次 commit 内容
|
||||
env.last_commit_text = commit_text
|
||||
|
||||
-- 统计长度
|
||||
local input_length = utf8.len(commit_text) or string.len(commit_text)
|
||||
update_stats(input_length)
|
||||
save_stats()
|
||||
end)
|
||||
end
|
||||
return { init = init, func = translator }
|
||||
92
lua/key_binder.lua
Normal file
92
lua/key_binder.lua
Normal file
@@ -0,0 +1,92 @@
|
||||
-- 正则按键绑定处理器
|
||||
-- 本处理器在 Rime 标准库的按键绑定处理器(key_binder)的基础上增加了用正则表达式判断当前输入的编码的功能
|
||||
-- 也即,在输入编码不同时,可以将按键绑定到不同的功能
|
||||
|
||||
-- RIME_PROCESS_RESULTS 定义在 wanxiang.lua 中,这里需要引入才能使用
|
||||
local wanxiang = require("wanxiang")
|
||||
|
||||
local this = {}
|
||||
|
||||
---@class KeyBinderEnv: Env
|
||||
---@field redirecting boolean
|
||||
---@field bindings Binding[]
|
||||
|
||||
---@class Binding
|
||||
---element
|
||||
---@field match string
|
||||
---@field accept KeyEvent
|
||||
---@field send_sequence KeySequence
|
||||
|
||||
---解析配置文件中的按键绑定配置
|
||||
---@param value ConfigMap
|
||||
---@return Binding | nil
|
||||
local function parse(value)
|
||||
local match = value:get_value("match")
|
||||
local accept = value:get_value("accept")
|
||||
local send_sequence = value:get_value("send_sequence")
|
||||
if not match or not accept or not send_sequence then
|
||||
return nil
|
||||
end
|
||||
local key_event = KeyEvent(accept:get_string())
|
||||
local sequence = KeySequence(send_sequence:get_string())
|
||||
local binding = { match = match:get_string(), accept = key_event, send_sequence = sequence }
|
||||
return binding
|
||||
end
|
||||
|
||||
---@param env KeyBinderEnv
|
||||
function this.init(env)
|
||||
env.redirecting = false
|
||||
---@type Binding[]
|
||||
env.bindings = {}
|
||||
local bindings = env.engine.schema.config:get_list("key_binder/bindings")
|
||||
if not bindings then
|
||||
return
|
||||
end
|
||||
for i = 1, bindings.size do
|
||||
local item = bindings:get_at(i - 1)
|
||||
if not item then goto continue end
|
||||
local value = item:get_map()
|
||||
if not value then goto continue end
|
||||
local binding = parse(value)
|
||||
if not binding then goto continue end
|
||||
table.insert(env.bindings, binding)
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
|
||||
---@param key_event KeyEvent
|
||||
---@param env KeyBinderEnv
|
||||
---@return ProcessResult
|
||||
function this.func(key_event, env)
|
||||
-- local input = rime.current(env.engine.context)
|
||||
local input = env.engine.context.input
|
||||
-- log.info("key_binder"..input)
|
||||
if env.redirecting then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
|
||||
if not input then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
if env.engine.context == nil or env.engine.context.composition == nil or env.engine.context.composition:back() == nil then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
if not env.engine.context.composition:back():has_tag("abc") then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
for _, binding in ipairs(env.bindings) do
|
||||
-- 只有当按键和当前输入的模式都匹配的时候,才起作用
|
||||
if key_event:eq(binding.accept) and rime_api.regex_match(input, binding.match) then
|
||||
env.redirecting = true
|
||||
for _, event in ipairs(binding.send_sequence:toKeyEvent()) do
|
||||
env.engine:process_key(event)
|
||||
end
|
||||
env.redirecting = false
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
end
|
||||
end
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
return this
|
||||
256
lua/kp_number_processor.lua
Normal file
256
lua/kp_number_processor.lua
Normal file
@@ -0,0 +1,256 @@
|
||||
-- https://github.com/amzxyz/rime_wanxiang
|
||||
-- 万象家族 lua,小键盘行为控制:
|
||||
-- - 小键盘数字:根据 kp_number_mode 决定 “参与编码 / 直接上屏”
|
||||
-- - 主键盘数字:在有候选菜单时,用于选第 n 个候选
|
||||
--
|
||||
-- 用法示例(schema.yaml):
|
||||
-- engine:
|
||||
-- processors:
|
||||
-- - lua_processor@*kp_number_processor
|
||||
-- # 小键盘模式(可省略,默认 auto)
|
||||
-- # auto : 空闲时直接上屏,输入中参与编码
|
||||
-- # compose : 无论是否在输入中,小键盘都参与编码(不直接上屏)
|
||||
-- kp_number_mode: auto
|
||||
|
||||
local wanxiang = require("wanxiang")
|
||||
|
||||
-- 小键盘键码映射
|
||||
local KP = {
|
||||
[0xFFB1] = 1, -- KP_1
|
||||
[0xFFB2] = 2,
|
||||
[0xFFB3] = 3,
|
||||
[0xFFB4] = 4,
|
||||
[0xFFB5] = 5,
|
||||
[0xFFB6] = 6,
|
||||
[0xFFB7] = 7,
|
||||
[0xFFB8] = 8,
|
||||
[0xFFB9] = 9,
|
||||
[0xFFB0] = 0, -- KP_0
|
||||
}
|
||||
|
||||
local P = {}
|
||||
|
||||
-- 从 schema 读取 kp_number/patterns 列表
|
||||
local function load_function_patterns(config)
|
||||
local patterns = {}
|
||||
|
||||
local ok_list, list = pcall(function()
|
||||
return config:get_list("kp_number/patterns")
|
||||
end)
|
||||
if ok_list and list and list.size and list.size > 0 then
|
||||
for i = 0, list.size - 1 do
|
||||
local item = list:get_value_at(i)
|
||||
if item then
|
||||
local pat = item:get_string()
|
||||
if pat and pat ~= "" then
|
||||
table.insert(patterns, pat)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 如果用户没配,给一份保底的默认集合(等价你现在用的那些)
|
||||
if #patterns == 0 then
|
||||
patterns = {
|
||||
"^/[0-9]$", "^/10$", "^/[A-Za-z]+$",
|
||||
"^`[A-Za-z]*$",
|
||||
"^``[A-Za-z/`']*$",
|
||||
"^U[%da-f]+$",
|
||||
"^R[0-9]+%.?[0-9]*$",
|
||||
"^N0[1-9]?0?[1-9]?$",
|
||||
"^N1[02]?0?[1-9]?$",
|
||||
"^N0[1-9]?[1-2]?[1-9]?$",
|
||||
"^N1[02]?[1-2]?[1-9]?$",
|
||||
"^N0[1-9]?3?[01]?$",
|
||||
"^N1[02]?3?[01]?$",
|
||||
"^N19?[0-9]?[0-9]?[01]?[0-2]?[0-3]?[0-9]?$",
|
||||
"^N20?[0-9]?[0-9]?[01]?[0-2]?[0-3]?[0-9]?$",
|
||||
"^V.*$",
|
||||
}
|
||||
end
|
||||
|
||||
return patterns
|
||||
end
|
||||
|
||||
-- 根据“当前编码 + 这次按下的数字字符”判断是否属于命令模式
|
||||
local function is_function_code_after_digit(env, context, digit_char)
|
||||
if not context or not digit_char or digit_char == "" then
|
||||
return false
|
||||
end
|
||||
local code = context.input or ""
|
||||
local s = code .. digit_char
|
||||
|
||||
local pats = env.function_patterns
|
||||
if not pats or #pats == 0 then
|
||||
return false
|
||||
end
|
||||
|
||||
for _, pat in ipairs(pats) do
|
||||
-- 这里 pat 必须是 Lua pattern 语法
|
||||
if s:match(pat) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
---@param env Env
|
||||
function P.init(env)
|
||||
local engine = env.engine
|
||||
local config = engine.schema.config
|
||||
local context = engine.context
|
||||
|
||||
-- 读数字选词个数
|
||||
env.page_size = config:get_int("menu/page_size") or 6
|
||||
|
||||
-- 读小键盘模式:auto / compose,默认 auto
|
||||
local m = config:get_string("kp_number/kp_number_mode") or "auto"
|
||||
if m ~= "auto" and m ~= "compose" then
|
||||
m = "auto"
|
||||
end
|
||||
env.kp_mode = m
|
||||
|
||||
-- 初始化状态快照
|
||||
env.context = context
|
||||
env.is_composing = context:is_composing()
|
||||
env.has_menu = context:has_menu()
|
||||
|
||||
-- 读取命令模式 Lua pattern 集合
|
||||
env.function_patterns = load_function_patterns(config)
|
||||
|
||||
-- 用 update_notifier 同步 context / is_composing / has_menu
|
||||
env.kp_update_connection = context.update_notifier:connect(function(ctx)
|
||||
env.context = ctx
|
||||
env.is_composing = ctx:is_composing()
|
||||
env.has_menu = ctx:has_menu()
|
||||
end)
|
||||
end
|
||||
|
||||
---@param env Env
|
||||
function P.fini(env)
|
||||
if env.kp_update_connection then
|
||||
env.kp_update_connection:disconnect()
|
||||
env.kp_update_connection = nil
|
||||
end
|
||||
env.context = nil
|
||||
env.is_composing = nil
|
||||
env.has_menu = nil
|
||||
env.function_patterns = nil
|
||||
end
|
||||
|
||||
---@param key KeyEvent
|
||||
---@param env Env
|
||||
---@return ProcessResult
|
||||
function P.func(key, env)
|
||||
-- 只处理按下
|
||||
if key:release() then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
local engine = env.engine
|
||||
local context = env.context or engine.context
|
||||
local mode = env.kp_mode or "auto"
|
||||
local page_sz = env.page_size
|
||||
|
||||
local is_composing = env.is_composing
|
||||
local has_menu = env.has_menu
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- 1) 小键盘数字:auto / compose
|
||||
-- 如果“加上本次数字后”还匹配某个命令模式 pattern:
|
||||
-- 只作为编码输入,不 commit、不选词。
|
||||
------------------------------------------------------------------
|
||||
local kp_num = KP[key.keycode]
|
||||
if kp_num ~= nil then
|
||||
local ch = tostring(kp_num) -- "0".."9"
|
||||
|
||||
if is_function_code_after_digit(env, context, ch) then
|
||||
if context then
|
||||
if context.push_input then
|
||||
context:push_input(ch)
|
||||
else
|
||||
context.input = (context.input or "") .. ch
|
||||
end
|
||||
end
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
end
|
||||
|
||||
if mode == "auto" then
|
||||
-- 输入中:参与编码;空闲:直接上屏
|
||||
if is_composing then
|
||||
if context.push_input then
|
||||
context:push_input(ch)
|
||||
else
|
||||
context.input = (context.input or "") .. ch
|
||||
end
|
||||
else
|
||||
engine:commit_text(ch)
|
||||
end
|
||||
else
|
||||
-- compose:始终参与编码
|
||||
if context.push_input then
|
||||
context:push_input(ch)
|
||||
else
|
||||
context.input = (context.input or "") .. ch
|
||||
end
|
||||
end
|
||||
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
end
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- 2) 主键盘数字:
|
||||
-- 2.1 若“加上本次数字后”匹配命令模式 → 只当编码输入
|
||||
-- 2.2 否则:
|
||||
-- 有菜单时:选第 n 个候选
|
||||
-- 空闲时:直接上屏
|
||||
------------------------------------------------------------------
|
||||
local r = key:repr() or ""
|
||||
|
||||
if r:match("^[0-9]$") then
|
||||
-- 命令模式:只作为编码输入
|
||||
if is_function_code_after_digit(env, context, r) then
|
||||
if context then
|
||||
if context.push_input then
|
||||
context:push_input(r)
|
||||
else
|
||||
context.input = (context.input or "") .. r
|
||||
end
|
||||
end
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
end
|
||||
|
||||
-- 有候选菜单时,用数字选「当前页」的第 n 个候选
|
||||
if has_menu then
|
||||
local d = tonumber(r)
|
||||
if d and d >= 1 and d <= page_sz then
|
||||
local composition = context and context.composition
|
||||
if composition and not composition:empty() then
|
||||
local seg = composition:back() -- 当前正在编辑的 segment
|
||||
local menu = seg and seg.menu
|
||||
if menu and not menu:empty() then
|
||||
-- 当前高亮候选的全局下标(0 开始)
|
||||
local sel_index = seg.selected_index or 0
|
||||
local page_size = page_sz
|
||||
-- 当前页号 = 高亮索引 / 每页大小
|
||||
local page_no = math.floor(sel_index / page_size)
|
||||
local page_start = page_no * page_size
|
||||
-- 当前页第 n 个候选的全局下标
|
||||
local index = page_start + (d - 1)
|
||||
|
||||
-- 防止越界(最后一页候选不足一整页)
|
||||
if index < menu:candidate_count() then
|
||||
if context:select(index) then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
end
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
return P
|
||||
89
lua/letter_selector.lua
Normal file
89
lua/letter_selector.lua
Normal file
@@ -0,0 +1,89 @@
|
||||
-- @amzxyz https://github.com/amzxyz/rime_wanxiang
|
||||
-- 功能:仅在特定前缀或者tag模式下,按 qwertyuio 选择第 1~9 个候选
|
||||
|
||||
local wanxiang = require("wanxiang")
|
||||
|
||||
local M = {}
|
||||
|
||||
-- 键码映射:q w e r t y u i o → 1..9
|
||||
local KEY2IDX = {
|
||||
[0x71] = 1, -- q
|
||||
[0x77] = 2, -- w
|
||||
[0x65] = 3, -- e
|
||||
[0x72] = 4, -- r
|
||||
[0x74] = 5, -- t
|
||||
[0x79] = 6, -- y
|
||||
[0x75] = 7, -- u
|
||||
[0x69] = 8, -- i
|
||||
[0x6F] = 9, -- o
|
||||
}
|
||||
|
||||
-- 判断是否在命令模式
|
||||
local function is_function_mode_active(context)
|
||||
if not context or not context.composition or context.composition:empty() then
|
||||
return false
|
||||
end
|
||||
local seg = context.composition:back()
|
||||
if not seg then return false end
|
||||
return seg:has_tag("number") or seg:has_tag("Ndate")
|
||||
end
|
||||
|
||||
-- 缓存命令模式的状态,避免每次按键都计算
|
||||
local function on_update(env, ctx)
|
||||
env._fn_active = is_function_mode_active(ctx)
|
||||
end
|
||||
|
||||
function M.init(env)
|
||||
env._fn_active = false
|
||||
env._upd_conn = env.engine.context.update_notifier:connect(function(ctx)
|
||||
on_update(env, ctx)
|
||||
end)
|
||||
end
|
||||
|
||||
function M.fini(env)
|
||||
if env._upd_conn then
|
||||
env._upd_conn:disconnect()
|
||||
env._upd_conn = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function handle_key(key_event, env)
|
||||
-- 只处理按下;有修饰键则忽略
|
||||
if key_event:release() or key_event:ctrl() or key_event:alt() or key_event:super() then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
local idx = KEY2IDX[key_event.keycode]
|
||||
if not idx then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
local context = env.engine.context
|
||||
if not env._fn_active then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
if not context or not context.composition or context.composition:empty() then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
local seg = context.composition:back()
|
||||
if not seg or not seg.menu then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
-- 准备最多 9 个候选
|
||||
local count = seg.menu:prepare(9)
|
||||
if idx < 1 or idx > count then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
-- 选择:候选索引从 0 开始
|
||||
context:select(idx - 1)
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
end
|
||||
|
||||
function M.func(key_event, env)
|
||||
return handle_key(key_event, env)
|
||||
end
|
||||
|
||||
return M
|
||||
68
lua/lib/bit.lua
Normal file
68
lua/lib/bit.lua
Normal file
@@ -0,0 +1,68 @@
|
||||
local bit_ok, bit_ = pcall(require, "bit") -- LuaJIT 内置 bit 库
|
||||
local bit32_ok, bit32_ = pcall(require, "bit32") -- Lua 5.2 内置 bit32 库
|
||||
|
||||
---@alias fn_band fun(a: integer, b: integer): integer
|
||||
---@alias fn_bxor fun(a: integer, b: integer): integer
|
||||
---@type nil | { band: fn_band, bxor: fn_bxor }
|
||||
local bit53_ = nil -- Lua 5.3 引入的原生位运算操作符
|
||||
|
||||
---@diagnostic disable-next-line: deprecated
|
||||
local load_func = load or loadstring
|
||||
if load_func then
|
||||
---将新语法放入字符串中,避免在旧版 Lua 中导致语法错误
|
||||
local bit53_func, bit53_err = load_func("return {" ..
|
||||
"band = function(a, b) return a & b end," ..
|
||||
"bxor = function(a, b) return a ~ b end," ..
|
||||
"}")
|
||||
if bit53_func and not bit53_err then
|
||||
bit53_ = bit53_func()
|
||||
end
|
||||
end
|
||||
|
||||
local bit = {}
|
||||
|
||||
---@return integer
|
||||
function bit.bxor(a, b)
|
||||
if bit_ok then
|
||||
return bit_.bxor(a, b)
|
||||
elseif bit32_ok then
|
||||
return bit32_.bxor(a, b)
|
||||
elseif bit53_ then
|
||||
return bit53_.bxor(a, b)
|
||||
end
|
||||
|
||||
local p, c = 1, 0
|
||||
while a > 0 and b > 0 do
|
||||
local ra, rb = a % 2, b % 2
|
||||
if ra ~= rb then c = c + p end
|
||||
a, b, p = (a - ra) / 2, (b - rb) / 2, p * 2
|
||||
end
|
||||
if a < b then a = b end
|
||||
while a > 0 do
|
||||
local ra = a % 2
|
||||
if ra > 0 then c = c + p end
|
||||
a, p = (a - ra) / 2, p * 2
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
---@return integer
|
||||
function bit.band(a, b)
|
||||
if bit_ok then
|
||||
return bit_.band(a, b)
|
||||
elseif bit32_ok then
|
||||
return bit32_.band(a, b)
|
||||
elseif bit53_ then
|
||||
return bit53_.band(a, b)
|
||||
end
|
||||
|
||||
local p, c = 1, 0
|
||||
while a > 0 and b > 0 do
|
||||
local ra, rb = a % 2, b % 2
|
||||
if ra + rb > 1 then c = c + p end
|
||||
a, b, p = (a - ra) / 2, (b - rb) / 2, p * 2
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
return bit
|
||||
116
lua/lib/userdb.lua
Normal file
116
lua/lib/userdb.lua
Normal file
@@ -0,0 +1,116 @@
|
||||
local META_KEY_PREFIX = "\001" .. "/"
|
||||
|
||||
-- UserDb 缓存,使用弱引用表,不阻止垃圾回收并能自动清理
|
||||
local db_pool = setmetatable({}, { __mode = "v" })
|
||||
|
||||
---@class WrappedUserDb: UserDb
|
||||
---@field meta_query fun(self: self, prefix: string): DbAccessor
|
||||
---@field meta_fetch fun(self: self, key: string): string|nil
|
||||
---@field meta_update fun(self: self, key: string, value: string): boolean
|
||||
---@field meta_erase fun(self: self, key: string): boolean
|
||||
---@field query_with fun(self: self, prefix: string, handler: fun(key: string, value: string))
|
||||
---@field empty fun(self: self, include_metafield?: boolean) -- 清空数据库
|
||||
|
||||
-- 用于存放包装器对象的自定义方法
|
||||
local extends = {}
|
||||
|
||||
--- @param key string
|
||||
--- @return string|nil
|
||||
function extends:meta_fetch(key)
|
||||
return self._db:fetch(META_KEY_PREFIX .. key)
|
||||
end
|
||||
|
||||
--- @param key string
|
||||
--- @param value string
|
||||
--- @return boolean
|
||||
function extends:meta_update(key, value)
|
||||
return self._db:update(META_KEY_PREFIX .. key, value)
|
||||
end
|
||||
|
||||
--- @param key string
|
||||
--- @return boolean
|
||||
function extends:meta_erase(key)
|
||||
return self._db:erase(META_KEY_PREFIX .. key)
|
||||
end
|
||||
|
||||
--- @param prefix string
|
||||
--- @return DbAccessor
|
||||
function extends:meta_query(prefix)
|
||||
return self._db:query(META_KEY_PREFIX .. prefix)
|
||||
end
|
||||
|
||||
function extends:query_with(prefix, handler)
|
||||
local da = self._db:query(prefix)
|
||||
if da then
|
||||
for key, value in da:iter() do
|
||||
handler(key, value)
|
||||
end
|
||||
end
|
||||
da = nil
|
||||
collectgarbage()
|
||||
end
|
||||
|
||||
--- @param include_metafield boolean 是否也清理元数据。
|
||||
function extends:empty(include_metafield)
|
||||
self:query_with("", function(key, _)
|
||||
local is_metafield = key:find(META_KEY_PREFIX, 1, true) == 1
|
||||
if include_metafield or not is_metafield then
|
||||
self._db:erase(key)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local mt = {
|
||||
__index = function(wrapper, key)
|
||||
-- 优先使用自定义方法
|
||||
if extends[key] then
|
||||
return extends[key]
|
||||
end
|
||||
|
||||
-- 不是自定义方法,委托给真实的 UserDb 对象
|
||||
local real_db = wrapper._db
|
||||
local value = real_db[key]
|
||||
|
||||
if type(value) == "function" then
|
||||
return function(_, ...)
|
||||
return value(real_db, ...)
|
||||
end
|
||||
end
|
||||
|
||||
return value
|
||||
end,
|
||||
}
|
||||
|
||||
local userdb = {}
|
||||
|
||||
--- @param db_name string
|
||||
--- @param db_class "userdb" | "plain_userdb" | nil
|
||||
--- @return WrappedUserDb
|
||||
function userdb.UserDb(db_name, db_class)
|
||||
db_class = db_class or "userdb"
|
||||
local key = db_name .. "." .. db_class
|
||||
|
||||
---@type UserDb
|
||||
local db = db_pool[key]
|
||||
if not db then
|
||||
db = UserDb(db_name, db_class)
|
||||
db_pool[key] = db
|
||||
end
|
||||
|
||||
local wrapper = {
|
||||
_db = db,
|
||||
_pool_key = key,
|
||||
}
|
||||
|
||||
return setmetatable(wrapper, mt)
|
||||
end
|
||||
|
||||
function userdb.LevelDb(db_name)
|
||||
return userdb.UserDb(db_name, "userdb")
|
||||
end
|
||||
|
||||
function userdb.TableDb(db_name)
|
||||
return userdb.UserDb(db_name, "plain_userdb")
|
||||
end
|
||||
|
||||
return userdb
|
||||
722
lua/librime.lua
Normal file
722
lua/librime.lua
Normal file
@@ -0,0 +1,722 @@
|
||||
-- librime-lua 官方类型提示
|
||||
-- ⚠️ 仅用于类型提升,请勿直接 require 使用
|
||||
-- from https://github.com/hchunhui/librime-lua/blob/master/contrib/librime.lua
|
||||
-- Last Change: LTS
|
||||
---@meta rime
|
||||
|
||||
--- 全局对象
|
||||
|
||||
---@class RimeAPI
|
||||
---@field get_rime_version fun(): string
|
||||
---@field get_shared_data_dir fun(): string
|
||||
---@field get_user_data_dir fun(): string
|
||||
---@field get_sync_dir fun(): string
|
||||
---@field get_distribution_name fun(): string
|
||||
---@field get_distribution_code_name fun(): string
|
||||
---@field get_distribution_version fun(): string
|
||||
---@field get_user_id fun(): string
|
||||
---@field get_time_ms fun(): number
|
||||
---@field regex_match fun(input: string, pattern: string): boolean
|
||||
---@field regex_search fun(input: string, pattern: string): string[] | nil
|
||||
---@field regex_replace fun(input: string, pattern: string, fmt: string): string
|
||||
rime_api = {}
|
||||
|
||||
---@class Log
|
||||
---@field info fun(string)
|
||||
---@field warning fun(string)
|
||||
---@field error fun(string)
|
||||
log = {}
|
||||
|
||||
---@param cand Candidate
|
||||
function yield(cand) end
|
||||
|
||||
--- 常量
|
||||
|
||||
---@enum ConfigType
|
||||
local config_types = {
|
||||
kNull = "kNull",
|
||||
kScalar = "kScalar",
|
||||
kList = "kList",
|
||||
kMap = "kMap",
|
||||
}
|
||||
|
||||
---@enum SegmentType
|
||||
local segment_types = {
|
||||
kVoid = "kVoid",
|
||||
kGuess = "kGuess",
|
||||
kSelected = "kSelected",
|
||||
kConfirmed = "kConfirmed",
|
||||
}
|
||||
|
||||
---@enum CandidateDynamicType
|
||||
local candidate_dynamic_types = {
|
||||
kSentence = "Sentence",
|
||||
kPhrase = "Phrase",
|
||||
kSimple = "Simple",
|
||||
kShadow = "Shadow",
|
||||
kUniquified = "Uniquified",
|
||||
kOther = "Other",
|
||||
}
|
||||
|
||||
---@enum ProcessResult
|
||||
local process_results = {
|
||||
kRejected = 0,
|
||||
kAccepted = 1,
|
||||
kNoop = 2,
|
||||
}
|
||||
|
||||
---@enum ModifierMask
|
||||
local modifier_masks = {
|
||||
kShift = 0x1,
|
||||
kLock = 0x2,
|
||||
kControl = 0x4,
|
||||
kAlt = 0x8,
|
||||
}
|
||||
|
||||
--- 工具
|
||||
|
||||
---@class Set
|
||||
---@field empty fun(self: self): boolean
|
||||
---@field __index function
|
||||
---@field __add function
|
||||
---@field __sub function
|
||||
---@field __mul function
|
||||
---@field __set function
|
||||
|
||||
---@param values any[]
|
||||
---@return Set
|
||||
function Set(values) end
|
||||
|
||||
--- 对象接口及构造函数
|
||||
|
||||
---@class Env
|
||||
---@field engine Engine
|
||||
---@field name_space string
|
||||
|
||||
---@class Engine
|
||||
---@field schema Schema
|
||||
---@field context Context
|
||||
---@field active_engine Engine
|
||||
---@field process_key fun(self: self, key_event: KeyEvent): boolean
|
||||
---@field compose fun(self: self, ctx: Context)
|
||||
---@field commit_text fun(self: self, text: string)
|
||||
---@field apply_schema fun(self: self, schema: Schema)
|
||||
|
||||
---@class Context
|
||||
---@field composition Composition
|
||||
---@field input string
|
||||
---@field caret_pos integer
|
||||
---@field commit_notifier Notifier
|
||||
---@field select_notifier Notifier
|
||||
---@field update_notifier Notifier
|
||||
---@field delete_notifier Notifier
|
||||
---@field option_update_notifier OptionUpdateNotifier
|
||||
---@field property_update_notifier PropertyUpdateNotifier
|
||||
---@field unhandled_key_notifier KeyEventNotifier
|
||||
---@field commit_history CommitHistory
|
||||
---@field commit fun(self: self)
|
||||
---@field get_commit_text fun(self: self): string
|
||||
---@field get_script_text fun(self: self): string
|
||||
---@field get_preedit fun(self: self): Preedit
|
||||
---@field is_composing fun(self: self): boolean
|
||||
---@field has_menu fun(self: self): boolean
|
||||
---@field get_selected_candidate fun(self: self): Candidate
|
||||
---@field push_input fun(self: self, text: string)
|
||||
---@field pop_input fun(self: self, len: integer): boolean
|
||||
---@field delete_input fun(self: self, len: integer): boolean
|
||||
---@field clear fun(self: self)
|
||||
---@field select fun(self: self, index: integer): boolean
|
||||
---@field highlight fun(self: self, index: integer): boolean
|
||||
---@field confirm_current_selection fun(self: self): boolean
|
||||
---@field delete_current_selection fun(self: self): boolean
|
||||
---@field confirm_previous_selection fun(self: self): boolean
|
||||
---@field reopen_previous_selection fun(self: self): boolean
|
||||
---@field clear_previous_segment fun(self: self): boolean
|
||||
---@field reopen_previous_segment fun(self: self): boolean
|
||||
---@field clear_non_confirmed_composition fun(self: self): boolean
|
||||
---@field refresh_non_confirmed_composition fun(self: self): boolean
|
||||
---@field set_option fun(self: self, name: string, value: boolean)
|
||||
---@field get_option fun(self: self, name: string): boolean
|
||||
---@field set_property fun(self: self, key: string, value: string)
|
||||
---@field get_property fun(self: self, key: string): string
|
||||
---@field clear_transient_options fun(self: self)
|
||||
|
||||
---@class Preedit
|
||||
---@field text string
|
||||
---@field caret_pos integer
|
||||
---@field sel_start integer
|
||||
---@field sel_end integer
|
||||
|
||||
---@class Composition
|
||||
---@field empty fun(self: self): boolean
|
||||
---@field back fun(self: self): Segment
|
||||
---@field pop_back fun(self: self)
|
||||
---@field push_back fun(self: self)
|
||||
---@field has_finished_composition fun(self: self): boolean
|
||||
---@field get_prompt fun(self: self): string
|
||||
---@field toSegmentation fun(self: self): Segmentation
|
||||
---@field spans fun(self: self): Spans
|
||||
|
||||
---@class Segmentation
|
||||
---@field input string
|
||||
---@field size integer
|
||||
---@field empty fun(self: self): boolean
|
||||
---@field back fun(self: self): Segment | nil
|
||||
---@field pop_back fun(self: self)
|
||||
---@field reset_length fun(self: self, length: integer)
|
||||
---@field add_segment fun(self: self, seg: Segment): boolean
|
||||
---@field forward fun(self: self): boolean
|
||||
---@field trim fun(self: self): boolean
|
||||
---@field has_finished_segmentation fun(self: self): boolean
|
||||
---@field get_current_start_position fun(self: self): integer
|
||||
---@field get_current_end_position fun(self: self): integer
|
||||
---@field get_current_segment_length fun(self: self): integer
|
||||
---@field get_confirmed_position fun(self: self): integer
|
||||
---@field get_segments fun(self: self): Segment[]
|
||||
---@field get_at fun(self: self, index: integer): Segment
|
||||
|
||||
---@class Segment
|
||||
---@field status SegmentType
|
||||
---@field start integer
|
||||
---@field _start integer
|
||||
---@field _end integer
|
||||
---@field length integer
|
||||
---@field tags Set
|
||||
---@field menu Menu
|
||||
---@field selected_index integer
|
||||
---@field prompt string
|
||||
---@field clear fun(self: self)
|
||||
---@field close fun(self: self)
|
||||
---@field reopen fun(self: self, caret_pos: integer)
|
||||
---@field has_tag fun(self: self, tag: string): boolean
|
||||
---@field get_candidate_at fun(self: self, index: integer): Candidate
|
||||
---@field get_selected_candidate fun(self: self): Candidate
|
||||
---@field active_text fun(self: self, text: string): string
|
||||
---@field spans fun(self: self): Spans
|
||||
|
||||
---@param start_pos integer
|
||||
---@param end_pos integer
|
||||
---@return Segment
|
||||
function Segment(start_pos, end_pos) end
|
||||
|
||||
---@class Spans
|
||||
---@field _start integer
|
||||
---@field _end integer
|
||||
---@field count integer
|
||||
---@field vertices integer[]
|
||||
---@field add_span fun(self: self, start: integer, end: integer)
|
||||
---@field add_spans fun(self: self, spans: Spans)
|
||||
---@field add_vertex fun(self: self, vertex: integer)
|
||||
---@field previous_stop fun(self: self, caret_pos: integer): integer
|
||||
---@field next_stop fun(self: self, caret_pos: integer): integer
|
||||
---@field has_vertex fun(self: self, vertex: integer): boolean
|
||||
---@field count_between fun(self: self, start: integer, end: integer): integer
|
||||
---@field clear fun(self: self)
|
||||
|
||||
---@return Spans
|
||||
function Spans() end
|
||||
|
||||
---@class Schema
|
||||
---@field schema_id string
|
||||
---@field schema_name string
|
||||
---@field config Config
|
||||
---@field page_size integer
|
||||
---@field select_keys string
|
||||
|
||||
---@param schema_id string
|
||||
---@return Schema
|
||||
function Schema(schema_id) end
|
||||
|
||||
---@class Config
|
||||
---@field load_from_file fun(self: self, filename: string): boolean
|
||||
---@field save_to_file fun(self: self, filename: string): boolean
|
||||
---@field is_null fun(self: self, conf_path: string): boolean
|
||||
---@field is_value fun(self: self, conf_path: string): boolean
|
||||
---@field is_list fun(self: self, conf_path: string): boolean
|
||||
---@field is_map fun(self: self, conf_path: string): boolean
|
||||
---@field get_bool fun(self: self, conf_path: string): boolean|nil
|
||||
---@field set_bool fun(self: self, conf_path: string, b: boolean): boolean
|
||||
---@field get_int fun(self: self, conf_path: string): integer|nil
|
||||
---@field set_int fun(self: self, conf_path: string, i: integer): boolean
|
||||
---@field get_double fun(self: self, conf_path: string): number|nil
|
||||
---@field set_double fun(self: self, conf_path: string, f: number): boolean
|
||||
---@field get_string fun(self: self, conf_path: string): string|nil
|
||||
---@field set_string fun(self: self, conf_path: string, s: string): boolean
|
||||
---@field get_item fun(self: self, conf_path: string): ConfigItem|nil
|
||||
---@field set_item fun(self: self, conf_path: string, item: ConfigItem): boolean
|
||||
---@field get_value fun(self: self, conf_path: string): ConfigValue|nil
|
||||
---@field set_value fun(self: self, conf_path: string, value: ConfigValue): boolean
|
||||
---@field get_list fun(self: self, conf_path: string): ConfigList|nil
|
||||
---@field set_list fun(self: self, conf_path: string, list: ConfigList): boolean
|
||||
---@field get_map fun(self: self, conf_path: string): ConfigMap|nil
|
||||
---@field set_map fun(self: self, conf_path: string, map: ConfigMap): boolean
|
||||
---@field get_list_size fun(self: self, conf_path: string): integer|nil
|
||||
|
||||
---@class ConfigMap
|
||||
---@field type ConfigType
|
||||
---@field size integer
|
||||
---@field element ConfigItem
|
||||
---@field empty fun(self: self): boolean
|
||||
---@field has_key fun(self: self, key: string): boolean
|
||||
---@field keys fun(self: self): string[]
|
||||
---@field get fun(self: self, key: string): ConfigItem|nil
|
||||
---@field get_value fun(self: self, key: string): ConfigValue|nil
|
||||
---@field set fun(self: self, key: string, item: ConfigItem)
|
||||
---@field clear fun(self: self)
|
||||
|
||||
---@return ConfigMap
|
||||
function ConfigMap() end
|
||||
|
||||
---@class ConfigList
|
||||
---@field type ConfigType
|
||||
---@field size integer
|
||||
---@field element ConfigItem
|
||||
---@field get_at fun(self: self, index: integer): ConfigItem|nil
|
||||
---@field get_value_at fun(self: self, index: integer): ConfigValue|nil
|
||||
---@field set_at fun(self: self, index: integer, item: ConfigItem): boolean
|
||||
---@field append fun(self: self, item: ConfigItem): boolean
|
||||
---@field insert fun(self: self, i: integer, item: ConfigItem): boolean
|
||||
---@field clear fun(self: self): boolean
|
||||
---@field empty fun(self: self): boolean
|
||||
---@field resize fun(self: self, size: integer): boolean
|
||||
|
||||
---@return ConfigList
|
||||
function ConfigList() end
|
||||
|
||||
---@class ConfigValue
|
||||
---@field type ConfigType
|
||||
---@field value string
|
||||
---@field element ConfigItem
|
||||
---@field get_bool fun(self: self): boolean|nil
|
||||
---@field get_int fun(self: self): integer|nil
|
||||
---@field get_double fun(self: self): number|nil
|
||||
---@field get_string fun(self: self): string|nil
|
||||
---@field set_bool fun(self: self, b: boolean)
|
||||
---@field set_int fun(self: self, i: integer)
|
||||
---@field set_double fun(self: self, f: number)
|
||||
---@field set_string fun(self: self, s: string)
|
||||
|
||||
---@param value string | boolean
|
||||
---@return ConfigValue
|
||||
function ConfigValue(value) end
|
||||
|
||||
---@class ConfigItem
|
||||
---@field type ConfigType
|
||||
---@field empty boolean
|
||||
---@field get_value fun(self: self): ConfigValue|nil
|
||||
---@field get_map fun(self: self): ConfigMap|nil
|
||||
---@field get_list fun(self: self): ConfigList|nil
|
||||
---@field get_obj fun(self: self): ConfigMap|ConfigList|ConfigValue|nil
|
||||
|
||||
---@class KeyEvent
|
||||
---@field keycode integer
|
||||
---@field modifier integer
|
||||
---@field shift fun(self: self): boolean
|
||||
---@field ctrl fun(self: self): boolean
|
||||
---@field alt fun(self: self): boolean
|
||||
---@field caps fun(self: self): boolean
|
||||
---@field super fun(self: self): boolean
|
||||
---@field release fun(self: self): boolean
|
||||
---@field repr fun(self: self): string
|
||||
---@field eq fun(self: self, key: KeyEvent): boolean
|
||||
---@field lt fun(self: self, key: KeyEvent): boolean
|
||||
|
||||
---@param repr string
|
||||
---@return KeyEvent
|
||||
function KeyEvent(repr) end
|
||||
|
||||
---@param keycode integer
|
||||
---@param modifier integer
|
||||
---@return KeyEvent
|
||||
function KeyEvent(keycode, modifier) end
|
||||
|
||||
---@class KeySequence
|
||||
---@field parse fun(self: self, repr: string): boolean
|
||||
---@field repr fun(self: self): string
|
||||
---@field toKeyEvent fun(self: self): KeyEvent[]
|
||||
|
||||
---@param repr string?
|
||||
---@return KeySequence
|
||||
function KeySequence(repr) end
|
||||
|
||||
---@class Candidate
|
||||
---@field type string
|
||||
---@field start integer
|
||||
---@field _start integer
|
||||
---@field _end integer
|
||||
---@field quality number
|
||||
---@field text string
|
||||
---@field comment string
|
||||
---@field preedit string
|
||||
---@field get_dynamic_type fun(self: self): CandidateDynamicType
|
||||
---@field get_genuine fun(self: self): Candidate
|
||||
---@field get_genuines fun(self: self): Candidate[]
|
||||
---@field to_shadow_candidate fun(self: self, type: string?, text: string?, comment: string?, inherit_comment: boolean?): ShadowCandidate
|
||||
---@field to_uniquified_candidate fun(self: self, type: string?, text: string?, comment: string?): UniquifiedCandidate
|
||||
---@field to_phrase fun(self: self): Phrase
|
||||
---@field to_sentence fun(self: self): Sentence
|
||||
---@field append fun(self: self, cand: Candidate)
|
||||
---@field spans fun(self: self): Spans
|
||||
|
||||
---@param type string
|
||||
---@param start integer
|
||||
---@param _end integer
|
||||
---@param text string
|
||||
---@param comment string
|
||||
---@return Candidate
|
||||
function Candidate(type, start, _end, text, comment) end
|
||||
|
||||
---@class UniquifiedCandidate: Candidate
|
||||
|
||||
---@param candidate Candidate
|
||||
---@param type string?
|
||||
---@param text string?
|
||||
---@param comment string?
|
||||
function UniquifiedCandidate(candidate, type, text, comment) end
|
||||
|
||||
---@class ShadowCandidate: Candidate
|
||||
|
||||
---@param candidate Candidate
|
||||
---@param type string?
|
||||
---@param text string?
|
||||
---@param comment string?
|
||||
---@param inherit_comment boolean?
|
||||
---@return ShadowCandidate
|
||||
function ShadowCandidate(candidate, type, text, comment, inherit_comment) end
|
||||
|
||||
---@class Phrase
|
||||
-----@field language Language 暂时不支持
|
||||
---@field lang_name string
|
||||
---@field type string
|
||||
---@field start integer
|
||||
---@field _start integer
|
||||
---@field _end integer
|
||||
---@field quality number
|
||||
---@field text string
|
||||
---@field comment string
|
||||
---@field preedit string
|
||||
---@field weight number
|
||||
---@field code Code
|
||||
---@field entry DictEntry
|
||||
---@field toCandidate fun(self: self): Candidate
|
||||
---@field spans fun(self: self): Spans
|
||||
|
||||
---@param memory Memory
|
||||
---@param type string
|
||||
---@param start integer
|
||||
---@param _end integer
|
||||
---@param entry DictEntry
|
||||
---@return Phrase
|
||||
function Phrase(memory, type, start, _end, entry) end
|
||||
|
||||
---@class Sentence
|
||||
-----@field language Language 暂时不支持
|
||||
---@field lang_name string
|
||||
---@field type string
|
||||
---@field start integer
|
||||
---@field _start integer
|
||||
---@field _end integer
|
||||
---@field quality number
|
||||
---@field text string
|
||||
---@field comment string
|
||||
---@field preedit string
|
||||
---@field weight number
|
||||
---@field code Code
|
||||
---@field entry DictEntry
|
||||
---@field word_lengths integer[]
|
||||
---@field entrys DictEntry[]
|
||||
---@field entrys_size integer
|
||||
---@field entrys_empty boolean
|
||||
---@field toCandidate fun(self: self): Candidate
|
||||
|
||||
---@class Menu
|
||||
---@field add_translation fun(self: self, translation: Translation)
|
||||
---@field prepare fun(self: self, candidate_count: integer): integer
|
||||
---@field get_candidate_at fun(self: self, i: integer): Candidate|nil
|
||||
---@field candidate_count fun(self: self): integer
|
||||
---@field empty fun(self: self): boolean
|
||||
|
||||
---@return Menu
|
||||
function Menu() end
|
||||
|
||||
---@class Opencc
|
||||
---@field convert fun(self: self, text: string): string
|
||||
---@field convert_text fun(self: self, text: string): string
|
||||
---@field random_convert_text fun(self: self, text: string): string
|
||||
---@field convert_word fun(self: self, text: string): string[]
|
||||
|
||||
---@param filename string
|
||||
---@return Opencc
|
||||
function Opencc(filename) end
|
||||
|
||||
---@class Dictionary
|
||||
---@field name string
|
||||
---@field loaded boolean
|
||||
---@field lookup_words fun(self: self, code: string, predictive: boolean, limit: integer): boolean
|
||||
---@field decode fun(self: self, code: Code): string[]
|
||||
|
||||
---@class DictEntryIterator
|
||||
---@field exhausted boolean
|
||||
---@field size integer
|
||||
---@field iter fun(self: self): fun(): DictEntry|nil
|
||||
|
||||
---@class UserDictionary
|
||||
---@field name string
|
||||
---@field loaded boolean
|
||||
---@field tick integer
|
||||
---@field lookup_words fun(self: self, code: string, predictive: boolean, limit: integer): boolean
|
||||
---@field update_entry fun(self: self, entry: DictEntry, commits: integer, prefix: string, lang_name: string): boolean
|
||||
|
||||
---@class UserDictEntryIterator
|
||||
---@field exhausted boolean
|
||||
---@field size integer
|
||||
---@field iter fun(self: self): fun(): DictEntry|nil
|
||||
|
||||
---@class ReverseDb
|
||||
---@field lookup fun(self: self, key: string): string
|
||||
|
||||
---@param file_name string
|
||||
---@return ReverseDb
|
||||
function ReverseDb(file_name) end
|
||||
|
||||
---@class ReverseLookup
|
||||
---@field lookup fun(self: self, key: string): string
|
||||
---@field lookup_stems fun(self: self, key: string): string
|
||||
|
||||
---@param dict_name string
|
||||
---@return ReverseLookup
|
||||
function ReverseLookup(dict_name) end
|
||||
|
||||
---@class DictEntry
|
||||
---@field text string
|
||||
---@field comment string
|
||||
---@field preedit string
|
||||
---@field weight number
|
||||
---@field commit_count integer `2`
|
||||
---@field custom_code string "hao", "ni hao"
|
||||
---@field remaining_code_length integer "~ao"
|
||||
---@field code Code
|
||||
|
||||
---@return DictEntry
|
||||
function DictEntry() end
|
||||
|
||||
---@class CommitEntry: DictEntry
|
||||
---@field get fun(self: self): DictEntry[]
|
||||
---@field update_entry fun(self: self, entry: DictEntry, commit: integer, prefix: string): boolean
|
||||
---@field update fun(self: self, commit: integer): boolean
|
||||
|
||||
---@class Code
|
||||
---@field push fun(self: self, syllable_id: integer)
|
||||
---@field print fun(self: self): string
|
||||
|
||||
---@return Code
|
||||
function Code() end
|
||||
|
||||
---@class Translation
|
||||
---@field exhausted boolean
|
||||
---@field iter fun(self: self): fun(): Candidate|nil
|
||||
|
||||
function Translation() end
|
||||
|
||||
---@class Memory
|
||||
---@field lang_name string
|
||||
---@field dict Dictionary
|
||||
---@field user_dict UserDictionary
|
||||
---@field start_session fun(self: self): boolean
|
||||
---@field finish_session fun(self: self): boolean
|
||||
---@field discard_session fun(self: self): boolean
|
||||
---@field dict_lookup fun(self: self, input: string, predictive: boolean, limit: integer): boolean
|
||||
---@field user_lookup fun(self: self, input: string, predictive: boolean): boolean
|
||||
---@field dictiter_lookup fun(self: self, input: string, predictive: boolean, limit: integer): DictEntryIterator
|
||||
---@field useriter_lookup fun(self: self, input: string, predictive: boolean): UserDictEntryIterator
|
||||
---@field memorize fun(self: self, callback: fun(ce: CommitEntry))
|
||||
---@field decode fun(self: self, code: Code): string[]
|
||||
---@field iter_dict fun(self: self): fun(): DictEntry|nil
|
||||
---@field iter_user fun(self: self): fun(): DictEntry|nil
|
||||
---@field update_userdict fun(self: self, entry: DictEntry, commits: integer, prefix: string): boolean
|
||||
---@field update_entry fun(self: self, entry: DictEntry, commits: integer, prefix: string, lang_name?: string): boolean
|
||||
---@field update_candidate fun(self: self, candidate: Candidate, commits: integer): boolean
|
||||
---@field disconnect fun(self: self)
|
||||
|
||||
---@param engine Engine
|
||||
---@param schema Schema
|
||||
---@param namespace string?
|
||||
---@return Memory
|
||||
function Memory(engine, schema, namespace) end
|
||||
|
||||
---@class Projection
|
||||
---@field load fun(self: self, rules: ConfigList): boolean
|
||||
---@field apply fun(self: self, str: string, ret_org_str?: boolean): string
|
||||
|
||||
---@return Projection
|
||||
function Projection() end
|
||||
|
||||
---@class Component
|
||||
---@field Processor fun(engine: Engine, namespace: string, klass: string): Processor
|
||||
---@field Translator fun(engine: Engine, namespace: string, klass: string): Translator
|
||||
---@field Segmentor fun(engine: Engine, namespace: string, klass: string): Segmentor
|
||||
---@field Filter fun(engine: Engine, namespace: string, klass: string): Filter
|
||||
---@field ScriptTranslator fun(engine: Engine, namespace: string, klass: string): ScriptTranslator
|
||||
---@field TableTranslator fun(engine: Engine, namespace: string, klass: string): TableTranslator
|
||||
Component = {}
|
||||
|
||||
---@class Processor
|
||||
---@field name_space string
|
||||
---@field process_key_event fun(self: self, key_event: KeyEvent): ProcessResult
|
||||
|
||||
---@class Segmentor
|
||||
---@field name_space string
|
||||
---@field proceed fun(self: self, segmentation: Segmentation): boolean
|
||||
|
||||
---@class Translator
|
||||
---@field name_space string
|
||||
---@field query fun(self: self, input: string, segment: Segment): Translation
|
||||
|
||||
---@class ScriptTranslator
|
||||
---@field name_space string
|
||||
---@field lang_name string
|
||||
---@field memorize_callback fun(ce: CommitEntry)
|
||||
---@field max_homophones integer
|
||||
---@field spelling_hints integer
|
||||
---@field always_show_comments boolean
|
||||
---@field enable_correction boolean
|
||||
---@field delimiters string
|
||||
---@field tag string
|
||||
---@field enable_completion boolean
|
||||
---@field contextual_suggestions boolean
|
||||
---@field strict_spelling boolean
|
||||
---@field initial_quality number
|
||||
---@field preedit_formatter Projection
|
||||
---@field comment_formatter Projection
|
||||
---@field dict Dictionary
|
||||
---@field user_dict UserDictionary
|
||||
---@field translator Translator
|
||||
---@field query fun(self: self, input: string, segment: Segment): Translation
|
||||
---@field start_session fun(self: self): boolean
|
||||
---@field finish_session fun(self: self): boolean
|
||||
---@field discard_session fun(self: self): boolean
|
||||
---@field memorize fun(self: self, callback: fun(ce: CommitEntry))
|
||||
---@field update_entry fun(self: self, entry: DictEntry, commits: integer, prefix: string): boolean
|
||||
---@field reload_user_dict_disabling_patterns fun(self: self, config_list: ConfigList): boolean
|
||||
---@field set_memorize_callback fun(self: self, callback: fun(ce: CommitEntry))
|
||||
---@field disconnect fun(self: self)
|
||||
|
||||
---@class TableTranslator
|
||||
---@field name_space string
|
||||
---@field lang_name string
|
||||
---@field memorize_callback fun(ce: CommitEntry)
|
||||
---@field enable_charset_filter boolean
|
||||
---@field enable_encoder boolean
|
||||
---@field enable_sentence boolean
|
||||
---@field sentence_over_completion boolean
|
||||
---@field encode_commit_history boolean
|
||||
---@field max_phrase_length integer
|
||||
---@field max_homographs integer
|
||||
---@field delimiters string
|
||||
---@field tag string
|
||||
---@field enable_completion boolean
|
||||
---@field contextual_suggestions boolean
|
||||
---@field strict_spelling boolean
|
||||
---@field initial_quality number
|
||||
---@field preedit_formatter Projection
|
||||
---@field comment_formatter Projection
|
||||
---@field dict Dictionary
|
||||
---@field user_dict UserDictionary
|
||||
---@field translator Translator
|
||||
---@field query fun(self: self, input: string, segment: Segment): Translation
|
||||
---@field start_session fun(self: self): boolean
|
||||
---@field finish_session fun(self: self): boolean
|
||||
---@field discard_session fun(self: self): boolean
|
||||
---@field memorize fun(self: self, callback: fun(ce: CommitEntry))
|
||||
---@field update_entry fun(self: self, entry: DictEntry, commits: integer, prefix: string): boolean
|
||||
---@field reload_user_dict_disabling_patterns fun(self: self, config_list: ConfigList): boolean
|
||||
---@field set_memorize_callback fun(self: self, callback: fun(ce: CommitEntry))
|
||||
---@field disconnect fun(self: self)
|
||||
|
||||
---@class Filter
|
||||
---@field name_space string
|
||||
---@field apply fun(self: self, translation: Translation): Translation
|
||||
|
||||
---@class Notifier
|
||||
---@field connect fun(self: self, f: fun(ctx: Context), group: integer|nil): Connection
|
||||
|
||||
---@class OptionUpdateNotifier: Notifier
|
||||
---@field connect fun(self: self, f: fun(ctx: Context, name: string), group:integer|nil): function[]
|
||||
|
||||
---@class PropertyUpdateNotifier: Notifier
|
||||
---@field connect fun(self: self, f: fun(ctx: Context, name: string), group:integer|nil): function[]
|
||||
|
||||
---@class KeyEventNotifier: Notifier
|
||||
---@field connect fun(self: self, f: fun(ctx: Context, key: string), group:integer|nil): function[]
|
||||
|
||||
---@class Connection
|
||||
---@field disconnect fun(self: self)
|
||||
|
||||
---@class Switcher
|
||||
---@field attached_engine Engine
|
||||
---@field user_config Config
|
||||
---@field active boolean
|
||||
---@field process_key fun(self: self, key_event: KeyEvent): boolean
|
||||
---@field select_next_schema fun(self: self)
|
||||
---@field is_auto_save fun(self: self, option: string): boolean
|
||||
---@field refresh_menu fun(self: self)
|
||||
---@field activate fun(self: self)
|
||||
---@field deactivate fun(self: self)
|
||||
|
||||
---@param engine Engine
|
||||
---@return Switcher
|
||||
function Switcher(engine) end
|
||||
|
||||
---@class CommitRecord
|
||||
---@field text string
|
||||
---@field type string
|
||||
|
||||
---@class CommitHistory
|
||||
---@field size integer
|
||||
---@field push fun(self: self, key_event: KeyEvent)
|
||||
---@field back fun(self: self): CommitRecord|nil
|
||||
---@field to_table fun(self: self): CommitRecord[]
|
||||
---@field iter fun(self: self): fun(): (number, CommitRecord)|nil
|
||||
---@field latest_text fun(self: self): string
|
||||
---@field empty fun(self: self): boolean
|
||||
---@field clear fun(self: self)
|
||||
---@field pop_back fun(self: self)
|
||||
|
||||
---@class DbAccessor
|
||||
---@field reset fun(self: self): boolean
|
||||
---@field jump fun(self: self, prefix: string): boolean
|
||||
---@field iter fun(self: self): fun(): (string, string) | nil
|
||||
|
||||
---@class UserDb
|
||||
---@field _loaded boolean
|
||||
---@field read_only boolean
|
||||
---@field disabled boolean
|
||||
---@field name string
|
||||
---@field file_name string
|
||||
---@field open fun(self: self): boolean
|
||||
---@field open_read_only fun(self: self): boolean
|
||||
---@field close fun(self: self): boolean
|
||||
---@field query fun(self: self, prefix: string): DbAccessor
|
||||
---@field fetch fun(self: self, key: string): string|nil
|
||||
---@field update fun(self: self, key: string, value: string): boolean
|
||||
---@field erase fun(self: self, key: string): boolean
|
||||
---@field loaded fun(self: self): boolean
|
||||
---@field disable fun(self: self): boolean
|
||||
---@field enable fun(self: self): boolean
|
||||
|
||||
---@param db_name string
|
||||
---@param db_class string
|
||||
---@return UserDb
|
||||
function UserDb(db_name, db_class) end
|
||||
|
||||
---@class LevelDb: UserDb
|
||||
|
||||
---@param db_name string
|
||||
---@return LevelDb
|
||||
function LevelDb(db_name) end
|
||||
|
||||
---@class TableDb: UserDb
|
||||
|
||||
---@param db_name string
|
||||
---@return TableDb
|
||||
function TableDb(db_name) end
|
||||
61
lua/limit_repeated.lua
Normal file
61
lua/limit_repeated.lua
Normal file
@@ -0,0 +1,61 @@
|
||||
-- 用于限制最大候选数量以及重复最大输入编码,防止卡顿性能异常
|
||||
--@amzxyz
|
||||
--https://github.com/amzxyz
|
||||
local M = {}
|
||||
local ACCEPT, PASS = 1, 2
|
||||
|
||||
local MAX_REPEAT = 8 -- 连续重复输入声母上限
|
||||
local MAX_SEGMENTS = 40 -- 允许的最大“分段”数
|
||||
local INITIALS = "[bpmfdtnlgkhjqxrzcsywiu]"
|
||||
|
||||
-- 计算末尾重复
|
||||
local function tail_rep(s)
|
||||
local last, n = s:sub(-1), 1
|
||||
for i = #s - 1, 1, -1 do
|
||||
if s:sub(i, i) == last then n = n + 1 else break end
|
||||
end
|
||||
return last, n
|
||||
end
|
||||
|
||||
-- 在候选栏最后一个 segment 加提示
|
||||
local function prompt(ctx, msg)
|
||||
local comp = ctx.composition
|
||||
if comp and not comp:empty() then comp:back().prompt = msg end
|
||||
end
|
||||
|
||||
function M.func(key, env)
|
||||
local ctx, kc = env.engine.context, key.keycode
|
||||
-- 先拿到“上一轮”高亮候选的 preedit 及段数
|
||||
local cand = ctx:get_selected_candidate()
|
||||
local preedit = cand and (cand.preedit or cand:get_genuine().preedit) or ""
|
||||
local segs = 1
|
||||
for _ in preedit:gmatch("[%'%s]") do segs = segs + 1 end
|
||||
-- 本次按键字符(只关心字母 / 分隔符)
|
||||
local ch
|
||||
if kc >= 0x61 and kc <= 0x7A then -- a~z
|
||||
ch = string.char(kc)
|
||||
elseif kc == 0x27 then -- '
|
||||
ch = "'"
|
||||
elseif kc == 0x20 then -- space
|
||||
ch = " "
|
||||
end
|
||||
-- ① 连续声母限制:第 MAX_REPEAT 个同声母直接拦截
|
||||
if ch and kc >= 0x61 and kc <= 0x7A then
|
||||
local nxt = ctx.input .. ch
|
||||
local last, rep_n = tail_rep(nxt)
|
||||
if last:match(INITIALS) and rep_n > MAX_REPEAT then
|
||||
prompt(ctx, " 〔已超最大重复声母〕")
|
||||
return ACCEPT
|
||||
end
|
||||
end
|
||||
-- ② 分段限制:第 MAX_SEGMENTS 段拦截
|
||||
local segs_after = segs
|
||||
if ch == "'" or ch == " " then segs_after = segs + 1 end
|
||||
if segs_after >= MAX_SEGMENTS and kc >= 0x61 and kc <= 0x7A then
|
||||
prompt(ctx, " 〔已超最大输入长度〕")
|
||||
return ACCEPT
|
||||
end
|
||||
return PASS
|
||||
end
|
||||
|
||||
return M
|
||||
175
lua/number_translator.lua
Normal file
175
lua/number_translator.lua
Normal file
@@ -0,0 +1,175 @@
|
||||
-- 来源 https://github.com/yanhuacuo/98wubi-tables > http://98wb.ysepan.com/
|
||||
-- 数字、金额大写
|
||||
-- 触发前缀默认为 recognizer/patterns/number 的第 2 个字符,即 R
|
||||
|
||||
local function splitNumPart(str)
|
||||
local part = {}
|
||||
part.int, part.dot, part.dec = string.match(str, "^(%d*)(%.?)(%d*)")
|
||||
return part
|
||||
end
|
||||
|
||||
local function GetPreciseDecimal(nNum, n)
|
||||
if type(nNum) ~= "number" then nNum = tonumber(nNum) end
|
||||
n = n or 0;
|
||||
n = math.floor(n)
|
||||
if n < 0 then n = 0 end
|
||||
local nDecimal = 10 ^ n
|
||||
local nTemp = math.floor(nNum * nDecimal);
|
||||
local nRet = nTemp / nDecimal;
|
||||
return nRet;
|
||||
end
|
||||
|
||||
local function decimal_func(str, posMap, valMap)
|
||||
local dec
|
||||
posMap = posMap or { [1] = "角", [2] = "分", [3] = "厘", [4] = "毫" }
|
||||
valMap = valMap or { [0] = "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }
|
||||
if #str > 4 then dec = string.sub(tostring(str), 1, 4) else dec = tostring(str) end
|
||||
dec = string.gsub(dec, "0+$", "")
|
||||
|
||||
if dec == "" then return "整" end
|
||||
|
||||
local result = ""
|
||||
for pos = 1, #dec do
|
||||
local val = tonumber(string.sub(dec, pos, pos))
|
||||
if val ~= 0 then result = result .. valMap[val] .. posMap[pos] else result = result .. valMap[val] end
|
||||
end
|
||||
result = result:gsub(valMap[0] .. valMap[0], valMap[0])
|
||||
return result:gsub(valMap[0] .. valMap[0], valMap[0])
|
||||
end
|
||||
|
||||
-- 把数字串按千分位四位数分割,进行转换为中文
|
||||
local function formatNum(num, t)
|
||||
local digitUnit, wordFigure
|
||||
local result = ""
|
||||
num = tostring(num)
|
||||
if tonumber(t) < 1 then digitUnit = { "", "十", "百", "千" } else digitUnit = { "", "拾", "佰", "仟" } end
|
||||
if tonumber(t) < 1 then
|
||||
wordFigure = { "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九" }
|
||||
else
|
||||
wordFigure = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }
|
||||
end
|
||||
if string.len(num) > 4 or tonumber(num) == 0 then return wordFigure[1] end
|
||||
local lens = string.len(num)
|
||||
for i = 1, lens do
|
||||
local n = wordFigure[tonumber(string.sub(num, -i, -i)) + 1]
|
||||
if n ~= wordFigure[1] then result = n .. digitUnit[i] .. result else result = n .. result end
|
||||
end
|
||||
result = result:gsub(wordFigure[1] .. wordFigure[1], wordFigure[1])
|
||||
result = result:gsub(wordFigure[1] .. "$", "")
|
||||
result = result:gsub(wordFigure[1] .. "$", "")
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
-- 数值转换为中文
|
||||
local function number2cnChar(num, flag, digitUnit, wordFigure) --flag=0中文小写反之为大写
|
||||
local result = ""
|
||||
|
||||
if tonumber(flag) < 1 then
|
||||
digitUnit = digitUnit or { [1] = "万", [2] = "亿" }
|
||||
wordFigure = wordFigure or { [1] = "〇", [2] = "一", [3] = "十", [4] = "元" }
|
||||
else
|
||||
digitUnit = digitUnit or { [1] = "万", [2] = "亿" }
|
||||
wordFigure = wordFigure or { [1] = "零", [2] = "壹", [3] = "拾", [4] = "元" }
|
||||
end
|
||||
local lens = string.len(num)
|
||||
if lens < 5 then
|
||||
result = formatNum(num, flag)
|
||||
elseif lens < 9 then
|
||||
result = formatNum(string.sub(num, 1, -5), flag) .. digitUnit[1] .. formatNum(string.sub(num, -4, -1), flag)
|
||||
elseif lens < 13 then
|
||||
result = formatNum(string.sub(num, 1, -9), flag) ..
|
||||
digitUnit[2] ..
|
||||
formatNum(string.sub(num, -8, -5), flag) .. digitUnit[1] .. formatNum(string.sub(num, -4, -1), flag)
|
||||
else
|
||||
result = ""
|
||||
end
|
||||
|
||||
result = result:gsub("^" .. wordFigure[1], "")
|
||||
result = result:gsub(wordFigure[1] .. digitUnit[1], "")
|
||||
result = result:gsub(wordFigure[1] .. digitUnit[2], "")
|
||||
result = result:gsub(wordFigure[1] .. wordFigure[1], wordFigure[1])
|
||||
result = result:gsub(wordFigure[1] .. "$", "")
|
||||
if lens > 4 then result = result:gsub("^" .. wordFigure[2] .. wordFigure[3], wordFigure[3]) end
|
||||
if result ~= "" then result = result .. wordFigure[4] else result = "数值超限!" end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
local function number2zh(num, t)
|
||||
local result, wordFigure
|
||||
result = ""
|
||||
if tonumber(t) < 1 then
|
||||
wordFigure = { "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九" }
|
||||
else
|
||||
wordFigure = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }
|
||||
end
|
||||
if tostring(num) == nil then return "" end
|
||||
for pos = 1, string.len(num) do
|
||||
result = result .. wordFigure[tonumber(string.sub(num, pos, pos) + 1)]
|
||||
end
|
||||
result = result:gsub(wordFigure[1] .. wordFigure[1], wordFigure[1])
|
||||
return result:gsub(wordFigure[1] .. wordFigure[1], wordFigure[1])
|
||||
end
|
||||
|
||||
local function number_translatorFunc(num)
|
||||
local numberPart = splitNumPart(num)
|
||||
local result = {}
|
||||
if numberPart.dot ~= "" then
|
||||
table.insert(result,
|
||||
{ number2cnChar(numberPart.int, 0, { "万", "亿" }, { "〇", "一", "十", "点" }) .. number2zh(numberPart.dec, 0),
|
||||
"" })
|
||||
-- table.insert(result,
|
||||
-- { number2cnChar(numberPart.int, 1, { "萬", "億" }, { "〇", "一", "十", "点" }) .. number2zh(numberPart.dec, 1),
|
||||
-- "〔数字大写〕" })
|
||||
local upperRaw = number2cnChar(numberPart.int, 1, { "萬", "億" }, { "〇", "一", "十", "点" })
|
||||
local upper = upperRaw:gsub("^拾", "壹拾") .. number2zh(numberPart.dec, 1)
|
||||
table.insert(result, { upper, "" })
|
||||
else
|
||||
table.insert(result, { number2cnChar(numberPart.int, 0, { "万", "亿" }, { "〇", "一", "十", "" }), "" })
|
||||
table.insert(result,
|
||||
{ number2cnChar(numberPart.int, 1, { "萬", "億" }, { "零", "壹", "拾", "" }):gsub("^拾", "壹拾"), "" })
|
||||
end
|
||||
table.insert(result,
|
||||
{ number2cnChar(numberPart.int, 0) ..
|
||||
decimal_func(numberPart.dec, { [1] = "角", [2] = "分", [3] = "厘", [4] = "毫" },
|
||||
{ [0] = "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九" }), "" })
|
||||
|
||||
local number2cnCharInt = number2cnChar(numberPart.int, 1)
|
||||
local number2cnCharDec = decimal_func(numberPart.dec, { [1] = "角", [2] = "分", [3] = "厘", [4] = "毫" },
|
||||
{ [0] = "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" })
|
||||
if string.len(numberPart.int) > 4 and number2cnCharInt:find('^拾[壹贰叁肆伍陆柒捌玖]?') and number2cnCharInt:find('[万亿]') then -- 简易地规避 utf8 匹配问题
|
||||
local number2cnCharInt_var = number2cnCharInt:gsub('^拾', '壹拾')
|
||||
table.insert(result, { number2cnCharInt_var .. number2cnCharDec, "" })
|
||||
-- 会计书写要求 https://github.com/iDvel/rime-ice/issues/989
|
||||
else
|
||||
table.insert(result, { number2cnCharInt .. number2cnCharDec, "" })
|
||||
end
|
||||
local result = { result[1], result[4], result[2], result[3] }
|
||||
return result
|
||||
end
|
||||
|
||||
local function number_translator(input, seg, env)
|
||||
-- 获取 recognizer/patterns/number 的第 2 个字符作为触发前缀
|
||||
env.number_keyword = env.number_keyword or
|
||||
env.engine.schema.config:get_string('recognizer/patterns/number'):sub(2, 2)
|
||||
local str, num, numberPart
|
||||
if env.number_keyword ~= '' and input:sub(1, 1) == env.number_keyword then
|
||||
local context = env.engine.context
|
||||
local segment = context.composition:back()
|
||||
-- 设置手动排序的排序编码以支持 N 指令的手动排序
|
||||
context:set_property("sequence_adjustment_code", env.number_keyword)
|
||||
str = string.gsub(input, "^(%a+)", "")
|
||||
numberPart = number_translatorFunc(str)
|
||||
if str and #str > 0 and #numberPart > 0 then
|
||||
-- 设置标签
|
||||
segment.tags = segment.tags + Set({ "number" })
|
||||
for i = 1, #numberPart do
|
||||
yield(Candidate(input, seg.start, seg._end, numberPart[i][1], numberPart[i][2]))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- print(#number_translatorFunc(3355.433))
|
||||
return number_translator
|
||||
191
lua/partial_commit.lua
Normal file
191
lua/partial_commit.lua
Normal file
@@ -0,0 +1,191 @@
|
||||
-- @amzxyz https://github.com/amzxyz/rime_wanxiang
|
||||
-- Ctrl+1..9,0:上屏首选前 N 字;按 preedit/script_text 的前 N 音节对齐 raw input
|
||||
local wanxiang = require("wanxiang")
|
||||
|
||||
local M = {}
|
||||
|
||||
-- 数字键映射(主键盘 + 小键盘)
|
||||
local DIGIT = { [0x31]=1,[0x32]=2,[0x33]=3,[0x34]=4,[0x35]=5,[0x36]=6,[0x37]=7,[0x38]=8,[0x39]=9,[0x30]=10 }
|
||||
local KP = { [0xFFB1]=1,[0xFFB2]=2,[0xFFB3]=3,[0xFFB4]=4,[0xFFB5]=5,[0xFFB6]=6,[0xFFB7]=7,[0xFFB8]=8,[0xFFB9]=9,[0xFFB0]=10 }
|
||||
|
||||
-- 工具:字符串缩略 / 获取分隔符 / 安全转义 / 清洗 raw
|
||||
local function short(s)
|
||||
if not s then return "" end
|
||||
if #s > 120 then
|
||||
return s:sub(1, 117) .. "..."
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local function get_delimiters(ctx)
|
||||
local cfg = ctx.engine and ctx.engine.schema and ctx.engine.schema.config
|
||||
local delimiter = (cfg and cfg:get_string("speller/delimiter")) or " '"
|
||||
return delimiter:sub(1, 1), delimiter:sub(2, 2) -- auto, manual
|
||||
end
|
||||
|
||||
-- 放进字符类 [...] 使用的转义(只转义 % ^ ] -)
|
||||
local function esc_class(c)
|
||||
if not c or c == "" then return "" end
|
||||
return (c:gsub("([%%%^%]%-])", "%%%1"))
|
||||
end
|
||||
|
||||
-- 普通模式串位置的单字符转义(最小化:仅非字母数字下划线时转义)
|
||||
local function esc_pat(c)
|
||||
if not c or c == "" then return "" end
|
||||
if c:match("[%w_]") then return c end
|
||||
return (c:gsub("(%W)", "%%%1"))
|
||||
end
|
||||
|
||||
-- 清洗整串 raw:去掉手动分隔符(如 "'")
|
||||
local function clean_raw(ctx, raw)
|
||||
if not raw or raw == "" then return "" end
|
||||
local _, manual = get_delimiters(ctx)
|
||||
if manual and #manual == 1 then
|
||||
raw = raw:gsub(esc_pat(manual), "")
|
||||
end
|
||||
return raw
|
||||
end
|
||||
|
||||
-- 取候选前 n 个字符
|
||||
local function utf8_head(s, n)
|
||||
local i, c = 1, 0
|
||||
while i <= #s and c < n do
|
||||
local b = s:byte(i)
|
||||
i = i + ((b < 0x80) and 1 or ((b < 0xE0) and 2 or ((b < 0xF0) and 3 or 4)))
|
||||
c = c + 1
|
||||
end
|
||||
return s:sub(1, i - 1)
|
||||
end
|
||||
-- 生成 target:按分隔符切 preedit/script_text,取前 n 个并去分隔符拼接
|
||||
local function script_prefix(ctx, n)
|
||||
local raw_in = ctx.input or ""
|
||||
local prop_key = ctx:get_property("sequence_preedit_key") or ""
|
||||
local prop_val = ctx:get_property("sequence_preedit_val") or ""
|
||||
local script_txt = ctx:get_script_text() or ""
|
||||
|
||||
local s
|
||||
if prop_key == raw_in and prop_val ~= "" then
|
||||
s = prop_val
|
||||
else
|
||||
s = script_txt
|
||||
end
|
||||
if s == "" then return "" end
|
||||
|
||||
local auto, manual = get_delimiters(ctx)
|
||||
local pat = "[^" .. esc_class(auto) .. esc_class(manual) .. "%s]+"
|
||||
|
||||
local parts = {}
|
||||
for w in s:gmatch(pat) do parts[#parts + 1] = w end
|
||||
if #parts == 0 then return "" end
|
||||
|
||||
local upto = math.min(n, #parts)
|
||||
local target = table.concat({ table.unpack(parts, 1, upto) }, "")
|
||||
return target
|
||||
end
|
||||
-- 对齐“去分隔符后的 raw_clean”与 target;返回消耗长度(基于 raw_clean)
|
||||
local function eat_len_by_target(ctx, target)
|
||||
if target == "" then return 0 end
|
||||
local raw = ctx.input or ""
|
||||
if raw == "" then return 0 end
|
||||
|
||||
local clean = clean_raw(ctx, raw)
|
||||
local i, j, Lc, Lt = 1, 1, #clean, #target
|
||||
while i <= Lc and j <= Lt do
|
||||
if clean:sub(i, i) ~= target:sub(j, j) then
|
||||
return 0
|
||||
end
|
||||
i, j = i + 1, j + 1
|
||||
end
|
||||
if j <= Lt then return 0 end
|
||||
return i - 1
|
||||
end
|
||||
|
||||
local function set_pending(env, rest)
|
||||
env._cpc_pending_rest = rest or ""
|
||||
end
|
||||
local function has_pending(env)
|
||||
return type(env._cpc_pending_rest) == "string" and env._cpc_pending_rest ~= nil
|
||||
end
|
||||
local function take_pending(env)
|
||||
local r = env._cpc_pending_rest
|
||||
env._cpc_pending_rest = nil
|
||||
return r
|
||||
end
|
||||
|
||||
function M.init(env)
|
||||
local ctx = env.engine.context
|
||||
|
||||
env._cpc_update_conn = ctx.update_notifier:connect(function(c)
|
||||
if not has_pending(env) then return end
|
||||
local rest = take_pending(env) or ""
|
||||
|
||||
c.input = rest
|
||||
if c.clear_non_confirmed_composition then
|
||||
c:clear_non_confirmed_composition()
|
||||
end
|
||||
if c.caret_pos ~= nil then
|
||||
c.caret_pos = #rest
|
||||
end
|
||||
end)
|
||||
|
||||
env._cpc_key_handler = function(key)
|
||||
|
||||
if not key:ctrl() or key:release() then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
local n = DIGIT[key.keycode] or KP[key.keycode]
|
||||
if not n then return wanxiang.RIME_PROCESS_RESULTS.kNoop end
|
||||
|
||||
local c = env.engine.context
|
||||
if not c:is_composing() then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
local cand = c:get_selected_candidate() or c:get_candidate(0)
|
||||
if not cand or not cand.text or #cand.text == 0 then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
local head = utf8_head(cand.text, n)
|
||||
if head == "" then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
local target = script_prefix(c, n)
|
||||
if target == "" then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
local consumed = eat_len_by_target(c, target)
|
||||
if consumed == 0 then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
local raw_clean = clean_raw(c, c.input or "")
|
||||
local rest = raw_clean:sub(consumed + 1)
|
||||
|
||||
env.engine:commit_text(head)
|
||||
set_pending(env, rest)
|
||||
c:refresh_non_confirmed_composition()
|
||||
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
end
|
||||
end
|
||||
|
||||
function M.fini(env)
|
||||
if env._cpc_update_conn then
|
||||
env._cpc_update_conn:disconnect()
|
||||
env._cpc_update_conn = nil
|
||||
end
|
||||
env._cpc_key_handler = nil
|
||||
end
|
||||
|
||||
function M.func(key, env)
|
||||
if not env._cpc_key_handler then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
return env._cpc_key_handler(key)
|
||||
end
|
||||
|
||||
return M
|
||||
137
lua/quick_symbol_text.lua
Normal file
137
lua/quick_symbol_text.lua
Normal file
@@ -0,0 +1,137 @@
|
||||
-- 欢迎使用万象拼音方案(quick_symbol_text)
|
||||
-- @amzxyz
|
||||
-- https://github.com/amzxyz/rime_wanxiang
|
||||
-- 触发:由 schema.yaml -> quick_symbol_text/trigger 加载(默认 ^([a-z])/$ )
|
||||
-- a/、b/ ... 单字母触发预设编码自动上屏;值可设为 "repeat" 实现重复上屏上一条提交内容
|
||||
-- custom>schema>lua 合并键值(仅合并单字母 a-z 键)
|
||||
|
||||
local wanxiang = require("wanxiang")
|
||||
|
||||
-- 读取 symkey
|
||||
local function load_mapping_from_config(config)
|
||||
local symbol_map = {}
|
||||
local ok_map, map = pcall(function() return config:get_map("quick_symbol_text/symkey") end)
|
||||
if not ok_map or not map then return symbol_map end
|
||||
local ok_keys, keys = pcall(function() return map:keys() end)
|
||||
if not ok_keys or not keys then return symbol_map end
|
||||
for _, key in ipairs(keys) do
|
||||
local v = config:get_string("quick_symbol_text/symkey/" .. key)
|
||||
if v ~= nil then
|
||||
symbol_map[string.lower(tostring(key))] = v
|
||||
end
|
||||
end
|
||||
return symbol_map
|
||||
end
|
||||
|
||||
-- 读取 trigger
|
||||
local function load_trigger_from_config(config)
|
||||
local default_pat = "^([a-z])/$"
|
||||
if not config then return default_pat end
|
||||
local ok, s = pcall(function() return config:get_string("quick_symbol_text/trigger") end)
|
||||
if ok and type(s) == "string" and #s > 0 then return s end
|
||||
return default_pat
|
||||
end
|
||||
|
||||
-- 默认单字母映射
|
||||
local default_mapping = {
|
||||
q = ":",
|
||||
w = "?",
|
||||
e = "(",
|
||||
r = ")",
|
||||
t = "~",
|
||||
y = "·",
|
||||
u = "『",
|
||||
i = "』",
|
||||
o = "〖",
|
||||
p = "〗",
|
||||
a = "!",
|
||||
s = "……",
|
||||
d = "、",
|
||||
f = "“",
|
||||
g = "”",
|
||||
h = "‘",
|
||||
j = "’",
|
||||
k = "【",
|
||||
l = "】",
|
||||
z = "。",
|
||||
x = "?",
|
||||
c = "!",
|
||||
v = "——",
|
||||
b = "%",
|
||||
n = "《",
|
||||
m = "》",
|
||||
}
|
||||
|
||||
local function init(env)
|
||||
local config = env.engine.schema.config
|
||||
env.single_symbol_pattern = load_trigger_from_config(config)
|
||||
|
||||
-- 默认表
|
||||
env.mapping = {}
|
||||
for k, v in pairs(default_mapping) do
|
||||
if #k == 1 and k:match("^[a-z]$") then env.mapping[k] = v end
|
||||
end
|
||||
-- 覆盖(仅单字母)
|
||||
local custom = load_mapping_from_config(config)
|
||||
for k, v in pairs(custom) do
|
||||
local key = tostring(k):lower()
|
||||
if #key == 1 and key:match("^[a-z]$") then
|
||||
env.mapping[key] = v -- ""=禁用;"repeat"=特殊语义
|
||||
end
|
||||
end
|
||||
|
||||
env.last_commit_text = "欢迎使用万象拼音!"
|
||||
|
||||
-- 记录上屏文本(供 repeat)
|
||||
env.quick_symbol_text_commit_notifier =
|
||||
env.engine.context.commit_notifier:connect(function(ctx)
|
||||
local t = ctx:get_commit_text()
|
||||
if t ~= "" then env.last_commit_text = t end
|
||||
end)
|
||||
|
||||
-- 命中触发则上屏并清空
|
||||
env.quick_symbol_text_update_notifier =
|
||||
env.engine.context.update_notifier:connect(function(context)
|
||||
local input = context.input or ""
|
||||
local key = string.match(input, env.single_symbol_pattern)
|
||||
if not key then return end
|
||||
key = string.lower(key)
|
||||
local symbol = env.mapping[key]
|
||||
if symbol == nil or symbol == "" then return end -- 未配置/禁用
|
||||
if type(symbol) == "string" and symbol:lower() == "repeat" then
|
||||
if env.last_commit_text ~= "" then
|
||||
env.engine:commit_text(env.last_commit_text)
|
||||
context:clear()
|
||||
end
|
||||
else
|
||||
env.engine:commit_text(symbol)
|
||||
context:clear()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function fini(env)
|
||||
if env.quick_symbol_text_commit_notifier then
|
||||
env.quick_symbol_text_commit_notifier:disconnect()
|
||||
env.quick_symbol_text_commit_notifier = nil
|
||||
end
|
||||
if env.quick_symbol_text_update_notifier then
|
||||
env.quick_symbol_text_update_notifier:disconnect()
|
||||
env.quick_symbol_text_update_notifier = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- 命中时吃键,避免后续流程处理
|
||||
local function processor(key_event, env)
|
||||
local input = env.engine.context.input or ""
|
||||
local key = string.match(input, env.single_symbol_pattern)
|
||||
if key then
|
||||
key = string.lower(key)
|
||||
local symbol = env.mapping[key]
|
||||
if symbol ~= nil and symbol ~= "" then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
end
|
||||
end
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
return { init = init, fini = fini, func = processor }
|
||||
41
lua/select_character.lua
Normal file
41
lua/select_character.lua
Normal file
@@ -0,0 +1,41 @@
|
||||
-- 以词定字
|
||||
|
||||
local wanxiang = require("wanxiang")
|
||||
|
||||
local select = {}
|
||||
|
||||
function select.init(env)
|
||||
local config = env.engine.schema.config
|
||||
select.first_key = config:get_string('key_binder/select_first_character')
|
||||
select.last_key = config:get_string('key_binder/select_last_character')
|
||||
end
|
||||
|
||||
function select.func(key, env)
|
||||
local engine = env.engine
|
||||
local context = env.engine.context
|
||||
|
||||
if
|
||||
not key:release()
|
||||
and (context:is_composing() or context:has_menu())
|
||||
and (select.first_key or select.last_key)
|
||||
then
|
||||
local text = context.input
|
||||
if context:get_selected_candidate() then
|
||||
text = context:get_selected_candidate().text
|
||||
end
|
||||
if utf8.len(text) > 1 then
|
||||
if (key:repr() == select.first_key) then
|
||||
engine:commit_text(text:sub(1, utf8.offset(text, 2) - 1))
|
||||
context:clear()
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
elseif (key:repr() == select.last_key) then
|
||||
engine:commit_text(text:sub(utf8.offset(text, -1)))
|
||||
context:clear()
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
end
|
||||
end
|
||||
end
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
return select
|
||||
185
lua/set_schema.lua
Normal file
185
lua/set_schema.lua
Normal file
@@ -0,0 +1,185 @@
|
||||
--https://github.com/amzxyz/rime_wanxiang
|
||||
--@amzxyz
|
||||
--一个快速初始化方案类型的工具,使用方法,方案文件放进用户目录后先部署,再执行相关指令后重新部署完成切换
|
||||
local wanxiang = require("wanxiang")
|
||||
|
||||
-- 文件复制函数
|
||||
local function copy_file(src, dest)
|
||||
local fi = io.open(src, "r")
|
||||
if not fi then
|
||||
return false
|
||||
end
|
||||
local content = fi:read("*a")
|
||||
fi:close()
|
||||
|
||||
local fo = io.open(dest, "w")
|
||||
if not fo then
|
||||
return false
|
||||
end
|
||||
fo:write(content)
|
||||
fo:close()
|
||||
return true
|
||||
end
|
||||
|
||||
-- 替换方案函数(根据文件名应用特定替换模式)
|
||||
local function replace_schema(file_path, target_schema)
|
||||
local f = io.open(file_path, "r")
|
||||
if not f then
|
||||
return false
|
||||
end
|
||||
local content = f:read("*a")
|
||||
f:close()
|
||||
|
||||
-- 根据文件名决定替换模式
|
||||
if file_path:find("wanxiang_reverse") then
|
||||
-- 把 "__include: wanxiang_reverse.schema:/"(含可选后缀)改成 "__include: wanxiang_algebra:/mixed/"
|
||||
content = content:gsub("(%-?%s*__include:%s*)wanxiang_reverse%.schema:/[^%s\r\n]*", "%1wanxiang_algebra:/reverse/" .. target_schema)
|
||||
-- "__patch: wanxiang_reverse.schema:/hspzn" -> "__patch: wanxiang_algebra:/reverse/hspzn"
|
||||
content = content:gsub("(%-?%s*__patch:%s*)wanxiang_reverse%.schema:/([^%s\r\n]+)", "%1wanxiang_algebra:/reverse/%2")
|
||||
|
||||
content = content:gsub("([%s]*__include:%s*wanxiang_algebra:/reverse/)%S+", "%1" .. target_schema)
|
||||
|
||||
elseif file_path:find("wanxiang_mixedcode") then
|
||||
|
||||
-- "__include: wanxiang_mixedcode.schema:/全拼"
|
||||
-- -> "__include: wanxiang_algebra:/mixed/通用派生规则"
|
||||
-- "__patch: wanxiang_algebra:/mixed/全拼"
|
||||
content = content:gsub(
|
||||
"(%-?%s*)__include:%s*wanxiang_mixedcode%.schema:/全拼",
|
||||
function(lead)
|
||||
return lead .. "__include: wanxiang_algebra:/mixed/通用派生规则\n"
|
||||
.. lead .. "__patch: wanxiang_algebra:/mixed/全拼"
|
||||
end
|
||||
)
|
||||
content = content:gsub("([%s]*__patch:%s*wanxiang_algebra:/mixed/)%S+", "%1" .. target_schema)
|
||||
|
||||
elseif file_path:find("wanxiang%.custom") or file_path:find("wanxiang_pro%.custom") then
|
||||
-- 先把旧前缀整体替换为新前缀
|
||||
-- "- wanxiang.schema:/" -> "- wanxiang_algebra:/base/"
|
||||
-- "- wanxiang_pro.schema:/" -> "- wanxiang_algebra:/pro/"
|
||||
content = content:gsub("(%-+%s*)wanxiang%.schema:/", "%1wanxiang_algebra:/base/")
|
||||
content = content:gsub("(%-+%s*)wanxiang_pro%.schema:/", "%1wanxiang_algebra:/pro/")
|
||||
|
||||
-- 再将 base/pro 后面的 schema 名替换为 target_schema
|
||||
content = content:gsub("([%s%-]*wanxiang_algebra:/pro/)%S+", "%1" .. target_schema, 1)
|
||||
content = content:gsub("([%s%-]*wanxiang_algebra:/base/)%S+", "%1" .. target_schema, 1)
|
||||
|
||||
|
||||
end
|
||||
|
||||
f = io.open(file_path, "w")
|
||||
if not f then
|
||||
return false
|
||||
end
|
||||
f:write(content)
|
||||
f:close()
|
||||
return true
|
||||
end
|
||||
|
||||
-- translator 主函数
|
||||
local function translator(input, seg, env)
|
||||
if input == "/zjf" or input == "/jjf" then
|
||||
local target_aux = (input == "/zjf") and "直接辅助" or "间接辅助"
|
||||
local user_dir = rime_api.get_user_data_dir()
|
||||
local paths = {
|
||||
user_dir .. "/wanxiang_pro.custom.yaml",
|
||||
user_dir .. "/wanxiang.custom.yaml",
|
||||
}
|
||||
|
||||
local total_hits, touched = 0, 0
|
||||
for _, p in ipairs(paths) do
|
||||
local f = io.open(p, "r")
|
||||
if f then
|
||||
local content = f:read("*a"); f:close()
|
||||
|
||||
-- 两次 gsub 都要接收“新文本 + 命中次数”
|
||||
local n1, n2 = 0, 0
|
||||
content, n1 = content:gsub("(%-+%s*wanxiang_algebra:/pro/)直接辅助(%s*#?.*)", "%1" .. target_aux .. "%2")
|
||||
content, n2 = content:gsub("(%-+%s*wanxiang_algebra:/pro/)间接辅助(%s*#?.*)", "%1" .. target_aux .. "%2")
|
||||
local n = n1 + n2
|
||||
|
||||
if n > 0 then
|
||||
local w = io.open(p, "w")
|
||||
if w then w:write(content); w:close() end
|
||||
total_hits = total_hits + n
|
||||
touched = touched + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local msg = (total_hits > 0)
|
||||
and ("已切换到〔" .. target_aux .. "〕,请重新部署")
|
||||
or "未找到可切换的条目"
|
||||
yield(Candidate("switch", seg.start, seg._end, msg, ""))
|
||||
return
|
||||
end
|
||||
local schema_map = {
|
||||
["/flypy"] = "小鹤双拼",
|
||||
["/mspy"] = "微软双拼",
|
||||
["/zrm"] = "自然码",
|
||||
["/sogou"] = "搜狗双拼",
|
||||
["/znabc"] = "智能ABC",
|
||||
["/ziguang"] = "紫光双拼",
|
||||
["/pyjj"] = "拼音加加",
|
||||
["/gbpy"] = "国标双拼",
|
||||
["/lxsq"] = "乱序17",
|
||||
["/zrlong"] = "自然龙",
|
||||
["/hxlong"] = "汉心龙",
|
||||
["/pinyin"] = "全拼",
|
||||
}
|
||||
|
||||
local target_schema = schema_map[input]
|
||||
if target_schema then
|
||||
local user_dir = rime_api.get_user_data_dir()
|
||||
|
||||
-- 检查根目录是否存在自定义文件
|
||||
local pro_file = user_dir .. "/wanxiang_pro.custom.yaml"
|
||||
local normal_file = user_dir .. "/wanxiang.custom.yaml"
|
||||
local pro_exists = io.open(pro_file, "r")
|
||||
local normal_exists = io.open(normal_file, "r")
|
||||
local custom_file_exists = false
|
||||
|
||||
if pro_exists or normal_exists then
|
||||
custom_file_exists = true
|
||||
if pro_exists then pro_exists:close() end
|
||||
if normal_exists then normal_exists:close() end
|
||||
end
|
||||
|
||||
local files = {
|
||||
"wanxiang_mixedcode.custom.yaml",
|
||||
"wanxiang_reverse.custom.yaml"
|
||||
}
|
||||
|
||||
-- 判断是否为专业版
|
||||
local is_pro = wanxiang.is_pro_scheme(env)
|
||||
local fourth_file = is_pro and "wanxiang_pro.custom.yaml" or "wanxiang.custom.yaml"
|
||||
table.insert(files, fourth_file)
|
||||
|
||||
for _, name in ipairs(files) do
|
||||
local src = user_dir .. "/custom/" .. name
|
||||
local dest = user_dir .. "/" .. name
|
||||
|
||||
if name == fourth_file and custom_file_exists then
|
||||
-- 根目录自定义文件已存在,不复制,但依然修改
|
||||
replace_schema(dest, target_schema)
|
||||
else
|
||||
-- 其他文件: 若 custom 目录存在文件,则复制到根目录并修改
|
||||
local src_file = io.open(src, "r")
|
||||
if src_file then
|
||||
src_file:close()
|
||||
if copy_file(src, dest) then
|
||||
replace_schema(dest, target_schema)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 返回提示候选
|
||||
if custom_file_exists then
|
||||
yield(Candidate("switch", seg.start, seg._end, "检测到已有自定义文件,已为您切换到〔" .. target_schema .. "〕,请手动重新部署", ""))
|
||||
else
|
||||
yield(Candidate("switch", seg.start, seg._end, "已帮您复制并切换到〔" .. target_schema .. "〕,请手动重新部署", ""))
|
||||
end
|
||||
end
|
||||
end
|
||||
return translator
|
||||
3017
lua/shijian.lua
Normal file
3017
lua/shijian.lua
Normal file
File diff suppressed because it is too large
Load Diff
3491
lua/super_calculator.lua
Normal file
3491
lua/super_calculator.lua
Normal file
File diff suppressed because it is too large
Load Diff
535
lua/super_comment_preedit.lua
Normal file
535
lua/super_comment_preedit.lua
Normal file
@@ -0,0 +1,535 @@
|
||||
--@amzxyz https://github.com/amzxyz/rime_wanxiang
|
||||
|
||||
|
||||
local wanxiang = require('wanxiang')
|
||||
|
||||
local tone_map = {
|
||||
['ā']='a', ['á']='a', ['ǎ']='a', ['à']='a',
|
||||
['ē']='e', ['é']='e', ['ě']='e', ['è']='e',
|
||||
['ī']='i', ['í']='i', ['ǐ']='i', ['ì']='i',
|
||||
['ō']='o', ['ó']='o', ['ǒ']='o', ['ò']='o', ['ň']='n',
|
||||
['ū']='u', ['ú']='u', ['ǔ']='u', ['ù']='u', ['ǹ']='n',
|
||||
['ǖ']='ü', ['ǘ']='ü', ['ǚ']='ü', ['ǜ']='ü', ['ń']='n',
|
||||
}
|
||||
|
||||
local function remove_pinyin_tone(s)
|
||||
local result = {}
|
||||
for uchar in s:gmatch("[%z\1-\127\194-\244][\128-\191]*") do
|
||||
table.insert(result, tone_map[uchar] or uchar)
|
||||
end
|
||||
return table.concat(result)
|
||||
end
|
||||
|
||||
-- ----------------------
|
||||
-- # 辅助码拆分提示模块
|
||||
-- PRO 专用
|
||||
-- ----------------------
|
||||
local CF = {}
|
||||
function CF.init(env)
|
||||
if wanxiang.is_pro_scheme(env) then -- pro 版直接初始化
|
||||
CF.get_dict(env)
|
||||
end
|
||||
end
|
||||
|
||||
function CF.fini(env)
|
||||
env.chaifen_dict = nil
|
||||
collectgarbage()
|
||||
end
|
||||
|
||||
function CF.get_dict(env)
|
||||
if env.chaifen_dict == nil then
|
||||
env.chaifen_dict = ReverseLookup("wanxiang_chaifen")
|
||||
end
|
||||
return env.chaifen_dict
|
||||
end
|
||||
|
||||
function CF.get_comment(cand, env)
|
||||
local dict = CF.get_dict(env)
|
||||
if not dict then return "" end
|
||||
|
||||
local raw = dict:lookup(cand.text)
|
||||
if not raw or raw == "" then return "" end
|
||||
|
||||
local tpl = (env and env.settings and env.settings.chaifen) or ""
|
||||
|
||||
if tpl ~= "" then
|
||||
-- 取 chaifen 左右两边
|
||||
local left, right = tpl:match("^(.-)chaifen(.-)$")
|
||||
if left then
|
||||
return left .. raw .. right
|
||||
end
|
||||
end
|
||||
|
||||
return raw
|
||||
end
|
||||
|
||||
-- ----------------------
|
||||
-- # 错音错字提示模块
|
||||
-- ----------------------
|
||||
local CR = {}
|
||||
local corrections_cache = nil -- 用于缓存已加载的词典
|
||||
function CR.init(env)
|
||||
CR.style = env.settings.corrector_type or '{comment}'
|
||||
--if corrections_cache then return end
|
||||
local auto_delimiter = env.settings.auto_delimiter
|
||||
local is_pro = wanxiang.is_pro_scheme(env)
|
||||
-- 根据方案选择加载路径
|
||||
local path = (is_pro and "dicts/cuoyin.pro.dict.yaml") or "dicts/cuoyin.dict.yaml"
|
||||
local file, close_file, err = wanxiang.load_file_with_fallback(path)
|
||||
if not file then
|
||||
log.error(string.format("[super_comment]: 加载失败 %s,错误: %s", path, err))
|
||||
return
|
||||
end
|
||||
corrections_cache = {}
|
||||
for line in file:lines() do
|
||||
if not line:match("^#") then
|
||||
local text, code, weight, comment = line:match("^(.-)\t(.-)\t(.-)\t(.-)$")
|
||||
if text and code then
|
||||
text = text:match("^%s*(.-)%s*$")
|
||||
code = code:match("^%s*(.-)%s*$")
|
||||
comment = comment and comment:match("^%s*(.-)%s*$") or ""
|
||||
comment = comment:gsub("%s+", auto_delimiter)
|
||||
code = code:gsub("%s+", auto_delimiter)
|
||||
corrections_cache[code] = { text = text, comment = comment }
|
||||
end
|
||||
end
|
||||
end
|
||||
close_file()
|
||||
end
|
||||
|
||||
function CR.get_comment(cand)
|
||||
local correction = corrections_cache and corrections_cache[cand.comment] or nil
|
||||
if not (correction and cand.text == correction.text) then
|
||||
return nil
|
||||
end
|
||||
-- 只认占位符 `comment`,按“刀法”切分
|
||||
local tpl = CR.style or "comment"
|
||||
local left, right = tpl:match("^(.-)comment(.-)$")
|
||||
|
||||
if left then
|
||||
return left .. correction.comment .. right
|
||||
else
|
||||
return correction.comment
|
||||
end
|
||||
end
|
||||
|
||||
-- ----------------------
|
||||
-- 部件组字返回的注释
|
||||
-- ----------------------
|
||||
---@return string
|
||||
local function get_az_comment(_, env, initial_comment)
|
||||
if not initial_comment or initial_comment == "" then return "〔无〕" end
|
||||
local final_comment = nil
|
||||
local auto_delimiter = env.settings.auto_delimiter or " "
|
||||
-- 拆分初始评论为多个段落
|
||||
local segments = {}
|
||||
for segment in initial_comment:gmatch("[^%s]+") do
|
||||
table.insert(segments, segment)
|
||||
end
|
||||
local semicolon_count = select(2, segments[1]:gsub(";", "")) -- 使用第一个段来判断分号的数量
|
||||
local pinyins = {}
|
||||
local fuzhu = nil
|
||||
for _, segment in ipairs(segments) do
|
||||
local pinyin = segment:match("^[^;~]+")
|
||||
local fz = nil
|
||||
|
||||
if semicolon_count == 1 then
|
||||
-- 一个分号:取后段
|
||||
fz = segment:match(";(.+)$")
|
||||
else
|
||||
-- 无分号不取辅助码
|
||||
fz = nil
|
||||
end
|
||||
|
||||
if pinyin then table.insert(pinyins, pinyin) end
|
||||
if not fuzhu and fz and fz ~= "" then fuzhu = fz end
|
||||
end
|
||||
|
||||
-- 拼接结果
|
||||
if #pinyins > 0 then
|
||||
local pinyin_str = table.concat(pinyins, ",")
|
||||
if fuzhu then
|
||||
final_comment = string.format("〔音%s 辅%s〕", pinyin_str, fuzhu)
|
||||
else
|
||||
final_comment = string.format("〔音%s〕", pinyin_str)
|
||||
end
|
||||
end
|
||||
return final_comment or "〔无〕"
|
||||
end
|
||||
-- ----------------------
|
||||
-- # 辅助码提示或带调全拼注释模块 (Fuzhu)
|
||||
-- ----------------------
|
||||
local function get_fz_comment(cand, env, initial_comment)
|
||||
local length = utf8.len(cand.text)
|
||||
if length > env.settings.candidate_length then
|
||||
return ""
|
||||
end
|
||||
local auto_delimiter = env.settings.auto_delimiter or " "
|
||||
local segments = {}
|
||||
for segment in string.gmatch(initial_comment, "[^" .. auto_delimiter .. "]+") do
|
||||
table.insert(segments, segment)
|
||||
end
|
||||
|
||||
-- 根据 option 动态决定是否强制使用 tone
|
||||
local use_tone = env.engine.context:get_option("tone_hint")
|
||||
local fuzhu_type = use_tone and "tone" or "fuzhu"
|
||||
|
||||
local first_segment = segments[1] or ""
|
||||
local semicolon_count = select(2, first_segment:gsub(";", ""))
|
||||
local fuzhu_comments = {}
|
||||
-- 没有分号的情况
|
||||
if semicolon_count == 0 then
|
||||
return initial_comment:gsub(auto_delimiter, " ")
|
||||
else
|
||||
-- 有分号:按类型提取
|
||||
for _, segment in ipairs(segments) do
|
||||
if fuzhu_type == "tone" then
|
||||
-- 取第一个分号“前”的内容
|
||||
local before = segment:match("^(.-);")
|
||||
if before and before ~= "" then
|
||||
table.insert(fuzhu_comments, before)
|
||||
end
|
||||
else -- "fuzhu"
|
||||
-- 取第一个分号“后”的内容(到行尾)
|
||||
local after = segment:match(";(.+)$")
|
||||
if after and after ~= "" then
|
||||
table.insert(fuzhu_comments, after)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 最终拼接输出,fuzhu用 `,`,tone用 /连接
|
||||
if #fuzhu_comments > 0 then
|
||||
if fuzhu_type == "tone" then
|
||||
return table.concat(fuzhu_comments, " ")
|
||||
else
|
||||
return table.concat(fuzhu_comments, "/")
|
||||
end
|
||||
else
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local SV = {}
|
||||
|
||||
-- 工具:取光标前的编码(安全处理 caret 越界)
|
||||
local function front_input(ctx)
|
||||
if not ctx then return "" end
|
||||
local raw_full = ctx.input or ""
|
||||
local caret = ctx.caret_pos or #raw_full
|
||||
if caret < 0 then
|
||||
caret = 0
|
||||
elseif caret > #raw_full then
|
||||
caret = #raw_full
|
||||
end
|
||||
return raw_full:sub(1, caret)
|
||||
end
|
||||
|
||||
-- 这个模块主要用于将滤镜阶段未修改前的注释或者 preedit
|
||||
-- 存到上下文变量里,按键处理阶段使用;update_notifier 保证一致性
|
||||
function SV.init(env)
|
||||
env._sv_seq_sig = ""
|
||||
env._sv_last_pre = "" -- 最近一次要写入的 preedit
|
||||
env._saved_input_for_seq = "" -- 上次对应的 raw_in(光标前编码)
|
||||
|
||||
local ctx = env.engine.context
|
||||
|
||||
env._sv_ctx_conn = ctx.update_notifier:connect(function(c)
|
||||
local raw_in = front_input(c)
|
||||
|
||||
local pre = env._sv_last_pre or ""
|
||||
if pre == "" or raw_in == "" then
|
||||
return
|
||||
end
|
||||
|
||||
-- 不重写:光标前编码 + preedit
|
||||
local sig = raw_in .. "\t" .. pre
|
||||
if env._sv_seq_sig == sig then
|
||||
return
|
||||
end
|
||||
|
||||
c:set_property("sequence_preedit_key", raw_in)
|
||||
c:set_property("sequence_preedit_val", pre)
|
||||
env._sv_seq_sig = sig
|
||||
end)
|
||||
end
|
||||
|
||||
-- 断开 notifier,清理状态
|
||||
function SV.fini(env)
|
||||
if env._sv_ctx_conn then
|
||||
env._sv_ctx_conn:disconnect()
|
||||
env._sv_ctx_conn = nil
|
||||
end
|
||||
env._sv_seq_sig = nil
|
||||
env._sv_last_pre = nil
|
||||
env._saved_input_for_seq = nil
|
||||
end
|
||||
|
||||
-- 限制更新范围:同一个 raw_in 只记第一次的 preedit
|
||||
function SV.update_preedit(env, preedit)
|
||||
local ctx = env.engine.context
|
||||
if not ctx then return end
|
||||
|
||||
local raw_in = front_input(ctx)
|
||||
preedit = preedit or ""
|
||||
|
||||
if raw_in == "" or preedit == "" then
|
||||
return
|
||||
end
|
||||
|
||||
if env._saved_input_for_seq ~= raw_in then
|
||||
env._saved_input_for_seq = raw_in
|
||||
env._sv_last_pre = preedit
|
||||
end
|
||||
end
|
||||
-- 对 cand.preedit 应用 tone_preedit/0..9 的映射(数字 -> 上标等)
|
||||
local function apply_tone_preedit(env, cand)
|
||||
if not cand or not cand.preedit or cand.preedit == "" then
|
||||
return
|
||||
end
|
||||
|
||||
-- 用 context.input 判断是否有相邻数字
|
||||
local input
|
||||
local engine = env.engine
|
||||
if engine and engine.context then
|
||||
-- Rime 里一般是 string,保险起见兜个 nil
|
||||
input = engine.context.input or ""
|
||||
end
|
||||
|
||||
-- 如果整条输入串中存在相邻两个数字(例如 "li39"、"abc10" 等),
|
||||
-- 则整体不做任何转换,直接返回,为了配合小键盘输入逻辑中包吃书字面大小一致性
|
||||
if input and input ~= "" and input:match("%d%d") then
|
||||
return
|
||||
end
|
||||
|
||||
-- 懒加载 tone_map
|
||||
if not env.tone_map then
|
||||
env.tone_map = {}
|
||||
local cfg = engine and engine.schema and engine.schema.config
|
||||
if cfg then
|
||||
for d = 0, 9 do
|
||||
local k = tostring(d)
|
||||
local v = cfg:get_string("tone_preedit/" .. k)
|
||||
if v and v ~= "" then
|
||||
env.tone_map[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local preedit = cand.preedit
|
||||
local converted = preedit:gsub("([^%d%s]+)(%d+)", function(body, digits)
|
||||
local mapped = digits:gsub("%d", function(d)
|
||||
return env.tone_map and env.tone_map[d] or d
|
||||
end)
|
||||
return body .. mapped
|
||||
end)
|
||||
|
||||
if converted ~= preedit then
|
||||
cand.preedit = converted
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- ----------------------
|
||||
-- 主函数:根据优先级处理候选词的注释和preedit
|
||||
-- ----------------------
|
||||
local ZH = {}
|
||||
function ZH.init(env)
|
||||
local config = env.engine.schema.config
|
||||
local delimiter = config:get_string('speller/delimiter') or " '"
|
||||
local auto_delimiter = delimiter:sub(1, 1)
|
||||
local manual_delimiter = delimiter:sub(2, 2)
|
||||
env.settings = {
|
||||
delimiter = delimiter,
|
||||
auto_delimiter = auto_delimiter,
|
||||
manual_delimiter = manual_delimiter,
|
||||
corrector_enabled = config:get_bool("super_comment/corrector") or true,
|
||||
corrector_type = config:get_string("super_comment/corrector_type") or "{comment}",
|
||||
chaifen = config:get_string("super_comment/chaifen") or "〔chaifen〕",
|
||||
candidate_length = tonumber(config:get_string("super_comment/candidate_length")) or 1,
|
||||
}
|
||||
CR.init(env)
|
||||
SV.init(env)
|
||||
end
|
||||
function ZH.fini(env)
|
||||
-- 清理
|
||||
CF.fini(env)
|
||||
SV.fini(env)
|
||||
end
|
||||
function ZH.func(input, env)
|
||||
local config = env.engine.schema.config
|
||||
local context = env.engine.context
|
||||
local input_str = context.input
|
||||
local is_radical_mode = wanxiang.is_in_radical_mode(env)
|
||||
local schema_id = env.engine.schema.schema_id or ""
|
||||
local is_wanxiang_pro = (schema_id == "wanxiang_pro")
|
||||
local should_skip_candidate_comment = wanxiang.is_function_mode_active(context) or input_str == ""
|
||||
local is_tone_comment = env.engine.context:get_option("tone_hint")
|
||||
local is_comment_hint = env.engine.context:get_option("fuzhu_hint")
|
||||
local is_chaifen_enabled = env.engine.context:get_option("chaifen_switch")
|
||||
--preedit相关声明
|
||||
local delimiter = env.settings.delimiter
|
||||
local auto_delimiter = env.settings.auto_delimiter
|
||||
local manual_delimiter = env.settings.manual_delimiter
|
||||
local visual_delim = config:get_string("speller/visual_delimiter") or " "
|
||||
local tone_isolate = config:get_bool("speller/tone_isolate")
|
||||
local is_tone_display = context:get_option("tone_display")
|
||||
local is_full_pinyin = context:get_option("full_pinyin")
|
||||
local index = 0
|
||||
-- auto_phrase 相关声明
|
||||
local enable_auto_phrase = config:get_bool("add_user_dict/enable_auto_phrase") or false
|
||||
local enable_user_dict = config:get_bool("add_user_dict/enable_user_dict") or false
|
||||
|
||||
for cand in input:iter() do
|
||||
local genuine_cand = cand:get_genuine()
|
||||
local preedit = genuine_cand.preedit or ""
|
||||
local initial_comment = genuine_cand.comment
|
||||
local final_comment = initial_comment
|
||||
index = index + 1
|
||||
|
||||
SV.update_preedit(env, preedit) --储存到环境变量
|
||||
|
||||
-- preedit相关处理只跳过 preedit,不影响注释
|
||||
if is_radical_mode then
|
||||
goto after_preedit
|
||||
end
|
||||
if not is_tone_display and not is_full_pinyin then
|
||||
goto after_preedit
|
||||
end
|
||||
if (not initial_comment or initial_comment == "") then
|
||||
goto after_preedit
|
||||
end
|
||||
do
|
||||
-- 拆分 preedit
|
||||
local input_parts = {}
|
||||
local current_segment = ""
|
||||
for i = 1, #preedit do
|
||||
local char = preedit:sub(i, i)
|
||||
if char == auto_delimiter or char == manual_delimiter then
|
||||
if #current_segment > 0 then
|
||||
table.insert(input_parts, current_segment)
|
||||
current_segment = ""
|
||||
end
|
||||
table.insert(input_parts, char)
|
||||
else
|
||||
current_segment = current_segment .. char
|
||||
end
|
||||
end
|
||||
if #current_segment > 0 then
|
||||
table.insert(input_parts, current_segment)
|
||||
end
|
||||
|
||||
-- 拆分拼音段(comment)
|
||||
local pinyin_segments = {}
|
||||
for segment in string.gmatch(initial_comment, "[^" .. auto_delimiter .. manual_delimiter .. "]+") do
|
||||
local pinyin = segment:match("^[^;]+")
|
||||
if pinyin then
|
||||
pinyin = pinyin:gsub("[%[%]]", "") --去掉英文词库编码中的[]
|
||||
table.insert(pinyin_segments, pinyin)
|
||||
end
|
||||
end
|
||||
|
||||
-- 替换逻辑
|
||||
local pinyin_index = 1
|
||||
for i, part in ipairs(input_parts) do
|
||||
if part == auto_delimiter or part == manual_delimiter then
|
||||
input_parts[i] = visual_delim
|
||||
else
|
||||
local body, tone = part:match("([%a]+)([^%a]+)") --后面加号很必要
|
||||
local py = pinyin_segments[pinyin_index]
|
||||
|
||||
if py then
|
||||
if is_wanxiang_pro then
|
||||
input_parts[i] = py
|
||||
pinyin_index = pinyin_index + 1
|
||||
elseif i == #input_parts and #part == 1 then
|
||||
local prefix = py:sub(1, 2)
|
||||
local first_char = part:sub(1,1):lower()
|
||||
if first_char == "s" or first_char == "c" or first_char == "z" then
|
||||
input_parts[i] = part
|
||||
else
|
||||
if prefix == "zh" or prefix == "ch" or prefix == "sh" then
|
||||
input_parts[i] = prefix
|
||||
else
|
||||
input_parts[i] = part
|
||||
end
|
||||
end
|
||||
else
|
||||
if tone_isolate then
|
||||
input_parts[i] = py .. (tone or "")
|
||||
else
|
||||
input_parts[i] = py
|
||||
end
|
||||
pinyin_index = pinyin_index + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if is_full_pinyin then
|
||||
for idx, part in ipairs(input_parts) do
|
||||
input_parts[idx] = remove_pinyin_tone(part)
|
||||
end
|
||||
end
|
||||
|
||||
genuine_cand.preedit = table.concat(input_parts)
|
||||
end
|
||||
::after_preedit::
|
||||
apply_tone_preedit(env, genuine_cand)
|
||||
if should_skip_candidate_comment then
|
||||
yield(genuine_cand)
|
||||
goto continue
|
||||
end
|
||||
-- 进入注释处理阶段
|
||||
-- ① 辅助码注释或者声调注释
|
||||
if is_comment_hint then
|
||||
local fz_comment = get_fz_comment(cand, env, initial_comment)
|
||||
if fz_comment then
|
||||
final_comment = fz_comment
|
||||
end
|
||||
elseif is_tone_comment then
|
||||
local fz_comment = get_fz_comment(cand, env, initial_comment)
|
||||
if fz_comment then
|
||||
final_comment = fz_comment
|
||||
end
|
||||
else
|
||||
final_comment = ""
|
||||
end
|
||||
|
||||
-- ② 拆分注释
|
||||
if is_chaifen_enabled then
|
||||
local cf_comment = CF.get_comment(cand, env)
|
||||
if cf_comment and cf_comment ~= "" then --不为空很重要
|
||||
final_comment = cf_comment
|
||||
end
|
||||
end
|
||||
|
||||
-- ③ 错音错字提示
|
||||
if env.settings.corrector_enabled then
|
||||
local cr_comment = CR.get_comment(cand)
|
||||
if cr_comment and cr_comment ~= "" then
|
||||
final_comment = cr_comment
|
||||
end
|
||||
end
|
||||
|
||||
-- ④ 反查模式提示
|
||||
if is_radical_mode then
|
||||
local az_comment = get_az_comment(cand, env, initial_comment)
|
||||
if az_comment and az_comment ~= "" then
|
||||
final_comment = az_comment
|
||||
end
|
||||
end
|
||||
|
||||
-- 应用注释
|
||||
if final_comment ~= initial_comment then
|
||||
genuine_cand.comment = final_comment
|
||||
end
|
||||
|
||||
yield(genuine_cand)
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
return ZH
|
||||
1030
lua/super_filter.lua
Normal file
1030
lua/super_filter.lua
Normal file
File diff suppressed because it is too large
Load Diff
589
lua/super_lookup.lua
Normal file
589
lua/super_lookup.lua
Normal file
@@ -0,0 +1,589 @@
|
||||
--@amzxyz https://github.com/amzxyz/rime_wanxiang
|
||||
|
||||
--wanxiang_lookup: #设置归属于super_lookup.lua
|
||||
--tags: [ abc ] # 检索当前tag的候选
|
||||
--key: "`" # 输入中反查引导符,要添加到 speller/alphabet
|
||||
--lookup: [ wanxiang_reverse ] #反查滤镜数据库,万象都合并为一个了
|
||||
|
||||
-- 获取 wanxiang 模块
|
||||
local function get_wanxiang()
|
||||
local ok, mod = pcall(function() return require('wanxiang') end)
|
||||
if ok and type(mod) == 'table' then return mod end
|
||||
if type(_G.wanxiang) == 'table' then return _G.wanxiang end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 各输入法类型对应的转换规则
|
||||
-- flypy/mspy/sogou/abc/ziguang/pyjj/gbpy/lxsq/zrlong/hxlong
|
||||
local LOCAL_PROJECTION_RULES = {
|
||||
-- 全拼(pinyin)
|
||||
pinyin = {
|
||||
"xform/'//",
|
||||
"derive/^([nl])ue$/$1ve/",
|
||||
"derive/'([nl])ue$/'$1ve/",
|
||||
"derive/^([jqxy])u/$1v/",
|
||||
"derive/'([jqxy])u/'$1v/",
|
||||
},
|
||||
|
||||
-- 自然码(zrm)
|
||||
zrm = {
|
||||
"derive/^([jqxy])u(?=^|$|')/$1v/",
|
||||
"derive/'([jqxy])u(?=^|$|')/'$1v/",
|
||||
"derive/^([aoe])([ioun])(?=^|$|')/$1$1$2/",
|
||||
"derive/'([aoe])([ioun])(?=^|$|')/'$1$1$2/",
|
||||
"xform/^([aoe])(ng)?(?=^|$|')/$1$1$2/",
|
||||
"xform/'([aoe])(ng)?(?=^|$|')/'$1$1$2/",
|
||||
"xform/iu(?=^|$|')/<q>/",
|
||||
"xform/[iu]a(?=^|$|')/<w>/",
|
||||
"xform/[uv]an(?=^|$|')/<r>/",
|
||||
"xform/[uv]e(?=^|$|')/<t>/",
|
||||
"xform/ing(?=^|$|')|uai(?=^|$|')/<y>/",
|
||||
"xform/^sh/<u>/",
|
||||
"xform/^ch/<i>/",
|
||||
"xform/^zh/<v>/",
|
||||
"xform/'sh/'<u>/",
|
||||
"xform/'ch/'<i>/",
|
||||
"xform/'zh/'<v>/",
|
||||
"xform/uo(?=^|$|')/<o>/",
|
||||
"xform/[uv]n(?=^|$|')/<p>/",
|
||||
"xform/([a-z>])i?ong(?=^|$|')/$1<s>/",
|
||||
"xform/[iu]ang(?=^|$|')/<d>/",
|
||||
"xform/([a-z>])en(?=^|$|')/$1<f>/",
|
||||
"xform/([a-z>])eng(?=^|$|')/$1<g>/",
|
||||
"xform/([a-z>])ang(?=^|$|')/$1<h>/",
|
||||
"xform/ian(?=^|$|')/<m>/",
|
||||
"xform/([a-z>])an(?=^|$|')/$1<j>/",
|
||||
"xform/iao(?=^|$|')/<c>/",
|
||||
"xform/([a-z>])ao(?=^|$|')/$1<k>/",
|
||||
"xform/([a-z>])ai(?=^|$|')/$1<l>/",
|
||||
"xform/([a-z>])ei(?=^|$|')/$1<z>/",
|
||||
"xform/ie(?=^|$|')/<x>/",
|
||||
"xform/ui(?=^|$|')/<v>/",
|
||||
"xform/([a-z>])ou(?=^|$|')/$1<b>/",
|
||||
"xform/in(?=^|$|')/<n>/",
|
||||
"xform/'|<|>//",
|
||||
},
|
||||
|
||||
-- 小鹤(flypy)
|
||||
flypy = {
|
||||
"derive/^([jqxy])u(?=^|$|')/$1v/",
|
||||
"derive/'([jqxy])u(?=^|$|')/'$1v/",
|
||||
"derive/^([aoe])([ioun])(?=^|$|')/$1$1$2/",
|
||||
"derive/'([aoe])([ioun])(?=^|$|')/'$1$1$2/",
|
||||
"xform/^([aoe])(ng)?(?=^|$|')/$1$1$2/",
|
||||
"xform/'([aoe])(ng)?(?=^|$|')/'$1$1$2/",
|
||||
"xform/iu(?=^|$|')/<q>/",
|
||||
"xform/(.)ei(?=^|$|')/$1<w>/",
|
||||
"xform/uan(?=^|$|')/<r>/",
|
||||
"xform/[uv]e(?=^|$|')/<t>/",
|
||||
"xform/un(?=^|$|')/<y>/",
|
||||
"xform/^sh/<u>/",
|
||||
"xform/^ch/<i>/",
|
||||
"xform/^zh/<v>/",
|
||||
"xform/'sh/'<u>/",
|
||||
"xform/'ch/'<i>/",
|
||||
"xform/'zh/'<v>/",
|
||||
"xform/uo(?=^|$|')/<o>/",
|
||||
"xform/ie(?=^|$|')/<p>/",
|
||||
"xform/([a-z>])i?ong(?=^|$|')/$1<s>/",
|
||||
"xform/ing(?=^|$|')|uai(?=^|$|')/<k>/",
|
||||
"xform/([a-z>])ai(?=^|$|')/$1<d>/",
|
||||
"xform/([a-z>])en(?=^|$|')/$1<f>/",
|
||||
"xform/([a-z>])eng(?=^|$|')/$1<g>/",
|
||||
"xform/[iu]ang(?=^|$|')/<l>/",
|
||||
"xform/([a-z>])ang(?=^|$|')/$1<h>/",
|
||||
"xform/ian(?=^|$|')/<m>/",
|
||||
"xform/([a-z>])an(?=^|$|')/$1<j>/",
|
||||
"xform/([a-z>])ou(?=^|$|')/$1<z>/",
|
||||
"xform/[iu]a(?=^|$|')/<x>/",
|
||||
"xform/iao(?=^|$|')/<n>/",
|
||||
"xform/([a-z>])ao(?=^|$|')/$1<c>/",
|
||||
"xform/ui(?=^|$|')/<v>/",
|
||||
"xform/in(?=^|$|')/<b>/",
|
||||
"xform/'|<|>//",
|
||||
},
|
||||
|
||||
-- 微软(mspy)
|
||||
mspy = {
|
||||
"derive/^([jqxy])u(?=^|$|')/$1v/",
|
||||
"derive/'([jqxy])u(?=^|$|')/'$1v/",
|
||||
"derive/^([aoe].*)(?=^|$|')/o$1/",
|
||||
"derive/'([aoe].*)(?=^|$|')/'o$1/",
|
||||
"xform/^([ae])(.*)(?=^|$|')/$1$1$2/",
|
||||
"xform/'([ae])(.*)(?=^|$|')/'$1$1$2/",
|
||||
"xform/iu(?=^|$|')/<q>/",
|
||||
"xform/[iu]a(?=^|$|')/<w>/",
|
||||
"xform/er(?=^|$|')|[uv]an(?=^|$|')/<r>/",
|
||||
"xform/[uv]e(?=^|$|')/<t>/",
|
||||
"xform/v(?=^|$|')|uai(?=^|$|')/<y>/",
|
||||
"xform/^sh/<u>/",
|
||||
"xform/^ch/<i>/",
|
||||
"xform/^zh/<v>/",
|
||||
"xform/'sh/'<u>/",
|
||||
"xform/'ch/'<i>/",
|
||||
"xform/'zh/'<v>/",
|
||||
"xform/uo(?=^|$|')/<o>/",
|
||||
"xform/[uv]n(?=^|$|')/<p>/",
|
||||
"xform/([a-z>])i?ong(?=^|$|')/$1<s>/",
|
||||
"xform/[iu]ang(?=^|$|')/<d>/",
|
||||
"xform/([a-z>])en(?=^|$|')/$1<f>/",
|
||||
"xform/([a-z>])eng(?=^|$|')/$1<g>/",
|
||||
"xform/([a-z>])ang(?=^|$|')/$1<h>/",
|
||||
"xform/ian(?=^|$|')/<m>/",
|
||||
"xform/([a-z>])an(?=^|$|')/$1<j>/",
|
||||
"xform/iao(?=^|$|')/<c>/",
|
||||
"xform/([a-z>])ao(?=^|$|')/$1<k>/",
|
||||
"xform/([a-z>])ai(?=^|$|')/$1<l>/",
|
||||
"xform/([a-z>])ei(?=^|$|')/$1<z>/",
|
||||
"xform/ie(?=^|$|')/<x>/",
|
||||
"xform/ui(?=^|$|')/<v>/",
|
||||
"derive/<t>(?=^|$|')/<v>/",
|
||||
"xform/([a-z>])ou(?=^|$|')/$1<b>/",
|
||||
"xform/in(?=^|$|')/<n>/",
|
||||
"xform/ing(?=^|$|')/;/",
|
||||
"xform/'|<|>//",
|
||||
},
|
||||
|
||||
-- 搜狗双拼(sogou)
|
||||
sogou = {
|
||||
"derive/^([jqxy])u(?=^|$|')/$1v/",
|
||||
"derive/'([jqxy])u(?=^|$|')/'$1v/",
|
||||
"derive/^([aoe].*)(?=^|$|')/o$1/",
|
||||
"derive/'([aoe].*)(?=^|$|')/'o$1/",
|
||||
"xform/^([ae])(.*)(?=^|$|')/$1$1$2/",
|
||||
"xform/'([ae])(.*)(?=^|$|')/'$1$1$2/",
|
||||
"xform/iu(?=^|$|')/<q>/",
|
||||
"xform/[iu]a(?=^|$|')/<w>/",
|
||||
"xform/er(?=^|$|')|[uv]an(?=^|$|')/<r>/",
|
||||
"xform/[uv]e(?=^|$|')/<t>/",
|
||||
"xform/v(?=^|$|')|uai(?=^|$|')/<y>/",
|
||||
"xform/^sh/<u>/",
|
||||
"xform/^ch/<i>/",
|
||||
"xform/^zh/<v>/",
|
||||
"xform/'sh/'<u>/",
|
||||
"xform/'ch/'<i>/",
|
||||
"xform/'zh/'<v>/",
|
||||
"xform/uo(?=^|$|')/<o>/",
|
||||
"xform/[uv]n(?=^|$|')/<p>/",
|
||||
"xform/([a-z>])i?ong(?=^|$|')/$1<s>/",
|
||||
"xform/[iu]ang(?=^|$|')/<d>/",
|
||||
"xform/([a-z>])en(?=^|$|')/$1<f>/",
|
||||
"xform/([a-z>])eng(?=^|$|')/$1<g>/",
|
||||
"xform/([a-z>])ang(?=^|$|')/$1<h>/",
|
||||
"xform/ian(?=^|$|')/<m>/",
|
||||
"xform/([a-z>])an(?=^|$|')/$1<j>/",
|
||||
"xform/iao(?=^|$|')/<c>/",
|
||||
"xform/([a-z>])ao(?=^|$|')/$1<k>/",
|
||||
"xform/([a-z>])ai(?=^|$|')/$1<l>/",
|
||||
"xform/([a-z>])ei(?=^|$|')/$1<z>/",
|
||||
"xform/ie(?=^|$|')/<x>/",
|
||||
"xform/ui(?=^|$|')/<v>/",
|
||||
"xform/([a-z>])ou(?=^|$|')/$1<b>/",
|
||||
"xform/in(?=^|$|')/<n>/",
|
||||
"xform/ing(?=^|$|')/;/",
|
||||
"xform/'|<|>//",
|
||||
},
|
||||
|
||||
-- 智能(abc)
|
||||
abc = {
|
||||
"xform/^zh/<a>/",
|
||||
"xform/^ch/<e>/",
|
||||
"xform/^sh/<v>/",
|
||||
"xform/'zh/'<a>/",
|
||||
"xform/'ch/'<e>/",
|
||||
"xform/'sh/'<v>/",
|
||||
"xform/^([aoe].*)(?=^|$|')/<o>$1/",
|
||||
"xform/'([aoe].*)(?=^|$|')/'<o>$1/",
|
||||
"xform/ei(?=^|$|')/<q>/",
|
||||
"xform/ian(?=^|$|')/<w>/",
|
||||
"xform/er(?=^|$|')|iu(?=^|$|')/<r>/",
|
||||
"xform/[iu]ang(?=^|$|')/<t>/",
|
||||
"xform/ing(?=^|$|')/<y>/",
|
||||
"xform/uo(?=^|$|')/<o>/",
|
||||
"xform/uan(?=^|$|')/<p>/",
|
||||
"xform/([a-z>])i?ong(?=^|$|')/$1<s>/",
|
||||
"xform/[iu]a(?=^|$|')/<d>/",
|
||||
"xform/en(?=^|$|')/<f>/",
|
||||
"xform/eng(?=^|$|')/<g>/",
|
||||
"xform/ang(?=^|$|')/<h>/",
|
||||
"xform/an(?=^|$|')/<j>/",
|
||||
"xform/iao(?=^|$|')/<z>/",
|
||||
"xform/ao(?=^|$|')/<k>/",
|
||||
"xform/in(?=^|$|')|uai(?=^|$|')/<c>/",
|
||||
"xform/ai(?=^|$|')/<l>/",
|
||||
"xform/ie(?=^|$|')/<x>/",
|
||||
"xform/ou(?=^|$|')/<b>/",
|
||||
"xform/un(?=^|$|')/<n>/",
|
||||
"xform/[uv]e(?=^|$|')|ui(?=^|$|')/<m>/",
|
||||
"xform/'|<|>//",
|
||||
},
|
||||
|
||||
-- 紫光(ziguang)
|
||||
ziguang = {
|
||||
"derive/^([jqxy])u(?=^|$|')/$1v/",
|
||||
"derive/'([jqxy])u(?=^|$|')/'$1v/",
|
||||
"xform/'([aoe].*)(?=^|$|')/'<o>$1/",
|
||||
"xform/^([aoe].*)(?=^|$|')/<o>$1/",
|
||||
"xform/en(?=^|$|')/<w>/",
|
||||
"xform/eng(?=^|$|')/<t>/",
|
||||
"xform/in(?=^|$|')|uai(?=^|$|')/<y>/",
|
||||
"xform/^zh/<u>/",
|
||||
"xform/^sh/<i>/",
|
||||
"xform/'zh/'<u>/",
|
||||
"xform/'sh/'<i>/",
|
||||
"xform/uo(?=^|$|')/<o>/",
|
||||
"xform/ai(?=^|$|')/<p>/",
|
||||
"xform/^ch/<a>/",
|
||||
"xform/'ch/'<a>/",
|
||||
"xform/[iu]ang(?=^|$|')/<g>/",
|
||||
"xform/ang(?=^|$|')/<s>/",
|
||||
"xform/ie(?=^|$|')/<d>/",
|
||||
"xform/ian(?=^|$|')/<f>/",
|
||||
"xform/([a-z>])i?ong(?=^|$|')/$1<h>/",
|
||||
"xform/er(?=^|$|')|iu(?=^|$|')/<j>/",
|
||||
"xform/ei(?=^|$|')/<k>/",
|
||||
"xform/uan(?=^|$|')/<l>/",
|
||||
"xform/ing(?=^|$|')/;/",
|
||||
"xform/ou(?=^|$|')/<z>/",
|
||||
"xform/[iu]a(?=^|$|')/<x>/",
|
||||
"xform/iao(?=^|$|')/<b>/",
|
||||
"xform/ue(?=^|$|')|ui(?=^|$|')|ve(?=^|$|')/<n>/",
|
||||
"xform/un(?=^|$|')/<m>/",
|
||||
"xform/ao(?=^|$|')/<q>/",
|
||||
"xform/an(?=^|$|')/<r>/",
|
||||
"xform/'|<|>//",
|
||||
},
|
||||
|
||||
-- 拼音加加(pyjj)
|
||||
pyjj = {
|
||||
"derive/^([jqxy])u(?=^|$|')/$1v/",
|
||||
"derive/'([jqxy])u(?=^|$|')/'$1v/",
|
||||
"derive/^([aoe])([ioun])(?=^|$|')/$1$1$2/",
|
||||
"derive/'([aoe])([ioun])(?=^|$|')/'$1$1$2/",
|
||||
"xform/^([aoe])(ng)?(?=^|$|')/$1$1$2/",
|
||||
"xform/'([aoe])(ng)?(?=^|$|')/'$1$1$2/",
|
||||
"xform/iu(?=^|$|')/<n>/",
|
||||
"xform/[iu]a(?=^|$|')/<b>/",
|
||||
"xform/[uv]an(?=^|$|')/<c>/",
|
||||
"xform/[uv]e(?=^|$|')|uai(?=^|$|')/<x>/",
|
||||
"xform/ing(?=^|$|')|er(?=^|$|')/<q>/",
|
||||
"xform/^sh/<i>/",
|
||||
"xform/^ch/<u>/",
|
||||
"xform/^zh/<v>/",
|
||||
"xform/'sh/'<i>/",
|
||||
"xform/'ch/'<u>/",
|
||||
"xform/'zh/'<v>/",
|
||||
"xform/uo(?=^|$|')/<o>/",
|
||||
"xform/[uv]n(?=^|$|')/<z>/",
|
||||
"xform/([a-z>])i?ong(?=^|$|')/$1<y>/",
|
||||
"xform/[iu]ang(?=^|$|')/<h>/",
|
||||
"xform/([a-z>])en(?=^|$|')/$1<r>/",
|
||||
"xform/([a-z>])eng(?=^|$|')/$1<t>/",
|
||||
"xform/([a-z>])ang(?=^|$|')/$1<g>/",
|
||||
"xform/ian(?=^|$|')/<j>/",
|
||||
"xform/([a-z>])an(?=^|$|')/$1<f>/",
|
||||
"xform/iao(?=^|$|')/<k>/",
|
||||
"xform/([a-z>])ao(?=^|$|')/$1<d>/",
|
||||
"xform/([a-z>])ai(?=^|$|')/$1<s>/",
|
||||
"xform/([a-z>])ei(?=^|$|')/$1<w>/",
|
||||
"xform/ie(?=^|$|')/<m>/",
|
||||
"xform/ui(?=^|$|')/<v>/",
|
||||
"xform/([a-z>])ou(?=^|$|')/$1<p>/",
|
||||
"xform/in(?=^|$|')/<l>/",
|
||||
"xform/'|<|>//",
|
||||
},
|
||||
|
||||
-- 国标双拼(gbpy)
|
||||
gbpy = {
|
||||
"derive/^([aoe])([ioun])(?=^|$|')/$1$1$2/",
|
||||
"derive/'([aoe])([ioun])(?=^|$|')/'$1$1$2/",
|
||||
"xform/^([aoe])(ng)?(?=^|$|')/$1$1$2/",
|
||||
"xform/'([aoe])(ng)?(?=^|$|')/'$1$1$2/",
|
||||
"xform/iu(?=^|$|')/<y>/",
|
||||
"xform/(.)ei(?=^|$|')/$1<b>/",
|
||||
"xform/uan(?=^|$|')/<w>/",
|
||||
"xform/[uv]e(?=^|$|')/<x>/",
|
||||
"xform/un(?=^|$|')/<z>/",
|
||||
"xform/^sh/<u>/",
|
||||
"xform/^ch/<i>/",
|
||||
"xform/^zh/<v>/",
|
||||
"xform/'sh/'<u>/",
|
||||
"xform/'ch/'<i>/",
|
||||
"xform/'zh/'<v>/",
|
||||
"xform/uo(?=^|$|')/<o>/",
|
||||
"xform/ie(?=^|$|')/<t>/",
|
||||
"xform/([a-z>])i?ong(?=^|$|')/$1<s>/",
|
||||
"xform/ing(?=^|$|')|uai(?=^|$|')/<j>/",
|
||||
"xform/([a-z>])ai(?=^|$|')/$1<k>/",
|
||||
"xform/([a-z>])en(?=^|$|')/$1<r>/",
|
||||
"xform/([a-z>])eng(?=^|$|')/$1<h>/",
|
||||
"xform/[iu]ang(?=^|$|')/<n>/",
|
||||
"xform/([a-z>])ang(?=^|$|')/$1<g>/",
|
||||
"xform/ian(?=^|$|')/<d>/",
|
||||
"xform/([a-z>])an(?=^|$|')/$1<f>/",
|
||||
"xform/([a-z>])ou(?=^|$|')/$1<p>/",
|
||||
"xform/[iu]a(?=^|$|')/<q>/",
|
||||
"xform/iao(?=^|$|')/<m>/",
|
||||
"xform/([a-z>])ao(?=^|$|')/$1<c>/",
|
||||
"xform/ui(?=^|$|')/<v>/",
|
||||
"xform/in(?=^|$|')/<l>/",
|
||||
"xform/'|<|>//",
|
||||
},
|
||||
}
|
||||
|
||||
-- 根据输入法类型选择一套规则(只看 id)
|
||||
local function pick_rules(env)
|
||||
local wanx = get_wanxiang()
|
||||
local id = 'pinyin'
|
||||
if wanx and type(wanx.get_input_method_type) == 'function' then
|
||||
local ok, ret_id = pcall(wanx.get_input_method_type, env)
|
||||
if ok and type(ret_id) == 'string' and #ret_id > 0 then
|
||||
id = ret_id
|
||||
end
|
||||
end
|
||||
return LOCAL_PROJECTION_RULES[id] or LOCAL_PROJECTION_RULES['pinyin'] or {}
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 工具函数
|
||||
------------------------------------------------------------
|
||||
local function alt_lua_punc(s)
|
||||
if s then
|
||||
return s:gsub('([%.%+%-%*%?%[%]%^%$%(%)%%])', '%%%1')
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
-- 仅保留纯小写字母
|
||||
local function is_pure_lower_alpha(s)
|
||||
return type(s) == "string" and s:match("^[a-z]+$") ~= nil
|
||||
end
|
||||
|
||||
local function is_all_upper(s) return s:match('^%u+$') ~= nil end
|
||||
local function is_all_lower(s) return s:match('^%l+$') ~= nil end
|
||||
|
||||
local function add_to_set_list(set_map, list, elem)
|
||||
if not elem or #elem == 0 then return end
|
||||
if not set_map[elem] then
|
||||
set_map[elem] = true
|
||||
table.insert(list, elem)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 规则应用 / 反查逻辑
|
||||
------------------------------------------------------------
|
||||
local function expand_code_variant(code_projection, part)
|
||||
local out, seen = {}, {}
|
||||
local function add(s) add_to_set_list(seen, out, s) end
|
||||
add(part)
|
||||
if code_projection then
|
||||
local p = code_projection:apply(part, true)
|
||||
if p and #p > 0 then add(p) end
|
||||
end
|
||||
local base = {}
|
||||
for i = 1, #out do base[i] = out[i] end
|
||||
for _, s in ipairs(base) do
|
||||
if is_all_upper(s) then add(string.lower(s)) end -- 笔画:仅转小写参与
|
||||
if #s == 4 and is_all_lower(s) then -- 4 小写 → 取 1/3
|
||||
local s13 = s:sub(1,1) .. s:sub(3,3)
|
||||
add(s13)
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
local function build_reverse_group(code_projection, db_table, text)
|
||||
local group, seen = {}, {}
|
||||
for _, db in ipairs(db_table) do
|
||||
local code = db:lookup(text)
|
||||
if code and #code > 0 then
|
||||
for part in code:gmatch('%S+') do
|
||||
local variants = expand_code_variant(code_projection, part)
|
||||
for _, v in ipairs(variants) do add_to_set_list(seen, group, v) end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- 最终清理:只保留纯小写字母
|
||||
local cleaned, seen2 = {}, {}
|
||||
for _, v in ipairs(group) do
|
||||
v = tostring(v)
|
||||
if is_pure_lower_alpha(v) then add_to_set_list(seen2, cleaned, v) end
|
||||
end
|
||||
return cleaned
|
||||
end
|
||||
|
||||
-- 不支持通配;global_match=true 为“包含”,否则“前缀”
|
||||
local function group_match(group, fuma, global_match)
|
||||
if not fuma or #fuma == 0 then return false end
|
||||
local patt = alt_lua_punc(string.lower(fuma))
|
||||
for _, elem in ipairs(group) do
|
||||
local e = string.lower(elem)
|
||||
if global_match then
|
||||
if e:find(patt) then return true end
|
||||
else
|
||||
if e:find('^' .. patt) then return true end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- 单字优先
|
||||
local function handle_long_cand(if_single_char_first, cand, long_word_cands)
|
||||
if if_single_char_first and utf8.len(cand.text) > 1 then
|
||||
table.insert(long_word_cands, cand)
|
||||
else
|
||||
yield(cand)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 过滤器主体
|
||||
------------------------------------------------------------
|
||||
local f = {}
|
||||
|
||||
function f.init(env)
|
||||
local config = env.engine.schema.config
|
||||
|
||||
-- 反查 db
|
||||
env.if_reverse_lookup = false
|
||||
env.db_table = nil
|
||||
local db = config:get_list("wanxiang_lookup/lookup")
|
||||
if db and db.size > 0 then
|
||||
env.db_table = {}
|
||||
for i = 0, db.size - 1 do
|
||||
table.insert(env.db_table, ReverseLookup(db:get_value_at(i).value))
|
||||
end
|
||||
env.if_reverse_lookup = true
|
||||
end
|
||||
if not env.if_reverse_lookup then return end
|
||||
|
||||
-- 内置规则 + 自动选择(不读 schema 的 format)
|
||||
do
|
||||
local rules = pick_rules(env)
|
||||
if type(rules) == 'table' and #rules > 0 then
|
||||
env.code_projection = Projection()
|
||||
env.code_projection:load(rules)
|
||||
else
|
||||
env.code_projection = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- 引导键:优先从 wanxiang_lookup/key 读;否则默认 `
|
||||
env.search_key_str = config:get_string('wanxiang_lookup/key') or '`'
|
||||
env.search_key_alt = alt_lua_punc(env.search_key_str)
|
||||
|
||||
-- tags
|
||||
local tag = config:get_list('wanxiang_lookup/tags')
|
||||
if tag and tag.size > 0 then
|
||||
env.tag = {}
|
||||
for i = 0, tag.size - 1 do
|
||||
table.insert(env.tag, tag:get_value_at(i).value)
|
||||
end
|
||||
else
|
||||
env.tag = { 'abc' }
|
||||
end
|
||||
|
||||
-- 选词接管:词组保留引导码,否则上屏
|
||||
env.notifier = env.engine.context.select_notifier:connect(function(ctx)
|
||||
local input = ctx.input
|
||||
local code = input:match('^(.-)' .. env.search_key_alt)
|
||||
if (not code or #code == 0) then return end
|
||||
local preedit = ctx:get_preedit()
|
||||
local no_search_string = ctx.input:match('^(.-)' .. env.search_key_alt)
|
||||
local edit = preedit.text:match('^(.-)' .. env.search_key_alt)
|
||||
if edit and edit:match('[%w;]') then
|
||||
ctx.input = no_search_string .. env.search_key_str
|
||||
else
|
||||
ctx.input = no_search_string
|
||||
env.commit_code = no_search_string
|
||||
ctx:commit()
|
||||
end
|
||||
end)
|
||||
|
||||
env._group_cache = setmetatable({}, { __mode = 'kv' })
|
||||
end
|
||||
|
||||
function f.func(input, env)
|
||||
if not env.if_reverse_lookup then
|
||||
for cand in input:iter() do yield(cand) end
|
||||
return
|
||||
end
|
||||
|
||||
local code, fuma = env.engine.context.input:match('^(.-)' .. env.search_key_alt .. '(.+)$')
|
||||
if (not code or #code == 0) or (not fuma or #fuma == 0) then
|
||||
for cand in input:iter() do yield(cand) end
|
||||
return
|
||||
end
|
||||
|
||||
-- 双段辅码:a`X`Y(第二段匹配第二字或第一字“包含”)
|
||||
local fuma_2
|
||||
if fuma:find(env.search_key_alt) then
|
||||
fuma, fuma_2 = fuma:match('^(.-)' .. env.search_key_alt .. '(.*)$')
|
||||
end
|
||||
|
||||
local if_single_char_first = env.engine.context:get_option('char_priority')
|
||||
local long_word_cands = {}
|
||||
|
||||
for cand in input:iter() do
|
||||
if cand.type == 'sentence' then goto skip end
|
||||
|
||||
local cand_text = cand.text
|
||||
local text = cand_text
|
||||
local text_2 = nil
|
||||
|
||||
if utf8.len(cand_text) and utf8.len(cand_text) > 1 then
|
||||
text = cand_text:sub(1, utf8.offset(cand_text, 2) - 1)
|
||||
local cand_text_2 = cand_text:gsub('^' .. text, '')
|
||||
text_2 = cand_text_2:sub(1, utf8.offset(cand_text_2, 2) - 1)
|
||||
end
|
||||
|
||||
local group1 = env._group_cache[text]
|
||||
if not group1 then
|
||||
group1 = build_reverse_group(env.code_projection, env.db_table, text)
|
||||
env._group_cache[text] = group1
|
||||
end
|
||||
|
||||
local ok = false
|
||||
if fuma_2 and #fuma_2 > 0 then
|
||||
local group2 = nil
|
||||
if text_2 then
|
||||
group2 = env._group_cache[text_2]
|
||||
if not group2 then
|
||||
group2 = build_reverse_group(env.code_projection, env.db_table, text_2)
|
||||
env._group_cache[text_2] = group2
|
||||
end
|
||||
end
|
||||
ok =
|
||||
group_match(group1, fuma, false) and
|
||||
(
|
||||
(group2 and group_match(group2, fuma_2, false)) or
|
||||
group_match(group1, fuma_2, true) -- 第一字“包含”
|
||||
)
|
||||
else
|
||||
ok = group_match(group1, fuma, false) -- 单段:前缀匹配第一字
|
||||
end
|
||||
|
||||
if ok then
|
||||
handle_long_cand(if_single_char_first, cand, long_word_cands)
|
||||
end
|
||||
::skip::
|
||||
end
|
||||
|
||||
for _, c in ipairs(long_word_cands) do yield(c) end
|
||||
end
|
||||
|
||||
function f.tags_match(seg, env)
|
||||
for _, v in ipairs(env.tag) do if seg.tags[v] then return true end end
|
||||
return false
|
||||
end
|
||||
|
||||
function f.fini(env)
|
||||
if env.if_reverse_lookup and env.notifier then env.notifier:disconnect() end
|
||||
env.db_table = nil
|
||||
env._group_cache = nil
|
||||
collectgarbage('collect')
|
||||
end
|
||||
|
||||
return f
|
||||
250
lua/super_segmentation.lua
Normal file
250
lua/super_segmentation.lua
Normal file
@@ -0,0 +1,250 @@
|
||||
-- super_segmentation.lua
|
||||
--@amzxyz https://github.com/amzxyz/rime_wanxiang
|
||||
-- 规则:
|
||||
-- 1) 第 1 个 ':仅记录“现场”(baseline_head=当前整段输入,含你之前的手动分隔),记录起点索引,不重建
|
||||
-- 2) 第 2 个 ' 起:开始循环
|
||||
-- - 命中起点 s:只循环 s 后面的 m-1 个形态(跳过 s 本身)
|
||||
-- - 未命中:从 all[1] 开始循环 m 个形态
|
||||
-- 3) 走完一圈:恢复到 baseline_head,并尾部只保留 1 个 '
|
||||
-- 4) 支持 N=3..8(可扩展 PATTERNS)
|
||||
-- 5) 使用 update_notifier 预缓存可见分段,避免移动端“晚一拍”
|
||||
|
||||
local K_REJECT, K_ACCEPT, K_NOOP = 0, 1, 2
|
||||
local M = {}
|
||||
|
||||
-- ---------- utils ----------
|
||||
local function escp(ch) return ch:gsub("(%W)","%%%1") end
|
||||
local function sum(a) local s=0; for _,v in ipairs(a) do s=s+v end; return s end
|
||||
local function key_of(a) return table.concat(a, ",") end
|
||||
local function find_idx(list, key) for i,t in ipairs(list) do if key_of(t)==key then return i end end end
|
||||
local function count_trailing(s, ch) local n=0; for i=#s,1,-1 do if s:sub(i,i)==ch then n=n+1 else break end end; return n end
|
||||
local function strip_trailing(s, ch) return (s:gsub(escp(ch).."+$","")) end
|
||||
|
||||
-- 去掉手动与自动分隔符,得到“纯编码”
|
||||
local function strip_delims(s, md, ad)
|
||||
if md and md~="" then s = s:gsub(escp(md),"") end
|
||||
if ad and ad~="" then s = s:gsub(escp(ad),"") end
|
||||
return s
|
||||
end
|
||||
|
||||
-- 依据分组把 core 插入手动分隔符重建
|
||||
local function build_by_groups(core, ch_manual, groups)
|
||||
if not groups or #groups==0 or sum(groups)~=#core then return core end
|
||||
local out, i = {}, 1
|
||||
for gi,g in ipairs(groups) do
|
||||
out[#out+1] = core:sub(i, i+g-1); i = i + g
|
||||
if gi < #groups then out[#out+1] = ch_manual end
|
||||
end
|
||||
return table.concat(out)
|
||||
end
|
||||
|
||||
-- 从字符串解析分段长度(空格或 ' 都视为可见分隔)
|
||||
local function lens_from_string(s, md, ad)
|
||||
if not s or s=="" then return nil end
|
||||
local segs, buf = {}, {}
|
||||
local function flush() if #buf>0 then segs[#segs+1]=table.concat(buf); buf={} end end
|
||||
for i=1,#s do
|
||||
local c=s:sub(i,i)
|
||||
if c==md or c==ad or c==" " then
|
||||
flush()
|
||||
else
|
||||
local b=string.byte(c)
|
||||
if b and ((b>=65 and b<=90) or (b>=97 and b<=122)) then
|
||||
buf[#buf+1]=string.char(b):lower()
|
||||
end
|
||||
end
|
||||
end
|
||||
flush()
|
||||
if #segs==0 then return nil end
|
||||
local L={}; for _,seg in ipairs(segs) do L[#L+1]=#seg end
|
||||
return L
|
||||
end
|
||||
|
||||
-- —— 缓存读取:优先用通知器缓存的 lens,其次现场计算 ——
|
||||
local function get_cached_lens(env, ctx, md, ad)
|
||||
local L = env._last_preedit_lens
|
||||
if L and type(L)=="table" and #L>0 then return L end
|
||||
local seg = ctx.composition:back()
|
||||
local cand = seg and seg:get_selected_candidate() or nil
|
||||
return lens_from_string(cand and cand.preedit or nil, md, ad)
|
||||
end
|
||||
|
||||
-- ---------- patterns ----------
|
||||
local PATTERNS = {
|
||||
[3] = { all = { {2,1}, {1,2} } },
|
||||
[4] = { all = { {2,2}, {1,3}, {3,1} } },
|
||||
[5] = { all = { {2,3}, {3,2} } },
|
||||
[6] = { all = { {2,2,2}, {3,3} } },
|
||||
[7] = { all = { {2,2,3}, {2,3,2}, {3,2,2} } },
|
||||
[8] = { all = { {2,2,2,2}, {2,3,3}, {3,2,3}, {3,3,2} } },
|
||||
[10] = { all = { {2,2,2,2,2} } },
|
||||
[12] = { all = { {2,2,2,2,2,2} } },
|
||||
}
|
||||
|
||||
-- ---------- session state ----------
|
||||
local function reset_session(env)
|
||||
env._ss_core_letters = nil -- 纯编码(去分隔)
|
||||
env._ss_start_idx = nil -- 起点索引(1..m),未命中则 0
|
||||
env._ss_N = nil
|
||||
env._ss_baseline_head = nil -- 基线:包含你之前的手动分隔/空格
|
||||
end
|
||||
local function ulen(s)
|
||||
if not s or s == "" then return 0 end
|
||||
if utf8 and utf8.len then
|
||||
local ok, n = pcall(utf8.len, s)
|
||||
if ok and n then return n end
|
||||
end
|
||||
-- 兜底:简单按 UTF-8 码点数
|
||||
local n = 0
|
||||
if utf8 and utf8.codes then
|
||||
for _ in utf8.codes(s) do n = n + 1 end
|
||||
return n
|
||||
end
|
||||
-- 再兜底:直接 #s(有误差,但总比没有好)
|
||||
return #s
|
||||
end
|
||||
function M.init(env)
|
||||
local cfg = env.engine.schema.config
|
||||
local delimiter = cfg:get_string("speller/delimiter") or " '"
|
||||
if #delimiter < 2 then delimiter = " '" end
|
||||
env.auto_delim = delimiter:sub(1,1) -- 通常空格
|
||||
env.manual_delim = delimiter:sub(2,2) -- 通常单引号
|
||||
|
||||
-- 缓存最新一帧的可见分段与输入
|
||||
env._upd_conn = env.engine.context.update_notifier:connect(function(ctx)
|
||||
local seg = ctx.composition:back()
|
||||
local cand = seg and seg:get_selected_candidate() or nil
|
||||
local pre = cand and cand.preedit or nil
|
||||
env._last_preedit_lens = lens_from_string(pre, env.manual_delim, env.auto_delim)
|
||||
env._last_input_head = ctx.input
|
||||
env._last_input_for_caret = ctx.input
|
||||
env._last_caret_pos = ctx.caret_pos
|
||||
end)
|
||||
|
||||
reset_session(env)
|
||||
end
|
||||
|
||||
function M.fini(env)
|
||||
if env._upd_conn then env._upd_conn:disconnect(); env._upd_conn=nil end
|
||||
end
|
||||
|
||||
-- ---------- main ----------
|
||||
function M.func(key_event, env)
|
||||
if key_event:release() then return K_NOOP end
|
||||
|
||||
local ctx = env.engine.context
|
||||
if ctx.composition:empty() then return K_NOOP end
|
||||
|
||||
local md = env.manual_delim or "'"
|
||||
local ad = env.auto_delim or " "
|
||||
|
||||
-- 只处理手动分隔符键
|
||||
if key_event.keycode ~= string.byte(md) then
|
||||
reset_session(env); return K_NOOP
|
||||
end
|
||||
--用「上一帧」的光标位置判断是不是在中间编辑
|
||||
do
|
||||
local last_input = env._last_input_for_caret or ctx.input or ""
|
||||
local last_caret = env._last_caret_pos
|
||||
|
||||
local total_len = ulen(last_input)
|
||||
-- 只有「上一帧光标在末尾」我们才认定在玩超分段
|
||||
if not last_caret or last_caret ~= total_len then
|
||||
-- 上一帧光标不在末尾:说明用户在中间编辑,这次 ' 交给默认逻辑
|
||||
reset_session(env)
|
||||
return K_NOOP
|
||||
end
|
||||
end
|
||||
-- 把这次 ' 并入输入,统计尾部 ' 数
|
||||
local before = ctx.input or ""
|
||||
local after = before .. md
|
||||
local tlen = count_trailing(after, md)
|
||||
|
||||
-- 去掉末尾 ' 串,得到 head(本次按键前的完整输入)与 core(纯编码)
|
||||
local head = strip_trailing(after, md)
|
||||
local core = strip_delims(head, md, ad)
|
||||
local N = #core
|
||||
local conf = PATTERNS[N]
|
||||
|
||||
-- 若核心/长度变化,重置会话
|
||||
if env._ss_core_letters ~= core or env._ss_N ~= N then
|
||||
env._ss_core_letters = core
|
||||
env._ss_N = N
|
||||
env._ss_start_idx = nil
|
||||
env._ss_baseline_head = nil
|
||||
end
|
||||
|
||||
-- 只要本轮还没记过,就立刻记录“基线 + 起点”(无论 tlen==1 还是 tlen>=2)
|
||||
if env._ss_baseline_head == nil then
|
||||
env._ss_baseline_head = head -- 保留你原有的空格或手动 '
|
||||
end
|
||||
if conf and env._ss_start_idx == nil then
|
||||
local start_idx = 0
|
||||
-- 先用缓存的可见分段;不行就直接用 head 切分(可避免“23 又走到 23'”的伪步骤)
|
||||
local L = get_cached_lens(env, ctx, md, ad)
|
||||
if not (L and sum(L)==N) then
|
||||
L = lens_from_string(head, md, ad)
|
||||
end
|
||||
if L and sum(L)==N then
|
||||
local idx = find_idx(conf.all, key_of(L))
|
||||
if idx then start_idx = idx end
|
||||
end
|
||||
env._ss_start_idx = start_idx
|
||||
end
|
||||
|
||||
-- 第 1 个 ' :仅记录,不重建
|
||||
if tlen == 1 then
|
||||
ctx.input = after
|
||||
return K_ACCEPT
|
||||
end
|
||||
|
||||
-- 第 2 个 ' 起:循环(若无该长度配置,直接接纳输入)
|
||||
if not conf then
|
||||
ctx.input = after
|
||||
return K_ACCEPT
|
||||
end
|
||||
|
||||
local m = #conf.all
|
||||
local k = tlen - 1 -- 从第二个 ' 开始计数
|
||||
|
||||
-- 恢复:回到第一拍记录的 baseline(保留空格/已有 '),尾部只留 1 个 '
|
||||
local function restore()
|
||||
local baseline = env._ss_baseline_head or head
|
||||
ctx.input = baseline .. md
|
||||
reset_session(env)
|
||||
env._ss_core_letters = core
|
||||
env._ss_N = N
|
||||
end
|
||||
|
||||
if env._ss_start_idx and env._ss_start_idx ~= 0 then
|
||||
-- 命中起点:只循环后续 m-1 个形态,跳过当前形态
|
||||
local variants_count = m - 1
|
||||
local cycle_len = variants_count + 1
|
||||
local r = k % cycle_len
|
||||
if r == 0 then
|
||||
restore(); return K_ACCEPT
|
||||
else
|
||||
local idx = ((env._ss_start_idx - 1 + r) % m) + 1 -- 跳过起点本身
|
||||
local groups = conf.all[idx]
|
||||
local rebuilt = build_by_groups(core, md, groups)
|
||||
ctx.input = rebuilt .. md:rep(tlen)
|
||||
return K_ACCEPT
|
||||
end
|
||||
else
|
||||
-- 未命中起点:从 all[1] 开始循环 m 个形态
|
||||
local variants_count = m
|
||||
local cycle_len = variants_count + 1
|
||||
local r = k % cycle_len
|
||||
if r == 0 then
|
||||
restore(); return K_ACCEPT
|
||||
else
|
||||
local idx = ((r - 1) % m) + 1
|
||||
local groups = conf.all[idx]
|
||||
local rebuilt = build_by_groups(core, md, groups)
|
||||
ctx.input = rebuilt .. md:rep(tlen)
|
||||
return K_ACCEPT
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return { init = M.init, fini = M.fini, func = M.func }
|
||||
734
lua/super_sequence.lua
Normal file
734
lua/super_sequence.lua
Normal file
@@ -0,0 +1,734 @@
|
||||
-- 万象拼音 · 手动自由排序
|
||||
-- 核心规则: 向前移动 = "Control+j", 向后移动 = "Control+k", 重置 = "Control+l", 置顶 = "Control+p
|
||||
-- 1) p>0:有效排序(DB upsert + 导出)
|
||||
-- 2) p=0:墓碑(DB 删除 + 导出墓碑)
|
||||
-- 3) 初始化:先 flush 本机增量到导出 → 外部合并(所有设备文件+本机DB,LWW) → 重写本机导出(含墓碑) → 导入覆盖DB,p=0删除键,不导入
|
||||
-- 4) 关于同步的使用方法:先点击同步确保同步目录已经创建,建立sequence_device_list.txt设备清单,内部填写不同设备导出文件名称
|
||||
-- sequence_ff9b2823-8733-44bb-a497-daf382b74ca5.txt
|
||||
-- sequence_deepin.txt
|
||||
-- 可能是自定义名称,可能是随机串号
|
||||
-- sequence_开头,后面跟着installation_id,这个参数来自用户目录installation.yaml
|
||||
-- 清单有什么文件就会读取什么文件
|
||||
-- 仅使用 installation.yaml 的 sync_dir;读不到就回退到 user_dir/sync
|
||||
-- 核心规则: 向前移动 = "Control+j", 向后移动 = "Control+k", 重置 = "Control+l", 置顶 = "Control+p"
|
||||
-- 1) p>0:有效排序(DB upsert + 导出)
|
||||
-- 2) p=0:墓碑(DB 删除 + 导出墓碑)
|
||||
-- 3) 初始化:先 flush 本机增量到导出 → 外部合并(所有设备文件+本机DB,LWW) → 重写本机导出(含墓碑) → 导入覆盖DB,p=0删除键,不导入
|
||||
-- 4) 同步路径策略:能从 installation.yaml 读取到 sync_dir 就用它;读不到才用默认 user_dir/sync
|
||||
|
||||
local wanxiang = require("wanxiang")
|
||||
local userdb = require("lib/userdb")
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 一、常量与键位
|
||||
------------------------------------------------------------
|
||||
local DEFAULT_SEQ_KEY = { up = "Control+j", down = "Control+k", reset = "Control+l", pin = "Control+p" }
|
||||
local SYNC_FILE_PREFIX, SYNC_FILE_SUFFIX = "sequence", ".txt"
|
||||
|
||||
-- 运行期是否立刻写出到导出文件(只在重新部署时写出→设为 false)
|
||||
local RUNTIME_EXPORT = false
|
||||
|
||||
-- ☆☆ 前向声明,避免被当作全局导致 nil ☆☆
|
||||
local _normalize_path, _is_abs_path, _path_join, _manifest_path
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 二、通用工具(仅处理 "\" 与 "\\", 统一成 "/")
|
||||
------------------------------------------------------------
|
||||
_normalize_path = function(p)
|
||||
if not p or p == "" then return "" end
|
||||
if p:sub(1, 2) == "\\\\" then
|
||||
-- UNC:\\server\share\foo -> //server/share/foo
|
||||
return "//" .. p:sub(3):gsub("\\", "/"):gsub("/+", "/")
|
||||
else
|
||||
-- 普通:D:\dir\\file -> D:/dir/file
|
||||
return p:gsub("\\", "/"):gsub("/+", "/")
|
||||
end
|
||||
end
|
||||
|
||||
_is_abs_path = function(p)
|
||||
p = _normalize_path(p)
|
||||
return p:sub(1, 2) == "//" or p:match("^[A-Za-z]:/")
|
||||
end
|
||||
|
||||
_path_join = function(a, b)
|
||||
a = _normalize_path(a)
|
||||
b = _normalize_path(b)
|
||||
if not a or a == "" then return b end
|
||||
if not b or b == "" then return a end
|
||||
if _is_abs_path(b) then return b end
|
||||
if a:sub(-1) ~= "/" then a = a .. "/" end
|
||||
return a .. b
|
||||
end
|
||||
|
||||
_manifest_path = function(dir)
|
||||
return _path_join(dir, "sequence_device_list.txt")
|
||||
end
|
||||
|
||||
local function _read_lines(path)
|
||||
local t, f = {}, io.open(path, "r")
|
||||
if not f then return t end
|
||||
for line in f:lines() do t[#t + 1] = line end
|
||||
f:close()
|
||||
return t
|
||||
end
|
||||
|
||||
local function _write_lines(path, lines)
|
||||
local f = io.open(path, "w"); if not f then return false end
|
||||
for _, line in ipairs(lines) do f:write(line, "\n") end
|
||||
f:close()
|
||||
return true
|
||||
end
|
||||
|
||||
local function _trim(s) return (s:gsub("^%s+", ""):gsub("%s+$", "")) end
|
||||
local function _file_exists(path)
|
||||
if not path or path == "" then return false end
|
||||
local f = io.open(path, "r"); if f then f:close(); return true end
|
||||
return false
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 三、安装信息 & 同步目录(仅看 YAML;读不到就默认)
|
||||
------------------------------------------------------------
|
||||
local function _read_installation_yaml()
|
||||
local user_dir = rime_api.get_user_data_dir()
|
||||
if not user_dir or user_dir == "" then return nil, nil end
|
||||
local path = _path_join(user_dir, "installation.yaml")
|
||||
local f = io.open(path, "r"); if not f then return nil, nil end
|
||||
local installation_id, sync_dir
|
||||
for line in f:lines() do
|
||||
line = line:gsub("%s+#.*$", "")
|
||||
local key, val = line:match("^%s*([%w_]+)%s*:%s*(.+)$")
|
||||
if key and val then
|
||||
-- 去引号
|
||||
val = val:gsub('^%s*"(.*)"%s*$', "%1"):gsub("^%s*'(.*)'%s*$", "%1")
|
||||
val = val:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
if key == "installation_id" then
|
||||
installation_id = val
|
||||
elseif key == "sync_dir" then
|
||||
sync_dir = _normalize_path(val)
|
||||
end
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
return installation_id, sync_dir
|
||||
end
|
||||
|
||||
-- 只看 installation.yaml,读到就用;读不到就 user_dir/sync
|
||||
local function _sync_dir()
|
||||
local user_dir = rime_api.get_user_data_dir() or ""
|
||||
local _, ysync = _read_installation_yaml()
|
||||
|
||||
local function fix(x)
|
||||
if not x or x == "" then return "" end
|
||||
if x == "sync" then
|
||||
return (user_dir ~= "" and _path_join(user_dir, "sync")) or "sync"
|
||||
end
|
||||
return _normalize_path(x)
|
||||
end
|
||||
|
||||
if ysync and ysync ~= "" then
|
||||
return fix(ysync)
|
||||
end
|
||||
return _path_join(user_dir, "sync")
|
||||
end
|
||||
|
||||
local function _sync_ready()
|
||||
local install_id, ysync = _read_installation_yaml()
|
||||
local user_dir = rime_api.get_user_data_dir() or ""
|
||||
local dir
|
||||
if ysync and ysync ~= "" then
|
||||
dir = _normalize_path(ysync)
|
||||
if dir == "sync" then dir = _path_join(user_dir, "sync") end
|
||||
else
|
||||
dir = _path_join(user_dir, "sync")
|
||||
end
|
||||
local ok = (install_id and install_id ~= "") and (dir and dir ~= "")
|
||||
return ok, dir, install_id
|
||||
end
|
||||
|
||||
local function _detect_device_name()
|
||||
local installation_id = select(1, _read_installation_yaml())
|
||||
local function _san(s) return tostring(s):gsub("[%s/\\:%*%?\"<>|]", "_") end
|
||||
if installation_id and installation_id ~= "" then return _san(installation_id) end
|
||||
local dir = _sync_dir()
|
||||
for _, raw in ipairs(_read_lines(_manifest_path(dir))) do
|
||||
local name = _trim(raw or "")
|
||||
local m = name:match("^sequence_(.+)%.txt$")
|
||||
if m and not _is_abs_path(name) then return _san(m) end
|
||||
end
|
||||
return "device"
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 四、时间
|
||||
------------------------------------------------------------
|
||||
local function get_timestamp()
|
||||
local ms = type(rime_api.get_time_ms) == "function" and tonumber(rime_api.get_time_ms()) or nil
|
||||
return ms and (os.time() + ms / 1000.0) or os.time()
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 五、DB 与状态
|
||||
------------------------------------------------------------
|
||||
local seq_db = userdb.LevelDb("lua/sequence")
|
||||
|
||||
local seq_property = {
|
||||
ADJUST_KEY = "sequence_adjustment_code",
|
||||
}
|
||||
---@param context Context
|
||||
function seq_property.get(context)
|
||||
return context:get_property(seq_property.ADJUST_KEY)
|
||||
end
|
||||
|
||||
---@param context Context
|
||||
function seq_property.reset(context)
|
||||
local code = seq_property.get(context)
|
||||
if code ~= nil and code ~= "" then
|
||||
context:set_property(seq_property.ADJUST_KEY, "")
|
||||
end
|
||||
end
|
||||
|
||||
local curr_state = {}
|
||||
curr_state.ADJUST_MODE = { None = -1, Reset = 0, Pin = 1, Adjust = 2 }
|
||||
curr_state.default = {
|
||||
selected_phrase = nil, offset = 0, mode = curr_state.ADJUST_MODE.None,
|
||||
highlight_index = nil, adjust_code = nil, adjust_key = nil,
|
||||
dirty = false, last_dirty_ts = 0,
|
||||
}
|
||||
function curr_state.reset()
|
||||
if curr_state.mode == curr_state.ADJUST_MODE.None then return end
|
||||
for k, v in pairs(curr_state.default) do curr_state[k] = v end
|
||||
end
|
||||
function curr_state.is_pin_mode() return curr_state.mode == curr_state.ADJUST_MODE.Pin end
|
||||
function curr_state.is_reset_mode() return curr_state.mode == curr_state.ADJUST_MODE.Reset end
|
||||
function curr_state.is_adjust_mode() return curr_state.mode == curr_state.ADJUST_MODE.Adjust end
|
||||
function curr_state.has_adjustment() return curr_state.mode ~= curr_state.ADJUST_MODE.None end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 六、关键日志(精简)
|
||||
------------------------------------------------------------
|
||||
--[[
|
||||
local function _print_sync_probe(phase)
|
||||
local user_dir = tostring(rime_api.get_user_data_dir() or "")
|
||||
local iid, ysync = _read_installation_yaml()
|
||||
local chosen = _sync_dir()
|
||||
local inst_yaml = _path_join(user_dir, "installation.yaml")
|
||||
log.warning(string.format(
|
||||
"[sequence][%s] installation_id=%s yaml_sync_dir=%s chosen_sync_dir=%s inst_yaml=%s exists=%s",
|
||||
phase, tostring(iid), tostring(ysync), tostring(chosen),
|
||||
inst_yaml, tostring(_file_exists(inst_yaml))
|
||||
))
|
||||
end
|
||||
|
||||
local function _debug_paths_once()
|
||||
local dir = _sync_dir()
|
||||
local device_name = _detect_device_name()
|
||||
local export_name = string.format("%s_%s%s", SYNC_FILE_PREFIX, device_name, SYNC_FILE_SUFFIX)
|
||||
local export_path = _path_join(dir, export_name)
|
||||
log.info(string.format("[sequence] chosen_sync_dir=%s manifest_exists=%s",
|
||||
tostring(dir), tostring(_file_exists(_manifest_path(dir)))))
|
||||
log.info(string.format("[sequence] export_path=%s exists=%s",
|
||||
tostring(export_path), tostring(_file_exists(export_path))))
|
||||
end ]]--
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 七、记录解析(新格式)
|
||||
------------------------------------------------------------
|
||||
local function parse_adjustment_value_item(value_item)
|
||||
local item, p, o, t = value_item:match("i=(.+) p=(%S+) o=(%S*) t=(%S+)")
|
||||
if not item then return nil, nil end
|
||||
return item, { fixed_position = tonumber(p) or 0, offset = tonumber(o) or 0, updated_at = tonumber(t) }
|
||||
end
|
||||
|
||||
local function parse_adjustment_values(values_str)
|
||||
local mp = {}
|
||||
for seg in values_str:gmatch("[^\t]+") do
|
||||
local item, adj = parse_adjustment_value_item(seg)
|
||||
if item then mp[item] = adj end
|
||||
end
|
||||
return next(mp) and mp or nil
|
||||
end
|
||||
|
||||
local function get_input_adjustments(input)
|
||||
if not input or input == "" then return nil end
|
||||
local value_str = seq_db:fetch(input)
|
||||
return value_str and parse_adjustment_values(value_str) or nil
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 八、导出缓冲(去重 + 节流)
|
||||
------------------------------------------------------------
|
||||
local seq_data = {
|
||||
status = "pending",
|
||||
device_name = "device",
|
||||
last_export_ts = 0,
|
||||
export_interval = 1.2, -- 秒
|
||||
pending_map = {}, -- key: input.."\t"..item => line
|
||||
}
|
||||
|
||||
local function _pending_count() local n = 0; for _ in pairs(seq_data.pending_map) do n = n + 1 end; return n end
|
||||
|
||||
function seq_data._current_paths()
|
||||
local dir = _sync_dir()
|
||||
local device_name = seq_data.device_name or "device"
|
||||
local export_name = string.format("%s_%s%s", SYNC_FILE_PREFIX, device_name, SYNC_FILE_SUFFIX)
|
||||
local export_path = _path_join(dir, export_name)
|
||||
local manifest = _manifest_path(dir)
|
||||
return dir, device_name, export_name, export_path, manifest
|
||||
end
|
||||
|
||||
function seq_data._ensure_export_file()
|
||||
local ok = _sync_ready()
|
||||
if not ok then
|
||||
--log.info("[sequence] installation_id 或 sync_dir 缺失,跳过导出")
|
||||
return false
|
||||
end
|
||||
local _, _, export_name, export_path, manifest = seq_data._current_paths()
|
||||
if not _file_exists(manifest) then
|
||||
local mf = io.open(manifest, "w"); if not mf then return false end; mf:close()
|
||||
end
|
||||
if not _file_exists(export_path) then
|
||||
local f = io.open(export_path, "w"); if not f then return false end
|
||||
local user_id = wanxiang.get_user_id()
|
||||
if user_id then f:write("\001/user_id\t", user_id, "\n") end
|
||||
f:write("\001/device_name\t", seq_data.device_name or "device", "\n")
|
||||
f:close()
|
||||
end
|
||||
local names = _read_lines(manifest)
|
||||
local seen = {}; for _, n in ipairs(names) do seen[_trim(n)] = true end
|
||||
if not seen[export_name] then names[#names + 1] = export_name; _write_lines(manifest, names) end
|
||||
return true
|
||||
end
|
||||
|
||||
local function _enqueue_export(input, item, adj)
|
||||
local k = input .. "\t" .. item
|
||||
seq_data.pending_map[k] = string.format("%s\ti=%s p=%s o=%s t=%s\n",
|
||||
input, item, adj.fixed_position or 0, adj.offset or 0, adj.updated_at or "")
|
||||
end
|
||||
|
||||
function seq_data.flush_pending(max_lines)
|
||||
if _pending_count() == 0 then return end
|
||||
if not seq_data._ensure_export_file() then return end
|
||||
local _, _, _, export_path = seq_data._current_paths()
|
||||
local f = io.open(export_path, "a"); if not f then return end
|
||||
local wrote = 0
|
||||
for _, line in pairs(seq_data.pending_map) do
|
||||
if max_lines and wrote >= max_lines then break end
|
||||
f:write(line); wrote = wrote + 1
|
||||
end
|
||||
f:close()
|
||||
seq_data.pending_map = {}
|
||||
end
|
||||
|
||||
function seq_data.maybe_export(force)
|
||||
if force then
|
||||
seq_data.flush_pending(nil)
|
||||
seq_data.last_export_ts = get_timestamp()
|
||||
return
|
||||
end
|
||||
if _pending_count() == 0 then return end
|
||||
local now = get_timestamp()
|
||||
if now - (seq_data.last_export_ts or 0) < (seq_data.export_interval or 1.2) then return end
|
||||
seq_data.flush_pending(200)
|
||||
seq_data.last_export_ts = now
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 九、保存(本机操作):p=0 也导出墓碑(运行期不写盘;DB 暂存墓碑以便重部署覆盖)
|
||||
------------------------------------------------------------
|
||||
local function save_adjustment(input, item, adjustment, no_export)
|
||||
if not input or input == "" or not item or item == "" then return end
|
||||
local p = tonumber(adjustment.fixed_position) or 0
|
||||
local o = tonumber(adjustment.offset) or 0
|
||||
local t = adjustment.updated_at
|
||||
|
||||
local mp = get_input_adjustments(input) or {}
|
||||
if p <= 0 then
|
||||
-- 关键:DB 内也保留 p=0 墓碑(含时间戳),用于重部署时 LWW 覆盖外部文件
|
||||
mp[item] = { fixed_position = 0, offset = o, updated_at = t }
|
||||
else
|
||||
mp[item] = { fixed_position = p, offset = o, updated_at = t }
|
||||
end
|
||||
|
||||
local arr = {}
|
||||
for it, a in pairs(mp) do
|
||||
arr[#arr + 1] = string.format("i=%s p=%s o=%s t=%s",
|
||||
it, a.fixed_position, a.offset or 0, a.updated_at or "")
|
||||
end
|
||||
seq_db:update(input, table.concat(arr, "\t"))
|
||||
|
||||
-- 仅在允许运行期写出时才入队(默认 RUNTIME_EXPORT=false,不入队)
|
||||
if (not no_export) and RUNTIME_EXPORT then
|
||||
_enqueue_export(input, item, { fixed_position = p, offset = o, updated_at = t }) -- 包含 p=0 墓碑
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 十、合并器:收集“所有文件 + 本机DB”,按 t 取最新(包含 p=0)
|
||||
------------------------------------------------------------
|
||||
local function _keep_latest(latest, input, item, adj)
|
||||
latest[input] = latest[input] or {}
|
||||
local prev = latest[input][item]
|
||||
if (not prev) or ((adj.updated_at or 0) > (prev.updated_at or 0)) then
|
||||
latest[input][item] = {
|
||||
fixed_position = tonumber(adj.fixed_position) or 0,
|
||||
offset = tonumber(adj.offset) or 0,
|
||||
updated_at = tonumber(adj.updated_at) or 0
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function collect_latest_from_all_sources()
|
||||
local latest = {}
|
||||
|
||||
-- A) 本机 DB(包含 p=0 墓碑:让 DB 能覆盖外部)
|
||||
seq_db:query_with("", function(key, value)
|
||||
local mp = parse_adjustment_values(value)
|
||||
if mp then
|
||||
for item, a in pairs(mp) do
|
||||
_keep_latest(latest, key, item, a)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- B) 清单里的所有导出文件(包含 p=0)
|
||||
local dir = _sync_dir()
|
||||
local names = _read_lines(_manifest_path(dir))
|
||||
for _, raw in ipairs(names) do
|
||||
local name = _trim(raw or "")
|
||||
if name ~= "" and name:sub(1, 1) ~= "#" then
|
||||
if name:sub(1, #SYNC_FILE_PREFIX) == SYNC_FILE_PREFIX
|
||||
and name:sub(-#SYNC_FILE_SUFFIX) == SYNC_FILE_SUFFIX then
|
||||
local path = _is_abs_path(name) and name or _path_join(dir, name)
|
||||
local f = io.open(path, "r")
|
||||
if f then
|
||||
for line in f:lines() do
|
||||
if line ~= "" and line:sub(1, 2) ~= "\001" .. "/" then
|
||||
local key, value = line:match("^(%S+)\t(.+)$")
|
||||
if key and value then
|
||||
local item, adj1 = parse_adjustment_value_item(value)
|
||||
if item then
|
||||
_keep_latest(latest, key, item, adj1)
|
||||
else
|
||||
local mp = parse_adjustment_values(value)
|
||||
if mp then for it, a in pairs(mp) do _keep_latest(latest, key, it, a) end end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return latest
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 十一、把“合并结果”重写到我机导出(含 p=0)
|
||||
------------------------------------------------------------
|
||||
local function rewrite_export_from_latest(latest)
|
||||
local ok = _sync_ready()
|
||||
if not ok then return end
|
||||
local dir = _sync_dir()
|
||||
local installation_id = select(1, _read_installation_yaml())
|
||||
local device_name = (installation_id and installation_id ~= "") and tostring(installation_id):gsub("[%s/\\:%*%?\"<>|]", "_") or "device"
|
||||
local export_name = string.format("%s_%s%s", SYNC_FILE_PREFIX, device_name, SYNC_FILE_SUFFIX)
|
||||
local export_path = _path_join(dir, export_name)
|
||||
local manifest = _manifest_path(dir)
|
||||
|
||||
if not _file_exists(manifest) then local mf = io.open(manifest, "w"); if mf then mf:close() end end
|
||||
do
|
||||
local names = _read_lines(manifest); local seen = {}; for _, n in ipairs(names) do seen[_trim(n)] = true end
|
||||
if not seen[export_name] then names[#names + 1] = export_name; _write_lines(manifest, names) end
|
||||
end
|
||||
|
||||
local f = io.open(export_path, "w"); if not f then return end
|
||||
local user_id = wanxiang.get_user_id()
|
||||
if user_id then f:write("\001/user_id\t", user_id, "\n") end
|
||||
f:write("\001/device_name\t", device_name, "\n")
|
||||
|
||||
local inputs = {}
|
||||
for input, _ in pairs(latest) do inputs[#inputs + 1] = input end
|
||||
table.sort(inputs)
|
||||
for _, input in ipairs(inputs) do
|
||||
local items, keys = latest[input], {}
|
||||
for item, _ in pairs(items) do keys[#keys + 1] = item end
|
||||
table.sort(keys)
|
||||
for _, item in ipairs(keys) do
|
||||
local a = items[item]
|
||||
f:write(string.format("%s\ti=%s p=%s o=%s t=%s\n",
|
||||
input, item, a.fixed_position or 0, a.offset or 0, a.updated_at or ""))
|
||||
end
|
||||
end
|
||||
|
||||
f:close()
|
||||
--log.info(string.format("[sequence] export rewritten (merged LWW, incl tombstones): %s", export_path))
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 十二、把“合并结果”导入覆盖 DB(p<=0 删)
|
||||
------------------------------------------------------------
|
||||
local function apply_latest_to_db(latest)
|
||||
local updated_keys = 0
|
||||
for input, kv in pairs(latest) do
|
||||
local keep = {}
|
||||
for item, a in pairs(kv) do
|
||||
if (tonumber(a.fixed_position) or 0) > 0 then
|
||||
keep[item] = { fixed_position = a.fixed_position, offset = a.offset or 0, updated_at = a.updated_at }
|
||||
end
|
||||
end
|
||||
if next(keep) == nil then
|
||||
seq_db:erase(input)
|
||||
else
|
||||
local arr = {}
|
||||
for item, a in pairs(keep) do
|
||||
arr[#arr + 1] = string.format("i=%s p=%s o=%s t=%s", item, a.fixed_position, a.offset or 0, a.updated_at or "")
|
||||
end
|
||||
seq_db:update(input, table.concat(arr, "\t"))
|
||||
end
|
||||
updated_keys = updated_keys + 1
|
||||
end
|
||||
--log.info(string.format("[sequence] DB applied from merged LWW: %d keys", updated_keys))
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 十三、初始化:先导出→合并→重写导出→导入DB
|
||||
------------------------------------------------------------
|
||||
local function init_once()
|
||||
-- 1) 先导出:把本机 pending 增量写出去(如果是旧版本留下的队列,这里可一次性落盘;RUNTIME_EXPORT 与此无关)
|
||||
seq_data._ensure_export_file()
|
||||
seq_data.maybe_export(true)
|
||||
|
||||
-- 2) 外部合并(所有设备文件 + 本机 DB),LWW(含 p=0)
|
||||
local latest = collect_latest_from_all_sources()
|
||||
|
||||
-- 3) 用合并结果重写我机导出(包含 p=0)——始终写盘
|
||||
rewrite_export_from_latest(latest)
|
||||
|
||||
-- 4) 导入合并结果覆盖 DB(p<=0 删)
|
||||
apply_latest_to_db(latest)
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 十四、Pipeline:P / F
|
||||
------------------------------------------------------------
|
||||
local P = {}
|
||||
function P.init(env)
|
||||
seq_db:open()
|
||||
seq_data.device_name = _detect_device_name()
|
||||
--_print_sync_probe("init") -- 关键:一次性输出最终使用的 sync_dir
|
||||
--_debug_paths_once() -- 关键:简要输出导出与清单路径是否存在
|
||||
init_once()
|
||||
end
|
||||
|
||||
local function process_adjustment(context)
|
||||
local c = context:get_selected_candidate()
|
||||
curr_state.selected_phrase = c and c.text or nil
|
||||
context:refresh_non_confirmed_composition()
|
||||
if context.highlight and curr_state.highlight_index and curr_state.highlight_index > 0 then
|
||||
context:highlight(curr_state.highlight_index)
|
||||
end
|
||||
end
|
||||
-- 辅助:判断是否单个 ASCII 小写字母
|
||||
local function _is_single_lowercase_letter(s)
|
||||
return type(s) == "string" and #s == 1 and s:match("^[a-z]$") ~= nil
|
||||
end
|
||||
function P.func(key_event, env)
|
||||
local context = env.engine.context
|
||||
-- 不要在早期就重置 offset(保持原代码行为)
|
||||
curr_state.reset()
|
||||
|
||||
local selected_cand = context:get_selected_candidate()
|
||||
if not context:has_menu() or not selected_cand or not selected_cand.text then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
-- 先判断当前的 adjust_code(与 extract_adjustment_code 的逻辑一致)
|
||||
local function get_adjust_code()
|
||||
if wanxiang.is_function_mode_active(context) then
|
||||
local code = seq_property.get(context)
|
||||
if code and code ~= "" then return code end
|
||||
return nil
|
||||
end
|
||||
return context.input:sub(1, context.caret_pos)
|
||||
end
|
||||
|
||||
local adjust_code = get_adjust_code()
|
||||
|
||||
-- 如果不是 function-mode 且 adjust_code 是单个小写字母,则按键不应改变 curr_state.offset,因为单字母存在时间复杂度
|
||||
if (not wanxiang.is_function_mode_active(context)) and _is_single_lowercase_letter(adjust_code) then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
local key_repr = key_event:repr()
|
||||
local function get_seq_key(type)
|
||||
return env.engine.schema.config:get_string("key_binder/sequence/" .. type) or DEFAULT_SEQ_KEY[type]
|
||||
end
|
||||
|
||||
if key_repr == get_seq_key("up") then
|
||||
curr_state.offset = -1; curr_state.mode = curr_state.ADJUST_MODE.Adjust
|
||||
elseif key_repr == get_seq_key("down") then
|
||||
curr_state.offset = 1; curr_state.mode = curr_state.ADJUST_MODE.Adjust
|
||||
elseif key_repr == get_seq_key("reset") then
|
||||
curr_state.offset = nil; curr_state.mode = curr_state.ADJUST_MODE.Reset
|
||||
elseif key_repr == get_seq_key("pin") then
|
||||
curr_state.offset = nil; curr_state.mode = curr_state.ADJUST_MODE.Pin
|
||||
else
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
process_adjustment(context)
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
end
|
||||
|
||||
local F = {}
|
||||
|
||||
function F.fini()
|
||||
-- 退出时不落盘(仅在重新部署 init_once 重写导出)
|
||||
if RUNTIME_EXPORT then
|
||||
seq_data.maybe_export(true)
|
||||
end
|
||||
end
|
||||
|
||||
local function apply_prev_adjustment(cands, prev)
|
||||
local list = {}
|
||||
for _, info in pairs(prev or {}) do
|
||||
if info.raw_position then info.from_position = info.raw_position; table.insert(list, info) end
|
||||
end
|
||||
table.sort(list, function(a, b) return (a.updated_at or 0) < (b.updated_at or 0) end)
|
||||
|
||||
local n = #cands
|
||||
for i, record in ipairs(list) do
|
||||
local fromp = record.from_position
|
||||
if fromp and (record.fixed_position or 0) > 0 then
|
||||
local top = (record.offset == 0) and record.fixed_position or (record.raw_position + record.offset)
|
||||
if top < 1 then top = 1 elseif top > n then top = n end
|
||||
if fromp ~= top then
|
||||
local cand = table.remove(cands, fromp)
|
||||
table.insert(cands, top, cand)
|
||||
local lo, hi = math.min(fromp, top), math.max(fromp, top)
|
||||
for j = i, #list do
|
||||
local r = list[j]
|
||||
if lo <= r.from_position and r.from_position <= hi then
|
||||
r.from_position = r.from_position + ((top < fromp) and 1 or -1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function apply_curr_adjustment(candidates, curr_adjustment)
|
||||
if curr_adjustment == nil then return end
|
||||
|
||||
---@type integer | nil
|
||||
local from_position = nil
|
||||
for position, cand in ipairs(candidates) do
|
||||
if cand.text == curr_state.selected_phrase then
|
||||
from_position = position
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if from_position == nil then return end
|
||||
|
||||
local to_position = from_position
|
||||
if curr_state.is_adjust_mode() then
|
||||
to_position = from_position + curr_state.offset
|
||||
curr_adjustment.offset = to_position - curr_adjustment.raw_position
|
||||
curr_adjustment.fixed_position = to_position
|
||||
|
||||
local min_position, max_position = 1, #candidates
|
||||
if from_position ~= to_position then
|
||||
if to_position < min_position then
|
||||
to_position = min_position
|
||||
elseif to_position > max_position then
|
||||
to_position = max_position
|
||||
end
|
||||
|
||||
local candidate = table.remove(candidates, from_position)
|
||||
table.insert(candidates, to_position, candidate)
|
||||
|
||||
-- 运行期仅写 DB,不入导出队列
|
||||
save_adjustment(curr_state.adjust_code, curr_state.adjust_key, curr_adjustment, true)
|
||||
end
|
||||
end
|
||||
|
||||
curr_state.highlight_index = to_position - 1
|
||||
end
|
||||
|
||||
local function extract_adjustment_code(context)
|
||||
if wanxiang.is_function_mode_active(context) then
|
||||
local code = seq_property.get(context)
|
||||
if code and code ~= "" then return code end
|
||||
return nil
|
||||
end
|
||||
return context.input:sub(1, context.caret_pos)
|
||||
end
|
||||
|
||||
function F.func(input, env)
|
||||
local function original_list() for cand in input:iter() do yield(cand) end end
|
||||
|
||||
local context = env.engine.context
|
||||
local adjustment_allowed = not (wanxiang.is_function_mode_active(context) and seq_property.get(context) == nil)
|
||||
if not adjustment_allowed then
|
||||
--log.warning("[sequence] 当前指令不支持手动排序")
|
||||
return original_list()
|
||||
end
|
||||
|
||||
local adjust_code = extract_adjustment_code(context)
|
||||
if not adjust_code then return original_list() end
|
||||
|
||||
local prev_adjustments = get_input_adjustments(adjust_code)
|
||||
local curr_adjustment = curr_state.has_adjustment() and { fixed_position = 0, offset = 0, updated_at = get_timestamp() } or nil
|
||||
if (not curr_adjustment) and (not prev_adjustments) then return original_list() end
|
||||
|
||||
local cands, seen = {}, {}
|
||||
local is_fun_mode = wanxiang.is_function_mode_active(context)
|
||||
local pos = 0
|
||||
for candidate in input:iter() do
|
||||
local phrase = candidate.text
|
||||
if not seen[phrase] then
|
||||
seen[phrase] = true; pos = pos + 1; table.insert(cands, candidate)
|
||||
local curr_key = is_fun_mode and tostring(pos - 1) or phrase
|
||||
if curr_adjustment and curr_state.selected_phrase == phrase then
|
||||
curr_state.adjust_code = adjust_code
|
||||
curr_state.adjust_key = curr_key
|
||||
curr_adjustment.raw_position = pos
|
||||
end
|
||||
if prev_adjustments and prev_adjustments[curr_key] then
|
||||
prev_adjustments[curr_key].raw_position = pos
|
||||
end
|
||||
end
|
||||
end
|
||||
prev_adjustments = prev_adjustments or {}
|
||||
|
||||
-- 非位移:置顶/重置立即仅保存到 DB(不入队)
|
||||
if curr_adjustment and not curr_state.is_adjust_mode() then
|
||||
curr_adjustment.offset = 0
|
||||
local key = tostring(curr_state.adjust_key)
|
||||
if curr_state.is_reset_mode() then
|
||||
curr_adjustment.fixed_position = 0
|
||||
prev_adjustments[key] = nil
|
||||
save_adjustment(curr_state.adjust_code, curr_state.adjust_key, curr_adjustment, true)
|
||||
elseif curr_state.is_pin_mode() then
|
||||
curr_adjustment.fixed_position = 1
|
||||
prev_adjustments[key] = curr_adjustment
|
||||
save_adjustment(curr_state.adjust_code, curr_state.adjust_key, curr_adjustment, true)
|
||||
end
|
||||
end
|
||||
|
||||
apply_prev_adjustment(cands, prev_adjustments)
|
||||
apply_curr_adjustment(cands, curr_adjustment)
|
||||
|
||||
for _, cand in ipairs(cands) do yield(cand) end
|
||||
|
||||
-- 运行期不写盘;如需调试可改为 if RUNTIME_EXPORT then ... end
|
||||
if RUNTIME_EXPORT and (not curr_state.is_reset_mode()) then
|
||||
seq_data.maybe_export(false)
|
||||
end
|
||||
end
|
||||
|
||||
return { P = P, F = F }
|
||||
279
lua/super_tips.lua
Normal file
279
lua/super_tips.lua
Normal file
@@ -0,0 +1,279 @@
|
||||
-- 万象家族lua,超级提示,表情\化学式\方程式\简码等等直接上屏,不占用候选位置
|
||||
-- 采用leveldb数据库,支持大数据遍历,支持多种类型混合,多种拼音编码混合,维护简单
|
||||
-- 支持候选匹配和编码匹配两种,候选支持方向键高亮遍历
|
||||
-- https://github.com/amzxyz/rime_wanxiang
|
||||
-- - lua_processor@*super_tips
|
||||
-- key_binder/tips_key: "slash" # 上屏按键配置
|
||||
-- tips/disabled_types: [] # 禁用的 tips 类型
|
||||
local wanxiang = require("wanxiang")
|
||||
local bit = require("lib/bit")
|
||||
local userdb = require("lib/userdb")
|
||||
|
||||
local tips_db = userdb.LevelDb("lua/tips")
|
||||
|
||||
-- 获取文件内容哈希值,使用 FNV-1a 哈希算法
|
||||
local function calculate_file_hash(filepath)
|
||||
local file = io.open(filepath, "rb")
|
||||
if not file then return nil end
|
||||
|
||||
-- FNV-1a 哈希参数(32位)
|
||||
local FNV_OFFSET_BASIS = 0x811C9DC5
|
||||
local FNV_PRIME = 0x01000193
|
||||
|
||||
local hash = FNV_OFFSET_BASIS
|
||||
while true do
|
||||
local chunk = file:read(4096)
|
||||
if not chunk then break end
|
||||
for i = 1, #chunk do
|
||||
local byte = string.byte(chunk, i)
|
||||
hash = bit.bxor(hash, byte)
|
||||
hash = (hash * FNV_PRIME) % 0x100000000
|
||||
hash = bit.band(hash, 0xFFFFFFFF)
|
||||
end
|
||||
end
|
||||
|
||||
file:close()
|
||||
return string.format("%08x", hash)
|
||||
end
|
||||
|
||||
local tips = {}
|
||||
|
||||
---@type "pending" | "initialing" | "done"
|
||||
tips.status = "pending"
|
||||
|
||||
---@type table<string, boolean>
|
||||
tips.disabled_types = {}
|
||||
tips.preset_file_path = wanxiang.get_filename_with_fallback("lua/tips/tips_show.txt")
|
||||
tips.user_override_path = rime_api.get_user_data_dir() .. "/lua/tips/tips_user.txt"
|
||||
|
||||
local META_KEY = {
|
||||
version = "wanxiang_version",
|
||||
user_file_hash = "user_tips_file_hash",
|
||||
disabled_types = "disabled_types",
|
||||
}
|
||||
|
||||
---@param tip string
|
||||
function tips.is_disabled(tip)
|
||||
local type = tip:match("^(..-):")
|
||||
or tip:match("^(..-):")
|
||||
|
||||
if not type then return false end
|
||||
return tips.disabled_types[type] == true
|
||||
end
|
||||
|
||||
function tips.init_db_from_file(path)
|
||||
local file = io.open(path, "r")
|
||||
if not file then return end
|
||||
|
||||
for line in file:lines() do
|
||||
local value, key = line:match("([^\t]+)\t([^\t]+)")
|
||||
if key and value
|
||||
and not tips.is_disabled(value)
|
||||
then
|
||||
tips_db:update(key, value)
|
||||
end
|
||||
end
|
||||
|
||||
file:close()
|
||||
end
|
||||
|
||||
function tips.ensure_dir_exist(dir)
|
||||
-- 获取系统路径分隔符
|
||||
local sep = package.config:sub(1, 1)
|
||||
|
||||
dir = dir:gsub([["]], [[\"]]) -- 处理双引号
|
||||
|
||||
if sep == "/" then
|
||||
local cmd = 'mkdir -p "' .. dir .. '" 2>/dev/null'
|
||||
os.execute(cmd)
|
||||
end
|
||||
end
|
||||
|
||||
---@param config Config
|
||||
function tips.init(config)
|
||||
if tips.status ~= "pending" then return end
|
||||
|
||||
local dist = rime_api.get_distribution_code_name() or ""
|
||||
local user_lua_dir = rime_api.get_user_data_dir() .. "/lua"
|
||||
if dist ~= "hamster" and dist ~= "hamster3" and dist ~= "Weasel" then
|
||||
tips.ensure_dir_exist(user_lua_dir)
|
||||
tips.ensure_dir_exist(user_lua_dir .. "/tips")
|
||||
end
|
||||
|
||||
-- 读取配置
|
||||
local disabled_types_list = config:get_list("tips/disabled_types")
|
||||
if disabled_types_list then
|
||||
for i = 1, disabled_types_list.size do
|
||||
local item = disabled_types_list:get_value_at(i - 1)
|
||||
if item and #item.value > 0 then
|
||||
tips.disabled_types[item.value] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 检查是否需要重建数据库
|
||||
tips_db:open()
|
||||
local needs_rebuild = false
|
||||
|
||||
-- 检查 1: 万象版本号
|
||||
if tips_db:meta_fetch(META_KEY.version) ~= wanxiang.version then
|
||||
needs_rebuild = true
|
||||
end
|
||||
|
||||
-- 检查 2: 用户文件哈希 (仅在版本号相同时检查)
|
||||
local user_file_hash = calculate_file_hash(tips.user_override_path) or ""
|
||||
if not needs_rebuild
|
||||
and (tips_db:meta_fetch(META_KEY.user_file_hash) or "") ~= user_file_hash
|
||||
then
|
||||
needs_rebuild = true
|
||||
end
|
||||
|
||||
-- 检查 3: 禁用类型 (仅在前两者都相同时检查)
|
||||
local disabled_keys = {}
|
||||
for k, _ in pairs(tips.disabled_types) do
|
||||
table.insert(disabled_keys, k)
|
||||
end
|
||||
table.sort(disabled_keys) -- 排序以确保顺序一致
|
||||
local disabled_types_str = table.concat(disabled_keys, ",")
|
||||
|
||||
if not needs_rebuild
|
||||
and (tips_db:meta_fetch(META_KEY.disabled_types) or "") ~= disabled_types_str
|
||||
then
|
||||
needs_rebuild = true
|
||||
end
|
||||
|
||||
-- 如果需要,则执行重建
|
||||
if needs_rebuild then
|
||||
tips_db:empty()
|
||||
tips.init_db_from_file(tips.preset_file_path)
|
||||
tips.init_db_from_file(tips.user_override_path)
|
||||
|
||||
-- 重建成功后,再更新所有元数据,确保操作的原子性
|
||||
tips_db:meta_update(META_KEY.version, wanxiang.version)
|
||||
tips_db:meta_update(META_KEY.user_file_hash, user_file_hash)
|
||||
tips_db:meta_update(META_KEY.disabled_types, disabled_types_str)
|
||||
end
|
||||
|
||||
-- 关闭并以只读模式重新打开
|
||||
tips_db:close()
|
||||
tips_db:open_read_only()
|
||||
end
|
||||
|
||||
---从数据库中查询 tips
|
||||
---@param keys string | string[] 接受一个字符串或一个字符串数组作为键,使用数组时会挨个查询,直到获得有效值
|
||||
---@return string | nil
|
||||
function tips.get_tip(keys)
|
||||
-- 输入归一化:如果输入是 string,将其包装成单元素的 table
|
||||
if type(keys) == 'string' then
|
||||
keys = { keys }
|
||||
end
|
||||
|
||||
for _, key in ipairs(keys) do
|
||||
if key and key ~= "" then
|
||||
local tip = tips_db:fetch(key)
|
||||
if tip and #tip > 0 then
|
||||
return tip
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
---@class Env
|
||||
---@field current_tip string | nil 当前 tips 值
|
||||
---@field last_prompt string 最后一次设置的 prompt 值
|
||||
---@field tips_update_connection Connection
|
||||
|
||||
---tips prompt 处理
|
||||
---@param context Context
|
||||
---@param env Env
|
||||
local function update_tips_prompt(context, env)
|
||||
env.current_tip = nil
|
||||
|
||||
local is_tips_enabled = context:get_option("super_tips")
|
||||
if not is_tips_enabled then return end
|
||||
|
||||
local segment = context.composition:back()
|
||||
if not segment then return end
|
||||
|
||||
local cand = context:get_selected_candidate() or {}
|
||||
|
||||
if segment.selected_index == 0 then
|
||||
env.current_tip = tips.get_tip({ context.input, cand.text })
|
||||
else
|
||||
env.current_tip = tips.get_tip(cand.text)
|
||||
end
|
||||
|
||||
if env.current_tip ~= nil and env.current_tip ~= "" then
|
||||
-- 有 tips 则直接设置 prompt
|
||||
segment.prompt = "〔" .. env.current_tip .. "〕"
|
||||
env.last_prompt = segment.prompt
|
||||
elseif segment.prompt ~= "" and env.last_prompt == segment.prompt then
|
||||
-- 没有 tips,且当前 prompt 不为空,且是由 super_tips 设置的,则重置
|
||||
segment.prompt = ""
|
||||
env.last_prompt = segment.prompt
|
||||
end
|
||||
end
|
||||
|
||||
local P = {}
|
||||
|
||||
-- Processor:按键触发上屏 (S)
|
||||
---@param env Env
|
||||
function P.init(env)
|
||||
local config = env.engine.schema.config
|
||||
tips.init(config)
|
||||
|
||||
P.tips_key = config:get_string("key_binder/tips_key")
|
||||
|
||||
-- 注册 tips 查找监听器
|
||||
local context = env.engine.context
|
||||
env.tips_update_connection = context.update_notifier:connect(
|
||||
function(context)
|
||||
update_tips_prompt(context, env)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
function P.fini(env)
|
||||
-- 清理连接
|
||||
if env.tips_update_connection then
|
||||
env.tips_update_connection:disconnect()
|
||||
env.tips_update_connection = nil
|
||||
end
|
||||
end
|
||||
|
||||
---@param key KeyEvent
|
||||
---@param env Env
|
||||
---@return ProcessResult
|
||||
function P.func(key, env)
|
||||
local context = env.engine.context
|
||||
|
||||
local is_tips_enabled = context:get_option("super_tips")
|
||||
if not is_tips_enabled then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
-- 以下处理 tips 上屏逻辑
|
||||
if not P.tips_key -- 未设置上屏键
|
||||
or P.tips_key ~= key:repr() -- 或者当前按下的不是上屏键
|
||||
or wanxiang.is_function_mode_active(context) -- 或者是功能模式不用上屏
|
||||
or not env.current_tip or env.current_tip == "" -- 或匹配的 tips 为空/空字符串
|
||||
then
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
---@type string 从 tips 内容中获取上屏文本
|
||||
local commit_txt = env.current_tip:match(":%s*(.*)%s*") -- 优先匹配常规的全角冒号
|
||||
or env.current_tip:match(":%s*(.*)%s*") -- 没有匹配则回落到半角冒号
|
||||
|
||||
if commit_txt and #commit_txt > 0 then
|
||||
env.engine:commit_text(commit_txt)
|
||||
context:clear()
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
end
|
||||
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
return P
|
||||
6853
lua/tips/tips_show.txt
Normal file
6853
lua/tips/tips_show.txt
Normal file
File diff suppressed because it is too large
Load Diff
128
lua/tone_fallback.lua
Normal file
128
lua/tone_fallback.lua
Normal file
@@ -0,0 +1,128 @@
|
||||
-- 欢迎使用万象拼音方案
|
||||
-- @amzxyz
|
||||
-- https://github.com/amzxyz/rime_wanxiang
|
||||
-- 用来在声调辅助的时候当你输入 2 个数字的时候自动将声调替换为第二个数字,
|
||||
-- 也就是说你发现输入错误声调你可以手动轮巡输入而不用回退删除直接输入下一个即可
|
||||
-- 兼容小键盘输入中不回退
|
||||
|
||||
local wanxiang = require("wanxiang")
|
||||
|
||||
-- 将目标字符的连续段压缩为“最后一个字符”
|
||||
local function compress_runs_keep_last(text)
|
||||
local changed = false
|
||||
local out = text:gsub('([:"<>7890])([:"<>7890]+)', function(_, tail)
|
||||
changed = true
|
||||
return tail:sub(-1)
|
||||
end)
|
||||
return out, changed
|
||||
end
|
||||
|
||||
local function should_ignore(ctx)
|
||||
return wanxiang.is_function_mode_active(ctx) or ctx.input == ""
|
||||
end
|
||||
|
||||
-- 小键盘 keycode 判定(0xFFB0 ~ 0xFFB9)
|
||||
local function is_kp_digit_keycode(kc)
|
||||
return kc >= 0xFFB0 and kc <= 0xFFB9
|
||||
end
|
||||
|
||||
---@class Env
|
||||
---@field tone_state "idle"|"skip"|"compress"
|
||||
---@field tone_fallback_update_connection Connection|nil
|
||||
|
||||
local P = {}
|
||||
|
||||
function P.init(env)
|
||||
env.tone_state = "idle"
|
||||
|
||||
local ctx = env.engine and env.engine.context
|
||||
if not ctx or not ctx.update_notifier then return end
|
||||
|
||||
env.tone_fallback_update_connection = ctx.update_notifier:connect(function(c)
|
||||
if should_ignore(c) then
|
||||
env.tone_state = "idle"
|
||||
return
|
||||
end
|
||||
|
||||
-- 只在当前按键对应的一次更新里消费 state
|
||||
local state = env.tone_state or "idle"
|
||||
env.tone_state = "idle" -- 立刻消费,避免“下一次才生效”
|
||||
|
||||
-- 小键盘数字:标记为 skip,本次直接不压缩
|
||||
if state == "skip" then
|
||||
return
|
||||
end
|
||||
|
||||
-- 非压缩状态:直接不动
|
||||
if state ~= "compress" then
|
||||
return
|
||||
end
|
||||
|
||||
-- 压缩逻辑
|
||||
local input = c.input
|
||||
local caret = (c.caret_pos ~= nil) and c.caret_pos or #input
|
||||
if caret < 0 then caret = 0 end
|
||||
if caret > #input then caret = #input end
|
||||
|
||||
-- 仅处理光标左侧;右侧保持不变
|
||||
local left = (caret > 0) and input:sub(1, caret) or ""
|
||||
local right = (caret < #input) and input:sub(caret + 1) or ""
|
||||
|
||||
local left_new, changed = compress_runs_keep_last(left)
|
||||
if not changed then return end
|
||||
|
||||
-- 只改左侧,避免干扰右侧;并精确设置 caret_pos
|
||||
if caret > 0 then c:pop_input(caret) end
|
||||
if #left_new > 0 then c:push_input(left_new) end
|
||||
if c.caret_pos ~= nil then c.caret_pos = #left_new end
|
||||
-- 右侧 right 不需处理,Rime 会保持不变
|
||||
end)
|
||||
end
|
||||
|
||||
function P.fini(env)
|
||||
if env.tone_fallback_update_connection then
|
||||
env.tone_fallback_update_connection:disconnect()
|
||||
env.tone_fallback_update_connection = nil
|
||||
end
|
||||
env.tone_state = "idle"
|
||||
end
|
||||
|
||||
---@return ProcessResult
|
||||
function P.func(key, env)
|
||||
local ctx = env.engine.context
|
||||
if should_ignore(ctx) then
|
||||
env.tone_state = "idle"
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
-- 小键盘数字:标记这次按键为 skip,本轮 update_notifier 不压缩
|
||||
local kc = key.keycode
|
||||
if is_kp_digit_keycode(kc) then
|
||||
env.tone_state = "skip"
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
-- 主键盘数字 0–9:标记为 compress
|
||||
local r = key:repr() or ""
|
||||
if r:match("^[0-9]$") then
|
||||
env.tone_state = "compress"
|
||||
|
||||
-- 这里用“预测压缩是否会发生”来决定要不要告诉 Rime “我处理了这个按键”
|
||||
local input = ctx.input or ""
|
||||
local caret = (ctx.caret_pos ~= nil) and ctx.caret_pos or #input
|
||||
if caret < 0 then caret = 0 end
|
||||
if caret > #input then caret = #input end
|
||||
|
||||
local left = (caret > 0) and input:sub(1, caret) or ""
|
||||
local _, changed = compress_runs_keep_last(left)
|
||||
|
||||
return changed and wanxiang.RIME_PROCESS_RESULTS.kAccepted
|
||||
or wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
-- 其它按键:不触发压缩,也不跳过
|
||||
env.tone_state = "idle"
|
||||
return wanxiang.RIME_PROCESS_RESULTS.kNoop
|
||||
end
|
||||
|
||||
return P
|
||||
32
lua/unicode.lua
Normal file
32
lua/unicode.lua
Normal file
@@ -0,0 +1,32 @@
|
||||
-- Unicode
|
||||
-- 示例:输入 U62fc 得到「拼」
|
||||
-- 触发前缀默认为 recognizer/patterns/unicode 的第 2 个字符,即 U
|
||||
-- 2024.02.26: 限定编码最大值
|
||||
local function unicode(input, seg, env)
|
||||
-- 获取 recognizer/patterns/unicode 的第 2 个字符作为触发前缀
|
||||
env.unicode_keyword = env.unicode_keyword or
|
||||
env.engine.schema.config:get_string('recognizer/patterns/unicode'):sub(2, 2)
|
||||
if seg:has_tag("unicode") and env.unicode_keyword ~= '' and input:sub(1, 1) == env.unicode_keyword then
|
||||
local ucodestr = input:match(env.unicode_keyword .. "(%x+)")
|
||||
if ucodestr and #ucodestr > 1 then
|
||||
local segment = env.engine.context.composition:back()
|
||||
-- 设置标签
|
||||
segment.tags = segment.tags + Set({ "unicode" })
|
||||
local code = tonumber(ucodestr, 16)
|
||||
if code > 0x10FFFF then
|
||||
yield(Candidate("unicode", seg.start, seg._end, "数值超限!", ""))
|
||||
return
|
||||
end
|
||||
local text = utf8.char(code)
|
||||
yield(Candidate("unicode", seg.start, seg._end, text, string.format("U%x", code)))
|
||||
if code < 0x10000 then
|
||||
for i = 0, 15 do
|
||||
local text = utf8.char(code * 16 + i)
|
||||
yield(Candidate("unicode", seg.start, seg._end, text, string.format("U%x~%x", code, i)))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return unicode
|
||||
16
lua/version_display.lua
Normal file
16
lua/version_display.lua
Normal file
@@ -0,0 +1,16 @@
|
||||
local wanxiang = require("wanxiang")
|
||||
|
||||
--输入'/wx',显示万象项目地址和当前版本号
|
||||
local function translator(input, seg, env)
|
||||
if input == "/wx" then
|
||||
-- 候选1: GitHub 网址
|
||||
yield(Candidate("url", seg.start, seg._end, "https://github.com/amzxyz/rime_wanxiang", ""))
|
||||
-- 候选2: CNB 网址
|
||||
yield(Candidate("url", seg.start, seg._end, "https://cnb.cool/amzxyz/rime-wanxiang", ""))
|
||||
-- 判断是否为专业版
|
||||
local version_prefix = wanxiang.is_pro_scheme(env) and "增强版" or "标准版"
|
||||
-- 候选3: 当前版本号(加上“增强版”或“标准版”前缀)
|
||||
yield(Candidate("version", seg.start, seg._end, version_prefix .. wanxiang.version, ""))
|
||||
end
|
||||
end
|
||||
return translator
|
||||
710
lua/wanxiang.lua
Normal file
710
lua/wanxiang.lua
Normal file
@@ -0,0 +1,710 @@
|
||||
---@diagnostic disable: undefined-global
|
||||
|
||||
-- 万象的一些共用工具函数
|
||||
local wanxiang = {}
|
||||
|
||||
-- x-release-please-start-version
|
||||
|
||||
wanxiang.version = "v13.6.3"
|
||||
|
||||
-- x-release-please-end
|
||||
|
||||
-- 全局内容
|
||||
---@alias PROCESS_RESULT ProcessResult
|
||||
wanxiang.RIME_PROCESS_RESULTS = {
|
||||
kRejected = 0, -- 表示处理器明确拒绝了这个按键,停止处理链但不返回 true
|
||||
kAccepted = 1, -- 表示处理器成功处理了这个按键,停止处理链并返回 true
|
||||
kNoop = 2, -- 表示处理器没有处理这个按键,继续传递给下一个处理器
|
||||
}
|
||||
|
||||
-- 整个生命周期内不变,缓存判断结果
|
||||
local is_mobile_device = nil
|
||||
-- 判断是否为手机设备
|
||||
---@author amzxyz
|
||||
---@return boolean
|
||||
function wanxiang.is_mobile_device()
|
||||
local function _is_mobile_device()
|
||||
local dist = rime_api.get_distribution_code_name() or ""
|
||||
local user_data_dir = rime_api.get_user_data_dir() or ""
|
||||
local sys_dir = rime_api.get_shared_data_dir() or ""
|
||||
-- 转换为小写以便比较
|
||||
local lower_dist = dist:lower()
|
||||
local lower_path = user_data_dir:lower()
|
||||
local sys_lower_path = sys_dir:lower()
|
||||
-- 主判断:常见移动端输入法
|
||||
if lower_dist == "trime" or
|
||||
lower_dist == "hamster" or
|
||||
lower_dist == "hamster3" or
|
||||
lower_dist == "squirrel" then
|
||||
return true
|
||||
end
|
||||
|
||||
-- 补充判断:路径中包含移动设备特征,很可以mac的运行逻辑和手机一球样
|
||||
if lower_path:find("/android/") or
|
||||
lower_path:find("/mobile/") or
|
||||
lower_path:find("/sdcard/") or
|
||||
lower_path:find("/data/storage/") or
|
||||
lower_path:find("/storage/emulated/") or
|
||||
lower_path:find("applications") or
|
||||
lower_path:find("library") then
|
||||
return true
|
||||
end
|
||||
-- 补充判断:路径中包含移动设备特征,很可以mac的运行逻辑和手机一球样
|
||||
if sys_lower_path:find("applications") or
|
||||
sys_lower_path:find("library") then
|
||||
return true
|
||||
end
|
||||
-- 特定平台判断(Android/Linux)
|
||||
if jit and jit.os then
|
||||
local os_name = jit.os:lower()
|
||||
if os_name:find("android") then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- 所有检查未通过则默认为桌面设备
|
||||
return false
|
||||
end
|
||||
|
||||
if is_mobile_device == nil then
|
||||
is_mobile_device = _is_mobile_device()
|
||||
end
|
||||
return is_mobile_device
|
||||
end
|
||||
|
||||
--- 检测是否为万象专业版
|
||||
---@param env Env
|
||||
---@return boolean
|
||||
function wanxiang.is_pro_scheme(env)
|
||||
-- local schema_name = env.engine.schema.schema_name
|
||||
-- return schema_name:gsub("PRO$", "") ~= schema_name
|
||||
return env.engine.schema.schema_id == "wanxiang_pro"
|
||||
end
|
||||
|
||||
-- 以 `tag` 方式检测是否处于反查模式
|
||||
function wanxiang.is_in_radical_mode(env)
|
||||
local seg = env.engine.context.composition:back()
|
||||
return seg and (
|
||||
seg:has_tag("wanxiang_reverse")
|
||||
) or false
|
||||
end
|
||||
|
||||
---判断是否在命令模式
|
||||
---@param context Context | nil
|
||||
---@return boolean
|
||||
function wanxiang.is_function_mode_active(context)
|
||||
if not context or not context.composition or context.composition:empty() then
|
||||
return false
|
||||
end
|
||||
|
||||
local seg = context.composition:back()
|
||||
if not seg then return false end
|
||||
|
||||
return seg:has_tag("number") or -- number_translator.lua 数字金额转换 R+数字
|
||||
seg:has_tag("unicode") or -- unicode.lua 输出 Unicode 字符 U+小写字母或数字
|
||||
--seg:has_tag("punct") or -- 标点符号 全角半角提示
|
||||
seg:has_tag("calculator") or -- super_calculator.lua V键计算器
|
||||
seg:has_tag("shijian") or -- shijian.lua /rq /sr 等与时间日期相关功能
|
||||
seg:has_tag("Ndate") -- shijian.lua N日期功能
|
||||
end
|
||||
|
||||
---判断文件是否存在
|
||||
function wanxiang.file_exists(filename)
|
||||
local f = io.open(filename, "r")
|
||||
if f ~= nil then
|
||||
io.close(f)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- 判断字符是否为汉字
|
||||
function wanxiang.IsChineseCharacter(text)
|
||||
local codepoint = utf8.codepoint(text)
|
||||
return
|
||||
(codepoint >= 0x4E00 and codepoint <= 0x9FFF) -- Basic
|
||||
or (codepoint >= 0x3400 and codepoint <= 0x4DBF) -- Ext A
|
||||
or (codepoint >= 0x20000 and codepoint <= 0x2A6DF) -- Ext B
|
||||
or (codepoint >= 0x2A700 and codepoint <= 0x2B73F) -- Ext C
|
||||
or (codepoint >= 0x2B740 and codepoint <= 0x2B81F) -- Ext D
|
||||
or (codepoint >= 0x2B820 and codepoint <= 0x2CEAF) -- Ext E
|
||||
or (codepoint >= 0x2CEB0 and codepoint <= 0x2EBEF) -- Ext F
|
||||
or (codepoint >= 0x30000 and codepoint <= 0x3134F) -- Ext G
|
||||
or (codepoint >= 0x31350 and codepoint <= 0x323AF) -- Ext H
|
||||
or (codepoint >= 0x2EBF0 and codepoint <= 0x2EE5F) -- Ext I
|
||||
or (codepoint >= 0xF900 and codepoint <= 0xFAFF) -- Compatibility
|
||||
or (codepoint >= 0x2F800 and codepoint <= 0x2FA1F) -- Compatibility Supplement
|
||||
or (codepoint >= 0x2E80 and codepoint <= 0x2EFF) -- Radicals Supplement
|
||||
or (codepoint >= 0x2F00 and codepoint <= 0x2FDF) -- Kangxi Radicals
|
||||
end
|
||||
|
||||
---按照优先顺序获取文件:用户目录 > 系统目录
|
||||
---@param filename string 相对路径
|
||||
---@retur string | nil
|
||||
function wanxiang.get_filename_with_fallback(filename)
|
||||
local _path = filename:gsub("^/+", "") -- 去掉开头的斜杠
|
||||
|
||||
local user_path = rime_api.get_user_data_dir() .. '/' .. _path
|
||||
if wanxiang.file_exists(user_path) then
|
||||
return user_path
|
||||
end
|
||||
|
||||
local shared_path = rime_api.get_shared_data_dir() .. '/' .. _path
|
||||
if wanxiang.file_exists(shared_path) then
|
||||
return shared_path
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 按照优先顺序加载文件:用户目录 > 系统目录
|
||||
---@param filename string 相对路径
|
||||
---@retur file* | nil, function
|
||||
function wanxiang.load_file_with_fallback(filename, mode)
|
||||
mode = mode or "r" -- 默认读取模式
|
||||
|
||||
local _filename = wanxiang.get_filename_with_fallback(filename)
|
||||
|
||||
local file, err
|
||||
local function close()
|
||||
if not file then return end
|
||||
file:close()
|
||||
file = nil
|
||||
end
|
||||
|
||||
if _filename then
|
||||
file, err = io.open(_filename, mode)
|
||||
end
|
||||
|
||||
return file, close, err
|
||||
end
|
||||
|
||||
local USER_ID_DEFAULT = "unknown"
|
||||
---作为「小狼毫」和「仓」 `rime_api.get_user_id()` 的一个 workaround
|
||||
---详见:
|
||||
---1. https://github.com/rime/weasel/pull/1649
|
||||
---2. https://github.com/rime/librime/issues/1038
|
||||
---@return string
|
||||
function wanxiang.get_user_id()
|
||||
local user_id = rime_api.get_user_id()
|
||||
if user_id ~= USER_ID_DEFAULT then return user_id end
|
||||
|
||||
local user_data_dir = rime_api.get_user_data_dir()
|
||||
local installation_path = user_data_dir .. "/installation.yaml"
|
||||
local installation_file, _ = io.open(installation_path, "r")
|
||||
if not installation_file then return user_id end
|
||||
|
||||
for line in installation_file:lines() do
|
||||
local key, value = line:match('^([^#:]+):%s+"?([^"]%S+[^"])"?')
|
||||
if key == "installation_id" then
|
||||
user_id = value
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
installation_file:close()
|
||||
return user_id
|
||||
end
|
||||
wanxiang.INPUT_METHOD_MARKERS = {
|
||||
["Ⅰ"] = "pinyin", --全拼
|
||||
["Ⅱ"] = "zrm", --自然码双拼
|
||||
["Ⅲ"] = "flypy", --小鹤双拼
|
||||
["Ⅳ"] = "mspy", --微软双拼
|
||||
["Ⅴ"] = "sogou", --搜狗双拼
|
||||
["Ⅵ"] = "abc", --智能abc双拼
|
||||
["Ⅶ"] = "ziguang", --紫光双拼
|
||||
["Ⅷ"] = "pyjj", --拼音加加
|
||||
["Ⅸ"] = "gbpy", --国标双拼
|
||||
["Ⅹ"] = "wxsp", --万象双拼
|
||||
["Ⅺ"] = "zrlong", --自然龙
|
||||
["Ⅻ"] = "hxlong", --汉心龙
|
||||
["Ⅼ"] = "lxsq", --乱序17
|
||||
["ⅲ"] = "ⅲ", -- 间接辅助标记:命中则额外返回 md="ⅲ"
|
||||
}
|
||||
|
||||
local __input_type_cache = {} -- 缓存首个命中的 id(兼容旧用法)
|
||||
local __input_md_cache = {} -- 新增:是否命中“ⅲ”(若命中则为 "ⅲ",否则为 nil)
|
||||
|
||||
--- 根据 speller/algebra 中的特殊符号返回输入类型:
|
||||
--- - 若未命中“ⅲ”,只返回 id(保持旧行为)
|
||||
--- - 若命中“ⅲ”,返回两个值:id, "ⅲ"
|
||||
---@param env Env
|
||||
---@return string -- id
|
||||
---@return string|nil -- md(仅在命中“ⅲ”时返回 "ⅲ")
|
||||
function wanxiang.get_input_method_type(env)
|
||||
local schema_id = env.engine.schema.schema_id or "unknown"
|
||||
|
||||
-- 命中缓存则按是否有 md 决定返回 1 个或 2 个值
|
||||
local cached_id = __input_type_cache[schema_id]
|
||||
if cached_id then
|
||||
local cached_md = __input_md_cache[schema_id]
|
||||
if cached_md then
|
||||
return cached_id, cached_md -- 返回两个值:id, "ⅲ"
|
||||
else
|
||||
return cached_id -- 只返回 id
|
||||
end
|
||||
end
|
||||
|
||||
local cfg = env.engine.schema.config
|
||||
local result_id = "unknown"
|
||||
local md = nil -- 只有命中“ⅲ”时设为 "ⅲ"
|
||||
|
||||
local n = cfg:get_list_size("speller/algebra")
|
||||
for i = 0, n - 1 do
|
||||
local s = cfg:get_string(("speller/algebra/@%d"):format(i))
|
||||
if s then
|
||||
-- 不提前返回:需要把整段都扫描完,才能知道是否命中“ⅲ”
|
||||
for symbol, id in pairs(wanxiang.INPUT_METHOD_MARKERS) do
|
||||
if s:find(symbol, 1, true) then
|
||||
if symbol == "ⅲ" or id == "ⅲ" then
|
||||
md = "ⅲ" -- 记录辅助标记
|
||||
else
|
||||
if result_id == "unknown" then
|
||||
result_id = id -- 只记录第一个“正常映射”的 id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 写缓存
|
||||
__input_type_cache[schema_id] = result_id
|
||||
__input_md_cache[schema_id] = md -- 命中则为 "ⅲ",否则为 nil
|
||||
|
||||
-- 返回:命中“ⅲ”→两个值;否则一个值
|
||||
if md then
|
||||
return result_id, md
|
||||
else
|
||||
return result_id
|
||||
end
|
||||
end
|
||||
wanxiang.tone_matrix = {
|
||||
["a"] = {1,2,3,4},
|
||||
["ai"] = {1,2,3,4},
|
||||
["an"] = {1,2,3,4},
|
||||
["ang"] = {1,2,3,4},
|
||||
["ao"] = {1,2,3,4},
|
||||
["ba"] = {1,2,3,4},
|
||||
["bai"] = {1,2,3,4},
|
||||
["ban"] = {1,3,4},
|
||||
["bang"] = {1,3,4},
|
||||
["bao"] = {1,2,3,4},
|
||||
["bei"] = {1,3,4},
|
||||
["ben"] = {1,3,4},
|
||||
["beng"] = {1,2,3,4},
|
||||
["bi"] = {1,2,3,4},
|
||||
["bian"] = {1,3,4},
|
||||
["biang"] = {2},
|
||||
["biao"] = {1,2,3,4},
|
||||
["bie"] = {1,2,3,4},
|
||||
["bin"] = {1,4},
|
||||
["bing"] = {1,3,4},
|
||||
["bo"] = {1,2,3,4},
|
||||
["bu"] = {1,2,3,4},
|
||||
["bun"] = {1},
|
||||
["ca"] = {1,3,4},
|
||||
["cai"] = {1,2,3,4},
|
||||
["can"] = {1,2,3,4},
|
||||
["cang"] = {1,2,4},
|
||||
["cao"] = {1,2,3,4},
|
||||
["ce"] = {4},
|
||||
["cei"] = {4},
|
||||
["cen"] = {1,2},
|
||||
["ceng"] = {1,2,4},
|
||||
["ceok"] = {},
|
||||
["ceon"] = {},
|
||||
["cha"] = {1,2,3,4},
|
||||
["chai"] = {1,2,3,4},
|
||||
["chan"] = {1,2,3,4},
|
||||
["chang"] = {1,2,3,4},
|
||||
["chao"] = {1,2,3,4},
|
||||
["che"] = {1,2,3,4},
|
||||
["chen"] = {1,2,3,4},
|
||||
["cheng"] = {1,2,3,4},
|
||||
["chi"] = {1,2,3,4},
|
||||
["chong"] = {1,2,3,4},
|
||||
["chou"] = {1,2,3,4},
|
||||
["chu"] = {1,2,3,4},
|
||||
["chua"] = {1,3,4},
|
||||
["chuai"] = {1,2,3,4},
|
||||
["chuan"] = {1,2,3,4},
|
||||
["chuang"] = {1,2,3,4},
|
||||
["chui"] = {1,2,4},
|
||||
["chun"] = {1,2,3},
|
||||
["chuo"] = {1,4},
|
||||
["ci"] = {1,2,3,4},
|
||||
["cong"] = {1,2,3,4},
|
||||
["cou"] = {1,2,3,4},
|
||||
["cu"] = {1,2,3,4},
|
||||
["cuan"] = {1,2,4},
|
||||
["cui"] = {1,3,4},
|
||||
["cun"] = {1,2,3,4},
|
||||
["cuo"] = {1,2,3,4},
|
||||
["da"] = {1,2,3,4},
|
||||
["dai"] = {1,3,4},
|
||||
["dan"] = {1,3,4},
|
||||
["dang"] = {1,3,4},
|
||||
["dao"] = {1,2,3,4},
|
||||
["de"] = {1,2},
|
||||
["dei"] = {1,3},
|
||||
["den"] = {4},
|
||||
["deng"] = {1,3,4},
|
||||
["di"] = {1,2,3,4},
|
||||
["dia"] = {3},
|
||||
["dian"] = {1,2,3,4},
|
||||
["diao"] = {1,3,4},
|
||||
["die"] = {1,2,3,4},
|
||||
["dim"] = {2},
|
||||
["din"] = {4},
|
||||
["ding"] = {1,3,4},
|
||||
["diu"] = {1},
|
||||
["dong"] = {1,3,4},
|
||||
["dou"] = {1,2,3,4},
|
||||
["du"] = {1,2,3,4},
|
||||
["duan"] = {1,3,4},
|
||||
["dui"] = {1,3,4},
|
||||
["dun"] = {1,3,4},
|
||||
["duo"] = {1,2,3,4},
|
||||
["e"] = {1,2,3,4},
|
||||
["ei"] = {1,2,3,4},
|
||||
["en"] = {1,3,4},
|
||||
["eng"] = {1},
|
||||
["er"] = {2,3,4},
|
||||
["fa"] = {1,2,3,4},
|
||||
["fan"] = {1,2,3,4},
|
||||
["fang"] = {1,2,3,4},
|
||||
["fei"] = {1,2,3,4},
|
||||
["fen"] = {1,2,3,4},
|
||||
["feng"] = {1,2,3,4},
|
||||
["fiao"] = {4},
|
||||
["fo"] = {2},
|
||||
["fou"] = {1,2,3},
|
||||
["fu"] = {1,2,3,4},
|
||||
["ga"] = {1,2,3,4},
|
||||
["gai"] = {1,3,4},
|
||||
["gan"] = {1,3,4},
|
||||
["gang"] = {1,3,4},
|
||||
["gao"] = {1,3,4},
|
||||
["ge"] = {1,2,3,4},
|
||||
["gei"] = {3},
|
||||
["gen"] = {1,2,3,4},
|
||||
["geng"] = {1,3,4},
|
||||
["gong"] = {1,3,4},
|
||||
["gou"] = {1,3,4},
|
||||
["gu"] = {1,2,3,4},
|
||||
["gua"] = {1,2,3,4},
|
||||
["guai"] = {1,3,4},
|
||||
["guan"] = {1,3,4},
|
||||
["guang"] = {1,3,4},
|
||||
["gui"] = {1,3,4},
|
||||
["gun"] = {3,4},
|
||||
["guo"] = {1,2,3,4},
|
||||
["ha"] = {1,2,3,4},
|
||||
["hai"] = {1,2,3,4},
|
||||
["han"] = {1,2,3,4},
|
||||
["hang"] = {1,2,4},
|
||||
["hao"] = {1,2,3,4},
|
||||
["he"] = {1,2,3,4},
|
||||
["hei"] = {1},
|
||||
["hen"] = {2,3,4},
|
||||
["heng"] = {1,2,4},
|
||||
["hong"] = {1,2,3,4},
|
||||
["hou"] = {1,2,3,4},
|
||||
["hu"] = {1,2,3,4},
|
||||
["hua"] = {1,2,4},
|
||||
["huai"] = {2,4},
|
||||
["huan"] = {1,2,3,4},
|
||||
["huang"] = {1,2,3,4},
|
||||
["hui"] = {1,2,3,4},
|
||||
["hun"] = {1,2,3,4},
|
||||
["huo"] = {1,2,3,4},
|
||||
["ji"] = {1,2,3,4},
|
||||
["jia"] = {1,2,3,4},
|
||||
["jian"] = {1,3,4},
|
||||
["jiang"] = {1,3,4},
|
||||
["jiao"] = {1,2,3,4},
|
||||
["jie"] = {1,2,3,4},
|
||||
["jin"] = {1,3,4},
|
||||
["jing"] = {1,3,4},
|
||||
["jiong"] = {1,3,4},
|
||||
["jiu"] = {1,2,3,4},
|
||||
["ju"] = {1,2,3,4},
|
||||
["juan"] = {1,3,4},
|
||||
["jue"] = {1,2,3,4},
|
||||
["jun"] = {1,3,4},
|
||||
["ka"] = {1,3},
|
||||
["kai"] = {1,3,4},
|
||||
["kan"] = {1,3,4},
|
||||
["kang"] = {1,2,3,4},
|
||||
["kao"] = {1,3,4},
|
||||
["ke"] = {1,2,3,4},
|
||||
["kei"] = {1},
|
||||
["ken"] = {1,3,4},
|
||||
["keng"] = {1,3},
|
||||
["kong"] = {1,3,4},
|
||||
["kou"] = {1,3,4},
|
||||
["ku"] = {1,2,3,4},
|
||||
["kua"] = {1,3,4},
|
||||
["kuai"] = {2,3,4},
|
||||
["kuan"] = {1,3,4},
|
||||
["kuang"] = {1,2,3,4},
|
||||
["kui"] = {1,2,3,4},
|
||||
["kun"] = {1,3,4},
|
||||
["kuo"] = {4},
|
||||
["la"] = {1,2,3,4},
|
||||
["lai"] = {2,3,4},
|
||||
["lan"] = {2,3,4},
|
||||
["lang"] = {1,2,3,4},
|
||||
["lao"] = {1,2,3,4},
|
||||
["le"] = {1,4},
|
||||
["lei"] = {1,2,3,4},
|
||||
["leng"] = {1,2,3,4},
|
||||
["li"] = {1,2,3,4},
|
||||
["lia"] = {3},
|
||||
["lian"] = {2,3,4},
|
||||
["liang"] = {1,2,3,4},
|
||||
["liao"] = {1,2,3,4},
|
||||
["lie"] = {1,2,3,4},
|
||||
["lin"] = {1,2,3,4},
|
||||
["ling"] = {2,3,4},
|
||||
["liu"] = {1,2,3,4},
|
||||
["lo"] = {},
|
||||
["long"] = {1,2,3,4},
|
||||
["lou"] = {1,2,3,4},
|
||||
["lu"] = {1,2,3,4},
|
||||
["luan"] = {2,3,4},
|
||||
["lun"] = {1,2,3,4},
|
||||
["luo"] = {1,2,3,4},
|
||||
["lv"] = {2,3,4},
|
||||
["lve"] = {4},
|
||||
["ma"] = {1,2,3,4},
|
||||
["mai"] = {2,3,4},
|
||||
["man"] = {1,2,3,4},
|
||||
["mang"] = {1,2,3,4},
|
||||
["mao"] = {1,2,3,4},
|
||||
["me"] = {1,4},
|
||||
["mei"] = {2,3,4},
|
||||
["men"] = {1,2,4},
|
||||
["meng"] = {1,2,3,4},
|
||||
["mi"] = {1,2,3,4},
|
||||
["mian"] = {2,3,4},
|
||||
["miao"] = {1,2,3,4},
|
||||
["mie"] = {1,2,4},
|
||||
["min"] = {2,3},
|
||||
["ming"] = {2,3,4},
|
||||
["miu"] = {3,4},
|
||||
["mo"] = {1,2,3,4},
|
||||
["mou"] = {1,2,3,4},
|
||||
["mu"] = {2,3,4},
|
||||
["m̀"] = {},
|
||||
["n"] = {2,3,4},
|
||||
["na"] = {1,2,3,4},
|
||||
["nai"] = {2,3,4},
|
||||
["nan"] = {1,2,3,4},
|
||||
["nang"] = {1,2,3,4},
|
||||
["nao"] = {1,2,3,4},
|
||||
["ne"] = {2,4},
|
||||
["nei"] = {2,3,4},
|
||||
["nen"] = {4},
|
||||
["neng"] = {2,3,4},
|
||||
["ng"] = {2,3,4},
|
||||
["ni"] = {1,2,3,4},
|
||||
["nian"] = {1,2,3,4},
|
||||
["niang"] = {2,3,4},
|
||||
["niao"] = {3,4},
|
||||
["nie"] = {1,2,3,4},
|
||||
["nin"] = {2,3},
|
||||
["ning"] = {2,3,4},
|
||||
["niu"] = {1,2,3,4},
|
||||
["nong"] = {2,3,4},
|
||||
["nou"] = {2,3,4},
|
||||
["nu"] = {2,3,4},
|
||||
["nuan"] = {2,3,4},
|
||||
["nun"] = {2},
|
||||
["nuo"] = {2,3,4},
|
||||
["nv"] = {2,3,4},
|
||||
["nve"] = {4},
|
||||
["o"] = {1,2,3,4},
|
||||
["ou"] = {1,2,3,4},
|
||||
["pa"] = {1,2,3,4},
|
||||
["pai"] = {1,2,3,4},
|
||||
["pan"] = {1,2,3,4},
|
||||
["pang"] = {1,2,3,4},
|
||||
["pao"] = {1,2,3,4},
|
||||
["pei"] = {1,2,3,4},
|
||||
["pen"] = {1,2,3,4},
|
||||
["peng"] = {1,2,3,4},
|
||||
["pi"] = {1,2,3,4},
|
||||
["pian"] = {1,2,3,4},
|
||||
["piao"] = {1,2,3,4},
|
||||
["pie"] = {1,3,4},
|
||||
["pin"] = {1,2,3,4},
|
||||
["ping"] = {1,2,4},
|
||||
["po"] = {1,2,3,4},
|
||||
["pou"] = {1,2,3},
|
||||
["pu"] = {1,2,3,4},
|
||||
["qi"] = {1,2,3,4},
|
||||
["qia"] = {1,2,3,4},
|
||||
["qian"] = {1,2,3,4},
|
||||
["qiang"] = {1,2,3,4},
|
||||
["qiao"] = {1,2,3,4},
|
||||
["qie"] = {1,2,3,4},
|
||||
["qin"] = {1,2,3,4},
|
||||
["qing"] = {1,2,3,4},
|
||||
["qiong"] = {1,2,4},
|
||||
["qiu"] = {1,2,3,4},
|
||||
["qu"] = {1,2,3,4},
|
||||
["quan"] = {1,2,3,4},
|
||||
["que"] = {1,2,4},
|
||||
["qun"] = {1,2,3},
|
||||
["ran"] = {2,3,4},
|
||||
["rang"] = {1,2,3,4},
|
||||
["rao"] = {2,3,4},
|
||||
["re"] = {2,3,4},
|
||||
["ren"] = {2,3,4},
|
||||
["reng"] = {1,2},
|
||||
["ri"] = {4},
|
||||
["rong"] = {2,3,4},
|
||||
["rou"] = {2,3,4},
|
||||
["ru"] = {1,2,3,4},
|
||||
["rua"] = {2},
|
||||
["ruan"] = {2,3,4},
|
||||
["rui"] = {2,3,4},
|
||||
["run"] = {2,3,4},
|
||||
["ruo"] = {2,4},
|
||||
["sa"] = {1,2,3,4},
|
||||
["sai"] = {1,3,4},
|
||||
["san"] = {1,3,4},
|
||||
["sang"] = {1,3,4},
|
||||
["sao"] = {1,3,4},
|
||||
["se"] = {1,4},
|
||||
["sen"] = {1,3},
|
||||
["seng"] = {1,4},
|
||||
["sha"] = {1,2,3,4},
|
||||
["shai"] = {1,3,4},
|
||||
["shan"] = {1,2,3,4},
|
||||
["shang"] = {1,3,4},
|
||||
["shao"] = {1,2,3,4},
|
||||
["she"] = {1,2,3,4},
|
||||
["shei"] = {2},
|
||||
["shen"] = {1,2,3,4},
|
||||
["sheng"] = {1,2,3,4},
|
||||
["shi"] = {1,2,3,4},
|
||||
["shou"] = {1,2,3,4},
|
||||
["shu"] = {1,2,3,4},
|
||||
["shua"] = {1,3,4},
|
||||
["shuai"] = {1,3,4},
|
||||
["shuan"] = {1,4},
|
||||
["shuang"] = {1,3,4},
|
||||
["shui"] = {2,3,4},
|
||||
["shun"] = {3,4},
|
||||
["shuo"] = {1,4},
|
||||
["si"] = {1,2,3,4},
|
||||
["song"] = {1,2,3,4},
|
||||
["sou"] = {1,3,4},
|
||||
["su"] = {1,2,3,4},
|
||||
["suan"] = {1,3,4},
|
||||
["sui"] = {1,2,3,4},
|
||||
["sun"] = {1,3,4},
|
||||
["suo"] = {1,2,3,4},
|
||||
["ta"] = {1,2,3,4},
|
||||
["tai"] = {1,2,3,4},
|
||||
["tan"] = {1,2,3,4},
|
||||
["tang"] = {1,2,3,4},
|
||||
["tao"] = {1,2,3,4},
|
||||
["te"] = {4},
|
||||
["tei"] = {1},
|
||||
["teng"] = {1,2,4},
|
||||
["ti"] = {1,2,3,4},
|
||||
["tian"] = {1,2,3,4},
|
||||
["tiao"] = {1,2,3,4},
|
||||
["tie"] = {1,2,3,4},
|
||||
["tii"] = {2},
|
||||
["ting"] = {1,2,3,4},
|
||||
["tong"] = {1,2,3,4},
|
||||
["tou"] = {1,2,3,4},
|
||||
["tu"] = {1,2,3,4},
|
||||
["tuan"] = {1,2,3,4},
|
||||
["tui"] = {1,2,3,4},
|
||||
["tun"] = {1,2,3,4},
|
||||
["tuo"] = {1,2,3,4},
|
||||
["wa"] = {1,2,3,4},
|
||||
["wai"] = {1,3,4},
|
||||
["wan"] = {1,2,3,4},
|
||||
["wang"] = {1,2,3,4},
|
||||
["wei"] = {1,2,3,4},
|
||||
["wen"] = {1,2,3,4},
|
||||
["weng"] = {1,3,4},
|
||||
["wo"] = {1,3,4},
|
||||
["wu"] = {1,2,3,4},
|
||||
["xi"] = {1,2,3,4},
|
||||
["xia"] = {1,2,3,4},
|
||||
["xian"] = {1,2,3,4},
|
||||
["xiang"] = {1,2,3,4},
|
||||
["xiao"] = {1,2,3,4},
|
||||
["xie"] = {1,2,3,4},
|
||||
["xin"] = {1,2,3,4},
|
||||
["xing"] = {1,2,3,4},
|
||||
["xiong"] = {1,2,4},
|
||||
["xiu"] = {1,2,3,4},
|
||||
["xu"] = {1,2,3,4},
|
||||
["xuan"] = {1,2,3,4},
|
||||
["xue"] = {1,2,3,4},
|
||||
["xun"] = {1,2,4},
|
||||
["ya"] = {1,2,3,4},
|
||||
["yan"] = {1,2,3,4},
|
||||
["yang"] = {1,2,3,4},
|
||||
["yao"] = {1,2,3,4},
|
||||
["ye"] = {1,2,3,4},
|
||||
["yi"] = {1,2,3,4},
|
||||
["yin"] = {1,2,3,4},
|
||||
["ying"] = {1,2,3,4},
|
||||
["yo"] = {1},
|
||||
["yong"] = {1,2,3,4},
|
||||
["you"] = {1,2,3,4},
|
||||
["yu"] = {1,2,3,4},
|
||||
["yuan"] = {1,2,3,4},
|
||||
["yue"] = {1,3,4},
|
||||
["yun"] = {1,2,3,4},
|
||||
["za"] = {1,2,3},
|
||||
["zai"] = {1,3,4},
|
||||
["zan"] = {1,2,3,4},
|
||||
["zang"] = {1,3,4},
|
||||
["zao"] = {1,2,3,4},
|
||||
["ze"] = {2,4},
|
||||
["zei"] = {2},
|
||||
["zen"] = {1,3,4},
|
||||
["zeng"] = {1,3,4},
|
||||
["zha"] = {1,2,3,4},
|
||||
["zhai"] = {1,2,3,4},
|
||||
["zhan"] = {1,3,4},
|
||||
["zhang"] = {1,3,4},
|
||||
["zhao"] = {1,2,3,4},
|
||||
["zhe"] = {1,2,3,4},
|
||||
["zhei"] = {4},
|
||||
["zhen"] = {1,2,3,4},
|
||||
["zheng"] = {1,3,4},
|
||||
["zhi"] = {1,2,3,4},
|
||||
["zhong"] = {1,3,4},
|
||||
["zhou"] = {1,2,3,4},
|
||||
["zhu"] = {1,2,3,4},
|
||||
["zhua"] = {1,3},
|
||||
["zhuai"] = {1,3,4},
|
||||
["zhuan"] = {1,3,4},
|
||||
["zhuang"] = {1,3,4},
|
||||
["zhui"] = {1,3,4},
|
||||
["zhun"] = {1,3,4},
|
||||
["zhuo"] = {1,2,4},
|
||||
["zi"] = {1,2,3,4},
|
||||
["zong"] = {1,3,4},
|
||||
["zou"] = {1,3,4},
|
||||
["zu"] = {1,2,3,4},
|
||||
["zuan"] = {1,3,4},
|
||||
["zui"] = {1,2,3,4},
|
||||
["zun"] = {1,3,4},
|
||||
["zuo"] = {1,2,3,4},
|
||||
["ḿ"] = {2},
|
||||
}
|
||||
return wanxiang
|
||||
27
opencc/chinese_english.json
Normal file
27
opencc/chinese_english.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "Chinese to English",
|
||||
"segmentation": {
|
||||
"type": "mmseg",
|
||||
"dict": {
|
||||
"type": "text",
|
||||
"file": "chinese_english.txt"
|
||||
}
|
||||
},
|
||||
"conversion_chain": [
|
||||
{
|
||||
"dict": {
|
||||
"type": "group",
|
||||
"dicts": [
|
||||
{
|
||||
"type": "text",
|
||||
"file": "chinese_english.txt"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"file": "english_chinese.txt"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
54171
opencc/chinese_english.txt
Normal file
54171
opencc/chinese_english.txt
Normal file
File diff suppressed because it is too large
Load Diff
27
opencc/emoji.json
Normal file
27
opencc/emoji.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "Chinese to Emoji",
|
||||
"segmentation": {
|
||||
"type": "mmseg",
|
||||
"dict": {
|
||||
"type": "text",
|
||||
"file": "emoji.txt"
|
||||
}
|
||||
},
|
||||
"conversion_chain": [
|
||||
{
|
||||
"dict": {
|
||||
"type": "group",
|
||||
"dicts": [
|
||||
{
|
||||
"type": "text",
|
||||
"file": "emoji.txt"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"file": "others.txt"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
4910
opencc/emoji.txt
Normal file
4910
opencc/emoji.txt
Normal file
File diff suppressed because it is too large
Load Diff
43787
opencc/english_chinese.txt
Normal file
43787
opencc/english_chinese.txt
Normal file
File diff suppressed because it is too large
Load Diff
1335
opencc/others.txt
Normal file
1335
opencc/others.txt
Normal file
File diff suppressed because it is too large
Load Diff
47
release-please-config.json
Normal file
47
release-please-config.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/refs/heads/main/schemas/config.json",
|
||||
"bootstrap-sha": "3bc6a28c37385645de3e7a27e3f75faace624294",
|
||||
"release-type": "simple",
|
||||
"packages": {
|
||||
".": {
|
||||
"release-type": "simple",
|
||||
"extra-files": [
|
||||
"lua/wanxiang.lua"
|
||||
],
|
||||
"changelog-sections": [
|
||||
{
|
||||
"type": "feat",
|
||||
"section": "✨ 新特性"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"section": "📚 词库更新"
|
||||
},
|
||||
{
|
||||
"type": "perf",
|
||||
"section": "🔥 性能优化"
|
||||
},
|
||||
{
|
||||
"type": "fix",
|
||||
"section": "🐛 Bug 修复"
|
||||
},
|
||||
{
|
||||
"type": "refactor",
|
||||
"section": "💅 重构"
|
||||
},
|
||||
{
|
||||
"type": "docs",
|
||||
"section": "📖 文档"
|
||||
},
|
||||
{
|
||||
"type": "chore",
|
||||
"section": "🏡 杂项"
|
||||
},
|
||||
{
|
||||
"type": "ci",
|
||||
"section": "🤖 持续集成"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
1
version.txt
Normal file
1
version.txt
Normal file
@@ -0,0 +1 @@
|
||||
13.6.3
|
||||
24
wanxiang.dict.yaml
Normal file
24
wanxiang.dict.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
# Rime dictionary
|
||||
# encoding: utf-8
|
||||
#
|
||||
# rime配置的部署位置:
|
||||
# ~/.local/share/fcitx5/rime 或者 ~/.config/ibus/rime (Linux)
|
||||
# ~/Library/Rime (Mac OS)
|
||||
# %APPDATA%\Rime (Windows)
|
||||
#
|
||||
#
|
||||
|
||||
---
|
||||
name: wanxiang
|
||||
version: "LTS"
|
||||
sort: by_weight #字典初始排序,可選original或by_weight
|
||||
use_preset_vocabulary: false
|
||||
import_tables:
|
||||
- dicts/zi #字表,包含了所有带拼音的汉字
|
||||
- dicts/jichu #基础词库,2-3字词汇
|
||||
- dicts/lianxiang #联想词库,5字以上词汇,多用于输入前半段第二候选可以出来整段
|
||||
- dicts/cuoyin #错音错字,支持错音和错字输入的兼容,同时供超级注释lua使用会在输入错误音节打出的时候给予提示
|
||||
- dicts/duoyin #兼容词库,是基础词库的扩充,收录了多场景多种读音的词组
|
||||
- dicts/shici #诗词
|
||||
- dicts/diming #地名
|
||||
...
|
||||
641
wanxiang.schema.yaml
Normal file
641
wanxiang.schema.yaml
Normal file
@@ -0,0 +1,641 @@
|
||||
# Rime schema
|
||||
# encoding: utf-8
|
||||
# 方案说明
|
||||
schema:
|
||||
schema_id: wanxiang
|
||||
name: 万象拼音
|
||||
version: "LTS"
|
||||
author:
|
||||
- amzxyz
|
||||
description: |
|
||||
请勾选【万象拼音】以启用,万象拼音标准版本,带声调的词库,支持语法模型,全拼、简拼、整句、声调辅助筛选,拥有超越大厂的输入体验!
|
||||
【文本框输入:/pinyin全拼,/zrm自然码,/flypy小鹤,/mspy,/sogou,/pyjj等,详见README.md】
|
||||
dependencies:
|
||||
- wanxiang_mixedcode #中英文混合词汇
|
||||
- wanxiang_reverse # 部件拆字,反查及辅码
|
||||
|
||||
# 开关
|
||||
# reset: 默认状态。注释掉后,切换窗口时不会重置到默认状态。
|
||||
# states: 方案选单显示的名称。可以注释掉,仍可以通过快捷键切换。
|
||||
# abbrev: 默认的缩写取 states 的第一个字符,abbrev 可自定义一个字符
|
||||
switches:
|
||||
- name: ascii_mode # 中英输入状态
|
||||
states: [ 中文, 英文 ]
|
||||
- name: ascii_punct # 中英标点,可以在中文输入状态输入英文符号
|
||||
states: [ 中标, 英标 ]
|
||||
- name: full_shape #全角、半角字符输出
|
||||
states: [ 半角, 全角 ]
|
||||
- name: emoji #候选出现emoji滤镜,会显示在相应的候选后面,万象侧重于tips提示,避免候选被占用,因此默认为reset: 0,归属opencc emoji滤镜
|
||||
states: [表情关, 表情开]
|
||||
- name: chinese_english #候选进入翻译模式滤镜,会显示在相应的候选后面,万象侧重于tips提示,避免候选被占用,归属opencc 翻译滤镜
|
||||
states: [ 翻译关, 翻译开 ]
|
||||
- options: [ raw_input, tone_display, full_pinyin ] #开启后在输入编码的位置实时转换为带声调全拼或者不带声调全拼,不开启则采用系统配置原始编码,影响的是preedit_format,归属:super_preedit.lua
|
||||
states: [ 原编码, 有声调, 无声调 ]
|
||||
# reset: 2 #对于开关组从0开始数,第几个就reset几可设为默认
|
||||
- options: [ s2s, s2t, s2hk, s2tw ] # 简繁转换开关组,可以在一个空选项和多个实际“- simplifier@s2hk”引入的项目之前切换,这是一个开关组,你可以将其中任意一个s2s等设置为toggle快捷键,多次按下将轮询
|
||||
states: [ 简体, 通繁, 港繁, 臺繁 ]
|
||||
- name: tone_hint #开启后在候选的注释里面实时显示全拼声调,不开启则采用系统配置,影响的是comment_format,归属:super_comment.lua
|
||||
states: [ 读音关, 读音开 ]
|
||||
- name: super_tips #开启后在输入编码后面的提示区显示实时的提示数据,受tips数据库影响,表情、翻译、车牌、符号等对应关系数据,并可实现句号上屏,不开启则默认,影响的是segment.prompt参数,归属:super_tips.lua
|
||||
states: [ 提示关, 提示开 ]
|
||||
reset: 1
|
||||
- name: charset_filter #字符集过滤,默认开启8105通规显示,即小字集,可通过开关实时开启全字集,快捷键配套ctrl+g,归属:super_filter.lua
|
||||
states: [ 小字集, 大字集 ]
|
||||
reset: 1
|
||||
- name: char_priority #多体现在编码重合但候选有单字或者多字的情况`引导的辅码查词时是否单字优先,全拼常见,类似于特定编码情况下、反查状态下的调序能力。归属:super_lookup.lua
|
||||
states: [词组先, 单字先]
|
||||
- options: [ mixed, zh_only, en_only ]
|
||||
states: [ 混合输入, 仅中文, 仅英文 ]
|
||||
|
||||
# 输入引擎
|
||||
engine:
|
||||
processors:
|
||||
- lua_processor@*select_character #以词定字,默认左中括号上屏一个词的前一个字,右中括号上屏一个词的后一个字
|
||||
- lua_processor@*partial_commit #通过ctrl+1~0局部提交10个字以内的句子的前几个字(一般为正确的前几个)使用时要遵循合理的分词结构能促进后续编码打出正确的词汇
|
||||
- lua_processor@*letter_selector #在N模式R模式下输入数字被视为编码,那么如何上屏呢,现在除了方向键还提供qwertyuio对照1-9来选词
|
||||
- lua_processor@*quick_symbol_text #快符引导以及重复上屏,配合quick_symbol_text顶层配置清单定义扩展按键
|
||||
- lua_processor@*super_tips #超级提示模块:表情、简码、翻译、化学式、等等靠你想象
|
||||
- lua_processor@*tone_fallback #声调辅助回退,当你输入声调数字错误时,继续输入正确的而不用回退删除
|
||||
- lua_processor@*super_sequence*P #手动排序,高亮候选 ctrl+j左移动 ctrl+k 右移动 ctrl+l 移除位移 ctrl+p 置顶
|
||||
- lua_processor@*limit_repeated #用于限制最大候选长度以及最大重复输入声母编码长度,避免性能异常
|
||||
- lua_processor@*backspace_limit #防止连续 Backspace 在编码为空时删除已上屏内容
|
||||
- lua_processor@*kp_number_processor #管理小键盘的处理逻辑,有输入中数字不上屏和数字一直不上屏设置可选
|
||||
- ascii_composer #处理英文模式及中英文切换
|
||||
- recognizer #与 matcher 搭配,处理符合特定规则的输入码,如网址、反查等 tags
|
||||
- key_binder #在特定条件下将按键绑定到其他按键,如重定义逗号、句号为候选翻页、开关快捷键等
|
||||
- lua_processor@*key_binder #绑定按键扩展能力,支持正则扩展将按键生效情景更加细化
|
||||
- speller #拼写处理器,接受字符按键,编辑输入
|
||||
- punctuator #符号处理器,将单个字符按键直接映射为标点符号或文字
|
||||
- selector #选字处理器,处理数字选字键〔可以换成别的哦〕、上、下候选定位、换页
|
||||
- navigator #处理输入栏内的光标移动
|
||||
- express_editor #编辑器,处理空格、回车上屏、回退键
|
||||
segmentors:
|
||||
- ascii_segmentor #标识英文段落〔譬如在英文模式下〕字母直接上屛
|
||||
- matcher #配合 recognizer 标识符合特定规则的段落,如网址、反查等,加上特定 tag
|
||||
- abc_segmentor #标识常规的文字段落,加上 abc 这个 tag
|
||||
- affix_segmentor@wanxiang_reverse #反查 tag
|
||||
- affix_segmentor@add_user_dict #自造词tag
|
||||
- punct_segmentor #标识符号段落〔键入标点符号用〕加上 punct 这个 tag
|
||||
- fallback_segmentor #标识其他未标识段落,必须放在最后帮助tag模式切换后回退重新处理
|
||||
translators:
|
||||
- punct_translator #配合 punct_segmentor 转换标点符号
|
||||
- script_translator #脚本翻译器,用于拼音、粤拼等基于音节表的输入方案
|
||||
- lua_translator@*version_display #输入'/wx',显示万象项目网址和当前版本号
|
||||
- lua_translator@*set_schema #输入'/zrm',快速切换为自然码双拼, /flypy→小鹤双拼 /mspy→微软双拼 /zrm→自然码 /sogou→搜狗双拼 /abc→智能ABC /ziguang→紫光双拼 /pyjj→拼音加加 /gbpy→国标双拼 /lxsq→乱序17 /pinyin→全拼
|
||||
- lua_translator@*shijian #农历、日期、节气、节日、时间、周、问候模板等等,触发清单看下文
|
||||
- lua_translator@*unicode #通过输入大写U引导,并输入Unicode编码获得汉字输出
|
||||
- lua_translator@*number_translator #数字、金额大写,通过输入大写R1234获得候选输出
|
||||
- lua_translator@*super_calculator #超级计算器,Lua内查看高级用法
|
||||
- lua_translator@*input_statistics #一个输入统计的脚本,以日、周、月、年等维度的统计
|
||||
- table_translator@custom_phrase #自定义短语 custom_phrase.txt,用于置顶自定义编码候选词
|
||||
- table_translator@chengyu #简码成语词汇表导入
|
||||
- table_translator@wanxiang_mixedcode #中英等混合词汇表导入
|
||||
- table_translator@wanxiang_reverse #挂接部件组字和笔画反查
|
||||
- script_translator@add_user_dict #按需自造词
|
||||
- script_translator@user_dict_set #使用自造词
|
||||
filters:
|
||||
- reverse_lookup_filter@radical_reverse_lookup #部件拆字滤镜,放在super_comment前面,进一步被超级注释处理以获得拼音编码的提示
|
||||
- lua_filter@*auto_phrase #无感造词,关闭调频的时候将汉字写入次翻译器,当没有英文候选的时候追加\上屏可完成英文造词
|
||||
- lua_filter@*super_comment_preedit #超级注释模块、超级preedit,支持错词提示、辅助码显示,部件组字读音注释,有声调、无声调全拼编码的转换,支持个性化配置和关闭相应的功能,详情搜索super_comment_preedit进行详细配置
|
||||
- simplifier@emoji #Emoji滤镜
|
||||
- simplifier@s2t #简繁切换通繁
|
||||
- simplifier@s2tw #简繁切换台繁
|
||||
- simplifier@s2hk #简繁切换港繁
|
||||
- simplifier@chinese_english #中英翻译滤镜
|
||||
- lua_filter@*super_sequence*F #手动排序,对高亮候选 ctrl+j左移动 ctrl+k 右移动 ctrl+0 移除位移
|
||||
- lua_filter@*super_filter #功能太多详见Lua文件
|
||||
- lua_filter@*super_lookup #字词输入中反查辅助筛选
|
||||
- uniquifier # 去重
|
||||
|
||||
grammar:
|
||||
language: wanxiang-lts-zh-hans
|
||||
collocation_max_length: 8 #命中的最长词组
|
||||
collocation_min_length: 2 #命中的最短词组,搭配词频健全的词库时候应当最小值设为3避开2字高频词
|
||||
collocation_penalty: -10 #默认-12 对常见搭配词组施加的惩罚值。较高的负值会降低这些搭配被选中的概率,防止过于频繁地出现某些固定搭配。
|
||||
non_collocation_penalty: -17 #默认-12 对非搭配词组施加的惩罚值。较高的负值会降低非搭配词组被选中的概率,避免不合逻辑或不常见的词组组合。
|
||||
weak_collocation_penalty: -24 #默认-24 对弱搭配词组施加的惩罚值。保持默认值通常是为了有效过滤掉不太常见但仍然合理的词组组合。
|
||||
rear_penalty: -18 #默认-18 对词组中后续词语的位置施加的惩罚值。较高的负值会降低某些词语在句子后部出现的概率,防止句子结构不自然。
|
||||
|
||||
super_comment: # 超级注释模块,子项配置 true 开启,false 关闭
|
||||
candidate_length: 2 # 候选词辅助码提醒的生效长度,0为关闭 但同时清空其它,应当使用上面开关来处理
|
||||
corrector_type: "〔comment〕" # 随意更换左右括号,比如"〔comment〕" 不加括号为无括号,comment占位不能动
|
||||
chaifen: "〔chaifen〕" # 随意更换左右括号,比如"〔chaifen〕" 不加括号为无括号,chaifen占位不能动
|
||||
|
||||
# Tips 配置项
|
||||
tips:
|
||||
# 禁用的 tips 类型,初始化 tips 数据库的时候会直接忽略相关规则,修改部署后生效
|
||||
# 可选项为:偏旁,符号,化学式,时间,符号,组字,翻译,表情,货币,车牌
|
||||
disabled_types: []
|
||||
|
||||
#在8105基础上你可以通过黑白名单微调你自己的字符集过滤清单,主数据库位于lua/charset.bin不可编辑
|
||||
charsetlist: []
|
||||
charsetblacklist: []
|
||||
|
||||
#shijian:仅仅作为提示使用,编码已经写死,引导键可以在key_binder下修改前缀
|
||||
#时间:osj 或者 /sj
|
||||
#日期:orq 或者 /rq
|
||||
#农历:onl 或者 /nl
|
||||
#星期:oxq 或者 /xq
|
||||
#今年第几周:oww 或者 /ww
|
||||
#节气:ojq 或者 /jq
|
||||
#日期+时间:odt 或者 /dt
|
||||
#时间戳:ott 或者 /tt
|
||||
#大写N日期:N20250315 或者N0312不带年
|
||||
#节日:ojr 或者 /jr
|
||||
#问候模板:/day 或者 oday
|
||||
# 通用日期时间格式化函数(供 /rq、/sj、/dt、N0101、N20150101 场景复用)
|
||||
# 支持转义:
|
||||
# \X —— 转义单个字符 X,按字面量输出(如 \Y \m \H 等)
|
||||
# [[...]] —— 区块整体按字面量输出
|
||||
#
|
||||
# 约定占位符:
|
||||
# 【日期】
|
||||
# Y 四位年份 0000-9999 例:2025
|
||||
# y 两位年份 00-99 例:25
|
||||
# m 月(前导零) 01-12 例:02
|
||||
# n 月(不带前导零) 1-12 例:2
|
||||
# d 日(前导零) 01-31 例:09
|
||||
# j 日(不带前导零) 1-31 例:9
|
||||
#
|
||||
# 【时间】
|
||||
# H 24小时(前导零) 00-23 例:08
|
||||
# G 24小时(不带零) 0-23 例:8
|
||||
# I 12小时(前导零) 01-12 例:08
|
||||
# l 12小时(不带零) 1-12 例:8 (注意是小写 L)
|
||||
# M 分钟(前导零) 00-59 例:05
|
||||
# S 秒(前导零) 00-59 例:09
|
||||
# p am/pm(小写) am / pm
|
||||
# P AM/PM(大写) AM / PM
|
||||
# 【时区】
|
||||
# O 带冒号格式 +08:00、-04:30、+05:45
|
||||
# o 不带冒号格式 +0800、-0430、+0545
|
||||
date_formats:
|
||||
- "Y年m月d日"
|
||||
- "Y-m-d"
|
||||
- "Y/m/d"
|
||||
- "Y.m.d"
|
||||
- "Ymd"
|
||||
- "Y年n月j日"
|
||||
- "y年n月j日"
|
||||
- "n月j日"
|
||||
time_formats:
|
||||
- "H:M"
|
||||
- "H点M分"
|
||||
- "H:M:S"
|
||||
- "H时M分S秒"
|
||||
- "下午I:M"
|
||||
- "I:M P"
|
||||
datetime_formats:
|
||||
- "Y-m-d H:M:S"
|
||||
- "Y-m-dTH:M:S O"
|
||||
- "YmdHMS"
|
||||
- "Y年m月d日 H点M分"
|
||||
- "y/m/d I:M p"
|
||||
|
||||
#常规状态下数字转换成相应的字符,由超级preedit接管
|
||||
tone_preedit:
|
||||
"7": "¹"
|
||||
"8": "²"
|
||||
"9": "³"
|
||||
"0": "⁴"
|
||||
|
||||
# a/、单字母组合,触发预设编码自动上屏快符,支持将值设为"repeat" 以支持对应按键重复上屏功能,custom>schema>lua最终合并键值
|
||||
# 现在就支持26字母快符,结合成对符号输入,这边的压力小一些
|
||||
quick_symbol_text:
|
||||
trigger: "^([a-z])/$"
|
||||
symkey:
|
||||
q: "repeat"
|
||||
w: "?"
|
||||
e: "("
|
||||
r: ")"
|
||||
t: "~"
|
||||
y: "·"
|
||||
u: "『"
|
||||
i: "』"
|
||||
o: "〖"
|
||||
p: "〗"
|
||||
a: "!"
|
||||
s: "……"
|
||||
d: "、"
|
||||
f: "“"
|
||||
g: "”"
|
||||
h: "‘"
|
||||
j: "’"
|
||||
k: "【"
|
||||
l: "】"
|
||||
z: "。”"
|
||||
x: "?”"
|
||||
c: "!”"
|
||||
v: "——"
|
||||
b: "%"
|
||||
n: "《"
|
||||
m: "》"
|
||||
|
||||
#通过在有候选的情况下,通过末尾检测到形如\a来触发为第一候选进行成对符号包裹例如nihao\c 候选[你好]
|
||||
#trigger只能设置为单符号,因为按下一次锁定第一候选,按下映射开始包裹符号pro用户不能设置为/
|
||||
#两个字符可以不用|默认前后分割,需要明确区分前后的使用|分割,可以有一侧为空,不可以使用多个||
|
||||
paired_symbols:
|
||||
#sort_window: 10
|
||||
trigger: "\\" #(注意反斜杠这是转义写法\\使用时\单反斜杠即可)
|
||||
mirror: true #包裹后完全替换第一候选true,原候选后移到第二false
|
||||
symkey:
|
||||
# ===== 基本括号与引号 =====
|
||||
a: "[]" # 方括号
|
||||
b: "【】" # 黑方头括号
|
||||
c: "❲❳" # 双大括号 / 装饰括号
|
||||
d: "〔〕" # 方头括号
|
||||
e: "⟮⟯" # 小圆括号 / 装饰括号
|
||||
f: "⟦⟧" # 双方括号 / 数学集群括号
|
||||
g: "「」" # 直角引号
|
||||
# h: 预留用于 Markdown 一级标题
|
||||
i: "『』" # 双直角引号
|
||||
j: "<>" # 尖括号
|
||||
k: "《》" # 书名号(双)
|
||||
l: "〈〉" # 书名号(单)
|
||||
m: "‹›" # 法文单书名号
|
||||
n: "«»" # 法文双书名号
|
||||
o: "⦅⦆" # 白圆括号
|
||||
p: "⦇⦈" # 白方括号
|
||||
q: "()" # 圆括号
|
||||
r: "〖〗" # 花括号扩展 / 装饰括号
|
||||
s: "[]" # 全角方括号
|
||||
t: "⟨⟩" # 数学角括号
|
||||
u: "〈〉" # 数学尖括号
|
||||
v: "❰❱" # 装饰角括号
|
||||
w: "()" # 全角圆括号
|
||||
x: "{}" # 全角花括号
|
||||
y: "⟪⟫" # 双角括号
|
||||
z: "{}" # 花括号
|
||||
|
||||
# ===== 扩展括号族 / 引号 =====
|
||||
dy: "''" # 英文单引号
|
||||
sy: "\"\"" # 英文双引号
|
||||
zs: "“”" # 中文弯双引号
|
||||
zd: "‘’" # 中文弯单引号
|
||||
fy: "``" # 反引号
|
||||
|
||||
# ===== 双字母括号族 =====
|
||||
aa: "〚〛" # 双中括号
|
||||
bb: "〘〙" # 双中括号(小)
|
||||
cc: "〚〛" # 双中括号(重复,可用于 Lua 匹配)
|
||||
dd: "❨❩" # 小圆括号装饰
|
||||
ee: "❪❫" # 小圆括号装饰
|
||||
ff: "❬❭" # 小尖括号装饰
|
||||
gg: "⦉⦊" # 双弯方括号
|
||||
ii: "⦍⦎" # 双弯方括号
|
||||
jj: "⦏⦐" # 双弯方括号
|
||||
kk: "⦑⦒" # 双弯方括号
|
||||
ll: "❮❯" # 小尖括号装饰
|
||||
mm: "⌈⌉" # 上取整 / 数学符号
|
||||
nn: "⌊⌋" # 下取整 / 数学符号
|
||||
oo: "⦗⦘" # 双方括号装饰(补齐)
|
||||
pp: "⦙⦚" # 双方括号装饰(补齐)
|
||||
qq: "⟬⟭" # 小双角括号
|
||||
rr: "❴❵" # 花括号装饰
|
||||
ss: "⌜⌝" # 数学上角符号
|
||||
tt: "⌞⌟" # 数学下角符号
|
||||
uu: "⸢⸣" # 装饰方括号
|
||||
vv: "⸤⸥" # 装饰方括号
|
||||
ww: "﹁﹂" # 中文书名号 / 注释引号
|
||||
xx: "﹃﹄" # 中文书名号 / 注释引号
|
||||
yy: "⌠⌡" # 数学 / 程序符号
|
||||
zz: "⟅⟆" # 数学 / 装饰括号
|
||||
|
||||
# ===== Markdown / 标记 =====
|
||||
md: "**|**" # Markdown 粗体
|
||||
jc: "**|**" # 加粗
|
||||
it: "__|__" # 斜体
|
||||
st: "~~|~~" # 删除线
|
||||
eq: "==|==" # 高亮
|
||||
ln: "`|`" # 行内代码
|
||||
cb: "```|```" # 代码块
|
||||
qt: "> |" # 引用
|
||||
ul: "- |" # 无序列表项
|
||||
ol: "1. |" # 有序列表项
|
||||
lk: "[|](url)" # 链接
|
||||
im: "" # 图片
|
||||
h: "# |" # 一级标题
|
||||
hh: "## |" # 二级标题
|
||||
hhh: "### |" # 三级标题
|
||||
hhhh: "#### |" # 四级标题
|
||||
sp: "\\|" # 反斜杠转义
|
||||
br: "| " # 换行
|
||||
cm: "<!--|-->" # 注释
|
||||
|
||||
# ===== 运算与标记符 =====
|
||||
pl: "++"
|
||||
mi: "--"
|
||||
sl: "//"
|
||||
bs: "\\\\"
|
||||
at: "@@"
|
||||
dl: "$$"
|
||||
pc: "%%"
|
||||
an: "&&"
|
||||
cr: "^^"
|
||||
cl: "::"
|
||||
sc: ";;"
|
||||
ex: "!!"
|
||||
qu: "??"
|
||||
sb: "sb"
|
||||
|
||||
# Lua 配置:计算器触发关键字
|
||||
calculator:
|
||||
trigger: "V"
|
||||
|
||||
# 主翻译器,拼音
|
||||
translator:
|
||||
dictionary: wanxiang # 挂载主词库
|
||||
# packs: user #导入根目录下名称为user.dict.yaml的自定义固定词典
|
||||
#prism: wanxiang # 多方案共用一个词库时,为避免冲突,需要用 prism 指定一个名字。
|
||||
enable_completion: true # 启用候选词补全
|
||||
# user_dict: zrm.userdb # 用户词典的文件名称
|
||||
# db_class: tabledb #开启后就不会产生wanxiang.userdb这样的文件夹,会直接输出文本wanxiang.txt同时无法使用同步能力,可设 tabledb〔文本〕或 userdb〔二进制〕
|
||||
enable_user_dict: true # 是否开启自动调频,即开启用户词典
|
||||
# enable_encoder: true #是否开启自动造词
|
||||
# enable_sentence: false #是否开启自动造句
|
||||
# enable_correction: false #是否开启自动纠错
|
||||
# encode_commit_history: true # 预留历史上屏自动编码成词
|
||||
core_word_length: 4 # >0 启用,按段学词 + 相邻段拼接
|
||||
max_word_length: 7 # >0 启用,过长短语不记整词,只加元素权重
|
||||
contextual_suggestions: false #模型用来开启词组权重预测,效果一般关闭
|
||||
max_homophones: 5
|
||||
max_homographs: 5
|
||||
initial_quality: 3 #初始质量拼音的权重应该比英文大
|
||||
spelling_hints: 30 #将注释以词典code字符串形式完全暴露,通过super_comment.lua完全接管,灵活配置。
|
||||
always_show_comments: true # Rime 默认在 preedit 等于 comment 时取消显示 comment,这里强制一直显示,供super_comment_preedit.lua做判断用。
|
||||
comment_format: {comment} #将注释以词典字符串形式完全暴露,通过super_preedit.lua完全接管,灵活配置。
|
||||
#disable_user_dict_for_patterns: #如果你开启调频,需要一并考虑这个配置是否需要,基本的6码3字不调频,你可以自定义,目前的逻辑是依然记录用户词但满足规则的不输出不被使用
|
||||
# - "^[a-z]{1,6}"
|
||||
|
||||
# 自定义短语
|
||||
custom_phrase:
|
||||
dictionary: ""
|
||||
user_dict: custom_phrase #需要手动创建 custom_phrase.txt 文件
|
||||
db_class: stabledb #可设 tabledb〔文本〕或 userdb〔二进制〕
|
||||
enable_completion: false #补全提示
|
||||
enable_sentence: false #禁止造句
|
||||
initial_quality: 99 #custom_phrase 的权重应该比 pinyin 和 wanxiang_en 大
|
||||
|
||||
|
||||
# 简码词库导入位于dicts得chengyu.txt文件词库
|
||||
chengyu:
|
||||
dictionary: ""
|
||||
user_dict: dicts/chengyu
|
||||
db_class: stabledb
|
||||
enable_sentence: false
|
||||
enable_completion: false
|
||||
initial_quality: 1.3
|
||||
|
||||
# 中文、英文、数字、符号等混合词汇
|
||||
wanxiang_mixedcode:
|
||||
dictionary: wanxiang_mixedcode
|
||||
user_dict: en
|
||||
enable_completion: true
|
||||
enable_sentence: false
|
||||
initial_quality: 2
|
||||
comment_format:
|
||||
- xform/^.+$//
|
||||
|
||||
|
||||
# Emoji
|
||||
emoji:
|
||||
option_name: emoji
|
||||
opencc_config: emoji.json
|
||||
tags: [abc]
|
||||
inherit_comment: false
|
||||
|
||||
|
||||
#中文转英文
|
||||
chinese_english:
|
||||
option_name: chinese_english
|
||||
opencc_config: chinese_english.json
|
||||
tips: char
|
||||
inherit_comment: false
|
||||
|
||||
# 简繁切换
|
||||
s2t:
|
||||
option_name: s2t
|
||||
opencc_config: s2t.json # s2t.json | s2hk.json | s2tw.json | s2twp.json
|
||||
tips: none # 转换提示: all 都显示 | char 仅单字显示 | none 不显示。
|
||||
tags: [ abc ] # 限制在对应 tag,不对其他如反查的内容做简繁转换
|
||||
|
||||
s2hk:
|
||||
opencc_config: s2hk.json
|
||||
option_name: s2hk
|
||||
tags: [abc]
|
||||
|
||||
s2tw:
|
||||
opencc_config: s2tw.json
|
||||
option_name: s2tw
|
||||
tags: [abc]
|
||||
|
||||
# 部件拆字反查
|
||||
wanxiang_reverse:
|
||||
tag: wanxiang_reverse
|
||||
dictionary: wanxiang_reverse
|
||||
db_class: stabledb
|
||||
enable_user_dict: false
|
||||
enable_sentence: false
|
||||
prefix: "`" # 反查前缀(反查时前缀会消失),与 recognizer/patterns/wanxiang_reverse 匹配
|
||||
tips: "〔反查:拆分|笔画〕"
|
||||
|
||||
# 部件拆字滤镜
|
||||
radical_reverse_lookup:
|
||||
tags: [ wanxiang_reverse ] #起作用tag范围
|
||||
overwrite_comment: true #是否覆盖其他提示
|
||||
dictionary: wanxiang #带音调的词典
|
||||
|
||||
wanxiang_lookup: #设置归属于super_lookup.lua
|
||||
tags: [ abc ] # 检索当前tag的候选
|
||||
key: "`" # 输入中反查引导符,要添加到 speller/alphabet
|
||||
lookup: [ wanxiang_reverse ] #反查滤镜数据库,万象都合并为一个了
|
||||
|
||||
# 处理符合特定规则的输入码,如网址、反查
|
||||
recognizer:
|
||||
import_preset: default # 从 default.yaml 继承通用的
|
||||
patterns: # 再增加方案专有的:
|
||||
punct: "^/([0-9]|10|[A-Za-z]+)$" # 响应 symbols.yaml 的 symbols
|
||||
wanxiang_reverse: "^`[A-Za-z]*$" # 响应部件拆字与笔画的反查,与 wanxiang_reverse/prefix 匹配
|
||||
#add_user_dict: "^ac[A-Za-z/`']*$" #引导式造词
|
||||
unicode: "^U[a-f0-9]+" # U 作为触发前缀,响应 lua_translator@unicode,输出 Unicode 字符
|
||||
number: "^R[0-9]+[.]?[0-9]*" # R 作为触发前缀, 响应 lua_translator@number_translator,数字金额大写
|
||||
yr1: "^N0[1-9]?0?[1-9]?"
|
||||
yr2: "^N1[02]?0?[1-9]?"
|
||||
yr3: "^N0[1-9]?[1-2]?[1-9]?"
|
||||
yr4: "^N1[02]?[1-2]?[1-9]?"
|
||||
yr5: "^N0[1-9]?3?[01]?"
|
||||
yr6: "^N1[02]?3?[01]?"
|
||||
nyr1: "^N19?[0-9]?[0-9]?[0-9]?[0-9]?[0-9]?[0-9]?"
|
||||
nyr2: "^N20?[0-9]?[0-9]?[0-9]?[0-9]?[0-9]?[0-9]?"
|
||||
calculator: "^V.*$" # V 作为触发前缀,计算器功能引导
|
||||
#add_user_dict: "^ac[A-Za-z/`']*$" #自造词引导方式
|
||||
email: "^[A-Za-z][-_.0-9A-Za-z]*@.*$" # email @ 之后不上屏
|
||||
url: "^(www[.]|https?:|ftp[.:]|mailto:|file:).*$|^[a-z]+[.].+$" # URL
|
||||
# 给 kp_number_processor 用的“命令模式 Lua 正则集合”
|
||||
# 能够细化哪些情况数字是用来当作输入编码的,不在正则范围的将用于上屏
|
||||
# 直接加载上面的正则会遇到不符合预期的情况,毕竟Lua正则逻辑与之不同
|
||||
kp_number:
|
||||
#小键盘数字处理逻辑
|
||||
# "compose" : 小键盘数字始终参与编码
|
||||
# "auto" : 输入中 push,空闲时 commit(默认)
|
||||
kp_number_mode: auto
|
||||
patterns:
|
||||
# /符号引导模式
|
||||
- "^/[0-9]$"
|
||||
- "^/10$"
|
||||
- "^/[A-Za-z]+$"
|
||||
# U模式
|
||||
- "^U[%da-f]+$"
|
||||
# R模式
|
||||
- "^R[0-9]+%.?[0-9]*$"
|
||||
# N模式
|
||||
# Lua 不支持 {1,8},改成等价写法:N 后 1~8 个数字
|
||||
- "^N0[1-9]?0?[1-9]?$"
|
||||
- "^N1[02]?0?[1-9]?$"
|
||||
- "^N0[1-9]?[1-2]?[1-9]?$"
|
||||
- "^N1[02]?[1-2]?[1-9]?$"
|
||||
- "^N0[1-9]?3?[01]?$"
|
||||
- "^N1[02]?3?[01]?$"
|
||||
- "^N19?[0-9]?[0-9]?[01]?[0-2]?[0-3]?[0-9]?$"
|
||||
- "^N20?[0-9]?[0-9]?[01]?[0-2]?[0-3]?[0-9]?$"
|
||||
# 计算器模式
|
||||
- "^V.*$"
|
||||
# email
|
||||
- "^[A-Za-z][-_.0-9A-Za-z]*@.*$"
|
||||
# URL 前缀几种:
|
||||
- "^www[.].*$"
|
||||
- "^https?:.*$"
|
||||
- "^ftp[.:].*$"
|
||||
- "^mailto:.*$"
|
||||
- "^file:.*$"
|
||||
- "^webdav:.*$"
|
||||
# 标点符号
|
||||
# punctuator 下面有三个子项:
|
||||
# 设置为一个映射,就自动上屏;设置为多个映射,如 '/' : [ '/', ÷ ] 则进行复选。
|
||||
# full_shape: 全角没改,使用预设值
|
||||
# half_shape: 标点符号全部直接上屏,和 macOS 自带输入法的区别是
|
||||
# '|' 是半角的,
|
||||
# '~' 是半角的,
|
||||
# '`'(反引号)没有改成 '·'(间隔号)。
|
||||
# symbols Rime 的预设配置是以 '/' 前缀开头输出一系列字符,自定义的修改 symbols.yaml
|
||||
punctuator:
|
||||
digit_separators: ",." #数字分隔符,系统逻辑是在中文状态下输入数字后继续输入句号按下两次即输入半角状态
|
||||
__include: wanxiang_symbols:/symbol_table # 从 wanxiang_symbols.yaml 导入所有符号配置
|
||||
|
||||
# 从 default 继承快捷键
|
||||
key_binder:
|
||||
import_preset: default # 从 default.yaml 继承通用的
|
||||
sequence: # Lua 配置:手动排序的快捷键 super_sequence.lua,不要用方向键,各种冲突,一定要避免冲突
|
||||
up: "Control+j" # 上移
|
||||
down: "Control+k" # 下移
|
||||
reset: "Control+l" # 重置
|
||||
pin: "Control+p" # 置顶
|
||||
# Lua 配置: shijian.lua 的引导符,涉及:日期、时间、节日、节气、生日、问候模板等功能
|
||||
shijian_keys: ["/", "o"]
|
||||
# Lua 配置: 超级tips上屏按键
|
||||
tips_key: "comma" #修改时候去default找
|
||||
# Lua 配置: 以词定字(上屏当前词句的第一个或最后一个字),和中括号翻页有冲突
|
||||
select_first_character: "bracketleft" # 左中括号 [
|
||||
select_last_character: "bracketright" # 右中括号 ]
|
||||
bindings: # 也可以再增加方案专有的
|
||||
# 通过按下/发送/+1节约一个按键,不冲突的时候可以开启
|
||||
#- { match: "[a-z]{1,4}", accept: "/", send_sequence: "/1" }
|
||||
# 翻页 , .
|
||||
# - { when: paging, accept: comma, send: Page_Up }
|
||||
# - { when: has_menu, accept: period, send: Page_Down }
|
||||
# 翻页 [ ]
|
||||
# - { when: paging, accept: bracketleft, send: Page_Up }
|
||||
# - { when: has_menu, accept: bracketright, send: Page_Down }
|
||||
# 翻页 - =
|
||||
- { when: has_menu, accept: minus, send: Page_Up }
|
||||
- { when: has_menu, accept: equal, send: Page_Down }
|
||||
# Option/Alt + ←/→ 切换光标至下/上一个拼音
|
||||
- { when: always, toggle: ascii_punct, accept: Control+Shift+3 } # 切换中英标点
|
||||
- { when: always, toggle: ascii_punct, accept: Control+Shift+numbersign } # 切换中英标点
|
||||
- { when: always, toggle: s2t, accept: Control+Shift+4 } # 切换简繁
|
||||
- { when: always, toggle: s2t, accept: Control+Shift+dollar } # 切换简繁
|
||||
- { when: composing, accept: Alt+Left, send: Shift+Left }
|
||||
- { when: composing, accept: Alt+Right, send: Shift+Right }
|
||||
- { when: composing, accept: Control+w, send: Control+BackSpace }
|
||||
#分号用于次选,微软、搜狗双拼不可启用
|
||||
#- { when: has_menu, accept: semicolon, send: 2 }
|
||||
#使用Control+e进入翻译模式
|
||||
- { when: has_menu, accept: "Control+e", toggle: chinese_english}
|
||||
#使用快捷键Control+a开启和关闭辅助码显示
|
||||
- { when: has_menu, accept: "Control+a", toggle: tone_hint }
|
||||
#通过快捷键Control+s使得输入码显示音调
|
||||
- { when: has_menu, accept: "Control+s", toggle: tone_display }
|
||||
#通过快捷键Control+t开启超级tips
|
||||
- { when: has_menu, accept: "Control+t", toggle: super_tips }
|
||||
#通过快捷键Control+q开启超级tips
|
||||
- { when: has_menu, accept: "Control+q", toggle: corrector }
|
||||
#通过快捷键Control+g开启字符集过滤
|
||||
- { when: has_menu, accept: "Control+g", toggle: charset_filter }
|
||||
#通过快捷键Control+q切换中文、英文、混合模式
|
||||
- { when: has_menu, accept: "Control+q", toggle: zh_only }
|
||||
# 使用 tab 在不同音节之间跳转
|
||||
- { when: has_menu, accept: "Tab", send: "Control+Right" }
|
||||
- { when: composing, accept: "Tab", send: "Control+Right" }
|
||||
#当tab第一个字补码正确后,可以使用Ctrl+tab进行上屏并依次补码
|
||||
- { when: composing, accept: "Control+Tab", send_sequence: '{Home}{Shift+Right}{1}{Shift+Right}' }
|
||||
#当输入编码后发现没有词,则通过双击``进入造词模式而且不需要删除编码,这个功能与``直接引导相呼应相配合
|
||||
- { match: "^.*`$", accept: "`", send_sequence: '{BackSpace}{Home}{`}{`}{End}' }
|
||||
#斜杠被占用引导符号,因此输入本身设置为双击
|
||||
- { match: "^/$", accept: "/", send_sequence: '{space}' }
|
||||
|
||||
editor:
|
||||
bindings:
|
||||
space: confirm # 空格键:上屏候选项
|
||||
Return: commit_raw_input # 回车键:上屏原始输入
|
||||
Control+Return: commit_script_text # Ctrl+回车键:上屏变换后输入(经过 preedit转换的)
|
||||
Control+Shift+Return: commit_comment # Ctrl+Shift+回车键:上屏 comment
|
||||
BackSpace: revert # 退格键:向前删除(撤消上次输入)
|
||||
Delete: delete # Delete 键:向后删除
|
||||
Control+BackSpace: back_syllable # Ctrl+退格键:删除一个音节
|
||||
Control+Delete: delete_candidate # Ctrl+Delete键:删除或降权候选项
|
||||
Escape: cancel # Esc 键:取消输入
|
||||
|
||||
# 拼写设定
|
||||
speller:
|
||||
# table_translator翻译器,支持自动上屏。例如 “zmhu”可以自动上屏“怎么回事”
|
||||
# auto_select: true
|
||||
# auto_select_pattern: ^[a-z]+/|^[a-df-zA-DF-Z]\w{3}|^e\w{4}
|
||||
# 如果不想让什么标点直接上屏,可以加在 alphabet,或者编辑标点符号为两个及以上的映射,alphabet就是将字符纳入输入编码的范畴
|
||||
alphabet: zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA1234567890`;/\
|
||||
# initials 定义仅作为始码的按键,排除 ` 让单个的 ` 可以直接上屏
|
||||
initials: zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA/
|
||||
delimiter: " '" # 系统配置,第一位<空格>是拼音之间的分隔符;第二位<'>表示可以手动输入单引号来分割拼音。
|
||||
visual_delimiter: " " # super_preedit.lua配置:是否让分隔符号跟着一起转换,例如nǐ'hǎo 在实际使用中表现出视觉拥挤,我们可以让delimiter平时是'转换为拼音的时候使用空格nǐ hǎo,更符合实际。
|
||||
tone_isolate: true # super_preedit.lua配置:是否将数字声调从转换后拼音中隔离出来(true=隔离, false 直接参与转换)例如:nǐ3
|
||||
algebra:
|
||||
__patch:
|
||||
#- 模糊音 #模糊音选择性开启
|
||||
- wanxiang_algebra:/base/全拼 #拼音转双拼码
|
||||
|
||||
|
||||
# 自定义词典
|
||||
user_dict_set:
|
||||
dictionary: wanxiang
|
||||
initial_quality: 0
|
||||
enable_completion: false
|
||||
enable_sentence: false
|
||||
spelling_hints: 50
|
||||
contextual_suggestions: false #模型预测,假设模型里面有的四个字的词汇 现在智能 而首选组合 现在只能 当你输入 现在 上屏后下一次输入zhi neng就会输出,智能前提是没有权重更高的了,很明显这与你的预期“现在只能”不符。很明显实际上又要预测又要连续句子,放一起是很难优雅的。
|
||||
max_homophones: 5
|
||||
max_homographs: 5
|
||||
comment_format:
|
||||
enable_user_dict: false
|
||||
user_dict: zc
|
||||
# 自定义词典加词(``引导)
|
||||
add_user_dict:
|
||||
tag: add_user_dict
|
||||
dictionary: wanxiang
|
||||
initial_quality: -1
|
||||
user_dict: zc
|
||||
enable_completion: true # 提前显示尚未输入完整码的字〔仅 table_translator 有效〕
|
||||
enable_user_dict: false
|
||||
enable_auto_phrase: true # lua造词功能,在custom开启,相关功能位于auto_phrase.lua,开启后:模型能造的句子不造词,现有的词不造词,只造词库没有的,选词可造词
|
||||
spelling_hints: 50
|
||||
comment_format:
|
||||
prefix: "``"
|
||||
tips: "〔开始造词〕"
|
||||
2880
wanxiang_algebra.yaml
Normal file
2880
wanxiang_algebra.yaml
Normal file
File diff suppressed because it is too large
Load Diff
16
wanxiang_mixedcode.dict.yaml
Normal file
16
wanxiang_mixedcode.dict.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
# Rime dictionary
|
||||
# encoding: utf-8
|
||||
#
|
||||
# rime配置的部署位置:
|
||||
# ~/.local/share/fcitx5/rime 或者 ~/.config/ibus/rime (Linux)
|
||||
# ~/Library/Rime (Mac OS)
|
||||
# %APPDATA%\Rime (Windows)
|
||||
---
|
||||
name: wanxiang_mixedcode
|
||||
version: "LTS"
|
||||
sort: by_weight #字典初始排序,可選original或by_weight
|
||||
use_preset_vocabulary: false
|
||||
import_tables:
|
||||
- dicts/en #英文词库
|
||||
- dicts/cn&en #中英文混合词库
|
||||
...
|
||||
37
wanxiang_mixedcode.schema.yaml
Normal file
37
wanxiang_mixedcode.schema.yaml
Normal file
@@ -0,0 +1,37 @@
|
||||
# Rime schema settings
|
||||
# encoding: utf-8
|
||||
schema:
|
||||
schema_id: wanxiang_mixedcode
|
||||
name: "万象:英文与混合编码"
|
||||
version: "LTS"
|
||||
author: amzxyz
|
||||
description: |
|
||||
混合编码负责将英文、中英文混合、携带符号的词组等全部统一到这个方案中完成
|
||||
engine:
|
||||
processors:
|
||||
- key_binder
|
||||
- speller
|
||||
- selector
|
||||
- navigator
|
||||
- express_editor
|
||||
segmentors:
|
||||
- abc_segmentor
|
||||
translators:
|
||||
- echo_translator
|
||||
- table_translator
|
||||
filters:
|
||||
- uniquifier
|
||||
|
||||
key_binder:
|
||||
__include: default:/key_binder?
|
||||
|
||||
|
||||
speller:
|
||||
alphabet: "abcdefghijklmnopqrstuvwxyz;"
|
||||
delimiter: " '"
|
||||
algebra:
|
||||
__include: wanxiang_algebra:/mixed/通用派生规则
|
||||
__patch: wanxiang_algebra:/mixed/全拼 #可选的选项有(全拼, 自然码, 小鹤双拼, 微软双拼, 搜狗双拼, 智能ABC, 紫光双拼, 拼音加加, 自然龙, 汉心龙)
|
||||
translator:
|
||||
dictionary: wanxiang_mixedcode
|
||||
enable_user_dict: false
|
||||
260374
wanxiang_reverse.dict.yaml
Normal file
260374
wanxiang_reverse.dict.yaml
Normal file
File diff suppressed because it is too large
Load Diff
38
wanxiang_reverse.schema.yaml
Normal file
38
wanxiang_reverse.schema.yaml
Normal file
@@ -0,0 +1,38 @@
|
||||
# Rime schema settings
|
||||
# encoding: utf-8
|
||||
schema:
|
||||
schema_id: wanxiang_reverse
|
||||
name: "万象:拆分与笔画反查"
|
||||
version: "LTS"
|
||||
author: amzxyz
|
||||
description: |
|
||||
万象的反查功能模块,方案融合了组字与笔画的能力
|
||||
engine:
|
||||
processors:
|
||||
- key_binder
|
||||
- speller
|
||||
- selector
|
||||
- navigator
|
||||
- express_editor
|
||||
segmentors:
|
||||
- abc_segmentor
|
||||
translators:
|
||||
- echo_translator
|
||||
- table_translator
|
||||
filters:
|
||||
- uniquifier
|
||||
|
||||
key_binder:
|
||||
__include: default:/key_binder?
|
||||
|
||||
|
||||
speller:
|
||||
alphabet: "abcdefghijklmnopqrstuvwxyz;"
|
||||
delimiter: " '"
|
||||
algebra:
|
||||
__include: wanxiang_algebra:/reverse/全拼
|
||||
__patch: wanxiang_algebra:/reverse/hspzn #笔画类型有hspzn,hupvd及hslzy(适配乱序17)可选
|
||||
|
||||
translator:
|
||||
dictionary: wanxiang_reverse
|
||||
enable_user_dict: false
|
||||
459
wanxiang_symbols.yaml
Normal file
459
wanxiang_symbols.yaml
Normal file
@@ -0,0 +1,459 @@
|
||||
# Rime's symbols
|
||||
# encoding: utf-8
|
||||
#
|
||||
# copy from /Library/Input Methods/Squirrel.app/Contents/SharedSupport/symbols.yaml
|
||||
# version: LTS
|
||||
symbol_table:
|
||||
full_shape:
|
||||
' ' : { commit: ' ' }
|
||||
',' : { commit: , }
|
||||
'.' : { commit: 。 }
|
||||
'<' : [ 《, 〈, «, ‹ ]
|
||||
'>' : [ 》, 〉, », › ]
|
||||
'/' : [ /, ÷, ×, +, − ]
|
||||
'?' : { commit: ? }
|
||||
';' : { commit: ; }
|
||||
':' : { commit: : }
|
||||
'''' : { pair: [ '‘', '’' ] }
|
||||
'"' : { pair: [ '“', '”' ] }
|
||||
'\' : [ 、, \ ]
|
||||
'|' : [ ·, |, '§', '¦' ]
|
||||
'`' : `
|
||||
'~' : ~
|
||||
'!' : { commit: ! }
|
||||
'@' : [ @, ☯ ]
|
||||
'#' : [ #, ⌘ ]
|
||||
'%' : [ %, '°', '℃' ]
|
||||
'$' : [ ¥, '$', '€', '£', '¥', '¢', '¤' ]
|
||||
'^' : { commit: …… }
|
||||
'&' : &
|
||||
'*' : [ *, ·, ・, ×, ※, ❂ ]
|
||||
'(' : (
|
||||
')' : )
|
||||
'-' : -
|
||||
'_' : ——
|
||||
'+' : +
|
||||
'=' : =
|
||||
'[' : [ 「, 【, 〔, [ ]
|
||||
']' : [ 」, 】, 〕, ] ]
|
||||
'{' : [ 『, 〖, { ]
|
||||
'}' : [ 』, 〗, } ]
|
||||
half_shape:
|
||||
',' : ','
|
||||
'.' : '。'
|
||||
'<' : '《'
|
||||
'>' : '》'
|
||||
'/' : '/'
|
||||
'?' : '?'
|
||||
';' : ';'
|
||||
':' : ':'
|
||||
'''' : { pair: [ '‘', '’' ] }
|
||||
'"' : { pair: [ '“', '”' ] }
|
||||
'\' : '、'
|
||||
'|' : '|'
|
||||
'`' : [ "`", "```" ]
|
||||
'~' : '~'
|
||||
'!' : '!'
|
||||
'@' : '@'
|
||||
'#' : '#'
|
||||
'%' : '%'
|
||||
'$' : '¥'
|
||||
'^' : '……'
|
||||
'&' : '&'
|
||||
'*' : '*'
|
||||
'(' : '('
|
||||
')' : ')'
|
||||
'-' : '-'
|
||||
'_' : ——
|
||||
'+' : '+'
|
||||
'=' : '='
|
||||
'[' : '【'
|
||||
']' : '】'
|
||||
'{' : '「'
|
||||
'}' : '」'
|
||||
symbols:
|
||||
#符号、电脑
|
||||
'/fh': [ ©, ®, ℗, ℠, ™, ℡, ℻, ☇, ☈, ☉, ☊, ☋, ☌, ☍, ☎, ☏, ☐, ☑, ☒, ☓, ☕, ☖, ☗, ⛉, ⛊, ☘, ☙, ☚, ☛, ☜, ☝, ☞, ☟, ☠, ☡, ☢, ☣, ☤, ☥, ☦, ☧, ☨, ☩, ☪, ☫, ☬, ☭, ☮, ☯, ☸, ♨, ♰, ♱, ♲, ♳, ♴, ♵, ♶, ♷, ♸, ♹, ♺, ♻, ♼, ♽, ♾, ♿, ⚆, ⚇, ⚈, ⚉, ⚐, ⚑, ⚒, ⚓, ⚔, ⚕, ⚖, ⚗, ⚘, ⚙, ⚚, ⚛, ⚜, ⚝, ⚞, ⚟, ⚠, ⚡, ⚰, ⚱, ⚲, ⚳, ⚴, ⚵, ⚶, ⚷, ⚸, ⚹, ⚺, ⚻, ⚼, ⚽, ⚾, ⚿, ⛀, ⛁, ⛂, ⛃, ⛋, ⛌, ⛍, ⛎, ⛏, ⛐, ⛑, ⛒, ⛓, ⛔, ⛕, ⛖, ⛗, ⛘, ⛙, ⛚, ⛛, ⛜, ⛝, ⛞, ⛟, ⛠, ⛡, ⛢, ⛣, ⛨, ⛩, ⛪, ⛫, ⛬, ⛭, ⛮, ⛯, ⛰, ⛱, ⛲, ⛳, ⛴, ⛵, ⛶, ⛷, ⛸, ⛹, ⛺, ⛻, ⛼, ⛽, ⛾, ⛿ ]
|
||||
'/dn': [ ❖, ⌘, ⌃, ⌥, ⎇, ⇧, ⇪, ␣, ⇥, ⇤, ↩, ⌅, ⌤, ⌫, ⌦, ⌧, ⎋, ⌨, ◁, ⌀, ⌖, ⌗, ⏏, ↖, ↘, ⇞, ⇟, ⌚, ⏰, ⏱, ⏲, ⏳, ⌛, ⌜, ⌝⌞⌟, ⍑, ⏩, ⏪, ⏫, ⏬, ⏭, ⏮, ⏯ ]
|
||||
#象棋、麻将、色子、扑克
|
||||
'/xq': [ ♔, ♕, ♖, ♗, ♘, ♙, ♚, ♛, ♜, ♝, ♞, ♟ ]
|
||||
'/mj': [ 🀀, 🀁, 🀂, 🀃, 🀄, 🀅, 🀆, 🀇, 🀈, 🀉, 🀊, 🀋, 🀌, 🀍, 🀎, 🀏, 🀐, 🀑, 🀒, 🀓, 🀔, 🀕, 🀖, 🀗, 🀘, 🀙, 🀚, 🀛, 🀜, 🀝, 🀞, 🀟, 🀠, 🀡, 🀢, 🀣, 🀤, 🀥, 🀦, 🀧, 🀨, 🀩, 🀪, 🀫 ]
|
||||
'/sz': [ ⚀, ⚁, ⚂, ⚃, ⚄, ⚅ ]
|
||||
'/pk': [ ♠, ♥, ♣, ♦, ♤, ♡, ♧, ♢ ]
|
||||
#音乐
|
||||
'/yy': [ 𝄞, ♩, ♪, ♫, ♬, ♭, ♮, ♯ ]
|
||||
#两性
|
||||
'/lx': [ ♂, ♀, ⚢, ⚣, ⚤, ⚥, ⚦, ⚧, ⚨, ⚩, ⚪, ⚫, ⚬, ⚭, ⚮, ⚯ ]
|
||||
#八卦、八卦名、六十四卦、六十四卦名、太玄经
|
||||
'/bg': [ ☰, ☱, ☲, ☳, ☴, ☵, ☶, ☷ ]
|
||||
'/bgm': [ 乾, 兑, 离, 震, 巽, 坎, 艮, 坤 ]
|
||||
'/lssg': [ ䷀, ䷁, ䷂, ䷃, ䷄, ䷅, ䷆, ䷇, ䷈, ䷉, ䷊, ䷋, ䷌, ䷍, ䷎, ䷏, ䷐, ䷑, ䷒, ䷓, ䷔, ䷕, ䷖, ䷗, ䷘, ䷙, ䷚, ䷛, ䷜, ䷝, ䷞, ䷟, ䷠, ䷡, ䷢, ䷣, ䷤, ䷥, ䷦, ䷧, ䷨, ䷩, ䷪, ䷫, ䷬, ䷭, ䷮, ䷯, ䷰, ䷱, ䷲, ䷳, ䷴, ䷵, ䷶, ䷷, ䷸, ䷹, ䷺, ䷻, ䷼, ䷽, ䷾, ䷿ ]
|
||||
'/lssgm': [ 乾, 坤, 屯, 蒙, 需, 讼, 师, 比, 小畜, 履, 泰, 否, 同人, 大有, 谦, 豫, 随, 蛊, 临, 观, 噬嗑, 贲, 剥, 复, 无妄, 大畜, 颐, 大过, 坎, 离, 咸, 恒, 遯, 大壮, 晋, 明夷, 家人, 睽, 蹇, 解, 损, 益, 夬, 姤, 萃, 升, 困, 井, 革, 鼎, 震, 艮, 渐, 归妹, 丰, 旅, 巽, 兑, 涣, 节, 中孚, 小过, 既济, 未济 ]
|
||||
'/txj': [ ⚊, ⚋, ⚌, ⚍, ⚎, ⚏, 𝌀, 𝌁, 𝌂, 𝌃, 𝌄, 𝌅, 𝌆, 𝌇, 𝌈, 𝌉, 𝌊, 𝌋, 𝌌, 𝌍, 𝌎, 𝌏, 𝌐, 𝌑, 𝌒, 𝌓, 𝌔, 𝌕, 𝌖, 𝌗, 𝌘, 𝌙, 𝌚, 𝌛, 𝌜, 𝌝, 𝌞, 𝌟, 𝌠, 𝌡, 𝌢, 𝌣, 𝌤, 𝌥, 𝌦, 𝌧, 𝌨, 𝌩, 𝌪, 𝌫, 𝌬, 𝌭, 𝌮, 𝌯, 𝌰, 𝌱, 𝌲, 𝌳, 𝌴, 𝌵, 𝌶, 𝌷, 𝌸, 𝌹, 𝌺, 𝌻, 𝌼, 𝌽, 𝌾, 𝌿, 𝍀, 𝍁, 𝍂, 𝍃, 𝍄, 𝍅, 𝍆, 𝍇, 𝍈, 𝍉, 𝍊, 𝍋, 𝍌, 𝍍, 𝍎, 𝍏, 𝍐, 𝍑, 𝍒, 𝍓, 𝍔, 𝍕, 𝍖 ]
|
||||
#天体、星座、星座名、十二宫
|
||||
'/tt': [ ☄, ☼, ☽, ☾, ☿, ♀, ♁, ♂, ♃, ♄, ♅, ♆, ♇ ]
|
||||
'/xz': [ ♈, ♉, ♊, ♋, ♌, ♍, ♎, ♏, ♐, ♑, ♒, ♓ ]
|
||||
'/xzm': [ 白羊座, 金牛座, 双子座, 巨蟹座, 狮子座, 室女座, 天秤座, 天蝎座, 人马座, 摩羯座, 宝瓶座, 双鱼座 ]
|
||||
'/xzg': [ 白羊宫, 金牛宫, 双子宫, 巨蟹宫, 狮子宫, 室女宫, 天秤宫, 天蝎宫, 人马宫, 摩羯宫, 宝瓶宫, 双鱼宫 ]
|
||||
#星号
|
||||
'/wjx': [ ★, ☆, ⛤, ⛥, ⛦, ⛧ ]
|
||||
'/xh': [ ✡, ❋, ❊, ❉, ❈, ❇, ❆, ❅, ❄, ❃, ❂, ❁, ❀, ✿, ✾, ✽, ✼, ✻, ✺, ✹, ✸, ✷, ✶, ✵, ✴, ✳, ✲, ✱, ✰, ✯, ✮, ✭, ✬, ✫, ✪, ✩, ✧, ✦, ✥, ✤, ✣, ✢ ]
|
||||
#方块
|
||||
'/fk': [ ▀, ▁, ▂, ▃, ▄, ▅, ▆, ▇, █, ▉, ▊, ▋, ▌, ▍, ▎, ▏, ▐, ░, ▒, ▓, ▔, ▕, ▖, ▗, ▘, ▙, ▚, ▛, ▜, ▝, ▞, ▟ ]
|
||||
#几何
|
||||
'/jh': [ ■, □, ▢, ▣, ▤, ▥, ▦, ▧, ▨, ▩, ▪, ▫, ▬, ▭, ▮, ▯, ▰, ▱, ▲, △, ▴, ▵, ▶, ▷, ▸, ▹, ►, ▻, ▼, ▽, ▾, ▿, ◀, ◁, ◂, ◃, ◄, ◅, ◆, ◇, ◈, ◉, ◊, ○, ◌, ◍, ◎, ●, ◐, ◑, ◒, ◓, ◔, ◕, ◖, ◗, ◘, ◙, ◚, ◛, ◜, ◝, ◞, ◟, ◠, ◡, ◢, ◣, ◤, ◥, ◦, ◧, ◨, ◩, ◪, ◫, ◬, ◭, ◮, ◯, ◰, ◱, ◲, ◳, ◴, ◵, ◶, ◷, ◸, ◹, ◺, ◻, ◼, ◽, ◾, ◿ ]
|
||||
#箭头
|
||||
'/jt': [ →, ↑, ↓, ←, ↕, ↔, ↖, ↗, ↙, ↘, ↚, ↛, ↮, ↜, ↝, ↞, ↟, ↠, ↡, ↢, ↣, ↤, ↥, ↦, ↧, ↨, ↩, ↪, ↫, ↬, ↭, ↯, ↰, ↱, ↲, ↳, ↴, ↵, ↶, ↷, ↸, ↹, ↺, ↻, ↼, ↽, ↾, ↿, ⇀, ⇁, ⇂, ⇃, ⇄, ⇅, ⇆, ⇇, ⇈, ⇉, ⇊, ⇋, ⇌, ⇐, ⇍, ⇑, ⇒, ⇏, ⇓, ⇔, ⇎, ⇕, ⇖, ⇗, ⇘, ⇙, ⇚, ⇛, ⇜, ⇝, ⇞, ⇟, ⇠, ⇡, ⇢, ⇣, ⇤, ⇥, ⇦, ⇧, ⇨, ⇩, ⇪, ⇫, ⇬, ⇭, ⇮, ⇯, ⇰, ⇱, ⇲, ⇳, ⇴, ⇵, ⇶, ⇷, ⇸, ⇹, ⇺, ⇻, ⇼, ⇽, ➔, ➘, ➙, ➚, ➛, ➜, ➝, ➞, ➟, ➠, ➡, ➢, ➣, ➤, ➥, ➦, ➧, ➨, ➩, ➪, ➫, ➬, ➭, ➮, ➱, ➲, ➳, ➴, ➵, ➶, ➷, ➸, ➹, ➺, ➻, ➼, ➽, ➾ ]
|
||||
#数学
|
||||
'/sx': [ +,-, ×, ÷, ±, ∈, ∏, ∑, <, ≮, =, ≠, >, ≯, ∕, √, ∝, ∞, ∟, ∠, ∥, ∧, ∨, ∩, ∪, ∫, ∮, ∴, ∵, ∷, ∽, ≈, ≌, ≒, ≡, ≤, ≥, ≦, ≧, ⊕, ⊙, ⊥, ⊿, ㏑, ㏒ ]
|
||||
'/dy': [ >, ≥, ≧, ≯ ]
|
||||
'/xy': [ <, ≤, ≦, ≮ ]
|
||||
'/yw': [ ∵ ]
|
||||
'/sy': [ ∴ ]
|
||||
#数字+圆v弧v点
|
||||
'/szq': [ ⓪, ①, ②, ③, ④, ⑤, ⑥, ⑦, ⑧, ⑨, ⑩, ⑪, ⑫, ⑬, ⑭, ⑮, ⑯, ⑰, ⑱, ⑲, ⑳, ㉑, ㉒, ㉓, ㉔, ㉕, ㉖, ㉗, ㉘, ㉙, ㉚, ㉛, ㉜, ㉝, ㉞, ㉟, ㊱, ㊲, ㊳, ㊴, ㊵, ㊶, ㊷, ㊸, ㊹, ㊺, ㊻, ㊼, ㊽, ㊾, ㊿, ⓿, ❶, ❷, ❸, ❹, ❺, ❻, ❼, ❽, ❾, ❿, ⓫, ⓬, ⓭, ⓮, ⓯, ⓰, ⓱, ⓲, ⓳, ⓴ ]
|
||||
'/szh': [ ⑴, ⑵, ⑶, ⑷, ⑸, ⑹, ⑺, ⑻, ⑼, ⑽, ⑾, ⑿, ⒀, ⒁, ⒂, ⒃, ⒄, ⒅, ⒆, ⒇ ]
|
||||
'/szd': [ ⒈, ⒉, ⒊, ⒋, ⒌, ⒍, ⒎, ⒏, ⒐, ⒑, ⒒, ⒓, ⒔, ⒕, ⒖, ⒗, ⒘, ⒙, ⒚, ⒛ ]
|
||||
#字母+圈v弧
|
||||
'/zmq': [ ⓐ, Ⓐ, ⓑ, Ⓑ, ⓒ, Ⓒ, ⓓ, Ⓓ, ⓔ, Ⓔ, ⓕ, Ⓕ, ⓖ, Ⓖ, ⓗ, Ⓗ, ⓘ, Ⓘ, ⓙ, Ⓙ, ⓚ, Ⓚ, ⓛ, Ⓛ, ⓜ, Ⓜ, ⓝ, Ⓝ, ⓞ, Ⓞ, ⓟ, Ⓟ, ⓠ, Ⓠ, ⓡ, Ⓡ, ⓢ, Ⓢ, ⓣ, Ⓣ, ⓤ, Ⓤ, ⓥ, Ⓥ, ⓦ, Ⓦ, ⓧ, Ⓧ, ⓨ, Ⓨ, ⓩ, Ⓩ ]
|
||||
'/zmh': [ ⒜, ⒝, ⒞, ⒟, ⒠, ⒡, ⒢, ⒣, ⒤, ⒥, ⒦, ⒧, ⒨, ⒩, ⒪, ⒫, ⒬, ⒭, ⒮, ⒯, ⒰, ⒱, ⒲, ⒳, ⒴, ⒵ ]
|
||||
#数字、分数
|
||||
'/0': [ 零, 〇, ⁰, ₀, ⓪, ⓿ , 0]
|
||||
'/1': [ 一, 壹, ¹, ₁, Ⅰ, ⅰ, ①, ➀, ❶, ➊, ⓵, ⑴, ⒈, 1, ㊀, ㈠, 弌, 壱, 幺, ㆒ ]
|
||||
'/2': [ 二, 贰, ², ₂, Ⅱ, ⅱ, ②, ➁, ❷, ➋, ⓶, ⑵, ⒉, 2, ㊁, ㈡, 弍, 弐, 貮, 㒃, 㒳, 两, 俩, ㆓]
|
||||
'/3': [ 三, 叁, ³, ₃, Ⅲ, ⅲ, ③, ➂, ❸, ➌, ⓷, ⑶, ⒊, 3, ㊂, ㈢, 参, 参, 叁, 弎, 仨, ㆔]
|
||||
'/4': [ 四, 肆, ⁴, ₄, Ⅳ, ⅳ, ④, ➃, ❹, ➍, ⓸, ⑷, ⒋, 4, ㊃, ㈣, 亖]
|
||||
'/5': [ 五, 伍, ⁵, ₅, Ⅴ, ⅴ, ⑤, ➄, ❺, ➎, ⓹, ⑸, ⒌, 5, ㊄, ㈤, 㐅, 㠪, 𠄡 ]
|
||||
'/6': [ 六, 陆, ⁶, ₆, Ⅵ, ⅵ, ⑥, ➅, ❻, ➏, ⓺, ⑹, ⒍, 6, ㊅, ㈥, ↅ]
|
||||
'/7': [ 七, 柒, ⁷, ₇, Ⅶ, ⅶ, ⑦, ➆, ❼, ➐, ⓻, ⑺, ⒎, 7, ㊆, ㈦, 漆]
|
||||
'/8': [ 八, 捌, ⁸, ₈, Ⅷ, ⅷ, ⑧, ➇, ❽, ➑, ⓼, ⑻, ⒏, 8, ㊇, ㈧ ]
|
||||
'/9': [ 九, 玖, ⁹, ₉, Ⅸ, ⅸ, ⑨, ➈, ❾, ➒, ⓽, ⑼, ⒐, 9, ㊈, ㈨ ]
|
||||
'/10': [ 十, 拾, ¹⁰, ₁₀, Ⅹ, ⅹ, ⑩, ➉, ❿, ➓, ⓾, ⑽, ⒑, 10, ㊉, ㈩, 什 ]
|
||||
'/fs': [ ⅟, ½, ↉, ⅓, ⅔, ¼, ⅕, ⅖, ⅗, ⅘, ⅙, ⅚, ⅐, ⅛, ⅜, ⅝, ⅞, ⅑, ⅒, ‰]
|
||||
#苏州码
|
||||
'/szm': [ 〡, 〢, 〣, 〤, 〥, 〦, 〧, 〨, 〩, 〸, 〹, 〺 ]
|
||||
#罗马数字
|
||||
'/lm': [ ⅰ, ⅱ, ⅲ, ⅳ, ⅴ, ⅵ, ⅶ, ⅷ, ⅸ, ⅹ, ⅺ, ⅻ, ⅼ, ⅽ, ⅾ, ⅿ ]
|
||||
'/lmd': [ Ⅰ, Ⅱ, Ⅲ, Ⅳ, Ⅴ, Ⅵ, Ⅶ, Ⅷ, Ⅸ, Ⅹ, Ⅺ, Ⅻ, Ⅼ, Ⅽ, Ⅾ, Ⅿ ]
|
||||
#拉丁
|
||||
'/a': [ā, á, ǎ, à, ȁ, â, ă, ȃ, ȧ, ä, å, ã, ₐ, ᵃ, ª, ⱥ, ꬰ, ả, ą, ạ, ḁ, ẚ, ấ, ầ, ẫ, ẩ, ắ, ằ, ẵ, ẳ, ǡ, ǟ, ǻ, ậ, ặ, ᶏ, ɐ, ᵄ, ɑ, ᵅ, ᶐ, ɒ, ᶛ]
|
||||
'/A': [Ā, Á, Ǎ, À, Ȁ, Â, Ă, Ȃ, Ȧ, Ä, Å, Ã, ᴀ, ᴬ, Ⱥ, Ả, Ą, Ạ, Ḁ, Ấ, Ầ, Ẫ, Ẩ, Ắ, Ằ, Ẵ, Ẳ, Ǡ, Ǟ, Ǻ, Ậ, Ặ, Ɐ, Ɑ, Ɒ ]
|
||||
'/b': [ḃ, ḅ, ᵇ, ƀ, ƃ, ḇ, ɓ, ᵬ, ᶀ, ꞗ]
|
||||
'/B': [Ḃ, Ḅ, ʙ, ᴃ, ᴮ, ᴯ, Ƀ, Ƃ, Ḇ, Ɓ, Ꞗ]
|
||||
'/c': [ç, ć, č, ĉ, ċ, ᶜ, ȼ, ꞓ, ƈ, ḉ, ꞔ, ɕ, ᶝ, ꜿ]
|
||||
'/C': [Ç, Ć, Č, Ĉ, Ċ, ᴄ, Ȼ, Ꞓ, Ƈ, Ḉ, Ꜿ]
|
||||
'/d': [ď, ḋ, ᵈ, đ, ƌ, ᵭ, ḑ, ḓ, ḏ, ḍ, ɖ, ɗ, ᶑ, ᶁ, ð, ᶞ, ꝱ, ʤ, ʣ, ʥ, ȡ, ƍ, dz, dž, ẟ]
|
||||
'/D': [Ď, Ḋ, ᴅ, ᴆ, ᴰ, Đ, Ƌ, Ḑ, Ḓ, Ḏ, Ḍ, Ɖ, Ɗ, Ð, DZ, Dz, DŽ, Dž ]
|
||||
'/e': [ē, é, ě, è, ȅ, ê, ĕ, ȇ, ė, ë, ẽ, ₑ, ᵉ, ɇ, ꬳ, ẻ, ȩ, ę, ḙ, ẹ, ḛ, ḗ, ḕ, ế, ề, ễ, ể, ḝ, ệ, ᶒ, ꬴ, ɘ, ə, ɚ, ᶕ, ɛ, ᵋ, ᶓ, ɜ, ᵌ, ᴈ, ᶟ, ɝ, ᶔ, ɞ, ʚ, ǝ, ₔ, ᵊ, ȝ, ⱸ]
|
||||
'/E': [Ē, É, Ě, È, Ȅ, Ê, Ĕ, Ȇ, Ė, Ë, Ẽ, ᴇ, ᴱ, Ɇ, Ẻ, Ȩ, Ę, Ḙ, Ẹ, Ḛ, Ḗ, Ḕ, Ế, Ề, Ễ, Ể, Ḝ, Ệ, Ə, Ɛ, Ɜ, Ǝ, ⱻ, ᴲ, Ȝ ]
|
||||
'/f': [ḟ, ᶠ, ƒ, ᵮ, ᶂ, ꞙ ]
|
||||
'/F': [Ḟ, ꜰ, Ƒ, Ꞙ, ꟻ]
|
||||
'/g': [ḡ, ǵ, ǧ, ĝ, ğ, ġ, ᵍ, ǥ, ꞡ, ģ, ɠ, ᵷ, ᶃ, ɡ, ꬶ, ᶢ, ɣ, ˠ, ɤ, ᵹ]
|
||||
'/G': [Ḡ, Ǵ, Ǧ, Ĝ, Ğ, Ġ, ʛ, ᴳ, Ǥ, Ꞡ, Ģ, Ɠ, Ɡ, Ɣ ]
|
||||
'/h': [ĥ, ȟ, ḣ, ḧ, ͪ, ħ, ɦ, ʱ, ꜧ, ꭜ, ɧ, ḩ, ẖ, ḫ, ḥ, ⱨ, ꞕ, ɥ, ᶣ, ʮ, ʯ, ⱶ]
|
||||
'/H': [Ĥ, Ȟ, Ḣ, Ḧ, ʜ, ᴴ, Ħ, Ɦ, Ꜧ, Ḩ, Ḫ, Ḥ, Ⱨ, Ɥ, Ⱶ]
|
||||
'/i': [ī, í, ǐ, ì, ȉ, î, ĭ, ȋ, ï, ĩ, ᵢ, ı, ɨ, ᶤ, ỉ, į, ị, ḭ, ᴉ, ᵎ, ḯ, ᶖ, ɩ, ᶥ, ᵼ]
|
||||
'/I': [Ī, Í, Ǐ, Ì, Ȉ, Î, Ĭ, Ȋ, Ï, Ĩ, ɪ, ᴵ, ᶦ, Ɨ, ᵻ, ᶧ, Ỉ, Į, Ị, Ḭ, Ḯ, ꟾ, Ɩ ]
|
||||
'/j': [ĵ, ǰ, ⱼ, ʲ, ɉ, ȷ, ɟ, ᶡ, ʄ, ʝ, ᶨ]
|
||||
'/J': [Ĵ, ᴊ, ᴶ, Ɉ, Ʝ ]
|
||||
'/k': [ḱ, ǩ, ₖ, ᵏ, ꝁ, ꝃ, ꞣ, ꝅ, ķ, ḵ, ḳ, ƙ, ᶄ, ⱪ, ʞ, ĸ]
|
||||
'/K': [Ḱ, Ǩ, ᴋ, ᴷ, Ꝁ, Ꝃ, Ꞣ, Ꝅ, Ķ, Ḵ, Ḳ, Ƙ, Ⱪ, Ʞ ]
|
||||
'/l': [ĺ, ˡ, ł, ꝉ, ƚ, ⱡ, ɫ, ꭞ, ꬸ, ɬ, ľ, ļ, ḻ, ḽ, ḷ, ŀ, ꝲ, ƛ, ᶅ, ᶪ, ɭ, ᶩ, ḹ, ꬷ, ꭝ, ꬹ, ȴ, ꝇ]
|
||||
'/L': [Ĺ, ʟ, ᶫ, Ƚ, Ꝉ, Ł, ᴌ, Ⱡ, Ɫ, Ɬ, Ľ, Ļ, Ḻ, Ḽ, Ḷ, Ŀ, Ꝇ]
|
||||
'/m': [ḿ, m̀, ṁ, ᵐ, ₘ, ṃ, ᵯ, ɱ, ᶬ, ꬺ, ᶆ, ꝳ, ɯ, ᵚ, ɰ, ᶭ, ᴟ]
|
||||
'/M': [Ḿ, Ṁ, ᴍ, ᴹ, Ṃ, Ɱ, Ɯ, ꟽ, ꟿ ]
|
||||
'/n': [ń, ň, ǹ, ṅ, ñ, ₙ, ⁿ, ɲ, ᶮ, ɳ, ᶯ, ȵ, ƞ, ŋ, ᵑ, ꬻ, ꬼ, ꝴ, ʼn, ꞥ, ņ, ṉ, ṋ, ṇ, ᵰ, ꞑ, ᶇ]
|
||||
'/N': [Ń, Ň, Ǹ, Ṅ, Ñ, ɴ, ᴺ, ᴻ, ᶰ, Ɲ, Ƞ, Ŋ, Ņ, Ṉ, Ṋ, Ṇ, Ꞑ ]
|
||||
'/o': [ō, ó, ǒ, ò, ő, ô, ŏ, ȯ, ö, õ, ₒ, ᵒ, º, ɔ, ᵓ, ᶗ, ꬿ, ø, ǫ, ọ, ơ, ɵ, ᶱ, ᴑ, ᴒ, ᴓ, ꝋ, ꝍ, ṓ, ṑ, ố, ồ, ỗ, ổ, ȱ, ȫ, ȭ, ṍ, ṏ, ộ, ǭ, ǿ, ớ, ờ, ỡ, ở, ợ, ɷ, ⱺ, ᴖ, ᵔ, ᴗ, ᵕ]
|
||||
'/O': [Ō, Ó, Ő, Ǒ, Ò, Ô, Ŏ, Ȯ, Ö, Õ, ᴏ, ᴼ, Ɔ, ᴐ, Ø, Ǫ, Ọ, Ơ, Ɵ, Ꝋ, Ꝍ, Ṓ, Ṑ, Ố, Ồ, Ỗ, Ổ, Ȱ, Ȫ, Ȭ, Ṍ, Ṏ, Ộ, Ǭ, Ǿ, Ớ, Ờ, Ỡ, Ở, Ợ ]
|
||||
'/p': [ṕ, ṗ, ᵖ, ᵽ, ꝑ, ᵱ, ƥ, ᶈ, ꝓ, ꝕ, ɸ, ᶲ, ⱷ ]
|
||||
'/P': [Ṕ, Ṗ, ᴘ, ᴾ, Ᵽ, Ꝑ, Ƥ, Ꝓ, Ꝕ, ꟼ]
|
||||
'/q': [ɋ, ꝗ, ꝙ, ʠ]
|
||||
'/Q': [Ɋ, Ꝗ, Ꝙ ]
|
||||
'/r': [ŕ, ř, ȑ, ȓ, ṙ, ᵣ, ɍ, ꞧ, ᵲ, ŗ, ṟ, ṛ, ṝ, ᵳ, ɽ, ᶉ, ꭇ, ꭈ, ꭊ, ꭉ, ꝵ, ꭋ, ꭌ, ɹ, ʴ, ɺ, ɻ, ʵ, ⱹ, ɼ, ʳ, ɾ, ɿ, ꝛ, ꝝ]
|
||||
'/R': [Ŕ, Ř, Ȑ, Ȓ, Ṙ, ʀ, ᴙ, ᴿ, Ʀ, ꭆ, Ɍ, Ꞧ, Ŗ, Ṟ, Ṛ, Ṝ, Ɽ, ꝶ, ʶ, ʁ, Ꝛ, Ꝝ]
|
||||
'/s': [ś, ŝ, š, ṡ, ˢ, ʂ, ᶳ, ᵴ, ꞩ, ᶊ, ş, ṣ, ș, ȿ, ṥ, ṧ, ṩ, ʃ, ᶴ, ʆ, ᶘ, ʅ, ƪ, ß, ſ, ẛ, ẜ, ẝ]
|
||||
'/S': [Ś, Ŝ, Š, Ṡ, ꜱ, Ꞩ, Ş, Ṣ, Ș, Ṥ, Ṧ, Ṩ, Ʃ, ẞ, ]
|
||||
'/t': [ť, ṫ, ẗ, ᵗ, ₜ, ʈ, þ, ꝥ, ꝧ, ŧ, ⱦ, ţ, ṯ, ṱ, ṭ, ț, ƭ, ᵵ, ƫ, ᶵ, ʇ, ȶ, ꝷ]
|
||||
'/T': [Ť, Ṫ, ᴛ, ᵀ, Ʈ, Þ, Ꝥ, Ꝧ, Ŧ, Ⱦ, Ţ, Ṯ, Ṱ, Ṭ, Ț, Ƭ, Ʇ ]
|
||||
'/u': [ū, ú, ǔ, ù, ű, ȕ, û, ŭ, ȗ, ü, ǖ, ǘ, ǚ, ǜ, ů, ũ, ᵤ, ᵘ, ʉ, ᶶ, ủ, ų, ṷ, ụ, ṳ, ṵ, ư, ʊ, ᶷ, ᵿ, ᶙ, ṻ, ṹ, ứ, ừ, ữ, ử, ự, ꭒ, ꭟ, ꝸ, ꭎ, ꭏ, ᴝ, ᵙ, ᴞ]
|
||||
'/U': [Ū, Ú, Ű, Ǔ, Ù, Ȕ, Û, Ŭ, Ȗ, Ü, Ǖ, Ǘ, Ǚ, Ǜ, Ů, Ũ, ᴜ, ᵁ, ᶸ, Ʉ, Ủ, Ų, Ṷ, Ụ, Ṳ, Ṵ, Ư, Ʊ, Ṻ, Ṹ, Ứ, Ừ, Ữ, Ử, Ự ]
|
||||
'/v': [ü, ǖ, ǘ, ǚ, ǜ, ṽ, ᵛ, ᵥ, ṿ, ꝟ, ʋ, ᶹ, ᶌ, ⱴ, ⱱ, ỽ, ʌ, ᶺ]
|
||||
'/V': [Ü, Ǖ, Ǘ, Ǚ, Ǜ, Ṽ, ᴠ, ⱽ, Ṿ, Ꝟ, Ʋ, Ỽ, Ʌ ]
|
||||
'/w': [ẃ, ẁ, ŵ, ẇ, ẅ, ẘ, ʷ, ẉ, ƿ, ʍ, ⱳ]
|
||||
'/W': [Ẃ, Ẁ, Ŵ, Ẇ, Ẅ, W̊, ᴡ, ᵂ, Ẉ, Ƿ, Ⱳ]
|
||||
'/x': [ẋ, ẍ, ᶍ, ˣ, ₓ, ꭖ, ꭗ, ꭘ, ꭙ]
|
||||
'/X': [Ẋ, Ẍ ]
|
||||
'/y': [ȳ, ý, ỳ, ŷ, ẏ, ÿ, ẙ, ỹ, ʸ, ɏ, ỷ, ỵ, ƴ, ʎ, ỿ, ꭚ]
|
||||
'/Y': [Ȳ, Ý, Ỳ, Ŷ, Ẏ, Ÿ, Ỹ, ʏ, Ɏ, Ỷ, Ỵ, Ƴ, Ỿ ]
|
||||
'/z': [ź, ž, ẑ, ż, ᶻ, ʐ, ᶼ, ʑ, ᶽ, ƶ, ẕ, ẓ, ᵶ, ȥ, ⱬ, ᶎ, ʒ, ᶾ, ǯ, ʓ, ƹ, ƺ, ᶚ, θ, ᶿ, ɀ, ꝣ]
|
||||
'/Z': [Ź, Ž, Ẑ, Ż, ᴢ, Ƶ, Ẕ, Ẓ, Ȥ, Ⱬ, Ʒ, ᴣ, Ǯ, Ƹ, Ɀ, Ꝣ]
|
||||
'/aa': [ꜳ]
|
||||
'/AA': [Ꜳ]
|
||||
'/ae': [æ, ǣ, ǽ, ᵆ, ᴂ]
|
||||
'/AE': [Æ, Ǣ, Ǽ, ᴭ, ᴁ ]
|
||||
'/ao': [ꜵ]
|
||||
'/AO': [Ꜵ]
|
||||
'/au': [ꜷ]
|
||||
'/AU': [Ꜷ]
|
||||
'/av': [ꜹ, ꜻ]
|
||||
'/AV': [Ꜹ, Ꜻ]
|
||||
'/ay': [ꜽ]
|
||||
'/AY': [Ꜽ]
|
||||
'/db': [ȸ]
|
||||
'/ff': [ff]
|
||||
'/ffi': [ffi]
|
||||
'/ffl': [ffl]
|
||||
'/fi': [fi]
|
||||
'/fl': [fl]
|
||||
'/fn': [ʩ]
|
||||
'/hv': [ƕ]
|
||||
'/HV': [Ƕ]
|
||||
'/ij': [ij]
|
||||
'/IJ': [IJ]
|
||||
'/lj': [lj]
|
||||
'/ll': [ỻ]
|
||||
'/LL': [Ỻ]
|
||||
'/ls': [ʪ]
|
||||
'/lz': [ʫ, ɮ]
|
||||
'/nj': [nj]
|
||||
'/Nj': [Nj]
|
||||
'/NJ': [NJ]
|
||||
'/oe': [œ, ᴔ]
|
||||
'/OE': [Œ, ɶ ]
|
||||
'/oi': [ƣ]
|
||||
'/OI': [Ƣ]
|
||||
'/oo': [ꝏ]
|
||||
'/OO': [Ꝏ]
|
||||
'/ou': [ȣ ]
|
||||
'/OU': [Ȣ, ᴽ]
|
||||
'/qp': [ȹ]
|
||||
'/Rx': [℞]
|
||||
'/tc': [ʨ]
|
||||
'/th': [ᵺ]
|
||||
'/ts': [ʦ, ʧ]
|
||||
'/tz': [ꜩ]
|
||||
'/TZ': [Ꜩ]
|
||||
'/ue': [ᵫ]
|
||||
'/vy': [ꝡ]
|
||||
'/VY': [Ꝡ]
|
||||
'/ww': [ʬ]
|
||||
'/num': [№]
|
||||
#上标、下标
|
||||
'/sb': [ ⁰, ¹, ², ³, ⁴, ⁵, ⁶, ⁷, ⁸, ⁹, ˜, ⁺, ⁻, ⁼, ⁽, ⁾, ᴬ, ᵃ, ᵄ, ᵅ, ᶛ, ᴭ, ᵆ, ᴮ, ᴯ, ᵇ, ᵝ, ᶜ, ᵓ, ᶝ, ᴰ, ᵈ, ᶞ, ᵟ, ᴱ, ᵉ, ᴲ, ᵊ, ᵋ, ᶟ, ᵌ, ᶠ, ᶡ, ᶲ, ᵠ, ᴳ, ᵍ, ᶢ, ˠ, ᵞ, ᴴ, ʰ, ᶣ, ʱ, ᴵ, ⁱ, ᶤ, ᵎ, ᶥ, ᴶ, ʲ, ᶨ, ᴷ, ᵏ, ᴸ, ᶫ, ˡ, ᶩ, ᶪ, ᴹ, ᵐ, ᶬ, ᵚ, ᶭ, ᴺ, ᴻ, ⁿ, ᵑ, ᶮ, ᶯ, ᴼ, ᵒ, ᶱ, ᴽ, ᴾ, ᵖ, ᴿ, ʳ, ʶ, ʴ, ʵ, ˢ, ᶴ, ᶳ, ᵀ, ᵗ, ᶵ, ᶿ, ᵁ, ᵘ, ᶶ, ᶷ, ᵙ, ⱽ, ᵛ, ᶺ, ᶹ, ᵂ, ʷ, ˣ, ᵡ, ʸ, ᶻ, ᶾ, ᶽ, ᶼ ]
|
||||
'/xb': [ ₀, ₁, ₂, ₃, ₄, ₅, ₆, ₇, ₈, ₉, ₊, ₋, ₌, ₍, ₎, ‸, ᴀ, ₐ, ᴁ, ʙ, ᴃ, ᵦ, ᴄ, ᴐ, ᴒ, ᴅ, ᴆ, ᴇ, ₑ, ₔ, ᵩ, ɢ, ʛ, ᴦ, ᵧ, ʜ, ₕ, ɪ, ᵻ, ᵢ, ᴊ, ⱼ, ᴋ, ₖ, ʟ, ₗ, ᴌ, ᴧ, ᴍ, ₘ, ꟺ, ɴ, ᴎ, ₙ, ᴏ, ₒ, ɶ, ʘ, ᴓ, ᴑ, ᴘ, ₚ, ᴨ, ᴪ, ʀ, ᵣ, ᴙ, ʁ, ᴚ, ᵨ, ₛ, ᴛ, ₜ, ᴜ, ᵤ, ᵾ, ᴠ, ᵥ, ᴡ, ₓ, ᵪ, ʏ, ᴢ, ᴣ ]
|
||||
#希腊
|
||||
'/xl': [ α, β, γ, δ, ε, ζ, η, θ, ι, κ, λ, μ, ν, ξ, ο, π, ρ, σ, τ, υ, φ, χ, ψ, ω ]
|
||||
'/xld': [ Α, Β, Γ, Δ, Ε, Ζ, Η, Θ, Ι, Κ, Λ, Μ, Ν, Ξ, Ο, Π, Ρ, Σ, Τ, Υ, Φ, Χ, Ψ, Ω ]
|
||||
#俄语
|
||||
'/ey': [ а, б, в, г, д, е, ё, ж, з, и, й, к, л, м, н, о, п, р, с, т, у, ф, х, ц, ч, ш, щ, ъ, ы, ь, э, ю, я ]
|
||||
'/eyd': [ А, Б, В, Г, Д, Е, Ё, Ж, З, И, Й, К, Л, М, Н, О, П, Р, С, Т, У, Ф, Х, Ц, Ч, Ш, Щ, Ъ, Ы, Ь, Э, Ю, Я ]
|
||||
#月份、日期、曜日等
|
||||
'/yf': [ ㋀, ㋁, ㋂, ㋃, ㋄, ㋅, ㋆, ㋇, ㋈, ㋉, ㋊, ㋋ ]
|
||||
'/rf': [ ㏠, ㏡, ㏢, ㏣, ㏤, ㏥, ㏦, ㏧, ㏨, ㏩, ㏪, ㏫, ㏬, ㏭, ㏮, ㏯, ㏰, ㏱, ㏲, ㏳, ㏴, ㏵, ㏶, ㏷, ㏸, ㏹, ㏺, ㏻, ㏼, ㏽, ㏾ ]
|
||||
'/yr': [ 月, 火, 水, 木, 金, 土, 日, ㊊, ㊋, ㊌, ㊍, ㊎, ㊏, ㊐, ㊗, ㊡, ㈪, ㈫, ㈬, ㈭, ㈮, ㈯, ㈰, ㈷, ㉁, ㉀ ]
|
||||
#时间
|
||||
'/sj': [ ㍘, ㍙, ㍚, ㍛, ㍜, ㍝, ㍞, ㍟, ㍠, ㍡, ㍢, ㍣, ㍤, ㍥, ㍦, ㍧, ㍨, ㍩, ㍪, ㍫, ㍬, ㍭, ㍮, ㍯, ㍰ ]
|
||||
#天干、地支、干支
|
||||
'/tg': [ 甲, 乙, 丙, 丁, 戊, 己, 庚, 辛, 壬, 癸 ]
|
||||
'/dz': [ 子, 丑, 寅, 卯, 辰, 巳, 午, 未, 申, 酉, 戌, 亥 ]
|
||||
'/gz': [ 甲子, 乙丑, 丙寅, 丁卯, 戊辰, 己巳, 庚午, 辛未, 壬申, 癸酉, 甲戌, 乙亥, 丙子, 丁丑, 戊寅, 己卯, 庚辰, 辛巳, 壬午, 癸未, 甲申, 乙酉, 丙戌, 丁亥, 戊子, 己丑, 庚寅, 辛卯, 壬辰, 癸巳, 甲午, 乙未, 丙申, 丁酉, 戊戌, 己亥, 庚子, 辛丑, 壬寅, 癸卯, 甲辰, 乙巳, 丙午, 丁未, 戊申, 己酉, 庚戌, 辛亥, 壬子, 癸丑, 甲寅, 乙卯, 丙辰, 丁巳, 戊午, 己未, 庚申, 辛酉, 壬戌, 癸亥 ]
|
||||
#节气
|
||||
'/jq': [ 立春, 雨水, 惊蛰, 春分, 清明, 谷雨, 立夏, 小满, 芒种, 夏至, 小暑, 大暑, 立秋, 处暑, 白露, 秋分, 寒露, 霜降, 立冬, 小雪, 大雪, 冬至, 小寒, 大寒 ]
|
||||
#单位
|
||||
'/dw': [ Å, ℃, %, ‰, ‱, °, ℉, ㏃, ㏆, ㎈, ㏄, ㏅, ㎝, ㎠, ㎤, ㏈, ㎗, ㎙, ㎓, ㎬, ㏉, ㏊, ㏋, ㎐, ㏌, ㎄, ㎅, ㎉, ㎏, ㎑, ㏍, ㎘, ㎞, ㏎, ㎢, ㎦, ㎪, ㏏, ㎸, ㎾, ㏀, ㏐, ㏓, ㎧, ㎨, ㎡, ㎥, ㎃, ㏔, ㎆, ㎎, ㎒, ㏕, ㎖, ㎜, ㎟, ㎣, ㏖, ㎫, ㎳, ㎷, ㎹, ㎽, ㎿, ㏁, ㎁, ㎋, ㎚, ㎱, ㎵, ㎻, ㏘, ㎩, ㎀, ㎊, ㏗, ㏙, ㏚, ㎰, ㎴, ㎺, ㎭, ㎮, ㎯, ㏛, ㏜, ㎔, ㏝, ㎂, ㎌, ㎍, ㎕, ㎛, ㎲, ㎶, ㎼ ]
|
||||
#货币
|
||||
'/hb': [ ¥, ¥, ¤, ¢, $, $, £, £, ৳, ฿, ₠, ₡, ₢, ₣, ₤, ₥, ₦, ₧, ₩, ₪, ₫, €, ₭, ₮, ₯, ₰, ₱, ₲, ₳, ₴, ₵, ₶, ₷, ₸, ₹, ₺, ₨, ﷼ ]
|
||||
#结构、偏旁、康熙(部首)、笔画、标点
|
||||
'/jg': [ ⿰, ⿱, ⿲, ⿳, ⿴, ⿵, ⿶, ⿷, ⿸, ⿹, ⿺, ⿻, 〾 ]
|
||||
'/pp': [ 乛, 冫, 丷, 龹, ⺌, 龸, 亻, 亼, 亽, 仒, 冖, 冂, 冃, 冄, 宀, 罒, 㓁, 罓, 冈, 凵, 厶, 刂, 勹, 匚, 匸, 卩, 阝, 厂, 丆, 广, 壬, 訁, 讠, 釒, 钅, 飠, 饣, 龺, 攵, 夂, 夊, 尢, 尣, 兂, 旡, 巜, 巛, 彐, 彑, 彡, 彳, 龰, 辶, 廴, 㞢, 忄, 㣺, 扌, 爫, 龵, 廾, 歺, 癶, 氵, 氺, 火, 灬, 爿, 丬, 疒, 牜, ⺶, 犭, 豕, 豸, 虍, 艹, 卝, 龷, 丗, 龶, 芈, 丵, 菐, 黹, 礻, 衤, 糸, 糹, 纟, 龻, 镸, 髟, 襾, 覀, 吅, 㗊, 㠭, 㸚, 叕]
|
||||
'/kx': [ 一, 丨, 丶, 丿, 乙, 亅, 二, 亠, 人, 儿, 入, 八, 冂, 冖, 冫, 几, 凵, 刀, 力, 勹, 匕, 匚, 匸, 十, 卜, 卩, 厂, 厶, 又, 口, 囗, 土, 士, 夂, 夊, 夕, 大, 女, 子, 宀, 寸, 小, 尢, 尸, 屮, 山, 巛, 工, 己, 巾, 干, 幺, 广, 廴, 廾, 弋, 弓, 彐, 彡, 彳, 心, 戈, 戶, 手, 支, 攴, 文, 斗, 斤, 方, 无, 日, 曰, 月, 木, 欠, 止, 歹, 殳, 毋, 比, 毛, 氏, 气, 水, 火, 爪, 父, 爻, 爿, 片, 牙, 牛, 犬, 玄, 玉, 瓜, 瓦, 甘, 生, 用, 田, 疋, 疒, 癶, 白, 皮, 皿, 目, 矛, 矢, 石, 示, 禸, 禾, 穴, 立, 竹, 米, 糸, 缶, 网, 羊, 羽, 老, 而, 耒, 耳, 聿, 肉, 臣, 自, 至, 臼, 舌, 舛, 舟, 艮, 色, 艸, 虍, 虫, 血, 行, 衣, 襾, 見, 角, 言, 谷, 豆, 豕, 豸, 貝, 赤, 走, 足, 身, 車, 辛, 辰, 辵, 邑, 酉, 釆, 里, 金, 長, 門, 阜, 隶, 隹, 雨, 靑, 非, 面, 革, 韋, 韭, 音, 頁, 風, 飛, 食, 首, 香, 馬, 骨, 高, 髟, 鬥, 鬯, 鬲, 鬼, 魚, 鳥, 鹵, 鹿, 麥, 麻, 黃, 黍, 黑, 黹, 黽, 鼎, 鼓, 鼠, 鼻, 齊, 齒, 龍, 龜, 龠 ]
|
||||
'/bh': [ ㇀, ㇁, ㇂, ㇃, ㇄, ㇅, ㇆, ㇇, ㇈, ㇉, ㇊, ㇋, ㇌, ㇍, ㇎, ㇏, ㇐, ㇑, ㇒, ㇓, ㇔, ㇕, ㇖, ㇗, ㇘, ㇙, ㇚, ㇛, ㇜, ㇝, ㇞, ㇟, ㇠, ㇡, ㇢, ㇣]
|
||||
'/bd': [ 、, 。, 「, 」, 『, 』, 【, 】, 〈, 〉, 《, 》, ₋, ⁻, ―, ˗, ˉ, _, ﹍, ﹎, ., ¡, ‼, ⁉, ¿, ؟, ⁈, ⁇, 、, 。, 〃, 〄, 々, 〆, 〇, 〒, 〓, 〔, 〕, 〖, 〗, 〘, 〙, 〚, 〛, 〜, 〝, 〞, 〟, 〠, 〰, 〱, 〲, 〳, 〴, 〵, 〶, 〷, 〻, 〼, 〽 ]
|
||||
'/bdz': [ ﹅, ﹆, ﹁, ﹂, ﹃, ﹄, ︙, ︱, ︻, ︼, ︗, ︘, ︵, ︶, ︷, ︸, ︹, ︺, ︿, ﹀, ︽, ︾, ︰, ︲, ︳, ︴, ﹉, ﹊, ﹋, ﹌, ﹍, ﹎, ﹏, ﹇, ﹈, ︐, ︑, ︒, ︔, ︕, ︖ ]
|
||||
#拼音、注音、声调
|
||||
'/py': [ ā, á, ǎ, à, ō, ó, ǒ, ò, ê, ê̄, ế, ê̌, ề, ē, é, ě, è, ī, í, ǐ, ì, ū, ú, ǔ, ù, ü, ǖ, ǘ, ǚ, ǜ, ḿ, m̀, ń, ň, ǹ, ẑ, ĉ, ŝ, ŋ ]
|
||||
'/pyd': [ Ā, Á, Ǎ, À, Ō, Ó, Ǒ, Ò, Ê, Ê̄, Ế, Ê̌, Ề, Ē, É, Ě, È, Ī, Í, Ǐ, Ì, Ū, Ú, Ǔ, Ù, Ü, Ǖ, Ǘ, Ǚ, Ǜ, Ḿ, M̀, Ń, Ň, Ǹ, Ẑ, Ĉ, Ŝ, Ŋ ]
|
||||
'/zy': [ ㄅ, ㄆ, ㄇ, ㄈ, ㄉ, ㄊ, ㄋ, ㄌ, ㄍ, ㄎ, ㄏ, ㄐ, ㄑ, ㄒ, ㄓ, ㄔ, ㄕ, ㄖ, ㄗ, ㄘ, ㄙ, ㄧ, ㄨ, ㄩ, ㄚ, ㄛ, ㄜ, ㄝ, ㄞ, ㄟ, ㄠ, ㄡ, ㄢ, ㄣ, ㄤ, ㄥ, ㄦ, ㄪ, ㄫ, ㄬ, ㄭ, ㆠ, ㆡ, ㆢ, ㆣ, ㆤ, ㆥ, ㆦ, ㆧ, ㆨ, ㆩ, ㆪ, ㆫ, ㆬ, ㆭ, ㆮ, ㆯ, ㆰ, ㆱ, ㆲ, ㆳ, ㆴ, ㆵ, ㆶ, ㆷ ]
|
||||
'/sd': [ ˉ, ˊ, ˇ, ˋ, ˆ, ˙, ˜, ˥, ˦, ˧, ˨, ˩, ꜀, ꜁, ꜂, ꜃, ꜄, ꜅, ꜆, ꜇, '〪', '〫', '〬', '〭' ]
|
||||
#汉字+圈v弧
|
||||
'/hzq': [ ㊀, ㊁, ㊂, ㊃, ㊄, ㊅, ㊆, ㊇, ㊈, ㊉, ㊊, ㊋, ㊌, ㊍, ㊎, ㊏, ㊐, ㊑, ㊒, ㊓, ㊔, ㊕, ㊖, ㊗, ㊘, ㊙, ㊚, ㊛, ㊜, ㊝, ㊞, ㊟, ㊠, ㊡, ㊢, ㊣, ㊤, ㊥, ㊦, ㊧, ㊨, ㊩, ㊪, ㊫, ㊬, ㊭, ㊮, ㊯, ㊰, ㉄, ㉅, ㉆, ㉇ ]
|
||||
'/hzh': [ ㈠, ㈡, ㈢, ㈣, ㈤, ㈥, ㈦, ㈧, ㈨, ㈩, ㈪, ㈫, ㈬, ㈭, ㈮, ㈯, ㈰, ㈱, ㈲, ㈳, ㈴, ㈵, ㈶, ㈷, ㈸, ㈹, ㈺, ㈻, ㈼, ㈽, ㈾, ㈿, ㉀, ㉁, ㉂, ㉃ ]
|
||||
#いろは順
|
||||
'/iro': [ い, ろ, は, に, ほ, へ, と, ち, り, ぬ, る, を, わ, か, よ, た, れ, そ, つ, ね, な, ら, む, う, ゐ, の, お, く, や, ま, け, ふ, こ, え, て, あ, さ, き, ゆ, め, み, し, ゑ, ひ, も, せ, す ]
|
||||
#假名
|
||||
'/jm': [ あ, ぁ, い, ぃ, う, ぅ, え, ぇ, お, ぉ, か, ゕ, が, き, ぎ, く, ぐ, け, ゖ, げ, こ, ご, さ, ざ, し, じ, す, ず, せ, ぜ, そ, ぞ, た, だ, ち, ぢ, つ, っ, づ, て, で, と, ど, な, に, ぬ, ね, の, は, ば, ぱ, ひ, び, ぴ, ふ, ぶ, ぷ, へ, べ, ぺ, ほ, ぼ, ぽ, ま, み, む, め, も, や, ゃ, ゆ, ゅ, よ, ょ, ら, り, る, れ, ろ, わ, ゎ, ゐ, ゔ, ゑ, を, ん, ・, ー, ゝ, ゞ, ゟ ]
|
||||
'/pjm': [ ア, ァ, イ, ィ, ウ, ゥ, エ, ェ, オ, ォ, カ, ヵ, ガ, キ, ギ, ク, グ, ケ, ヶ, ゲ, コ, ゴ, サ, ザ, シ, ジ, ス, ズ, セ, ゼ, ソ, ゾ, タ, ダ, チ, ヂ, ツ, ッ, ヅ, テ, デ, ト, ド, ナ, ニ, ヌ, ネ, ノ, ハ, バ, パ, ヒ, ビ, ピ, フ, ブ, プ, ヘ, ベ, ペ, ホ, ボ, ポ, マ, ミ, ム, メ, モ, ヤ, ャ, ユ, ュ, ヨ, ョ, ラ, リ, ル, レ, ロ, ワ, ヮ, ヰ, ヸ, ヴ, ヱ, ヹ, ヲ, ヺ, ン, ・, ー, ヽ, ヾ, ヿ, ㇰ, ㇱ, ㇲ, ㇳ, ㇴ, ㇵ, ㇶ, ㇷ, ㇸ, ㇹ, ㇺ, ㇻ, ㇼ, ㇽ, ㇾ, ㇿ ]
|
||||
'/jmk': [ か, ゕ, き, く, け, ゖ, こ, カ, ヵ, キ, ク, ケ, ヶ, コ ]
|
||||
'/jmg': [ が, ぎ, ぐ, げ, ご, ガ, ギ, グ, ゲ, ゴ ]
|
||||
'/jms': [ さ, し, す, せ, そ, サ, シ, ス, セ, ソ ]
|
||||
'/jmz': [ ざ, じ, ず, ぜ, ぞ, ザ, ジ, ズ, ゼ, ゾ ]
|
||||
'/jmt': [ た, ち, つ, っ, て, と, タ, チ, ツ, ッ, テ, ト ]
|
||||
'/jmd': [ だ, ぢ, づ, で, ど, ダ, ヂ, ヅ, デ, ド ]
|
||||
'/jmn': [ な, に, ぬ, ね, の, ん, ナ, ニ, ヌ, ネ, ノ, ン ]
|
||||
'/jmh': [ は, ひ, ふ, へ, ほ, ハ, ヒ, フ, ヘ, ホ ]
|
||||
'/jmb': [ ば, び, ぶ, べ, ぼ, バ, ビ, ブ, ベ, ボ ]
|
||||
'/jmp': [ ぱ, ぴ, ぷ, ぺ, ぽ, パ, ピ, プ, ペ, ポ ]
|
||||
'/jmm': [ ま, み, む, め, も, マ, ミ, ム, メ, モ ]
|
||||
'/jmy': [ や, ゃ, ゆ, ゅ, よ, ょ, ヤ, ャ, ユ, ュ, ヨ, ョ ]
|
||||
'/jmr': [ ら, り, る, れ, ろ, ラ, リ, ル, レ, ロ ]
|
||||
'/jmw': [ わ, ゐ, ゑ, を, ワ, ヰ, ヱ, ヲ ]
|
||||
'/jma': [ あ, か, が, さ, ざ, た, だ, な, は, ば, ぱ, ま, や, ら, わ, ア, カ, ガ, サ, ザ, タ, ダ, ナ, ハ, バ, パ, マ, ヤ, ラ, ワ ]
|
||||
'/jmi': [ い, き, ぎ, し, じ, ち, ぢ, に, ひ, び, ぴ, み, り, ゐ, イ, キ, ギ, シ, ジ, チ, ヂ, ニ, ヒ, ビ, ピ, ミ, リ, ヰ ]
|
||||
'/jmu': [ う, く, ぐ, す, ず, つ, づ, ぬ, ふ, ぶ, ぷ, む, る, ウ, ク, グ, ス, ズ, ツ, ヅ, ヌ, フ, ブ, プ, ム, ル ]
|
||||
'/jme': [ え, け, げ, せ, ぜ, て, で, ね, へ, べ, ぺ, め, れ, ゑ, エ, ケ, ゲ, セ, ゼ, テ, デ, ネ, ヘ, ベ, ペ, メ, レ, ヱ ]
|
||||
'/jmo': [ お, こ, ご, そ, ぞ, と, ど, の, ほ, ぼ, ぽ, も, ろ, を, オ, コ, ゴ, ソ, ゾ, ト, ド, ノ, ホ, ボ, ポ, モ, ロ, ヲ ]
|
||||
#假名+圈
|
||||
'/jmq': [ ㋐, ㋑, ㋒, ㋓, ㋔, ㋕, ㋖, ㋗, ㋘, ㋙, ㋚, ㋛, ㋜, ㋝, ㋞, ㋟, ㋠, ㋡, ㋢, ㋣, ㋤, ㋥, ㋦, ㋧, ㋨, ㋩, ㋪, ㋫, ㋬, ㋭, ㋮, ㋯, ㋰, ㋱, ㋲, ㋳, ㋴, ㋵, ㋶, ㋷, ㋸, ㋹, ㋺, ㋻, ㋼, ㋽, ㋾ ]
|
||||
#假名+半角
|
||||
'/jmbj': [ ア, ァ, イ, ィ, ウ, ゥ, エ, ェ, オ, ォ, カ, キ, ク, ケ, コ, サ, シ, ス, セ, ソ, タ, チ, ツ, ッ, テ, ト, ナ, ニ, ヌ, ネ, ノ, ハ, ヒ, フ, ヘ, ホ, マ, ミ, ム, メ, モ, ヤ, ャ, ユ, ュ, ヨ, ョ, ラ, リ, ル, レ, ロ, ワ, ヲ, ン, ・, ー, ゙, ゚ ]
|
||||
#韩文
|
||||
'/hw': [ ㄱ, ㄴ, ㄷ, ㄹ, ㅁ, ㅂ, ㅅ, ㅇ, ㅈ, ㅊ, ㅋ, ㅌ, ㅍ, ㅎ ]
|
||||
#韩文+圈v弧
|
||||
'/hwq': [ ㉠, ㉡, ㉢, ㉣, ㉤, ㉥, ㉦, ㉧, ㉨, ㉩, ㉪, ㉫, ㉬, ㉭, ㉮, ㉯, ㉰, ㉱, ㉲, ㉳, ㉴, ㉵, ㉶, ㉷, ㉸, ㉹, ㉺, ㉻, ㉼, ㉽, ㉾, ㉿ ]
|
||||
'/hwh': [ ㈀, ㈁, ㈂, ㈃, ㈄, ㈅, ㈆, ㈇, ㈈, ㈉, ㈊, ㈋, ㈌, ㈍, ㈎, ㈏, ㈐, ㈑, ㈒, ㈓, ㈔, ㈕, ㈖, ㈗, ㈘, ㈙, ㈚, ㈛, ㈜, ㈝, ㈞ ]
|
||||
# 中文标点符号表,来自 https://www.w3.org/TR/clreq/#tables_of_chinese_punctuation_marks
|
||||
# 将点号、非夹、夹注、行间四个类别放在不同的列表中
|
||||
'/dh': [。, ., ,, 、, :, ;, !, ‼, ?, ⁇]
|
||||
'/fj': [⸺, ——, ……, ⋯⋯, ~, -, –, —, ·, ・, ‧, /, /, \, |]
|
||||
'/jz': [「, 」, 『, 』, “, ”, ‘, ’, (, ), 《, 》, 〈, 〉, 【, 】, 〖, 〗, 〔, 〕, [, ], {, }, «, », ‹, ›, ⟨, ⟩]
|
||||
'/hj': [_, ﹏, ●, •]
|
||||
'/yd': [·, ・, •, ●]
|
||||
# Unicode General Punctuation https://www.unicode.org/charts/PDF/U2000.pdf
|
||||
# 将 Unicdoe 中的非 ASCII 英文标点列在此处,而实际上对应的中文标点与其共享码位
|
||||
# 中英标点
|
||||
'/bdzy': [‐, ‑, ‒, –, —, ―, ‖, ‗, ‘, ’, ‚, ‛, “, ”, „, ‟, †, ‡, •, ‣, ․, ‥, …, ‧, ‰, ‱, ′, ″, ‴, ‵, ‶, ‷, ‸, ‹, ›, ※, ‼, ‽, ‾, ‿, ⁀, ⁁, ⁂, ⁃, ⁄, ⁅, ⁆, ⁇, ⁈, ⁉, ⁊, ⁋, ⁌, ⁍, ⁎, ⁏, ⁐, ⁑, ⁒, ⁓, ⁔, ⁕, ⁖, ⁗, ⁘, ⁙, ⁚, ⁛, ⁜, ⁝, ⁞]
|
||||
#动物界
|
||||
'/dwj': [🐶, 🐮, 🐵, 🙈, 🙉, 🙊, 🐒, 🐔, 🐴, 🐷, 🐽, 🐭, 🦐, 🦀, 🐢, 🐱, 🐹, 🐰, 🐻, 🐼, 🐨, 🐧, 🐦, 🐤, 🐣, 🐥, 🐯, 🦁, 🐸, 🐙, 🦆, 🦅, 🦉, 🦇, 🐺, 🐗, 🦄, 🐝, 🐛, 🦋, 🐌, 🐞, 🐜, 🕷, 🦂, 🐍, 🦎, 🦑, 🐠, 🐟, 🐡, 🐬, 🐳, 🐊, 🐆, 🐅, 🐃, 🐂, 🐄, 🐪, 🐫, 🐘, 🦏, 🦍, 🐐, 🐏, 🐑, 🐎, 🐖, 🐀, 🐁, 🐓, 🦃, 🕊, 🐕, 🐩, 🐈, 🐇, 🐿, 🦆, 🦅, 🦉, 🦇, 🐺, 🐗, 🦄, 🐴, 🐝, 🐛, 🐞, 🪲, 🦟, 🐚, 🐌, 🦋, 🐜, 🕷️, 🐢, 🐍, 🦎, 🦂, 🦀, 🦑, 🐙, 🦐, 🦞, 🦪, 🐠, 🐟, 🐡, 🪼, 🐬, 🦈, 🐋, 🐊, 🐆, 🐅, 🐃, 🐂, 🐄, 🦬, 🦌, 🐪, 🐫, 🐘, 🦏, 🦍, 🦧, 🦣, 🐎, 🐖, 🐐, 🐏, 🐑, 🐕, 🐩, 🐈, 🐈⬛️, 🐇, 🐁, 🐀, 🐿️, 🐉, 🐒, 🦙, 🦛, 🫏, 🫎, 🦖, 🦕, 🦡, 🦝, 🦨, 🦫, 🦦, 🦭, 🦥, 🐓, 🦃, 🕊️, 🦩, 🪿, 🦢, 🦜, 🦤, 🦚, 🐦⬛]
|
||||
#表情
|
||||
'/bq': [ 😀, 😁, 😂, 🤣, 😃, 😄, 😅, 😆, 😉, 😊, 😋, 😎, 😍, 😘, 😗, 😙, 😚, ☺, 🙂, 🤗, 🤩, 🤔, 🤨, 😐, 😑, 😶, 🙄, 😏, 😣, 😥, 😮, 🤐, 😯, 😪, 😫, 😴, 😌, 😛, 😜, 😝, 🤤, 😒, 😓, 😔, 😕, 🙃, 🤑, 😲, ☹, 🙁, 😖, 😞, 😟, 😤, 😢, 😭, 😦, 😧, 😨, 😩, 🤯, 😬, 😰, 😱, 😳, 🤪, 😵, 😠, 😡, 🤬, 😷, 🤒, 🤕, 🤢, 🤮, 🤧, 😇, 🤠, 🤡, 🤥, 🤫, 🤭, 🧐, 🤓 ]
|
||||
#天气
|
||||
'/tq': [☀️, 🌤️, ⛅️, 🌦️, 🌥️, ☁️, 🌨️, 🌧️, 🌩️, ⛈️, ❄️, 💨, 🌪️, 🌫️, 🌊]
|
||||
#国旗
|
||||
'/gq': [🏳️, 🏴, 🏴☠️, 🏁, 🚩, 🏳️🌈, 🏳️⚧️, 🇺🇳, 🇦🇺, 🇨🇦, 🇨🇳, 🇩🇪, 🇭🇰, 🇯🇵, 🇳🇿, 🇹🇼, 🇺🇸]
|
||||
#手势
|
||||
'/ss': [👌, 👍, 👎, 👊, 🤝, ✌️, 💪, 🙏, ✊, 👏, 👋, 🤞, ✋, 🤚, 🖖, 🤙, 🖕, 🤟, ☝️, 👆, 👇, 👈, 👉, 🤛, 🤜, 🤲, 🤘, 🙌, 👐, ✍️, 💅]
|
||||
#按键
|
||||
'/aj': [⌘, ⌥, ⇧, ⌃, ⎋, ⇪, , ⌫, ⌦, ↩︎, ⏎, ␣, ⏏, ⇟, ⇞]
|
||||
#特殊符号
|
||||
'/tsfh': [©, ®, ℗, ⓘ, ℠, ™, ℡, ␡, ♂, ♀, ☉, ☊, ☋, ☌, ☍, ☐, ☑︎, ☒, ☜, ☝, ☞, ☟, ✎, ✄, ♻, ⚐, ⚑, ⚠]
|
||||
#常用
|
||||
'/cy': [👌, 👍, 😂, 😅, 😡, 😮, 😱, 😭, 😘, 😰, 💩]
|
||||
#中华
|
||||
'/zh': [🧧, 🥮, 🧨, 🧮]
|
||||
#早餐
|
||||
'/zc': [🍜, 🍚, 🍲, 🥘, 🥟, 🥠, 🥡, 🥢]
|
||||
#串串
|
||||
'/cc': [🍢, 🍡]
|
||||
#体育器材
|
||||
'/tyqc': [🏒, 🏸, 🏓, 🏑, 🏏, ⛳️, 🏹, ⚽️, 🏀, 🏈, ⚾️, 🥎️, 🎾, 🏐, 🏉, 🎱, ⛸️, 🛼, 🎿, 🎳, 🥏, 🥍, 🛹, 🤿, 🪂, 🛷, 🥌, 🪃, 🪁]
|
||||
#运动员
|
||||
'/ydy': [⛷️, 🏂🏻, 🏋🏻, 🤺, 🤼🏻, 🤸🏻, ⛹🏻, 🤾🏻, 🏌🏻, 🏄🏻, 🏊🏻, 🤽🏻, 🚣🏻, 🏇🏻, 🚴🏻, 🚵🏻, 🧗🏻, 🤹🏻]
|
||||
#动物脸
|
||||
'/dwl': [🐶, 🐱, 🐭, 🐹, 🐰, 🦊, 🐻, 🐻❄️, 🐼, 🐨, 🐯, 🦁, 🐮, 🐷, 🐽, 🐸, 🐵]
|
||||
#包包
|
||||
'/bb': [👝, 👛, 👜, 💼, 🧳, 🎒]
|
||||
#午餐/晚餐
|
||||
'/wc': [🍛, 🍲, 🍝, 🍜, 🥘, 🍣, 🍱, 🍘, 🍙, 🍚, 🥡]
|
||||
#景点
|
||||
'/jd': [🗽, 🏰, 🗼, 🗻, 🏯, 🏝️, 🏖️, 🌁, 🌉, 🏞️]
|
||||
#器官
|
||||
'/qg': [👁️, 👂🏻, 👃🏻, 👄, 🦷, 🧠, 🫁, 🫀, 🦵🏻, 🦶🏻, 🖐🏻, 👅]
|
||||
#圆形
|
||||
'/yx': [🔴, 🟠, 🟡, 🟢, 🔵, 🟣, 🟤, ⚫️, ⚪️]
|
||||
#纸币
|
||||
'/zb': [💵, 💶, 💷, 💴]
|
||||
#夜空
|
||||
'/yk': [🌙, 💫, ⭐️, 🌟, ✨, 🌛, 🌜]
|
||||
#自然
|
||||
'/zr': [🔥, 💧, 🌬️, 🫧, ☀️, 🌤️, ⛅️, 🌦️, 🌥️, ☁️, 🌨️, 🌧️, 🌩️, ⛈️, ❄️, 💨, 🌪️, 🌫️, 🌊, 🧊, 🪨]
|
||||
#娱乐
|
||||
'/yule': [🎮, 🎰, 🎲, 🎯, 🎳, 🎧, 🎤️, 🎪, 🎫, 🎟️, ♟️, 🕹️, 🖲️, 🪀, 🪩]
|
||||
#宗教
|
||||
'/zj': [✝️, ☪️, 🕉️, ☸️, 🔯, 🕎, ☯️, ☦️, 🪯, 🛐, ⛪️, 🕌, 🕍, 🕋, ⛩️, 🛕]
|
||||
#家鸡/鸡鸡
|
||||
'/jj': [🦆, 🐓, 🦃, 🐔, 🐤, 🐣, 🐥, 🦚, 🪿]
|
||||
#工具
|
||||
'/gj': [⚙️, 🔩, ⛏️, 🛠️, ⚒️, 🔨, 🔧, ⛓️, 🧰, 🪒, 🪚, 🪛, 🪜, 🪡]
|
||||
#帽子
|
||||
'/mz': [👒, 🧢, 🎩, 🎓, ⛑️, 🪖]
|
||||
#甜心/桃心
|
||||
'/tx': [❤️, 🧡, 💛, 💚, 💙, 🩵, 🩷, 💜, 🤎, 🖤, 🩶, 🤍]
|
||||
#数码
|
||||
'/sm': [⌚️, 📱, 💻, ⌨️, 🖥️, 🖨️, 🖱️, 📷, 📹, 💾, 💽, 💿, 📀]
|
||||
#早点
|
||||
'/zd': [🍳, 🥚, 🧀, 🥖, 🥛, 🍯, 🥪, 🥫, 🥯, 🧇, 🫓]
|
||||
#时分
|
||||
'/sf': [🕛, 🕧, 🕐, 🕜, 🕑, 🕝, 🕒, 🕞, 🕓, 🕟, 🕔, 🕠, 🕕, 🕡, 🕖, 🕢, 🕗, 🕣, 🕘, 🕤, 🕙, 🕥, 🕚, 🕦]
|
||||
#月亮
|
||||
'/yl': [🌕, 🌖, 🌗, 🌘, 🌑, 🌒, 🌓, 🌔]
|
||||
#服装
|
||||
'/fz': [🧥, 👚, 👕, 👖, 🩳, 👔, 👗, 👘, 🥻, 🩲, 👙, 🩱, 🥼]
|
||||
#水果
|
||||
'/sg': [🍏, 🍎, 🍐, 🍊, 🍋, 🍌, 🍉, 🍇, 🍓, 🫐, 🍈, 🍒, 🍑, 🍍, 🥝, 🥑, 🥥, 🥭]
|
||||
#植物
|
||||
'/zw': [🌲, 🌳, 🎄, 🌵, 🌴, 🌱, 🌿, ☘️, 🍀, 🎍, 🪴, 🌾, 🥬, 🪻]
|
||||
#乐器
|
||||
'/yq': [🎻, 🎸, 🎹, 🎷, 🎺, 🥁, 🪕, 🪘, 🪗, 🪈, 🪇]
|
||||
#武器
|
||||
'/wq': [🔫, 🗡️, ⚔️, 🔪, 🛡️, 🪓, 🚀]
|
||||
#汽车
|
||||
'/qc': [🚗, 🚕, 🚙, 🚌, 🚎, 🏎️, 🚓, 🚑, 🚒, 🚐, 🚚, 🚛, 🎢, 🛻, 🚔, 🚍, 🚘, 🚖, 🛺]
|
||||
#火车
|
||||
'/hc': [🚄, 🚅, 🚝, 🚆, 🚂, 🚉, 🚈, 🚇, 🚊]
|
||||
#公交车
|
||||
'/gjc': [🚞, 🚋, 🚃, 🚟]
|
||||
#奖牌
|
||||
'/jp': [🏅, 🎖️, 🥇, 🥈, 🥉, 🏆]
|
||||
#球类
|
||||
'/ql': [⚽️, 🏀, 🏈, 🏐, 🏉, ⚾️, 🥎️, 🎾, 🎱, 🪀, 🏓, 🏸, 🏒, 🏑, 🏏, 🛹, 🥍]
|
||||
#甜点
|
||||
'/td': [🍯, 🍰, 🍮, 🎂, 🍭, 🍬, 🍫, 🍩, 🍪, 🍦, 🧁]
|
||||
#十二生肖
|
||||
'/sesx': [🐁, 🐀, 🐂, 🐃, 🐄, 🦬, 🐅, 🐆, 🐇, 🐉, 🐍, 🐎, 🐏, 🐐, 🐑, 🐒, 🦧, 🦍, 🦃, 🐓, 🐕, 🦮, 🐕🦺, 🐖, 🐗]
|
||||
#节日色彩
|
||||
'/jrsc': [🎊, 🎉, 🪅, 🎏, 🎎, 🏮, 🎐, 🧧, 🎁, 🧨, 🎇, 🎆, 🎑, 🎄, 🧑🏻🎄]
|
||||
#粗粮
|
||||
'/cl': [🌽, 🥔, 🍠, 🥜, 🌰]
|
||||
#精灵
|
||||
'/jl': [🧙🏻, 🧝🏻, 🧛🏻, 🧟, 🧞, 🧜🏻, 🧚🏻, 🦹🏻]
|
||||
#船只
|
||||
'/cz': [🚢, ⛴️, 🛳️, 🛥️, 🚤, ⛵️, 🛶, ⚓️]
|
||||
#花朵
|
||||
'/hd': [🌸, 🌺, 🌼, 🌻, 🌷, 🌹, 💐, 🥀, 🪷, 🪻]
|
||||
#色彩
|
||||
'/sc': [🍅, 🍆, 🥒, 🥕, 🌶️, 🥦, 🥗, 🥬, 🫒, 🫑, 🫘, 🫛]
|
||||
#叶子
|
||||
'/yz': [🍃, 🍂, 🍁, 🌱, 🌿, 🥬]
|
||||
#虫子
|
||||
'/chz': [🐛, 🪱, 🐞, 🪲, 🪳, 🦗, 🦟, 🐜, 🪰, 🐌, 🐝]
|
||||
#血型
|
||||
'/xx': [🅰️, 🅱️, 🅾️, 🆎️]
|
||||
#西餐
|
||||
'/xc': [🍕, 🥓, 🧀, 🥖, 🥐, 🍝, 🌯, 🌮, 🥙, 🍟, 🍔, 🌭, 🥞, 🥪, 🥯, 🧇, 🫕]
|
||||
#调料
|
||||
'/tl': [🧄, 🫚, 🧅, 🧂, 🧀]
|
||||
#酒水
|
||||
'/js': [🍷, 🥃, 🍺, 🍶, 🍾, 🍸]
|
||||
#雪
|
||||
'/xue': [❄️, 🌨️, ☃️, ⛄️, 🧊]
|
||||
#小零食
|
||||
'/xls': [🍭, 🍬, 🍫, 🍿, 🍩, 🍪]
|
||||
#电器
|
||||
'/dq': [💡, 📺, ☎️, 📟, 📞, 📠, 📻, 🕰️, 📡, 🔦]
|
||||
'/exz': [👡, 👢, 👞, 👟, 🥾, 🥿, 👠, 🛼, ⛸️]
|
||||
#颜色
|
||||
'/ys': [🟥, 🟧, 🟨, 🟩, 🟦, 🟪, 🟫, ⬛️, ⬜️, 🔴, 🟠, 🟡, 🟢, 🔵, 🟣, 🟤, ⚫️, ⚪️, ❤️, 🧡, 💛, 💚, 💙, 🩵, 🩷, 💜, 🤎, 🖤, 🩶, 🤍]
|
||||
#餐饮
|
||||
'/yp': [🧋, 🍹, 🧃, 🍸, 🍵, ☕️, 🥛, 🍷, 🥃, 🍶, 🥂, 🍾, 🍻, 🍺, 🧉]
|
||||
#餐具
|
||||
'/cj': [🥄, 🍴, 🍽️, 🥣, 🥢, 🫖]
|
||||
#发型
|
||||
'/fx': [🦲, 🦰, 🦱, 🦳]
|
||||
'/eyl': [🐠, 🐟, 🐡, 🪼, 🐬, 🐳, 🐋, 🦈, 🦭, 🦦]
|
||||
#鸟类
|
||||
'/niao': [🦆, 🦅, 🦉, 🦇, 🐓, 🦃, 🕊️, 🐧, 🐦, 🦚, 🦜, 🦩, 🦤, 🦢, 🪿, 🐦⬛]
|
||||
#面包
|
||||
'/mb': [🍞, 🥐, 🥖, 🥨, 🥯, 🍩, 🥮]
|
||||
#点心
|
||||
'/dx': [🍮, 🍩, 🍪, 🍧, 🍨, 🍦, 🍰, 🧁, 🧇, 🧆]
|
||||
365
wanxiang_t9.schema.yaml
Normal file
365
wanxiang_t9.schema.yaml
Normal file
@@ -0,0 +1,365 @@
|
||||
# Rime schema
|
||||
# encoding: utf-8
|
||||
schema:
|
||||
schema_id: wanxiang_t9
|
||||
name: 万象・仓九
|
||||
version: "LTS"
|
||||
author:
|
||||
- amzxyz
|
||||
- morse
|
||||
description: |
|
||||
仓输入法:万象拼音九宫格方案
|
||||
dependencies:
|
||||
- wanxiang_mixedcode #中英文混合词汇
|
||||
- wanxiang_reverse # 部件拆字,反查及辅码
|
||||
|
||||
# 开关
|
||||
# reset: 默认状态。注释掉后,切换窗口时不会重置到默认状态。
|
||||
# states: 方案选单显示的名称。可以注释掉,仍可以通过快捷键切换。
|
||||
# abbrev: 默认的缩写取 states 的第一个字符,abbrev 可自定义一个字符
|
||||
switches:
|
||||
- name: ascii_mode # 中英输入状态
|
||||
states: [ 中文, 英文 ]
|
||||
- name: ascii_punct # 中英标点,可以在中文输入状态输入英文符号
|
||||
states: [ 中标, 英标 ]
|
||||
- name: full_shape #全角、半角字符输出
|
||||
states: [ 半角, 全角 ]
|
||||
- name: emoji #候选出现emoji滤镜,会显示在相应的候选后面,万象侧重于tips提示,避免候选被占用,因此默认为reset: 0,归属opencc emoji滤镜
|
||||
states: [表情关, 表情开]
|
||||
- name: chinese_english #候选进入翻译模式滤镜,会显示在相应的候选后面,万象侧重于tips提示,避免候选被占用,归属opencc 翻译滤镜
|
||||
states: [ 翻译关, 翻译开 ]
|
||||
- options: [ raw_input, tone_display, full_pinyin ] #开启后在输入编码的位置实时转换为带声调全拼或者不带声调全拼,不开启则采用系统配置原始编码,影响的是preedit_format,归属:super_preedit.lua
|
||||
states: [ 原编码, 有声调, 无声调 ]
|
||||
# reset: 2 #对于开关组从0开始数,第几个就reset几可设为默认
|
||||
- options: [ s2s, s2t, s2hk, s2tw ] # 简繁转换开关组,可以在一个空选项和多个实际“- simplifier@s2hk”引入的项目之前切换,这是一个开关组,你可以将其中任意一个s2s等设置为toggle快捷键,多次按下将轮询
|
||||
states: [ 简体, 通繁, 港繁, 臺繁 ]
|
||||
- name: tone_hint #开启后在候选的注释里面实时显示全拼声调,不开启则采用系统配置,影响的是comment_format,归属:super_comment.lua
|
||||
states: [ 读音关, 读音开 ]
|
||||
- name: super_tips #开启后在输入编码后面的提示区显示实时的提示数据,受tips数据库影响,表情、翻译、车牌、符号等对应关系数据,并可实现句号上屏,不开启则默认,影响的是segment.prompt参数,归属:super_tips.lua
|
||||
states: [ 提示关, 提示开 ]
|
||||
reset: 1
|
||||
|
||||
|
||||
# 输入引擎
|
||||
engine:
|
||||
processors:
|
||||
- lua_processor@*super_tips #超级提示模块:表情、简码、翻译、化学式、等等靠你想象
|
||||
- lua_processor@*partial_commit #通过ctrl+1~0局部提交10个字以内的句子的前几个字(一般为正确的前几个)使用时要遵循合理的分词结构能促进后续编码打出正确的词汇
|
||||
- lua_processor@*super_sequence*P #手动排序,高亮候选 ctrl+j左移动 ctrl+k 右移动 ctrl+l 移除位移 ctrl+p 置顶
|
||||
- lua_processor@*limit_repeated #用于限制最大候选长度以及最大重复输入声母编码长度,避免性能异常
|
||||
- lua_processor@*backspace_limit #防止连续 Backspace 在编码为空时删除已上屏内容
|
||||
- ascii_composer #处理英文模式及中英文切换
|
||||
- recognizer #与 matcher 搭配,处理符合特定规则的输入码,如网址、反查等 tags
|
||||
- key_binder #在特定条件下将按键绑定到其他按键,如重定义逗号、句号为候选翻页、开关快捷键等
|
||||
- lua_processor@*key_binder #绑定按键扩展能力,支持正则扩展将按键生效情景更加细化
|
||||
- speller #拼写处理器,接受字符按键,编辑输入
|
||||
- punctuator #符号处理器,将单个字符按键直接映射为标点符号或文字
|
||||
- selector #选字处理器,处理数字选字键〔可以换成别的哦〕、上、下候选定位、换页
|
||||
- navigator #处理输入栏内的光标移动
|
||||
- express_editor #编辑器,处理空格、回车上屏、回退键
|
||||
segmentors:
|
||||
- ascii_segmentor #标识英文段落〔譬如在英文模式下〕字母直接上屛
|
||||
- matcher #配合 recognizer 标识符合特定规则的段落,如网址、反查等,加上特定 tag
|
||||
- abc_segmentor #标识常规的文字段落,加上 abc 这个 tag
|
||||
- affix_segmentor@wanxiang_reverse #反查 tag
|
||||
- punct_segmentor #标识符号段落〔键入标点符号用〕加上 punct 这个 tag
|
||||
- fallback_segmentor #标识其他未标识段落,必须放在最后帮助tag模式切换后回退重新处理
|
||||
translators:
|
||||
- punct_translator #配合 punct_segmentor 转换标点符号
|
||||
- script_translator #脚本翻译器,用于拼音、粤拼等基于音节表的输入方案
|
||||
- lua_translator@*version_display #输入'/wx',显示万象项目网址和当前版本号
|
||||
- lua_translator@*shijian #农历、日期、节气、节日、时间、周、问候模板等等,触发清单看下文
|
||||
- lua_translator@*unicode #通过输入大写U引导,并输入Unicode编码获得汉字输出
|
||||
- lua_translator@*number_translator #数字、金额大写,通过输入大写R1234获得候选输出
|
||||
- lua_translator@*super_calculator #超级计算器,Lua内查看高级用法
|
||||
- table_translator@custom_phrase #自定义短语 custom_phrase.txt,用于置顶自定义编码候选词
|
||||
- table_translator@chengyu #简码成语词汇表导入
|
||||
- table_translator@wanxiang_mixedcode #中英等混合词汇表导入
|
||||
- table_translator@wanxiang_reverse #挂接部件组字和笔画反查
|
||||
filters:
|
||||
- lua_filter@*super_sequence*F #手动排序,高亮候选 ctrl+j左移动 ctrl+k 右移动 ctrl+0 移除位移
|
||||
- reverse_lookup_filter@radical_reverse_lookup #部件拆字滤镜,放在super_comment前面,进一步被超级注释处理以获得拼音编码的提示
|
||||
- lua_filter@*super_comment_preedit #超级注释模块、超级preedit,支持错词提示、辅助码显示,部件组字读音注释,有声调、无声调全拼编码的转换,支持个性化配置和关闭相应的功能,详情搜索super_comment_preedit进行详细配置
|
||||
- simplifier@emoji #Emoji滤镜
|
||||
- simplifier@s2t #简繁切换通繁
|
||||
- simplifier@s2tw #简繁切换台繁
|
||||
- simplifier@s2hk #简繁切换港繁
|
||||
- simplifier@chinese_english #中英翻译滤镜
|
||||
- lua_filter@*super_lookup #字词输入中反查辅助筛选
|
||||
- lua_filter@*super_filter #功能太多详见Lua文件
|
||||
- uniquifier # 去重
|
||||
|
||||
super_comment: # 超级注释模块,子项配置 true 开启,false 关闭
|
||||
candidate_length: 1 # 候选词辅助码提醒的生效长度,0为关闭 但同时清空其它,应当使用上面开关来处理
|
||||
corrector_type: "〔comment〕" # 错音措字,随意更换左右括号,比如"〔comment〕" 不加括号为无括号,comment占位不能动
|
||||
chaifen: "〔chaifen〕" # 拆分显示,随意更换左右括号,比如"〔chaifen〕" 不加括号为无括号,chaifen占位不能动
|
||||
|
||||
# Tips 配置项
|
||||
tips:
|
||||
# 禁用的 tips 类型,初始化 tips 数据库的时候会直接忽略相关规则,修改部署后生效
|
||||
# 可选项为:偏旁,符号,化学式,时间,符号,组字,翻译,表情,货币,车牌
|
||||
disabled_types: []
|
||||
|
||||
#在8105基础上你可以通过黑白名单微调你自己的字符集过滤清单,主数据库位于lua/charset.bin不可编辑
|
||||
charsetlist: []
|
||||
charsetblacklist: []
|
||||
#shijian:仅仅作为提示使用,编码已经写死,引导键可以在key_binder下修改前缀
|
||||
#时间:osj 或者 /sj
|
||||
#日期:orq 或者 /rq
|
||||
#农历:onl 或者 /nl
|
||||
#星期:oxq 或者 /xq
|
||||
#今年第几周:oww 或者 /ww
|
||||
#节气:ojq 或者 /jq
|
||||
#日期+时间:odt 或者 /dt
|
||||
#时间戳:ott 或者 /tt
|
||||
#大写N日期:N20250315 或者N0312不带年
|
||||
#节日:ojr 或者 /jr
|
||||
#问候模板:/day 或者 oday
|
||||
# 通用日期时间格式化函数(供 /rq、/sj、/dt、N0101、N20150101 场景复用)
|
||||
# 支持转义:
|
||||
# \X —— 转义单个字符 X,按字面量输出(如 \Y \m \H 等)
|
||||
# [[...]] —— 区块整体按字面量输出
|
||||
#
|
||||
# 约定占位符:
|
||||
# 【日期】
|
||||
# Y 四位年份 0000-9999 例:2025
|
||||
# y 两位年份 00-99 例:25
|
||||
# m 月(前导零) 01-12 例:02
|
||||
# n 月(不带前导零) 1-12 例:2
|
||||
# d 日(前导零) 01-31 例:09
|
||||
# j 日(不带前导零) 1-31 例:9
|
||||
#
|
||||
# 【时间】
|
||||
# H 24小时(前导零) 00-23 例:08
|
||||
# G 24小时(不带零) 0-23 例:8
|
||||
# I 12小时(前导零) 01-12 例:08
|
||||
# l 12小时(不带零) 1-12 例:8 (注意是小写 L)
|
||||
# M 分钟(前导零) 00-59 例:05
|
||||
# S 秒(前导零) 00-59 例:09
|
||||
# p am/pm(小写) am / pm
|
||||
# P AM/PM(大写) AM / PM
|
||||
# 【时区】
|
||||
# O 带冒号格式 +08:00、-04:30、+05:45
|
||||
# o 不带冒号格式 +0800、-0430、+0545
|
||||
date_formats:
|
||||
- "Y年m月d日"
|
||||
- "Y-m-d"
|
||||
- "Y/m/d"
|
||||
- "Y.m.d"
|
||||
- "Ymd"
|
||||
- "Y年n月j日"
|
||||
- "y年n月j日"
|
||||
- "n月j日"
|
||||
time_formats:
|
||||
- "H:M"
|
||||
- "H点M分"
|
||||
- "H:M:S"
|
||||
- "H时M分S秒"
|
||||
- "下午I:M"
|
||||
- "I:M P"
|
||||
datetime_formats:
|
||||
- "Y-m-d H:M:S"
|
||||
- "Y-m-dTH:M:S O"
|
||||
- "YmdHMS"
|
||||
- "Y年m月d日 H点M分"
|
||||
- "y/m/d I:M p"
|
||||
|
||||
# Lua 配置:计算器触发关键字
|
||||
calculator:
|
||||
trigger: "V"
|
||||
|
||||
# 主翻译器,拼音
|
||||
translator:
|
||||
dictionary: wanxiang # 挂载主词库
|
||||
# packs: user #导入根目录下名称为user.dict.yaml的自定义固定词典
|
||||
prism: wanxiang_t9 # 多方案共用一个词库时,为避免冲突,需要用 prism 指定一个名字。
|
||||
enable_completion: true # 启用候选词补全
|
||||
# user_dict: zrm.userdb # 用户词典的文件名称
|
||||
# db_class: tabledb #开启后就不会产生wanxiang.userdb这样的文件夹,会直接输出文本wanxiang.txt同时无法使用同步能力,可设 tabledb〔文本〕或 userdb〔二进制〕
|
||||
enable_user_dict: true # 是否开启自动调频,即开启用户词典
|
||||
enable_encoder: true #是否开启自动造词
|
||||
enable_sentence: false #是否开启自动造句
|
||||
enable_correction: false #是否开启自动纠错
|
||||
encode_commit_history: true # 预留历史上屏自动编码成词
|
||||
contextual_suggestions: false #模型预测,假设模型里面有的四个字的词汇 现在智能 而首选组合 现在只能 当你输入 现在 上屏后下一次输入zhi neng就会输出,智能前提是没有权重更高的了,很明显这与你的预期“现在只能”不符。很明显实际上又要预测又要连续句子,放一起是很难优雅的。
|
||||
max_homophones: 5
|
||||
max_homographs: 5
|
||||
core_word_length: 4 # >0 启用,按段学词 + 相邻段拼接
|
||||
max_word_length: 7 # >0 启用,过长短语不记整词,只加元素权重
|
||||
initial_quality: 3 #初始质量拼音的权重应该比英文大
|
||||
spelling_hints: 30 #将注释以词典code字符串形式完全暴露,通过super_comment.lua完全接管,灵活配置。
|
||||
always_show_comments: true # Rime 默认在 preedit 等于 comment 时取消显示 comment,这里强制一直显示,供super_comment.lua做判断用。
|
||||
comment_format: {comment} #将注释以词典字符串形式完全暴露,通过super_preedit.lua完全接管,灵活配置。
|
||||
|
||||
#disable_user_dict_for_patterns: #如果你开启调频,需要一并考虑这个配置是否需要,基本的6码3字不调频,你可以自定义,目前的逻辑是依然记录用户词但满足规则的不输出不被使用
|
||||
# - "^[a-z]{1,6}"
|
||||
|
||||
# 自定义短语
|
||||
custom_phrase:
|
||||
dictionary: ""
|
||||
user_dict: custom_phrase #需要手动创建 custom_phrase.txt 文件
|
||||
db_class: stabledb #可设 tabledb〔文本〕或 userdb〔二进制〕
|
||||
enable_completion: false #补全提示
|
||||
enable_sentence: false #禁止造句
|
||||
initial_quality: 99 #custom_phrase 的权重应该比 pinyin 和 wanxiang_en 大
|
||||
|
||||
|
||||
# 简码词库导入位于dicts得chengyu.txt文件词库
|
||||
chengyu:
|
||||
dictionary: ""
|
||||
user_dict: dicts/chengyu
|
||||
db_class: stabledb
|
||||
enable_sentence: false
|
||||
enable_completion: false
|
||||
initial_quality: 1.3
|
||||
|
||||
# 中文、英文、数字、符号等混合词汇
|
||||
wanxiang_mixedcode:
|
||||
dictionary: wanxiang_mixedcode
|
||||
db_class: stabledb
|
||||
enable_completion: true
|
||||
enable_sentence: false
|
||||
initial_quality: 2
|
||||
comment_format:
|
||||
- xform/^.+$//
|
||||
|
||||
# Emoji
|
||||
emoji:
|
||||
option_name: emoji
|
||||
opencc_config: emoji.json
|
||||
inherit_comment: false # 在反查中,emoji 返回空注释
|
||||
|
||||
|
||||
#中文转英文
|
||||
chinese_english:
|
||||
option_name: chinese_english
|
||||
opencc_config: chinese_english.json
|
||||
tips: char
|
||||
inherit_comment: false
|
||||
|
||||
# 简繁切换
|
||||
s2t:
|
||||
option_name: s2t
|
||||
opencc_config: s2t.json # s2t.json | s2hk.json | s2tw.json | s2twp.json
|
||||
tips: none # 转换提示: all 都显示 | char 仅单字显示 | none 不显示。
|
||||
tags: [ abc ] # 限制在对应 tag,不对其他如反查的内容做简繁转换
|
||||
|
||||
s2hk:
|
||||
opencc_config: s2hk.json
|
||||
option_name: s2hk
|
||||
tags: [abc]
|
||||
|
||||
s2tw:
|
||||
opencc_config: s2tw.json
|
||||
option_name: s2tw
|
||||
tags: [abc]
|
||||
|
||||
# 部件拆字反查
|
||||
wanxiang_reverse:
|
||||
tag: wanxiang_reverse
|
||||
dictionary: wanxiang_reverse
|
||||
db_class: stabledb
|
||||
enable_user_dict: false
|
||||
prefix: "`" # 反查前缀(反查时前缀会消失影响打英文所以设定为两个字母,或可改成一个非字母符号),与 recognizer/patterns/radical_lookup 匹配
|
||||
tips: "〔反查:部件|笔画〕"
|
||||
|
||||
# 部件拆字滤镜
|
||||
radical_reverse_lookup:
|
||||
tags: [ wanxiang_reverse ] #起作用tag范围
|
||||
overwrite_comment: true #是否覆盖其他提示
|
||||
dictionary: wanxiang #带音调的词典
|
||||
|
||||
wanxiang_lookup: #设置归属于super_lookup.lua
|
||||
tags: [ abc ] # 检索当前tag的候选
|
||||
key: "`" # 输入中反查引导符,要添加到 speller/alphabet
|
||||
lookup: [ wanxiang_reverse ] #反查滤镜数据库,万象都合并为一个了
|
||||
|
||||
# 处理符合特定规则的输入码,如网址、反查
|
||||
recognizer:
|
||||
import_preset: default # 从 default.yaml 继承通用的
|
||||
patterns: # 再增加方案专有的:
|
||||
punct: "^/([0-9]|10|[A-Za-z]+)$" # 响应 symbols.yaml 的 symbols
|
||||
wanxiang_reverse: "^`[A-Za-z]*$" # 响应部件拆字与笔画的反查,与 wanxiang_reverse/prefix 匹配
|
||||
#add_user_dict: "^ac[A-Za-z/`']*$" #引导式造词
|
||||
unicode: "^U[a-f0-9]+" # U 作为触发前缀,响应 lua_translator@unicode,输出 Unicode 字符
|
||||
number: "^R[0-9]+[.]?[0-9]*" # R 作为触发前缀, 响应 lua_translator@number_translator,数字金额大写
|
||||
lunar: "^N[0-9]{1,8}" # N 作为触发前缀,响应 lua_translator@shijian,公历转农历,输入 N20250515 得到「二〇二五年五月十五」
|
||||
calculator: "^V.*$" # V 作为触发前缀,计算器功能引导
|
||||
|
||||
punctuator:
|
||||
digit_separators: ",." #数字分隔符,系统逻辑是在中文状态下输入数字后继续输入句号按下两次即输入半角状态
|
||||
__include: wanxiang_symbols:/symbol_table # 从 wanxiang_symbols.yaml 导入所有符号配置
|
||||
__patch: t9_sym
|
||||
t9_sym:
|
||||
half_shape/+:
|
||||
"1": [1, "@", ".", "/", ":", "_", "-", "#"]
|
||||
"@": [1, "@", !, :, 、, ……, ~]
|
||||
"#": [0, "#", "$", "%", "^", "&", "*", "(", ")"]
|
||||
# 从 default 继承快捷键
|
||||
key_binder:
|
||||
import_preset: default # 从 default.yaml 继承通用的
|
||||
sequence: # Lua 配置:手动排序的快捷键 super_sequence.lua,不要用方向键,各种冲突,一定要避免冲突
|
||||
up: "Control+j" # 上移
|
||||
down: "Control+k" # 下移
|
||||
reset: "Control+l" # 重置
|
||||
pin: "Control+p" # 置顶
|
||||
# Lua 配置: shijian.lua 的引导符,涉及:日期、时间、节日、节气、生日、问候模板等功能
|
||||
shijian_keys: ["/", "o"]
|
||||
# Lua 配置: 超级tips上屏按键
|
||||
tips_key: "period" #修改时候去default找
|
||||
# Lua 配置: 以词定字(上屏当前词句的第一个或最后一个字),和中括号翻页有冲突
|
||||
select_first_character: "bracketleft" # 左中括号 [
|
||||
select_last_character: "bracketright" # 右中括号 ]
|
||||
bindings: # 也可以再增加方案专有的
|
||||
- { when: has_menu, accept: 1, send: apostrophe }
|
||||
|
||||
#当tab第一个字补码正确后,可以使用Ctrl+tab进行上屏并依次补码
|
||||
- { when: composing, accept: "Control+Tab", send_sequence: '{Home}{Shift+Right}{1}{Shift+Right}' }
|
||||
- { match: "^.*`$", accept: "`", send_sequence: '{BackSpace}{Home}{`}{`}{End}' }
|
||||
|
||||
# 拼写设定
|
||||
speller:
|
||||
# table_translator翻译器,支持自动上屏。例如 “zmhu”可以自动上屏“怎么回事”
|
||||
# auto_select: true
|
||||
# auto_select_pattern: ^[a-z]+/|^[a-df-zA-DF-Z]\w{3}|^e\w{4}
|
||||
# 如果不想让什么标点直接上屏,可以加在 alphabet,或者编辑标点符号为两个及以上的映射,alphabet就是将字符纳入输入编码的范畴
|
||||
alphabet: zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA987654321`/\
|
||||
initials: zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA987654321
|
||||
delimiter: " '" # 系统配置,第一位<空格>是拼音之间的分隔符;第二位<'>表示可以手动输入单引号来分割拼音。
|
||||
visual_delimiter: " " # super_preedit.lua配置:是否让分隔符号跟着一起转换,例如nǐ'hǎo 在实际使用中表现出视觉拥挤,我们可以让delimiter平时是'转换为拼音的时候使用空格nǐ hǎo,更符合实际。
|
||||
tone_isolate: true # super_preedit.lua配置:是否将数字声调从转换后拼音中隔离出来(true=隔离, false 直接参与转换)例如:nǐ3
|
||||
algebra:
|
||||
- xlit/āáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜüńňǹḿm̀/aaaaooooeeeeiiiiuuuuvvvvvnnnmmm/
|
||||
- xform/^(.*);.*$/$1/
|
||||
- derive/^ng$/eng/
|
||||
- xform/^n$/en/
|
||||
- xform/^m$/me/
|
||||
- abbrev/^([a-z]).+$/$1/
|
||||
- abbrev/^([zcs]h).+$/$1/
|
||||
- derive/^([nl])ve$/$1ue/
|
||||
- derive/^([jqxy])u/$1v/
|
||||
- derive/un$/uen/
|
||||
- derive/ui$/uei/
|
||||
- derive/iu$/iou/
|
||||
- derive/([aeiou])ng$/$1gn/
|
||||
- derive/([dtngkhrzcs])o(u|ng)$/$1o/
|
||||
- derive/ong$/on/
|
||||
- derive/ao$/oa/
|
||||
- derive/([iu])a(o|ng?)$/a$1$2/
|
||||
- derive/[abc]/2/
|
||||
- derive/[def]/3/
|
||||
- derive/[hgi]/4/
|
||||
- derive/[jkl]/5/
|
||||
- derive/[omn]/6/
|
||||
- derive/[pqrs]/7/
|
||||
- derive/[tuv]/8/
|
||||
- derive/[wxyz]/9/
|
||||
|
||||
grammar:
|
||||
language: wanxiang-lts-zh-hans
|
||||
collocation_max_length: 8 #命中的最长词组
|
||||
collocation_min_length: 2 #命中的最短词组,搭配词频健全的词库时候应当最小值设为3避开2字高频词
|
||||
collocation_penalty: -6 #默认-12 对常见搭配词组施加的惩罚值。较高的负值会降低这些搭配被选中的概率,防止过于频繁地出现某些固定搭配。
|
||||
non_collocation_penalty: -17 #默认-12 对非搭配词组施加的惩罚值。较高的负值会降低非搭配词组被选中的概率,避免不合逻辑或不常见的词组组合。
|
||||
weak_collocation_penalty: -24 #默认-24 对弱搭配词组施加的惩罚值。保持默认值通常是为了有效过滤掉不太常见但仍然合理的词组组合。
|
||||
rear_penalty: -18 #默认-18 对词组中后续词语的位置施加的惩罚值。较高的负值会降低某些词语在句子后部出现的概率,防止句子结构不自然。
|
||||
269
weasel.yaml
Normal file
269
weasel.yaml
Normal file
@@ -0,0 +1,269 @@
|
||||
# Weasel settings
|
||||
# encoding: utf-8
|
||||
|
||||
config_version: "LTS"
|
||||
|
||||
# [app_options]
|
||||
# 针对特定应用的设置
|
||||
app_options:
|
||||
cmd.exe:
|
||||
ascii_mode: true
|
||||
ascii_punct: true
|
||||
idea64.exe:
|
||||
ascii_mode: false
|
||||
ascii_punct: true
|
||||
Code.exe:
|
||||
ascii_mode: false
|
||||
ascii_punct: true
|
||||
Bandizip.exe:
|
||||
ascii_mode: true # 英文模式
|
||||
7zFM.exe:
|
||||
ascii_mode: true # 英文模式
|
||||
firefox.exe:
|
||||
inline_preedit: true # 行内显示预编辑区:规避 <https://github.com/rime/weasel/issues/946>
|
||||
# cmd.exe:
|
||||
# ascii_mode: true # 英文模式
|
||||
# conhost.exe:
|
||||
# ascii_mode: true
|
||||
# windowsterminal.exe:
|
||||
# ascii_mode: true
|
||||
# wt.exe:
|
||||
# ascii_mode: true
|
||||
# pwsh.exe:
|
||||
# ascii_mode: true
|
||||
# powershell.exe:
|
||||
# ascii_mode: true
|
||||
# mintty.exe:
|
||||
# ascii_mode: true
|
||||
# nvim-qt.exe:
|
||||
# ascii_mode: true
|
||||
# vim_mode: true # vim 模式, Esc <C-c> <C-[> 切换到 ascii 状态
|
||||
# [End of <app_options>]
|
||||
|
||||
# [global settings]
|
||||
show_notifications: true # 是否显示状态变化的通知:true;false;option_list(方案内的开头 option)
|
||||
show_notifications_time: 1200 # 通知显示的时间,单位 ms
|
||||
global_ascii: false # 切换为 ascii 模式时,是否影响所有窗口:true;false
|
||||
# [End of <global settings>]
|
||||
|
||||
# [style]
|
||||
# 字体;候选项、候选窗口的行为、布局及样式
|
||||
style:
|
||||
color_scheme: win11_light # 默认配色方案
|
||||
|
||||
# 全局字体
|
||||
# 格式:字体1:起始码位:结束码位:字重:字形,字体2……,字体会依次 fallback
|
||||
# 详细设定请参考 <https://github.com/rime/weasel/wiki/字體設定>
|
||||
font_face: "Segoe UI Emoji, Microsoft YaHei, SF Pro, Noto Color Emoji"
|
||||
label_font_face: "Microsoft YaHei" # 标签字体
|
||||
comment_font_face: "Microsoft YaHei" # 注释字体
|
||||
font_point: 12 # 全局字体字号
|
||||
label_font_point: 11 # 标签字体字号,不设定 fallback 到 font_point
|
||||
comment_font_point: 11 # 注释字体字号,不设定 fallback 到 font_point
|
||||
|
||||
inline_preedit: true # 行内显示预编辑区:true;false
|
||||
preedit_type: composition # 预编辑区内容:composition(编码); preview(选中的候选);preview_all(全部候选)
|
||||
|
||||
fullscreen: false # 候选窗口全屏显示:true;false
|
||||
horizontal: true # 候选项横排:true;false
|
||||
vertical_text: false # 竖排文本:true;false
|
||||
# text_orientation: horizontal # 文本排列方向,效果和 `vertical_text` 相同:horizontal;vertical
|
||||
vertical_text_left_to_right: false # 竖排方向是否从左到右:true;false
|
||||
vertical_text_with_wrap: false # 文本竖排模式下,自动换行:true;false
|
||||
vertical_auto_reverse: false # 文本竖排模式下,候选窗口位于光标上方时倒序排列:true;false
|
||||
|
||||
label_format: "%s." # 标签字符:例如 %s. 效果为 1. 2. 3. ....
|
||||
mark_text: "" # 标记字符,显示在选中的候选标签前,需要在配色方案中指定颜色;如该项为空字符串 "" 而配色方案中 hilited_mark_color 非透明色,则显示 Windows 11 输入法风格标记
|
||||
ascii_tip_follow_cursor: false # 切换 ASCII 模式时,提示跟随鼠标,而非输入光标
|
||||
enhanced_position: true # 无法定位候选框时,在窗口左上角显示候选框:true;false
|
||||
display_tray_icon: false # 托盘显示独立于语言栏的额外图标:true;false
|
||||
antialias_mode: default # 次像素反锯齿设定:default;force_dword;cleartype;grayscale;aliased
|
||||
candidate_abbreviate_length: 30 # 候选项略写,超过此数字则用省略号代替。设置为 0 则不启用此功能
|
||||
# mouse_hover_ms: 0 # ! 已弃用。鼠标悬停选词响应时间(ms),设置为 0 时禁用该功能
|
||||
hover_type: semi_hilite # 鼠标在候选窗口悬停时:none(无动作);hilite(选中鼠标下的候选);semi_hilite(高亮鼠标下的候选)
|
||||
|
||||
paging_on_scroll: true # 在候选窗口上滑动滚轮的行为:true(翻页);false (选中下一个候选)
|
||||
click_to_capture: false # 鼠标点击候选项,创建截图:true;false
|
||||
|
||||
layout:
|
||||
align_type: center # 标签、候选文字、注解文字之间的相对对齐方式
|
||||
max_height: 2800 # 候选框最大高度、宽度。超过设定值会尝试自动折叠,设置为 0 不启用此功能
|
||||
max_width: 1400 # 2800
|
||||
min_height: 0 # 候选框最小高度、宽度
|
||||
min_width: 50 #80
|
||||
#type: horizontal # 布局类型;功能近似 style 下的窗口控制选项 horizontal; vertical
|
||||
border_width: 1 # 边框宽度,别名 `border`
|
||||
border: 1
|
||||
margin_x: 8 # 主体元素和候选框的左右、上下边距,为负值时,不显示候选框
|
||||
margin_y: 8
|
||||
spacing: 18 # inline_preedit 为 false 时,编码区域和候选区域的间距
|
||||
candidate_spacing: 15 # 候选项之间的间距
|
||||
hilite_spacing: 6 # 候选项和相应标签的间距,候选项与注解文字之间的距离
|
||||
hilite_padding: 6 # 高亮区域和内部文字的间距,影响高亮区域大小
|
||||
hilite_padding_y: 5 # 高亮区域和内部文字的左右、上下间距,如无特殊指定则依 hilite_padding 设置
|
||||
hilite_padding_x: 5
|
||||
shadow_offset_x: "-8" # 阴影绘制的偏离距离
|
||||
shadow_offset_y: "8"
|
||||
shadow_radius: 8 # 阴影区域半径,为 0 不显示阴影;需要同时在配色方案中指定非透明的阴影颜色
|
||||
corner_radius: 8 # 候选窗口圆角半径
|
||||
round_corner: 8 # 候选背景色块圆角半径,别名 `hilited_corner_radius`
|
||||
preset_color_schemes:
|
||||
jianchun:
|
||||
name: 简纯
|
||||
author: amzxyz
|
||||
back_color: '0xf2f2f2'
|
||||
border_color: '0xCE7539'
|
||||
text_color: '0x3c647e'
|
||||
hilited_text_color: '0x3c647e'
|
||||
hilited_back_color: '0x797954'
|
||||
hilited_comment_text_color: '0xffffff'
|
||||
hilited_candidate_text_color: '0xffffff'
|
||||
hilited_candidate_back_color: '0xCE7539'
|
||||
hilited_label_color: '0xdedede'
|
||||
candidate_text_color: '0x000000'
|
||||
comment_text_color: '0x000000'
|
||||
label_color: '0x91897e'
|
||||
|
||||
win11_light:
|
||||
name: "Win11浅色 / Win11light"
|
||||
text_color: 0x191919
|
||||
label_color: 0x191919
|
||||
hilited_label_color: 0x191919
|
||||
back_color: 0xf9f9f9
|
||||
border_color: 0x009e5a00
|
||||
hilited_mark_color: 0xc06700
|
||||
hilited_candidate_back_color: 0xf0f0f0
|
||||
shadow_color: 0x20000000
|
||||
|
||||
win11_dark:
|
||||
name: "Win11暗色 / Win11Dark"
|
||||
text_color: 0xf9f9f9
|
||||
label_color: 0xf9f9f9
|
||||
back_color: 0x2C2C2C
|
||||
hilited_label_color: 0xf9f9f9
|
||||
border_color: 0x002C2C2C
|
||||
hilited_mark_color: 0xFFC24C
|
||||
hilited_candidate_back_color: 0x383838
|
||||
shadow_color: 0x20000000
|
||||
|
||||
mac_light:
|
||||
name: "Mac 白"
|
||||
text_color: 0x000000
|
||||
back_color: 0xffffff
|
||||
border_color: 0xe9e9e9
|
||||
label_color: 0x999999
|
||||
hilited_text_color: 0x000000
|
||||
hilited_back_color: 0xffffff
|
||||
candidate_text_color: 0x000000
|
||||
comment_text_color: 0x999999
|
||||
hilited_candidate_text_color: 0xffffff
|
||||
hilited_comment_text_color: 0xdddddd
|
||||
hilited_candidate_back_color: 16740656
|
||||
hilited_label_color: 0xffffff
|
||||
|
||||
wechat:
|
||||
name: "微信/Wechat"
|
||||
text_color: 0x424242
|
||||
label_color: 0x999999
|
||||
back_color: 0xFFFFFF
|
||||
border_color: 0xFFFFFF
|
||||
comment_text_color: 0x999999
|
||||
candidate_text_color: 0x3c3c3c
|
||||
hilited_comment_text_color: 0xFFFFFF
|
||||
hilited_back_color: 0x79af22
|
||||
hilited_text_color: 0xFFFFFF
|
||||
hilited_label_color: 0xFFFFFF
|
||||
hilited_candidate_back_color: 0x79af22
|
||||
shadow_color: 0x20000000
|
||||
|
||||
Lumk_light:
|
||||
name: "鹿鸣/Lumk light"
|
||||
author: "Lumk X <x@xx.cc>"
|
||||
back_color: 0xF9F9F9
|
||||
border_color: 0xE2E7F5
|
||||
candidate_text_color: 0x121212
|
||||
comment_text_color: 0x8E8E8E
|
||||
hilited_candidate_back_color: 0xECE4FC
|
||||
hilited_candidate_label_color: 0xB18FF4
|
||||
hilited_candidate_text_color: 0x7A40EC
|
||||
hilited_label_color: 0xA483EC
|
||||
hilited_mark_color: 0x7A40EC
|
||||
label_color: 0x888785
|
||||
text_color: 0x8100EB
|
||||
shadow_color: 0x20000000
|
||||
|
||||
amber-7:
|
||||
name: 淡白/weasel
|
||||
author: 五笔小筑 <wubixiaozhu@126.com>
|
||||
# 背景设置
|
||||
back_color: 0xffffff # 窗口背景
|
||||
border_color: 0xE99321 # 窗口边框
|
||||
shadow_color: 0x00000000 # 窗口阴影
|
||||
# 内选区域
|
||||
text_color: 0xE99321 # 文字
|
||||
hilited_text_color: 0x2238dc # 编码
|
||||
hilited_back_color: 0xffffff # 背景
|
||||
hilited_shadow_color: 0x00000000 # 阴影
|
||||
# 以下两项在 inline_preedit: false 时生效
|
||||
nextpage_color: 0x0000FF # 翻页箭头颜色:下一页;不设置则不显示箭头
|
||||
prevpage_color: 0x0000FF # 翻页箭头颜色:上一页;不设置则不显示箭头
|
||||
# 激活候选项
|
||||
hilited_mark_color: 0x00000000 # 激活标签
|
||||
hilited_label_color: 0x2021FF #序号文字
|
||||
hilited_candidate_text_color: 0x2021FF #候选文字
|
||||
hilited_comment_text_color: 0x000000 #提示文字
|
||||
hilited_candidate_back_color: 0xECF1FC #激活背景
|
||||
hilited_candidate_border_color: 0xCFDCFD #激活边框
|
||||
hilited_candidate_shadow_color: 0x00000000 #激活阴影
|
||||
# 其它候选项
|
||||
label_color: 0xE99321 #序号文字
|
||||
candidate_text_color: 0xE99321 #候选文字
|
||||
comment_text_color: 0x000000 #提示文字
|
||||
candidate_back_color: 0xffffff #候选背景
|
||||
candidate_border_color: 0xffffff #候选边框
|
||||
candidate_shadow_color: 0x00000000 #候选阴影
|
||||
|
||||
win10gray:
|
||||
name: win10灰/win10gray
|
||||
author: 五笔小筑 <wubixiaozhu@126.com>
|
||||
back_color: 0xfff4f4f4
|
||||
shadow_color: 0xf7606060
|
||||
border_color: 0xff305c3c
|
||||
text_color: 0xff000000
|
||||
hilited_text_color: 0xff000000
|
||||
hilited_back_color: 0x4ff4f4f4
|
||||
hilited_shadow_color: 0x00000000
|
||||
hilited_mark_color: 0xffd77800
|
||||
hilited_label_color: 0xff555555
|
||||
hilited_candidate_text_color: 0xff000000
|
||||
hilited_comment_text_color: 0xff555555
|
||||
hilited_candidate_back_color: 0x4fcccccc
|
||||
hilited_candidate_border_color: 0x00000000
|
||||
hilited_candidate_shadow_color: 0x00000000
|
||||
label_color: 0xff888888
|
||||
candidate_text_color: 0xff222222
|
||||
comment_text_color: 0xff888888
|
||||
candidate_back_color: 0x00000000
|
||||
candidate_border_color: 0x00000000
|
||||
candidate_shadow_color: 0x00000000
|
||||
|
||||
mint_light_blue:
|
||||
name: "蓝水鸭/Mint Light Blue"
|
||||
author: Mintimate <"Mintimate's Blog">
|
||||
text_color: 0x6495ed
|
||||
back_color: 0xefefef
|
||||
label_color: 0xcac9c8
|
||||
border_color: 0xefefef
|
||||
shadow_color: 0xb4000000
|
||||
comment_text_color: 0xcac9c8
|
||||
candidate_text_color: 0x424242
|
||||
hilited_text_color: 0xed9564
|
||||
hilited_back_color: 0xefefef
|
||||
hilited_candidate_back_color: 0xed9564
|
||||
hilited_candidate_text_color: 0xefefef
|
||||
hilited_candidate_label_color: 0xcac9c8
|
||||
hilited_label_color: 0xcac9c8
|
||||
hilited_comment_text_color: 0xefefef
|
||||
nextpage_color: 0x0000FF
|
||||
prevpage_color: 0x0000FF
|
||||
|
||||
4056
简纯+.trime.yaml
Normal file
4056
简纯+.trime.yaml
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user