Skip to content

Commit 8c920ec

Browse files
authored
Merge pull request #344 from vim-denops/v7-pre
🎉 Denops v7
2 parents 09e6495 + 6eb990e commit 8c920ec

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+9873
-1324
lines changed

.github/workflows/test.yml

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,58 +41,62 @@ jobs:
4141
run: deno task check
4242

4343
test:
44+
needs: check
45+
4446
strategy:
47+
fail-fast: false
4548
matrix:
4649
runner:
4750
- windows-latest
4851
- macos-latest
4952
- ubuntu-latest
5053
version:
51-
- "1.38.x"
54+
- "1.45.x"
5255
- "1.x"
5356
host_version:
54-
- vim: "v9.0.2189"
55-
nvim: "v0.9.4"
57+
- vim: "v9.1.0448"
58+
nvim: "v0.10.0"
59+
5660
runs-on: ${{ matrix.runner }}
61+
5762
steps:
5863
- run: git config --global core.autocrlf false
5964
if: runner.os == 'Windows'
65+
6066
- uses: actions/checkout@v4
67+
6168
- uses: denoland/setup-deno@v1.1.4
6269
with:
6370
deno-version: "${{ matrix.version }}"
71+
6472
- uses: rhysd/action-setup-vim@v1
6573
id: vim
6674
with:
6775
version: "${{ matrix.host_version.vim }}"
68-
- name: Check Vim
69-
run: |
70-
echo ${DENOPS_TEST_VIM}
71-
${DENOPS_TEST_VIM} --version
72-
env:
73-
DENOPS_TEST_VIM: ${{ steps.vim.outputs.executable }}
76+
7477
- uses: rhysd/action-setup-vim@v1
7578
id: nvim
7679
with:
7780
neovim: true
7881
version: "${{ matrix.host_version.nvim }}"
79-
- name: Check Neovim
82+
83+
- name: Export executables
8084
run: |
81-
echo ${DENOPS_TEST_NVIM}
82-
${DENOPS_TEST_NVIM} --version
83-
env:
84-
DENOPS_TEST_NVIM: ${{ steps.nvim.outputs.executable }}
85+
echo "DENOPS_TEST_VIM_EXECUTABLE=${{ steps.vim.outputs.executable }}" >> "$GITHUB_ENV"
86+
echo "DENOPS_TEST_NVIM_EXECUTABLE=${{ steps.nvim.outputs.executable }}" >> "$GITHUB_ENV"
87+
8588
- name: Perform pre-cache
8689
run: deno cache ./denops/@denops-private/mod.ts
90+
8791
- name: Test
8892
run: deno task test:coverage
8993
env:
9094
DENOPS_TEST_DENOPS_PATH: "./"
91-
DENOPS_TEST_VIM_EXECUTABLE: ${{ steps.vim.outputs.executable }}
92-
DENOPS_TEST_NVIM_EXECUTABLE: ${{ steps.nvim.outputs.executable }}
93-
timeout-minutes: 5
95+
timeout-minutes: 10
96+
9497
- run: |
9598
deno task coverage --lcov > coverage.lcov
99+
96100
- uses: codecov/codecov-action@v4
97101
with:
98102
os: ${{ runner.os }}

.github/workflows/update.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
git config user.name github-actions[bot]
1919
git config user.email github-actions[bot]@users.noreply.github.com
2020
- name: Update dependencies and commit changes
21-
run: deno task -q upgrade:commit --summary ../title.txt --report ../body.md
21+
run: deno task -q update:commit --summary ../title.txt --report ../body.md
2222
- name: Check result
2323
id: result
2424
uses: andstor/file-existence-action@v2

README.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,15 @@
33
<strong>Denops</strong><br>
44
<sup>An ecosystem for Vim/Neovim enabling developers to write plugins in Deno.</sup>
55

