🐜
denopsでvimのcodic拡張機能を書いた
denopsでvimのcodic拡張機能を書いた
denopsでcodicの拡張機能を書きました。
背景
普段プログラムを書いているときに雑にget
とかを雑に使いがちなので、ちゃんと命名をしたいと思ってCodicを使ってます。
(Google翻訳とかだとプログラムでよく使う単語と若干違うのがでるイメージがある)
いちいちブラウザを開いて調べるのは手間なのでエディタからAPIを叩けるようにしました。
あとはvimの拡張機能がdenoで掛けるようになったらしいので勉強がてら書きたかったのもあります。
作っている最中に調べたら既に先人が作っていらっしゃった。
多分こっちのほうが高性能です。
実装
を使っています。
APIからの結果を表示するだけなので80行程度で書けました。
import { start } from "https://deno.land/x/denops_std@v0.4/mod.ts";
async function fetchAPI(text: string[], TOKEN: string) {
if (text.length >= 4) {
throw new Error(`The number of texts must be 3 or less.`);
}
const BASEURL = "https://api.codic.jp/v1/engine/translate.json";
const res = await fetch(BASEURL, {
headers: new Headers({
"Authorization": `Bearer ${TOKEN}`,
}),
body: new URLSearchParams({
"text": text.join("\n"),
}),
method: "POST",
});
if (res.status !== 200) {
console.log(res.status);
}
const json = res.json();
const data = await json;
return data;
}
start(async (vim) => {
vim.register({
async codic(args: unknown): Promise<void> {
if (typeof args !== "string") {
throw new Error(`'args' must be a string`);
}
const TOKEN = Deno.env.get("CODIC_TOKEN");
// console.log(`your token is ${TOKEN}`);
if (TOKEN === undefined) {
console.error("No token set");
throw new Error(`No token set`);
}
const targets = args.split(/\s+/);
const data = await fetchAPI(targets, TOKEN);
const contents: string[] = [];
for (const datum of data) {
contents.push(`${datum["text"]} -> ${datum["translated_text"]} `);
for (const word of datum["words"]) {
let content = ` - ${word["text"]}: `;
if (word["successful"]) {
for (const candidate of word["candidates"]) {
content += `${candidate["text"]}, `;
}
} else {
content += "null";
}
contents.push(content);
}
contents.push("");
}
await vim.cmd("botright new");
await vim.call(
"setline",
1,
contents,
);
await vim.execute(`
setlocal bufhidden=wipe buftype=nofile
setlocal nobackup noswapfile
setlocal nomodified nomodifiable
`);
},
});
await vim.execute(`
command! -nargs=? -bar Codic call denops#request('${vim.name}', 'codic', [<q-args>])
`);
});
APIを叩くためにアクセストークンを取得する必要があるので、Deno.env.get()
で$CODIC_TOKEN
を取得しています。
(環境変数の取得はvim.eval("$CODIC_TOKEN")
でもできるようです。)
vim内の変数でlet g:codic_accesstoken
とかでもいいかと思いましたがvimrcをdotfilesで管理していたりすると面倒なので環境変数からの読み込みにしました。
:Codic <text>
で与えられたtext
を/\s+/
で分割して\n
で結合してAPIを叩いています。
API側の制限で1度に変換できるのは3つまでです。
今後実装する予定の機能
-
選択範囲の変換
-選択範囲の置換をするのでcamelCaseだったりsnake_caseを選べるようにする
vimでの矩形選択がコマンドへは自動で行選択になるようなので断念
参考にさせていただいた記事
追記情報
2021/04/05
- コードを修正
- 実装予定の経過を追加
- リンクをカード形式に変更
Discussion