aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/memline.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/memline.c')
-rw-r--r--src/nvim/memline.c114
1 files changed, 65 insertions, 49 deletions
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 3c671121b7..6b2f26b2d8 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -39,7 +39,6 @@
#include <stddef.h>
#include <stdio.h>
#include <string.h>
-#include <sys/types.h>
#include <time.h>
#include <uv.h>
@@ -47,6 +46,7 @@
#include "klib/kvec.h"
#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
+#include "nvim/autocmd_defs.h"
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
#include "nvim/change.h"
@@ -56,11 +56,11 @@
#include "nvim/eval/typval.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/fileio.h"
-#include "nvim/func_attr.h"
#include "nvim/getchar.h"
-#include "nvim/gettext.h"
+#include "nvim/gettext_defs.h"
#include "nvim/globals.h"
#include "nvim/highlight.h"
+#include "nvim/highlight_defs.h"
#include "nvim/input.h"
#include "nvim/macros_defs.h"
#include "nvim/main.h"
@@ -68,16 +68,21 @@
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memfile.h"
+#include "nvim/memfile_defs.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/option.h"
+#include "nvim/option_defs.h"
#include "nvim/option_vars.h"
#include "nvim/os/fs.h"
+#include "nvim/os/fs_defs.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
+#include "nvim/os/os_defs.h"
#include "nvim/os/process.h"
#include "nvim/os/time.h"
+#include "nvim/os/time_defs.h"
#include "nvim/path.h"
#include "nvim/pos_defs.h"
#include "nvim/spell.h"
@@ -331,7 +336,7 @@ int ml_open(buf_T *buf)
b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
b0p->b0_flags = (char)(get_fileformat(buf) + 1);
set_b0_fname(b0p, buf);
- (void)os_get_username(b0p->b0_uname, B0_UNAME_SIZE);
+ os_get_username(b0p->b0_uname, B0_UNAME_SIZE);
b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL;
os_get_hostname(b0p->b0_hname, B0_HNAME_SIZE);
b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL;
@@ -345,7 +350,7 @@ int ml_open(buf_T *buf)
// is created.
mf_put(mfp, hp, true, false);
if (!buf->b_help && !buf->b_spell) {
- (void)mf_sync(mfp, 0);
+ mf_sync(mfp, 0);
}
// Fill in root pointer block and write page 1.
@@ -451,7 +456,7 @@ void ml_setname(buf_T *buf)
emsg(_("E301: Oops, lost the swap file!!!"));
return;
}
- (void)os_set_cloexec(mfp->mf_fd);
+ os_set_cloexec(mfp->mf_fd);
}
if (!success) {
emsg(_("E302: Could not rename swap file"));
@@ -486,7 +491,7 @@ void ml_open_file(buf_T *buf)
if (buf->b_spell) {
char *fname = vim_tempname();
if (fname != NULL) {
- (void)mf_open_file(mfp, fname); // consumes fname!
+ mf_open_file(mfp, fname); // consumes fname!
}
buf->b_may_swap = false;
return;
@@ -530,8 +535,8 @@ void ml_open_file(buf_T *buf)
if (*p_dir != NUL && mfp->mf_fname == NULL) {
need_wait_return = true; // call wait_return() later
no_wait_return++;
- (void)semsg(_("E303: Unable to open swap file for \"%s\", recovery impossible"),
- buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname);
+ semsg(_("E303: Unable to open swap file for \"%s\", recovery impossible"),
+ buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname);
no_wait_return--;
}
@@ -795,7 +800,7 @@ void ml_recover(bool checkext)
i = 1;
} else { // several swapfiles found, choose
// list the names of the swapfiles
- (void)recover_names(fname, true, NULL, 0, NULL);
+ recover_names(fname, true, NULL, 0, NULL);
msg_putchar('\n');
msg_puts(_("Enter number of swap file to use (0 to quit): "));
i = get_number(false, NULL);
@@ -804,7 +809,7 @@ void ml_recover(bool checkext)
}
}
// get the swapfile name that will be used
- (void)recover_names(fname, false, NULL, i, &fname_used);
+ recover_names(fname, false, NULL, i, &fname_used);
}
if (fname_used == NULL) {
goto theend; // user chose invalid number.
@@ -975,7 +980,7 @@ void ml_recover(bool checkext)
set_fileformat(b0_ff - 1, OPT_LOCAL);
}
if (b0_fenc != NULL) {
- set_option_value_give_err("fenc", CSTR_AS_OPTVAL(b0_fenc), OPT_LOCAL);
+ set_option_value_give_err(kOptFileencoding, CSTR_AS_OPTVAL(b0_fenc), OPT_LOCAL);
xfree(b0_fenc);
}
unchanged(curbuf, true, true);
@@ -1292,7 +1297,7 @@ int recover_names(char *fname, bool do_list, list_T *ret_list, int nr, char **fn
// Isolate a directory name from *dirp and put it in dir_name (we know
// it is large enough, so use 31000 for length).
// Advance dirp to next directory name.
- (void)copy_option_part(&dirp, dir_name, 31000, ",");
+ copy_option_part(&dirp, dir_name, 31000, ",");
if (dir_name[0] == '.' && dir_name[1] == NUL) { // check current dir
if (fname == NULL) {
@@ -1403,7 +1408,7 @@ int recover_names(char *fname, bool do_list, list_T *ret_list, int nr, char **fn
msg_puts(". ");
msg_puts(path_tail(files[i]));
msg_putchar('\n');
- (void)swapfile_info(files[i]);
+ swapfile_info(files[i]);
}
} else {
msg_puts(_(" -- none --\n"));
@@ -1642,7 +1647,7 @@ static bool swapfile_unchanged(char *fname)
return ret;
}
-static int recov_file_names(char **names, char *path, int prepend_dot)
+static int recov_file_names(char **names, char *path, bool prepend_dot)
FUNC_ATTR_NONNULL_ALL
{
int num_names = 0;
@@ -1689,9 +1694,9 @@ void ml_sync_all(int check_file, int check_char, bool do_fsync)
if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL) {
continue; // no file
}
- ml_flush_line(buf); // flush buffered line
+ ml_flush_line(buf, false); // flush buffered line
// flush locked block
- (void)ml_find_line(buf, 0, ML_FLUSH);
+ ml_find_line(buf, 0, ML_FLUSH);
if (bufIsChanged(buf) && check_file && mf_need_trans(buf->b_ml.ml_mfp)
&& buf->b_ffname != NULL) {
// If the original file does not exist anymore or has been changed
@@ -1707,8 +1712,8 @@ void ml_sync_all(int check_file, int check_char, bool do_fsync)
}
}
if (buf->b_ml.ml_mfp->mf_dirty == MF_DIRTY_YES) {
- (void)mf_sync(buf->b_ml.ml_mfp, (check_char ? MFS_STOP : 0)
- | (do_fsync && bufIsChanged(buf) ? MFS_FLUSH : 0));
+ mf_sync(buf->b_ml.ml_mfp, (check_char ? MFS_STOP : 0)
+ | (do_fsync && bufIsChanged(buf) ? MFS_FLUSH : 0));
if (check_char && os_char_avail()) { // character available now
break;
}
@@ -1724,7 +1729,7 @@ void ml_sync_all(int check_file, int check_char, bool do_fsync)
/// changed or deleted.
///
/// @param message if true, the success of preserving is reported.
-void ml_preserve(buf_T *buf, int message, bool do_fsync)
+void ml_preserve(buf_T *buf, bool message, bool do_fsync)
{
memfile_T *mfp = buf->b_ml.ml_mfp;
int got_int_save = got_int;
@@ -1740,8 +1745,8 @@ void ml_preserve(buf_T *buf, int message, bool do_fsync)
// before.
got_int = false;
- ml_flush_line(buf); // flush buffered line
- (void)ml_find_line(buf, 0, ML_FLUSH); // flush locked block
+ ml_flush_line(buf, false); // flush buffered line
+ ml_find_line(buf, 0, ML_FLUSH); // flush locked block
int status = mf_sync(mfp, MFS_ALL | (do_fsync ? MFS_FLUSH : 0));
// stack is invalid after mf_sync(.., MFS_ALL)
@@ -1768,7 +1773,7 @@ void ml_preserve(buf_T *buf, int message, bool do_fsync)
CHECK(buf->b_ml.ml_locked_low != lnum, "low != lnum");
lnum = buf->b_ml.ml_locked_high + 1;
}
- (void)ml_find_line(buf, 0, ML_FLUSH); // flush locked block
+ ml_find_line(buf, 0, ML_FLUSH); // flush locked block
// sync the updated pointer blocks
if (mf_sync(mfp, MFS_ALL | (do_fsync ? MFS_FLUSH : 0)) == FAIL) {
status = FAIL;
@@ -1857,7 +1862,7 @@ static char *ml_get_buf_impl(buf_T *buf, linenr_T lnum, bool will_change)
siemsg(_(e_ml_get_invalid_lnum_nr), (int64_t)lnum);
recursive--;
}
- ml_flush_line(buf);
+ ml_flush_line(buf, false);
errorret:
STRCPY(questions, "???");
buf->b_ml.ml_line_lnum = lnum;
@@ -1876,7 +1881,7 @@ errorret:
// Don't use the last used line when 'swapfile' is reset, need to load all
// blocks.
if (buf->b_ml.ml_line_lnum != lnum) {
- ml_flush_line(buf);
+ ml_flush_line(buf, false);
// Find the data block containing the line.
// This also fills the stack with the blocks from the root to the data
@@ -1959,7 +1964,7 @@ int ml_append(linenr_T lnum, char *line, colnr_T len, bool newfile)
}
if (curbuf->b_ml.ml_line_lnum != 0) {
- ml_flush_line(curbuf);
+ ml_flush_line(curbuf, false);
}
return ml_append_int(curbuf, lnum, line, len, newfile, false);
}
@@ -1979,7 +1984,7 @@ int ml_append_buf(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfi
}
if (buf->b_ml.ml_line_lnum != 0) {
- ml_flush_line(buf);
+ ml_flush_line(buf, false);
}
return ml_append_int(buf, lnum, line, len, newfile, false);
}
@@ -1989,7 +1994,8 @@ int ml_append_buf(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfi
/// @param len length of line, including NUL, or 0
/// @param newfile flag, see above
/// @param mark mark the new line
-static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfile, int mark)
+static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfile,
+ bool mark)
{
// lnum out of range
if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL) {
@@ -2242,7 +2248,7 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo
// pointer blocks is done below
int lineadd = buf->b_ml.ml_locked_lineadd;
buf->b_ml.ml_locked_lineadd = 0;
- (void)ml_find_line(buf, 0, ML_FLUSH); // flush data block
+ ml_find_line(buf, 0, ML_FLUSH); // flush data block
// update pointer blocks for the new data block
for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0; stack_idx--) {
@@ -2289,8 +2295,7 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo
// fix line count for rest of blocks in the stack
ml_lineadd(buf, lineadd);
// fix stack itself
- buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
- lineadd;
+ buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high += lineadd;
(buf->b_ml.ml_stack_top)++;
}
@@ -2418,7 +2423,7 @@ void ml_add_deleted_len_buf(buf_T *buf, char *ptr, ssize_t len)
int ml_replace(linenr_T lnum, char *line, bool copy)
{
- return ml_replace_buf(curbuf, lnum, line, copy);
+ return ml_replace_buf(curbuf, lnum, line, copy, false);
}
/// Replace line "lnum", with buffering, in current buffer.
@@ -2433,7 +2438,7 @@ int ml_replace(linenr_T lnum, char *line, bool copy)
/// changed_lines(), unless update_screen(UPD_NOT_VALID) is used.
///
/// @return FAIL for failure, OK otherwise
-int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy)
+int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy, bool noalloc)
{
if (line == NULL) { // just checking...
return FAIL;
@@ -2445,12 +2450,13 @@ int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy)
}
if (copy) {
+ assert(!noalloc);
line = xstrdup(line);
}
if (buf->b_ml.ml_line_lnum != lnum) {
// another line is buffered, flush it
- ml_flush_line(buf);
+ ml_flush_line(buf, false);
}
if (kv_size(buf->update_callbacks)) {
@@ -2464,6 +2470,13 @@ int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy)
buf->b_ml.ml_line_ptr = line;
buf->b_ml.ml_line_lnum = lnum;
buf->b_ml.ml_flags = (buf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;
+ if (noalloc) {
+ // TODO(bfredl): this is a bit of a hack. but replacing lines in a loop is really common,
+ // and allocating a separate scratch buffer for each line which is immediately freed adds
+ // a lot of noise. A more general refactor could be to use a _fixed_ scratch buffer for
+ // all lines up to $REASONABLE_SIZE .
+ ml_flush_line(buf, true);
+ }
return OK;
}
@@ -2478,7 +2491,7 @@ int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy)
/// @return FAIL for failure, OK otherwise
int ml_delete(linenr_T lnum, bool message)
{
- ml_flush_line(curbuf);
+ ml_flush_line(curbuf, false);
return ml_delete_int(curbuf, lnum, message);
}
@@ -2491,7 +2504,7 @@ int ml_delete(linenr_T lnum, bool message)
/// @return FAIL for failure, OK otherwise
int ml_delete_buf(buf_T *buf, linenr_T lnum, bool message)
{
- ml_flush_line(buf);
+ ml_flush_line(buf, false);
return ml_delete_int(buf, lnum, message);
}
@@ -2511,7 +2524,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
set_keep_msg(_(no_lines_msg), 0);
}
- int i = ml_replace_buf(buf, 1, "", true);
+ int i = ml_replace_buf(buf, 1, "", true, false);
buf->b_ml.ml_flags |= ML_EMPTY;
return i;
@@ -2719,7 +2732,7 @@ size_t ml_flush_deleted_bytes(buf_T *buf, size_t *codepoints, size_t *codeunits)
}
/// flush ml_line if necessary
-static void ml_flush_line(buf_T *buf)
+static void ml_flush_line(buf_T *buf, bool noalloc)
{
static bool entered = false;
@@ -2788,15 +2801,18 @@ static void ml_flush_line(buf_T *buf)
// that has only one line.
// Don't forget to copy the mark!
// How about handling errors???
- (void)ml_append_int(buf, lnum, new_line, new_len, false,
- (int)(dp->db_index[idx] & DB_MARKED));
- (void)ml_delete_int(buf, lnum, false);
+ ml_append_int(buf, lnum, new_line, new_len, false,
+ (int)(dp->db_index[idx] & DB_MARKED));
+ ml_delete_int(buf, lnum, false);
}
}
- xfree(new_line);
+ if (!noalloc) {
+ xfree(new_line);
+ }
entered = false;
} else if (buf->b_ml.ml_flags & ML_ALLOCATED) {
+ assert(!noalloc); // caller must set ML_LINE_DIRTY with noalloc, handled above
xfree(buf->b_ml.ml_line_ptr);
}
@@ -3208,7 +3224,7 @@ static void attention_message(buf_T *buf, char *fname)
assert(buf->b_fname != NULL);
no_wait_return++;
- (void)emsg(_("E325: ATTENTION"));
+ emsg(_("E325: ATTENTION"));
msg_puts(_("\nFound a swap file by the name \""));
msg_home_replace(fname);
msg_puts("\"\n");
@@ -3311,7 +3327,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
// First allocate some memory to put the directory name in.
const size_t dir_len = strlen(*dirp) + 1;
char *dir_name = xmalloc(dir_len);
- (void)copy_option_part(dirp, dir_name, dir_len, ",");
+ copy_option_part(dirp, dir_name, dir_len, ",");
// We try different swapfile names until we find one that does not exist yet.
char *fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name);
@@ -3348,7 +3364,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
if (!recoverymode && buf_fname != NULL && !buf->b_help && !(buf->b_flags & BF_DUMMY)) {
int fd;
ZeroBlock b0;
- int differ = false;
+ bool differ = false;
// Try to read block 0 from the swapfile to get the original file name (and inode number).
fd = os_open(fname, O_RDONLY, 0);
@@ -3387,7 +3403,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
// Show the ATTENTION message when:
// - there is an old swapfile for the current file
// - the buffer was not recovered
- if (differ == false && !(curbuf->b_flags & BF_RECOVERED)
+ if (!differ && !(curbuf->b_flags & BF_RECOVERED)
&& vim_strchr(p_shm, SHM_ATTENTION) == NULL) {
sea_choice_T choice = SEA_CHOICE_NONE;
@@ -3898,7 +3914,7 @@ int ml_find_line_or_offset(buf_T *buf, linenr_T lnum, int *offp, bool no_ff)
// was never cached to start with anyway).
bool can_cache = (lnum != 0 && !ffdos && buf->b_ml.ml_line_lnum == lnum);
if (lnum == 0 || buf->b_ml.ml_line_lnum < lnum || !no_ff) {
- ml_flush_line(curbuf);
+ ml_flush_line(curbuf, false);
} else if (can_cache && buf->b_ml.ml_line_offset > 0) {
return (int)buf->b_ml.ml_line_offset;
}
@@ -3908,7 +3924,7 @@ int ml_find_line_or_offset(buf_T *buf, linenr_T lnum, int *offp, bool no_ff)
|| lnum < 0) {
// memline is currently empty. Although if it is loaded,
// it behaves like there is one empty line.
- if (!ffdos && buf->b_ml.ml_mfp && (lnum == 1 || lnum == 2)) {
+ if (no_ff && buf->b_ml.ml_mfp && (lnum == 1 || lnum == 2)) {
return lnum - 1;
}
return -1;
@@ -4025,7 +4041,7 @@ void goto_byte(int cnt)
{
int boff = cnt;
- ml_flush_line(curbuf); // cached line may be dirty
+ ml_flush_line(curbuf, false); // cached line may be dirty
setpcmark();
if (boff) {
boff--;