<commit_before>let s:save_cpo = &cpo
set cpo&vim

let s:lsp_clients = {} " { id, opts, req_seq, on_notifications: { request, on_notification }, stdout: { max_buffer_size, buffer, content_length, headers } }
let s:lsp_default_max_buffer = -1

let s:lsp_text_document_sync_kind_none = 0
let s:lsp_text_document_sync_kind_full = 1
let s:lsp_text_document_sync_kind_incremental = 2

function! s:trim(str) abort
  return matchstr(a:str,'^\s*\zs.\{-}\ze\s*$')
endfunction

function! s:_on_lsp_stdout(id, data, event) abort
    if has_key(s:lsp_clients, a:id)
        let l:client = s:lsp_clients[a:id]

        let l:client.stdout.buffer .= join(a:data, "\n")

        if l:client.stdout.max_buffer_size != -1 && len(l:client.stdout.buffer) > l:client.stdout.max_buffer_size
            echom 'lsp: reached max buffer size'
            call async#job#stop(a:id)
        endif

        while 1
            if l:client.stdout.content_length == -1         " if content-length is -1 we haven't parsed the headers
                " wait for all the headers to arrive
                let l:header_end_index = stridx(l:client.stdout.buffer, "\r\n\r\n")
                if l:header_end_index >= 0
                    for l:header in split(l:client.stdout.buffer[:l:header_end_index - 1], "\r\n")
                        let l:header_key_value_seperator = stridx(l:header, ":")
                        let l:header_key = s:trim(l:header[:l:header_key_value_seperator - 1])
                        let l:header_value = s:trim(l:header[l:header_key_value_seperator + 1:])
                        if l:header_key ==? 'Content-Length'
                            let l:client.stdout.content_length = str2nr(l:header_value, 10)
                        endif
                        let l:client.stdout.headers[l:header_key] = s:trim(l:header_value)
                    endfor
                    let l:client.stdout.buffer = l:client.stdout.buffer[l:header_end_index + 4:]
                    continue
                else
                    " wait for next buffer to arrive
                    break
                endif
            else
                if len(l:client.stdout.buffer) >= l:client.stdout.content_length
                    " we have the full message
                    let l:response_str = l:client.stdout.buffer[:l:client.stdout.content_length - 1]
                    let l:client.stdout.buffer = l:client.stdout.buffer[l:client.stdout.content_length:]
                    let l:client.stdout.content_length = -1 " reset since we are done reading the current message
                    let l:response_msg = json_decode(l:response_str)
                    if has_key(l:response_msg, 'id')
                        let l:on_notification_data = { 'response': l:response_msg }
                        if has_key(l:client.on_notifications, l:response_msg.id)
                            " requests are absent for server instantiated events
                            let l:on_notification_data.request = l:client.on_notifications[l:response_msg.id].request
                        endif
                        if has_key(l:client.opts, 'on_notification')
                            call l:client.opts.on_notification(a:id, l:on_notification_data, 'on_notification')
                        endif
                        if has_key(l:client.on_notifications, 'on_notification')
                            call l:client.on_notifications[l:response_msg.id](a:id, l:on_notification_data, 'on_notification')
                        endif
                        if has_key(l:client.on_notifications, l:response_msg.id)
                            " requests are absent for server instantiated events
                            call remove(l:client.on_notifications, l:response_msg.id)
                        endif
                    endif
                    if len(l:client.stdout.buffer) > 0
                        " we have more data in the buffer so try parsing the new headers from top
                        continue
                    else
                        " we are done processing the message here so stop
                        break
                    endif
                else
                    " we don't have the entire message body, so wait for the next buffer
                    break
                endif
            endif
        endwhile
    endif<commit_msg>correctly call send on_notification callback<commit_after>let s:save_cpo = &cpo
set cpo&vim

let s:lsp_clients = {} " { id, opts, req_seq, on_notifications: { 'req_seq': { request, on_notification } }, stdout: { max_buffer_size, buffer, content_length, headers } }
let s:lsp_default_max_buffer = -1

