1
0

More than 1 year has passed since last update.

NeoVim に簡易電卓機能を追加

Posted at

ややこしい計算は電卓に頼りたくなるのだけど、これが案外、面倒くさいという話を学生さんと交しました。

  • まずは、電卓アプリを起動するのが面倒。そして

  • 数式を入力するのに、仕事の文脈と行き来しながら何度か数値をコピペするのが面倒。おまけに、

  • 計算結果をコピーして、どこかに貼るのが面倒。

    計算した結果はほぼ確実にどこかにペーストするのだから、計算結果は勝手にコピーされるべきだ。

というわけで、仕事の中心にいるテキストエティタ (neovim - vim の進化版) に自分が望む電卓機能を追加したというお話しです。

最初に Python との連携機能を用いた実装

こちらは Vim script 2行でできました。

py3 from math import *
command! -nargs=* P let @* = py3eval("str(<args>)") | echo @*

その心は :P 2 + 3 + 5 とやれば、結果の 10 を表示し、これをクリップボードにコピーします。neovim の文書に "*p でペーストできることはもちろん、ほかのアプリ (Word, Excel, ブラウザ、なんでもあれ) にもペーストできます。

また、この設定の1行目で math モジュールをインポートしているので、:P sin(pi / 6) のような math モジュールに定義されている定数や関数も簡単に利用できます。

つぎに NeoVim に組込まれている Lua を用いた実装。

NeoVim 0.5.0 は Lua を内包し、最近、利用できるようになった NeoVim 0.7.0 で Lua から NeoVim の機能拡張がしやすくなりました。

数式の文法は Python でも Lua でもほとんど違いはないだろうと思ったので、NeoVim がもともと含んでいる Lua で実装した方が軽いかと思って作ってみました。(もっとも、Python API を利用するパッケージがほかにあるから、Lua で実装する意義はほとんどないけれど)

前の実装よりすこしややこしいけれど、こんな感じです。

vim.api.nvim_create_user_command('C', function (args)
    vim.fn.setreg('*', tostring(load('return ' .. args.args)()))
    print(vim.fn.getreg('*'))
  end, { nargs='+' } )

load 関数は eval っぽい役割を果し、引数に与えられた文字列を本体とする関数を構成してくれるので、その場で呼び出して計算結果 (result) を得ています。C コマンドとともに書いた数式が Lua の引数 (args.args) に与えられるので、それを return と連結して load 関数に与えると、数式を評価する関数が得られます。これをその場で呼び出す(load(...)())ことで計算しています。

vim のレジスタには文字列を収めるものらしいので、保存する前に文字列化しています。ちなみに、setreg の第一引数に与えている * はクリップボードに該当する vim のレジスタです。

よくわからなかった、Python での from math import * 相当のことを Lua で実現する方法です。Lua の math モジュールで定義されている要素を走査して、大域モジュール (_G) に追加すればよいことを StackOverflow で学びました。

function using(module, ...)
  for k,v in pairs(module) do
    if _G[k] then
      io.stderr:write("use: skipping duplicate symbol ", k, "\n")
    else
      _G[k] = module[k]
    end
  end
end

using(math)

もうすこし簡単にできないものかなぁ。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0