Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
memline.c File Reference
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/cursor.h"
#include "nvim/eval.h"
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
#include "nvim/getchar.h"
#include "nvim/input.h"
#include "nvim/main.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memfile.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/option.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
#include "nvim/os/process.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/screen.h"
#include "nvim/sha256.h"
#include "nvim/spell.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/version.h"
#include "nvim/vim.h"
#include "nvim/window.h"
#include <time.h>

Data Structures

struct  pointer_entry
struct  pointer_block
struct  data_block
struct  block0


#define CHECK(c, s)   do { } while (0)
#define DATA_ID   (('d' << 8) + 'a')
#define PTR_ID   (('p' << 8) + 't')
#define BLOCK0_ID0   'b'
#define BLOCK0_ID1   '0'
#define DB_MARKED   ((unsigned)1 << ((sizeof(unsigned) * 8) - 1))
#define INDEX_SIZE   (sizeof(unsigned))
#define HEADER_SIZE   (sizeof(DATA_BL) - INDEX_SIZE)
#define B0_FNAME_SIZE_ORG   900
#define B0_FNAME_SIZE_NOCRYPT   898
#define B0_FNAME_SIZE_CRYPT   890
#define B0_UNAME_SIZE   40
#define B0_HNAME_SIZE   40
#define B0_MAGIC_LONG   0x30313233L
#define B0_MAGIC_INT   0x20212223L
#define B0_MAGIC_SHORT   0x10111213L
#define B0_MAGIC_CHAR   0x55
#define B0_DIRTY   0x55
#define b0_dirty   b0_fname[B0_FNAME_SIZE_ORG - 1]
#define b0_flags   b0_fname[B0_FNAME_SIZE_ORG - 2]
#define B0_FF_MASK   3
#define B0_SAME_DIR   4
#define B0_HAS_FENC   8
#define STACK_INCR   5
#define ML_DELETE   0x11
#define ML_INSERT   0x12
#define ML_FIND   0x13
#define ML_FLUSH   0x02
#define ML_SIMPLE(x)   ((x) & 0x10)
#define MLCS_MAXL   800
#define MLCS_MINL   400


typedef struct block0 ZERO_BL
typedef struct pointer_block PTR_BL
typedef struct data_block DATA_BL
typedef struct pointer_entry PTR_EN


enum  upd_block0_T { UB_FNAME = 0, UB_SAME_DIR }


int ml_open (buf_T *buf)
void ml_setname (buf_T *buf)
void ml_open_files (void)
void ml_open_file (buf_T *buf)
void check_need_swap (bool newfile)
void ml_close (buf_T *buf, int del_file)
void ml_close_all (bool del_file)
void ml_close_notmod (void)
void ml_timestamp (buf_T *buf)
void ml_recover (bool checkext)
int recover_names (char_u *fname, int list, int nr, char_u **fname_out)
char * make_percent_swname (const char *dir, const char *name) FUNC_ATTR_NONNULL_ARG(1)
void get_b0_dict (const char *fname, dict_T *d)
void ml_sync_all (int check_file, int check_char, bool do_fsync)
void ml_preserve (buf_T *buf, int message, bool do_fsync)
char_uml_get (linenr_T lnum)
char_uml_get_pos (const pos_T *pos) FUNC_ATTR_NONNULL_ALL
int gchar_pos (pos_T *pos) FUNC_ATTR_NONNULL_ARG(1)
char_uml_get_buf (buf_T *buf, linenr_T lnum, bool will_change) FUNC_ATTR_NONNULL_ALL
int ml_line_alloced (void)
int ml_append (linenr_T lnum, char *line, colnr_T len, bool newfile)
int ml_append_buf (buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, bool newfile) FUNC_ATTR_NONNULL_ARG(1)
void ml_add_deleted_len (char_u *ptr, ssize_t len)
void ml_add_deleted_len_buf (buf_T *buf, char_u *ptr, ssize_t len)
int ml_replace (linenr_T lnum, char *line, bool copy)
int ml_replace_buf (buf_T *buf, linenr_T lnum, char_u *line, bool copy)
int ml_delete (linenr_T lnum, bool message)
void ml_setmarked (linenr_T lnum)
 set the B_MARKED flag for line 'lnum' More...
