dart-lang / dart-lang/dart-vim-plugin
job_start is incompatible with neovim
- Dominant language
- Vim Script
- Stars
- 653
- Forks
- 51
- PR merge metrics
- No merged PRs in 30d
Description
Unfortunately vim and neovim have different job APIs. In vim it's `job_start`, and in neovim it's `jobstart`. Since 5d8f54c when this plugin moved to `job_start`, this plugin stopped working for neovim.
Here's an initial attempt to resolve it:
```
if has('nvim')
let l:options = {
\ 'on_stdout': { id, data, event -> extend(l:stdout_data, data) },
\ 'on_stderr': { id, data, event -> extend(l:stderr_data, data) },
\ 'on_exit': { id, code, event ->
\ s:formatResult(l:stdout_data, l:stderr_data, l:buffer_content)} }
let l:job = jobstart(l:cmd, l:options)
call chansend(l:job, join(l:buffer_content, "\n") . "\n")
call chanclose(l:job, 'stdin')
else
let l:job = job_start(l:cmd, l:options)
call ch_sendraw(job_getchannel(l:job), join(l:buffer_content, "\n"))
call ch_close_in(job_getchannel(l:job))
endif
```
However, it ends up writing the buffer BEFORE the formatted code is applied to the buffer. With a bit of hackery, I got it to work with:
```
function! s:FormatOnSave()
" Dart code formatting on save
if get(g:, 'dart_format_on_save', 0)
if has('nvim')
if get(b:, 'dart_formatting_for_save', 0)
return
endif
let b:dart_formatting_for_save = 1
endif
call dart#fmt()
endif
endfunction
```
and
```
function! s:onNvimFormatExit(stdout_data, stderr_data, buffer_content) abort
call s:formatResult(a:stdout_data, a:stderr_data, a:buffer_content)
if get(b:, 'dart_formatting_for_save', 0)
let b:dart_formatting_for_save = 0
noautocmd write
endif
endfunction
function! dart#fmt(...) abort
...
if has('nvim')
let l:options = {
\ 'on_stdout': { id, data, event -> extend(l:stdout_data, data) },
\ 'on_stderr': { id, data, event -> extend(l:stderr_data, data) },
\ 'on_exit': { id, code, event ->
\ s:onNvimFormatExit(l:stdout_data, l:stderr_data, l:buffer_content)} }
let l:job = jobstart(l:cmd, l:options)
call chansend(l:job, join(l:buffer_content, "\n") . "\n")
call chanclose(l:job, 'stdin')
else
let l:job = job_start(l:cmd, l:options)
call ch_sendraw(job_getchannel(l:job), join(l:buffer_content, "\n"))
call ch_close_in(job_getchannel(l:job))
endif
endfunction
```
I acknowledge it's messy but I don't have the time to work on it further, so feel free to adapt the code. I declare my contributions as public domain.
Contributor guide
Research direction
Start at dart#fmt and s:FormatOnSave, then compare the proposed jobstart/chansend/chanclose path with the job_start/job_getchannel path. Done means Dart formatting on save works in both Vim and Neovim, with the formatted buffer written only after formatting completes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart, vim
- Domain
- developer-experience, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100