🌟

BigQuery 標準 SQL の LSP を nvim-lsp から使う

2022/03/20に公開

最近、LSP の設定を nvim-lsp ベースに変更したのですが、その過程で @dr666m1 さんが公開されている BigQuery(標準 SQL)の LSP を見つけたので設定してみました。

https://github.com/dr666m1/bq-extension-vscode

以下、nvim-lsp nvim-lsp-installer nvim-lspconfig 前提となります。

はじめに

gcloudsqlite3 が入っていた方が良さそうなので、入っていない場合は事前にインストールしておきます。Mac(Homebrew)の場合はこんな感じ。

$ brew install sqlite
$ brew install --cask google-cloud-sdk

ログインもしておきましょう。必要に応じて、set-quota-project も。

$ gcloud auth application-default login
$ gcloud auth application-default set-quota-project <QUOTA_PROJECT_ID>

nvim-lsp-installer へのサーバー追加

環境が変わるたびに手動で設定するのは疲れるので、nvim-lsp-installer にカスタムサーバーとして追加してみます。カスタムサーバーの追加方法については、このあたりを参考にしました。

https://github.com/williamboman/nvim-lsp-installer/blob/main/CUSTOM_SERVERS.md

Server クラスのインスタンスを作成して、必要な設定をしていきます。インストール時に必要な処理(git clone してきて npm install を走らせる等)も指示してあげます。

local lspInstallerServer = require("nvim-lsp-installer.server")
local lspInstallerSettings = require("nvim-lsp-installer.settings")
local lspInstallerPath = require("nvim-lsp-installer.core.path")
local lspInstallerStd = require("nvim-lsp-installer.core.managers.std")
local lspInstallerGit = require("nvim-lsp-installer.core.managers.git")
local lspInstallerNpm = require("nvim-lsp-installer.core.managers.npm")

local lspInstallerRootDir = lspInstallerSettings.current.install_root_dir

local bqServer = lspInstallerServer.Server:new({
    name = 'bqls',
    root_dir = lspInstallerPath.concat({ lspInstallerRootDir, 'bq-language-server'}),
    languages = { 'sql' },
    homepage = 'https://github.com/dr666m1/bq-extension-vscode',
    installer = function(ctx)
        lspInstallerGit.clone({'https://github.com/dr666m1/bq-extension-vscode.git'}).with_receipt()
        ctx.spawn.npm {'install'}
        lspInstallerNpm.run('compile')
    end,
    default_options = {
        cmd = { lspInstallerPath.concat { lspInstallerRootDir, 'bq-language-server', 'server', 'bin', 'bq-language-server' }, '--stdio' },
    },
})

lspInstaller.register(bqServer)

こんな感じで、カスタムサーバーを追加しておくと、:LspInstallInfo の中に bqls というサーバーが出てきます。そのまま i を押せばインストール完了です。

nvim-lspconfig の追加

インストールは出来ましたが、これだけだとまだ動きません。バッファを開いた際につながる様に、nvim-lspconfig にも bqls を追加します。

local lspConfig = require('lspconfig')
local lspConfigs = require('lspconfig.configs')

if not lspConfigs.bqls then
    lspConfigs.bqls = { default_config = {
        cmd = { lspInstallerPath.concat { lspInstallerRootDir, 'bq-language-server', 'server', 'bin', 'bq-language-server' }, '--stdio' },
        filetypes = { 'sql' },
        root_dir = lspConfig.util.find_git_ancestor,
        single_file_support = true,
        settings = { bqExtensionVSCode = { diagnostic = { forVSCode = false } } },
    } }
end

ここまでの設定で、.sql ファイルを開くと bqls が立ち上がるようになりました。保存すると自動的に Dry Run も動いてくれて良い感じです。

整形(format)の実行

bq-extension-vscode に内包された prettier-plugin-bq によって、こんな感じでサクッと標準 SQL の整形ができます。

:lua vim.lsp.buf.formatting()

私の場合は、(LSP 全般的に)こんな感じでキーバインドしています。まぁこの辺はお好みで。

local on_attach = function (_, bufnr)
    local function nnoremap_silent_buffer(lhs, rhs)
        vim.api.nvim_buf_set_keymap(bufnr, 'n', lhs, rhs, { noremap=true, silent=true })
    end

    nnoremap_silent_buffer('g=', '<Cmd>lua vim.lsp.buf.formatting()<CR>')
end

local lspInstaller = require("nvim-lsp-installer")

lspInstaller.on_server_ready(function(server)
    local opts = { on_attach = on_attach }
    server:setup(opts)
    vim.cmd [[ do User LspAttachBuffers ]]
end)

おわりに

BigQuery コンソール上のエディタも決して悪くはないと思うのですが、なにしろ整形が絶望的なので今後は neovim で編集することが増えそうです。@dr666m1 さん、ありがとうございます。

今後の課題

  • .sql ファイル一律で動いてしまうので、BigQuery 以外の SQL ファイルを編集する場合は邪魔になるかもしれない → 対策しました
  • bq/updateCache を実行すると、データセットやテーブルの情報を取得して補完に活用してくれる様なのですが、私の環境では上手く取得出来ていない模様。cache.sqlite ファイルのタイムスタンプは更新されるものの中身が入ってこない → 解決しました

Discussion