首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Coding
V2EX  ›  Vim

使用 coc.nvim 整合自动构建工具

  •  
  •   chemzqm · 174 天前 · 1697 次点击
    这是一个创建于 174 天前的主题,其中的信息可能已经有所发展或是发生改变。

    优点

    • 无需新开窗口
    • 观察 statusline 即可了解构建状态
    • 使用 quickfix 列表快速跳转错误位置

    实现

    以 webpack 为例:

    const {commands, workspace, Disposable} = require('coc.nvim')
    const path = require('path')
    
    const patternWebpack = /ERROR\sin\s(?<filename>\S+)\s(?<line>\d+):(?<col>\d+)/
    const errorPattern = /ERROR\sin\s(?<filename>[^(]+)\((?<line>\d+),(?<col>\d+)\)/
    
    exports.activate = context => {
      let {nvim} = workspace
      let statusItem = workspace.createStatusBarItem(1, {progress: true})
      let task = workspace.createTask('WEBPACK')
      let cwd
    
      async function check() {
        let running = await task.running
        if (running) {
          statusItem.isProgress = false
          statusItem.text = '?'
          statusItem.show()
        } else {
          statusItem.hide()
        }
      }
      check().catch(_e => {
        // noop
      })
      task.onExit(code => {
        if (code != 0) {
          workspace.showMessage(`Webpack exit with code ${code}`, 'warning')
        }
        statusItem.hide()
      })
      task.onStdout(lines => {
        let i = 0
        let items = []
        for (let line of lines) {
          if (line.indexOf('ERROR') !== -1) {
            let res = patternWebpack.exec(line)
            if (res == null) {
              res = errorPattern.exec(line)
            }
            if (res != null) {
              let {filename} = res.groups
              if (!path.isAbsolute(filename)) {
                filename = path.join(cwd, filename)
              }
              items.push({
                filename,
                lnum: parseInt(res.groups.line),
                col: parseInt(res.groups.col),
                text: lines[i + 1].trim(),
                type: 'E'
              })
            }
          }
          i++
        }
        nvim.call('setqflist', [items], true)
        statusItem.text = items.length == 0 ? '✓' : '✗'
        statusItem.isProgress = false
      })
      task.onStderr(lines => {
        for (let line of lines) {
          if (line.match(/webpack\sis\swatching/)) {
            statusItem.text = 'watching'
          }
        }
      })
    
      context.subscriptions.push(Disposable.create(() => {
        task.dispose()
      }))
      context.subscriptions.push(commands.registerCommand('webpack.watch', async () => {
        cwd = workspace.cwd
        task.start({
          cmd: 'webpack',
          args: ['--watch', '--no-color'],
          cwd: workspace.cwd
        })
        statusItem.show()
      }))
    }
    

    将文件保存为 $VIMCONFIG/coc-extensions/webpack.js,设置自定义 Webpack 命令 ( vim 中执行 :echo $VIMCONFIG 查看 $VIMCONFIG )

    command! -nargs=0 Webpack :call CocAction('runCommand', 'webpack.watch')
    

    友情提示

    • 该示例使用 webpack --watch, 而不是保存完重现构建,效率高一些
    • 任务是由 vim/neovim 执行的,重启 coc 服务不用重启任务
    • coc-tsserver 插件自带了 tsserver.watchBuild 命令执行 tsc --watch 构建
    6 回复  |  直到 2019-06-27 12:40:38 +08:00
        1
    weixiangzhe   174 天前
    支持下楼主,coc 解决好多问题,
        2
    yuuko   174 天前
    滋瓷,是不是可以搞成一个通用的列出 package.json 的 script command
        3
    chemzqm   174 天前
    @yuuko 当然可以,只是我不了解这方面的其它需求,这个够我用了
        4
    lancelock   174 天前
    vim 可以打断点 debug 吗? gdb 之类的用不来
        5
    ivechan   174 天前
    @lancelock

    :packadd termdebug
    :h :Termdebug

    使用 GUI 版本的 vim,比如 gvim,应该是可以使用鼠标的。
        6
    Taigacute   172 天前
    👍
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2786 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 25ms · UTC 12:18 · PVG 20:18 · LAX 04:18 · JFK 07:18
    ♥ Do have faith in what you're doing.