Repository: neovim/neovim
File: src/nvim/vterm/state.c (C)

Code before:
#include <assert.h>
#include <stdio.h>
#include <string.h>

#include "nvim/grid.h"
#include "nvim/mbyte.h"
#include "nvim/vterm/encoding.h"
#include "nvim/vterm/parser.h"
#include "nvim/vterm/pen.h"
#include "nvim/vterm/state.h"
#include "nvim/vterm/vterm.h"
#include "nvim/vterm/vterm_internal_defs.h"

#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "vterm/state.c.generated.h"
#endif

#define strneq(a, b, n) (strncmp(a, b, n) == 0)

// Primary Device Attributes (DA1) response.
// We make this a global (extern) variable so that we can override it with FFI
// in tests.
char vterm_primary_device_attr[] = "1;2;52";

// Some convenient wrappers to make callback functions easier

static void putglyph(VTermState *state, const schar_T schar, int width, VTermPos pos)
{
  VTermGlyphInfo info = {
    .schar = schar,
    .width = width,
    .protected_cell = state->protected_cell,
    .dwl = state->lineinfo[pos.row].doublewidth,
    .dhl = state->lineinfo[pos.row].doubleheight,
  };

  if (state->callbacks && state->callbacks->putglyph) {
    if ((*state->callbacks->putglyph)(&info, pos, state->cbdata)) {
      return;
    }
  }

  DEBUG_LOG("libvterm: Unhandled putglyph U+%04x at (%d,%d)\n", chars[0], pos.col, pos.row);
}

static void updatecursor(VTermState *state, VTermPos *oldpos, int cancel_phantom)
{
  if (state->pos.col == oldpos->col && state->pos.row == oldpos->row) {

Review comment (suggestion):
FYI, the `1;2` response is a device-specific format that predates DEC's standardization of the `DA` response. The second parameter is actually a bitfield value that represents extensions specific to the VT100 range of devices. It isn't expected to have additional parameters after it.

If you want to indicate a level-1 device using the _standard_ `DA` format, the first parameter should be `61`, and then any additional parameters represent the supported extensions. For example, a level-1 device with just the new clipboard extension would be `61;52`.

Probably not super important, though, since many apps that parse the `DA` response will likely ignore the first parameter anyway.

Code after:
#include <assert.h>
#include <stdio.h>
#include <string.h>

#include "nvim/grid.h"
#include "nvim/mbyte.h"
#include "nvim/vterm/encoding.h"
#include "nvim/vterm/parser.h"
#include "nvim/vterm/pen.h"
#include "nvim/vterm/state.h"
#include "nvim/vterm/vterm.h"
#include "nvim/vterm/vterm_internal_defs.h"

#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "vterm/state.c.generated.h"
#endif

#define strneq(a, b, n) (strncmp(a, b, n) == 0)

// Primary Device Attributes (DA1) response.
// We make this a global (extern) variable so that we can override it with FFI
// in tests.
char vterm_primary_device_attr[] = "61;22;52";

// Some convenient wrappers to make callback functions easier

static void putglyph(VTermState *state, const schar_T schar, int width, VTermPos pos)
{
  VTermGlyphInfo info = {
    .schar = schar,
    .width = width,
    .protected_cell = state->protected_cell,
    .dwl = state->lineinfo[pos.row].doublewidth,
    .dhl = state->lineinfo[pos.row].doubleheight,
  };

  if (state->callbacks && state->callbacks->putglyph) {
    if ((*state->callbacks->putglyph)(&info, pos, state->cbdata)) {
      return;
    }
  }

  DEBUG_LOG("libvterm: Unhandled putglyph U+%04x at (%d,%d)\n", chars[0], pos.col, pos.row);
}

static void updatecursor(VTermState *state, VTermPos *oldpos, int cancel_phantom)
{
  if (state->pos.col == oldpos->col && state->pos.row == oldpos->row) {