void UpdateDebugBuffer() {
    Buffer *buffer = GetBuffer(DebugBufferID);

    Window *window = GetActiveWind();
    View   *view   = GetView(window->active_view);
    if (view->active_buffer.id == buffer->id.id) return;

    BSet main = GetBSet(LastActiveLayoutWindowID);

    Scratch  scratch;
    String   s      = Format(scratch, "wid: %d\nvid: %d\nbid: %d\nframe: %lld\n", (int)main.window->id.id, (int)main.view->id.id, (int)main.buffer->id.id, (long long)FrameID);
    String16 string = ToString16(scratch, s);
    RawReplaceText(buffer, GetRange(buffer), string);

    float xmouse, ymouse;
    SDL_GetMouseState(&xmouse, &ymouse);
    RawAppendf(buffer, "mouse: [%f, %f]\n", xmouse, ymouse);

    RawAppendf(buffer, "BufferID id = %d\n", main.buffer->id.id);
    RawAppendf(buffer, "String name = %S\n", main.buffer->name);
    RawAppendf(buffer, "Int change_id = %lld\n", (long long)main.buffer->change_id);
    RawAppendf(buffer, "Int user_change_id = %lld\n", (long long)main.buffer->user_change_id);
    RawAppendf(buffer, "Int file_mod_time = %lld\n", (long long)main.buffer->file_mod_time);
    RawAppendf(buffer, "\n");

    RawAppendf(buffer, "U16 *data = %zu\n", main.buffer->data);
    RawAppendf(buffer, "Int len = %lld\n", (long long)main.buffer->len);
    RawAppendf(buffer, "Int cap = %lld\n", (long long)main.buffer->cap);
    RawAppendf(buffer, "Array<Int> line_starts = {len = %lld, cap = %lld, data = %zu}\n", (long long)main.buffer->line_starts.len, (long long)main.buffer->line_starts.cap, main.buffer->line_starts.data);
    RawAppendf(buffer, "\n");

    RawAppendf(buffer, "Array<HistoryEntry> undo_stack = {len = %lld, cap = %lld, data = %zu}\n", (long long)main.buffer->undo_stack.len, (long long)main.buffer->undo_stack.cap, main.buffer->undo_stack.data);
    RawAppendf(buffer, "Array<HistoryEntry> redo_stack = {len = %lld, cap = %lld, data = %zu}\n", (long long)main.buffer->redo_stack.len, (long long)main.buffer->redo_stack.cap, main.buffer->redo_stack.data);
    RawAppendf(buffer, "int edit_phase = %d", main.buffer->edit_phase);
    RawAppendf(buffer, "\n");

    RawAppendf(buffer, "int no_history = %d\n", main.buffer->no_history);
    RawAppendf(buffer, "int no_line_starts = %d\n", main.buffer->no_line_starts);
    RawAppendf(buffer, "int dirty = %d\n", main.buffer->dirty);
    RawAppendf(buffer, "int changed_on_disk = %d\n", main.buffer->changed_on_disk);
    RawAppendf(buffer, "int garbage = %d\n", main.buffer->garbage);
}

void StatusBarUpdate() {
    Window *status_bar_window = GetWindow(StatusBarWindowID, NULL);
    if (status_bar_window == NULL) {
        return;
    }

    Scratch scratch;
    BSet main = GetBSet(LastActiveLayoutWindowID);
    BSet title = GetBSet(status_bar_window);
    title.view->scroll.y = 0;

    String16 buffer_string = GetString(title.buffer);
    Range replace_range = {0, title.buffer->len};
    bool found_separator = Seek(buffer_string, u" |", &replace_range.max);

    // Parse the title and line
    if (title.window->id == ActiveWindowID) {
        if (title.buffer->change_id == title.window->status_bar_last_buffer_change_id) {
            return;
        }
        String16 buffer_name = GetString(title.buffer, replace_range);
        buffer_name = Skip(buffer_name, 1);
        buffer_name = Trim(buffer_name);

        Int column = ChopNumber(&buffer_name);
        if (column == -1) return;

        Int line = ChopNumber(&buffer_name);
        if (line == -1) {
            line   = column;
            column = 0;
        }

        Int buffer_pos = XYToPos(main.buffer, {column, line});
        Caret &caret = main.view->carets[0];
        if (GetFront(caret) != buffer_pos) {
            caret = MakeCaret(buffer_pos);
        }
        title.window->status_bar_last_buffer_change_id = title.buffer->change_id;
        return;
    }

    Caret   caret = main.view->carets[0];
    XY      xy    = PosToXY(main.buffer, GetFront(caret));

    // add separator at the end of buffer
    if (!found_separator) {
        SelectRange(title.view, GetBufferEndAsRange(title.buffer));
        Array<Edit> edits = ReplaceEx(scratch, title.view, u" |");
    }


    // replace data up to separator with filename and stuff
    const char *reopen = main.buffer->changed_on_disk ? " Reopen()" : "";
    String s = Format(scratch, "# %S:%lld:%lld%s", main.buffer->name, (long long)xy.line + 1ll, (long long)xy.col + 1ll, reopen);
    For (ActiveProcesses) {
        if (it.view_id == main.view->id.id) {
            s = Format(scratch, "%S %lld Kill()", s, (long long)it.id);
        }
    }

    String16 string            = ToString16(scratch, s);
    String16 string_to_replace = GetString(title.buffer, replace_range);
    if (string_to_replace != string) {
        SelectRange(title.view, replace_range);
        Array<Edit> edits = ReplaceEx(scratch, title.view, string);
    }

    SelectRange(title.view, MakeRange(0));
    ResetHistory(title.buffer);
}