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

useSkkServer = true のとき漢字変換でハングアップする (Windows) #168

Closed
bsdfan opened this issue Dec 25, 2023 · 18 comments · Fixed by #169 or #171
Closed

useSkkServer = true のとき漢字変換でハングアップする (Windows) #168

bsdfan opened this issue Dec 25, 2023 · 18 comments · Fixed by #169 or #171
Assignees
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@bsdfan
Copy link

bsdfan commented Dec 25, 2023

useSkkServer = true で日本語変換しようとすると nvim がハングアップします。
(固まって何もできなくなり、タスクマネージャーで落とすしかない)

どこで問題が起こっているのかわからないのですが、調べられる範囲では下記の状況です。

  • "Kanji" で 「▽かんじ」までは入力できるが、次にスペースを押すとハングアップする
  • 個人辞書に登録済みの単語でもハングアップする
  • useSkkServer = false の場合はハングアップしない
  • useSkkServer = true でも、skkserver を起動していない場合はハングアップしない
  • 同じ環境で、9a58aae52062cd8aea69d63219cbd991843b1ffc では問題ないが、f6d3829c8f141e0c0da6e7387fba3e22fe02c41e では問題が発生する

OS: Windows 10
NVIM v0.9.4
deno 1.39.1
crvskkserv ver. 2.5.6 / yaskkserv2 0.1.7 (どちらの場合でも)

@Shougo Shougo self-assigned this Dec 25, 2023
@Shougo Shougo added the bug Something isn't working label Dec 25, 2023
@Shougo
Copy link
Contributor

Shougo commented Dec 25, 2023

原因が分かったので修正します。Linux だとハングアップはしません。エラーになります。

@Shougo
Copy link
Contributor

Shougo commented Dec 25, 2023

@bsdfan Please test #169.

@bsdfan
Copy link
Author

bsdfan commented Dec 25, 2023

更新して試してみましたが、症状は改善していませんでした。
Linuxでは修正されたということは、Windows だけなのか、こちらの環境の問題なんでしょうか・・・
もう少しいろいろ試してみます。

@Shougo
Copy link
Contributor

Shougo commented Dec 25, 2023

Windowsでは試していません。私の環境ではハングアップは再現しませんでしたので。
残念ながら動いていたという以前のルーチンは互換性の問題で使えません。
オープンソースなので調査お願いします。

@Shougo
Copy link
Contributor

Shougo commented Dec 25, 2023

ちなみに、他の実装方法がないか独自に調査していましたがハングアップしたりでロクに動かないので無理でした。

@tani
Copy link
Contributor

tani commented Dec 26, 2023

以下の設定ファイルで動作しないことを確認しました。

local jetpackfile = vim.fn.stdpath('data') .. '/site/pack/jetpack/opt/vim-jetpack/plugin/jetpack.vim'
local jetpackurl = "https://raw.githubusercontent.com/tani/vim-jetpack/master/plugin/jetpack.vim"
if vim.fn.filereadable(jetpackfile) == 0 then
  vim.fn.system(string.format('curl -fsSLo %s --create-dirs %s', jetpackfile, jetpackurl))
end

vim.cmd.source(jetpackfile)
require('jetpack.packer').startup(function(use)
  use({ 'tani/vim-jetapck' })
  use({ 'vim-denops/denops.vim' })
  use({
    'vim-skk/skkeleton',
    config = function()
      vim.keymap.set('i', '<C-j>', '<Plug>(skkeleton-toggle)')
      vim.fn['skkeleton#config']({
        useSkkServer = true
      })
    end
  })
end)

問題が解決していないので、Issueをreopenしていただけますか?

@Shougo Shougo reopened this Dec 26, 2023
@Shougo
Copy link
Contributor

Shougo commented Dec 26, 2023

ちなみに、jetpack は最小構成にいらないと思います

@Shougo Shougo added help wanted Extra attention is needed windows labels Dec 26, 2023
@Shougo
Copy link
Contributor

Shougo commented Dec 26, 2023

import * as encoding from "https://esm.sh/encoding-japanese@2.0.0/";
import { TextLineStream } from "https://deno.land/std@0.209.0/streams/mod.ts";

const Encode = {
  "utf-32": "UTF32",
  "utf-16": "UTF16",
  "utf-16be": "UTF16BE",
  "utf-16le": "UTF16LE",
  "binary": "BINARY",
  "ascii": "ASCII",
  "jis": "JIS",
  "utf-8": "UTF8",
  "euc-jp": "EUCJP",
  "sjis": "SJIS",
  "unicode": "UNICODE",
  "auto": "AUTO",
} as const;


function encode(str: string, encode: Encoding): Uint8Array {
  const utf8Encoder = new TextEncoder();
  const utf8Bytes = utf8Encoder.encode(str);
  const eucBytesArray = encoding.convert(utf8Bytes, Encode[encode], "UTF8");
  const eucBytes = Uint8Array.from(eucBytesArray);
  return eucBytes;
}

async function* iterLine(
  r: ReadableStream<Uint8Array>,
  encoding: string,
): AsyncIterable<string> {
  const lines = r
    .pipeThrough(new TextDecoderStream(encoding), {
      preventAbort: true,
      preventCancel: true,
      preventClose: true,
    })
    .pipeThrough(new TextLineStream());

  for await (const line of lines.values({ preventCancel: true })) {
    yield line as string;
  }
}

