Mercurial > vim
comparison src/memline.c @ 625:81fe2ccc1207 v7.0179
updated for version 7.0179
author | vimboss |
---|---|
date | Thu, 12 Jan 2006 23:22:24 +0000 |
parents | 66263e241ce3 |
children | 52c87a746f4a |
comparison
equal
deleted
inserted
replaced
624:91e7d4a7b3b0 | 625:81fe2ccc1207 |
---|---|
11 /* #define CHECK(c, s) if (c) EMSG(s) */ | 11 /* #define CHECK(c, s) if (c) EMSG(s) */ |
12 #define CHECK(c, s) | 12 #define CHECK(c, s) |
13 | 13 |
14 /* | 14 /* |
15 * memline.c: Contains the functions for appending, deleting and changing the | 15 * memline.c: Contains the functions for appending, deleting and changing the |
16 * text lines. The memfile functions are used to store the information in blocks | 16 * text lines. The memfile functions are used to store the information in |
17 * of memory, backed up by a file. The structure of the information is a tree. | 17 * blocks of memory, backed up by a file. The structure of the information is |
18 * The root of the tree is a pointer block. The leaves of the tree are data | 18 * a tree. The root of the tree is a pointer block. The leaves of the tree |
19 * blocks. In between may be several layers of pointer blocks, forming branches. | 19 * are data blocks. In between may be several layers of pointer blocks, |
20 * forming branches. | |
20 * | 21 * |
21 * Three types of blocks are used: | 22 * Three types of blocks are used: |
22 * - Block nr 0 contains information for recovery | 23 * - Block nr 0 contains information for recovery |
23 * - Pointer blocks contain list of pointers to other blocks. | 24 * - Pointer blocks contain list of pointers to other blocks. |
24 * - Data blocks contain the actual text. | 25 * - Data blocks contain the actual text. |
167 short b0_magic_short; /* check for byte order of short */ | 168 short b0_magic_short; /* check for byte order of short */ |
168 char_u b0_magic_char; /* check for last char */ | 169 char_u b0_magic_char; /* check for last char */ |
169 }; | 170 }; |
170 | 171 |
171 /* | 172 /* |
172 * Note: b0_fname and b0_flags are put at the end of the file name. For very | 173 * Note: b0_dirty and b0_flags are put at the end of the file name. For very |
173 * long file names in older versions of Vim they are invalid. | 174 * long file names in older versions of Vim they are invalid. |
174 * The 'fileencoding' comes before b0_flags, with a NUL in front. But only | 175 * The 'fileencoding' comes before b0_flags, with a NUL in front. But only |
175 * when there is room, for very long file names it's omitted. | 176 * when there is room, for very long file names it's omitted. |
176 */ | 177 */ |
177 #define B0_DIRTY 0x55 | 178 #define B0_DIRTY 0x55 |
243 #ifdef FEAT_BYTEOFF | 244 #ifdef FEAT_BYTEOFF |
244 static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype)); | 245 static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype)); |
245 #endif | 246 #endif |
246 | 247 |
247 /* | 248 /* |
248 * open a new memline for 'curbuf' | 249 * Open a new memline for "buf". |
249 * | 250 * |
250 * return FAIL for failure, OK otherwise | 251 * Return FAIL for failure, OK otherwise. |
251 */ | 252 */ |
252 int | 253 int |
253 ml_open() | 254 ml_open(buf) |
255 buf_T *buf; | |
254 { | 256 { |
255 memfile_T *mfp; | 257 memfile_T *mfp; |
256 bhdr_T *hp = NULL; | 258 bhdr_T *hp = NULL; |
257 ZERO_BL *b0p; | 259 ZERO_BL *b0p; |
258 PTR_BL *pp; | 260 PTR_BL *pp; |
259 DATA_BL *dp; | 261 DATA_BL *dp; |
260 | 262 |
261 /* | 263 /* |
262 * init fields in memline struct | 264 * init fields in memline struct |
263 */ | 265 */ |
264 curbuf->b_ml.ml_stack_size = 0; /* no stack yet */ | 266 buf->b_ml.ml_stack_size = 0; /* no stack yet */ |
265 curbuf->b_ml.ml_stack = NULL; /* no stack yet */ | 267 buf->b_ml.ml_stack = NULL; /* no stack yet */ |
266 curbuf->b_ml.ml_stack_top = 0; /* nothing in the stack */ | 268 buf->b_ml.ml_stack_top = 0; /* nothing in the stack */ |
267 curbuf->b_ml.ml_locked = NULL; /* no cached block */ | 269 buf->b_ml.ml_locked = NULL; /* no cached block */ |
268 curbuf->b_ml.ml_line_lnum = 0; /* no cached line */ | 270 buf->b_ml.ml_line_lnum = 0; /* no cached line */ |
269 #ifdef FEAT_BYTEOFF | 271 #ifdef FEAT_BYTEOFF |
270 curbuf->b_ml.ml_chunksize = NULL; | 272 buf->b_ml.ml_chunksize = NULL; |
271 #endif | 273 #endif |
272 | 274 |
273 /* | 275 /* |
274 * When 'updatecount' is non-zero, flag that a swap file may be opened later. | 276 * When 'updatecount' is non-zero swap file may be opened later. |
275 */ | 277 */ |
276 if (p_uc && curbuf->b_p_swf) | 278 if (p_uc && buf->b_p_swf) |
277 curbuf->b_may_swap = TRUE; | 279 buf->b_may_swap = TRUE; |
278 else | 280 else |
279 curbuf->b_may_swap = FALSE; | 281 buf->b_may_swap = FALSE; |
280 | 282 |
281 /* | 283 /* |
282 * Open the memfile. No swap file is created yet. | 284 * Open the memfile. No swap file is created yet. |
283 */ | 285 */ |
284 mfp = mf_open(NULL, 0); | 286 mfp = mf_open(NULL, 0); |
285 if (mfp == NULL) | 287 if (mfp == NULL) |
286 goto error; | 288 goto error; |
287 | 289 |
288 curbuf->b_ml.ml_mfp = mfp; | 290 buf->b_ml.ml_mfp = mfp; |
289 curbuf->b_ml.ml_flags = ML_EMPTY; | 291 buf->b_ml.ml_flags = ML_EMPTY; |
290 curbuf->b_ml.ml_line_count = 1; | 292 buf->b_ml.ml_line_count = 1; |
291 #ifdef FEAT_LINEBREAK | 293 #ifdef FEAT_LINEBREAK |
292 curwin->w_nrwidth_line_count = 0; | 294 curwin->w_nrwidth_line_count = 0; |
293 #endif | 295 #endif |
294 | 296 |
295 #if defined(MSDOS) && !defined(DJGPP) | 297 #if defined(MSDOS) && !defined(DJGPP) |
296 /* for 16 bit MS-DOS create a swapfile now, because we run out of | 298 /* for 16 bit MS-DOS create a swapfile now, because we run out of |
297 * memory very quickly */ | 299 * memory very quickly */ |
298 if (p_uc != 0) | 300 if (p_uc != 0) |
299 ml_open_file(curbuf); | 301 ml_open_file(buf); |
300 #endif | 302 #endif |
301 | 303 |
302 /* | 304 /* |
303 * fill block0 struct and write page 0 | 305 * fill block0 struct and write page 0 |
304 */ | 306 */ |
311 } | 313 } |
312 b0p = (ZERO_BL *)(hp->bh_data); | 314 b0p = (ZERO_BL *)(hp->bh_data); |
313 | 315 |
314 b0p->b0_id[0] = BLOCK0_ID0; | 316 b0p->b0_id[0] = BLOCK0_ID0; |
315 b0p->b0_id[1] = BLOCK0_ID1; | 317 b0p->b0_id[1] = BLOCK0_ID1; |
316 b0p->b0_dirty = curbuf->b_changed ? B0_DIRTY : 0; | |
317 b0p->b0_flags = get_fileformat(curbuf) + 1; | |
318 b0p->b0_magic_long = (long)B0_MAGIC_LONG; | 318 b0p->b0_magic_long = (long)B0_MAGIC_LONG; |
319 b0p->b0_magic_int = (int)B0_MAGIC_INT; | 319 b0p->b0_magic_int = (int)B0_MAGIC_INT; |
320 b0p->b0_magic_short = (short)B0_MAGIC_SHORT; | 320 b0p->b0_magic_short = (short)B0_MAGIC_SHORT; |
321 b0p->b0_magic_char = B0_MAGIC_CHAR; | 321 b0p->b0_magic_char = B0_MAGIC_CHAR; |
322 | |
323 STRNCPY(b0p->b0_version, "VIM ", 4); | 322 STRNCPY(b0p->b0_version, "VIM ", 4); |
324 STRNCPY(b0p->b0_version + 4, Version, 6); | 323 STRNCPY(b0p->b0_version + 4, Version, 6); |
325 set_b0_fname(b0p, curbuf); | |
326 long_to_char((long)mfp->mf_page_size, b0p->b0_page_size); | 324 long_to_char((long)mfp->mf_page_size, b0p->b0_page_size); |
327 (void)get_user_name(b0p->b0_uname, B0_UNAME_SIZE); | 325 |
328 b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL; | 326 if (!B_SPELL(buf)) |
329 mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE); | 327 { |
330 b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL; | 328 b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0; |
331 long_to_char(mch_get_pid(), b0p->b0_pid); | 329 b0p->b0_flags = get_fileformat(buf) + 1; |
330 set_b0_fname(b0p, buf); | |
331 (void)get_user_name(b0p->b0_uname, B0_UNAME_SIZE); | |
332 b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL; | |
333 mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE); | |
334 b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL; | |
335 long_to_char(mch_get_pid(), b0p->b0_pid); | |
336 } | |
332 | 337 |
333 /* | 338 /* |
334 * Always sync block number 0 to disk, so we can check the file name in | 339 * Always sync block number 0 to disk, so we can check the file name in |
335 * the swap file in findswapname(). Don't do this for help files though. | 340 * the swap file in findswapname(). Don't do this for help files though |
341 * and spell buffer though. | |
336 * Only works when there's a swapfile, otherwise it's done when the file | 342 * Only works when there's a swapfile, otherwise it's done when the file |
337 * is created. | 343 * is created. |
338 */ | 344 */ |
339 mf_put(mfp, hp, TRUE, FALSE); | 345 mf_put(mfp, hp, TRUE, FALSE); |
340 if (!curbuf->b_help) | 346 if (!buf->b_help && !B_SPELL(buf)) |
341 (void)mf_sync(mfp, 0); | 347 (void)mf_sync(mfp, 0); |
342 | 348 |
343 /* | 349 /* |
344 * fill in root pointer block and write page 1 | 350 * Fill in root pointer block and write page 1. |
345 */ | 351 */ |
346 if ((hp = ml_new_ptr(mfp)) == NULL) | 352 if ((hp = ml_new_ptr(mfp)) == NULL) |
347 goto error; | 353 goto error; |
348 if (hp->bh_bnum != 1) | 354 if (hp->bh_bnum != 1) |
349 { | 355 { |
350 EMSG(_("E298: Didn't get block nr 1?")); | 356 EMSG(_("E298: Didn't get block nr 1?")); |
356 pp->pb_pointer[0].pe_page_count = 1; | 362 pp->pb_pointer[0].pe_page_count = 1; |
357 pp->pb_pointer[0].pe_old_lnum = 1; | 363 pp->pb_pointer[0].pe_old_lnum = 1; |
358 pp->pb_pointer[0].pe_line_count = 1; /* line count after insertion */ | 364 pp->pb_pointer[0].pe_line_count = 1; /* line count after insertion */ |
359 mf_put(mfp, hp, TRUE, FALSE); | 365 mf_put(mfp, hp, TRUE, FALSE); |
360 | 366 |
361 /* | 367 /* |
362 * allocate first data block and create an empty line 1. | 368 * Allocate first data block and create an empty line 1. |
363 */ | 369 */ |
364 if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL) | 370 if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL) |
365 goto error; | 371 goto error; |
366 if (hp->bh_bnum != 2) | 372 if (hp->bh_bnum != 2) |
367 { | 373 { |
368 EMSG(_("E298: Didn't get block nr 2?")); | 374 EMSG(_("E298: Didn't get block nr 2?")); |
382 { | 388 { |
383 if (hp) | 389 if (hp) |
384 mf_put(mfp, hp, FALSE, FALSE); | 390 mf_put(mfp, hp, FALSE, FALSE); |
385 mf_close(mfp, TRUE); /* will also free(mfp->mf_fname) */ | 391 mf_close(mfp, TRUE); /* will also free(mfp->mf_fname) */ |
386 } | 392 } |
387 curbuf->b_ml.ml_mfp = NULL; | 393 buf->b_ml.ml_mfp = NULL; |
388 return FAIL; | 394 return FAIL; |
389 } | 395 } |
390 | 396 |
391 /* | 397 /* |
392 * ml_setname() is called when the file name of "buf" has been changed. | 398 * ml_setname() is called when the file name of "buf" has been changed. |
515 char_u *dirp; | 521 char_u *dirp; |
516 | 522 |
517 mfp = buf->b_ml.ml_mfp; | 523 mfp = buf->b_ml.ml_mfp; |
518 if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf) | 524 if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf) |
519 return; /* nothing to do */ | 525 return; /* nothing to do */ |
526 | |
527 #ifdef FEAT_SYN_HL | |
528 /* For a spell buffer use a temp file name. */ | |
529 if (buf->b_spell) | |
530 { | |
531 fname = vim_tempname('s'); | |
532 if (fname != NULL) | |
533 (void)mf_open_file(mfp, fname); /* consumes fname! */ | |
534 buf->b_may_swap = FALSE; | |
535 return; | |
536 } | |
537 #endif | |
520 | 538 |
521 /* | 539 /* |
522 * Try all directories in 'directory' option. | 540 * Try all directories in 'directory' option. |
523 */ | 541 */ |
524 dirp = p_dir; | 542 dirp = p_dir; |
884 } | 902 } |
885 if (fname == NULL) | 903 if (fname == NULL) |
886 goto theend; /* out of memory */ | 904 goto theend; /* out of memory */ |
887 | 905 |
888 /* When called from main() still need to initialize storage structure */ | 906 /* When called from main() still need to initialize storage structure */ |
889 if (called_from_main && ml_open() == FAIL) | 907 if (called_from_main && ml_open(curbuf) == FAIL) |
890 getout(1); | 908 getout(1); |
891 | 909 |
892 /* | 910 /* |
893 * allocate a buffer structure (only the memline in it is really used) | 911 * allocate a buffer structure (only the memline in it is really used) |
894 */ | 912 */ |
2097 | 2115 |
2098 if (curbuf->b_ml.ml_line_lnum != 0) | 2116 if (curbuf->b_ml.ml_line_lnum != 0) |
2099 ml_flush_line(curbuf); | 2117 ml_flush_line(curbuf); |
2100 return ml_append_int(curbuf, lnum, line, len, newfile, FALSE); | 2118 return ml_append_int(curbuf, lnum, line, len, newfile, FALSE); |
2101 } | 2119 } |
2120 | |
2121 #if defined(FEAT_SYN_HL) || defined(PROTO) | |
2122 /* | |
2123 * Like ml_append() but for an arbitrary buffer. The buffer must already have | |
2124 * a memline. | |
2125 */ | |
2126 int | |
2127 ml_append_buf(buf, lnum, line, len, newfile) | |
2128 buf_T *buf; | |
2129 linenr_T lnum; /* append after this line (can be 0) */ | |
2130 char_u *line; /* text of the new line */ | |
2131 colnr_T len; /* length of new line, including NUL, or 0 */ | |
2132 int newfile; /* flag, see above */ | |
2133 { | |
2134 if (buf->b_ml.ml_mfp == NULL) | |
2135 return FAIL; | |
2136 | |
2137 if (buf->b_ml.ml_line_lnum != 0) | |
2138 ml_flush_line(buf); | |
2139 return ml_append_int(buf, lnum, line, len, newfile, FALSE); | |
2140 } | |
2141 #endif | |
2102 | 2142 |
2103 static int | 2143 static int |
2104 ml_append_int(buf, lnum, line, len, newfile, mark) | 2144 ml_append_int(buf, lnum, line, len, newfile, mark) |
2105 buf_T *buf; | 2145 buf_T *buf; |
2106 linenr_T lnum; /* append after this line (can be 0) */ | 2146 linenr_T lnum; /* append after this line (can be 0) */ |
2597 #endif | 2637 #endif |
2598 return OK; | 2638 return OK; |
2599 } | 2639 } |
2600 | 2640 |
2601 /* | 2641 /* |
2602 * replace line lnum, with buffering, in current buffer | 2642 * Replace line lnum, with buffering, in current buffer. |
2603 * | 2643 * |
2604 * If copy is TRUE, make a copy of the line, otherwise the line has been | 2644 * If copy is TRUE, make a copy of the line, otherwise the line has been |
2605 * copied to allocated memory already. | 2645 * copied to allocated memory already. |
2606 * | 2646 * |
2607 * Check: The caller of this function should probably also call | 2647 * Check: The caller of this function should probably also call |
2641 | 2681 |
2642 return OK; | 2682 return OK; |
2643 } | 2683 } |
2644 | 2684 |
2645 /* | 2685 /* |
2646 * delete line 'lnum' | 2686 * Delete line 'lnum' in the current buffer. |
2647 * | 2687 * |
2648 * Check: The caller of this function should probably also call | 2688 * Check: The caller of this function should probably also call |
2649 * deleted_lines() after this. | 2689 * deleted_lines() after this. |
2650 * | 2690 * |
2651 * return FAIL for failure, OK otherwise | 2691 * return FAIL for failure, OK otherwise |
4112 } | 4152 } |
4113 else | 4153 else |
4114 #endif | 4154 #endif |
4115 { | 4155 { |
4116 MSG_PUTS("\n"); | 4156 MSG_PUTS("\n"); |
4117 need_wait_return = TRUE; /* call wait_return later */ | 4157 if (msg_silent == 0) |
4158 /* call wait_return() later */ | |
4159 need_wait_return = TRUE; | |
4118 } | 4160 } |
4119 | 4161 |
4120 #ifdef CREATE_DUMMY_FILE | 4162 #ifdef CREATE_DUMMY_FILE |
4121 /* Going to try another name, need the dummy file again. */ | 4163 /* Going to try another name, need the dummy file again. */ |
4122 if (did_use_dummy) | 4164 if (did_use_dummy) |