linenr_T ml_firstmarked (void)
 find the first line with its B_MARKED flag set More...
void ml_clearmarked (void)
 clear all DB_MARKED flags More...
size_t ml_flush_deleted_bytes (buf_T *buf, size_t *codepoints, size_t *codeunits)
char_umakeswapname (char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name)
char_uget_file_in_dir (char_u *fname, char_u *dname)
void copy_option_part ((char_u **) dirp,(char_u *) dir_name, dir_len, ",")
 for (;;)
 if (os_isdir((char_u *) dir_name))
else if (! *found_existing_dir &&**dirp==NUL)
 xfree (dir_name)
void ml_setflags (buf_T *buf)
long ml_find_line_or_offset (buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
void goto_byte (long cnt)
 Goto byte in buffer with offset 'cnt'. More...
int inc (pos_T *lp)
int incl (pos_T *lp)
 Same as inc(), but skip NUL at the end of non-empty lines. More...
int dec (pos_T *lp)
int decl (pos_T *lp)
 Same as dec(), but skip NUL at the end of non-empty lines. More...


static char size_t n
char * dir_name = xmalloc(dir_len)
char * buf_fname = buf->b_fname
const size_t dir_len = strlen(*dirp) + 1

Macro Definition Documentation


#define B0_DIRTY   0x55

◆ b0_dirty

#define b0_dirty   b0_fname[B0_FNAME_SIZE_ORG - 1]


#define B0_FF_MASK   3

◆ b0_flags

#define b0_flags   b0_fname[B0_FNAME_SIZE_ORG - 2]


#define B0_FNAME_SIZE_CRYPT   890


#define B0_FNAME_SIZE_NOCRYPT   898


#define B0_FNAME_SIZE_ORG   900


#define B0_HAS_FENC   8


#define B0_HNAME_SIZE   40


#define B0_MAGIC_CHAR   0x55


#define B0_MAGIC_INT   0x20212223L


#define B0_MAGIC_LONG   0x30313233L


#define B0_MAGIC_SHORT   0x10111213L


#define B0_SAME_DIR   4


#define B0_UNAME_SIZE   40


#define BLOCK0_ID0   'b'


#define BLOCK0_ID1   '0'


#define CHECK (   c,
)    do { } while (0)


#define DATA_ID   (('d' << 8) + 'a')




#define DB_MARKED   ((unsigned)1 << ((sizeof(unsigned) * 8) - 1))


#define HEADER_SIZE   (sizeof(DATA_BL) - INDEX_SIZE)


#define INDEX_SIZE   (sizeof(unsigned))


#define ML_DELETE   0x11


#define ML_FIND   0x13


#define ML_FLUSH   0x02


#define ML_INSERT   0x12


#define ML_SIMPLE (   x)    ((x) & 0x10)


#define MLCS_MAXL   800


#define MLCS_MINL   400


#define PTR_ID   (('p' << 8) + 't')


#define STACK_INCR   5

Typedef Documentation


typedef struct data_block DATA_BL


typedef struct pointer_block PTR_BL


typedef struct pointer_entry PTR_EN


typedef struct block0 ZERO_BL

Enumeration Type Documentation

◆ upd_block0_T


Function Documentation

◆ check_need_swap()

void check_need_swap ( bool  newfile)

If still need to create a swap file, and starting to edit a not-readonly file, or reading into an existing buffer, create a swap file now.

newfilereading file into new buffer

◆ copy_option_part()

