window.vim 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. let g:coc_max_treeview_width = get(g:, 'coc_max_treeview_width', 40)
  2. let s:is_vim = !has('nvim')
  3. " Get tabpagenr of winid, return -1 if window doesn't exist
  4. function! coc#window#tabnr(winid) abort
  5. if exists('*nvim_win_get_tabpage')
  6. try
  7. return nvim_win_get_tabpage(a:winid)
  8. catch /Invalid window id/
  9. return -1
  10. endtry
  11. endif
  12. if exists('*win_execute')
  13. let ref = {}
  14. call win_execute(a:winid, 'let ref["out"] = tabpagenr()')
  15. return get(ref, 'out', -1)
  16. elseif !s:is_vim
  17. let info = getwininfo(a:winid)
  18. return empty(info) ? -1 : info[0]['tabnr']
  19. else
  20. throw 'win_execute() does not exist, please upgrade your vim.'
  21. endif
  22. endfunction
  23. function! coc#window#get_cursor(winid) abort
  24. if exists('*nvim_win_get_cursor')
  25. return nvim_win_get_cursor(a:winid)
  26. endif
  27. return coc#api#exec('win_get_cursor', [a:winid])
  28. endfunction
  29. " Check if winid visible on current tabpage
  30. function! coc#window#visible(winid) abort
  31. if s:is_vim
  32. if coc#window#tabnr(a:winid) != tabpagenr()
  33. return 0
  34. endif
  35. " Check possible hidden popup
  36. try
  37. return get(popup_getpos(a:winid), 'visible', 0) == 1
  38. catch /^Vim\%((\a\+)\)\=:E993/
  39. return 1
  40. endtry
  41. endif
  42. if !nvim_win_is_valid(a:winid)
  43. return 0
  44. endif
  45. return coc#window#tabnr(a:winid) == tabpagenr()
  46. endfunction
  47. " Return v:null when name or window doesn't exist,
  48. " 'getwinvar' only works on window of current tab
  49. function! coc#window#get_var(winid, name, ...) abort
  50. if !s:is_vim
  51. try
  52. if a:name =~# '^&'
  53. return nvim_win_get_option(a:winid, a:name[1:])
  54. else
  55. return nvim_win_get_var(a:winid, a:name)
  56. endif
  57. catch /E5555/
  58. return get(a:, 1, v:null)
  59. endtry
  60. else
  61. try
  62. return coc#api#exec('win_get_var', [a:winid, a:name, get(a:, 1, v:null)])
  63. catch /.*/
  64. return get(a:, 1, v:null)
  65. endtry
  66. endif
  67. endfunction
  68. " Not throw like setwinvar
  69. function! coc#window#set_var(winid, name, value) abort
  70. try
  71. if !s:is_vim
  72. if a:name =~# '^&'
  73. call nvim_win_set_option(a:winid, a:name[1:], a:value)
  74. else
  75. call nvim_win_set_var(a:winid, a:name, a:value)
  76. endif
  77. else
  78. call coc#api#exec('win_set_var', [a:winid, a:name, a:value])
  79. endif
  80. catch /Invalid window id/
  81. " ignore
  82. endtry
  83. endfunction
  84. function! coc#window#is_float(winid) abort
  85. if s:is_vim
  86. if exists('*popup_list')
  87. return index(popup_list(), a:winid) != -1
  88. else
  89. try
  90. return !empty(popup_getpos(a:winid))
  91. catch /^Vim\%((\a\+)\)\=:E993/
  92. return 0
  93. endtry
  94. endif
  95. return 0
  96. elseif exists('*nvim_win_get_config')
  97. let config = nvim_win_get_config(a:winid)
  98. return !empty(config) && !empty(get(config, 'relative', ''))
  99. endif
  100. endfunction
  101. function! coc#window#set_height(winid, height) abort
  102. if empty(getwininfo(a:winid))
  103. return
  104. endif
  105. if exists('*nvim_win_set_height')
  106. call nvim_win_set_height(a:winid, a:height)
  107. else
  108. call coc#compat#execute(a:winid, 'noa resize '.a:height, 'silent')
  109. endif
  110. endfunction
  111. function! coc#window#adjust_width(winid) abort
  112. let bufnr = winbufnr(a:winid)
  113. if bufloaded(bufnr)
  114. let maxwidth = 0
  115. let lines = getbufline(bufnr, 1, '$')
  116. if len(lines) > 2
  117. call coc#compat#execute(a:winid, 'setl nowrap')
  118. for line in lines
  119. let w = strwidth(line)
  120. if w > maxwidth
  121. let maxwidth = w
  122. endif
  123. endfor
  124. endif
  125. if maxwidth > winwidth(a:winid)
  126. call coc#compat#execute(a:winid, 'vertical resize '.min([maxwidth, g:coc_max_treeview_width]))
  127. endif
  128. endif
  129. endfunction
  130. " Get single window by window variable, current tab only
  131. function! coc#window#find(key, val) abort
  132. for i in range(1, winnr('$'))
  133. let res = getwinvar(i, a:key)
  134. if res == a:val
  135. return win_getid(i)
  136. endif
  137. endfor
  138. return -1
  139. endfunction
  140. " Visible buffer numbers
  141. function! coc#window#bufnrs() abort
  142. let winids = []
  143. if exists('*nvim_list_wins')
  144. let winids = nvim_list_wins()
  145. else
  146. let winids = map(getwininfo(), 'v:val["winid"]')
  147. endif
  148. return uniq(map(winids, 'winbufnr(v:val)'))
  149. endfunction
  150. " Avoid errors
  151. function! coc#window#close(winid) abort
  152. if empty(a:winid) || a:winid == -1
  153. return
  154. endif
  155. if exists('*nvim_win_is_valid') && exists('*nvim_win_close')
  156. if nvim_win_is_valid(a:winid)
  157. call nvim_win_close(a:winid, 1)
  158. endif
  159. elseif exists('*win_execute')
  160. call coc#compat#execute(a:winid, 'noa close!', 'silent!')
  161. else
  162. let curr = win_getid()
  163. if curr == a:winid
  164. silent! close!
  165. else
  166. let res = win_gotoid(a:winid)
  167. if res
  168. silent! close!
  169. call win_gotoid(curr)
  170. endif
  171. endif
  172. endif
  173. endfunction
  174. function! coc#window#visible_range(bufnr) abort
  175. let winid = bufwinid(a:bufnr)
  176. if winid == -1
  177. return v:null
  178. endif
  179. let info = getwininfo(winid)[0]
  180. return [info['topline'], info['botline']]
  181. endfunction
  182. function! coc#window#visible_ranges(bufnr) abort
  183. let wins = gettabinfo(tabpagenr())[0]['windows']
  184. let res = []
  185. for id in wins
  186. let info = getwininfo(id)[0]
  187. if info['bufnr'] == a:bufnr
  188. call add(res, [info['topline'], info['botline']])
  189. endif
  190. endfor
  191. return res
  192. endfunction