6-
[![Deno 1.38.5 or above](https://img.shields.io/badge/Deno-Support%201.38.5-yellowgreen.svg?logo=deno)](https://github.com/denoland/deno/tree/v1.38.5)
7-
[![Vim 9.0.2189 or above](https://img.shields.io/badge/Vim-Support%209.0.2189-yellowgreen.svg?logo=vim)](https://github.com/vim/vim/tree/v9.0.2189)
8-
[![Neovim 0.9.4 or above](https://img.shields.io/badge/Neovim-Support%200.9.4-yellowgreen.svg?logo=neovim&logoColor=white)](https://github.com/neovim/neovim/tree/v0.9.4)
6+
[![Deno 1.45.0 or above](https://img.shields.io/badge/Deno-Support%201.45.0-yellowgreen.svg?logo=deno)](https://github.com/denoland/deno/tree/v1.45.0)
7+
[![Vim 9.1.0448 or above](https://img.shields.io/badge/Vim-Support%209.1.0448-yellowgreen.svg?logo=vim)](https://github.com/vim/vim/tree/v9.1.0448)
8+
[![Neovim 0.10.0 or above](https://img.shields.io/badge/Neovim-Support%200.10.0-yellowgreen.svg?logo=neovim&logoColor=white)](https://github.com/neovim/neovim/tree/v0.10.0)
99

1010
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
11-
[![deno land](http://img.shields.io/badge/available%20on-deno.land/x/denops__core-lightgrey.svg?logo=deno)](https://deno.land/x/denops_core)
1211
[![test](https://github.com/vim-denops/denops.vim/actions/workflows/test.yml/badge.svg)](https://github.com/vim-denops/denops.vim/actions/workflows/test.yml)
1312
[![codecov](https://codecov.io/github/vim-denops/denops.vim/branch/main/graph/badge.svg?token=k50SaoYUp0)](https://codecov.io/github/vim-denops/denops.vim)
1413

1514
[![vim help](https://img.shields.io/badge/vim-%3Ah%20denops-orange.svg)](doc/denops.txt)
16-
[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/denops_core/mod.ts)
1715
[![Documentation](https://img.shields.io/badge/denops-Documentation-yellow.svg)](https://vim-denops.github.io/denops-documentation/)
1816

1917
</div>

autoload/denops.vim

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ function! denops#request_async(name, method, params, success, failure) abort
2525
\)
2626
endfunction
2727

28+
function! denops#interrupt(...) abort
29+
let l:args = a:0 ? [a:1] : []
30+
call denops#server#wait_async({ -> denops#_internal#server#chan#notify(
31+
\ 'invoke',
32+
\ ['interrupt', l:args],
33+
\)})
34+
endfunction
35+
2836
" Configuration
2937
call denops#_internal#conf#define('denops#disabled', 0)
3038
call denops#_internal#conf#define('denops#deno', 'deno')

autoload/denops/_internal/echo.vim

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,7 @@ function! s:echomsg_batch() abort
5656
let s:delayed_timer = 0
5757
let s:delayed_messages = []
5858
" Forcibly show the messages to the user
59-
call feedkeys(printf("\<Cmd>%dmessages\<CR>", l:counter), 'n')
59+
if l:counter > 1 && !g:denops#_test
60+
call feedkeys(printf("\<Cmd>%dmessages\<CR>", l:counter), 'n')
61+
endif
6062
endfunction

autoload/denops/_internal/event.vim

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function denops#_internal#event#emit(name) abort
2+
execute 'doautocmd <nomodeline> User' a:name
3+
endfunction

autoload/denops/_internal/job.vim

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,17 @@ if has('nvim')
2424
\ 'on_stderr': funcref('s:on_recv', [a:options.on_stderr]),
2525
\ 'on_exit': funcref('s:on_exit', [a:options.on_exit]),
2626
\}
27-
return jobstart(a:args, l:options)
27+
try
28+
return jobstart(a:args, l:options)
29+
catch
30+
" NOTE: Call `on_exit` when cmd (args[0]) is not executable.
31+
call timer_start(0, { -> l:options.on_exit(-1, -1, 'exit') })
32+
endtry
2833
endfunction
2934

3035
function! s:stop(job) abort
3136
try
3237
call jobstop(a:job)
33-
call jobwait([a:job])
3438
catch /^Vim\%((\a\+)\)\=:E900/
3539
" NOTE:
3640
" Vim does not raise exception even the job has already closed so fail
@@ -58,24 +62,27 @@ else
5862
\ 'err_cb': funcref('s:out_cb', [a:options.on_stderr, 'stderr']),
5963
\ 'exit_cb': funcref('s:exit_cb', [a:options.on_exit, 'exit']),
6064
\}
61-
return job_start(a:args, l:options)
65+
let l:job = job_start(a:args, l:options)
66+
if l:job->job_status() ==# "fail"
67+
" NOTE:
68+
" On Windows call `on_exit` when cmd (args[0]) is not executable.
69+
" On Unix a non-existing command results in "dead" instead of "fail",
70+
" and `on_exit` is called by `job_start()`.
71+
call timer_start(0, { -> l:options.exit_cb(-1, -1) })
72+
endif
73+
return l:job
6274
endfunction
6375

6476
function! s:stop(job) abort
6577
call job_stop(a:job)
6678
call timer_start(s:KILL_TIMEOUT_MS, { -> job_stop(a:job, 'kill') })
67-
" Wait until the job is actually closed
68-
while job_status(a:job) ==# 'run'
69-
sleep 10m
70-
endwhile
71-
redraw
7279
endfunction
7380

74-
function! s:out_cb(callback, event, ch, msg) abort
75-
call a:callback(a:ch, a:msg, a:event)
81+
function! s:out_cb(callback, event, job, msg) abort
82+
call a:callback(a:job, a:msg, a:event)
7683
endfunction
7784

78-
function! s:exit_cb(callback, event, ch, status) abort
79-
call a:callback(a:ch, a:status, a:event)
85+
function! s:exit_cb(callback, event, job, status) abort
86+
call a:callback(a:job, a:status, a:event)
8087
endfunction
8188
endif

autoload/denops/_internal/plugin.vim

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
const s:STATE_RESERVED = 'reserved'
22
const s:STATE_LOADING = 'loading'
33
const s:STATE_LOADED = 'loaded'
4+
const s:STATE_UNLOADING = 'unloading'
45
const s:STATE_FAILED = 'failed'
56

7+
const s:VALID_NAME_PATTERN = '^[-_0-9a-zA-Z]\+$'
8+
69
let s:plugins = {}
710

11+
function! denops#_internal#plugin#is_valid_name(name) abort
12+
return a:name =~# s:VALID_NAME_PATTERN
13+
endfunction
14+
815
function! denops#_internal#plugin#get(name) abort
916
if !has_key(s:plugins, a:name)
17+
if !denops#_internal#plugin#is_valid_name(a:name)
18+
throw printf('[denops] Invalid plugin name: %s', a:name)
19+
endif
1020
let s:plugins[a:name] = #{name: a:name, script: '', state: s:STATE_RESERVED, callbacks: []}
1121
endif
1222
return s:plugins[a:name]
@@ -20,24 +30,41 @@ function! denops#_internal#plugin#load(name, script) abort
2030
const l:script = denops#_internal#path#norm(a:script)
2131
const l:args = [a:name, l:script]
2232
let l:plugin = denops#_internal#plugin#get(a:name)
33+
if l:plugin.state !=# s:STATE_RESERVED && l:plugin.state !=# s:STATE_FAILED
34+
call denops#_internal#echo#debug(printf('already loaded. skip: %s', l:args))
35+
return
36+
endif
2337
let l:plugin.state = s:STATE_LOADING
2438
let l:plugin.script = l:script
25-
let s:plugins[a:name] = l:plugin
2639
call denops#_internal#echo#debug(printf('load plugin: %s', l:args))
2740
call denops#_internal#server#chan#notify('invoke', ['load', l:args])
2841
endfunction
2942

43+
function! denops#_internal#plugin#unload(name) abort
44+
const l:args = [a:name]
45+
let l:plugin = denops#_internal#plugin#get(a:name)
46+
if l:plugin.state ==# s:STATE_LOADED
47+
let l:plugin.state = s:STATE_UNLOADING
48+
endif
49+
call denops#_internal#echo#debug(printf('unload plugin: %s', l:args))
50+
call denops#_internal#server#chan#notify('invoke', ['unload', l:args])
51+
endfunction
52+
3053
function! denops#_internal#plugin#reload(name) abort
3154
const l:args = [a:name]
3255
let l:plugin = denops#_internal#plugin#get(a:name)
33-
let l:plugin.state = s:STATE_LOADING
56+
if l:plugin.state ==# s:STATE_LOADED
57+
let l:plugin.state = s:STATE_UNLOADING
58+
endif
3459
call denops#_internal#echo#debug(printf('reload plugin: %s', l:args))
3560
call denops#_internal#server#chan#notify('invoke', ['reload', l:args])
3661
endfunction
3762

3863
function! s:DenopsSystemPluginPre() abort
3964
const l:name = matchstr(expand('<amatch>'), 'DenopsSystemPluginPre:\zs.*')
40-
execute printf('doautocmd <nomodeline> User DenopsPluginPre:%s', l:name)
65+
let l:plugin = denops#_internal#plugin#get(l:name)
66+
let l:plugin.state = s:STATE_LOADING
67+
call denops#_internal#event#emit(printf('DenopsPluginPre:%s', l:name))
4168
endfunction
4269

4370
function! s:DenopsSystemPluginPost() abort
@@ -49,21 +76,46 @@ function! s:DenopsSystemPluginPost() abort
4976
for l:Callback in l:callbacks
5077
call l:Callback()
5178
endfor
52-
execute printf('doautocmd <nomodeline> User DenopsPluginPost:%s', l:name)
79+
call denops#_internal#event#emit(printf('DenopsPluginPost:%s', l:name))
5380
endfunction
5481

5582
function! s:DenopsSystemPluginFail() abort
5683
const l:name = matchstr(expand('<amatch>'), 'DenopsSystemPluginFail:\zs.*')
5784
let l:plugin = denops#_internal#plugin#get(l:name)
5885
let l:plugin.state = s:STATE_FAILED
5986
let l:plugin.callbacks = []
60-
execute printf('doautocmd <nomodeline> User DenopsPluginFail:%s', l:name)
87+
call denops#_internal#event#emit(printf('DenopsPluginFail:%s', l:name))
88+
endfunction
89+
90+
function! s:DenopsSystemPluginUnloadPre() abort
91+
const l:name = matchstr(expand('<amatch>'), 'DenopsSystemPluginUnloadPre:\zs.*')
92+
let l:plugin = denops#_internal#plugin#get(l:name)
93+
let l:plugin.state = s:STATE_UNLOADING
94+
call denops#_internal#event#emit(printf('DenopsPluginUnloadPre:%s', l:name))
95+
endfunction
96+
97+
function! s:DenopsSystemPluginUnloadPost() abort
98+
const l:name = matchstr(expand('<amatch>'), 'DenopsSystemPluginUnloadPost:\zs.*')
99+
let l:plugin = denops#_internal#plugin#get(l:name)
100+
let l:plugin.state = s:STATE_RESERVED
101+
call denops#_internal#event#emit(printf('DenopsPluginUnloadPost:%s', l:name))
102+
endfunction
103+
104+
function! s:DenopsSystemPluginUnloadFail() abort
105+
const l:name = matchstr(expand('<amatch>'), 'DenopsSystemPluginUnloadFail:\zs.*')
106+
let l:plugin = denops#_internal#plugin#get(l:name)
107+
let l:plugin.state = s:STATE_RESERVED
108+
let l:plugin.callbacks = []
109+
call denops#_internal#event#emit(printf('DenopsPluginUnloadFail:%s', l:name))
61110
endfunction
62111

63112
augroup denops_autoload_plugin_internal
64113
autocmd!
65114
autocmd User DenopsSystemPluginPre:* ++nested call s:DenopsSystemPluginPre()
66115
autocmd User DenopsSystemPluginPost:* ++nested call s:DenopsSystemPluginPost()
67116
autocmd User DenopsSystemPluginFail:* ++nested call s:DenopsSystemPluginFail()
117+
autocmd User DenopsSystemPluginUnloadPre:* ++nested call s:DenopsSystemPluginUnloadPre()
118+
autocmd User DenopsSystemPluginUnloadPost:* ++nested call s:DenopsSystemPluginUnloadPost()
119+
autocmd User DenopsSystemPluginUnloadFail:* ++nested call s:DenopsSystemPluginUnloadFail()
68120
autocmd User DenopsClosed let s:plugins = {}
69121
augroup END

autoload/denops/_internal/rpc/nvim.vim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ endfunction
2424
function! denops#_internal#rpc#nvim#close(chan) abort
2525
call timer_stop(a:chan._healthcheck_timer)
2626
call chanclose(a:chan._id)
27-
call a:chan._on_close(a:chan)
27+
call timer_start(0, { -> a:chan._on_close(a:chan) })
2828
endfunction
2929

3030
function! denops#_internal#rpc#nvim#notify(chan, method, params) abort

autoload/denops/_internal/rpc/vim.vim

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,34 @@ function! denops#_internal#rpc#vim#connect(addr, ...) abort
33
\ 'on_close': { -> 0 },
44
\}, a:0 ? a:1 : {},
55
\)
6-
let l:chan = ch_open(a:addr, {
6+
let l:chan = {
7+
\ '_on_close': l:options.on_close,
8+
\}
9+
let l:chan._handle = ch_open(a:addr, {
710
\ 'mode': 'json',
811
\ 'drop': 'auto',
912
\ 'noblock': 1,
1013
\ 'timeout': g:denops#_internal#rpc#vim#timeout,
11-
\ 'close_cb': l:options.on_close,
14+
\ 'close_cb': { -> l:chan._on_close(l:chan) },
1215
\})
13-
if ch_status(l:chan) !=# 'open'
16+
if ch_status(l:chan._handle) !=# 'open'
1417
throw printf('Failed to connect `%s`', a:addr)
1518
endif
1619
return l:chan
1720
endfunction
1821

1922
function! denops#_internal#rpc#vim#close(chan) abort
20-
return ch_close(a:chan)
23+
" NOTE: 'close_cb' specified on `ch_open` is not invoked when `ch_close` called.
24+
call ch_close(a:chan._handle)
25+
call timer_start(0, { -> a:chan._on_close(a:chan) })
2126
endfunction
2227

2328
function! denops#_internal#rpc#vim#notify(chan, method, params) abort
24-
return ch_sendraw(a:chan, json_encode([0, [a:method] + a:params]) . "\n")
29+
return ch_sendraw(a:chan._handle, json_encode([0, [a:method] + a:params]) . "\n")
2530
endfunction
2631

2732
function! denops#_internal#rpc#vim#request(chan, method, params) abort
28-
let [l:ok, l:err] = ch_evalexpr(a:chan, [a:method] + a:params)
33+
let [l:ok, l:err] = ch_evalexpr(a:chan._handle, [a:method] + a:params)
2934
if l:err isnot# v:null
3035
throw l:err
3136
endif

0 commit comments

Comments
 (0)