/* * Write all the named marks for all buffers. * Return the number of buffers for which marks have been written. */ int write_viminfo_marks(FILE *fp_out) { int count; buf_T *buf; int is_mark_set; int i; win_T *win; tabpage_T *tp; /* * Set b_last_cursor for the all buffers that have a window. */ FOR_ALL_TAB_WINDOWS(tp, win) set_last_cursor(win); fputs(_("\n# History of marks within files (newest to oldest):\n"), fp_out); count = 0; for (buf = firstbuf; buf != NULL; buf = buf->b_next) { /* * Only write something if buffer has been loaded and at least one * mark is set. */ if (buf->b_marks_read) { if (buf->b_last_cursor.lnum != 0) is_mark_set = TRUE; else { is_mark_set = FALSE; for (i = 0; i < NMARKS; i++) if (buf->b_namedm[i].lnum != 0) { is_mark_set = TRUE; break; } } if (is_mark_set && buf->b_ffname != NULL && buf->b_ffname[0] != NUL && !removable(buf->b_ffname)) { home_replace(NULL, buf->b_ffname, IObuff, IOSIZE, TRUE); fprintf(fp_out, "\n> "); viminfo_writestring(fp_out, IObuff); write_one_mark(fp_out, '"', &buf->b_last_cursor); write_one_mark(fp_out, '^', &buf->b_last_insert); write_one_mark(fp_out, '.', &buf->b_last_change); /* changelist positions are stored oldest first */ for (i = 0; i < buf->b_changelistlen; ++i) write_one_mark(fp_out, '+', &buf->b_changelist[i]); for (i = 0; i < NMARKS; i++) write_one_mark(fp_out, 'a' + i, &buf->b_namedm[i]); count++; } } } return count; }
/* * Adjust marks between line1 and line2 (inclusive) to move 'amount' lines. * Must be called before changed_*(), appended_lines() or deleted_lines(). * May be called before or after changing the text. * When deleting lines line1 to line2, use an 'amount' of MAXLNUM: The marks * within this range are made invalid. * If 'amount_after' is non-zero adjust marks after line2. * Example: Delete lines 34 and 35: mark_adjust(34, 35, MAXLNUM, -2); * Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0); * or: mark_adjust(56, 55, MAXLNUM, 2); */ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) { int i; int fnum = curbuf->b_fnum; linenr_T *lp; win_T *win; tabpage_T *tab; static pos_T initpos = INIT_POS_T(1, 0, 0); if (line2 < line1 && amount_after == 0L) /* nothing to do */ return; if (!cmdmod.lockmarks) { /* named marks, lower case and upper case */ for (i = 0; i < NMARKS; i++) { one_adjust(&(curbuf->b_namedm[i].lnum)); if (namedfm[i].fmark.fnum == fnum) one_adjust_nodel(&(namedfm[i].fmark.mark.lnum)); } for (i = NMARKS; i < NMARKS + EXTRA_MARKS; i++) { if (namedfm[i].fmark.fnum == fnum) one_adjust_nodel(&(namedfm[i].fmark.mark.lnum)); } /* last Insert position */ one_adjust(&(curbuf->b_last_insert.lnum)); /* last change position */ one_adjust(&(curbuf->b_last_change.lnum)); /* last cursor position, if it was set */ if (!equalpos(curbuf->b_last_cursor, initpos)) one_adjust(&(curbuf->b_last_cursor.lnum)); /* list of change positions */ for (i = 0; i < curbuf->b_changelistlen; ++i) one_adjust_nodel(&(curbuf->b_changelist[i].lnum)); /* Visual area */ one_adjust_nodel(&(curbuf->b_visual.vi_start.lnum)); one_adjust_nodel(&(curbuf->b_visual.vi_end.lnum)); /* quickfix marks */ qf_mark_adjust(NULL, line1, line2, amount, amount_after); /* location lists */ FOR_ALL_TAB_WINDOWS(tab, win) qf_mark_adjust(win, line1, line2, amount, amount_after); } /* previous context mark */ one_adjust(&(curwin->w_pcmark.lnum)); /* previous pcmark */ one_adjust(&(curwin->w_prev_pcmark.lnum)); /* saved cursor for formatting */ if (saved_cursor.lnum != 0) one_adjust_nodel(&(saved_cursor.lnum)); /* * Adjust items in all windows related to the current buffer. */ FOR_ALL_TAB_WINDOWS(tab, win) { if (!cmdmod.lockmarks) /* Marks in the jumplist. When deleting lines, this may create * duplicate marks in the jumplist, they will be removed later. */ for (i = 0; i < win->w_jumplistlen; ++i) if (win->w_jumplist[i].fmark.fnum == fnum) one_adjust_nodel(&(win->w_jumplist[i].fmark.mark.lnum)); if (win->w_buffer == curbuf) { if (!cmdmod.lockmarks) /* marks in the tag stack */ for (i = 0; i < win->w_tagstacklen; i++) if (win->w_tagstack[i].fmark.fnum == fnum) one_adjust_nodel(&(win->w_tagstack[i].fmark.mark.lnum)); /* the displayed Visual area */ if (win->w_old_cursor_lnum != 0) { one_adjust_nodel(&(win->w_old_cursor_lnum)); one_adjust_nodel(&(win->w_old_visual_lnum)); } /* topline and cursor position for windows with the same buffer * other than the current window */ if (win != curwin) { if (win->w_topline >= line1 && win->w_topline <= line2) { if (amount == MAXLNUM) { /* topline is deleted */ if (line1 <= 1) win->w_topline = 1; else win->w_topline = line1 - 1; } else /* keep topline on the same line */ win->w_topline += amount; win->w_topfill = 0; } else if (amount_after && win->w_topline > line2) { win->w_topline += amount_after; win->w_topfill = 0; } if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) { if (amount == MAXLNUM) { /* line with cursor is deleted */ if (line1 <= 1) win->w_cursor.lnum = 1; else win->w_cursor.lnum = line1 - 1; win->w_cursor.col = 0; } else /* keep cursor on the same line */ win->w_cursor.lnum += amount; } else if (amount_after && win->w_cursor.lnum > line2) win->w_cursor.lnum += amount_after; } /* adjust folds */ foldMarkAdjust(win, line1, line2, amount, amount_after); } } /* adjust diffs */ diff_mark_adjust(line1, line2, amount, amount_after); }
/* * Free everything that we allocated. * Can be used to detect memory leaks, e.g., with ccmalloc. * NOTE: This is tricky! Things are freed that functions depend on. Don't be * surprised if Vim crashes... * Some things can't be freed, esp. things local to a library function. */ void free_all_mem(void) { buf_T *buf, *nextbuf; static int entered = FALSE; /* When we cause a crash here it is caught and Vim tries to exit cleanly. * Don't try freeing everything again. */ if (entered) return; entered = TRUE; block_autocmds(); /* don't want to trigger autocommands here */ /* Close all tabs and windows. Reset 'equalalways' to avoid redraws. */ p_ea = FALSE; if (first_tabpage->tp_next != NULL) do_cmdline_cmd((char_u *)"tabonly!"); if (firstwin != lastwin) do_cmdline_cmd((char_u *)"only!"); /* Free all spell info. */ spell_free_all(); /* Clear user commands (before deleting buffers). */ ex_comclear(NULL); /* Clear menus. */ do_cmdline_cmd((char_u *)"aunmenu *"); do_cmdline_cmd((char_u *)"menutranslate clear"); /* Clear mappings, abbreviations, breakpoints. */ do_cmdline_cmd((char_u *)"lmapclear"); do_cmdline_cmd((char_u *)"xmapclear"); do_cmdline_cmd((char_u *)"mapclear"); do_cmdline_cmd((char_u *)"mapclear!"); do_cmdline_cmd((char_u *)"abclear"); do_cmdline_cmd((char_u *)"breakdel *"); do_cmdline_cmd((char_u *)"profdel *"); do_cmdline_cmd((char_u *)"set keymap="); free_titles(); free_findfile(); /* Obviously named calls. */ free_all_autocmds(); clear_termcodes(); free_all_options(); free_all_marks(); alist_clear(&global_alist); free_homedir(); free_users(); free_search_patterns(); free_old_sub(); free_last_insert(); free_prev_shellcmd(); free_regexp_stuff(); free_tag_stuff(); free_cd_dir(); free_signs(); set_expr_line(NULL); diff_clear(curtab); clear_sb_text(); /* free any scrollback text */ /* Free some global vars. */ vim_free(last_cmdline); vim_free(new_last_cmdline); set_keep_msg(NULL, 0); /* Clear cmdline history. */ p_hi = 0; init_history(); { win_T *win; tabpage_T *tab; qf_free_all(NULL); /* Free all location lists */ FOR_ALL_TAB_WINDOWS(tab, win) qf_free_all(win); } /* Close all script inputs. */ close_all_scripts(); /* Destroy all windows. Must come before freeing buffers. */ win_free_all(); /* Free all buffers. Reset 'autochdir' to avoid accessing things that * were freed already. */ p_acd = FALSE; for (buf = firstbuf; buf != NULL; ) { nextbuf = buf->b_next; close_buffer(NULL, buf, DOBUF_WIPE, FALSE); if (buf_valid(buf)) buf = nextbuf; /* didn't work, try next one */ else buf = firstbuf; } free_cmdline_buf(); /* Clear registers. */ clear_registers(); ResetRedobuff(); ResetRedobuff(); /* highlight info */ free_highlight(); reset_last_sourcing(); free_tabpage(first_tabpage); first_tabpage = NULL; # ifdef UNIX /* Machine-specific free. */ mch_free_mem(); # endif /* message history */ for (;; ) if (delete_first_msg() == FAIL) break; eval_clear(); free_termoptions(); /* screenlines (can't display anything now!) */ free_screenlines(); clear_hl_tables(); vim_free(NameBuff); }