void copy_option_part ( (char_u **)  dirp,
(char_u *)  dir_name,
dir_len  ,

◆ dec()

int dec ( pos_T lp)

◆ decl()

int decl ( pos_T lp)

Same as dec(), but skip NUL at the end of non-empty lines.

◆ for()

for ( ;;  )

◆ gchar_pos()

int gchar_pos ( pos_T pos)
codepoint at pos. pos must be either valid or have col set to MAXCOL!

◆ get_b0_dict()

void get_b0_dict ( const char *  fname,
dict_T d 

This is used by the swapinfo() function.

information found in swapfile "fname" in dictionary "d".

◆ get_file_in_dir()

char_u* get_file_in_dir ( char_u fname,
char_u dname 

Get file name to use for swap file or backup file. Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir' option "dname".

  • If "dname" is ".", return "fname" (swap file in dir of file).
  • If "dname" starts with "./", insert "dname" in "fname" (swap file relative to dir of file).
  • Otherwise, prepend "dname" to the tail of "fname" (swap file in specific dir).

The return value is an allocated string and can be NULL.

dnamedon't use "dirname", it is a global for Alpha

◆ goto_byte()

void goto_byte ( long  cnt)

Goto byte in buffer with offset 'cnt'.

◆ if() [1/2]

else if ( ! *found_existing_dir &&**  dirp = NUL)

◆ if() [2/2]

if ( os_isdir((char_u *) dir_name )

◆ inc()

int inc ( pos_T lp)

Increment the line pointer "lp" crossing line boundaries as necessary.

1 when going to the next line. 2 when moving forward onto a NUL at the end of the line). -1 when at the end of file. 0 otherwise.

◆ incl()

int incl ( pos_T lp)

Same as inc(), but skip NUL at the end of non-empty lines.

◆ make_percent_swname()

char* make_percent_swname ( const char *  dir,
const char *  name 

Append the full path to name with path separators made into percent signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")

◆ makeswapname()

char_u* makeswapname ( char_u fname,
char_u ffname,
buf_T buf,
char_u dir_name 

Make swap file name out of the file name and a directory name.

pointer to allocated memory or NULL.

◆ ml_add_deleted_len()

void ml_add_deleted_len ( char_u ptr,
ssize_t  len 

◆ ml_add_deleted_len_buf()

void ml_add_deleted_len_buf ( buf_T buf,
char_u ptr,
ssize_t  len 

◆ ml_append()

int ml_append ( linenr_T  lnum,
char *  line,
colnr_T  len,
bool  newfile 

Append a line after lnum (may be 0 to insert a line in front of the file). "line" does not need to be allocated, but can't be another line in a buffer, unlocking may make it invalid.

newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum will be set for recovery Check: The caller of this function should probably also call appended_lines().

lnumappend after this line (can be 0)
linetext of the new line
lenlength of new line, including NUL, or 0
newfileflag, see above
FAIL for failure, OK otherwise

◆ ml_append_buf()

int ml_append_buf ( buf_T buf,
linenr_T  lnum,
char_u line,
colnr_T  len,
bool  newfile 

Like ml_append() but for an arbitrary buffer. The buffer must already have a memline.

lnumappend after this line (can be 0)
linetext of the new line
lenlength of new line, including NUL, or 0
newfileflag, see above

◆ ml_clearmarked()

void ml_clearmarked ( void  )

clear all DB_MARKED flags

◆ ml_close()

void ml_close ( buf_T buf,
int  del_file 

Close memline for buffer 'buf'.

del_fileif TRUE, delete the swap file

◆ ml_close_all()

void ml_close_all ( bool  del_file)

Close all existing memlines and memfiles. Only used when exiting.

del_fileif true, delete the memfiles.

◆ ml_close_notmod()

void ml_close_notmod ( void  )

Close all memfiles for not modified buffers. Only use just before exiting!

◆ ml_delete()

int ml_delete ( linenr_T  lnum,
bool  message 

Delete line lnum in the current buffer.

The caller of this function should probably also call deleted_lines() after this.
messageShow "--No lines in buffer--" message.
FAIL for failure, OK otherwise

◆ ml_find_line_or_offset()

long ml_find_line_or_offset ( buf_T buf,
linenr_T  lnum,
long *  offp,
bool  no_ff 

Find offset for line or line with offset.

bufbuffer to use
lnumif > 0, find offset of lnum, return offset if == 0, return line with offset *offp
offpoffset to use to find line, store remaining column offset Should be NULL when getting offset of line
no_ffignore 'fileformat' option, always use one byte for NL.
-1 if information is not available

◆ ml_firstmarked()

linenr_T ml_firstmarked ( void  )

find the first line with its B_MARKED flag set

◆ ml_flush_deleted_bytes()

size_t ml_flush_deleted_bytes ( buf_T buf,
size_t *  codepoints,
size_t *  codeunits 

◆ ml_get()

char_u* ml_get ( linenr_T  lnum)
a pointer to a (read-only copy of a) line.

On failure an error message is given and IObuff is returned (to avoid having to check for error everywhere).

◆ ml_get_buf()

char_u* ml_get_buf ( buf_T buf,
linenr_T  lnum,
bool  will_change 
will_changetrue mark the buffer dirty (chars in the line will be changed)
a pointer to a line in a specific buffer

◆ ml_get_pos()

char_u* ml_get_pos ( const pos_T pos)
pointer to position "pos".

◆ ml_line_alloced()

int ml_line_alloced ( void  )

Check if a line that was just obtained by a call to ml_get is in allocated memory.

◆ ml_open()

int ml_open ( buf_T buf)

Open a new memline for "buf".

FAIL for failure, OK otherwise.

◆ ml_open_file()

void ml_open_file ( buf_T buf)

Open a swap file for an existing memfile, if there is no swap file yet. If we are unable to find a file name, mf_fname will be NULL and the memfile will be in memory only (no recovery possible).

◆ ml_open_files()

void ml_open_files ( void  )

Open a file for the memfile for all buffers that are not readonly or have been modified. Used when 'updatecount' changes from zero to non-zero.

◆ ml_preserve()

void ml_preserve ( buf_T buf,
int  message,
bool  do_fsync 

sync one buffer, including negative blocks

after this all the blocks are in the swap file

Used for the :preserve command and when the original file has been changed or deleted.

messageif TRUE, the success of preserving is reported.

◆ ml_recover()

void ml_recover ( bool  checkext)

Try to recover curbuf from the .swp file.

checkextif true, check the extension and detect whether it is a swap file.

◆ ml_replace()

int ml_replace ( linenr_T  lnum,
char *  line,
bool  copy 

◆ ml_replace_buf()

int ml_replace_buf ( buf_T buf,
linenr_T  lnum,
char_u line,
bool  copy 

Replace line "lnum", with buffering, in current buffer.

copyif true, make a copy of the line, otherwise the line has been copied to allocated memory already. if false, the "line" may be freed to add text properties!

Do not use it after calling ml_replace().

Check: The caller of this function should probably also call changed_lines(), unless update_screen(NOT_VALID) is used.

FAIL for failure, OK otherwise

◆ ml_setflags()

void ml_setflags ( buf_T buf)

Set the flags in the first block of the swap file:

  • file is modified or not: buf->b_changed
  • 'fileformat'
  • 'fileencoding'

◆ ml_setmarked()

void ml_setmarked ( linenr_T  lnum)

set the B_MARKED flag for line 'lnum'

◆ ml_setname()

void ml_setname ( buf_T buf)

ml_setname() is called when the file name of "buf" has been changed. It may rename the swap file.

◆ ml_sync_all()

void ml_sync_all ( int  check_file,
int  check_char,
bool  do_fsync 

sync all memlines

check_fileif TRUE, check if original file exists and was not changed.
check_charif TRUE, stop syncing when character becomes available, but

always sync at least one block.

◆ ml_timestamp()

void ml_timestamp ( buf_T buf)

Update the timestamp in the .swp file. Used when the file has been written.

◆ recover_names()

int recover_names ( char_u fname,
int  list,
int  nr,
char_u **  fname_out 

Find the names of swap files in current directory and the directory given with the 'directory' option.

Used to:

  • list the swap files for "vim -r"
  • count the number of swap files when recovering
  • list the swap files when recovering
  • find the name of the n'th swap file when recovering
fnamebase for swap file name
listwhen TRUE, list the swap file names
nrwhen non-zero, return nr'th swap file name
fname_outresult when "nr" > 0

◆ xfree()

xfree ( dir_name  )

Variable Documentation

◆ buf_fname

char* buf_fname = buf->b_fname

◆ dir_len

const size_t dir_len = strlen(*dirp) + 1

◆ dir_name

dir_name = xmalloc(dir_len)

◆ fname

return fname
Initial value:
= (char *)makeswapname((char_u *)buf_fname, buf->b_ffname, buf,

◆ n

char size_t n
Initial value:
char *fname
char_u * makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name)
Definition: memline.c:3224
char * dir_name
Definition: memline.c:3420
char *const buf
Definition: encode.c:234
Definition: memline.c:3434
unsigned char char_u
Definition: types.h:12
char * buf_fname
Definition: memline.c:3421