⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buffer.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Buffer manipulation primitives for GNU Emacs.   Copyright (C) 1985, 1986, 1987, 1988, 1990 Free Software Foundation, Inc.This file is part of GNU Emacs.GNU Emacs is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GNU Emacs is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Emacs; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */#include <sys/param.h>#ifndef MAXPATHLEN/* in 4.1, param.h fails to define this. */#define MAXPATHLEN 1024#endif /* not MAXPATHLEN */#ifdef NULL#undef NULL#endif#include "config.h"#include "lisp.h"#include "window.h"#include "commands.h"#include "buffer.h"#include "syntax.h"struct buffer *current_buffer;		/* the current buffer *//* First buffer in chain of all buffers (in reverse order of creation).   Threaded through ->next.  */struct buffer *all_buffers;/* This structure holds the default values of the buffer-local variables   defined with DEFVAR_PER_BUFFER, that have special slots in each buffer.   The default value occupies the same slot in this structure   as an individual buffer's value occupies in that buffer.   Setting the default value also goes through the alist of buffers   and stores into each buffer that does not say it has a local value.  */struct buffer buffer_defaults;/* A Lisp_Object pointer to the above, used for staticpro */static Lisp_Object Vbuffer_defaults;/* This structure marks which slots in a buffer have corresponding   default values in buffer_defaults.   Each such slot has a nonzero value in this structure.   The value has only one nonzero bit.   When a buffer has its own local value for a slot,   the bit for that slot (found in the same slot in this structure)   is turned on in the buffer's local_var_flags slot.   If a slot in this structure is -1, then even though there may   be a DEFVAR_PER_BUFFER for the slot, there is no default value for it;   and the corresponding slot in buffer_defaults is not used.   If a slot is -2, then there is no DEFVAR_PER_BUFFER for it,   but there is a default value which is copied into each buffer.   If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is   zero, that is a bug */struct buffer buffer_local_flags;/* This structure holds the names of symbols whose values may be   buffer-local.  It is indexed and accessed in the same way as the above. */struct buffer buffer_local_symbols;/* A Lisp_Object pointer to the above, used for staticpro */static Lisp_Object Vbuffer_local_symbols;Lisp_Object Fset_buffer ();/* Alist of all buffer names vs the buffers. *//* This used to be a variable, but is no longer, to prevent lossage due to user rplac'ing this alist or its elements.  */Lisp_Object Vbuffer_alist;Lisp_Object Qfundamental_mode, Qmode_class;Lisp_Object QSFundamental;	/* A string "Fundamental" *//* For debugging; temporary.  See set_buffer_internal.  *//* Lisp_Object Qlisp_mode, Vcheck_symbol; */nsberror (spec)     Lisp_Object spec;{  if (XTYPE (spec) == Lisp_String)    error ("No buffer named %s", XSTRING (spec)->data);  error ("Invalid buffer argument");}DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 0, 0,  "Return a list of all buffers.")  (){  return Fmapcar (Qcdr, Vbuffer_alist);}DEFUN ("get-buffer", Fget_buffer, Sget_buffer, 1, 1, 0,  "Return the buffer named NAME (a string).\n\It is found by looking up NAME in  buffer-alist.\n\If there is no buffer named NAME, nil is returned.\n\NAME may also be a buffer; it is returned.")  (name)     register Lisp_Object name;{  if (XTYPE (name) == Lisp_Buffer)    return name;  CHECK_STRING (name, 0);  return Fcdr (Fassoc (name, Vbuffer_alist));}DEFUN ("get-file-buffer", Fget_file_buffer, Sget_file_buffer, 1, 1, 0,  "Return the buffer visiting file FILENAME (a string).\n\If there is no such buffer, nil is returned.")  (filename)     register Lisp_Object filename;{  register Lisp_Object tail, buf, tem;  CHECK_STRING (filename, 0);  filename = Fexpand_file_name (filename, Qnil);  for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)    {      buf = Fcdr (XCONS (tail)->car);      if (XTYPE (buf) != Lisp_Buffer) continue;      if (XTYPE (XBUFFER (buf)->filename) != Lisp_String) continue;      tem = Fstring_equal (XBUFFER (buf)->filename, filename);      if (!NULL (tem))	return buf;    }  return Qnil;}DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 1, 0,  "Like get-buffer but creates a buffer named NAME and returns it if none already exists.")  (name)     register Lisp_Object name;{  register Lisp_Object buf, function, tem;  int count = specpdl_ptr - specpdl;  register struct buffer *b;  register unsigned char *data;  /* register struct buffer *bx; */  buf = Fget_buffer (name);  if (!NULL (buf)) return buf;  b = (struct buffer *) malloc (sizeof (struct buffer));  if (!b) memory_full ();  BUF_GAP_SIZE (b) = 20;  data = (unsigned char *) malloc (BUF_GAP_SIZE (b));  if (!data)    {      free (b);      memory_full ();    }  BUF_BEG_ADDR (b) = data;  BUF_PT (b) = 1;  BUF_GPT (b) = 1;  BUF_BEGV (b) = 1;  BUF_ZV (b) = 1;  BUF_Z (b) = 1;  BUF_MODIFF (b) = 1;  /* Put this on the chain of all buffers including killed ones.  */  b->next = all_buffers;  all_buffers = b;  /* Put this in the alist of all live buffers.  */  XSET (buf, Lisp_Buffer, b);#if 0  XSETTYPE (buf, Lisp_Buffer);  bx = b;			/* Use of bx avoids compiler bug on Sun */  XSETBUFFER (buf, bx);#endif  Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil));  b->mark = Fmake_marker ();  b->markers = Qnil;  b->name = name;  /* Enable undo in this buffer unless name starts with a space.  */  if (XSTRING (name)->data[0] != ' ')    b->undo_list = Qnil;  else    b->undo_list = Qt;  reset_buffer (b);  function = buffer_defaults.major_mode;  if (NULL (function))    {      tem = Fget (current_buffer->major_mode, Qmode_class);      if (EQ (tem, Qnil))	function = current_buffer->major_mode;    }  if (NULL (function) || EQ (function, Qfundamental_mode))    return buf;  /* To select a nonfundamental mode,     select the buffer temporarily and then call the mode function. */  record_unwind_protect (save_excursion_restore, save_excursion_save ());  Fset_buffer (buf);  call0 (function);  unbind_to (count);  return buf;}/* Reinitialize everything about a buffer except its name and contents.  */voidreset_buffer (b)     register struct buffer *b;{  b->filename = Qnil;  b->directory = (current_buffer) ? current_buffer->directory : Qnil;  b->modtime = 0;  b->save_modified = 1;  b->save_length = 0;  b->last_window_start = 1;  b->backed_up = Qnil;  b->auto_save_modified = 0;  b->auto_save_file_name = Qnil;  b->read_only = Qnil;  reset_buffer_local_variables(b);}reset_buffer_local_variables(b)     register struct buffer *b;{  register int offset;  /* Reset the major mode to Fundamental, together with all the     things that depend on the major mode.     default-major-mode is handled at a higher level.     We ignore it here.  */  b->major_mode = Qfundamental_mode;  b->keymap = Qnil;  b->abbrev_table = Vfundamental_mode_abbrev_table;  b->mode_name = QSFundamental;  /* Reset all per-buffer variables to their defaults.  */  b->local_var_alist = Qnil;  b->local_var_flags = 0;  /* For each slot that has a default value,     copy that into the slot.  */  for (offset = (char *)&buffer_local_flags.name - (char *)&buffer_local_flags;       offset < sizeof (struct buffer);       offset += sizeof (Lisp_Object)) /* sizeof int == sizeof Lisp_Object */    if (*(int *)(offset + (char *) &buffer_local_flags) > 0	|| *(int *)(offset + (char *) &buffer_local_flags) == -2)      *(Lisp_Object *)(offset + (char *)b) =		*(Lisp_Object *)(offset + (char *)&buffer_defaults);}DEFUN ("generate-new-buffer", Fgenerate_new_buffer, Sgenerate_new_buffer,  1, 1, 0,  "Creates and returns a buffer named NAME if one does not already exist,\n\else tries adding successive suffixes to NAME until a new buffer-name is\n\formed, then creates and returns a new buffer with that new name.") (name)     register Lisp_Object name;{  register Lisp_Object gentemp, tem;  int count;  char number[10];  CHECK_STRING (name, 0);  tem = Fget_buffer (name);  if (NULL (tem))    return Fget_buffer_create (name);  count = 1;  while (1)    {      sprintf (number, "<%d>", ++count);      gentemp = concat2 (name, build_string (number));      tem = Fget_buffer (gentemp);      if (NULL (tem))	return Fget_buffer_create (gentemp);    }}DEFUN ("buffer-name", Fbuffer_name, Sbuffer_name, 0, 1, 0,  "Return the name of BUFFER, as a string.\n\No arg means return name of current buffer.")  (buffer)     register Lisp_Object buffer;{  if (NULL (buffer))    return current_buffer->name;  CHECK_BUFFER (buffer, 0);  return XBUFFER (buffer)->name;}#ifdef NOTDEF /* Useless. If you need this, you should be using `eq'  DEFUN ("buffer-number", Fbuffer_number, Sbuffer_number, 0, 1, 0,    "Return the number of BUFFER.\n\  No arg means return number of current buffer.")    (buffer)       Lisp_Object buffer;  {    if (NULL (buffer))      return current_buffer->number;    CHECK_BUFFER (buffer, 0);    return XBUFFER (buffer)->number;  } */#endif NOTDEFDEFUN ("buffer-file-name", Fbuffer_file_name, Sbuffer_file_name, 0, 1, 0,  "Return name of file BUFFER is visiting, or NIL if none.\n\No argument means use current buffer as BUFFER.")  (buffer)     register Lisp_Object buffer;{  if (NULL (buffer))    return current_buffer->filename;  CHECK_BUFFER (buffer, 0);  return XBUFFER (buffer)->filename;}DEFUN ("buffer-local-variables", Fbuffer_local_variables,  Sbuffer_local_variables, 0, 1, 0,  "Return alist of variables that are buffer-local in BUFFER.\n\No argument means use current buffer as BUFFER.\n\Each element of the value looks like (SYMBOL . VALUE).\n\Note that storing new VALUEs in these elements\n\does not change the local values.")  (buffer)     register Lisp_Object buffer;{  register struct buffer *buf;  register Lisp_Object val;  if (NULL (buffer))    buf = current_buffer;  else    {      CHECK_BUFFER (buffer, 0);      buf = XBUFFER (buffer);    }  {    /* Reference each variable in the alist in our current buffer.       If inquiring about the current buffer, this gets the current values,       so store them into the alist so the alist is up to date.       If inquiring about some other buffer, this swaps out any values       for that buffer, making the alist up to date automatically.  */    register Lisp_Object tem;    for (tem = buf->local_var_alist; CONSP (tem); tem = XCONS (tem)->cdr)      {	Lisp_Object v1 = Fsymbol_value (XCONS (XCONS (tem)->car)->car);	if (buf == current_buffer)	  XCONS (XCONS (tem)->car)->cdr = v1;      }  }  /* Make a copy of the alist, to return it.  */  val = Fcopy_alist (buf->local_var_alist);  /* Add on all the variables stored in special slots.  */  {    register int offset, mask;    for (offset = (char *)&buffer_local_symbols.name - (char *)&buffer_local_symbols;	 offset < sizeof (struct buffer);	 offset += (sizeof (int))) /* sizeof int == sizeof Lisp_Object */      {	mask = *(int *)(offset + (char *) &buffer_local_flags);	if (mask == -1 || (buf->local_var_flags & mask))	  val = Fcons (Fcons (*(Lisp_Object *)(offset + (char *)&buffer_local_symbols),			      *(Lisp_Object *)(offset + (char *)buf)),		       val);      }  }  return (val);}DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p,  0, 1, 0,  "Return t if BUFFER is modified since file last read in or saved.\n\No argument means use current buffer as BUFFER.")  (buffer)     register Lisp_Object buffer;{  register struct buffer *buf;  if (NULL (buffer))    buf = current_buffer;  else    {      CHECK_BUFFER (buffer, 0);      buf = XBUFFER (buffer);    }  return buf->save_modified < BUF_MODIFF (buf) ? Qt : Qnil;}DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p,  1, 1, 0,  "Mark current buffer as modified or unmodified according to FLAG.")  (flag)     register Lisp_Object flag;{  register int already;  register Lisp_Object fn;#ifdef CLASH_DETECTION  /* If buffer becoming modified, lock the file.     If buffer becoming unmodified, unlock the file.  */  fn = current_buffer->filename;  if (!NULL (fn))    {      already = current_buffer->save_modified < MODIFF;      if (!already && !NULL (flag))	lock_file (fn);      else if (already && NULL (flag))	unlock_file (fn);    }#endif /* CLASH_DETECTION */  current_buffer->save_modified = NULL (flag) ? MODIFF : 0;  update_mode_lines++;  return flag;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -