Mercurial > hg > xemacs-beta
comparison src/buffer.c @ 386:4af0ddfb7c5b r21-2-8
Import from CVS: tag r21-2-8
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:08:50 +0200 |
parents | 8626e4521993 |
children | aabb7f5b1c81 |
comparison
equal
deleted
inserted
replaced
385:bc48d89bf15c | 386:4af0ddfb7c5b |
---|---|
124 buffers and as a reset-value when local-vars are killed. */ | 124 buffers and as a reset-value when local-vars are killed. */ |
125 struct buffer buffer_local_flags; | 125 struct buffer buffer_local_flags; |
126 | 126 |
127 /* This is the initial (startup) directory, as used for the *scratch* buffer. | 127 /* This is the initial (startup) directory, as used for the *scratch* buffer. |
128 We're making this a global to make others aware of the startup directory. | 128 We're making this a global to make others aware of the startup directory. |
129 `initial_directory' is stored in external format. | |
129 */ | 130 */ |
130 char initial_directory[MAXPATHLEN+1]; | 131 char initial_directory[MAXPATHLEN+1]; |
131 | 132 |
132 /* This structure holds the names of symbols whose values may be | 133 /* This structure holds the names of symbols whose values may be |
133 buffer-local. It is indexed and accessed in the same way as the above. */ | 134 buffer-local. It is indexed and accessed in the same way as the above. */ |
1123 | 1124 |
1124 return Qnil; | 1125 return Qnil; |
1125 } | 1126 } |
1126 | 1127 |
1127 DEFUN ("kill-buffer", Fkill_buffer, 1, 1, "bKill buffer: ", /* | 1128 DEFUN ("kill-buffer", Fkill_buffer, 1, 1, "bKill buffer: ", /* |
1128 Kill the buffer BUFNAME. | 1129 Kill the buffer BUFFER. |
1129 The argument may be a buffer or may be the name of a buffer. | 1130 The argument may be a buffer or may be the name of a buffer. |
1130 An argument of nil means kill the current buffer. | 1131 An argument of nil means kill the current buffer. |
1131 | 1132 |
1132 Value is t if the buffer is actually killed, nil if user says no. | 1133 Value is t if the buffer is actually killed, nil if user says no. |
1133 | 1134 |
1137 when the hook functions are called. | 1138 when the hook functions are called. |
1138 | 1139 |
1139 Any processes that have this buffer as the `process-buffer' are killed | 1140 Any processes that have this buffer as the `process-buffer' are killed |
1140 with `delete-process'. | 1141 with `delete-process'. |
1141 */ | 1142 */ |
1142 (bufname)) | 1143 (buffer)) |
1143 { | 1144 { |
1144 /* This function can call lisp */ | 1145 /* This function can call lisp */ |
1145 Lisp_Object buf; | 1146 Lisp_Object buf; |
1146 REGISTER struct buffer *b; | 1147 REGISTER struct buffer *b; |
1147 struct gcpro gcpro1, gcpro2; | 1148 struct gcpro gcpro1, gcpro2; |
1148 | 1149 |
1149 if (NILP (bufname)) | 1150 if (NILP (buffer)) |
1150 buf = Fcurrent_buffer (); | 1151 buf = Fcurrent_buffer (); |
1151 else if (BUFFERP (bufname)) | 1152 else if (BUFFERP (buffer)) |
1152 buf = bufname; | 1153 buf = buffer; |
1153 else | 1154 else |
1154 { | 1155 { |
1155 buf = get_buffer (bufname, 0); | 1156 buf = get_buffer (buffer, 0); |
1156 if (NILP (buf)) nsberror (bufname); | 1157 if (NILP (buf)) nsberror (buffer); |
1157 } | 1158 } |
1158 | 1159 |
1159 b = XBUFFER (buf); | 1160 b = XBUFFER (buf); |
1160 | 1161 |
1161 /* OK to delete an already-deleted buffer. */ | 1162 /* OK to delete an already-deleted buffer. */ |
1173 /* Query if the buffer is still modified. */ | 1174 /* Query if the buffer is still modified. */ |
1174 if (INTERACTIVE && !NILP (b->filename) | 1175 if (INTERACTIVE && !NILP (b->filename) |
1175 && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)) | 1176 && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)) |
1176 { | 1177 { |
1177 Lisp_Object killp; | 1178 Lisp_Object killp; |
1178 GCPRO2 (buf, bufname); | 1179 GCPRO1 (buf); |
1179 killp = call1 | 1180 killp = call1 |
1180 (Qyes_or_no_p, | 1181 (Qyes_or_no_p, |
1181 (emacs_doprnt_string_c | 1182 (emacs_doprnt_string_c |
1182 ((CONST Bufbyte *) GETTEXT ("Buffer %s modified; kill anyway? "), | 1183 ((CONST Bufbyte *) GETTEXT ("Buffer %s modified; kill anyway? "), |
1183 Qnil, -1, XSTRING_DATA (b->name)))); | 1184 Qnil, -1, XSTRING_DATA (b->name)))); |
1359 } | 1360 } |
1360 return Qt; | 1361 return Qt; |
1361 } | 1362 } |
1362 | 1363 |
1363 DEFUN ("record-buffer", Frecord_buffer, 1, 1, 0, /* | 1364 DEFUN ("record-buffer", Frecord_buffer, 1, 1, 0, /* |
1364 Place buffer BUF first in the buffer order. | 1365 Place buffer BUFFER first in the buffer order. |
1365 Call this function when a buffer is selected "visibly". | 1366 Call this function when a buffer is selected "visibly". |
1366 | 1367 |
1367 This function changes the global buffer order and the per-frame buffer | 1368 This function changes the global buffer order and the per-frame buffer |
1368 order for the selected frame. The buffer order keeps track of recency | 1369 order for the selected frame. The buffer order keeps track of recency |
1369 of selection so that `other-buffer' will return a recently selected | 1370 of selection so that `other-buffer' will return a recently selected |
1370 buffer. See `other-buffer' for more information. | 1371 buffer. See `other-buffer' for more information. |
1371 */ | 1372 */ |
1372 (buf)) | 1373 (buffer)) |
1373 { | 1374 { |
1374 REGISTER Lisp_Object lynk, prev; | 1375 REGISTER Lisp_Object lynk, prev; |
1375 struct frame *f = selected_frame (); | 1376 struct frame *f = selected_frame (); |
1376 | 1377 |
1377 prev = Qnil; | 1378 prev = Qnil; |
1378 for (lynk = Vbuffer_alist; CONSP (lynk); lynk = XCDR (lynk)) | 1379 for (lynk = Vbuffer_alist; CONSP (lynk); lynk = XCDR (lynk)) |
1379 { | 1380 { |
1380 if (EQ (XCDR (XCAR (lynk)), buf)) | 1381 if (EQ (XCDR (XCAR (lynk)), buffer)) |
1381 break; | 1382 break; |
1382 prev = lynk; | 1383 prev = lynk; |
1383 } | 1384 } |
1384 /* Effectively do Vbuffer_alist = delq_no_quit (lynk, Vbuffer_alist) */ | 1385 /* Effectively do Vbuffer_alist = delq_no_quit (lynk, Vbuffer_alist) */ |
1385 if (NILP (prev)) | 1386 if (NILP (prev)) |
1392 /* That was the global one. Now do the same thing for the | 1393 /* That was the global one. Now do the same thing for the |
1393 per-frame buffer-alist. */ | 1394 per-frame buffer-alist. */ |
1394 prev = Qnil; | 1395 prev = Qnil; |
1395 for (lynk = f->buffer_alist; CONSP (lynk); lynk = XCDR (lynk)) | 1396 for (lynk = f->buffer_alist; CONSP (lynk); lynk = XCDR (lynk)) |
1396 { | 1397 { |
1397 if (EQ (XCDR (XCAR (lynk)), buf)) | 1398 if (EQ (XCDR (XCAR (lynk)), buffer)) |
1398 break; | 1399 break; |
1399 prev = lynk; | 1400 prev = lynk; |
1400 } | 1401 } |
1401 /* Effectively do f->buffer_alist = delq_no_quit (lynk, f->buffer_alist) */ | 1402 /* Effectively do f->buffer_alist = delq_no_quit (lynk, f->buffer_alist) */ |
1402 if (NILP (prev)) | 1403 if (NILP (prev)) |
1411 DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, 1, 1, 0, /* | 1412 DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, 1, 1, 0, /* |
1412 Set an appropriate major mode for BUFFER, according to `default-major-mode'. | 1413 Set an appropriate major mode for BUFFER, according to `default-major-mode'. |
1413 Use this function before selecting the buffer, since it may need to inspect | 1414 Use this function before selecting the buffer, since it may need to inspect |
1414 the current buffer's major mode. | 1415 the current buffer's major mode. |
1415 */ | 1416 */ |
1416 (buf)) | 1417 (buffer)) |
1417 { | 1418 { |
1418 int speccount = specpdl_depth (); | 1419 int speccount = specpdl_depth (); |
1419 REGISTER Lisp_Object function, tem; | 1420 Lisp_Object function = XBUFFER (Vbuffer_defaults)->major_mode; |
1420 | 1421 |
1421 function = XBUFFER (Vbuffer_defaults)->major_mode; | |
1422 if (NILP (function)) | 1422 if (NILP (function)) |
1423 { | 1423 { |
1424 tem = Fget (current_buffer->major_mode, Qmode_class, Qnil); | 1424 Lisp_Object tem = Fget (current_buffer->major_mode, Qmode_class, Qnil); |
1425 if (NILP (tem)) | 1425 if (NILP (tem)) |
1426 function = current_buffer->major_mode; | 1426 function = current_buffer->major_mode; |
1427 } | 1427 } |
1428 | 1428 |
1429 if (NILP (function) || EQ (function, Qfundamental_mode)) | 1429 if (NILP (function) || EQ (function, Qfundamental_mode)) |
1432 /* To select a nonfundamental mode, | 1432 /* To select a nonfundamental mode, |
1433 select the buffer temporarily and then call the mode function. */ | 1433 select the buffer temporarily and then call the mode function. */ |
1434 | 1434 |
1435 record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); | 1435 record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); |
1436 | 1436 |
1437 Fset_buffer (buf); | 1437 Fset_buffer (buffer); |
1438 call0 (function); | 1438 call0 (function); |
1439 | 1439 |
1440 return unbind_to (speccount, Qnil); | 1440 return unbind_to (speccount, Qnil); |
1441 } | 1441 } |
1442 | 1442 |
1450 DEFUN ("current-buffer", Fcurrent_buffer, 0, 0, 0, /* | 1450 DEFUN ("current-buffer", Fcurrent_buffer, 0, 0, 0, /* |
1451 Return the current buffer as a Lisp object. | 1451 Return the current buffer as a Lisp object. |
1452 */ | 1452 */ |
1453 ()) | 1453 ()) |
1454 { | 1454 { |
1455 Lisp_Object buf; | 1455 Lisp_Object buffer; |
1456 XSETBUFFER (buf, current_buffer); | 1456 XSETBUFFER (buffer, current_buffer); |
1457 return buf; | 1457 return buffer; |
1458 } | 1458 } |
1459 | 1459 |
1460 /* Set the current buffer to B. */ | 1460 /* Set the current buffer to B. */ |
1461 | 1461 |
1462 void | 1462 void |
2686 /* Want no undo records for *scratch* until after Emacs is dumped */ | 2686 /* Want no undo records for *scratch* until after Emacs is dumped */ |
2687 Fbuffer_disable_undo (scratch); | 2687 Fbuffer_disable_undo (scratch); |
2688 } | 2688 } |
2689 } | 2689 } |
2690 | 2690 |
2691 /* Is PWD another name for `.' ? */ | |
2692 static int | |
2693 directory_is_current_directory (char *pwd) | |
2694 { | |
2695 Bufbyte *pwd_internal; | |
2696 struct stat dotstat, pwdstat; | |
2697 | |
2698 GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (pwd, pwd_internal); | |
2699 | |
2700 return (IS_DIRECTORY_SEP (*pwd_internal) | |
2701 && stat (pwd_internal, &pwdstat) == 0 | |
2702 && stat ("." , &dotstat) == 0 | |
2703 && dotstat.st_ino == pwdstat.st_ino | |
2704 && dotstat.st_dev == pwdstat.st_dev | |
2705 && (int) strlen (pwd_internal) < MAXPATHLEN); | |
2706 } | |
2707 | |
2691 void | 2708 void |
2692 init_initial_directory (void) | 2709 init_initial_directory (void) |
2693 { | 2710 { |
2694 /* This function can GC */ | 2711 /* This function can GC */ |
2695 | 2712 |
2696 char *pwd; | 2713 char *pwd; |
2697 struct stat dotstat, pwdstat; | |
2698 int rc; | |
2699 | 2714 |
2700 initial_directory[0] = 0; | 2715 initial_directory[0] = 0; |
2701 | 2716 |
2702 /* If PWD is accurate, use it instead of calling getcwd. This is faster | 2717 /* If PWD is accurate, use it instead of calling getcwd. This is faster |
2703 when PWD is right, and may avoid a fatal error. */ | 2718 when PWD is right, and may avoid a fatal error. */ |
2704 if ((pwd = getenv ("PWD")) != 0 && IS_DIRECTORY_SEP (*pwd) | 2719 if ((pwd = getenv ("PWD")) != NULL |
2705 && stat (pwd, &pwdstat) == 0 | 2720 && directory_is_current_directory (pwd)) |
2706 && stat (".", &dotstat) == 0 | |
2707 && dotstat.st_ino == pwdstat.st_ino | |
2708 && dotstat.st_dev == pwdstat.st_dev | |
2709 && (int) strlen (pwd) < MAXPATHLEN) | |
2710 strcpy (initial_directory, pwd); | 2721 strcpy (initial_directory, pwd); |
2711 else if (getcwd (initial_directory, MAXPATHLEN) == NULL) | 2722 else if (getcwd (initial_directory, MAXPATHLEN) == NULL) |
2712 fatal ("`getcwd' failed: %s\n", strerror (errno)); | 2723 fatal ("`getcwd' failed: %s\n", strerror (errno)); |
2713 | 2724 |
2714 /* Maybe this should really use some standard subroutine | 2725 /* Make sure pwd is DIRECTORY_SEP-terminated. |
2726 Maybe this should really use some standard subroutine | |
2715 whose definition is filename syntax dependent. */ | 2727 whose definition is filename syntax dependent. */ |
2716 rc = strlen (initial_directory); | 2728 { |
2717 if (!(IS_DIRECTORY_SEP (initial_directory[rc - 1]))) | 2729 int len = strlen (initial_directory); |
2718 { | 2730 |
2719 initial_directory[rc] = DIRECTORY_SEP; | 2731 if (! IS_DIRECTORY_SEP (initial_directory[len - 1])) |
2720 initial_directory[rc + 1] = '\0'; | 2732 { |
2721 } | 2733 initial_directory[len] = DIRECTORY_SEP; |
2734 initial_directory[len + 1] = '\0'; | |
2735 } | |
2736 } | |
2737 | |
2722 /* XEmacs change: store buffer's default directory | 2738 /* XEmacs change: store buffer's default directory |
2723 using preferred (i.e. as defined at compile-time) | 2739 using preferred (i.e. as defined at compile-time) |
2724 directory separator. --marcpa */ | 2740 directory separator. --marcpa */ |
2725 #ifdef DOS_NT | 2741 #ifdef DOS_NT |
2726 #define CORRECT_DIR_SEPS(s) \ | 2742 #define CORRECT_DIR_SEPS(s) \ |
2737 { | 2753 { |
2738 /* This function can GC */ | 2754 /* This function can GC */ |
2739 | 2755 |
2740 Fset_buffer (Fget_buffer_create (QSscratch)); | 2756 Fset_buffer (Fget_buffer_create (QSscratch)); |
2741 | 2757 |
2742 current_buffer->directory = build_string (initial_directory); | 2758 current_buffer->directory = |
2759 build_ext_string (initial_directory, FORMAT_FILENAME); | |
2743 | 2760 |
2744 #if 0 /* FSFmacs */ | 2761 #if 0 /* FSFmacs */ |
2745 /* #### is this correct? */ | 2762 /* #### is this correct? */ |
2746 temp = get_minibuffer (0); | 2763 temp = get_minibuffer (0); |
2747 XBUFFER (temp)->directory = current_buffer->directory; | 2764 XBUFFER (temp)->directory = current_buffer->directory; |