Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

💥 Kensaku v3 #9

Merged
merged 3 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,11 @@ const pattern = await denops.dispatch("kensaku", "query", "kensaku");

### Vim script からの利用

`kensaku#query()` を以下のように呼び出します。戻り値は JavaScript
の正規表現なので、利用する場合は `\v` を前置する必要があります。
`kensaku#query()` を以下のように呼び出します。

```vim
function! Search(value) abort
let @/ = '\v' .. a:value
let @/ = a:value
normal! n
endfunction

Expand All @@ -84,7 +83,7 @@ call Search(kensaku#query('kensaku'))

```vim
function! Search(value) abort
let @/ = '\v' .. a:value
let @/ = a:value
normal! n
endfunction

Expand All @@ -94,6 +93,15 @@ call kensaku#query_async(
\)
```

## v2 との違い

Kensaku [v2](https://github.com/lambdalisue/kensaku.vim/tree/v2) までは
`kensaku#query()` などで返す正規表現は JavaScript のものだったため `\v`
を前置することで Very magic を指定する必要がありました。 Kensaku v3 からは
`kensaku#query()` は Vim script の正規表現を返すように変更されたので `\v`
の前置が不要になりました。 なおプラグイン作者などが利用する `denops.dispatch()`
経由での呼び出しは依然として JavaScript の正規表現を返します。

## 参考情報

- [Migemo: ローマ字のまま日本語をインクリメンタル検索](http://0xcc.net/migemo/)
Expand Down
12 changes: 9 additions & 3 deletions autoload/kensaku.vim
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@ function! kensaku#query(value) abort
if denops#plugin#wait('kensaku') isnot# 0
return ''
endif
return denops#request('kensaku', 'query', [a:value])
let l:option = extend({
\ 'rxop': g:kensaku#rxop#vim,
\}, a:0 ? a:1 : {},
\)
return denops#request('kensaku', 'query', [a:value, l:option])
endfunction

function! kensaku#query_async(value, success, ...) abort
let l:Failure = a:0 ? a:1 : funcref('s:failure')
let l:option = a:0 ? a:1 : {}
let l:option.rxop = get(l:option, 'rxop', g:kensaku#rxop#vim)
let l:Failure = get(l:option, 'failure', funcref('s:failure'))
return denops#request_async(
\ 'kensaku',
\ 'query',
\ [a:value],
\ [a:value, l:option],
\ { v -> a:success(v) },
\ { e -> l:Failure(e) },
\)
Expand Down
2 changes: 2 additions & 0 deletions autoload/kensaku/rxop.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let g:kensaku#rxop#vim = ['\|', '\%(', '\)', '[', ']', '']
let g:kensaku#rxop#javascript = ['|', '(?:', ')', '[', ']', '']
7 changes: 4 additions & 3 deletions denops/kensaku/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Denops } from "https://deno.land/x/[email protected]/mod.ts";
import * as unknownutil from "https://deno.land/x/[email protected]/mod.ts";
import { query, setRomanTable } from "./migemo.ts";
import { assertQueryOption, query, setRomanTable } from "./migemo.ts";