const conn = await Deno.connect({
  hostname: "127.0.0.1",
  port: 1178,
});

const requestEncoding = "euc-jp";
const responseEncoding = "euc-jp";

if (conn) {
  const word = "1ほかん ";
  await conn.write(encode(word, requestEncoding));
  const reader = conn.readable.getReader();
  reader.releaseLock();

  for await (
    const str of iterLine(conn.readable, responseEncoding)
  ) {
    console.log(str);

    break;
  }

  conn?.write(encode("0", requestEncoding));
  conn?.close();
}

Please test the script.

% deno run -A --no-lock deno_connets.ts
1/保管/補完;completion/補間;[数学]interpolation/

@Shougo Shougo removed the windows label Dec 26, 2023
@bsdfan
Copy link
Author

bsdfan commented Dec 26, 2023

@Shougo
上に書かれたスクリプトはちゃんと動作しました。

追加で確認できたこと

  • immediatelyJisyoRW = false にすると、ユーザ辞書に登録済みの読みに対しては変換できるようになります。しかも、ユーザ辞書に登録されていない部分も候補として出てきます。
  • 変換できるのは1回目だけで、もう一度変換しようとするとハングアップします

@Shougo
Copy link
Contributor

Shougo commented Dec 26, 2023

Please test #171

@bsdfan
Copy link
Author

bsdfan commented Dec 26, 2023

ハングアップせず変換できました。
が、2回目以降の変換では skkserver からの候補が取得できていないです。

@Shougo
Copy link
Contributor

Shougo commented Dec 26, 2023

Test script 2

import * as encoding from "https://esm.sh/encoding-japanese@2.0.0/";
import { TextLineStream } from "https://deno.land/std@0.209.0/streams/mod.ts";

const Encode = {
  "utf-32": "UTF32",
  "utf-16": "UTF16",
  "utf-16be": "UTF16BE",
  "utf-16le": "UTF16LE",
  "binary": "BINARY",
  "ascii": "ASCII",
  "jis": "JIS",
  "utf-8": "UTF8",
  "euc-jp": "EUCJP",
  "sjis": "SJIS",
  "unicode": "UNICODE",
  "auto": "AUTO",
} as const;


function encode(str: string, encode: Encoding): Uint8Array {
  const utf8Encoder = new TextEncoder();
  const utf8Bytes = utf8Encoder.encode(str);
  const eucBytesArray = encoding.convert(utf8Bytes, Encode[encode], "UTF8");
  const eucBytes = Uint8Array.from(eucBytesArray);
  return eucBytes;
}

async function* iterLine(
  r: ReadableStream<Uint8Array>,
  encoding: string,
): AsyncIterable<string> {
  const lines = r
    .pipeThrough(new TextDecoderStream(encoding), {
      preventAbort: true,
      preventCancel: true,
      preventClose: true,
    })
    .pipeThrough(new TextLineStream());

  for await (const line of lines.values({ preventCancel: true })) {
    yield line as string;
  }
}

const conn = await Deno.connect({
  hostname: "127.0.0.1",
  port: 1178,
});

const requestEncoding = "euc-jp";
const responseEncoding = "euc-jp";

if (conn) {
  {
    const word = "1ほかん ";
    await conn.write(encode(word, requestEncoding));
    const reader = conn.readable.getReader();
    reader.releaseLock();

    for await (
      const str of iterLine(conn.readable, responseEncoding)
    ) {
      console.log(str);

      break;
    }
  }

  {
    const word = "2あい ";
    await conn.write(encode(word, requestEncoding));
    const reader = conn.readable.getReader();
    reader.releaseLock();

    for await (
      const str of iterLine(conn.readable, responseEncoding)
    ) {
      console.log(str);

      break;
    }
  }

  conn?.write(encode("0", requestEncoding));
  conn?.close();
}

@bsdfan
Copy link
Author

bsdfan commented Dec 26, 2023

2回目のところでエラーが発生します。

1/保管/補完;completion/補間;[数学]interpolation/
error: Uncaught (in promise) TypeError: ReadableStream is locked.
    const reader = conn.readable.getReader();
                                 ^
    at setUpReadableStreamDefaultReader (ext:deno_web/06_streams.js:3729:11)
    at acquireReadableStreamDefaultReader (ext:deno_web/06_streams.js:417:3)
    at ReadableStream.getReader (ext:deno_web/06_streams.js:5274:14)
    at file:///C:/tmp/deno_connets2.ts:72:34
    at eventLoopTick (ext:core/01_core.js:181:11)

@Shougo
Copy link
Contributor

Shougo commented Dec 26, 2023

はい。おそらくこれが原因なので、修正方法を探っています

@Shougo
Copy link
Contributor

Shougo commented Dec 26, 2023

@bsdfan #171 こちらをもう一度試してください。毎回close するようにしてみました。

@bsdfan
Copy link
Author

bsdfan commented Dec 27, 2023

そのままだと skkserver から候補が全くとれなくなりました。
this.connect() に await が必要な気がしたので、await を追記したところ、ちゃんと変換できるようになりました。

@Shougo
Copy link
Contributor

Shougo commented Dec 27, 2023

修正しました。

@Shougo
Copy link
Contributor

Shougo commented Dec 27, 2023

@kuu この実装でよいでしょうか?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants