Skip to content
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
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ require("skkelua").config({
enabled = true,
insertOnSelect = true, -- 候補にフォーカスした時点で本文へ挿入する
deferOkuri = true, -- 送り仮名確定でも自動変換せず、第一候補を自動選択する
abbrevWithSpace = false, -- abbrev モードの候補から半角スペースを外す (既定は true)
},
pureSpace = true, -- Space を変換に使わず「変換中なら確定 + 空白」にする
})
Expand All @@ -133,7 +134,10 @@ require("skkelua").config({
漢字を含む単語も pum で変換しながら登録できます。辞書に無い読みでも
この項目だけのメニューが開くので、変換キーを使わずに新しい単語を登録できます
- abbrev モード (`/`) の入力中は、「[辞書登録]」の下に入力したアルファベットの
前に半角スペースを足したものが並びます (▽overall なら ` overall`)
前に半角スペースを足したものが並びます (▽overall なら ` overall`)。
`completion.abbrevWithSpace = false` にすると半角スペースを足さない
入力そのもの (▽overall なら `overall`) が並びます。
どちらも確定ではユーザー辞書に登録されません
- skkelua の有効・無効に連動して補完も付いたり外れたりします

## skkeleton との関係
Expand Down
12 changes: 10 additions & 2 deletions doc/skkelua.txt
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,11 @@ in-process の LSP サーバー (|vim.lsp.start()| の cmd 関数) として実
▽おく*る のまま補完メニューの第一候補を自動選択・挿入します。
CTRL-P で選択を外すと変換前のひらがなに戻ります。
insertOnSelect と併用してください
- abbrevWithSpace (true): abbrev モード (/) の入力そのままの候補 (raw 候補)
の前に半角スペースを足すかどうか。true なら ▽overall で " overall"、
false なら "overall" が [辞書登録] の下に並びます。
他の SKK では abbrev モードにこの候補が出ないため、それに合わせる場合は
false にします

変換の開始・確定を補完メニューだけで行う場合は、Space を変換に使わない
pureSpace (|skkelua-options|) も合わせて有効にすると快適です。
Expand Down Expand Up @@ -323,8 +328,11 @@ pureSpace (|skkelua-options|) も合わせて有効にすると快適です。
(送りあり入力では送り仮名が確定するまで表示されません)
- abbrev モード (/) の入力中は、[辞書登録] の下に入力したアルファベットの
前に半角スペースを足したものが並びます (▽overall なら " overall")。
この候補の確定ではユーザー辞書に登録されません。入力そのものは
<C-y> の無変換確定で入ります
abbrevWithSpace (上記) を false にすると半角スペースを足さない
入力そのもの (▽overall なら "overall") が並びます。
いずれの候補の確定でもユーザー辞書には登録されません。
入力そのものは abbrevWithSpace が true の場合でも <C-y> の
無変換確定で入力できます
- 登録プロンプトは insert モードのバッファなので、中でも skkelua の
かな入力と補完メニューがそのまま使えます (プロンプト内の補完に
[辞書登録] は出ません)。<CR> で登録、<Esc> / CTRL-C でキャンセル。
Expand Down
3 changes: 3 additions & 0 deletions lua/skkelua/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ M.default_indicator = default_indicator
---@field enabled boolean 変換候補を builtin LSP 補完として表示するかどうか
---@field insertOnSelect boolean 候補の選択 (フォーカス) と同時に本文へ挿入するかどうか
---@field deferOkuri boolean 送り仮名確定時に自動変換せず、補完メニューでの選択に委ねるかどうか
---@field abbrevWithSpace boolean abbrev モードの raw 候補 (入力そのもの) の前に半角スペースを足すかどうか
local default_completion = {
enabled = false,
insertOnSelect = false,
deferOkuri = false,
abbrevWithSpace = true,
}

M.default_completion = default_completion
Expand Down Expand Up @@ -169,6 +171,7 @@ local validators = {
ensure_type(merged.enabled, "boolean", "completion.enabled")
ensure_type(merged.insertOnSelect, "boolean", "completion.insertOnSelect")
ensure_type(merged.deferOkuri, "boolean", "completion.deferOkuri")
ensure_type(merged.abbrevWithSpace, "boolean", "completion.abbrevWithSpace")
return merged
end,
completionRankFile = ensure_string("completionRankFile"),
Expand Down
2 changes: 1 addition & 1 deletion lua/skkelua/function/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ function M.purge_candidate(context, key)
elseif state.type == "input" then
if state.mode == "direct" then
local sel_word, data = require("skkelua.lsp").selected_word()
-- raw 候補 (abbrev の半角スペース + 入力) は辞書エントリではないので対象外
-- raw 候補 (abbrev の入力そのまま) は辞書エントリではないので対象外
if data and not data.raw then
type_, word, candidate = data.type, data.midasi, data.word
-- pum が直接書き換えたバッファのテキストを表示中として認識させ、
Expand Down
18 changes: 10 additions & 8 deletions lua/skkelua/lsp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ end
---@field type skkelua.HenkanType
---@field affix? skkelua.AffixType
---@field rank? number 並び順の決定に使うランク (大きいほど上)
---@field raw? boolean 辞書由来でない候補 (abbrev の半角スペース + 入力。登録・purge の対象外)
---@field raw? boolean 辞書由来でない候補 (abbrev の入力そのまま。completion.abbrevWithSpace で半角スペースを前置できる。登録・purge の対象外)

--- 送りなし変換入力 (▽かんじ) の候補: 見出しの前方一致検索
--- (@ddc-sources/skkeleton の gather に相当)。
--- ユーザー辞書で確定済みの候補 (ランク持ち) を確定が新しい順に先頭へ置き、
--- 残りは見出しの辞書順で並べる。
--- abbrev モードでは入力の半角スペース前置形を末尾に足す
--- abbrev モードでは入力の raw 候補を末尾に足す
--- (補完リストでは [辞書登録] の後ろに並ぶ)
---@return skkelua.LspCandidate[]
local function okurinasi_candidates()
Expand Down Expand Up @@ -111,11 +111,13 @@ local function okurinasi_candidates()
end)
local context = require("skkelua.store").get_context()
if context.mode == "abbrev" then
-- 入力したアルファベットの前に半角スペースを足したもの (英単語を
-- 和文の中に空けて入れる用)。入力そのものは <C-y> の無変換確定で
-- 入るので候補には並べない
-- 入力そのものの raw 候補。completion.abbrevWithSpace (デフォルト true) だと
-- 前に半角スペースを足す (英単語を和文の中に空けて入れる用)。false なら
-- 入力そのまま (▽overall なら "overall")
local feed = context.state.henkanFeed
result[#result + 1] = { word = " " .. feed, midasi = feed, okuri = "", type = "okurinasi", raw = true }
local with_space = require("skkelua.config").config.completion.abbrevWithSpace
local word = with_space and (" " .. feed) or feed
result[#result + 1] = { word = word, midasi = feed, okuri = "", type = "okurinasi", raw = true }
end
return result
end
Expand Down Expand Up @@ -327,7 +329,7 @@ local function make_completion_list()
set_completeopt(buf, auto_select)

local items = {}
-- abbrev の raw 候補 (半角スペース + 入力) は辞書候補ではないので、
-- abbrev の raw 候補 (入力そのもの) は辞書候補ではないので、
-- [辞書登録] より後ろに回す
local trailing = {}
local seen = {}
Expand Down Expand Up @@ -516,7 +518,7 @@ function M._on_complete_done(reason, completed_item)
end)
return
end
-- abbrev の raw 候補 (半角スペース + 入力) は辞書へ登録しない
-- abbrev の raw 候補 (入力そのもの) は辞書へ登録しない
if data.raw then
return
end
Expand Down
8 changes: 8 additions & 0 deletions tests/config_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ t.test("set_config validation", function()
skkelua.config({ useGoogleJapaneseInput = true })
end)

-- completion の部分指定はデフォルトへマージされる
skkelua.config({ completion = { abbrevWithSpace = false } })
t.assert_equals(false, config.completion.abbrevWithSpace)
t.assert_equals(false, config.completion.enabled)
t.assert_error(function()
skkelua.config({ completion = { abbrevWithSpace = "no" } })
end)

-- userDictionary の ~ 展開
skkelua.config({ userDictionary = "~/.test-skkeleton" })
t.assert_true(not vim.startswith(config.userDictionary, "~"))
Expand Down
58 changes: 57 additions & 1 deletion tests/lsp_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ t.test("abbrev input adds a space-prefixed raw candidate below [辞書登録]",
labels[#labels + 1] = item.label
end
-- 辞書候補、[辞書登録] の後ろに、スペース前置形だけが並ぶ
-- (入力そのものは <C-y> の無変換確定で入るので候補にしない)
-- (completion.abbrevWithSpace = false だと半角スペース無しの入力そのままになる)
t.assert_equals({ "全体", "[辞書登録]", " overall" }, labels)
-- 並び順は sortText で保たれる (クライアントは sortText で並べ替える)
t.assert_equals({ "00001", "00002", "00003" }, vim.tbl_map(function(item)
Expand Down Expand Up @@ -697,6 +697,62 @@ t.test("abbrev keeps a dictionary candidate equal to the input and adds only the
vim.cmd.bwipeout({ bang = true })
end)

t.test("completion.abbrevWithSpace=false uses the raw input without a leading space", function()
local skkelua = require("skkelua")
local lib = require("skkelua.store").get_library()
lib:register_henkan_result("okurinasi", "overall", "全体")
skkelua.config({ completion = { enabled = true, abbrevWithSpace = false } })
skkelua._handle_request("enable", {}, vim_status)

local pre_edit = setup_state({ "/", "o", "v", "e", "r", "a", "l", "l" })
t.assert_equals("▽overall", pre_edit)

local list = require("skkelua.lsp")._make_completion_list()
local labels = {}
for _, item in ipairs(list.items) do
labels[#labels + 1] = item.label
end
t.assert_equals({ "全体", "[辞書登録]", "overall" }, labels)
t.assert_equals({ "00001", "00002", "00003" }, vim.tbl_map(function(item)
return item.sortText
end, list.items))

local raw = list.items[3]
t.assert_equals("overall", raw.textEdit.newText)
t.assert_equals(true, raw.data.raw)

-- 入力そのものの候補を確定しても辞書には登録されない
require("skkelua.lsp")._on_complete_done("accept", {
user_data = { nvim = { lsp = { completion_item = { data = raw.data } } } },
})
t.assert_equals({ "全体" }, lib:get_henkan_result("okurinasi", "overall"))

vim.cmd.bwipeout({ bang = true })
end)

t.test("completion.abbrevWithSpace=false drops a raw candidate duplicated by a dictionary candidate", function()
local skkelua = require("skkelua")
local lib = require("skkelua.store").get_library()
-- 辞書候補が入力そのものと同じ場合は dedup され、raw 候補は並ばない
lib:register_henkan_result("okurinasi", "ov", "ov")
skkelua.config({ completion = { enabled = true, abbrevWithSpace = false } })
skkelua._handle_request("enable", {}, vim_status)

local pre_edit = setup_state({ "/", "o", "v" })
t.assert_equals("▽ov", pre_edit)

local list = require("skkelua.lsp")._make_completion_list()
local labels = {}
for _, item in ipairs(list.items) do
labels[#labels + 1] = item.label
end
t.assert_equals({ "ov", "[辞書登録]" }, labels)
-- 先頭は辞書候補なので確定時に登録される (raw ではない)
t.assert_equals(nil, list.items[1].data.raw)

vim.cmd.bwipeout({ bang = true })
end)

t.test("kana input does not add raw candidates", function()
setup_library()
local skkelua = require("skkelua")
Expand Down