let s:lsp_text_document_sync_kind_none = 0
let s:lsp_text_document_sync_kind_full = 1
let s:lsp_text_document_sync_kind_incremental = 2

function! s:trim(str) abort
  return matchstr(a:str,'^\s*\zs.\{-}\ze\s*$')
endfunction

function! s:_on_lsp_stdout(id, data, event) abort
    if has_key(s:lsp_clients, a:id)
        let l:client = s:lsp_clients[a:id]

        let l:client.stdout.buffer .= join(a:data, "\n")

        if l:client.stdout.max_buffer_size != -1 && len(l:client.stdout.buffer) > l:client.stdout.max_buffer_size
            echom 'lsp: reached max buffer size'
            call async#job#stop(a:id)
        endif

        while 1
            if l:client.stdout.content_length == -1         " if content-length is -1 we haven't parsed the headers
                " wait for all the headers to arrive
                let l:header_end_index = stridx(l:client.stdout.buffer, "\r\n\r\n")
                if l:header_end_index >= 0
                    for l:header in split(l:client.stdout.buffer[:l:header_end_index - 1], "\r\n")
                        let l:header_key_value_seperator = stridx(l:header, ":")
                        let l:header_key = s:trim(l:header[:l:header_key_value_seperator - 1])
                        let l:header_value = s:trim(l:header[l:header_key_value_seperator + 1:])
                        if l:header_key ==? 'Content-Length'
                            let l:client.stdout.content_length = str2nr(l:header_value, 10)
                        endif
                        let l:client.stdout.headers[l:header_key] = s:trim(l:header_value)
                    endfor
                    let l:client.stdout.buffer = l:client.stdout.buffer[l:header_end_index + 4:]
                    continue
                else
                    " wait for next buffer to arrive
                    break
                endif
            else
                if len(l:client.stdout.buffer) >= l:client.stdout.content_length
                    " we have the full message
                    let l:response_str = l:client.stdout.buffer[:l:client.stdout.content_length - 1]
                    let l:client.stdout.buffer = l:client.stdout.buffer[l:client.stdout.content_length:]
                    let l:client.stdout.content_length = -1 " reset since we are done reading the current message
                    let l:response_msg = json_decode(l:response_str)
                    if has_key(l:response_msg, 'id')
                        let l:on_notification_data = { 'response': l:response_msg }
                        if has_key(l:client.on_notifications, l:response_msg.id)
                            " requests are absent for server instantiated events
                            let l:on_notification_data.request = l:client.on_notifications[l:response_msg.id].request
                        endif
                        if has_key(l:client.opts, 'on_notification')
                            " call the client's on_notification
                            call l:client.opts.on_notification(a:id, l:on_notification_data, 'on_notification')
                        endif
                        if has_key(l:client.on_notifications, l:response_msg.id) && has_key(l:client.on_notifications[l:response_msg.id], 'on_notification')
                            " call on notification registered during send
                            call l:client.on_notifications[l:response_msg.id].on_notification(a:id, l:on_notification_data, 'on_notification')
                        endif
                        if has_key(l:client.on_notifications, l:response_msg.id)
                            " requests are absent for server instantiated events
                            call remove(l:client.on_notifications, l:response_msg.id)
                        endif
                    endif
                    if len(l:client.stdout.buffer) > 0
                        " we have more data in the buffer so try parsing the new headers from top
                        continue
                    else
                        " we are done processing the message here so stop
                        break
                    endif
                else
                    " we don't have the entire message body, so wait for the next buffer
                    break
                endif
            endif
        endwhile
    endif
{'fraction_non_alphanumeric': 0.0845288015890532, 'fraction_numerical': 0.004193334804678879, 'mean_word_length': 1.6368926389292988, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3189212', 'n_tokens_mistral': 2601, 'n_tokens_neox': 2435, 'n_words': 554}