1
0

cursor.vim 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. if exists('g:loaded_syntastic_notifier_cursor') || !exists('g:loaded_syntastic_plugin')
  2. finish
  3. endif
  4. let g:loaded_syntastic_notifier_cursor = 1
  5. let g:SyntasticCursorNotifier = {}
  6. " Public methods {{{1
  7. function! g:SyntasticCursorNotifier.New() abort " {{{2
  8. let newObj = copy(self)
  9. return newObj
  10. endfunction " }}}2
  11. function! g:SyntasticCursorNotifier.enabled() abort " {{{2
  12. return syntastic#util#var('echo_current_error')
  13. endfunction " }}}2
  14. function! g:SyntasticCursorNotifier.refresh(loclist) abort " {{{2
  15. if self.enabled() && !a:loclist.isEmpty()
  16. call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'cursor: refresh')
  17. let b:syntastic_private_messages = copy(a:loclist.messages(bufnr('')))
  18. let b:syntastic_private_line = -1
  19. let b:syntastic_cursor_columns = a:loclist.getCursorColumns()
  20. autocmd! syntastic CursorMoved
  21. autocmd syntastic CursorMoved * call SyntasticRefreshCursor()
  22. endif
  23. endfunction " }}}2
  24. " @vimlint(EVL103, 1, a:loclist)
  25. function! g:SyntasticCursorNotifier.reset(loclist) abort " {{{2
  26. call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'cursor: reset')
  27. autocmd! syntastic CursorMoved
  28. unlet! b:syntastic_private_messages
  29. let b:syntastic_private_line = -1
  30. endfunction " }}}2
  31. " @vimlint(EVL103, 0, a:loclist)
  32. " }}}1
  33. " Private functions {{{1
  34. function! SyntasticRefreshCursor() abort " {{{2
  35. if !exists('b:syntastic_private_messages') || empty(b:syntastic_private_messages)
  36. " file not checked
  37. return
  38. endif
  39. if !exists('b:syntastic_private_line')
  40. let b:syntastic_private_line = -1
  41. endif
  42. let l = line('.')
  43. let current_messages = get(b:syntastic_private_messages, l, {})
  44. if !exists('b:syntastic_cursor_columns')
  45. let b:syntastic_cursor_columns = g:syntastic_cursor_columns
  46. endif
  47. if b:syntastic_cursor_columns
  48. let c = virtcol('.')
  49. if !exists('b:syntastic_private_idx')
  50. let b:syntastic_private_idx = -1
  51. endif
  52. if s:_is_same_index(l, b:syntastic_private_line, c, b:syntastic_private_idx, current_messages)
  53. return
  54. else
  55. let b:syntastic_private_line = l
  56. endif
  57. if !empty(current_messages)
  58. let b:syntastic_private_idx = s:_find_index(c, current_messages)
  59. call syntastic#util#wideMsg(current_messages[b:syntastic_private_idx].text)
  60. else
  61. let b:syntastic_private_idx = -1
  62. echo
  63. endif
  64. else
  65. if l == b:syntastic_private_line
  66. return
  67. endif
  68. let b:syntastic_private_line = l
  69. if !empty(current_messages)
  70. call syntastic#util#wideMsg(current_messages[0].text)
  71. else
  72. echo
  73. endif
  74. endif
  75. endfunction " }}}2
  76. " }}}1
  77. " Utilities {{{1
  78. function! s:_is_same_index(line, old_line, column, idx, messages) abort " {{{2
  79. if a:old_line >= 0 && a:line == a:old_line && a:idx >= 0
  80. if len(a:messages) <= 1
  81. return 1
  82. endif
  83. if a:messages[a:idx].scol <= a:column || a:idx == 0
  84. if a:idx == len(a:messages) - 1 || a:column < a:messages[a:idx + 1].scol
  85. return 1
  86. else
  87. return 0
  88. endif
  89. else
  90. return 0
  91. endif
  92. else
  93. return 0
  94. endif
  95. endfunction " }}}2
  96. function! s:_find_index(column, messages) abort " {{{2
  97. let max = len(a:messages) - 1
  98. if max == 0
  99. return 0
  100. endif
  101. let min = 0
  102. " modified binary search: assign index 0 to columns to the left of the first error
  103. while min < max - 1
  104. let mid = (min + max) / 2
  105. if a:column < a:messages[mid].scol
  106. let max = mid
  107. else
  108. let min = mid
  109. endif
  110. endwhile
  111. return a:column < a:messages[max].scol ? min : max
  112. endfunction " }}}2
  113. " }}}1
  114. " vim: set sw=4 sts=4 et fdm=marker: