Function: make-local-variable

make-local-variable is an interactive function defined in data.c.

Signature

(make-local-variable VARIABLE)

Documentation

Make VARIABLE have a separate value in the current buffer.

Other buffers will continue to share a common default value.
(The buffer-local value of VARIABLE starts out as the same value
VARIABLE previously had. If VARIABLE was void, it remains void.) Return VARIABLE.

If the variable is already arranged to become local when set, this function causes a local value to exist for this buffer, just as setting the variable would do.

This function returns VARIABLE, and therefore
  (set (make-local-variable 'VARIABLE) VALUE-EXP)
works.

See also make-variable-buffer-local.

Do not use make-local-variable to make a hook variable buffer-local. Instead, use add-hook and specify t for the LOCAL argument.

View in manual

Probably introduced at or before Emacs version 21.1.

Key Bindings

Source Code

// Defined in /usr/src/emacs/src/data.c
{
  Lisp_Object tem;
  bool forwarded UNINIT;
  union Lisp_Val_Fwd valcontents UNINIT;
  struct Lisp_Symbol *sym;
  struct Lisp_Buffer_Local_Value *blv = NULL;

  CHECK_SYMBOL (variable);
  sym = XSYMBOL (variable);

 start:
  switch (sym->u.s.redirect)
    {
    case SYMBOL_VARALIAS: sym = SYMBOL_ALIAS (sym); goto start;
    case SYMBOL_PLAINVAL:
      forwarded = 0; valcontents.value = SYMBOL_VAL (sym); break;
    case SYMBOL_LOCALIZED:
      blv = SYMBOL_BLV (sym);
      break;
    case SYMBOL_FORWARDED:
      forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym);
      if (KBOARD_OBJFWDP (valcontents.fwd))
	error ("Symbol %s may not be buffer-local",
	       SDATA (SYMBOL_NAME (variable)));
      break;
    default: emacs_abort ();
    }

  if (sym->u.s.trapped_write == SYMBOL_NOWRITE)
    xsignal1 (Qsetting_constant, variable);

  if (!blv)
    {
      if (forwarded && BUFFER_OBJFWDP (valcontents.fwd))
        {
          int offset = XBUFFER_OBJFWD (valcontents.fwd)->offset;
          int idx = PER_BUFFER_IDX (offset);
          eassert (idx);
          if (idx > 0)
            /* If idx < 0, it's always buffer local, like `mode-name`.  */
            SET_PER_BUFFER_VALUE_P (current_buffer, idx, true);
          return variable;
        }
      blv = make_blv (sym, forwarded, valcontents);
      sym->u.s.redirect = SYMBOL_LOCALIZED;
      SET_SYMBOL_BLV (sym, blv);
    }

  /* Make sure this buffer has its own value of symbol.  */
  XSETSYMBOL (variable, sym);	/* Update in case of aliasing.  */
  tem = assq_no_quit (variable, BVAR (current_buffer, local_var_alist));
  if (NILP (tem))
    {
      if (let_shadows_buffer_binding_p (sym))
	{
	  AUTO_STRING (format,
		       "Making %s buffer-local while locally let-bound!");
	  CALLN (Fmessage, format, SYMBOL_NAME (variable));
	}

      if (BUFFERP (blv->where) && current_buffer == XBUFFER (blv->where))
        /* Make sure the current value is permanently recorded, if it's the
           default value.  */
        swap_in_global_binding (sym);

      bset_local_var_alist
	(current_buffer,
	 Fcons (Fcons (variable, XCDR (blv->defcell)),
		BVAR (current_buffer, local_var_alist)));

      /* If the symbol forwards into a C variable, then load the binding
         for this buffer now, to preserve the invariant that forwarded
         variables must always hold the value corresponding to the
         current buffer (they are swapped eagerly).
         Otherwise, if C code modifies the variable before we load the
         binding in, then that new value would clobber the default binding
         the next time we unload it.  See bug#34318.  */
      if (blv->fwd.fwdptr)
        swap_in_symval_forwarding (sym, blv);
    }

  return variable;
}