export function main(denops: Denops): void {
denops.dispatcher = {
Expand All @@ -9,9 +9,10 @@ export function main(denops: Denops): void {
*
* 必要になる辞書などは自動的にダウンロード・キャッシュします。
*/
query(value: unknown) {
query(value: unknown, option: unknown = {}) {
unknownutil.assertString(value);
return query(denops, value);
assertQueryOption(option);
return query(denops, value, option);
},
setRomanTable(romanTable: unknown) {
unknownutil.assertArray<[string, string, number?]>(romanTable);
Expand Down
32 changes: 27 additions & 5 deletions denops/kensaku/migemo.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { Denops } from "https://deno.land/x/[email protected]/mod.ts";
import * as path from "https://deno.land/[email protected]/path/mod.ts";
import * as fs from "https://deno.land/[email protected]/fs/mod.ts";
import * as unknownutil from "https://deno.land/x/[email protected]/mod.ts";
import * as u from "https://deno.land/x/[email protected]/mod.ts";
import * as batch from "https://deno.land/x/[email protected]/batch/mod.ts";
import * as vars from "https://deno.land/x/[email protected]/variable/mod.ts";
import * as jsmigemo from "https://cdn.jsdelivr.net/npm/[email protected].4/dist/jsmigemo.min.mjs";
import * as jsmigemo from "https://cdn.jsdelivr.net/npm/[email protected].6/dist/jsmigemo.min.mjs";

let migemo: jsmigemo.Migemo | undefined;

Expand All @@ -16,8 +16,8 @@ async function init(denops: Denops): Promise<jsmigemo.Migemo> {
await vars.g.get(denops, "kensaku_dictionary_cache");
},
);
unknownutil.assertString(dictionaryUrl);
unknownutil.assertString(dictionaryCache);
u.assertString(dictionaryUrl);
u.assertString(dictionaryCache);

const data = await readOrFetch(dictionaryUrl, dictionaryCache);
const dict = new jsmigemo.CompactDictionary(data.buffer);
Expand Down Expand Up @@ -49,8 +49,30 @@ async function getMigemo(denops: Denops): Promise<jsmigemo.Migemo> {
return migemo;
}

export async function query(denops: Denops, value: string): Promise<string> {
type Rxop = [string, string, string, string, string, string];

type QueryOption = {
rxop?: Rxop;
};

export function assertQueryOption(x: unknown): asserts x is QueryOption {
if (
!(u.isObject(x) &&
(x.rxop == null || u.isArray(x.rxop, u.isString) && x.rxop.length === 6))
) {
throw new Error("Not a QueryOption");
}
}

const rxopJavaScript = ["|", "(?:", ")", "[", "]", ""];

export async function query(
denops: Denops,
value: string,
option: QueryOption = {},
): Promise<string> {
const migemo = await getMigemo(denops);
migemo.setRxop(option.rxop || rxopJavaScript);
return migemo.query(value);
}

Expand Down
70 changes: 59 additions & 11 deletions doc/kensaku.jax
Original file line number Diff line number Diff line change
Expand Up @@ -54,36 +54,84 @@ VARIABLES *kensaku-variables*

Default: `~/.cache/kensaku.vim/migemo-compact-dict`

*g:kensaku#rxop#vim*
*g:kensaku#rxop#javascript*
正規表現で使う記号のプリセットです。 |kensaku#query()| で使用します。
>
call kensaku#query("kensaku", {
\ 'rxop': g:kensaku#rxop#vim,
\})
call kensaku#query("kensaku", {
\ 'rxop': g:kensaku#rxop#javascript,
\})
<
*g:kensaku_disable_v3_migration_warning*
Kensaku v3 で適用された破壊的変更に関する警告メッセージを非表示にしま
す。なお、このメッセージ自体は v3.0.1 以降で削除される予定です。

-----------------------------------------------------------------------------
FUNCTIONS *kensaku-functions*

*kensaku#query()*
kensaku#query({value})
kensaku#query({value}[, {option}])
{value} をローマ字として解釈し、検索するための正規表現を返します。
結果を Vim スクリプトにて利用する場合は "\v" を前置して "very magic"
として利用してください (|/magic| 参照)。
>
function! Search(value) abort
let @/ = '\v' .. a:value
let @/ = a:value
normal! n
endfunction

call Search(kensaku#query('kensaku'))
<
{option} には以下のパラメータがあります。

"rxop" 正規表現に利用する記号文字のリストです。
"[or, startGroup, endGroup, startClass, endClass, newline]" で
表され、それぞれ以下の意味を持ちます。
or 選択子 (alternation operator)。|/bar|
startGroup グループ化の開始。|/\(|
endGroup グループ化の終了。|/\)|
startClass 文字クラスの開始。|/\[]|
endClass 文字クラスの終了。|/\[]|
newline 行末。|/\_s|
デフォルト: |g:kensaku#rxop#vim|
>
" :grep で kensaku.vim を使う
command! -nargs=1 KensakuGrep call KensakuGrep(<q-args>)

function! KensakuGrep(input) abort
if !executable('rg')
return
endif
let grepprg = &grepprg
set grepprg=rg\ -e\ $*\ --vimgrep
" :execute は '|' でコマンドを区切るのでエスケープ
execute 'grep' kensaku#query(a:input, {
\ 'rxop': ['\|', '(', ')', '[', ']', ''],
\})
let &grepprg = grepprg
endfunction
<

*kensaku#query_async()*
kensaku#query_async({value}, {success}[, {failure}])
kensaku#query_async({value}, {success}[, {option}])
|kensaku#query()| の非同期バージョンで、結果を {success} コールバックに
渡します。エラー時は {failure} コールバックが呼ばれます。
渡します。

{option} には以下のパラメータがあります。

"rxop" |kensaku#query()| と同じです。
"failure" エラー時に呼ばれるコールバック関数です。
>
function! Search(value) abort
let @/ = '\v' .. a:value
let @/ = a:value
normal! n
endfunction

call kensaku#query_async(
\ 'kensaku',
\ function('Search'),
\)
call kensaku#query_async('kensaku', function('Search'), {
\ 'failure': { e -> ...},
\ 'rxop': ...,
\})
<

*kensaku#set_roman_table()*
Expand Down
11 changes: 11 additions & 0 deletions plugin/kensaku.vim
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,14 @@ call s:define(
\ 'kensaku_dictionary_cache',
\ expand('~/.cache/kensaku.vim/migemo-compact-dict')
\)

" XXX
" Remove this warning message after v3.0.0
if !exists('g:kensaku_disable_v3_migration_warning')
echohl WarningMsg
echomsg '[kensaku] BREAKING CHANGES:'
echomsg '[kensaku] Kensaku v3 returns Vim script regex from `kensaku#query()` function so users no longer need to prepend `\v` (very magic).'
echomsg '[kensaku] Additionally, Optional arguments of `kensaku#query_async()` has slightly changed. See help for more detail.'
echomsg '[kensaku] Disable this message by `let g:kensaku_disable_v3_migration_warning = 1` or wait until the next release.'
echohl None
endif