// File: /workspace/github_c_makefile_star2_O0/justy989[P]ce/ce_app.c
// Function: apply_completion_to_buffer
bool apply_completion_to_buffer(CeComplete_t* complete,
                                CeBuffer_t* buffer,
                                int64_t start_x,
                                CePoint_t* cursor){
     if(complete->current < 0){
          return false;
     }

     // Do we even need completion ?
     int64_t completion_len = strlen(complete->elements[complete->current].string);
     int64_t input_len = strlen(buffer->lines[cursor->y] + start_x);
     int64_t input_offset = 0;
     if(input_len > completion_len) input_offset = input_len - completion_len;
     if(strcmp(complete->elements[complete->current].string, buffer->lines[cursor->y] + start_x + input_offset) == 0){
          return false;
     }

     // If the input text matches a later section of the current match, delete it.
     char* insertion = strdup(complete->elements[complete->current].string);
     int64_t insertion_len = strlen(insertion);
     CePoint_t delete_point = *cursor;
     int64_t delete_len = 0;
     if(complete->current_match){
          delete_len = strlen(complete->current_match);
          delete_point = ce_buffer_advance_point(buffer, *cursor, -delete_len);
          if(delete_len > 0){
               ce_buffer_remove_string_change(buffer, delete_point, delete_len, cursor, *cursor,
                                              false);
          }
     }

     // Insert the match from the start of the matching completion.
     CePoint_t cursor_end = {delete_point.x + insertion_len, delete_point.y};
     if(insertion_len > 0){
          // This chain is based on whether nor not the remove string change above was called.
          bool chain_undo = (complete->current_match && delete_len > 0);
          ce_buffer_insert_string_change(buffer, insertion, delete_point, cursor, cursor_end,
                                         chain_undo);
     }

     // Delete any previous match from after the cursor
     int64_t extra_len = strlen(buffer->lines[cursor->y] + cursor->x);
     char* extra = strdup(buffer->lines[cursor->y] + cursor->x);
     bool removed = false;
     for(int64_t i = extra_len; i > 0; i--){
          extra[i] = 0;
          for(int64_t c = 0; c < complete->count; c++){
               if(_str_endswith(complete->elements[c].string, extra)){
                    ce_buffer_remove_string_change(buffer, *cursor, i, cursor, cursor_end, true);
                    removed = true;
                    break;
               }
          }
          if(removed){
               break;
          }
     }
     free(extra);

     // We explicitly do not free insertion as its ownership was given to
     // ce_buffer_insert_string_change().

     return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jge 0x15e8f
movb $0x0, -0x1(%rbp)
jmp 0x161e1
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
imulq $0x18, 0x18(%rcx), %rcx
addq %rcx, %rax
movq (%rax), %rdi
callq 0xd200
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq -0x28(%rbp), %rcx
movq 0x8(%rcx), %rcx
movq (%rax,%rcx,8), %rdi
addq -0x20(%rbp), %rdi
callq 0xd200
movq %rax, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x30(%rbp), %rax
jle 0x15eec
movq -0x38(%rbp), %rax
subq -0x30(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
imulq $0x18, 0x18(%rcx), %rcx
addq %rcx, %rax
movq (%rax), %rdi
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq -0x28(%rbp), %rcx
movq 0x8(%rcx), %rcx
movq (%rax,%rcx,8), %rsi
addq -0x20(%rbp), %rsi
addq -0x40(%rbp), %rsi
callq 0xd370
cmpl $0x0, %eax
jne 0x15f30
movb $0x0, -0x1(%rbp)
jmp 0x161e1
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
imulq $0x18, 0x18(%rcx), %rcx
addq %rcx, %rax
movq (%rax), %rdi
callq 0xd620
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
callq 0xd200
movq %rax, -0x50(%rbp)
movq -0x28(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x60(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0x58(%rbp)
movq $0x0, -0x68(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x15ffe
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xd200
movq %rax, -0x68(%rbp)
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rax
xorl %ecx, %ecx
subq -0x68(%rbp), %rcx
movq (%rax), %rsi
movq 0x8(%rax), %rdx
callq 0xfaf0
movq %rax, -0x78(%rbp)
movq %rdx, -0x70(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x68(%rbp)
jle 0x15ffc
movq -0x18(%rbp), %rdi
movq -0x68(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x28(%rbp), %rax
movq -0x60(%rbp), %rsi
movq -0x58(%rbp), %rdx
xorl %r9d, %r9d
movq (%rax), %r10
movq %r10, (%rsp)
movq 0x8(%rax), %rax
movq %rax, 0x8(%rsp)
callq 0x110a0
jmp 0x15ffe
movq -0x60(%rbp), %rax
addq -0x50(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x80(%rbp)
cmpq $0x0, -0x50(%rbp)
jle 0x16087
movq -0x10(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0xb9(%rbp)
je 0x1603d
cmpq $0x0, -0x68(%rbp)
setg %al
movb %al, -0xb9(%rbp)
movb -0xb9(%rbp), %al
andb $0x1, %al
movb %al, -0x89(%rbp)
movq -0x18(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x28(%rbp), %r8
movb -0x89(%rbp), %al
movq -0x60(%rbp), %rdx
movq -0x58(%rbp), %rcx
leaq -0x88(%rbp), %r9
andb $0x1, %al
movq (%r9), %r10
movq %r10, (%rsp)
movq 0x8(%r9), %r9
movq %r9, 0x8(%rsp)
movzbl %al, %r9d
callq 0x10da0
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq -0x28(%rbp), %rcx
movq 0x8(%rcx), %rcx
movq (%rax,%rcx,8), %rdi
movq -0x28(%rbp), %rax
addq (%rax), %rdi
callq 0xd200
movq %rax, -0x98(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq -0x28(%rbp), %rcx
movq 0x8(%rcx), %rcx
movq (%rax,%rcx,8), %rdi
movq -0x28(%rbp), %rax
addq (%rax), %rdi
callq 0xd620
movq %rax, -0xa0(%rbp)
movb $0x0, -0xa1(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0xb0(%rbp)
cmpq $0x0, -0xb0(%rbp)
jle 0x161d1
movq -0xa0(%rbp), %rax
movq -0xb0(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq $0x0, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jge 0x161ad
movq -0x10(%rbp), %rax
movq (%rax), %rax
imulq $0x18, -0xb8(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rdi
movq -0xa0(%rbp), %rsi
callq 0x15df0
testb $0x1, %al
jne 0x1614f
jmp 0x16194
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rax
movq -0xb0(%rbp), %rcx
movq -0x28(%rbp), %r8
movq (%rax), %rsi
movq 0x8(%rax), %rdx
leaq -0x88(%rbp), %rax
movl $0x1, %r9d
movq (%rax), %r10
movq %r10, (%rsp)
movq 0x8(%rax), %rax
movq %rax, 0x8(%rsp)
callq 0x110a0
movb $0x1, -0xa1(%rbp)
jmp 0x161ad
jmp 0x16196
movq -0xb8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xb8(%rbp)
jmp 0x16113
testb $0x1, -0xa1(%rbp)
je 0x161b8
jmp 0x161d1
jmp 0x161ba
movq -0xb0(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0xb0(%rbp)
jmp 0x160e8
movq -0xa0(%rbp), %rdi
callq 0xd090
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xd0, %rsp
popq %rbp
retq
nop