mirror of
https://github.com/neovim/neovim.git
synced 2025-09-16 00:08:19 +00:00
refactor: migrate comment style (#20012)
Done automatically using the following perl command: perl -pi -0777pe 's#\n\K */\*\n(.+?)\s*\*/\n#join("\n", map { $_ =~ s:^\s*\K \*://:; $_ } split("\n", $1)) . "\n"#sge' src/nvim/**/*.c Co-authored-by: zeertzjq <zeertzjq@outlook.com> Co-authored-by: zeertzjq <zeertzjq@outlook.com>
This commit is contained in:
@@ -48,25 +48,23 @@ typedef struct {
|
|||||||
#define GETFILE_SUCCESS(x) ((x) <= 0)
|
#define GETFILE_SUCCESS(x) ((x) <= 0)
|
||||||
#define MODIFIABLE(buf) (buf->b_p_ma)
|
#define MODIFIABLE(buf) (buf->b_p_ma)
|
||||||
|
|
||||||
/*
|
// Flags for w_valid.
|
||||||
* Flags for w_valid.
|
// These are set when something in a window structure becomes invalid, except
|
||||||
* These are set when something in a window structure becomes invalid, except
|
// when the cursor is moved. Call check_cursor_moved() before testing one of
|
||||||
* when the cursor is moved. Call check_cursor_moved() before testing one of
|
// the flags.
|
||||||
* the flags.
|
// These are reset when that thing has been updated and is valid again.
|
||||||
* These are reset when that thing has been updated and is valid again.
|
//
|
||||||
*
|
// Every function that invalidates one of these must call one of the
|
||||||
* Every function that invalidates one of these must call one of the
|
// invalidate_* functions.
|
||||||
* invalidate_* functions.
|
//
|
||||||
*
|
// w_valid is supposed to be used only in screen.c. From other files, use the
|
||||||
* w_valid is supposed to be used only in screen.c. From other files, use the
|
// functions that set or reset the flags.
|
||||||
* functions that set or reset the flags.
|
//
|
||||||
*
|
// VALID_BOTLINE VALID_BOTLINE_AP
|
||||||
* VALID_BOTLINE VALID_BOTLINE_AP
|
// on on w_botline valid
|
||||||
* on on w_botline valid
|
// off on w_botline approximated
|
||||||
* off on w_botline approximated
|
// off off w_botline not valid
|
||||||
* off off w_botline not valid
|
// on off not possible
|
||||||
* on off not possible
|
|
||||||
*/
|
|
||||||
#define VALID_WROW 0x01 // w_wrow (window row) is valid
|
#define VALID_WROW 0x01 // w_wrow (window row) is valid
|
||||||
#define VALID_WCOL 0x02 // w_wcol (window col) is valid
|
#define VALID_WCOL 0x02 // w_wcol (window col) is valid
|
||||||
#define VALID_VIRTCOL 0x04 // w_virtcol (file col) is valid
|
#define VALID_VIRTCOL 0x04 // w_virtcol (file col) is valid
|
||||||
@@ -112,9 +110,7 @@ typedef uint64_t disptick_T; // display tick type
|
|||||||
#include "nvim/sign_defs.h"
|
#include "nvim/sign_defs.h"
|
||||||
#include "nvim/terminal.h" // for Terminal
|
#include "nvim/terminal.h" // for Terminal
|
||||||
|
|
||||||
/*
|
// The taggy struct is used to store the information about a :tag command.
|
||||||
* The taggy struct is used to store the information about a :tag command.
|
|
||||||
*/
|
|
||||||
typedef struct taggy {
|
typedef struct taggy {
|
||||||
char *tagname; // tag name
|
char *tagname; // tag name
|
||||||
fmark_T fmark; // cursor position BEFORE ":tag"
|
fmark_T fmark; // cursor position BEFORE ":tag"
|
||||||
@@ -126,17 +122,13 @@ typedef struct taggy {
|
|||||||
typedef struct buffblock buffblock_T;
|
typedef struct buffblock buffblock_T;
|
||||||
typedef struct buffheader buffheader_T;
|
typedef struct buffheader buffheader_T;
|
||||||
|
|
||||||
/*
|
// structure used to store one block of the stuff/redo/recording buffers
|
||||||
* structure used to store one block of the stuff/redo/recording buffers
|
|
||||||
*/
|
|
||||||
struct buffblock {
|
struct buffblock {
|
||||||
buffblock_T *b_next; // pointer to next buffblock
|
buffblock_T *b_next; // pointer to next buffblock
|
||||||
char b_str[1]; // contents (actually longer)
|
char b_str[1]; // contents (actually longer)
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
// header used for the stuff buffer and the redo buffer
|
||||||
* header used for the stuff buffer and the redo buffer
|
|
||||||
*/
|
|
||||||
struct buffheader {
|
struct buffheader {
|
||||||
buffblock_T bh_first; // first (dummy) block of list
|
buffblock_T bh_first; // first (dummy) block of list
|
||||||
buffblock_T *bh_curr; // buffblock for appending
|
buffblock_T *bh_curr; // buffblock for appending
|
||||||
@@ -149,11 +141,9 @@ typedef struct {
|
|||||||
buffheader_T sr_old_redobuff;
|
buffheader_T sr_old_redobuff;
|
||||||
} save_redo_T;
|
} save_redo_T;
|
||||||
|
|
||||||
/*
|
// Structure that contains all options that are local to a window.
|
||||||
* Structure that contains all options that are local to a window.
|
// Used twice in a window: for the current buffer and for all buffers.
|
||||||
* Used twice in a window: for the current buffer and for all buffers.
|
// Also used in wininfo_T.
|
||||||
* Also used in wininfo_T.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int wo_arab;
|
int wo_arab;
|
||||||
#define w_p_arab w_onebuf_opt.wo_arab // 'arabic'
|
#define w_p_arab w_onebuf_opt.wo_arab // 'arabic'
|
||||||
@@ -268,16 +258,14 @@ typedef struct {
|
|||||||
#define w_p_script_ctx w_onebuf_opt.wo_script_ctx
|
#define w_p_script_ctx w_onebuf_opt.wo_script_ctx
|
||||||
} winopt_T;
|
} winopt_T;
|
||||||
|
|
||||||
/*
|
// Window info stored with a buffer.
|
||||||
* Window info stored with a buffer.
|
//
|
||||||
*
|
// Two types of info are kept for a buffer which are associated with a
|
||||||
* Two types of info are kept for a buffer which are associated with a
|
// specific window:
|
||||||
* specific window:
|
// 1. Each window can have a different line number associated with a buffer.
|
||||||
* 1. Each window can have a different line number associated with a buffer.
|
// 2. The window-local options for a buffer work in a similar way.
|
||||||
* 2. The window-local options for a buffer work in a similar way.
|
// The window-info is kept in a list at b_wininfo. It is kept in
|
||||||
* The window-info is kept in a list at b_wininfo. It is kept in
|
// most-recently-used order.
|
||||||
* most-recently-used order.
|
|
||||||
*/
|
|
||||||
struct wininfo_S {
|
struct wininfo_S {
|
||||||
wininfo_T *wi_next; // next entry or NULL for last entry
|
wininfo_T *wi_next; // next entry or NULL for last entry
|
||||||
wininfo_T *wi_prev; // previous entry or NULL for first entry
|
wininfo_T *wi_prev; // previous entry or NULL for first entry
|
||||||
@@ -290,12 +278,10 @@ struct wininfo_S {
|
|||||||
int wi_changelistidx; // copy of w_changelistidx
|
int wi_changelistidx; // copy of w_changelistidx
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
// Argument list: Array of file names.
|
||||||
* Argument list: Array of file names.
|
// Used for the global argument list and the argument lists local to a window.
|
||||||
* Used for the global argument list and the argument lists local to a window.
|
//
|
||||||
*
|
// TODO(neovim): move struct arglist to another header
|
||||||
* TODO: move struct arglist to another header
|
|
||||||
*/
|
|
||||||
typedef struct arglist {
|
typedef struct arglist {
|
||||||
garray_T al_ga; // growarray with the array of file names
|
garray_T al_ga; // growarray with the array of file names
|
||||||
int al_refcount; // number of windows using this arglist
|
int al_refcount; // number of windows using this arglist
|
||||||
@@ -321,9 +307,7 @@ typedef struct argentry {
|
|||||||
#define ARGCOUNT (ALIST(curwin)->al_ga.ga_len)
|
#define ARGCOUNT (ALIST(curwin)->al_ga.ga_len)
|
||||||
#define WARGCOUNT(wp) (ALIST(wp)->al_ga.ga_len)
|
#define WARGCOUNT(wp) (ALIST(wp)->al_ga.ga_len)
|
||||||
|
|
||||||
/*
|
// Used for the typeahead buffer: typebuf.
|
||||||
* Used for the typeahead buffer: typebuf.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t *tb_buf; // buffer for typed characters
|
uint8_t *tb_buf; // buffer for typed characters
|
||||||
uint8_t *tb_noremap; // mapping flags for characters in tb_buf[]
|
uint8_t *tb_noremap; // mapping flags for characters in tb_buf[]
|
||||||
@@ -347,9 +331,7 @@ typedef struct {
|
|||||||
String save_inputbuf;
|
String save_inputbuf;
|
||||||
} tasave_T;
|
} tasave_T;
|
||||||
|
|
||||||
/*
|
// Structure used for mappings and abbreviations.
|
||||||
* Structure used for mappings and abbreviations.
|
|
||||||
*/
|
|
||||||
typedef struct mapblock mapblock_T;
|
typedef struct mapblock mapblock_T;
|
||||||
struct mapblock {
|
struct mapblock {
|
||||||
mapblock_T *m_next; // next mapblock in list
|
mapblock_T *m_next; // next mapblock in list
|
||||||
@@ -414,9 +396,7 @@ struct stl_item {
|
|||||||
|
|
||||||
typedef struct qf_info_S qf_info_T;
|
typedef struct qf_info_S qf_info_T;
|
||||||
|
|
||||||
/*
|
// Used for :syntime: timing of executing a syntax pattern.
|
||||||
* Used for :syntime: timing of executing a syntax pattern.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
proftime_T total; // total time used
|
proftime_T total; // total time used
|
||||||
proftime_T slowest; // time of slowest call
|
proftime_T slowest; // time of slowest call
|
||||||
@@ -424,10 +404,8 @@ typedef struct {
|
|||||||
long match; // nr of times matched
|
long match; // nr of times matched
|
||||||
} syn_time_T;
|
} syn_time_T;
|
||||||
|
|
||||||
/*
|
// These are items normally related to a buffer. But when using ":ownsyntax"
|
||||||
* These are items normally related to a buffer. But when using ":ownsyntax"
|
// a window may have its own instance.
|
||||||
* a window may have its own instance.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
hashtab_T b_keywtab; // syntax keywords hash table
|
hashtab_T b_keywtab; // syntax keywords hash table
|
||||||
hashtab_T b_keywtab_ic; // idem, ignore case
|
hashtab_T b_keywtab_ic; // idem, ignore case
|
||||||
@@ -514,13 +492,11 @@ EXTERN int curbuf_splice_pending INIT(= 0);
|
|||||||
// Maximum number of maphash blocks we will have
|
// Maximum number of maphash blocks we will have
|
||||||
#define MAX_MAPHASH 256
|
#define MAX_MAPHASH 256
|
||||||
|
|
||||||
/*
|
// buffer: structure that holds information about one file
|
||||||
* buffer: structure that holds information about one file
|
//
|
||||||
*
|
// Several windows can share a single Buffer
|
||||||
* Several windows can share a single Buffer
|
// A buffer is unallocated if there is no memfile for it.
|
||||||
* A buffer is unallocated if there is no memfile for it.
|
// A buffer is new if the associated file has never been loaded yet.
|
||||||
* A buffer is new if the associated file has never been loaded yet.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct file_buffer {
|
struct file_buffer {
|
||||||
handle_T handle; // unique id for the buffer (buffer number)
|
handle_T handle; // unique id for the buffer (buffer number)
|
||||||
@@ -570,15 +546,13 @@ struct file_buffer {
|
|||||||
varnumber_T b_last_changedtick_pum; // b:changedtick when TextChangedP was
|
varnumber_T b_last_changedtick_pum; // b:changedtick when TextChangedP was
|
||||||
// last triggered.
|
// last triggered.
|
||||||
|
|
||||||
bool b_saving; /* Set to true if we are in the middle of
|
bool b_saving; // Set to true if we are in the middle of
|
||||||
saving the buffer. */
|
// saving the buffer.
|
||||||
|
|
||||||
/*
|
// Changes to a buffer require updating of the display. To minimize the
|
||||||
* Changes to a buffer require updating of the display. To minimize the
|
// work, remember changes made and update everything at once.
|
||||||
* work, remember changes made and update everything at once.
|
bool b_mod_set; // true when there are changes since the last
|
||||||
*/
|
// time the display was updated
|
||||||
bool b_mod_set; /* true when there are changes since the last
|
|
||||||
time the display was updated */
|
|
||||||
linenr_T b_mod_top; // topmost lnum that was changed
|
linenr_T b_mod_top; // topmost lnum that was changed
|
||||||
linenr_T b_mod_bot; // lnum below last changed line, AFTER the
|
linenr_T b_mod_bot; // lnum below last changed line, AFTER the
|
||||||
// change
|
// change
|
||||||
@@ -609,17 +583,13 @@ struct file_buffer {
|
|||||||
fmark_T b_last_insert; // where Insert mode was left
|
fmark_T b_last_insert; // where Insert mode was left
|
||||||
fmark_T b_last_change; // position of last change: '. mark
|
fmark_T b_last_change; // position of last change: '. mark
|
||||||
|
|
||||||
/*
|
// the changelist contains old change positions
|
||||||
* the changelist contains old change positions
|
|
||||||
*/
|
|
||||||
fmark_T b_changelist[JUMPLISTSIZE];
|
fmark_T b_changelist[JUMPLISTSIZE];
|
||||||
int b_changelistlen; // number of active entries
|
int b_changelistlen; // number of active entries
|
||||||
bool b_new_change; // set by u_savecommon()
|
bool b_new_change; // set by u_savecommon()
|
||||||
|
|
||||||
/*
|
// Character table, only used in charset.c for 'iskeyword'
|
||||||
* Character table, only used in charset.c for 'iskeyword'
|
// bitset with 4*64=256 bits: 1 bit per character 0-255.
|
||||||
* bitset with 4*64=256 bits: 1 bit per character 0-255.
|
|
||||||
*/
|
|
||||||
uint64_t b_chartab[4];
|
uint64_t b_chartab[4];
|
||||||
|
|
||||||
// Table used for mappings local to a buffer.
|
// Table used for mappings local to a buffer.
|
||||||
@@ -629,18 +599,14 @@ struct file_buffer {
|
|||||||
mapblock_T *b_first_abbr;
|
mapblock_T *b_first_abbr;
|
||||||
// User commands local to the buffer.
|
// User commands local to the buffer.
|
||||||
garray_T b_ucmds;
|
garray_T b_ucmds;
|
||||||
/*
|
// start and end of an operator, also used for '[ and ']
|
||||||
* start and end of an operator, also used for '[ and ']
|
|
||||||
*/
|
|
||||||
pos_T b_op_start;
|
pos_T b_op_start;
|
||||||
pos_T b_op_start_orig; // used for Insstart_orig
|
pos_T b_op_start_orig; // used for Insstart_orig
|
||||||
pos_T b_op_end;
|
pos_T b_op_end;
|
||||||
|
|
||||||
bool b_marks_read; // Have we read ShaDa marks yet?
|
bool b_marks_read; // Have we read ShaDa marks yet?
|
||||||
|
|
||||||
/*
|
// The following only used in undo.c.
|
||||||
* The following only used in undo.c.
|
|
||||||
*/
|
|
||||||
u_header_T *b_u_oldhead; // pointer to oldest header
|
u_header_T *b_u_oldhead; // pointer to oldest header
|
||||||
u_header_T *b_u_newhead; // pointer to newest header; may not be valid
|
u_header_T *b_u_newhead; // pointer to newest header; may not be valid
|
||||||
// if b_u_curhead is not NULL
|
// if b_u_curhead is not NULL
|
||||||
@@ -673,11 +639,9 @@ struct file_buffer {
|
|||||||
#define KEYMAP_LOADED 2 // 'keymap' mappings have been loaded
|
#define KEYMAP_LOADED 2 // 'keymap' mappings have been loaded
|
||||||
garray_T b_kmap_ga; // the keymap table
|
garray_T b_kmap_ga; // the keymap table
|
||||||
|
|
||||||
/*
|
// Options local to a buffer.
|
||||||
* Options local to a buffer.
|
// They are here because their value depends on the type of file
|
||||||
* They are here because their value depends on the type of file
|
// or contents of the file being edited.
|
||||||
* or contents of the file being edited.
|
|
||||||
*/
|
|
||||||
bool b_p_initialized; // set when options initialized
|
bool b_p_initialized; // set when options initialized
|
||||||
|
|
||||||
LastSet b_p_script_ctx[BV_COUNT]; // SCTXs for buffer-local options
|
LastSet b_p_script_ctx[BV_COUNT]; // SCTXs for buffer-local options
|
||||||
@@ -834,19 +798,17 @@ struct file_buffer {
|
|||||||
ScopeDictDictItem b_bufvar; ///< Variable for "b:" Dictionary.
|
ScopeDictDictItem b_bufvar; ///< Variable for "b:" Dictionary.
|
||||||
dict_T *b_vars; ///< b: scope dictionary.
|
dict_T *b_vars; ///< b: scope dictionary.
|
||||||
|
|
||||||
/* When a buffer is created, it starts without a swap file. b_may_swap is
|
// When a buffer is created, it starts without a swap file. b_may_swap is
|
||||||
* then set to indicate that a swap file may be opened later. It is reset
|
// then set to indicate that a swap file may be opened later. It is reset
|
||||||
* if a swap file could not be opened.
|
// if a swap file could not be opened.
|
||||||
*/
|
|
||||||
bool b_may_swap;
|
bool b_may_swap;
|
||||||
bool b_did_warn; /* Set to true if user has been warned on first
|
bool b_did_warn; /* Set to true if user has been warned on first
|
||||||
change of a read-only file */
|
change of a read-only file */
|
||||||
|
|
||||||
/* Two special kinds of buffers:
|
// Two special kinds of buffers:
|
||||||
* help buffer - used for help files, won't use a swap file.
|
// help buffer - used for help files, won't use a swap file.
|
||||||
* spell buffer - used for spell info, never displayed and doesn't have a
|
// spell buffer - used for spell info, never displayed and doesn't have a
|
||||||
* file name.
|
// file name.
|
||||||
*/
|
|
||||||
bool b_help; // true for help file buffer (when set b_p_bt
|
bool b_help; // true for help file buffer (when set b_p_bt
|
||||||
// is "help")
|
// is "help")
|
||||||
bool b_spell; // True for a spell file buffer, most fields
|
bool b_spell; // True for a spell file buffer, most fields
|
||||||
@@ -906,25 +868,21 @@ struct file_buffer {
|
|||||||
int b_diff_failed; // internal diff failed for this buffer
|
int b_diff_failed; // internal diff failed for this buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
// Stuff for diff mode.
|
||||||
* Stuff for diff mode.
|
|
||||||
*/
|
|
||||||
#define DB_COUNT 8 // up to four buffers can be diff'ed
|
#define DB_COUNT 8 // up to four buffers can be diff'ed
|
||||||
|
|
||||||
/*
|
// Each diffblock defines where a block of lines starts in each of the buffers
|
||||||
* Each diffblock defines where a block of lines starts in each of the buffers
|
// and how many lines it occupies in that buffer. When the lines are missing
|
||||||
* and how many lines it occupies in that buffer. When the lines are missing
|
// in the buffer the df_count[] is zero. This is all counted in
|
||||||
* in the buffer the df_count[] is zero. This is all counted in
|
// buffer lines.
|
||||||
* buffer lines.
|
// There is always at least one unchanged line in between the diffs.
|
||||||
* There is always at least one unchanged line in between the diffs.
|
// Otherwise it would have been included in the diff above or below it.
|
||||||
* Otherwise it would have been included in the diff above or below it.
|
// df_lnum[] + df_count[] is the lnum below the change. When in one buffer
|
||||||
* df_lnum[] + df_count[] is the lnum below the change. When in one buffer
|
// lines have been inserted, in the other buffer df_lnum[] is the line below
|
||||||
* lines have been inserted, in the other buffer df_lnum[] is the line below
|
// the insertion and df_count[] is zero. When appending lines at the end of
|
||||||
* the insertion and df_count[] is zero. When appending lines at the end of
|
// the buffer, df_lnum[] is one beyond the end!
|
||||||
* the buffer, df_lnum[] is one beyond the end!
|
// This is using a linked list, because the number of differences is expected
|
||||||
* This is using a linked list, because the number of differences is expected
|
// to be reasonable small. The list is sorted on lnum.
|
||||||
* to be reasonable small. The list is sorted on lnum.
|
|
||||||
*/
|
|
||||||
typedef struct diffblock_S diff_T;
|
typedef struct diffblock_S diff_T;
|
||||||
struct diffblock_S {
|
struct diffblock_S {
|
||||||
diff_T *df_next;
|
diff_T *df_next;
|
||||||
@@ -964,18 +922,16 @@ struct tabpage_S {
|
|||||||
char *tp_prevdir; ///< Previous directory.
|
char *tp_prevdir; ///< Previous directory.
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
// Structure to cache info for displayed lines in w_lines[].
|
||||||
* Structure to cache info for displayed lines in w_lines[].
|
// Each logical line has one entry.
|
||||||
* Each logical line has one entry.
|
// The entry tells how the logical line is currently displayed in the window.
|
||||||
* The entry tells how the logical line is currently displayed in the window.
|
// This is updated when displaying the window.
|
||||||
* This is updated when displaying the window.
|
// When the display is changed (e.g., when clearing the screen) w_lines_valid
|
||||||
* When the display is changed (e.g., when clearing the screen) w_lines_valid
|
// is changed to exclude invalid entries.
|
||||||
* is changed to exclude invalid entries.
|
// When making changes to the buffer, wl_valid is reset to indicate wl_size
|
||||||
* When making changes to the buffer, wl_valid is reset to indicate wl_size
|
// may not reflect what is actually in the buffer. When wl_valid is false,
|
||||||
* may not reflect what is actually in the buffer. When wl_valid is false,
|
// the entries can only be used to count the number of displayed lines used.
|
||||||
* the entries can only be used to count the number of displayed lines used.
|
// wl_lnum and wl_lastlnum are invalid too.
|
||||||
* wl_lnum and wl_lastlnum are invalid too.
|
|
||||||
*/
|
|
||||||
typedef struct w_line {
|
typedef struct w_line {
|
||||||
linenr_T wl_lnum; // buffer line number for logical line
|
linenr_T wl_lnum; // buffer line number for logical line
|
||||||
uint16_t wl_size; // height in screen lines
|
uint16_t wl_size; // height in screen lines
|
||||||
@@ -984,10 +940,8 @@ typedef struct w_line {
|
|||||||
linenr_T wl_lastlnum; // last buffer line number for logical line
|
linenr_T wl_lastlnum; // last buffer line number for logical line
|
||||||
} wline_T;
|
} wline_T;
|
||||||
|
|
||||||
/*
|
// Windows are kept in a tree of frames. Each frame has a column (FR_COL)
|
||||||
* Windows are kept in a tree of frames. Each frame has a column (FR_COL)
|
// or row (FR_ROW) layout or is a leaf, which has a window.
|
||||||
* or row (FR_ROW) layout or is a leaf, which has a window.
|
|
||||||
*/
|
|
||||||
struct frame_S {
|
struct frame_S {
|
||||||
char fr_layout; // FR_LEAF, FR_COL or FR_ROW
|
char fr_layout; // FR_LEAF, FR_COL or FR_ROW
|
||||||
int fr_width;
|
int fr_width;
|
||||||
@@ -1008,12 +962,10 @@ struct frame_S {
|
|||||||
#define FR_ROW 1 // frame with a row of windows
|
#define FR_ROW 1 // frame with a row of windows
|
||||||
#define FR_COL 2 // frame with a column of windows
|
#define FR_COL 2 // frame with a column of windows
|
||||||
|
|
||||||
/*
|
// Struct used for highlighting 'hlsearch' matches, matches defined by
|
||||||
* Struct used for highlighting 'hlsearch' matches, matches defined by
|
// ":match" and matches defined by match functions.
|
||||||
* ":match" and matches defined by match functions.
|
// For 'hlsearch' there is one pattern for all windows. For ":match" and the
|
||||||
* For 'hlsearch' there is one pattern for all windows. For ":match" and the
|
// match functions there is a different pattern for each window.
|
||||||
* match functions there is a different pattern for each window.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
regmmatch_T rm; // points to the regexp program; contains last found
|
regmmatch_T rm; // points to the regexp program; contains last found
|
||||||
// match (may continue in next line)
|
// match (may continue in next line)
|
||||||
@@ -1049,10 +1001,8 @@ struct posmatch {
|
|||||||
linenr_T botlnum; ///< bottom buffer line
|
linenr_T botlnum; ///< bottom buffer line
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
// matchitem_T provides a linked list for storing match items for ":match" and
|
||||||
* matchitem_T provides a linked list for storing match items for ":match" and
|
// the match functions.
|
||||||
* the match functions.
|
|
||||||
*/
|
|
||||||
typedef struct matchitem matchitem_T;
|
typedef struct matchitem matchitem_T;
|
||||||
struct matchitem {
|
struct matchitem {
|
||||||
matchitem_T *next;
|
matchitem_T *next;
|
||||||
@@ -1221,12 +1171,10 @@ struct window_S {
|
|||||||
int eob;
|
int eob;
|
||||||
} w_p_fcs_chars;
|
} w_p_fcs_chars;
|
||||||
|
|
||||||
/*
|
// "w_topline", "w_leftcol" and "w_skipcol" specify the offsets for
|
||||||
* "w_topline", "w_leftcol" and "w_skipcol" specify the offsets for
|
// displaying the buffer.
|
||||||
* displaying the buffer.
|
linenr_T w_topline; // buffer line number of the line at the
|
||||||
*/
|
// top of the window
|
||||||
linenr_T w_topline; /* buffer line number of the line at the
|
|
||||||
top of the window */
|
|
||||||
char w_topline_was_set; // flag set to true when topline is set,
|
char w_topline_was_set; // flag set to true when topline is set,
|
||||||
// e.g. by winrestview()
|
// e.g. by winrestview()
|
||||||
int w_topfill; // number of filler lines above w_topline
|
int w_topfill; // number of filler lines above w_topline
|
||||||
@@ -1279,15 +1227,12 @@ struct window_S {
|
|||||||
int w_height_outer;
|
int w_height_outer;
|
||||||
int w_width_outer;
|
int w_width_outer;
|
||||||
|
|
||||||
/*
|
// === start of cached values ====
|
||||||
* === start of cached values ====
|
|
||||||
*/
|
// Recomputing is minimized by storing the result of computations.
|
||||||
/*
|
// Use functions in screen.c to check if they are valid and to update.
|
||||||
* Recomputing is minimized by storing the result of computations.
|
// w_valid is a bitfield of flags, which indicate if specific values are
|
||||||
* Use functions in screen.c to check if they are valid and to update.
|
// valid or need to be recomputed.
|
||||||
* w_valid is a bitfield of flags, which indicate if specific values are
|
|
||||||
* valid or need to be recomputed.
|
|
||||||
*/
|
|
||||||
int w_valid;
|
int w_valid;
|
||||||
pos_T w_valid_cursor; /* last known position of w_cursor, used
|
pos_T w_valid_cursor; /* last known position of w_cursor, used
|
||||||
to adjust w_valid */
|
to adjust w_valid */
|
||||||
@@ -1295,10 +1240,8 @@ struct window_S {
|
|||||||
|
|
||||||
bool w_viewport_invalid;
|
bool w_viewport_invalid;
|
||||||
|
|
||||||
/*
|
// w_cline_height is the number of physical lines taken by the buffer line
|
||||||
* w_cline_height is the number of physical lines taken by the buffer line
|
// that the cursor is on. We use this to avoid extra calls to plines_win().
|
||||||
* that the cursor is on. We use this to avoid extra calls to plines_win().
|
|
||||||
*/
|
|
||||||
int w_cline_height; // current size of cursor line
|
int w_cline_height; // current size of cursor line
|
||||||
bool w_cline_folded; // cursor line is folded
|
bool w_cline_folded; // cursor line is folded
|
||||||
|
|
||||||
@@ -1311,11 +1254,9 @@ struct window_S {
|
|||||||
// more than one screen line or when
|
// more than one screen line or when
|
||||||
// w_leftcol is non-zero
|
// w_leftcol is non-zero
|
||||||
|
|
||||||
/*
|
// w_wrow and w_wcol specify the cursor position in the window.
|
||||||
* w_wrow and w_wcol specify the cursor position in the window.
|
// This is related to positions in the window, not in the display or
|
||||||
* This is related to positions in the window, not in the display or
|
// buffer, thus w_wrow is relative to w_winrow.
|
||||||
* buffer, thus w_wrow is relative to w_winrow.
|
|
||||||
*/
|
|
||||||
int w_wrow, w_wcol; // cursor position in window
|
int w_wrow, w_wcol; // cursor position in window
|
||||||
|
|
||||||
linenr_T w_botline; // number of the line below the bottom of
|
linenr_T w_botline; // number of the line below the bottom of
|
||||||
@@ -1324,16 +1265,14 @@ struct window_S {
|
|||||||
int w_filler_rows; // number of filler rows at the end of the
|
int w_filler_rows; // number of filler rows at the end of the
|
||||||
// window
|
// window
|
||||||
|
|
||||||
/*
|
// Info about the lines currently in the window is remembered to avoid
|
||||||
* Info about the lines currently in the window is remembered to avoid
|
// recomputing it every time. The allocated size of w_lines[] is Rows.
|
||||||
* recomputing it every time. The allocated size of w_lines[] is Rows.
|
// Only the w_lines_valid entries are actually valid.
|
||||||
* Only the w_lines_valid entries are actually valid.
|
// When the display is up-to-date w_lines[0].wl_lnum is equal to w_topline
|
||||||
* When the display is up-to-date w_lines[0].wl_lnum is equal to w_topline
|
// and w_lines[w_lines_valid - 1].wl_lnum is equal to w_botline.
|
||||||
* and w_lines[w_lines_valid - 1].wl_lnum is equal to w_botline.
|
// Between changing text and updating the display w_lines[] represents
|
||||||
* Between changing text and updating the display w_lines[] represents
|
// what is currently displayed. wl_valid is reset to indicated this.
|
||||||
* what is currently displayed. wl_valid is reset to indicated this.
|
// This is used for efficient redrawing.
|
||||||
* This is used for efficient redrawing.
|
|
||||||
*/
|
|
||||||
int w_lines_valid; // number of valid entries
|
int w_lines_valid; // number of valid entries
|
||||||
wline_T *w_lines;
|
wline_T *w_lines;
|
||||||
|
|
||||||
@@ -1346,9 +1285,7 @@ struct window_S {
|
|||||||
// column being used
|
// column being used
|
||||||
int w_scwidth; // width of 'signcolumn'
|
int w_scwidth; // width of 'signcolumn'
|
||||||
|
|
||||||
/*
|
// === end of cached values ===
|
||||||
* === end of cached values ===
|
|
||||||
*/
|
|
||||||
|
|
||||||
int w_redr_type; // type of redraw to be performed on win
|
int w_redr_type; // type of redraw to be performed on win
|
||||||
int w_upd_rows; // number of window lines to update when
|
int w_upd_rows; // number of window lines to update when
|
||||||
@@ -1406,17 +1343,13 @@ struct window_S {
|
|||||||
ScopeDictDictItem w_winvar; ///< Variable for "w:" dictionary.
|
ScopeDictDictItem w_winvar; ///< Variable for "w:" dictionary.
|
||||||
dict_T *w_vars; ///< Dictionary with w: variables.
|
dict_T *w_vars; ///< Dictionary with w: variables.
|
||||||
|
|
||||||
/*
|
// The w_prev_pcmark field is used to check whether we really did jump to
|
||||||
* The w_prev_pcmark field is used to check whether we really did jump to
|
// a new line after setting the w_pcmark. If not, then we revert to
|
||||||
* a new line after setting the w_pcmark. If not, then we revert to
|
// using the previous w_pcmark.
|
||||||
* using the previous w_pcmark.
|
|
||||||
*/
|
|
||||||
pos_T w_pcmark; // previous context mark
|
pos_T w_pcmark; // previous context mark
|
||||||
pos_T w_prev_pcmark; // previous w_pcmark
|
pos_T w_prev_pcmark; // previous w_pcmark
|
||||||
|
|
||||||
/*
|
// the jumplist contains old cursor positions
|
||||||
* the jumplist contains old cursor positions
|
|
||||||
*/
|
|
||||||
xfmark_T w_jumplist[JUMPLISTSIZE];
|
xfmark_T w_jumplist[JUMPLISTSIZE];
|
||||||
int w_jumplistlen; // number of active entries
|
int w_jumplistlen; // number of active entries
|
||||||
int w_jumplistidx; // current position
|
int w_jumplistidx; // current position
|
||||||
@@ -1426,12 +1359,10 @@ struct window_S {
|
|||||||
matchitem_T *w_match_head; // head of match list
|
matchitem_T *w_match_head; // head of match list
|
||||||
int w_next_match_id; // next match ID
|
int w_next_match_id; // next match ID
|
||||||
|
|
||||||
/*
|
// the tagstack grows from 0 upwards:
|
||||||
* the tagstack grows from 0 upwards:
|
// entry 0: older
|
||||||
* entry 0: older
|
// entry 1: newer
|
||||||
* entry 1: newer
|
// entry 2: newest
|
||||||
* entry 2: newest
|
|
||||||
*/
|
|
||||||
taggy_T w_tagstack[TAGSTACKSIZE]; // the tag stack
|
taggy_T w_tagstack[TAGSTACKSIZE]; // the tag stack
|
||||||
int w_tagstackidx; // idx just below active entry
|
int w_tagstackidx; // idx just below active entry
|
||||||
int w_tagstacklen; // number of tags on stack
|
int w_tagstacklen; // number of tags on stack
|
||||||
@@ -1442,12 +1373,10 @@ struct window_S {
|
|||||||
bool w_floating; ///< whether the window is floating
|
bool w_floating; ///< whether the window is floating
|
||||||
FloatConfig w_float_config;
|
FloatConfig w_float_config;
|
||||||
|
|
||||||
/*
|
// w_fraction is the fractional row of the cursor within the window, from
|
||||||
* w_fraction is the fractional row of the cursor within the window, from
|
// 0 at the top row to FRACTION_MULT at the last row.
|
||||||
* 0 at the top row to FRACTION_MULT at the last row.
|
// w_prev_fraction_row was the actual cursor row when w_fraction was last
|
||||||
* w_prev_fraction_row was the actual cursor row when w_fraction was last
|
// calculated.
|
||||||
* calculated.
|
|
||||||
*/
|
|
||||||
int w_fraction;
|
int w_fraction;
|
||||||
int w_prev_fraction_row;
|
int w_prev_fraction_row;
|
||||||
|
|
||||||
|
385
src/nvim/edit.c
385
src/nvim/edit.c
@@ -1,9 +1,7 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
/*
|
// edit.c: functions for Insert mode
|
||||||
* edit.c: functions for Insert mode
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -1359,9 +1357,7 @@ void ins_redraw(bool ready)
|
|||||||
emsg_on_display = false; // may remove error message now
|
emsg_on_display = false; // may remove error message now
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Handle a CTRL-V or CTRL-Q typed in Insert mode.
|
||||||
* Handle a CTRL-V or CTRL-Q typed in Insert mode.
|
|
||||||
*/
|
|
||||||
static void ins_ctrl_v(void)
|
static void ins_ctrl_v(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -1391,10 +1387,8 @@ static void ins_ctrl_v(void)
|
|||||||
revins_legal++;
|
revins_legal++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Put a character directly onto the screen. It's not stored in a buffer.
|
||||||
* Put a character directly onto the screen. It's not stored in a buffer.
|
// Used while handling CTRL-K, CTRL-V, etc. in Insert mode.
|
||||||
* Used while handling CTRL-K, CTRL-V, etc. in Insert mode.
|
|
||||||
*/
|
|
||||||
static int pc_status;
|
static int pc_status;
|
||||||
#define PC_STATUS_UNSET 0 // pc_bytes was not set
|
#define PC_STATUS_UNSET 0 // pc_bytes was not set
|
||||||
#define PC_STATUS_RIGHT 1 // right half of double-wide char
|
#define PC_STATUS_RIGHT 1 // right half of double-wide char
|
||||||
@@ -1511,9 +1505,7 @@ bool prompt_curpos_editable(void)
|
|||||||
&& curwin->w_cursor.col >= (int)STRLEN(prompt_text());
|
&& curwin->w_cursor.col >= (int)STRLEN(prompt_text());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Undo the previous edit_putchar().
|
||||||
* Undo the previous edit_putchar().
|
|
||||||
*/
|
|
||||||
void edit_unputchar(void)
|
void edit_unputchar(void)
|
||||||
{
|
{
|
||||||
if (pc_status != PC_STATUS_UNSET && pc_row >= msg_scrolled) {
|
if (pc_status != PC_STATUS_UNSET && pc_row >= msg_scrolled) {
|
||||||
@@ -1528,10 +1520,8 @@ void edit_unputchar(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Called when p_dollar is set: display a '$' at the end of the changed text
|
||||||
* Called when p_dollar is set: display a '$' at the end of the changed text
|
// Only works when cursor is in the line that changes.
|
||||||
* Only works when cursor is in the line that changes.
|
|
||||||
*/
|
|
||||||
void display_dollar(colnr_T col)
|
void display_dollar(colnr_T col)
|
||||||
{
|
{
|
||||||
colnr_T save_col;
|
colnr_T save_col;
|
||||||
@@ -1554,10 +1544,8 @@ void display_dollar(colnr_T col)
|
|||||||
curwin->w_cursor.col = save_col;
|
curwin->w_cursor.col = save_col;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Call this function before moving the cursor from the normal insert position
|
||||||
* Call this function before moving the cursor from the normal insert position
|
// in insert mode.
|
||||||
* in insert mode.
|
|
||||||
*/
|
|
||||||
void undisplay_dollar(void)
|
void undisplay_dollar(void)
|
||||||
{
|
{
|
||||||
if (dollar_vcol >= 0) {
|
if (dollar_vcol >= 0) {
|
||||||
@@ -1600,11 +1588,9 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
|
|||||||
vc = getvcol_nolist(&curwin->w_cursor);
|
vc = getvcol_nolist(&curwin->w_cursor);
|
||||||
vcol = vc;
|
vcol = vc;
|
||||||
|
|
||||||
/*
|
// For Replace mode we need to fix the replace stack later, which is only
|
||||||
* For Replace mode we need to fix the replace stack later, which is only
|
// possible when the cursor is in the indent. Remember the number of
|
||||||
* possible when the cursor is in the indent. Remember the number of
|
// characters before the cursor if it's possible.
|
||||||
* characters before the cursor if it's possible.
|
|
||||||
*/
|
|
||||||
start_col = curwin->w_cursor.col;
|
start_col = curwin->w_cursor.col;
|
||||||
|
|
||||||
// determine offset from first non-blank
|
// determine offset from first non-blank
|
||||||
@@ -1614,10 +1600,8 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
|
|||||||
|
|
||||||
insstart_less = curwin->w_cursor.col;
|
insstart_less = curwin->w_cursor.col;
|
||||||
|
|
||||||
/*
|
// If the cursor is in the indent, compute how many screen columns the
|
||||||
* If the cursor is in the indent, compute how many screen columns the
|
// cursor is to the left of the first non-blank.
|
||||||
* cursor is to the left of the first non-blank.
|
|
||||||
*/
|
|
||||||
if (new_cursor_col < 0) {
|
if (new_cursor_col < 0) {
|
||||||
vcol = get_indent() - vcol;
|
vcol = get_indent() - vcol;
|
||||||
}
|
}
|
||||||
@@ -1626,9 +1610,7 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
|
|||||||
start_col = -1;
|
start_col = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set the new indent. The cursor will be put on the first non-blank.
|
||||||
* Set the new indent. The cursor will be put on the first non-blank.
|
|
||||||
*/
|
|
||||||
if (type == INDENT_SET) {
|
if (type == INDENT_SET) {
|
||||||
(void)set_indent(amount, call_changed_bytes ? SIN_CHANGED : 0);
|
(void)set_indent(amount, call_changed_bytes ? SIN_CHANGED : 0);
|
||||||
} else {
|
} else {
|
||||||
@@ -1643,20 +1625,16 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
|
|||||||
}
|
}
|
||||||
insstart_less -= curwin->w_cursor.col;
|
insstart_less -= curwin->w_cursor.col;
|
||||||
|
|
||||||
/*
|
// Try to put cursor on same character.
|
||||||
* Try to put cursor on same character.
|
// If the cursor is at or after the first non-blank in the line,
|
||||||
* If the cursor is at or after the first non-blank in the line,
|
// compute the cursor column relative to the column of the first
|
||||||
* compute the cursor column relative to the column of the first
|
// non-blank character.
|
||||||
* non-blank character.
|
// If we are not in insert mode, leave the cursor on the first non-blank.
|
||||||
* If we are not in insert mode, leave the cursor on the first non-blank.
|
// If the cursor is before the first non-blank, position it relative
|
||||||
* If the cursor is before the first non-blank, position it relative
|
// to the first non-blank, counted in screen columns.
|
||||||
* to the first non-blank, counted in screen columns.
|
|
||||||
*/
|
|
||||||
if (new_cursor_col >= 0) {
|
if (new_cursor_col >= 0) {
|
||||||
/*
|
// When changing the indent while the cursor is touching it, reset
|
||||||
* When changing the indent while the cursor is touching it, reset
|
// Insstart_col to 0.
|
||||||
* Insstart_col to 0.
|
|
||||||
*/
|
|
||||||
if (new_cursor_col == 0) {
|
if (new_cursor_col == 0) {
|
||||||
insstart_less = MAXCOL;
|
insstart_less = MAXCOL;
|
||||||
}
|
}
|
||||||
@@ -1687,10 +1665,8 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
|
|||||||
new_cursor_col = (int)(cts.cts_ptr - cts.cts_line);
|
new_cursor_col = (int)(cts.cts_ptr - cts.cts_line);
|
||||||
clear_chartabsize_arg(&cts);
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
/*
|
// May need to insert spaces to be able to position the cursor on
|
||||||
* May need to insert spaces to be able to position the cursor on
|
// the right screen column.
|
||||||
* the right screen column.
|
|
||||||
*/
|
|
||||||
if (vcol != (int)curwin->w_virtcol) {
|
if (vcol != (int)curwin->w_virtcol) {
|
||||||
curwin->w_cursor.col = (colnr_T)new_cursor_col;
|
curwin->w_cursor.col = (colnr_T)new_cursor_col;
|
||||||
size_t i = (size_t)(curwin->w_virtcol - vcol);
|
size_t i = (size_t)(curwin->w_virtcol - vcol);
|
||||||
@@ -1701,10 +1677,8 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
|
|||||||
xfree(ptr);
|
xfree(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When changing the indent while the cursor is in it, reset
|
||||||
* When changing the indent while the cursor is in it, reset
|
// Insstart_col to 0.
|
||||||
* Insstart_col to 0.
|
|
||||||
*/
|
|
||||||
insstart_less = MAXCOL;
|
insstart_less = MAXCOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1718,9 +1692,7 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
|
|||||||
curwin->w_set_curswant = true;
|
curwin->w_set_curswant = true;
|
||||||
changed_cline_bef_curs();
|
changed_cline_bef_curs();
|
||||||
|
|
||||||
/*
|
// May have to adjust the start of the insert.
|
||||||
* May have to adjust the start of the insert.
|
|
||||||
*/
|
|
||||||
if (State & MODE_INSERT) {
|
if (State & MODE_INSERT) {
|
||||||
if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0) {
|
if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0) {
|
||||||
if ((int)Insstart.col <= insstart_less) {
|
if ((int)Insstart.col <= insstart_less) {
|
||||||
@@ -1998,15 +1970,13 @@ static void insert_special(int c, int allow_modmask, int ctrlv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Special characters in this context are those that need processing other
|
||||||
* Special characters in this context are those that need processing other
|
// than the simple insertion that can be performed here. This includes ESC
|
||||||
* than the simple insertion that can be performed here. This includes ESC
|
// which terminates the insert, and CR/NL which need special processing to
|
||||||
* which terminates the insert, and CR/NL which need special processing to
|
// open up a new line. This routine tries to optimize insertions performed by
|
||||||
* open up a new line. This routine tries to optimize insertions performed by
|
// the "redo", "undo" or "put" commands, so it needs to know when it should
|
||||||
* the "redo", "undo" or "put" commands, so it needs to know when it should
|
// stop and defer processing to the "normal" mechanism.
|
||||||
* stop and defer processing to the "normal" mechanism.
|
// '0' and '^' are special, because they can be followed by CTRL-D.
|
||||||
* '0' and '^' are special, because they can be followed by CTRL-D.
|
|
||||||
*/
|
|
||||||
#define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^')
|
#define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^')
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -2207,9 +2177,7 @@ void insertchar(int c, int flags, int second_indent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Put a character in the redo buffer, for when just after a CTRL-V.
|
||||||
* Put a character in the redo buffer, for when just after a CTRL-V.
|
|
||||||
*/
|
|
||||||
static void redo_literal(int c)
|
static void redo_literal(int c)
|
||||||
{
|
{
|
||||||
char buf[10];
|
char buf[10];
|
||||||
@@ -2259,10 +2227,8 @@ static void start_arrow_common(pos_T *end_insert_pos, bool end_change)
|
|||||||
check_spell_redraw();
|
check_spell_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we skipped highlighting word at cursor, do it now.
|
||||||
* If we skipped highlighting word at cursor, do it now.
|
// It may be skipped again, thus reset spell_redraw_lnum first.
|
||||||
* It may be skipped again, thus reset spell_redraw_lnum first.
|
|
||||||
*/
|
|
||||||
static void check_spell_redraw(void)
|
static void check_spell_redraw(void)
|
||||||
{
|
{
|
||||||
if (spell_redraw_lnum != 0) {
|
if (spell_redraw_lnum != 0) {
|
||||||
@@ -2273,11 +2239,9 @@ static void check_spell_redraw(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// stop_arrow() is called before a change is made in insert mode.
|
||||||
* stop_arrow() is called before a change is made in insert mode.
|
// If an arrow key has been used, start a new insertion.
|
||||||
* If an arrow key has been used, start a new insertion.
|
// Returns FAIL if undo is impossible, shouldn't insert then.
|
||||||
* Returns FAIL if undo is impossible, shouldn't insert then.
|
|
||||||
*/
|
|
||||||
int stop_arrow(void)
|
int stop_arrow(void)
|
||||||
{
|
{
|
||||||
if (arrow_used) {
|
if (arrow_used) {
|
||||||
@@ -2327,11 +2291,9 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove)
|
|||||||
stop_redo_ins();
|
stop_redo_ins();
|
||||||
replace_flush(); // abandon replace stack
|
replace_flush(); // abandon replace stack
|
||||||
|
|
||||||
/*
|
// Save the inserted text for later redo with ^@ and CTRL-A.
|
||||||
* Save the inserted text for later redo with ^@ and CTRL-A.
|
// Don't do it when "restart_edit" was set and nothing was inserted,
|
||||||
* Don't do it when "restart_edit" was set and nothing was inserted,
|
// otherwise CTRL-O w and then <Left> will clear "last_insert".
|
||||||
* otherwise CTRL-O w and then <Left> will clear "last_insert".
|
|
||||||
*/
|
|
||||||
ptr = get_inserted();
|
ptr = get_inserted();
|
||||||
if (did_restart_edit == 0 || (ptr != NULL
|
if (did_restart_edit == 0 || (ptr != NULL
|
||||||
&& (int)STRLEN(ptr) > new_insert_skip)) {
|
&& (int)STRLEN(ptr) > new_insert_skip)) {
|
||||||
@@ -2438,10 +2400,8 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set the last inserted text to a single character.
|
||||||
* Set the last inserted text to a single character.
|
// Used for the replace command.
|
||||||
* Used for the replace command.
|
|
||||||
*/
|
|
||||||
void set_last_insert(int c)
|
void set_last_insert(int c)
|
||||||
{
|
{
|
||||||
char_u *s;
|
char_u *s;
|
||||||
@@ -2466,13 +2426,11 @@ void free_last_insert(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
// move cursor to start of line
|
||||||
* move cursor to start of line
|
// if flags & BL_WHITE move to first non-white
|
||||||
* if flags & BL_WHITE move to first non-white
|
// if flags & BL_SOL move to first non-white if startofline is set,
|
||||||
* if flags & BL_SOL move to first non-white if startofline is set,
|
// otherwise keep "curswant" column
|
||||||
* otherwise keep "curswant" column
|
// if flags & BL_FIX don't leave the cursor on a NUL.
|
||||||
* if flags & BL_FIX don't leave the cursor on a NUL.
|
|
||||||
*/
|
|
||||||
void beginline(int flags)
|
void beginline(int flags)
|
||||||
{
|
{
|
||||||
if ((flags & BL_SOL) && !p_sol) {
|
if ((flags & BL_SOL) && !p_sol) {
|
||||||
@@ -2493,13 +2451,11 @@ void beginline(int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// oneright oneleft cursor_down cursor_up
|
||||||
* oneright oneleft cursor_down cursor_up
|
//
|
||||||
*
|
// Move one char {right,left,down,up}.
|
||||||
* Move one char {right,left,down,up}.
|
// Doesn't move onto the NUL past the end of the line, unless it is allowed.
|
||||||
* Doesn't move onto the NUL past the end of the line, unless it is allowed.
|
// Return OK when successful, FAIL when we hit a line of file boundary.
|
||||||
* Return OK when successful, FAIL when we hit a line of file boundary.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int oneright(void)
|
int oneright(void)
|
||||||
{
|
{
|
||||||
@@ -2600,9 +2556,8 @@ int cursor_up(long n, int upd_topline)
|
|||||||
if (n >= lnum) {
|
if (n >= lnum) {
|
||||||
lnum = 1;
|
lnum = 1;
|
||||||
} else if (hasAnyFolding(curwin)) {
|
} else if (hasAnyFolding(curwin)) {
|
||||||
/*
|
// Count each sequence of folded lines as one logical line.
|
||||||
* Count each sequence of folded lines as one logical line.
|
|
||||||
*/
|
|
||||||
// go to the start of the current fold
|
// go to the start of the current fold
|
||||||
(void)hasFolding(lnum, &lnum, NULL);
|
(void)hasFolding(lnum, &lnum, NULL);
|
||||||
|
|
||||||
@@ -2761,10 +2716,8 @@ char_u *get_last_insert(void)
|
|||||||
return last_insert + last_insert_skip;
|
return last_insert + last_insert_skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get last inserted string, and remove trailing <Esc>.
|
||||||
* Get last inserted string, and remove trailing <Esc>.
|
// Returns pointer to allocated memory (must be freed) or NULL.
|
||||||
* Returns pointer to allocated memory (must be freed) or NULL.
|
|
||||||
*/
|
|
||||||
char_u *get_last_insert_save(void)
|
char_u *get_last_insert_save(void)
|
||||||
{
|
{
|
||||||
char_u *s;
|
char_u *s;
|
||||||
@@ -2803,20 +2756,18 @@ static bool echeck_abbr(int c)
|
|||||||
curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0);
|
curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// replace-stack functions
|
||||||
* replace-stack functions
|
//
|
||||||
*
|
// When replacing characters, the replaced characters are remembered for each
|
||||||
* When replacing characters, the replaced characters are remembered for each
|
// new character. This is used to re-insert the old text when backspacing.
|
||||||
* new character. This is used to re-insert the old text when backspacing.
|
//
|
||||||
*
|
// There is a NUL headed list of characters for each character that is
|
||||||
* There is a NUL headed list of characters for each character that is
|
// currently in the file after the insertion point. When BS is used, one NUL
|
||||||
* currently in the file after the insertion point. When BS is used, one NUL
|
// headed list is put back for the deleted character.
|
||||||
* headed list is put back for the deleted character.
|
//
|
||||||
*
|
// For a newline, there are two NUL headed lists. One contains the characters
|
||||||
* For a newline, there are two NUL headed lists. One contains the characters
|
// that the NL replaced. The extra one stores the characters after the cursor
|
||||||
* that the NL replaced. The extra one stores the characters after the cursor
|
// that were deleted (always white space).
|
||||||
* that were deleted (always white space).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static char_u *replace_stack = NULL;
|
static char_u *replace_stack = NULL;
|
||||||
static ssize_t replace_stack_nr = 0; // next entry in replace stack
|
static ssize_t replace_stack_nr = 0; // next entry in replace stack
|
||||||
@@ -2901,10 +2852,8 @@ static void replace_pop_ins(void)
|
|||||||
State = oldState;
|
State = oldState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Insert bytes popped from the replace stack. "cc" is the first byte. If it
|
||||||
* Insert bytes popped from the replace stack. "cc" is the first byte. If it
|
// indicates a multi-byte char, pop the other bytes too.
|
||||||
* indicates a multi-byte char, pop the other bytes too.
|
|
||||||
*/
|
|
||||||
static void mb_replace_pop_ins(int cc)
|
static void mb_replace_pop_ins(int cc)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
@@ -2951,10 +2900,8 @@ static void mb_replace_pop_ins(int cc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// make the replace stack empty
|
||||||
* make the replace stack empty
|
// (called when exiting replace mode)
|
||||||
* (called when exiting replace mode)
|
|
||||||
*/
|
|
||||||
static void replace_flush(void)
|
static void replace_flush(void)
|
||||||
{
|
{
|
||||||
XFREE_CLEAR(replace_stack);
|
XFREE_CLEAR(replace_stack);
|
||||||
@@ -2962,15 +2909,13 @@ static void replace_flush(void)
|
|||||||
replace_stack_nr = 0;
|
replace_stack_nr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Handle doing a BS for one character.
|
||||||
* Handle doing a BS for one character.
|
// cc < 0: replace stack empty, just move cursor
|
||||||
* cc < 0: replace stack empty, just move cursor
|
// cc == 0: character was inserted, delete it
|
||||||
* cc == 0: character was inserted, delete it
|
// cc > 0: character was replaced, put cc (first byte of original char) back
|
||||||
* cc > 0: character was replaced, put cc (first byte of original char) back
|
// and check for more characters to be put back
|
||||||
* and check for more characters to be put back
|
// When "limit_col" is >= 0, don't delete before this column. Matters when
|
||||||
* When "limit_col" is >= 0, don't delete before this column. Matters when
|
// using composing characters, use del_char_after_col() instead of del_char().
|
||||||
* using composing characters, use del_char_after_col() instead of del_char().
|
|
||||||
*/
|
|
||||||
static void replace_do_bs(int limit_col)
|
static void replace_do_bs(int limit_col)
|
||||||
{
|
{
|
||||||
int cc;
|
int cc;
|
||||||
@@ -3033,12 +2978,10 @@ bool cindent_on(void)
|
|||||||
return !p_paste && (curbuf->b_p_cin || *curbuf->b_p_inde != NUL);
|
return !p_paste && (curbuf->b_p_cin || *curbuf->b_p_inde != NUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Re-indent the current line, based on the current contents of it and the
|
||||||
* Re-indent the current line, based on the current contents of it and the
|
// surrounding lines. Fixing the cursor position seems really easy -- I'm very
|
||||||
* surrounding lines. Fixing the cursor position seems really easy -- I'm very
|
// confused what all the part that handles Control-T is doing that I'm not.
|
||||||
* confused what all the part that handles Control-T is doing that I'm not.
|
// "get_the_indent" should be get_c_indent, get_expr_indent or get_lisp_indent.
|
||||||
* "get_the_indent" should be get_c_indent, get_expr_indent or get_lisp_indent.
|
|
||||||
*/
|
|
||||||
void fixthisline(IndentGetter get_the_indent)
|
void fixthisline(IndentGetter get_the_indent)
|
||||||
{
|
{
|
||||||
int amount = get_the_indent();
|
int amount = get_the_indent();
|
||||||
@@ -3096,10 +3039,8 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
|
|||||||
look = (char_u *)curbuf->b_p_cink; // 'indentexpr' empty: use 'cinkeys'
|
look = (char_u *)curbuf->b_p_cink; // 'indentexpr' empty: use 'cinkeys'
|
||||||
}
|
}
|
||||||
while (*look) {
|
while (*look) {
|
||||||
/*
|
// Find out if we want to try a match with this key, depending on
|
||||||
* Find out if we want to try a match with this key, depending on
|
// 'when' and a '*' or '!' before the key.
|
||||||
* 'when' and a '*' or '!' before the key.
|
|
||||||
*/
|
|
||||||
switch (when) {
|
switch (when) {
|
||||||
case '*':
|
case '*':
|
||||||
try_match = (*look == '*'); break;
|
try_match = (*look == '*'); break;
|
||||||
@@ -3286,9 +3227,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Map Hebrew keyboard when in hkmap mode.
|
||||||
* Map Hebrew keyboard when in hkmap mode.
|
|
||||||
*/
|
|
||||||
int hkmap(int c)
|
int hkmap(int c)
|
||||||
FUNC_ATTR_PURE
|
FUNC_ATTR_PURE
|
||||||
{
|
{
|
||||||
@@ -3390,9 +3329,7 @@ static void ins_reg(void)
|
|||||||
int literally = 0;
|
int literally = 0;
|
||||||
int vis_active = VIsual_active;
|
int vis_active = VIsual_active;
|
||||||
|
|
||||||
/*
|
// If we are going to wait for a character, show a '"'.
|
||||||
* If we are going to wait for a character, show a '"'.
|
|
||||||
*/
|
|
||||||
pc_status = PC_STATUS_UNSET;
|
pc_status = PC_STATUS_UNSET;
|
||||||
if (redrawing() && !char_avail()) {
|
if (redrawing() && !char_avail()) {
|
||||||
// may need to redraw when no more chars available now
|
// may need to redraw when no more chars available now
|
||||||
@@ -3474,9 +3411,7 @@ static void ins_reg(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// CTRL-G commands in Insert mode.
|
||||||
* CTRL-G commands in Insert mode.
|
|
||||||
*/
|
|
||||||
static void ins_ctrl_g(void)
|
static void ins_ctrl_g(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -3530,9 +3465,7 @@ static void ins_ctrl_g(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// CTRL-^ in Insert mode.
|
||||||
* CTRL-^ in Insert mode.
|
|
||||||
*/
|
|
||||||
static void ins_ctrl_hat(void)
|
static void ins_ctrl_hat(void)
|
||||||
{
|
{
|
||||||
if (map_to_exists_mode("", MODE_LANGMAP, false)) {
|
if (map_to_exists_mode("", MODE_LANGMAP, false)) {
|
||||||
@@ -3576,10 +3509,8 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
|
|||||||
AppendToRedobuff(ESC_STR);
|
AppendToRedobuff(ESC_STR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Repeating insert may take a long time. Check for
|
||||||
* Repeating insert may take a long time. Check for
|
// interrupt now and then.
|
||||||
* interrupt now and then.
|
|
||||||
*/
|
|
||||||
if (*count > 0) {
|
if (*count > 0) {
|
||||||
line_breakcheck();
|
line_breakcheck();
|
||||||
if (got_int) {
|
if (got_int) {
|
||||||
@@ -3622,10 +3553,8 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
|
|||||||
RESET_FMARK(&curbuf->b_last_insert, curwin->w_cursor, curbuf->b_fnum, view);
|
RESET_FMARK(&curbuf->b_last_insert, curwin->w_cursor, curbuf->b_fnum, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// The cursor should end up on the last inserted character.
|
||||||
* The cursor should end up on the last inserted character.
|
// Don't do it for CTRL-O, unless past the end of the line.
|
||||||
* Don't do it for CTRL-O, unless past the end of the line.
|
|
||||||
*/
|
|
||||||
if (!nomove
|
if (!nomove
|
||||||
&& (curwin->w_cursor.col != 0 || curwin->w_cursor.coladd > 0)
|
&& (curwin->w_cursor.col != 0 || curwin->w_cursor.coladd > 0)
|
||||||
&& (restart_edit == NUL || (gchar_cursor() == NUL && !VIsual_active))
|
&& (restart_edit == NUL || (gchar_cursor() == NUL && !VIsual_active))
|
||||||
@@ -3663,10 +3592,8 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Toggle language: hkmap and revins_on.
|
||||||
* Toggle language: hkmap and revins_on.
|
// Move to end of reverse inserted text.
|
||||||
* Move to end of reverse inserted text.
|
|
||||||
*/
|
|
||||||
static void ins_ctrl_(void)
|
static void ins_ctrl_(void)
|
||||||
{
|
{
|
||||||
if (revins_on && revins_chars && revins_scol >= 0) {
|
if (revins_on && revins_chars && revins_scol >= 0) {
|
||||||
@@ -3733,9 +3660,7 @@ static bool ins_start_select(int c)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// <Insert> key in Insert mode: toggle insert/replace mode.
|
||||||
* <Insert> key in Insert mode: toggle insert/replace mode.
|
|
||||||
*/
|
|
||||||
static void ins_insert(int replaceState)
|
static void ins_insert(int replaceState)
|
||||||
{
|
{
|
||||||
set_vim_var_string(VV_INSERTMODE, ((State & REPLACE_FLAG) ? "i" :
|
set_vim_var_string(VV_INSERTMODE, ((State & REPLACE_FLAG) ? "i" :
|
||||||
@@ -3753,9 +3678,7 @@ static void ins_insert(int replaceState)
|
|||||||
ui_cursor_shape(); // may show different cursor shape
|
ui_cursor_shape(); // may show different cursor shape
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Pressed CTRL-O in Insert mode.
|
||||||
* Pressed CTRL-O in Insert mode.
|
|
||||||
*/
|
|
||||||
static void ins_ctrl_o(void)
|
static void ins_ctrl_o(void)
|
||||||
{
|
{
|
||||||
if (State & VREPLACE_FLAG) {
|
if (State & VREPLACE_FLAG) {
|
||||||
@@ -3772,13 +3695,11 @@ static void ins_ctrl_o(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If the cursor is on an indent, ^T/^D insert/delete one
|
||||||
* If the cursor is on an indent, ^T/^D insert/delete one
|
// shiftwidth. Otherwise ^T/^D behave like a "<<" or ">>".
|
||||||
* shiftwidth. Otherwise ^T/^D behave like a "<<" or ">>".
|
// Always round the indent to 'shiftwidth', this is compatible
|
||||||
* Always round the indent to 'shiftwidth', this is compatible
|
// with vi. But vi only supports ^T and ^D after an
|
||||||
* with vi. But vi only supports ^T and ^D after an
|
// autoindent, we support it everywhere.
|
||||||
* autoindent, we support it everywhere.
|
|
||||||
*/
|
|
||||||
static void ins_shift(int c, int lastc)
|
static void ins_shift(int c, int lastc)
|
||||||
{
|
{
|
||||||
if (stop_arrow() == FAIL) {
|
if (stop_arrow() == FAIL) {
|
||||||
@@ -3786,9 +3707,7 @@ static void ins_shift(int c, int lastc)
|
|||||||
}
|
}
|
||||||
AppendCharToRedobuff(c);
|
AppendCharToRedobuff(c);
|
||||||
|
|
||||||
/*
|
// 0^D and ^^D: remove all indent.
|
||||||
* 0^D and ^^D: remove all indent.
|
|
||||||
*/
|
|
||||||
if (c == Ctrl_D && (lastc == '0' || lastc == '^')
|
if (c == Ctrl_D && (lastc == '0' || lastc == '^')
|
||||||
&& curwin->w_cursor.col > 0) {
|
&& curwin->w_cursor.col > 0) {
|
||||||
curwin->w_cursor.col--;
|
curwin->w_cursor.col--;
|
||||||
@@ -3844,9 +3763,7 @@ static void ins_del(void)
|
|||||||
AppendCharToRedobuff(K_DEL);
|
AppendCharToRedobuff(K_DEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Delete one character for ins_bs().
|
||||||
* Delete one character for ins_bs().
|
|
||||||
*/
|
|
||||||
static void ins_bs_one(colnr_T *vcolp)
|
static void ins_bs_one(colnr_T *vcolp)
|
||||||
{
|
{
|
||||||
dec_cursor();
|
dec_cursor();
|
||||||
@@ -3941,11 +3858,9 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
|
|||||||
Insstart.lnum--;
|
Insstart.lnum--;
|
||||||
Insstart.col = (colnr_T)STRLEN(ml_get(Insstart.lnum));
|
Insstart.col = (colnr_T)STRLEN(ml_get(Insstart.lnum));
|
||||||
}
|
}
|
||||||
/*
|
// In replace mode:
|
||||||
* In replace mode:
|
// cc < 0: NL was inserted, delete it
|
||||||
* cc < 0: NL was inserted, delete it
|
// cc >= 0: NL was replaced, put original characters back
|
||||||
* cc >= 0: NL was replaced, put original characters back
|
|
||||||
*/
|
|
||||||
cc = -1;
|
cc = -1;
|
||||||
if (State & REPLACE_FLAG) {
|
if (State & REPLACE_FLAG) {
|
||||||
cc = replace_pop(); // returns -1 if NL was inserted
|
cc = replace_pop(); // returns -1 if NL was inserted
|
||||||
@@ -4025,9 +3940,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
|
|||||||
curwin->w_cursor.col = save_col;
|
curwin->w_cursor.col = save_col;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Handle deleting one 'shiftwidth' or 'softtabstop'.
|
||||||
* Handle deleting one 'shiftwidth' or 'softtabstop'.
|
|
||||||
*/
|
|
||||||
if (mode == BACKSPACE_CHAR
|
if (mode == BACKSPACE_CHAR
|
||||||
&& ((p_sta && in_indent)
|
&& ((p_sta && in_indent)
|
||||||
|| ((get_sts_value() != 0
|
|| ((get_sts_value() != 0
|
||||||
@@ -4589,9 +4502,7 @@ static bool ins_tab(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When 'expandtab' not set: Replace spaces by TABs where possible.
|
||||||
* When 'expandtab' not set: Replace spaces by TABs where possible.
|
|
||||||
*/
|
|
||||||
if (!curbuf->b_p_et && (tabstop_count(curbuf->b_p_vsts_array) > 0
|
if (!curbuf->b_p_et && (tabstop_count(curbuf->b_p_vsts_array) > 0
|
||||||
|| get_sts_value() > 0
|
|| get_sts_value() > 0
|
||||||
|| (p_sta && ind))) {
|
|| (p_sta && ind))) {
|
||||||
@@ -4742,11 +4653,9 @@ bool ins_eol(int c)
|
|||||||
}
|
}
|
||||||
undisplay_dollar();
|
undisplay_dollar();
|
||||||
|
|
||||||
/*
|
// Strange Vi behaviour: In Replace mode, typing a NL will not delete the
|
||||||
* Strange Vi behaviour: In Replace mode, typing a NL will not delete the
|
// character under the cursor. Only push a NUL on the replace stack,
|
||||||
* character under the cursor. Only push a NUL on the replace stack,
|
// nothing to put back when the NL is deleted.
|
||||||
* nothing to put back when the NL is deleted.
|
|
||||||
*/
|
|
||||||
if ((State & REPLACE_FLAG)
|
if ((State & REPLACE_FLAG)
|
||||||
&& !(State & VREPLACE_FLAG)) {
|
&& !(State & VREPLACE_FLAG)) {
|
||||||
replace_push(NUL);
|
replace_push(NUL);
|
||||||
@@ -4780,11 +4689,9 @@ bool ins_eol(int c)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Handle digraph in insert mode.
|
||||||
* Handle digraph in insert mode.
|
// Returns character still to be inserted, or NUL when nothing remaining to be
|
||||||
* Returns character still to be inserted, or NUL when nothing remaining to be
|
// done.
|
||||||
* done.
|
|
||||||
*/
|
|
||||||
static int ins_digraph(void)
|
static int ins_digraph(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -4853,10 +4760,8 @@ static int ins_digraph(void)
|
|||||||
return NUL;
|
return NUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Handle CTRL-E and CTRL-Y in Insert mode: copy char from other line.
|
||||||
* Handle CTRL-E and CTRL-Y in Insert mode: copy char from other line.
|
// Returns the char to be inserted, or NUL if none found.
|
||||||
* Returns the char to be inserted, or NUL if none found.
|
|
||||||
*/
|
|
||||||
int ins_copychar(linenr_T lnum)
|
int ins_copychar(linenr_T lnum)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -4894,9 +4799,7 @@ int ins_copychar(linenr_T lnum)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// CTRL-Y or CTRL-E typed in Insert mode.
|
||||||
* CTRL-Y or CTRL-E typed in Insert mode.
|
|
||||||
*/
|
|
||||||
static int ins_ctrl_ey(int tc)
|
static int ins_ctrl_ey(int tc)
|
||||||
{
|
{
|
||||||
int c = tc;
|
int c = tc;
|
||||||
@@ -4933,10 +4836,8 @@ static int ins_ctrl_ey(int tc)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Try to do some very smart auto-indenting.
|
||||||
* Try to do some very smart auto-indenting.
|
// Used when inserting a "normal" character.
|
||||||
* Used when inserting a "normal" character.
|
|
||||||
*/
|
|
||||||
static void ins_try_si(int c)
|
static void ins_try_si(int c)
|
||||||
{
|
{
|
||||||
pos_T *pos, old_pos;
|
pos_T *pos, old_pos;
|
||||||
@@ -4944,20 +4845,16 @@ static void ins_try_si(int c)
|
|||||||
int i;
|
int i;
|
||||||
bool temp;
|
bool temp;
|
||||||
|
|
||||||
/*
|
// do some very smart indenting when entering '{' or '}'
|
||||||
* do some very smart indenting when entering '{' or '}'
|
|
||||||
*/
|
|
||||||
if (((did_si || can_si_back) && c == '{') || (can_si && c == '}' && inindent(0))) {
|
if (((did_si || can_si_back) && c == '{') || (can_si && c == '}' && inindent(0))) {
|
||||||
// for '}' set indent equal to indent of line containing matching '{'
|
// for '}' set indent equal to indent of line containing matching '{'
|
||||||
if (c == '}' && (pos = findmatch(NULL, '{')) != NULL) {
|
if (c == '}' && (pos = findmatch(NULL, '{')) != NULL) {
|
||||||
old_pos = curwin->w_cursor;
|
old_pos = curwin->w_cursor;
|
||||||
/*
|
// If the matching '{' has a ')' immediately before it (ignoring
|
||||||
* If the matching '{' has a ')' immediately before it (ignoring
|
// white-space), then line up with the start of the line
|
||||||
* white-space), then line up with the start of the line
|
// containing the matching '(' if there is one. This handles the
|
||||||
* containing the matching '(' if there is one. This handles the
|
// case where an "if (..\n..) {" statement continues over multiple
|
||||||
* case where an "if (..\n..) {" statement continues over multiple
|
// lines -- webb
|
||||||
* lines -- webb
|
|
||||||
*/
|
|
||||||
ptr = (char_u *)ml_get(pos->lnum);
|
ptr = (char_u *)ml_get(pos->lnum);
|
||||||
i = pos->col;
|
i = pos->col;
|
||||||
if (i > 0) { // skip blanks before '{'
|
if (i > 0) { // skip blanks before '{'
|
||||||
@@ -5001,9 +4898,7 @@ static void ins_try_si(int c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// set indent of '#' always to 0
|
||||||
* set indent of '#' always to 0
|
|
||||||
*/
|
|
||||||
if (curwin->w_cursor.col > 0 && can_si && c == '#' && inindent(0)) {
|
if (curwin->w_cursor.col > 0 && can_si && c == '#' && inindent(0)) {
|
||||||
// remember current indent for next line
|
// remember current indent for next line
|
||||||
old_indent = get_indent();
|
old_indent = get_indent();
|
||||||
@@ -5016,10 +4911,8 @@ static void ins_try_si(int c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get the value that w_virtcol would have when 'list' is off.
|
||||||
* Get the value that w_virtcol would have when 'list' is off.
|
// Unless 'cpo' contains the 'L' flag.
|
||||||
* Unless 'cpo' contains the 'L' flag.
|
|
||||||
*/
|
|
||||||
colnr_T get_nolist_virtcol(void)
|
colnr_T get_nolist_virtcol(void)
|
||||||
{
|
{
|
||||||
// check validity of cursor in current buffer
|
// check validity of cursor in current buffer
|
||||||
@@ -5034,12 +4927,10 @@ colnr_T get_nolist_virtcol(void)
|
|||||||
return curwin->w_virtcol;
|
return curwin->w_virtcol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Handle the InsertCharPre autocommand.
|
||||||
* Handle the InsertCharPre autocommand.
|
// "c" is the character that was typed.
|
||||||
* "c" is the character that was typed.
|
// Return a pointer to allocated memory with the replacement string.
|
||||||
* Return a pointer to allocated memory with the replacement string.
|
// Return NULL to continue inserting "c".
|
||||||
* Return NULL to continue inserting "c".
|
|
||||||
*/
|
|
||||||
static char_u *do_insert_char_pre(int c)
|
static char_u *do_insert_char_pre(int c)
|
||||||
{
|
{
|
||||||
char buf[MB_MAXBYTES + 1];
|
char buf[MB_MAXBYTES + 1];
|
||||||
|
@@ -11,33 +11,31 @@
|
|||||||
#define COPYID_INC 2
|
#define COPYID_INC 2
|
||||||
#define COPYID_MASK (~0x1)
|
#define COPYID_MASK (~0x1)
|
||||||
|
|
||||||
/*
|
// Structure returned by get_lval() and used by set_var_lval().
|
||||||
* Structure returned by get_lval() and used by set_var_lval().
|
// For a plain name:
|
||||||
* For a plain name:
|
// "name" points to the variable name.
|
||||||
* "name" points to the variable name.
|
// "exp_name" is NULL.
|
||||||
* "exp_name" is NULL.
|
// "tv" is NULL
|
||||||
* "tv" is NULL
|
// For a magic braces name:
|
||||||
* For a magic braces name:
|
// "name" points to the expanded variable name.
|
||||||
* "name" points to the expanded variable name.
|
// "exp_name" is non-NULL, to be freed later.
|
||||||
* "exp_name" is non-NULL, to be freed later.
|
// "tv" is NULL
|
||||||
* "tv" is NULL
|
// For an index in a list:
|
||||||
* For an index in a list:
|
// "name" points to the (expanded) variable name.
|
||||||
* "name" points to the (expanded) variable name.
|
// "exp_name" NULL or non-NULL, to be freed later.
|
||||||
* "exp_name" NULL or non-NULL, to be freed later.
|
// "tv" points to the (first) list item value
|
||||||
* "tv" points to the (first) list item value
|
// "li" points to the (first) list item
|
||||||
* "li" points to the (first) list item
|
// "range", "n1", "n2" and "empty2" indicate what items are used.
|
||||||
* "range", "n1", "n2" and "empty2" indicate what items are used.
|
// For an existing Dict item:
|
||||||
* For an existing Dict item:
|
// "name" points to the (expanded) variable name.
|
||||||
* "name" points to the (expanded) variable name.
|
// "exp_name" NULL or non-NULL, to be freed later.
|
||||||
* "exp_name" NULL or non-NULL, to be freed later.
|
// "tv" points to the dict item value
|
||||||
* "tv" points to the dict item value
|
// "newkey" is NULL
|
||||||
* "newkey" is NULL
|
// For a non-existing Dict item:
|
||||||
* For a non-existing Dict item:
|
// "name" points to the (expanded) variable name.
|
||||||
* "name" points to the (expanded) variable name.
|
// "exp_name" NULL or non-NULL, to be freed later.
|
||||||
* "exp_name" NULL or non-NULL, to be freed later.
|
// "tv" points to the Dictionary typval_T
|
||||||
* "tv" points to the Dictionary typval_T
|
// "newkey" is the key for the new item.
|
||||||
* "newkey" is the key for the new item.
|
|
||||||
*/
|
|
||||||
typedef struct lval_S {
|
typedef struct lval_S {
|
||||||
const char *ll_name; ///< Start of variable name (can be NULL).
|
const char *ll_name; ///< Start of variable name (can be NULL).
|
||||||
size_t ll_name_len; ///< Length of the .ll_name.
|
size_t ll_name_len; ///< Length of the .ll_name.
|
||||||
|
@@ -1576,16 +1576,14 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t
|
|||||||
// Find the function name in the table, call its implementation.
|
// Find the function name in the table, call its implementation.
|
||||||
error = call_internal_func((char_u *)fname, argcount, argvars, rettv);
|
error = call_internal_func((char_u *)fname, argcount, argvars, rettv);
|
||||||
}
|
}
|
||||||
/*
|
// The function call (or "FuncUndefined" autocommand sequence) might
|
||||||
* The function call (or "FuncUndefined" autocommand sequence) might
|
// have been aborted by an error, an interrupt, or an explicitly thrown
|
||||||
* have been aborted by an error, an interrupt, or an explicitly thrown
|
// exception that has not been caught so far. This situation can be
|
||||||
* exception that has not been caught so far. This situation can be
|
// tested for by calling aborting(). For an error in an internal
|
||||||
* tested for by calling aborting(). For an error in an internal
|
// function or for the "E132" error in call_user_func(), however, the
|
||||||
* function or for the "E132" error in call_user_func(), however, the
|
// throw point at which the "force_abort" flag (temporarily reset by
|
||||||
* throw point at which the "force_abort" flag (temporarily reset by
|
// emsg()) is normally updated has not been reached yet. We need to
|
||||||
* emsg()) is normally updated has not been reached yet. We need to
|
// update that flag first to make aborting() reliable.
|
||||||
* update that flag first to make aborting() reliable.
|
|
||||||
*/
|
|
||||||
update_force_abort();
|
update_force_abort();
|
||||||
}
|
}
|
||||||
if (error == ERROR_NONE) {
|
if (error == ERROR_NONE) {
|
||||||
@@ -1720,11 +1718,9 @@ char_u *trans_function_name(char **pp, bool skip, int flags, funcdict_T *fdp, pa
|
|||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) {
|
if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) {
|
||||||
/*
|
// Report an invalid expression in braces, unless the expression
|
||||||
* Report an invalid expression in braces, unless the expression
|
// evaluation has been cancelled due to an aborting error, an
|
||||||
* evaluation has been cancelled due to an aborting error, an
|
// interrupt, or an exception.
|
||||||
* interrupt, or an exception.
|
|
||||||
*/
|
|
||||||
if (!aborting()) {
|
if (!aborting()) {
|
||||||
if (end != NULL) {
|
if (end != NULL) {
|
||||||
semsg(_(e_invarg2), start);
|
semsg(_(e_invarg2), start);
|
||||||
@@ -1923,9 +1919,7 @@ void ex_function(exarg_T *eap)
|
|||||||
bool show_block = false;
|
bool show_block = false;
|
||||||
bool do_concat = true;
|
bool do_concat = true;
|
||||||
|
|
||||||
/*
|
// ":function" without argument: list functions.
|
||||||
* ":function" without argument: list functions.
|
|
||||||
*/
|
|
||||||
if (ends_excmd(*eap->arg)) {
|
if (ends_excmd(*eap->arg)) {
|
||||||
if (!eap->skip) {
|
if (!eap->skip) {
|
||||||
todo = (int)func_hashtab.ht_used;
|
todo = (int)func_hashtab.ht_used;
|
||||||
@@ -1946,9 +1940,7 @@ void ex_function(exarg_T *eap)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// ":function /pat": list functions matching pattern.
|
||||||
* ":function /pat": list functions matching pattern.
|
|
||||||
*/
|
|
||||||
if (*eap->arg == '/') {
|
if (*eap->arg == '/') {
|
||||||
p = skip_regexp(eap->arg + 1, '/', true, NULL);
|
p = skip_regexp(eap->arg + 1, '/', true, NULL);
|
||||||
if (!eap->skip) {
|
if (!eap->skip) {
|
||||||
@@ -2000,11 +1992,9 @@ void ex_function(exarg_T *eap)
|
|||||||
name = (char *)trans_function_name(&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL);
|
name = (char *)trans_function_name(&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL);
|
||||||
paren = (vim_strchr(p, '(') != NULL);
|
paren = (vim_strchr(p, '(') != NULL);
|
||||||
if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) {
|
if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) {
|
||||||
/*
|
// Return on an invalid expression in braces, unless the expression
|
||||||
* Return on an invalid expression in braces, unless the expression
|
// evaluation has been cancelled due to an aborting error, an
|
||||||
* evaluation has been cancelled due to an aborting error, an
|
// interrupt, or an exception.
|
||||||
* interrupt, or an exception.
|
|
||||||
*/
|
|
||||||
if (!aborting()) {
|
if (!aborting()) {
|
||||||
if (fudi.fd_newkey != NULL) {
|
if (fudi.fd_newkey != NULL) {
|
||||||
semsg(_(e_dictkey), fudi.fd_newkey);
|
semsg(_(e_dictkey), fudi.fd_newkey);
|
||||||
@@ -2069,9 +2059,7 @@ void ex_function(exarg_T *eap)
|
|||||||
goto ret_free;
|
goto ret_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// ":function name(arg1, arg2)" Define function.
|
||||||
* ":function name(arg1, arg2)" Define function.
|
|
||||||
*/
|
|
||||||
p = skipwhite(p);
|
p = skipwhite(p);
|
||||||
if (*p != '(') {
|
if (*p != '(') {
|
||||||
if (!eap->skip) {
|
if (!eap->skip) {
|
||||||
@@ -2154,9 +2142,7 @@ void ex_function(exarg_T *eap)
|
|||||||
semsg(_(e_trailing_arg), p);
|
semsg(_(e_trailing_arg), p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Read the body of the function, until ":endfunction" is found.
|
||||||
* Read the body of the function, until ":endfunction" is found.
|
|
||||||
*/
|
|
||||||
if (KeyTyped) {
|
if (KeyTyped) {
|
||||||
// Check if the function already exists, don't let the user type the
|
// Check if the function already exists, don't let the user type the
|
||||||
// whole function before telling him it doesn't work! For a script we
|
// whole function before telling him it doesn't work! For a script we
|
||||||
@@ -2410,9 +2396,7 @@ void ex_function(exarg_T *eap)
|
|||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If there are no errors, add the function
|
||||||
* If there are no errors, add the function
|
|
||||||
*/
|
|
||||||
if (fudi.fd_dict == NULL) {
|
if (fudi.fd_dict == NULL) {
|
||||||
v = find_var((const char *)name, STRLEN(name), &ht, false);
|
v = find_var((const char *)name, STRLEN(name), &ht, false);
|
||||||
if (v != NULL && v->di_tv.v_type == VAR_FUNC) {
|
if (v != NULL && v->di_tv.v_type == VAR_FUNC) {
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
/*
|
// ex_cmds.c: some functions for command line commands
|
||||||
* ex_cmds.c: some functions for command line commands
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
@@ -249,11 +247,9 @@ void ex_align(exarg_T *eap)
|
|||||||
indent = width;
|
indent = width;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
// if 'textwidth' set, use it
|
||||||
* if 'textwidth' set, use it
|
// else if 'wrapmargin' set, use it
|
||||||
* else if 'wrapmargin' set, use it
|
// if invalid value, use 80
|
||||||
* if invalid value, use 80
|
|
||||||
*/
|
|
||||||
if (width <= 0) {
|
if (width <= 0) {
|
||||||
width = (int)curbuf->b_p_tw;
|
width = (int)curbuf->b_p_tw;
|
||||||
}
|
}
|
||||||
@@ -287,18 +283,14 @@ void ex_align(exarg_T *eap)
|
|||||||
} else {
|
} else {
|
||||||
new_indent = width - len; // right align
|
new_indent = width - len; // right align
|
||||||
|
|
||||||
/*
|
// Make sure that embedded TABs don't make the text go too far
|
||||||
* Make sure that embedded TABs don't make the text go too far
|
// to the right.
|
||||||
* to the right.
|
|
||||||
*/
|
|
||||||
if (has_tab) {
|
if (has_tab) {
|
||||||
while (new_indent > 0) {
|
while (new_indent > 0) {
|
||||||
(void)set_indent(new_indent, 0);
|
(void)set_indent(new_indent, 0);
|
||||||
if (linelen(NULL) <= width) {
|
if (linelen(NULL) <= width) {
|
||||||
/*
|
// Now try to move the line as much as possible to
|
||||||
* Now try to move the line as much as possible to
|
// the right. Stop when it moves too far.
|
||||||
* the right. Stop when it moves too far.
|
|
||||||
*/
|
|
||||||
do {
|
do {
|
||||||
(void)set_indent(++new_indent, 0);
|
(void)set_indent(++new_indent, 0);
|
||||||
} while (linelen(NULL) <= width);
|
} while (linelen(NULL) <= width);
|
||||||
@@ -933,10 +925,8 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
|
|||||||
|
|
||||||
num_lines = line2 - line1 + 1;
|
num_lines = line2 - line1 + 1;
|
||||||
|
|
||||||
/*
|
// First we copy the old text to its new location -- webb
|
||||||
* First we copy the old text to its new location -- webb
|
// Also copy the flag that ":global" command uses.
|
||||||
* Also copy the flag that ":global" command uses.
|
|
||||||
*/
|
|
||||||
if (u_save(dest, dest + 1) == FAIL) {
|
if (u_save(dest, dest + 1) == FAIL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
@@ -949,21 +939,19 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Now we must be careful adjusting our marks so that we don't overlap our
|
||||||
* Now we must be careful adjusting our marks so that we don't overlap our
|
// mark_adjust() calls.
|
||||||
* mark_adjust() calls.
|
//
|
||||||
*
|
// We adjust the marks within the old text so that they refer to the
|
||||||
* We adjust the marks within the old text so that they refer to the
|
// last lines of the file (temporarily), because we know no other marks
|
||||||
* last lines of the file (temporarily), because we know no other marks
|
// will be set there since these line numbers did not exist until we added
|
||||||
* will be set there since these line numbers did not exist until we added
|
// our new lines.
|
||||||
* our new lines.
|
//
|
||||||
*
|
// Then we adjust the marks on lines between the old and new text positions
|
||||||
* Then we adjust the marks on lines between the old and new text positions
|
// (either forwards or backwards).
|
||||||
* (either forwards or backwards).
|
//
|
||||||
*
|
// And Finally we adjust the marks we put at the end of the file back to
|
||||||
* And Finally we adjust the marks we put at the end of the file back to
|
// their final destination at the new text position -- webb
|
||||||
* their final destination at the new text position -- webb
|
|
||||||
*/
|
|
||||||
last_line = curbuf->b_ml.ml_line_count;
|
last_line = curbuf->b_ml.ml_line_count;
|
||||||
mark_adjust_nofold(line1, line2, last_line - line2, 0L, kExtmarkNOOP);
|
mark_adjust_nofold(line1, line2, last_line - line2, 0L, kExtmarkNOOP);
|
||||||
|
|
||||||
@@ -1011,9 +999,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
|
|||||||
// send update regarding the new lines that were added
|
// send update regarding the new lines that were added
|
||||||
buf_updates_send_changes(curbuf, dest + 1, num_lines, 0);
|
buf_updates_send_changes(curbuf, dest + 1, num_lines, 0);
|
||||||
|
|
||||||
/*
|
// Now we delete the original text -- webb
|
||||||
* Now we delete the original text -- webb
|
|
||||||
*/
|
|
||||||
if (u_save(line1 + extra - 1, line2 + extra + 1) == FAIL) {
|
if (u_save(line1 + extra - 1, line2 + extra + 1) == FAIL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
@@ -1030,9 +1016,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
|
|||||||
dest + line_off, 0, dest_byte + byte_off,
|
dest + line_off, 0, dest_byte + byte_off,
|
||||||
kExtmarkUndo);
|
kExtmarkUndo);
|
||||||
|
|
||||||
/*
|
// Leave the cursor on the last of the moved lines.
|
||||||
* Leave the cursor on the last of the moved lines.
|
|
||||||
*/
|
|
||||||
if (dest >= line1) {
|
if (dest >= line1) {
|
||||||
curwin->w_cursor.lnum = dest;
|
curwin->w_cursor.lnum = dest;
|
||||||
} else {
|
} else {
|
||||||
@@ -1069,17 +1053,15 @@ void ex_copy(linenr_T line1, linenr_T line2, linenr_T n)
|
|||||||
curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
|
curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// there are three situations:
|
||||||
* there are three situations:
|
// 1. destination is above line1
|
||||||
* 1. destination is above line1
|
// 2. destination is between line1 and line2
|
||||||
* 2. destination is between line1 and line2
|
// 3. destination is below line2
|
||||||
* 3. destination is below line2
|
//
|
||||||
*
|
// n = destination (when starting)
|
||||||
* n = destination (when starting)
|
// curwin->w_cursor.lnum = destination (while copying)
|
||||||
* curwin->w_cursor.lnum = destination (while copying)
|
// line1 = start of source (while copying)
|
||||||
* line1 = start of source (while copying)
|
// line2 = end of source (while copying)
|
||||||
* line2 = end of source (while copying)
|
|
||||||
*/
|
|
||||||
if (u_save(n, n + 1) == FAIL) {
|
if (u_save(n, n + 1) == FAIL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1155,10 +1137,8 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out
|
|||||||
msg_scroll = scroll_save;
|
msg_scroll = scroll_save;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Try to find an embedded bang, like in :!<cmd> ! [args]
|
||||||
* Try to find an embedded bang, like in :!<cmd> ! [args]
|
// (:!! is indicated by the 'forceit' variable)
|
||||||
* (:!! is indicated by the 'forceit' variable)
|
|
||||||
*/
|
|
||||||
bool ins_prevcmd = forceit;
|
bool ins_prevcmd = forceit;
|
||||||
trailarg = arg;
|
trailarg = arg;
|
||||||
do {
|
do {
|
||||||
@@ -1187,10 +1167,8 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out
|
|||||||
xfree(newcmd);
|
xfree(newcmd);
|
||||||
newcmd = t;
|
newcmd = t;
|
||||||
|
|
||||||
/*
|
// Scan the rest of the argument for '!', which is replaced by the
|
||||||
* Scan the rest of the argument for '!', which is replaced by the
|
// previous command. "\!" is replaced by "!" (this is vi compatible).
|
||||||
* previous command. "\!" is replaced by "!" (this is vi compatible).
|
|
||||||
*/
|
|
||||||
trailarg = NULL;
|
trailarg = NULL;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
if (*p == '!') {
|
if (*p == '!') {
|
||||||
@@ -1221,9 +1199,7 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out
|
|||||||
AppendToRedobuff("\n");
|
AppendToRedobuff("\n");
|
||||||
bangredo = false;
|
bangredo = false;
|
||||||
}
|
}
|
||||||
/*
|
// Add quotes around the command, for shells that need them.
|
||||||
* Add quotes around the command, for shells that need them.
|
|
||||||
*/
|
|
||||||
if (*p_shq != NUL) {
|
if (*p_shq != NUL) {
|
||||||
newcmd = xmalloc(STRLEN(prevcmd) + 2 * STRLEN(p_shq) + 1);
|
newcmd = xmalloc(STRLEN(prevcmd) + 2 * STRLEN(p_shq) + 1);
|
||||||
STRCPY(newcmd, p_shq);
|
STRCPY(newcmd, p_shq);
|
||||||
@@ -1298,18 +1274,16 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char *cmd, b
|
|||||||
changed_line_abv_curs();
|
changed_line_abv_curs();
|
||||||
invalidate_botline();
|
invalidate_botline();
|
||||||
|
|
||||||
/*
|
// When using temp files:
|
||||||
* When using temp files:
|
// 1. * Form temp file names
|
||||||
* 1. * Form temp file names
|
// 2. * Write the lines to a temp file
|
||||||
* 2. * Write the lines to a temp file
|
// 3. Run the filter command on the temp file
|
||||||
* 3. Run the filter command on the temp file
|
// 4. * Read the output of the command into the buffer
|
||||||
* 4. * Read the output of the command into the buffer
|
// 5. * Delete the original lines to be filtered
|
||||||
* 5. * Delete the original lines to be filtered
|
// 6. * Remove the temp files
|
||||||
* 6. * Remove the temp files
|
//
|
||||||
*
|
// When writing the input with a pipe or when catching the output with a
|
||||||
* When writing the input with a pipe or when catching the output with a
|
// pipe only need to do 3.
|
||||||
* pipe only need to do 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (do_out) {
|
if (do_out) {
|
||||||
shell_flags |= kShellOptDoOut;
|
shell_flags |= kShellOptDoOut;
|
||||||
@@ -1337,10 +1311,8 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char *cmd, b
|
|||||||
goto filterend;
|
goto filterend;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// The writing and reading of temp files will not be shown.
|
||||||
* The writing and reading of temp files will not be shown.
|
// Vi also doesn't do this and the messages are not very informative.
|
||||||
* Vi also doesn't do this and the messages are not very informative.
|
|
||||||
*/
|
|
||||||
no_wait_return++; // don't call wait_return() while busy
|
no_wait_return++; // don't call wait_return() while busy
|
||||||
if (itmp != NULL && buf_write(curbuf, itmp, NULL, line1, line2, eap,
|
if (itmp != NULL && buf_write(curbuf, itmp, NULL, line1, line2, eap,
|
||||||
false, false, false, true) == FAIL) {
|
false, false, false, true) == FAIL) {
|
||||||
@@ -1428,10 +1400,8 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char *cmd, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Put cursor on first filtered line for ":range!cmd".
|
||||||
* Put cursor on first filtered line for ":range!cmd".
|
// Adjust '[ and '] (set by buf_write()).
|
||||||
* Adjust '[ and '] (set by buf_write()).
|
|
||||||
*/
|
|
||||||
curwin->w_cursor.lnum = line1;
|
curwin->w_cursor.lnum = line1;
|
||||||
del_lines(linecount, true);
|
del_lines(linecount, true);
|
||||||
curbuf->b_op_start.lnum -= linecount; // adjust '[
|
curbuf->b_op_start.lnum -= linecount; // adjust '[
|
||||||
@@ -1440,9 +1410,7 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char *cmd, b
|
|||||||
// for next write
|
// for next write
|
||||||
foldUpdate(curwin, curbuf->b_op_start.lnum, curbuf->b_op_end.lnum);
|
foldUpdate(curwin, curbuf->b_op_start.lnum, curbuf->b_op_end.lnum);
|
||||||
} else {
|
} else {
|
||||||
/*
|
// Put cursor on last new line for ":r !cmd".
|
||||||
* Put cursor on last new line for ":r !cmd".
|
|
||||||
*/
|
|
||||||
linecount = curbuf->b_op_end.lnum - curbuf->b_op_start.lnum + 1;
|
linecount = curbuf->b_op_end.lnum - curbuf->b_op_start.lnum + 1;
|
||||||
curwin->w_cursor.lnum = curbuf->b_op_end.lnum;
|
curwin->w_cursor.lnum = curbuf->b_op_end.lnum;
|
||||||
}
|
}
|
||||||
@@ -1504,10 +1472,8 @@ void do_shell(char *cmd, int flags)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// For autocommands we want to get the output on the current screen, to
|
||||||
* For autocommands we want to get the output on the current screen, to
|
// avoid having to type return below.
|
||||||
* avoid having to type return below.
|
|
||||||
*/
|
|
||||||
msg_putchar('\r'); // put cursor at start of line
|
msg_putchar('\r'); // put cursor at start of line
|
||||||
msg_putchar('\n'); // may shift screen one line up
|
msg_putchar('\n'); // may shift screen one line up
|
||||||
|
|
||||||
@@ -1740,13 +1706,11 @@ int rename_buffer(char *new_fname)
|
|||||||
if (aborting()) { // autocmds may abort script processing
|
if (aborting()) { // autocmds may abort script processing
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
/*
|
// The name of the current buffer will be changed.
|
||||||
* The name of the current buffer will be changed.
|
// A new (unlisted) buffer entry needs to be made to hold the old file
|
||||||
* A new (unlisted) buffer entry needs to be made to hold the old file
|
// name, which will become the alternate file name.
|
||||||
* name, which will become the alternate file name.
|
// But don't set the alternate file name if the buffer didn't have a
|
||||||
* But don't set the alternate file name if the buffer didn't have a
|
// name.
|
||||||
* name.
|
|
||||||
*/
|
|
||||||
fname = curbuf->b_ffname;
|
fname = curbuf->b_ffname;
|
||||||
sfname = curbuf->b_sfname;
|
sfname = curbuf->b_sfname;
|
||||||
xfname = curbuf->b_fname;
|
xfname = curbuf->b_fname;
|
||||||
@@ -1860,9 +1824,7 @@ int do_write(exarg_T *eap)
|
|||||||
other = otherfile(ffname);
|
other = otherfile(ffname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we have a new file, put its name in the list of alternate file names.
|
||||||
* If we have a new file, put its name in the list of alternate file names.
|
|
||||||
*/
|
|
||||||
if (other) {
|
if (other) {
|
||||||
if (vim_strchr(p_cpo, CPO_ALTWRITE) != NULL
|
if (vim_strchr(p_cpo, CPO_ALTWRITE) != NULL
|
||||||
|| eap->cmdidx == CMD_saveas) {
|
|| eap->cmdidx == CMD_saveas) {
|
||||||
@@ -2113,13 +2075,11 @@ void do_wqall(exarg_T *eap)
|
|||||||
} else if (!bufIsChanged(buf) || bt_dontwrite(buf)) {
|
} else if (!bufIsChanged(buf) || bt_dontwrite(buf)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/*
|
// Check if there is a reason the buffer cannot be written:
|
||||||
* Check if there is a reason the buffer cannot be written:
|
// 1. if the 'write' option is set
|
||||||
* 1. if the 'write' option is set
|
// 2. if there is no file name (even after browsing)
|
||||||
* 2. if there is no file name (even after browsing)
|
// 3. if the 'readonly' is set (even after a dialog)
|
||||||
* 3. if the 'readonly' is set (even after a dialog)
|
// 4. if overwriting is allowed (even after a dialog)
|
||||||
* 4. if overwriting is allowed (even after a dialog)
|
|
||||||
*/
|
|
||||||
if (not_writing()) {
|
if (not_writing()) {
|
||||||
error++;
|
error++;
|
||||||
break;
|
break;
|
||||||
@@ -2405,10 +2365,8 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
|
|||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// End Visual mode before switching to another buffer, so the text can be
|
||||||
* End Visual mode before switching to another buffer, so the text can be
|
// copied into the GUI selection buffer.
|
||||||
* copied into the GUI selection buffer.
|
|
||||||
*/
|
|
||||||
reset_VIsual();
|
reset_VIsual();
|
||||||
|
|
||||||
if ((command != NULL || newlnum > (linenr_T)0)
|
if ((command != NULL || newlnum > (linenr_T)0)
|
||||||
@@ -2426,10 +2384,8 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
|
|||||||
xfree(p);
|
xfree(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we are starting to edit another file, open a (new) buffer.
|
||||||
* If we are starting to edit another file, open a (new) buffer.
|
// Otherwise we re-use the current buffer.
|
||||||
* Otherwise we re-use the current buffer.
|
|
||||||
*/
|
|
||||||
if (other_file) {
|
if (other_file) {
|
||||||
const int prev_alt_fnum = curwin->w_alt_fnum;
|
const int prev_alt_fnum = curwin->w_alt_fnum;
|
||||||
|
|
||||||
@@ -2507,12 +2463,10 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
|
|||||||
solcol = pos->col;
|
solcol = pos->col;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Make the (new) buffer the one used by the current window.
|
||||||
* Make the (new) buffer the one used by the current window.
|
// If the old buffer becomes unused, free it if ECMD_HIDE is false.
|
||||||
* If the old buffer becomes unused, free it if ECMD_HIDE is false.
|
// If the current buffer was empty and has no file name, curbuf
|
||||||
* If the current buffer was empty and has no file name, curbuf
|
// is returned by buflist_new(), nothing to do here.
|
||||||
* is returned by buflist_new(), nothing to do here.
|
|
||||||
*/
|
|
||||||
if (buf != curbuf) {
|
if (buf != curbuf) {
|
||||||
const int save_cmdwin_type = cmdwin_type;
|
const int save_cmdwin_type = cmdwin_type;
|
||||||
|
|
||||||
@@ -2663,13 +2617,11 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
|
|||||||
// highlighting to work in the other file.
|
// highlighting to work in the other file.
|
||||||
did_filetype = false;
|
did_filetype = false;
|
||||||
|
|
||||||
/*
|
// other_file oldbuf
|
||||||
* other_file oldbuf
|
// false false re-edit same file, buffer is re-used
|
||||||
* false false re-edit same file, buffer is re-used
|
// false true re-edit same file, nothing changes
|
||||||
* false true re-edit same file, nothing changes
|
// true false start editing new file, new buffer
|
||||||
* true false start editing new file, new buffer
|
// true true start editing in existing buffer (nothing to do)
|
||||||
* true true start editing in existing buffer (nothing to do)
|
|
||||||
*/
|
|
||||||
if (!other_file && !oldbuf) { // re-use the buffer
|
if (!other_file && !oldbuf) { // re-use the buffer
|
||||||
set_last_cursor(curwin); // may set b_last_cursor
|
set_last_cursor(curwin); // may set b_last_cursor
|
||||||
if (newlnum == ECMD_LAST || newlnum == ECMD_LASTL) {
|
if (newlnum == ECMD_LAST || newlnum == ECMD_LASTL) {
|
||||||
@@ -2728,9 +2680,7 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
|
|||||||
curbuf->b_op_end.lnum = 0;
|
curbuf->b_op_end.lnum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we get here we are sure to start editing
|
||||||
* If we get here we are sure to start editing
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Assume success now
|
// Assume success now
|
||||||
retval = OK;
|
retval = OK;
|
||||||
@@ -2741,17 +2691,13 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
|
|||||||
curbuf->b_flags &= ~BF_NOTEDITED;
|
curbuf->b_flags &= ~BF_NOTEDITED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check if we are editing the w_arg_idx file in the argument list.
|
||||||
* Check if we are editing the w_arg_idx file in the argument list.
|
|
||||||
*/
|
|
||||||
check_arg_idx(curwin);
|
check_arg_idx(curwin);
|
||||||
|
|
||||||
if (!auto_buf) {
|
if (!auto_buf) {
|
||||||
/*
|
// Set cursor and init window before reading the file and executing
|
||||||
* Set cursor and init window before reading the file and executing
|
// autocommands. This allows for the autocommands to position the
|
||||||
* autocommands. This allows for the autocommands to position the
|
// cursor.
|
||||||
* cursor.
|
|
||||||
*/
|
|
||||||
curwin_init();
|
curwin_init();
|
||||||
|
|
||||||
// It's possible that all lines in the buffer changed. Need to update
|
// It's possible that all lines in the buffer changed. Need to update
|
||||||
@@ -2765,19 +2711,15 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
|
|||||||
// Change directories when the 'acd' option is set.
|
// Change directories when the 'acd' option is set.
|
||||||
do_autochdir();
|
do_autochdir();
|
||||||
|
|
||||||
/*
|
// Careful: open_buffer() and apply_autocmds() may change the current
|
||||||
* Careful: open_buffer() and apply_autocmds() may change the current
|
// buffer and window.
|
||||||
* buffer and window.
|
|
||||||
*/
|
|
||||||
orig_pos = curwin->w_cursor;
|
orig_pos = curwin->w_cursor;
|
||||||
topline = curwin->w_topline;
|
topline = curwin->w_topline;
|
||||||
if (!oldbuf) { // need to read the file
|
if (!oldbuf) { // need to read the file
|
||||||
swap_exists_action = SEA_DIALOG;
|
swap_exists_action = SEA_DIALOG;
|
||||||
curbuf->b_flags |= BF_CHECK_RO; // set/reset 'ro' flag
|
curbuf->b_flags |= BF_CHECK_RO; // set/reset 'ro' flag
|
||||||
|
|
||||||
/*
|
// Open the buffer and read the file.
|
||||||
* Open the buffer and read the file.
|
|
||||||
*/
|
|
||||||
if (flags & ECMD_NOWINENTER) {
|
if (flags & ECMD_NOWINENTER) {
|
||||||
readfile_flags |= READ_NOWINENTER;
|
readfile_flags |= READ_NOWINENTER;
|
||||||
}
|
}
|
||||||
@@ -2868,10 +2810,8 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
|
|||||||
// Check if cursors in other windows on the same buffer are still valid
|
// Check if cursors in other windows on the same buffer are still valid
|
||||||
check_lnums(false);
|
check_lnums(false);
|
||||||
|
|
||||||
/*
|
// Did not read the file, need to show some info about the file.
|
||||||
* Did not read the file, need to show some info about the file.
|
// Do this after setting the cursor.
|
||||||
* Do this after setting the cursor.
|
|
||||||
*/
|
|
||||||
if (oldbuf
|
if (oldbuf
|
||||||
&& !auto_buf) {
|
&& !auto_buf) {
|
||||||
int msg_scroll_save = msg_scroll;
|
int msg_scroll_save = msg_scroll;
|
||||||
@@ -3559,10 +3499,8 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Small incompatibility: vi sees '\n' as end of the command, but in
|
||||||
* Small incompatibility: vi sees '\n' as end of the command, but in
|
// Vim we want to use '\n' to find/substitute a NUL.
|
||||||
* Vim we want to use '\n' to find/substitute a NUL.
|
|
||||||
*/
|
|
||||||
sub = cmd; // remember the start of the substitution
|
sub = cmd; // remember the start of the substitution
|
||||||
|
|
||||||
while (cmd[0]) {
|
while (cmd[0]) {
|
||||||
@@ -3620,9 +3558,7 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// check for trailing command or garbage
|
||||||
* check for trailing command or garbage
|
|
||||||
*/
|
|
||||||
cmd = skipwhite(cmd);
|
cmd = skipwhite(cmd);
|
||||||
if (*cmd && *cmd != '"') { // if not end-of-line or comment
|
if (*cmd && *cmd != '"') { // if not end-of-line or comment
|
||||||
eap->nextcmd = check_nextcmd(cmd);
|
eap->nextcmd = check_nextcmd(cmd);
|
||||||
@@ -3711,50 +3647,48 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T
|
|||||||
bool skip_match = false;
|
bool skip_match = false;
|
||||||
linenr_T sub_firstlnum; // nr of first sub line
|
linenr_T sub_firstlnum; // nr of first sub line
|
||||||
|
|
||||||
/*
|
// The new text is build up step by step, to avoid too much
|
||||||
* The new text is build up step by step, to avoid too much
|
// copying. There are these pieces:
|
||||||
* copying. There are these pieces:
|
// sub_firstline The old text, unmodified.
|
||||||
* sub_firstline The old text, unmodified.
|
// copycol Column in the old text where we started
|
||||||
* copycol Column in the old text where we started
|
// looking for a match; from here old text still
|
||||||
* looking for a match; from here old text still
|
// needs to be copied to the new text.
|
||||||
* needs to be copied to the new text.
|
// matchcol Column number of the old text where to look
|
||||||
* matchcol Column number of the old text where to look
|
// for the next match. It's just after the
|
||||||
* for the next match. It's just after the
|
// previous match or one further.
|
||||||
* previous match or one further.
|
// prev_matchcol Column just after the previous match (if any).
|
||||||
* prev_matchcol Column just after the previous match (if any).
|
// Mostly equal to matchcol, except for the first
|
||||||
* Mostly equal to matchcol, except for the first
|
// match and after skipping an empty match.
|
||||||
* match and after skipping an empty match.
|
// regmatch.*pos Where the pattern matched in the old text.
|
||||||
* regmatch.*pos Where the pattern matched in the old text.
|
// new_start The new text, all that has been produced so
|
||||||
* new_start The new text, all that has been produced so
|
// far.
|
||||||
* far.
|
// new_end The new text, where to append new text.
|
||||||
* new_end The new text, where to append new text.
|
//
|
||||||
*
|
// lnum The line number where we found the start of
|
||||||
* lnum The line number where we found the start of
|
// the match. Can be below the line we searched
|
||||||
* the match. Can be below the line we searched
|
// when there is a \n before a \zs in the
|
||||||
* when there is a \n before a \zs in the
|
// pattern.
|
||||||
* pattern.
|
// sub_firstlnum The line number in the buffer where to look
|
||||||
* sub_firstlnum The line number in the buffer where to look
|
// for a match. Can be different from "lnum"
|
||||||
* for a match. Can be different from "lnum"
|
// when the pattern or substitute string contains
|
||||||
* when the pattern or substitute string contains
|
// line breaks.
|
||||||
* line breaks.
|
//
|
||||||
*
|
// Special situations:
|
||||||
* Special situations:
|
// - When the substitute string contains a line break, the part up
|
||||||
* - When the substitute string contains a line break, the part up
|
// to the line break is inserted in the text, but the copy of
|
||||||
* to the line break is inserted in the text, but the copy of
|
// the original line is kept. "sub_firstlnum" is adjusted for
|
||||||
* the original line is kept. "sub_firstlnum" is adjusted for
|
// the inserted lines.
|
||||||
* the inserted lines.
|
// - When the matched pattern contains a line break, the old line
|
||||||
* - When the matched pattern contains a line break, the old line
|
// is taken from the line at the end of the pattern. The lines
|
||||||
* is taken from the line at the end of the pattern. The lines
|
// in the match are deleted later, "sub_firstlnum" is adjusted
|
||||||
* in the match are deleted later, "sub_firstlnum" is adjusted
|
// accordingly.
|
||||||
* accordingly.
|
//
|
||||||
*
|
// The new text is built up in new_start[]. It has some extra
|
||||||
* The new text is built up in new_start[]. It has some extra
|
// room to avoid using xmalloc()/free() too often.
|
||||||
* room to avoid using xmalloc()/free() too often.
|
//
|
||||||
*
|
// Make a copy of the old line, so it won't be taken away when
|
||||||
* Make a copy of the old line, so it won't be taken away when
|
// updating the screen or handling a multi-line match. The "old_"
|
||||||
* updating the screen or handling a multi-line match. The "old_"
|
// pointers point into this copy.
|
||||||
* pointers point into this copy.
|
|
||||||
*/
|
|
||||||
sub_firstlnum = lnum;
|
sub_firstlnum = lnum;
|
||||||
copycol = 0;
|
copycol = 0;
|
||||||
matchcol = 0;
|
matchcol = 0;
|
||||||
@@ -3765,14 +3699,12 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T
|
|||||||
got_match = true;
|
got_match = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Loop until nothing more to replace in this line.
|
||||||
* Loop until nothing more to replace in this line.
|
// 1. Handle match with empty string.
|
||||||
* 1. Handle match with empty string.
|
// 2. If subflags.do_ask is set, ask for confirmation.
|
||||||
* 2. If subflags.do_ask is set, ask for confirmation.
|
// 3. substitute the string.
|
||||||
* 3. substitute the string.
|
// 4. if subflags.do_all is set, find next match
|
||||||
* 4. if subflags.do_all is set, find next match
|
// 5. break if there isn't another match in this line
|
||||||
* 5. break if there isn't another match in this line
|
|
||||||
*/
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
SubResult current_match = {
|
SubResult current_match = {
|
||||||
.start = { 0, 0 },
|
.start = { 0, 0 },
|
||||||
@@ -3811,11 +3743,9 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T
|
|||||||
curwin->w_cursor.lnum = lnum;
|
curwin->w_cursor.lnum = lnum;
|
||||||
do_again = false;
|
do_again = false;
|
||||||
|
|
||||||
/*
|
// 1. Match empty string does not count, except for first
|
||||||
* 1. Match empty string does not count, except for first
|
// match. This reproduces the strange vi behaviour.
|
||||||
* match. This reproduces the strange vi behaviour.
|
// This also catches endless loops.
|
||||||
* This also catches endless loops.
|
|
||||||
*/
|
|
||||||
if (matchcol == prev_matchcol
|
if (matchcol == prev_matchcol
|
||||||
&& regmatch.endpos[0].lnum == 0
|
&& regmatch.endpos[0].lnum == 0
|
||||||
&& matchcol == regmatch.endpos[0].col) {
|
&& matchcol == regmatch.endpos[0].col) {
|
||||||
@@ -3880,9 +3810,7 @@ static int do_sub(exarg_T *eap, proftime_T timeout, long cmdpreview_ns, handle_T
|
|||||||
no_u_sync++;
|
no_u_sync++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Loop until 'y', 'n', 'q', CTRL-E or CTRL-Y typed.
|
||||||
* Loop until 'y', 'n', 'q', CTRL-E or CTRL-Y typed.
|
|
||||||
*/
|
|
||||||
while (subflags.do_ask) {
|
while (subflags.do_ask) {
|
||||||
if (exmode_active) {
|
if (exmode_active) {
|
||||||
char *prompt;
|
char *prompt;
|
||||||
@@ -4266,15 +4194,13 @@ skip:
|
|||||||
&& !re_multiline(regmatch.regprog)));
|
&& !re_multiline(regmatch.regprog)));
|
||||||
nmatch = -1;
|
nmatch = -1;
|
||||||
|
|
||||||
/*
|
// Replace the line in the buffer when needed. This is
|
||||||
* Replace the line in the buffer when needed. This is
|
// skipped when there are more matches.
|
||||||
* skipped when there are more matches.
|
// The check for nmatch_tl is needed for when multi-line
|
||||||
* The check for nmatch_tl is needed for when multi-line
|
// matching must replace the lines before trying to do another
|
||||||
* matching must replace the lines before trying to do another
|
// match, otherwise "\@<=" won't work.
|
||||||
* match, otherwise "\@<=" won't work.
|
// When the match starts below where we start searching also
|
||||||
* When the match starts below where we start searching also
|
// need to replace the line first (using \zs after \n).
|
||||||
* need to replace the line first (using \zs after \n).
|
|
||||||
*/
|
|
||||||
if (lastone
|
if (lastone
|
||||||
|| nmatch_tl > 0
|
|| nmatch_tl > 0
|
||||||
|| (nmatch = vim_regexec_multi(®match, curwin,
|
|| (nmatch = vim_regexec_multi(®match, curwin,
|
||||||
@@ -4282,13 +4208,11 @@ skip:
|
|||||||
matchcol, NULL, NULL)) == 0
|
matchcol, NULL, NULL)) == 0
|
||||||
|| regmatch.startpos[0].lnum > 0) {
|
|| regmatch.startpos[0].lnum > 0) {
|
||||||
if (new_start != NULL) {
|
if (new_start != NULL) {
|
||||||
/*
|
// Copy the rest of the line, that didn't match.
|
||||||
* Copy the rest of the line, that didn't match.
|
// "matchcol" has to be adjusted, we use the end of
|
||||||
* "matchcol" has to be adjusted, we use the end of
|
// the line as reference, because the substitute may
|
||||||
* the line as reference, because the substitute may
|
// have changed the number of characters. Same for
|
||||||
* have changed the number of characters. Same for
|
// "prev_matchcol".
|
||||||
* "prev_matchcol".
|
|
||||||
*/
|
|
||||||
STRCAT(new_start, sub_firstline + copycol);
|
STRCAT(new_start, sub_firstline + copycol);
|
||||||
matchcol = (colnr_T)STRLEN(sub_firstline) - matchcol;
|
matchcol = (colnr_T)STRLEN(sub_firstline) - matchcol;
|
||||||
prev_matchcol = (colnr_T)STRLEN(sub_firstline)
|
prev_matchcol = (colnr_T)STRLEN(sub_firstline)
|
||||||
@@ -4300,12 +4224,10 @@ skip:
|
|||||||
ml_replace(lnum, new_start, true);
|
ml_replace(lnum, new_start, true);
|
||||||
|
|
||||||
if (nmatch_tl > 0) {
|
if (nmatch_tl > 0) {
|
||||||
/*
|
// Matched lines have now been substituted and are
|
||||||
* Matched lines have now been substituted and are
|
// useless, delete them. The part after the match
|
||||||
* useless, delete them. The part after the match
|
// has been appended to new_start, we don't need
|
||||||
* has been appended to new_start, we don't need
|
// it in the buffer.
|
||||||
* it in the buffer.
|
|
||||||
*/
|
|
||||||
lnum++;
|
lnum++;
|
||||||
if (u_savedel(lnum, nmatch_tl) != OK) {
|
if (u_savedel(lnum, nmatch_tl) != OK) {
|
||||||
break;
|
break;
|
||||||
@@ -4348,9 +4270,7 @@ skip:
|
|||||||
sub_firstlnum, matchcol, NULL, NULL);
|
sub_firstlnum, matchcol, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// 5. break if there isn't another match in this line
|
||||||
* 5. break if there isn't another match in this line
|
|
||||||
*/
|
|
||||||
if (nmatch <= 0) {
|
if (nmatch <= 0) {
|
||||||
// If the match found didn't start where we were
|
// If the match found didn't start where we were
|
||||||
// searching, do the next search in the line where we
|
// searching, do the next search in the line where we
|
||||||
@@ -4513,12 +4433,10 @@ skip:
|
|||||||
/// @return true if a message was given.
|
/// @return true if a message was given.
|
||||||
bool do_sub_msg(bool count_only)
|
bool do_sub_msg(bool count_only)
|
||||||
{
|
{
|
||||||
/*
|
// Only report substitutions when:
|
||||||
* Only report substitutions when:
|
// - more than 'report' substitutions
|
||||||
* - more than 'report' substitutions
|
// - command was typed by user, or number of changed lines > 'report'
|
||||||
* - command was typed by user, or number of changed lines > 'report'
|
// - giving messages is not disabled by 'lazyredraw'
|
||||||
* - giving messages is not disabled by 'lazyredraw'
|
|
||||||
*/
|
|
||||||
if (((sub_nsubs > p_report && (KeyTyped || sub_nlines > 1 || p_report < 1))
|
if (((sub_nsubs > p_report && (KeyTyped || sub_nlines > 1 || p_report < 1))
|
||||||
|| count_only)
|
|| count_only)
|
||||||
&& messaging()) {
|
&& messaging()) {
|
||||||
@@ -4609,11 +4527,9 @@ void ex_global(exarg_T *eap)
|
|||||||
cmd = eap->arg;
|
cmd = eap->arg;
|
||||||
which_pat = RE_LAST; // default: use last used regexp
|
which_pat = RE_LAST; // default: use last used regexp
|
||||||
|
|
||||||
/*
|
// undocumented vi feature:
|
||||||
* undocumented vi feature:
|
// "\/" and "\?": use previous search pattern.
|
||||||
* "\/" and "\?": use previous search pattern.
|
// "\&": use previous substitute pattern.
|
||||||
* "\&": use previous substitute pattern.
|
|
||||||
*/
|
|
||||||
if (*cmd == '\\') {
|
if (*cmd == '\\') {
|
||||||
cmd++;
|
cmd++;
|
||||||
if (vim_strchr("/?&", *cmd) == NULL) {
|
if (vim_strchr("/?&", *cmd) == NULL) {
|
||||||
@@ -4752,9 +4668,7 @@ void free_old_sub(void)
|
|||||||
/// @return true when it was created.
|
/// @return true when it was created.
|
||||||
bool prepare_tagpreview(bool undo_sync)
|
bool prepare_tagpreview(bool undo_sync)
|
||||||
{
|
{
|
||||||
/*
|
// If there is already a preview window open, use that one.
|
||||||
* If there is already a preview window open, use that one.
|
|
||||||
*/
|
|
||||||
if (!curwin->w_p_pvw) {
|
if (!curwin->w_p_pvw) {
|
||||||
bool found_win = false;
|
bool found_win = false;
|
||||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||||
@@ -4765,9 +4679,7 @@ bool prepare_tagpreview(bool undo_sync)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found_win) {
|
if (!found_win) {
|
||||||
/*
|
// There is no preview window open yet. Create one.
|
||||||
* There is no preview window open yet. Create one.
|
|
||||||
*/
|
|
||||||
if (win_split(g_do_tagpreview > 0 ? g_do_tagpreview : 0, 0)
|
if (win_split(g_do_tagpreview > 0 ? g_do_tagpreview : 0, 0)
|
||||||
== FAIL) {
|
== FAIL) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -79,15 +79,13 @@ static void discard_pending_return(typval_T *p)
|
|||||||
tv_free(p);
|
tv_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When several errors appear in a row, setting "force_abort" is delayed until
|
||||||
* When several errors appear in a row, setting "force_abort" is delayed until
|
// the failing command returned. "cause_abort" is set to true meanwhile, in
|
||||||
* the failing command returned. "cause_abort" is set to true meanwhile, in
|
// order to indicate that situation. This is useful when "force_abort" was set
|
||||||
* order to indicate that situation. This is useful when "force_abort" was set
|
// during execution of a function call from an expression: the aborting of the
|
||||||
* during execution of a function call from an expression: the aborting of the
|
// expression evaluation is done without producing any error messages, but all
|
||||||
* expression evaluation is done without producing any error messages, but all
|
// error messages on parsing errors during the expression evaluation are given
|
||||||
* error messages on parsing errors during the expression evaluation are given
|
// (even if a try conditional is active).
|
||||||
* (even if a try conditional is active).
|
|
||||||
*/
|
|
||||||
static int cause_abort = false;
|
static int cause_abort = false;
|
||||||
|
|
||||||
/// @return true when immediately aborting on error, or when an interrupt
|
/// @return true when immediately aborting on error, or when an interrupt
|
||||||
@@ -153,69 +151,57 @@ bool cause_errthrow(const char *mesg, bool severe, bool *ignore)
|
|||||||
msglist_T *elem;
|
msglist_T *elem;
|
||||||
msglist_T **plist;
|
msglist_T **plist;
|
||||||
|
|
||||||
/*
|
// Do nothing when displaying the interrupt message or reporting an
|
||||||
* Do nothing when displaying the interrupt message or reporting an
|
// uncaught exception (which has already been discarded then) at the top
|
||||||
* uncaught exception (which has already been discarded then) at the top
|
// level. Also when no exception can be thrown. The message will be
|
||||||
* level. Also when no exception can be thrown. The message will be
|
// displayed by emsg().
|
||||||
* displayed by emsg().
|
|
||||||
*/
|
|
||||||
if (suppress_errthrow) {
|
if (suppress_errthrow) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If emsg() has not been called previously, temporarily reset
|
||||||
* If emsg() has not been called previously, temporarily reset
|
// "force_abort" until the throw point for error messages has been
|
||||||
* "force_abort" until the throw point for error messages has been
|
// reached. This ensures that aborting() returns the same value for all
|
||||||
* reached. This ensures that aborting() returns the same value for all
|
// errors that appear in the same command. This means particularly that
|
||||||
* errors that appear in the same command. This means particularly that
|
// for parsing errors during expression evaluation emsg() will be called
|
||||||
* for parsing errors during expression evaluation emsg() will be called
|
// multiply, even when the expression is evaluated from a finally clause
|
||||||
* multiply, even when the expression is evaluated from a finally clause
|
// that was activated due to an aborting error, interrupt, or exception.
|
||||||
* that was activated due to an aborting error, interrupt, or exception.
|
|
||||||
*/
|
|
||||||
if (!did_emsg) {
|
if (!did_emsg) {
|
||||||
cause_abort = force_abort;
|
cause_abort = force_abort;
|
||||||
force_abort = false;
|
force_abort = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If no try conditional is active and no exception is being thrown and
|
||||||
* If no try conditional is active and no exception is being thrown and
|
// there has not been an error in a try conditional or a throw so far, do
|
||||||
* there has not been an error in a try conditional or a throw so far, do
|
// nothing (for compatibility of non-EH scripts). The message will then
|
||||||
* nothing (for compatibility of non-EH scripts). The message will then
|
// be displayed by emsg(). When ":silent!" was used and we are not
|
||||||
* be displayed by emsg(). When ":silent!" was used and we are not
|
// currently throwing an exception, do nothing. The message text will
|
||||||
* currently throwing an exception, do nothing. The message text will
|
// then be stored to v:errmsg by emsg() without displaying it.
|
||||||
* then be stored to v:errmsg by emsg() without displaying it.
|
|
||||||
*/
|
|
||||||
if (((trylevel == 0 && !cause_abort) || emsg_silent) && !did_throw) {
|
if (((trylevel == 0 && !cause_abort) || emsg_silent) && !did_throw) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Ignore an interrupt message when inside a try conditional or when an
|
||||||
* Ignore an interrupt message when inside a try conditional or when an
|
// exception is being thrown or when an error in a try conditional or
|
||||||
* exception is being thrown or when an error in a try conditional or
|
// throw has been detected previously. This is important in order that an
|
||||||
* throw has been detected previously. This is important in order that an
|
// interrupt exception is catchable by the innermost try conditional and
|
||||||
* interrupt exception is catchable by the innermost try conditional and
|
// not replaced by an interrupt message error exception.
|
||||||
* not replaced by an interrupt message error exception.
|
|
||||||
*/
|
|
||||||
if (mesg == _(e_interr)) {
|
if (mesg == _(e_interr)) {
|
||||||
*ignore = true;
|
*ignore = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Ensure that all commands in nested function calls and sourced files
|
||||||
* Ensure that all commands in nested function calls and sourced files
|
// are aborted immediately.
|
||||||
* are aborted immediately.
|
|
||||||
*/
|
|
||||||
cause_abort = true;
|
cause_abort = true;
|
||||||
|
|
||||||
/*
|
// When an exception is being thrown, some commands (like conditionals) are
|
||||||
* When an exception is being thrown, some commands (like conditionals) are
|
// not skipped. Errors in those commands may affect what of the subsequent
|
||||||
* not skipped. Errors in those commands may affect what of the subsequent
|
// commands are regarded part of catch and finally clauses. Catching the
|
||||||
* commands are regarded part of catch and finally clauses. Catching the
|
// exception would then cause execution of commands not intended by the
|
||||||
* exception would then cause execution of commands not intended by the
|
// user, who wouldn't even get aware of the problem. Therefore, discard the
|
||||||
* user, who wouldn't even get aware of the problem. Therefore, discard the
|
// exception currently being thrown to prevent it from being caught. Just
|
||||||
* exception currently being thrown to prevent it from being caught. Just
|
// execute finally clauses and terminate.
|
||||||
* execute finally clauses and terminate.
|
|
||||||
*/
|
|
||||||
if (did_throw) {
|
if (did_throw) {
|
||||||
// When discarding an interrupt exception, reset got_int to prevent the
|
// When discarding an interrupt exception, reset got_int to prevent the
|
||||||
// same interrupt being converted to an exception again and discarding
|
// same interrupt being converted to an exception again and discarding
|
||||||
@@ -228,25 +214,21 @@ bool cause_errthrow(const char *mesg, bool severe, bool *ignore)
|
|||||||
|
|
||||||
#ifdef THROW_TEST
|
#ifdef THROW_TEST
|
||||||
if (!THROW_ON_ERROR) {
|
if (!THROW_ON_ERROR) {
|
||||||
/*
|
// Print error message immediately without searching for a matching
|
||||||
* Print error message immediately without searching for a matching
|
// catch clause; just finally clauses are executed before the script
|
||||||
* catch clause; just finally clauses are executed before the script
|
// is terminated.
|
||||||
* is terminated.
|
|
||||||
*/
|
|
||||||
return false;
|
return false;
|
||||||
} else // NOLINT(readability/braces)
|
} else // NOLINT(readability/braces)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/*
|
// Prepare the throw of an error exception, so that everything will
|
||||||
* Prepare the throw of an error exception, so that everything will
|
// be aborted (except for executing finally clauses), until the error
|
||||||
* be aborted (except for executing finally clauses), until the error
|
// exception is caught; if still uncaught at the top level, the error
|
||||||
* exception is caught; if still uncaught at the top level, the error
|
// message will be displayed and the script processing terminated
|
||||||
* message will be displayed and the script processing terminated
|
// then. - This function has no access to the conditional stack.
|
||||||
* then. - This function has no access to the conditional stack.
|
// Thus, the actual throw is made after the failing command has
|
||||||
* Thus, the actual throw is made after the failing command has
|
// returned. - Throw only the first of several errors in a row, except
|
||||||
* returned. - Throw only the first of several errors in a row, except
|
// a severe error is following.
|
||||||
* a severe error is following.
|
|
||||||
*/
|
|
||||||
if (msg_list != NULL) {
|
if (msg_list != NULL) {
|
||||||
plist = msg_list;
|
plist = msg_list;
|
||||||
while (*plist != NULL) {
|
while (*plist != NULL) {
|
||||||
@@ -312,10 +294,8 @@ void free_global_msglist(void)
|
|||||||
/// has returned (see do_one_cmd()).
|
/// has returned (see do_one_cmd()).
|
||||||
void do_errthrow(cstack_T *cstack, char *cmdname)
|
void do_errthrow(cstack_T *cstack, char *cmdname)
|
||||||
{
|
{
|
||||||
/*
|
// Ensure that all commands in nested function calls and sourced files
|
||||||
* Ensure that all commands in nested function calls and sourced files
|
// are aborted immediately.
|
||||||
* are aborted immediately.
|
|
||||||
*/
|
|
||||||
if (cause_abort) {
|
if (cause_abort) {
|
||||||
cause_abort = false;
|
cause_abort = false;
|
||||||
force_abort = true;
|
force_abort = true;
|
||||||
@@ -455,11 +435,9 @@ static int throw_exception(void *value, except_type_T type, char *cmdname)
|
|||||||
except_T *excp;
|
except_T *excp;
|
||||||
int should_free;
|
int should_free;
|
||||||
|
|
||||||
/*
|
// Disallow faking Interrupt or error exceptions as user exceptions. They
|
||||||
* Disallow faking Interrupt or error exceptions as user exceptions. They
|
// would be treated differently from real interrupt or error exceptions
|
||||||
* would be treated differently from real interrupt or error exceptions
|
// when no active try block is found, see do_cmdline().
|
||||||
* when no active try block is found, see do_cmdline().
|
|
||||||
*/
|
|
||||||
if (type == ET_USER) {
|
if (type == ET_USER) {
|
||||||
if (STRNCMP((char_u *)value, "Vim", 3) == 0
|
if (STRNCMP((char_u *)value, "Vim", 3) == 0
|
||||||
&& (((char_u *)value)[3] == NUL || ((char_u *)value)[3] == ':'
|
&& (((char_u *)value)[3] == NUL || ((char_u *)value)[3] == ':'
|
||||||
@@ -678,9 +656,7 @@ static void finish_exception(except_T *excp)
|
|||||||
discard_exception(excp, true);
|
discard_exception(excp, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Flags specifying the message displayed by report_pending.
|
||||||
* Flags specifying the message displayed by report_pending.
|
|
||||||
*/
|
|
||||||
#define RP_MAKE 0
|
#define RP_MAKE 0
|
||||||
#define RP_RESUME 1
|
#define RP_RESUME 1
|
||||||
#define RP_DISCARD 2
|
#define RP_DISCARD 2
|
||||||
@@ -958,11 +934,9 @@ void ex_while(exarg_T *eap)
|
|||||||
if (cstack->cs_idx == CSTACK_LEN - 1) {
|
if (cstack->cs_idx == CSTACK_LEN - 1) {
|
||||||
eap->errmsg = _("E585: :while/:for nesting too deep");
|
eap->errmsg = _("E585: :while/:for nesting too deep");
|
||||||
} else {
|
} else {
|
||||||
/*
|
// The loop flag is set when we have jumped back from the matching
|
||||||
* The loop flag is set when we have jumped back from the matching
|
// ":endwhile" or ":endfor". When not set, need to initialise this
|
||||||
* ":endwhile" or ":endfor". When not set, need to initialise this
|
// cstack entry.
|
||||||
* cstack entry.
|
|
||||||
*/
|
|
||||||
if ((cstack->cs_lflags & CSL_HAD_LOOP) == 0) {
|
if ((cstack->cs_lflags & CSL_HAD_LOOP) == 0) {
|
||||||
cstack->cs_idx++;
|
cstack->cs_idx++;
|
||||||
cstack->cs_looplevel++;
|
cstack->cs_looplevel++;
|
||||||
@@ -973,16 +947,12 @@ void ex_while(exarg_T *eap)
|
|||||||
|
|
||||||
skip = CHECK_SKIP;
|
skip = CHECK_SKIP;
|
||||||
if (eap->cmdidx == CMD_while) {
|
if (eap->cmdidx == CMD_while) {
|
||||||
/*
|
// ":while bool-expr"
|
||||||
* ":while bool-expr"
|
|
||||||
*/
|
|
||||||
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
|
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
|
||||||
} else {
|
} else {
|
||||||
void *fi;
|
void *fi;
|
||||||
|
|
||||||
/*
|
// ":for var in list-expr"
|
||||||
* ":for var in list-expr"
|
|
||||||
*/
|
|
||||||
if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0) {
|
if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0) {
|
||||||
// Jumping here from a ":continue" or ":endfor": use the
|
// Jumping here from a ":continue" or ":endfor": use the
|
||||||
// previously evaluated list.
|
// previously evaluated list.
|
||||||
@@ -1007,11 +977,9 @@ void ex_while(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If this cstack entry was just initialised and is active, set the
|
||||||
* If this cstack entry was just initialised and is active, set the
|
// loop flag, so do_cmdline() will set the line number in cs_line[].
|
||||||
* loop flag, so do_cmdline() will set the line number in cs_line[].
|
// If executing the command a second time, clear the loop flag.
|
||||||
* If executing the command a second time, clear the loop flag.
|
|
||||||
*/
|
|
||||||
if (!skip && !error && result) {
|
if (!skip && !error && result) {
|
||||||
cstack->cs_flags[cstack->cs_idx] |= (CSF_ACTIVE | CSF_TRUE);
|
cstack->cs_flags[cstack->cs_idx] |= (CSF_ACTIVE | CSF_TRUE);
|
||||||
cstack->cs_lflags ^= CSL_HAD_LOOP;
|
cstack->cs_lflags ^= CSL_HAD_LOOP;
|
||||||
@@ -1046,10 +1014,8 @@ void ex_continue(exarg_T *eap)
|
|||||||
if (cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR)) {
|
if (cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR)) {
|
||||||
rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
|
rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
|
||||||
|
|
||||||
/*
|
// Set CSL_HAD_CONT, so do_cmdline() will jump back to the
|
||||||
* Set CSL_HAD_CONT, so do_cmdline() will jump back to the
|
// matching ":while".
|
||||||
* matching ":while".
|
|
||||||
*/
|
|
||||||
cstack->cs_lflags |= CSL_HAD_CONT; // let do_cmdline() handle it
|
cstack->cs_lflags |= CSL_HAD_CONT; // let do_cmdline() handle it
|
||||||
} else {
|
} else {
|
||||||
// If a try conditional not in its finally clause is reached first,
|
// If a try conditional not in its finally clause is reached first,
|
||||||
@@ -1147,10 +1113,8 @@ void ex_endwhile(exarg_T *eap)
|
|||||||
(void)do_intthrow(cstack);
|
(void)do_intthrow(cstack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set loop flag, so do_cmdline() will jump back to the matching
|
||||||
* Set loop flag, so do_cmdline() will jump back to the matching
|
// ":while" or ":for".
|
||||||
* ":while" or ":for".
|
|
||||||
*/
|
|
||||||
cstack->cs_lflags |= CSL_HAD_ENDLOOP;
|
cstack->cs_lflags |= CSL_HAD_ENDLOOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1211,19 +1175,17 @@ void do_throw(cstack_T *cstack)
|
|||||||
#endif
|
#endif
|
||||||
idx = cleanup_conditionals(cstack, 0, inactivate_try);
|
idx = cleanup_conditionals(cstack, 0, inactivate_try);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
/*
|
// If this try conditional is active and we are before its first
|
||||||
* If this try conditional is active and we are before its first
|
// ":catch", set THROWN so that the ":catch" commands will check
|
||||||
* ":catch", set THROWN so that the ":catch" commands will check
|
// whether the exception matches. When the exception came from any of
|
||||||
* whether the exception matches. When the exception came from any of
|
// the catch clauses, it will be made pending at the ":finally" (if
|
||||||
* the catch clauses, it will be made pending at the ":finally" (if
|
// present) and rethrown at the ":endtry". This will also happen if
|
||||||
* present) and rethrown at the ":endtry". This will also happen if
|
// the try conditional is inactive. This is the case when we are
|
||||||
* the try conditional is inactive. This is the case when we are
|
// throwing an exception due to an error or interrupt on the way from
|
||||||
* throwing an exception due to an error or interrupt on the way from
|
// a preceding ":continue", ":break", ":return", ":finish", error or
|
||||||
* a preceding ":continue", ":break", ":return", ":finish", error or
|
// interrupt (not converted to an exception) to the finally clause or
|
||||||
* interrupt (not converted to an exception) to the finally clause or
|
// from a preceding throw of a user or error or interrupt exception to
|
||||||
* from a preceding throw of a user or error or interrupt exception to
|
// the matching catch clause or the finally clause.
|
||||||
* the matching catch clause or the finally clause.
|
|
||||||
*/
|
|
||||||
if (!(cstack->cs_flags[idx] & CSF_CAUGHT)) {
|
if (!(cstack->cs_flags[idx] & CSF_CAUGHT)) {
|
||||||
if (cstack->cs_flags[idx] & CSF_ACTIVE) {
|
if (cstack->cs_flags[idx] & CSF_ACTIVE) {
|
||||||
cstack->cs_flags[idx] |= CSF_THROWN;
|
cstack->cs_flags[idx] |= CSF_THROWN;
|
||||||
@@ -1263,22 +1225,20 @@ void ex_try(exarg_T *eap)
|
|||||||
// that the finally clause needs to be executed.
|
// that the finally clause needs to be executed.
|
||||||
cstack->cs_flags[cstack->cs_idx] |= CSF_ACTIVE | CSF_TRUE;
|
cstack->cs_flags[cstack->cs_idx] |= CSF_ACTIVE | CSF_TRUE;
|
||||||
|
|
||||||
/*
|
// ":silent!", even when used in a try conditional, disables
|
||||||
* ":silent!", even when used in a try conditional, disables
|
// displaying of error messages and conversion of errors to
|
||||||
* displaying of error messages and conversion of errors to
|
// exceptions. When the silent commands again open a try
|
||||||
* exceptions. When the silent commands again open a try
|
// conditional, save "emsg_silent" and reset it so that errors are
|
||||||
* conditional, save "emsg_silent" and reset it so that errors are
|
// again converted to exceptions. The value is restored when that
|
||||||
* again converted to exceptions. The value is restored when that
|
// try conditional is left. If it is left normally, the commands
|
||||||
* try conditional is left. If it is left normally, the commands
|
// following the ":endtry" are again silent. If it is left by
|
||||||
* following the ":endtry" are again silent. If it is left by
|
// a ":continue", ":break", ":return", or ":finish", the commands
|
||||||
* a ":continue", ":break", ":return", or ":finish", the commands
|
// executed next are again silent. If it is left due to an
|
||||||
* executed next are again silent. If it is left due to an
|
// aborting error, an interrupt, or an exception, restoring
|
||||||
* aborting error, an interrupt, or an exception, restoring
|
// "emsg_silent" does not matter since we are already in the
|
||||||
* "emsg_silent" does not matter since we are already in the
|
// aborting state and/or the exception has already been thrown.
|
||||||
* aborting state and/or the exception has already been thrown.
|
// The effect is then just freeing the memory that was allocated
|
||||||
* The effect is then just freeing the memory that was allocated
|
// to save the value.
|
||||||
* to save the value.
|
|
||||||
*/
|
|
||||||
if (emsg_silent) {
|
if (emsg_silent) {
|
||||||
eslist_T *elem = xmalloc(sizeof(*elem));
|
eslist_T *elem = xmalloc(sizeof(*elem));
|
||||||
elem->saved_emsg_silent = emsg_silent;
|
elem->saved_emsg_silent = emsg_silent;
|
||||||
@@ -1342,20 +1302,16 @@ void ex_catch(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!give_up) {
|
if (!give_up) {
|
||||||
/*
|
// Don't do something when no exception has been thrown or when the
|
||||||
* Don't do something when no exception has been thrown or when the
|
// corresponding try block never got active (because of an inactive
|
||||||
* corresponding try block never got active (because of an inactive
|
// surrounding conditional or after an error or interrupt or throw).
|
||||||
* surrounding conditional or after an error or interrupt or throw).
|
|
||||||
*/
|
|
||||||
if (!did_throw || !(cstack->cs_flags[idx] & CSF_TRUE)) {
|
if (!did_throw || !(cstack->cs_flags[idx] & CSF_TRUE)) {
|
||||||
skip = true;
|
skip = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check for a match only if an exception is thrown but not caught by
|
||||||
* Check for a match only if an exception is thrown but not caught by
|
// a previous ":catch". An exception that has replaced a discarded
|
||||||
* a previous ":catch". An exception that has replaced a discarded
|
// exception is not checked (THROWN is not set then).
|
||||||
* exception is not checked (THROWN is not set then).
|
|
||||||
*/
|
|
||||||
if (!skip && (cstack->cs_flags[idx] & CSF_THROWN)
|
if (!skip && (cstack->cs_flags[idx] & CSF_THROWN)
|
||||||
&& !(cstack->cs_flags[idx] & CSF_CAUGHT)) {
|
&& !(cstack->cs_flags[idx] & CSF_CAUGHT)) {
|
||||||
if (end != NULL && *end != NUL && !ends_excmd(*skipwhite(end + 1))) {
|
if (end != NULL && *end != NUL && !ends_excmd(*skipwhite(end + 1))) {
|
||||||
@@ -1422,16 +1378,14 @@ void ex_catch(exarg_T *eap)
|
|||||||
internal_error("ex_catch()");
|
internal_error("ex_catch()");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
// If there is a preceding catch clause and it caught the exception,
|
||||||
* If there is a preceding catch clause and it caught the exception,
|
// finish the exception now. This happens also after errors except
|
||||||
* finish the exception now. This happens also after errors except
|
// when this ":catch" was after the ":finally" or not within
|
||||||
* when this ":catch" was after the ":finally" or not within
|
// a ":try". Make the try conditional inactive so that the
|
||||||
* a ":try". Make the try conditional inactive so that the
|
// following catch clauses are skipped. On an error or interrupt
|
||||||
* following catch clauses are skipped. On an error or interrupt
|
// after the preceding try block or catch clause was left by
|
||||||
* after the preceding try block or catch clause was left by
|
// a ":continue", ":break", ":return", or ":finish", discard the
|
||||||
* a ":continue", ":break", ":return", or ":finish", discard the
|
// pending action.
|
||||||
* pending action.
|
|
||||||
*/
|
|
||||||
cleanup_conditionals(cstack, CSF_TRY, true);
|
cleanup_conditionals(cstack, CSF_TRY, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1495,14 +1449,12 @@ void ex_finally(exarg_T *eap)
|
|||||||
(void)do_intthrow(cstack);
|
(void)do_intthrow(cstack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If there is a preceding catch clause and it caught the exception,
|
||||||
* If there is a preceding catch clause and it caught the exception,
|
// finish the exception now. This happens also after errors except
|
||||||
* finish the exception now. This happens also after errors except
|
// when this is a multiple ":finally" or one not within a ":try".
|
||||||
* when this is a multiple ":finally" or one not within a ":try".
|
// After an error or interrupt, this also discards a pending
|
||||||
* After an error or interrupt, this also discards a pending
|
// ":continue", ":break", ":finish", or ":return" from the preceding
|
||||||
* ":continue", ":break", ":finish", or ":return" from the preceding
|
// try block or catch clause.
|
||||||
* try block or catch clause.
|
|
||||||
*/
|
|
||||||
cleanup_conditionals(cstack, CSF_TRY, false);
|
cleanup_conditionals(cstack, CSF_TRY, false);
|
||||||
|
|
||||||
// Make did_emsg, got_int, did_throw pending. If set, they overrule
|
// Make did_emsg, got_int, did_throw pending. If set, they overrule
|
||||||
@@ -1606,12 +1558,10 @@ void ex_endtry(exarg_T *eap)
|
|||||||
} else {
|
} else {
|
||||||
idx = cstack->cs_idx;
|
idx = cstack->cs_idx;
|
||||||
|
|
||||||
/*
|
// If we stopped with the exception currently being thrown at this
|
||||||
* If we stopped with the exception currently being thrown at this
|
// try conditional since we didn't know that it doesn't have
|
||||||
* try conditional since we didn't know that it doesn't have
|
// a finally clause, we need to rethrow it after closing the try
|
||||||
* a finally clause, we need to rethrow it after closing the try
|
// conditional.
|
||||||
* conditional.
|
|
||||||
*/
|
|
||||||
if (did_throw
|
if (did_throw
|
||||||
&& (cstack->cs_flags[idx] & CSF_TRUE)
|
&& (cstack->cs_flags[idx] & CSF_TRUE)
|
||||||
&& !(cstack->cs_flags[idx] & CSF_FINALLY)) {
|
&& !(cstack->cs_flags[idx] & CSF_FINALLY)) {
|
||||||
@@ -1645,12 +1595,10 @@ void ex_endtry(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If a ":return" is pending, we need to resume it after closing the
|
||||||
* If a ":return" is pending, we need to resume it after closing the
|
// try conditional; remember the return value. If there was a finally
|
||||||
* try conditional; remember the return value. If there was a finally
|
// clause making an exception pending, we need to rethrow it. Make it
|
||||||
* clause making an exception pending, we need to rethrow it. Make it
|
// the exception currently being thrown.
|
||||||
* the exception currently being thrown.
|
|
||||||
*/
|
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
pending = cstack->cs_pending[idx];
|
pending = cstack->cs_pending[idx];
|
||||||
cstack->cs_pending[idx] = CSTP_NONE;
|
cstack->cs_pending[idx] = CSTP_NONE;
|
||||||
@@ -1661,16 +1609,14 @@ void ex_endtry(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Discard anything pending on an error, interrupt, or throw in the
|
||||||
* Discard anything pending on an error, interrupt, or throw in the
|
// finally clause. If there was no ":finally", discard a pending
|
||||||
* finally clause. If there was no ":finally", discard a pending
|
// ":continue", ":break", ":return", or ":finish" if an error or
|
||||||
* ":continue", ":break", ":return", or ":finish" if an error or
|
// interrupt occurred afterwards, but before the ":endtry" was reached.
|
||||||
* interrupt occurred afterwards, but before the ":endtry" was reached.
|
// If an exception was caught by the last of the catch clauses and there
|
||||||
* If an exception was caught by the last of the catch clauses and there
|
// was no finally clause, finish the exception now. This happens also
|
||||||
* was no finally clause, finish the exception now. This happens also
|
// after errors except when this ":endtry" is not within a ":try".
|
||||||
* after errors except when this ":endtry" is not within a ":try".
|
// Restore "emsg_silent" if it has been reset by this try conditional.
|
||||||
* Restore "emsg_silent" if it has been reset by this try conditional.
|
|
||||||
*/
|
|
||||||
(void)cleanup_conditionals(cstack, CSF_TRY | CSF_SILENT, true);
|
(void)cleanup_conditionals(cstack, CSF_TRY | CSF_SILENT, true);
|
||||||
|
|
||||||
if (cstack->cs_idx >= 0 && (cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
|
if (cstack->cs_idx >= 0 && (cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
|
||||||
@@ -1733,18 +1679,16 @@ void ex_endtry(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// enter_cleanup() and leave_cleanup()
|
||||||
* enter_cleanup() and leave_cleanup()
|
//
|
||||||
*
|
// Functions to be called before/after invoking a sequence of autocommands for
|
||||||
* Functions to be called before/after invoking a sequence of autocommands for
|
// cleanup for a failed command. (Failure means here that a call to emsg()
|
||||||
* cleanup for a failed command. (Failure means here that a call to emsg()
|
// has been made, an interrupt occurred, or there is an uncaught exception
|
||||||
* has been made, an interrupt occurred, or there is an uncaught exception
|
// from a previous autocommand execution of the same command.)
|
||||||
* from a previous autocommand execution of the same command.)
|
//
|
||||||
*
|
// Call enter_cleanup() with a pointer to a cleanup_T and pass the same
|
||||||
* Call enter_cleanup() with a pointer to a cleanup_T and pass the same
|
// pointer to leave_cleanup(). The cleanup_T structure stores the pending
|
||||||
* pointer to leave_cleanup(). The cleanup_T structure stores the pending
|
// error/interrupt/exception state.
|
||||||
* error/interrupt/exception state.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// This function works a bit like ex_finally() except that there was not
|
/// This function works a bit like ex_finally() except that there was not
|
||||||
/// actually an extra try block around the part that failed and an error or
|
/// actually an extra try block around the part that failed and an error or
|
||||||
@@ -1829,18 +1773,14 @@ void leave_cleanup(cleanup_T *csp)
|
|||||||
if (msg_list != NULL) {
|
if (msg_list != NULL) {
|
||||||
free_global_msglist();
|
free_global_msglist();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
/*
|
// If there was no new error, interrupt, or throw between the calls
|
||||||
* If there was no new error, interrupt, or throw between the calls
|
// to enter_cleanup() and leave_cleanup(), restore the pending
|
||||||
* to enter_cleanup() and leave_cleanup(), restore the pending
|
// error/interrupt/exception state.
|
||||||
* error/interrupt/exception state.
|
|
||||||
*/
|
// If there was an exception being thrown when enter_cleanup() was
|
||||||
else {
|
// called, we need to rethrow it. Make it the exception currently
|
||||||
/*
|
// being thrown.
|
||||||
* If there was an exception being thrown when enter_cleanup() was
|
|
||||||
* called, we need to rethrow it. Make it the exception currently
|
|
||||||
* being thrown.
|
|
||||||
*/
|
|
||||||
if (pending & CSTP_THROW) {
|
if (pending & CSTP_THROW) {
|
||||||
current_exception = csp->exception;
|
current_exception = csp->exception;
|
||||||
} else if (pending & CSTP_ERROR) {
|
} else if (pending & CSTP_ERROR) {
|
||||||
@@ -1893,12 +1833,10 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
|
|||||||
|
|
||||||
for (idx = cstack->cs_idx; idx >= 0; idx--) {
|
for (idx = cstack->cs_idx; idx >= 0; idx--) {
|
||||||
if (cstack->cs_flags[idx] & CSF_TRY) {
|
if (cstack->cs_flags[idx] & CSF_TRY) {
|
||||||
/*
|
// Discard anything pending in a finally clause and continue the
|
||||||
* Discard anything pending in a finally clause and continue the
|
// search. There may also be a pending ":continue", ":break",
|
||||||
* search. There may also be a pending ":continue", ":break",
|
// ":return", or ":finish" before the finally clause. We must not
|
||||||
* ":return", or ":finish" before the finally clause. We must not
|
// discard it, unless an error or interrupt occurred afterwards.
|
||||||
* discard it, unless an error or interrupt occurred afterwards.
|
|
||||||
*/
|
|
||||||
if (did_emsg || got_int || (cstack->cs_flags[idx] & CSF_FINALLY)) {
|
if (did_emsg || got_int || (cstack->cs_flags[idx] & CSF_FINALLY)) {
|
||||||
switch (cstack->cs_pending[idx]) {
|
switch (cstack->cs_pending[idx]) {
|
||||||
case CSTP_NONE:
|
case CSTP_NONE:
|
||||||
@@ -1934,11 +1872,9 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Stop at a try conditional not in its finally clause. If this try
|
||||||
* Stop at a try conditional not in its finally clause. If this try
|
// conditional is in an active catch clause, finish the caught
|
||||||
* conditional is in an active catch clause, finish the caught
|
// exception.
|
||||||
* exception.
|
|
||||||
*/
|
|
||||||
if (!(cstack->cs_flags[idx] & CSF_FINALLY)) {
|
if (!(cstack->cs_flags[idx] & CSF_FINALLY)) {
|
||||||
if ((cstack->cs_flags[idx] & CSF_ACTIVE)
|
if ((cstack->cs_flags[idx] & CSF_ACTIVE)
|
||||||
&& (cstack->cs_flags[idx] & CSF_CAUGHT) && !(cstack->cs_flags[idx] & CSF_FINISHED)) {
|
&& (cstack->cs_flags[idx] & CSF_CAUGHT) && !(cstack->cs_flags[idx] & CSF_FINISHED)) {
|
||||||
@@ -1973,11 +1909,9 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When leaving a try conditional that reset "emsg_silent" on its
|
||||||
* When leaving a try conditional that reset "emsg_silent" on its
|
// entry after saving the original value, restore that value here and
|
||||||
* entry after saving the original value, restore that value here and
|
// free the memory used to store it.
|
||||||
* free the memory used to store it.
|
|
||||||
*/
|
|
||||||
if ((cstack->cs_flags[idx] & CSF_TRY)
|
if ((cstack->cs_flags[idx] & CSF_TRY)
|
||||||
&& (cstack->cs_flags[idx] & CSF_SILENT)) {
|
&& (cstack->cs_flags[idx] & CSF_SILENT)) {
|
||||||
eslist_T *elem;
|
eslist_T *elem;
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
/*
|
// ex_getln.c: Functions for entering and editing an Ex command line.
|
||||||
* ex_getln.c: Functions for entering and editing an Ex command line.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -2603,10 +2601,8 @@ bool text_locked(void)
|
|||||||
return textlock != 0;
|
return textlock != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Give an error message for a command that isn't allowed while the cmdline
|
||||||
* Give an error message for a command that isn't allowed while the cmdline
|
// window is open or editing the cmdline in another way.
|
||||||
* window is open or editing the cmdline in another way.
|
|
||||||
*/
|
|
||||||
void text_locked_msg(void)
|
void text_locked_msg(void)
|
||||||
{
|
{
|
||||||
emsg(_(get_text_locked_msg()));
|
emsg(_(get_text_locked_msg()));
|
||||||
@@ -2738,15 +2734,11 @@ bool cmdline_at_end(void)
|
|||||||
return (ccline.cmdpos >= ccline.cmdlen);
|
return (ccline.cmdpos >= ccline.cmdlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Allocate a new command line buffer.
|
||||||
* Allocate a new command line buffer.
|
// Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
|
||||||
* Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
|
|
||||||
*/
|
|
||||||
static void alloc_cmdbuff(int len)
|
static void alloc_cmdbuff(int len)
|
||||||
{
|
{
|
||||||
/*
|
// give some extra space to avoid having to allocate all the time
|
||||||
* give some extra space to avoid having to allocate all the time
|
|
||||||
*/
|
|
||||||
if (len < 80) {
|
if (len < 80) {
|
||||||
len = 100;
|
len = 100;
|
||||||
} else {
|
} else {
|
||||||
@@ -3088,10 +3080,8 @@ color_cmdline_error:
|
|||||||
#undef PRINT_ERRMSG
|
#undef PRINT_ERRMSG
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Draw part of the cmdline at the current cursor position. But draw stars
|
||||||
* Draw part of the cmdline at the current cursor position. But draw stars
|
// when cmdline_star is true.
|
||||||
* when cmdline_star is true.
|
|
||||||
*/
|
|
||||||
static void draw_cmdline(int start, int len)
|
static void draw_cmdline(int start, int len)
|
||||||
{
|
{
|
||||||
if (!color_cmdline(&ccline)) {
|
if (!color_cmdline(&ccline)) {
|
||||||
@@ -3342,11 +3332,9 @@ void cmdline_ui_flush(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Put a character on the command line. Shifts the following text to the
|
||||||
* Put a character on the command line. Shifts the following text to the
|
// right when "shift" is true. Used for CTRL-V, CTRL-K, etc.
|
||||||
* right when "shift" is true. Used for CTRL-V, CTRL-K, etc.
|
// "c" must be printable (fit in one display cell)!
|
||||||
* "c" must be printable (fit in one display cell)!
|
|
||||||
*/
|
|
||||||
void putcmdline(char c, int shift)
|
void putcmdline(char c, int shift)
|
||||||
{
|
{
|
||||||
if (cmd_silent) {
|
if (cmd_silent) {
|
||||||
@@ -3388,14 +3376,12 @@ void unputcmdline(void)
|
|||||||
ui_cursor_shape();
|
ui_cursor_shape();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Put the given string, of the given length, onto the command line.
|
||||||
* Put the given string, of the given length, onto the command line.
|
// If len is -1, then STRLEN() is used to calculate the length.
|
||||||
* If len is -1, then STRLEN() is used to calculate the length.
|
// If 'redraw' is true then the new part of the command line, and the remaining
|
||||||
* If 'redraw' is true then the new part of the command line, and the remaining
|
// part will be redrawn, otherwise it will not. If this function is called
|
||||||
* part will be redrawn, otherwise it will not. If this function is called
|
// twice in a row, then 'redraw' should be false and redrawcmd() should be
|
||||||
* twice in a row, then 'redraw' should be false and redrawcmd() should be
|
// called afterwards.
|
||||||
* called afterwards.
|
|
||||||
*/
|
|
||||||
void put_on_cmdline(char_u *str, int len, int redraw)
|
void put_on_cmdline(char_u *str, int len, int redraw)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -3603,12 +3589,10 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
|
|||||||
return cmdline_paste_reg(regname, literally, remcr);
|
return cmdline_paste_reg(regname, literally, remcr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Put a string on the command line.
|
||||||
* Put a string on the command line.
|
// When "literally" is true, insert literally.
|
||||||
* When "literally" is true, insert literally.
|
// When "literally" is false, insert as typed, but don't leave the command
|
||||||
* When "literally" is false, insert as typed, but don't leave the command
|
// line.
|
||||||
* line.
|
|
||||||
*/
|
|
||||||
void cmdline_paste_str(char_u *s, int literally)
|
void cmdline_paste_str(char_u *s, int literally)
|
||||||
{
|
{
|
||||||
int c, cv;
|
int c, cv;
|
||||||
@@ -3675,9 +3659,7 @@ static void redrawcmdprompt(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Redraw what is currently on the command line.
|
||||||
* Redraw what is currently on the command line.
|
|
||||||
*/
|
|
||||||
void redrawcmd(void)
|
void redrawcmd(void)
|
||||||
{
|
{
|
||||||
if (cmd_silent) {
|
if (cmd_silent) {
|
||||||
@@ -3714,10 +3696,8 @@ void redrawcmd(void)
|
|||||||
putcmdline(ccline.special_char, ccline.special_shift);
|
putcmdline(ccline.special_char, ccline.special_shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// An emsg() before may have set msg_scroll. This is used in normal mode,
|
||||||
* An emsg() before may have set msg_scroll. This is used in normal mode,
|
// in cmdline mode we can reset them now.
|
||||||
* in cmdline mode we can reset them now.
|
|
||||||
*/
|
|
||||||
msg_scroll = false; // next message overwrites cmdline
|
msg_scroll = false; // next message overwrites cmdline
|
||||||
|
|
||||||
// Typing ':' at the more prompt may set skip_redraw. We don't want this
|
// Typing ':' at the more prompt may set skip_redraw. We don't want this
|
||||||
@@ -3794,12 +3774,10 @@ void gotocmdline(bool clr)
|
|||||||
cmd_cursor_goto(cmdline_row, 0);
|
cmd_cursor_goto(cmdline_row, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check the word in front of the cursor for an abbreviation.
|
||||||
* Check the word in front of the cursor for an abbreviation.
|
// Called when the non-id character "c" has been entered.
|
||||||
* Called when the non-id character "c" has been entered.
|
// When an abbreviation is recognized it is removed from the text with
|
||||||
* When an abbreviation is recognized it is removed from the text with
|
// backspaces and the replacement string is inserted, followed by "c".
|
||||||
* backspaces and the replacement string is inserted, followed by "c".
|
|
||||||
*/
|
|
||||||
static int ccheck_abbr(int c)
|
static int ccheck_abbr(int c)
|
||||||
{
|
{
|
||||||
int spos = 0;
|
int spos = 0;
|
||||||
@@ -4310,9 +4288,7 @@ static int open_cmdwin(void)
|
|||||||
RedrawingDisabled = 0;
|
RedrawingDisabled = 0;
|
||||||
int save_count = save_batch_count();
|
int save_count = save_batch_count();
|
||||||
|
|
||||||
/*
|
// Call the main loop until <CR> or CTRL-C is typed.
|
||||||
* Call the main loop until <CR> or CTRL-C is typed.
|
|
||||||
*/
|
|
||||||
normal_enter(true, false);
|
normal_enter(true, false);
|
||||||
|
|
||||||
RedrawingDisabled = i;
|
RedrawingDisabled = i;
|
||||||
|
@@ -71,9 +71,7 @@
|
|||||||
|
|
||||||
static char_u *ff_expand_buffer = NULL; // used for expanding filenames
|
static char_u *ff_expand_buffer = NULL; // used for expanding filenames
|
||||||
|
|
||||||
/*
|
// type for the directory search stack
|
||||||
* type for the directory search stack
|
|
||||||
*/
|
|
||||||
typedef struct ff_stack {
|
typedef struct ff_stack {
|
||||||
struct ff_stack *ffs_prev;
|
struct ff_stack *ffs_prev;
|
||||||
|
|
||||||
@@ -104,9 +102,7 @@ typedef struct ff_stack {
|
|||||||
int ffs_star_star_empty;
|
int ffs_star_star_empty;
|
||||||
} ff_stack_T;
|
} ff_stack_T;
|
||||||
|
|
||||||
/*
|
// type for already visited directories or files.
|
||||||
* type for already visited directories or files.
|
|
||||||
*/
|
|
||||||
typedef struct ff_visited {
|
typedef struct ff_visited {
|
||||||
struct ff_visited *ffv_next;
|
struct ff_visited *ffv_next;
|
||||||
|
|
||||||
@@ -122,20 +118,18 @@ typedef struct ff_visited {
|
|||||||
char_u ffv_fname[1]; // actually longer
|
char_u ffv_fname[1]; // actually longer
|
||||||
} ff_visited_T;
|
} ff_visited_T;
|
||||||
|
|
||||||
/*
|
// We might have to manage several visited lists during a search.
|
||||||
* We might have to manage several visited lists during a search.
|
// This is especially needed for the tags option. If tags is set to:
|
||||||
* This is especially needed for the tags option. If tags is set to:
|
// "./++/tags,./++/TAGS,++/tags" (replace + with *)
|
||||||
* "./++/tags,./++/TAGS,++/tags" (replace + with *)
|
// So we have to do 3 searches:
|
||||||
* So we have to do 3 searches:
|
// 1) search from the current files directory downward for the file "tags"
|
||||||
* 1) search from the current files directory downward for the file "tags"
|
// 2) search from the current files directory downward for the file "TAGS"
|
||||||
* 2) search from the current files directory downward for the file "TAGS"
|
// 3) search from Vims current directory downwards for the file "tags"
|
||||||
* 3) search from Vims current directory downwards for the file "tags"
|
// As you can see, the first and the third search are for the same file, so for
|
||||||
* As you can see, the first and the third search are for the same file, so for
|
// the third search we can use the visited list of the first search. For the
|
||||||
* the third search we can use the visited list of the first search. For the
|
// second search we must start from an empty visited list.
|
||||||
* second search we must start from an empty visited list.
|
// The struct ff_visited_list_hdr is used to manage a linked list of already
|
||||||
* The struct ff_visited_list_hdr is used to manage a linked list of already
|
// visited lists.
|
||||||
* visited lists.
|
|
||||||
*/
|
|
||||||
typedef struct ff_visited_list_hdr {
|
typedef struct ff_visited_list_hdr {
|
||||||
struct ff_visited_list_hdr *ffvl_next;
|
struct ff_visited_list_hdr *ffvl_next;
|
||||||
|
|
||||||
@@ -145,29 +139,25 @@ typedef struct ff_visited_list_hdr {
|
|||||||
ff_visited_T *ffvl_visited_list;
|
ff_visited_T *ffvl_visited_list;
|
||||||
} ff_visited_list_hdr_T;
|
} ff_visited_list_hdr_T;
|
||||||
|
|
||||||
/*
|
// '**' can be expanded to several directory levels.
|
||||||
* '**' can be expanded to several directory levels.
|
// Set the default maximum depth.
|
||||||
* Set the default maximum depth.
|
|
||||||
*/
|
|
||||||
#define FF_MAX_STAR_STAR_EXPAND ((char_u)30)
|
#define FF_MAX_STAR_STAR_EXPAND ((char_u)30)
|
||||||
|
|
||||||
/*
|
// The search context:
|
||||||
* The search context:
|
// ffsc_stack_ptr: the stack for the dirs to search
|
||||||
* ffsc_stack_ptr: the stack for the dirs to search
|
// ffsc_visited_list: the currently active visited list
|
||||||
* ffsc_visited_list: the currently active visited list
|
// ffsc_dir_visited_list: the currently active visited list for search dirs
|
||||||
* ffsc_dir_visited_list: the currently active visited list for search dirs
|
// ffsc_visited_lists_list: the list of all visited lists
|
||||||
* ffsc_visited_lists_list: the list of all visited lists
|
// ffsc_dir_visited_lists_list: the list of all visited lists for search dirs
|
||||||
* ffsc_dir_visited_lists_list: the list of all visited lists for search dirs
|
// ffsc_file_to_search: the file to search for
|
||||||
* ffsc_file_to_search: the file to search for
|
// ffsc_start_dir: the starting directory, if search path was relative
|
||||||
* ffsc_start_dir: the starting directory, if search path was relative
|
// ffsc_fix_path: the fix part of the given path (without wildcards)
|
||||||
* ffsc_fix_path: the fix part of the given path (without wildcards)
|
// Needed for upward search.
|
||||||
* Needed for upward search.
|
// ffsc_wc_path: the part of the given path containing wildcards
|
||||||
* ffsc_wc_path: the part of the given path containing wildcards
|
// ffsc_level: how many levels of dirs to search downwards
|
||||||
* ffsc_level: how many levels of dirs to search downwards
|
// ffsc_stopdirs_v: array of stop directories for upward search
|
||||||
* ffsc_stopdirs_v: array of stop directories for upward search
|
// ffsc_find_what: FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE
|
||||||
* ffsc_find_what: FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE
|
// ffsc_tagfile: searching for tags file, don't use 'suffixesadd'
|
||||||
* ffsc_tagfile: searching for tags file, don't use 'suffixesadd'
|
|
||||||
*/
|
|
||||||
typedef struct ff_search_ctx_T {
|
typedef struct ff_search_ctx_T {
|
||||||
ff_stack_T *ffsc_stack_ptr;
|
ff_stack_T *ffsc_stack_ptr;
|
||||||
ff_visited_list_hdr_T *ffsc_visited_list;
|
ff_visited_list_hdr_T *ffsc_visited_list;
|
||||||
@@ -341,15 +331,13 @@ void *vim_findfile_init(char *path, char *filename, char *stopdirs, int level, i
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If stopdirs are given, split them into an array of pointers.
|
||||||
* If stopdirs are given, split them into an array of pointers.
|
// If this fails (mem allocation), there is no upward search at all or a
|
||||||
* If this fails (mem allocation), there is no upward search at all or a
|
// stop directory is not recognized -> continue silently.
|
||||||
* stop directory is not recognized -> continue silently.
|
// If stopdirs just contains a ";" or is empty,
|
||||||
* If stopdirs just contains a ";" or is empty,
|
// search_ctx->ffsc_stopdirs_v will only contain a NULL pointer. This
|
||||||
* search_ctx->ffsc_stopdirs_v will only contain a NULL pointer. This
|
// is handled as unlimited upward search. See function
|
||||||
* is handled as unlimited upward search. See function
|
// ff_path_in_stoplist() for details.
|
||||||
* ff_path_in_stoplist() for details.
|
|
||||||
*/
|
|
||||||
if (stopdirs != NULL) {
|
if (stopdirs != NULL) {
|
||||||
char *walker = stopdirs;
|
char *walker = stopdirs;
|
||||||
|
|
||||||
@@ -401,15 +389,13 @@ void *vim_findfile_init(char *path, char *filename, char *stopdirs, int level, i
|
|||||||
assert(wc_part - path >= 0);
|
assert(wc_part - path >= 0);
|
||||||
search_ctx->ffsc_fix_path = xstrnsave(path, (size_t)(wc_part - path));
|
search_ctx->ffsc_fix_path = xstrnsave(path, (size_t)(wc_part - path));
|
||||||
|
|
||||||
/*
|
// copy wc_path and add restricts to the '**' wildcard.
|
||||||
* copy wc_path and add restricts to the '**' wildcard.
|
// The octet after a '**' is used as a (binary) counter.
|
||||||
* The octet after a '**' is used as a (binary) counter.
|
// So '**3' is transposed to '**^C' ('^C' is ASCII value 3)
|
||||||
* So '**3' is transposed to '**^C' ('^C' is ASCII value 3)
|
// or '**76' is transposed to '**N'( 'N' is ASCII value 76).
|
||||||
* or '**76' is transposed to '**N'( 'N' is ASCII value 76).
|
// If no restrict is given after '**' the default is used.
|
||||||
* If no restrict is given after '**' the default is used.
|
// Due to this technique the path looks awful if you print it as a
|
||||||
* Due to this technique the path looks awful if you print it as a
|
// string.
|
||||||
* string.
|
|
||||||
*/
|
|
||||||
len = 0;
|
len = 0;
|
||||||
while (*wc_part != NUL) {
|
while (*wc_part != NUL) {
|
||||||
if (len + 5 >= MAXPATHL) {
|
if (len + 5 >= MAXPATHL) {
|
||||||
@@ -513,11 +499,9 @@ void *vim_findfile_init(char *path, char *filename, char *stopdirs, int level, i
|
|||||||
return search_ctx;
|
return search_ctx;
|
||||||
|
|
||||||
error_return:
|
error_return:
|
||||||
/*
|
// We clear the search context now!
|
||||||
* We clear the search context now!
|
// Even when the caller gave us a (perhaps valid) context we free it here,
|
||||||
* Even when the caller gave us a (perhaps valid) context we free it here,
|
// as we might have already destroyed it.
|
||||||
* as we might have already destroyed it.
|
|
||||||
*/
|
|
||||||
vim_findfile_cleanup(search_ctx);
|
vim_findfile_cleanup(search_ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -587,10 +571,8 @@ char_u *vim_findfile(void *search_ctx_arg)
|
|||||||
|
|
||||||
search_ctx = (ff_search_ctx_T *)search_ctx_arg;
|
search_ctx = (ff_search_ctx_T *)search_ctx_arg;
|
||||||
|
|
||||||
/*
|
// filepath is used as buffer for various actions and as the storage to
|
||||||
* filepath is used as buffer for various actions and as the storage to
|
// return a found filename.
|
||||||
* return a found filename.
|
|
||||||
*/
|
|
||||||
file_path = xmalloc(MAXPATHL);
|
file_path = xmalloc(MAXPATHL);
|
||||||
|
|
||||||
// store the end of the start dir -- needed for upward search
|
// store the end of the start dir -- needed for upward search
|
||||||
@@ -614,25 +596,23 @@ char_u *vim_findfile(void *search_ctx_arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// TODO(vim): decide if we leave this test in
|
||||||
* TODO: decide if we leave this test in
|
//
|
||||||
*
|
// GOOD: don't search a directory(-tree) twice.
|
||||||
* GOOD: don't search a directory(-tree) twice.
|
// BAD: - check linked list for every new directory entered.
|
||||||
* BAD: - check linked list for every new directory entered.
|
// - check for double files also done below
|
||||||
* - check for double files also done below
|
//
|
||||||
*
|
// Here we check if we already searched this directory.
|
||||||
* Here we check if we already searched this directory.
|
// We already searched a directory if:
|
||||||
* We already searched a directory if:
|
// 1) The directory is the same.
|
||||||
* 1) The directory is the same.
|
// 2) We would use the same wildcard string.
|
||||||
* 2) We would use the same wildcard string.
|
//
|
||||||
*
|
// Good if you have links on same directory via several ways
|
||||||
* Good if you have links on same directory via several ways
|
// or you have selfreferences in directories (e.g. SuSE Linux 6.3:
|
||||||
* or you have selfreferences in directories (e.g. SuSE Linux 6.3:
|
// /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
|
||||||
* /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
|
//
|
||||||
*
|
// This check is only needed for directories we work on for the
|
||||||
* This check is only needed for directories we work on for the
|
// first time (hence stackp->ff_filearray == NULL)
|
||||||
* first time (hence stackp->ff_filearray == NULL)
|
|
||||||
*/
|
|
||||||
if (stackp->ffs_filearray == NULL
|
if (stackp->ffs_filearray == NULL
|
||||||
&& ff_check_visited(&search_ctx->ffsc_dir_visited_list->ffvl_visited_list,
|
&& ff_check_visited(&search_ctx->ffsc_dir_visited_list->ffvl_visited_list,
|
||||||
stackp->ffs_fix_path, stackp->ffs_wc_path) == FAIL) {
|
stackp->ffs_fix_path, stackp->ffs_wc_path) == FAIL) {
|
||||||
@@ -666,12 +646,10 @@ char_u *vim_findfile(void *search_ctx_arg)
|
|||||||
|
|
||||||
file_path[0] = NUL;
|
file_path[0] = NUL;
|
||||||
|
|
||||||
/*
|
// If no filearray till now expand wildcards
|
||||||
* If no filearray till now expand wildcards
|
// The function expand_wildcards() can handle an array of paths
|
||||||
* The function expand_wildcards() can handle an array of paths
|
// and all possible expands are returned in one array. We use this
|
||||||
* and all possible expands are returned in one array. We use this
|
// to handle the expansion of '**' into an empty string.
|
||||||
* to handle the expansion of '**' into an empty string.
|
|
||||||
*/
|
|
||||||
if (stackp->ffs_filearray == NULL) {
|
if (stackp->ffs_filearray == NULL) {
|
||||||
char *dirptrs[2];
|
char *dirptrs[2];
|
||||||
|
|
||||||
@@ -737,13 +715,11 @@ char_u *vim_findfile(void *search_ctx_arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Here we copy until the next path separator or the end of
|
||||||
* Here we copy until the next path separator or the end of
|
// the path. If we stop at a path separator, there is
|
||||||
* the path. If we stop at a path separator, there is
|
// still something else left. This is handled below by
|
||||||
* still something else left. This is handled below by
|
// pushing every directory returned from expand_wildcards()
|
||||||
* pushing every directory returned from expand_wildcards()
|
// on the stack again for further search.
|
||||||
* on the stack again for further search.
|
|
||||||
*/
|
|
||||||
while (*rest_of_wildcards
|
while (*rest_of_wildcards
|
||||||
&& !vim_ispathsep(*rest_of_wildcards)) {
|
&& !vim_ispathsep(*rest_of_wildcards)) {
|
||||||
if (len + 1 >= MAXPATHL) {
|
if (len + 1 >= MAXPATHL) {
|
||||||
@@ -759,10 +735,8 @@ char_u *vim_findfile(void *search_ctx_arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Expand wildcards like "*" and "$VAR".
|
||||||
* Expand wildcards like "*" and "$VAR".
|
// If the path is a URL don't try this.
|
||||||
* If the path is a URL don't try this.
|
|
||||||
*/
|
|
||||||
if (path_with_url(dirptrs[0])) {
|
if (path_with_url(dirptrs[0])) {
|
||||||
stackp->ffs_filearray = xmalloc(sizeof(char *));
|
stackp->ffs_filearray = xmalloc(sizeof(char *));
|
||||||
stackp->ffs_filearray[0] = xstrdup(dirptrs[0]);
|
stackp->ffs_filearray[0] = xstrdup(dirptrs[0]);
|
||||||
@@ -786,10 +760,8 @@ char_u *vim_findfile(void *search_ctx_arg)
|
|||||||
if (stackp->ffs_stage == 0) {
|
if (stackp->ffs_stage == 0) {
|
||||||
// this is the first time we work on this directory
|
// this is the first time we work on this directory
|
||||||
if (*rest_of_wildcards == NUL) {
|
if (*rest_of_wildcards == NUL) {
|
||||||
/*
|
// We don't have further wildcards to expand, so we have to
|
||||||
* We don't have further wildcards to expand, so we have to
|
// check for the final file now.
|
||||||
* check for the final file now.
|
|
||||||
*/
|
|
||||||
for (int i = stackp->ffs_filearray_cur; i < stackp->ffs_filearray_size; i++) {
|
for (int i = stackp->ffs_filearray_cur; i < stackp->ffs_filearray_size; i++) {
|
||||||
if (!path_with_url(stackp->ffs_filearray[i])
|
if (!path_with_url(stackp->ffs_filearray[i])
|
||||||
&& !os_isdir(stackp->ffs_filearray[i])) {
|
&& !os_isdir(stackp->ffs_filearray[i])) {
|
||||||
@@ -808,10 +780,8 @@ char_u *vim_findfile(void *search_ctx_arg)
|
|||||||
}
|
}
|
||||||
STRCAT(file_path, search_ctx->ffsc_file_to_search);
|
STRCAT(file_path, search_ctx->ffsc_file_to_search);
|
||||||
|
|
||||||
/*
|
// Try without extra suffix and then with suffixes
|
||||||
* Try without extra suffix and then with suffixes
|
// from 'suffixesadd'.
|
||||||
* from 'suffixesadd'.
|
|
||||||
*/
|
|
||||||
len = STRLEN(file_path);
|
len = STRLEN(file_path);
|
||||||
if (search_ctx->ffsc_tagfile) {
|
if (search_ctx->ffsc_tagfile) {
|
||||||
suf = "";
|
suf = "";
|
||||||
@@ -894,10 +864,8 @@ char_u *vim_findfile(void *search_ctx_arg)
|
|||||||
stackp->ffs_stage = 1;
|
stackp->ffs_stage = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// if wildcards contains '**' we have to descent till we reach the
|
||||||
* if wildcards contains '**' we have to descent till we reach the
|
// leaves of the directory tree.
|
||||||
* leaves of the directory tree.
|
|
||||||
*/
|
|
||||||
if (STRNCMP(stackp->ffs_wc_path, "**", 2) == 0) {
|
if (STRNCMP(stackp->ffs_wc_path, "**", 2) == 0) {
|
||||||
for (int i = stackp->ffs_filearray_cur;
|
for (int i = stackp->ffs_filearray_cur;
|
||||||
i < stackp->ffs_filearray_size; i++) {
|
i < stackp->ffs_filearray_size; i++) {
|
||||||
@@ -1048,9 +1016,7 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
// if we reach this we didn't find a list and we have to allocate new list
|
||||||
* if we reach this we didn't find a list and we have to allocate new list
|
|
||||||
*/
|
|
||||||
retptr = xmalloc(sizeof(*retptr));
|
retptr = xmalloc(sizeof(*retptr));
|
||||||
|
|
||||||
retptr->ffvl_visited_list = NULL;
|
retptr->ffvl_visited_list = NULL;
|
||||||
@@ -1136,9 +1102,7 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// New file/dir. Add it to the list of visited files/dirs.
|
||||||
* New file/dir. Add it to the list of visited files/dirs.
|
|
||||||
*/
|
|
||||||
vp = xmalloc(sizeof(ff_visited_T) + STRLEN(ff_expand_buffer));
|
vp = xmalloc(sizeof(ff_visited_T) + STRLEN(ff_expand_buffer));
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
@@ -1434,11 +1398,9 @@ char_u *find_file_in_path_option(char_u *ptr, size_t len, int options, int first
|
|||||||
|| (ff_file_to_find[0] != NUL && ff_file_to_find[1] == ':')
|
|| (ff_file_to_find[0] != NUL && ff_file_to_find[1] == ':')
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
/*
|
// Absolute path, no need to use "path_option".
|
||||||
* Absolute path, no need to use "path_option".
|
// If this is not a first call, return NULL. We already returned a
|
||||||
* If this is not a first call, return NULL. We already returned a
|
// filename on the first call.
|
||||||
* filename on the first call.
|
|
||||||
*/
|
|
||||||
if (first == true) {
|
if (first == true) {
|
||||||
if (path_with_url((char *)ff_file_to_find)) {
|
if (path_with_url((char *)ff_file_to_find)) {
|
||||||
file_name = vim_strsave(ff_file_to_find);
|
file_name = vim_strsave(ff_file_to_find);
|
||||||
@@ -1483,11 +1445,9 @@ char_u *find_file_in_path_option(char_u *ptr, size_t len, int options, int first
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
// Loop over all paths in the 'path' or 'cdpath' option.
|
||||||
* Loop over all paths in the 'path' or 'cdpath' option.
|
// When "first" is set, first setup to the start of the option.
|
||||||
* When "first" is set, first setup to the start of the option.
|
// Otherwise continue to find the next match.
|
||||||
* Otherwise continue to find the next match.
|
|
||||||
*/
|
|
||||||
if (first == true) {
|
if (first == true) {
|
||||||
// vim_findfile_free_visited can handle a possible NULL pointer
|
// vim_findfile_free_visited can handle a possible NULL pointer
|
||||||
vim_findfile_free_visited(fdip_search_ctx);
|
vim_findfile_free_visited(fdip_search_ctx);
|
||||||
|
@@ -90,9 +90,7 @@
|
|||||||
* with iconv() to be able to allocate a buffer. */
|
* with iconv() to be able to allocate a buffer. */
|
||||||
#define ICONV_MULT 8
|
#define ICONV_MULT 8
|
||||||
|
|
||||||
/*
|
// Structure to pass arguments from buf_write() to buf_write_bytes().
|
||||||
* Structure to pass arguments from buf_write() to buf_write_bytes().
|
|
||||||
*/
|
|
||||||
struct bw_info {
|
struct bw_info {
|
||||||
int bw_fd; // file descriptor
|
int bw_fd; // file descriptor
|
||||||
char_u *bw_buf; // buffer with data to be written
|
char_u *bw_buf; // buffer with data to be written
|
||||||
@@ -257,12 +255,10 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip,
|
|||||||
|
|
||||||
curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read
|
curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read
|
||||||
|
|
||||||
/*
|
// If there is no file name yet, use the one for the read file.
|
||||||
* If there is no file name yet, use the one for the read file.
|
// BF_NOTEDITED is set to reflect this.
|
||||||
* BF_NOTEDITED is set to reflect this.
|
// Don't do this for a read from a filter.
|
||||||
* Don't do this for a read from a filter.
|
// Only do this when 'cpoptions' contains the 'f' flag.
|
||||||
* Only do this when 'cpoptions' contains the 'f' flag.
|
|
||||||
*/
|
|
||||||
if (curbuf->b_ffname == NULL
|
if (curbuf->b_ffname == NULL
|
||||||
&& !filtering
|
&& !filtering
|
||||||
&& fname != NULL
|
&& fname != NULL
|
||||||
@@ -401,12 +397,10 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip,
|
|||||||
// Set default or forced 'fileformat' and 'binary'.
|
// Set default or forced 'fileformat' and 'binary'.
|
||||||
set_file_options(set_options, eap);
|
set_file_options(set_options, eap);
|
||||||
|
|
||||||
/*
|
// When opening a new file we take the readonly flag from the file.
|
||||||
* When opening a new file we take the readonly flag from the file.
|
// Default is r/w, can be set to r/o below.
|
||||||
* Default is r/w, can be set to r/o below.
|
// Don't reset it when in readonly mode
|
||||||
* Don't reset it when in readonly mode
|
// Only set/reset b_p_ro when BF_CHECK_RO is set.
|
||||||
* Only set/reset b_p_ro when BF_CHECK_RO is set.
|
|
||||||
*/
|
|
||||||
check_readonly = (newfile && (curbuf->b_flags & BF_CHECK_RO));
|
check_readonly = (newfile && (curbuf->b_flags & BF_CHECK_RO));
|
||||||
if (check_readonly && !readonlymode) {
|
if (check_readonly && !readonlymode) {
|
||||||
curbuf->b_p_ro = false;
|
curbuf->b_p_ro = false;
|
||||||
@@ -419,17 +413,15 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip,
|
|||||||
curbuf->b_mtime_read = curbuf->b_mtime;
|
curbuf->b_mtime_read = curbuf->b_mtime;
|
||||||
curbuf->b_mtime_read_ns = curbuf->b_mtime_ns;
|
curbuf->b_mtime_read_ns = curbuf->b_mtime_ns;
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
/*
|
// Use the protection bits of the original file for the swap file.
|
||||||
* Use the protection bits of the original file for the swap file.
|
// This makes it possible for others to read the name of the
|
||||||
* This makes it possible for others to read the name of the
|
// edited file from the swapfile, but only if they can read the
|
||||||
* edited file from the swapfile, but only if they can read the
|
// edited file.
|
||||||
* edited file.
|
// Remove the "write" and "execute" bits for group and others
|
||||||
* Remove the "write" and "execute" bits for group and others
|
// (they must not write the swapfile).
|
||||||
* (they must not write the swapfile).
|
// Add the "read" and "write" bits for the user, otherwise we may
|
||||||
* Add the "read" and "write" bits for the user, otherwise we may
|
// not be able to write to the file ourselves.
|
||||||
* not be able to write to the file ourselves.
|
// Setting the bits is done below, after creating the swap file.
|
||||||
* Setting the bits is done below, after creating the swap file.
|
|
||||||
*/
|
|
||||||
swap_mode = ((int)file_info.stat.st_mode & 0644) | 0600;
|
swap_mode = ((int)file_info.stat.st_mode & 0644) | 0600;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@@ -520,10 +512,8 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip,
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Only set the 'ro' flag for readonly files the first time they are
|
||||||
* Only set the 'ro' flag for readonly files the first time they are
|
// loaded. Help files always get readonly mode
|
||||||
* loaded. Help files always get readonly mode
|
|
||||||
*/
|
|
||||||
if ((check_readonly && file_readonly) || curbuf->b_help) {
|
if ((check_readonly && file_readonly) || curbuf->b_help) {
|
||||||
curbuf->b_p_ro = true;
|
curbuf->b_p_ro = true;
|
||||||
}
|
}
|
||||||
@@ -645,13 +635,11 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip,
|
|||||||
curbuf->b_p_ro = true; // must use "w!" now
|
curbuf->b_p_ro = true; // must use "w!" now
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
/*
|
// Don't allow the autocommands to change the current buffer.
|
||||||
* Don't allow the autocommands to change the current buffer.
|
// Try to re-open the file.
|
||||||
* Try to re-open the file.
|
//
|
||||||
*
|
// Don't allow the autocommands to change the buffer name either
|
||||||
* Don't allow the autocommands to change the buffer name either
|
// (cd for example) if it invalidates fname or sfname.
|
||||||
* (cd for example) if it invalidates fname or sfname.
|
|
||||||
*/
|
|
||||||
if (!read_stdin && (curbuf != old_curbuf
|
if (!read_stdin && (curbuf != old_curbuf
|
||||||
|| (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
|
|| (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
|
||||||
|| (using_b_fname && (old_b_fname != curbuf->b_fname))
|
|| (using_b_fname && (old_b_fname != curbuf->b_fname))
|
||||||
@@ -679,10 +667,8 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip,
|
|||||||
|
|
||||||
msg_scroll = false; // overwrite the file message
|
msg_scroll = false; // overwrite the file message
|
||||||
|
|
||||||
/*
|
// Set linecnt now, before the "retry" caused by a wrong guess for
|
||||||
* Set linecnt now, before the "retry" caused by a wrong guess for
|
// fileformat, and after the autocommands, which may change them.
|
||||||
* fileformat, and after the autocommands, which may change them.
|
|
||||||
*/
|
|
||||||
linecnt = curbuf->b_ml.ml_line_count;
|
linecnt = curbuf->b_ml.ml_line_count;
|
||||||
|
|
||||||
// "++bad=" argument.
|
// "++bad=" argument.
|
||||||
@@ -695,9 +681,7 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip,
|
|||||||
curbuf->b_bad_char = 0;
|
curbuf->b_bad_char = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Decide which 'encoding' to use or use first.
|
||||||
* Decide which 'encoding' to use or use first.
|
|
||||||
*/
|
|
||||||
if (eap != NULL && eap->force_enc != 0) {
|
if (eap != NULL && eap->force_enc != 0) {
|
||||||
fenc = enc_canonize(eap->cmd + eap->force_enc);
|
fenc = enc_canonize(eap->cmd + eap->force_enc);
|
||||||
fenc_alloced = true;
|
fenc_alloced = true;
|
||||||
@@ -722,25 +706,23 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip,
|
|||||||
fenc = next_fenc(&fenc_next, &fenc_alloced);
|
fenc = next_fenc(&fenc_next, &fenc_alloced);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Jump back here to retry reading the file in different ways.
|
||||||
* Jump back here to retry reading the file in different ways.
|
// Reasons to retry:
|
||||||
* Reasons to retry:
|
// - encoding conversion failed: try another one from "fenc_next"
|
||||||
* - encoding conversion failed: try another one from "fenc_next"
|
// - BOM detected and fenc was set, need to setup conversion
|
||||||
* - BOM detected and fenc was set, need to setup conversion
|
// - "fileformat" check failed: try another
|
||||||
* - "fileformat" check failed: try another
|
//
|
||||||
*
|
// Variables set for special retry actions:
|
||||||
* Variables set for special retry actions:
|
// "file_rewind" Rewind the file to start reading it again.
|
||||||
* "file_rewind" Rewind the file to start reading it again.
|
// "advance_fenc" Advance "fenc" using "fenc_next".
|
||||||
* "advance_fenc" Advance "fenc" using "fenc_next".
|
// "skip_read" Re-use already read bytes (BOM detected).
|
||||||
* "skip_read" Re-use already read bytes (BOM detected).
|
// "did_iconv" iconv() conversion failed, try 'charconvert'.
|
||||||
* "did_iconv" iconv() conversion failed, try 'charconvert'.
|
// "keep_fileformat" Don't reset "fileformat".
|
||||||
* "keep_fileformat" Don't reset "fileformat".
|
//
|
||||||
*
|
// Other status indicators:
|
||||||
* Other status indicators:
|
// "tmpname" When != NULL did conversion with 'charconvert'.
|
||||||
* "tmpname" When != NULL did conversion with 'charconvert'.
|
// Output file has to be deleted afterwards.
|
||||||
* Output file has to be deleted afterwards.
|
// "iconv_fd" When != -1 did conversion with iconv().
|
||||||
* "iconv_fd" When != -1 did conversion with iconv().
|
|
||||||
*/
|
|
||||||
retry:
|
retry:
|
||||||
|
|
||||||
if (file_rewind) {
|
if (file_rewind) {
|
||||||
@@ -764,10 +746,8 @@ retry:
|
|||||||
conv_error = 0;
|
conv_error = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When retrying with another "fenc" and the first time "fileformat"
|
||||||
* When retrying with another "fenc" and the first time "fileformat"
|
// will be reset.
|
||||||
* will be reset.
|
|
||||||
*/
|
|
||||||
if (keep_fileformat) {
|
if (keep_fileformat) {
|
||||||
keep_fileformat = false;
|
keep_fileformat = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -793,9 +773,7 @@ retry:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (advance_fenc) {
|
if (advance_fenc) {
|
||||||
/*
|
// Try the next entry in 'fileencodings'.
|
||||||
* Try the next entry in 'fileencodings'.
|
|
||||||
*/
|
|
||||||
advance_fenc = false;
|
advance_fenc = false;
|
||||||
|
|
||||||
if (eap != NULL && eap->force_enc != 0) {
|
if (eap != NULL && eap->force_enc != 0) {
|
||||||
@@ -825,10 +803,8 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Conversion may be required when the encoding of the file is different
|
||||||
* Conversion may be required when the encoding of the file is different
|
// from 'encoding' or 'encoding' is UTF-16, UCS-2 or UCS-4.
|
||||||
* from 'encoding' or 'encoding' is UTF-16, UCS-2 or UCS-4.
|
|
||||||
*/
|
|
||||||
fio_flags = 0;
|
fio_flags = 0;
|
||||||
converted = need_conversion((char_u *)fenc);
|
converted = need_conversion((char_u *)fenc);
|
||||||
if (converted) {
|
if (converted) {
|
||||||
@@ -855,10 +831,8 @@ retry:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
// Use the 'charconvert' expression when conversion is required
|
||||||
* Use the 'charconvert' expression when conversion is required
|
// and we can't do it internally or with iconv().
|
||||||
* and we can't do it internally or with iconv().
|
|
||||||
*/
|
|
||||||
if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
|
if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
|
||||||
&& !read_fifo
|
&& !read_fifo
|
||||||
#ifdef HAVE_ICONV
|
#ifdef HAVE_ICONV
|
||||||
@@ -922,12 +896,10 @@ retry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (!error && !got_int) {
|
while (!error && !got_int) {
|
||||||
/*
|
// We allocate as much space for the file as we can get, plus
|
||||||
* We allocate as much space for the file as we can get, plus
|
// space for the old line plus room for one terminating NUL.
|
||||||
* space for the old line plus room for one terminating NUL.
|
// The amount is limited by the fact that read() only can read
|
||||||
* The amount is limited by the fact that read() only can read
|
// up to max_unsigned characters (and other things).
|
||||||
* up to max_unsigned characters (and other things).
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
if (!skip_read) {
|
if (!skip_read) {
|
||||||
// Use buffer >= 64K. Add linerest to double the size if the
|
// Use buffer >= 64K. Add linerest to double the size if the
|
||||||
@@ -999,10 +971,8 @@ retry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (read_buffer) {
|
if (read_buffer) {
|
||||||
/*
|
// Read bytes from curbuf. Used for converting text read
|
||||||
* Read bytes from curbuf. Used for converting text read
|
// from stdin.
|
||||||
* from stdin.
|
|
||||||
*/
|
|
||||||
if (read_buf_lnum > from) {
|
if (read_buf_lnum > from) {
|
||||||
size = 0;
|
size = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -1052,9 +1022,7 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
// Read bytes from the file.
|
||||||
* Read bytes from the file.
|
|
||||||
*/
|
|
||||||
size = read_eintr(fd, ptr, (size_t)size);
|
size = read_eintr(fd, ptr, (size_t)size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1062,10 +1030,8 @@ retry:
|
|||||||
if (size < 0) { // read error
|
if (size < 0) { // read error
|
||||||
error = true;
|
error = true;
|
||||||
} else if (conv_restlen > 0) {
|
} else if (conv_restlen > 0) {
|
||||||
/*
|
// Reached end-of-file but some trailing bytes could
|
||||||
* Reached end-of-file but some trailing bytes could
|
// not be converted. Truncated file?
|
||||||
* not be converted. Truncated file?
|
|
||||||
*/
|
|
||||||
|
|
||||||
// When we did a conversion report an error.
|
// When we did a conversion report an error.
|
||||||
if (fio_flags != 0
|
if (fio_flags != 0
|
||||||
@@ -1118,12 +1084,10 @@ retry:
|
|||||||
|
|
||||||
skip_read = false;
|
skip_read = false;
|
||||||
|
|
||||||
/*
|
// At start of file: Check for BOM.
|
||||||
* At start of file: Check for BOM.
|
// Also check for a BOM for other Unicode encodings, but not after
|
||||||
* Also check for a BOM for other Unicode encodings, but not after
|
// converting with 'charconvert' or when a BOM has already been
|
||||||
* converting with 'charconvert' or when a BOM has already been
|
// found.
|
||||||
* found.
|
|
||||||
*/
|
|
||||||
if ((filesize == 0)
|
if ((filesize == 0)
|
||||||
&& (fio_flags == FIO_UCSBOM
|
&& (fio_flags == FIO_UCSBOM
|
||||||
|| (!curbuf->b_p_bomb
|
|| (!curbuf->b_p_bomb
|
||||||
@@ -1172,9 +1136,7 @@ retry:
|
|||||||
ptr -= conv_restlen;
|
ptr -= conv_restlen;
|
||||||
size += conv_restlen;
|
size += conv_restlen;
|
||||||
conv_restlen = 0;
|
conv_restlen = 0;
|
||||||
/*
|
// Break here for a read error or end-of-file.
|
||||||
* Break here for a read error or end-of-file.
|
|
||||||
*/
|
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1188,11 +1150,9 @@ retry:
|
|||||||
char *top = ptr;
|
char *top = ptr;
|
||||||
size_t to_size = (size_t)(real_size - size);
|
size_t to_size = (size_t)(real_size - size);
|
||||||
|
|
||||||
/*
|
// If there is conversion error or not enough room try using
|
||||||
* If there is conversion error or not enough room try using
|
// another conversion. Except for when there is no
|
||||||
* another conversion. Except for when there is no
|
// alternative (help files).
|
||||||
* alternative (help files).
|
|
||||||
*/
|
|
||||||
while ((iconv(iconv_fd, (void *)&fromp, &from_size,
|
while ((iconv(iconv_fd, (void *)&fromp, &from_size,
|
||||||
&top, &to_size)
|
&top, &to_size)
|
||||||
== (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL)
|
== (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL)
|
||||||
@@ -1493,9 +1453,7 @@ rewind_retry:
|
|||||||
// count the number of characters (after conversion!)
|
// count the number of characters (after conversion!)
|
||||||
filesize += size;
|
filesize += size;
|
||||||
|
|
||||||
/*
|
// when reading the first part of a file: guess EOL type
|
||||||
* when reading the first part of a file: guess EOL type
|
|
||||||
*/
|
|
||||||
if (fileformat == EOL_UNKNOWN) {
|
if (fileformat == EOL_UNKNOWN) {
|
||||||
// First try finding a NL, for Dos and Unix
|
// First try finding a NL, for Dos and Unix
|
||||||
if (try_dos || try_unix) {
|
if (try_dos || try_unix) {
|
||||||
@@ -1560,10 +1518,8 @@ rewind_retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// This loop is executed once for every character read.
|
||||||
* This loop is executed once for every character read.
|
// Keep it fast!
|
||||||
* Keep it fast!
|
|
||||||
*/
|
|
||||||
if (fileformat == EOL_MAC) {
|
if (fileformat == EOL_MAC) {
|
||||||
ptr--;
|
ptr--;
|
||||||
while (++ptr, --size >= 0) {
|
while (++ptr, --size >= 0) {
|
||||||
@@ -1665,11 +1621,9 @@ failed:
|
|||||||
error = false;
|
error = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we get EOF in the middle of a line, note the fact and
|
||||||
* If we get EOF in the middle of a line, note the fact and
|
// complete the line ourselves.
|
||||||
* complete the line ourselves.
|
// In Dos format ignore a trailing CTRL-Z, unless 'binary' set.
|
||||||
* In Dos format ignore a trailing CTRL-Z, unless 'binary' set.
|
|
||||||
*/
|
|
||||||
if (!error
|
if (!error
|
||||||
&& !got_int
|
&& !got_int
|
||||||
&& linerest != 0
|
&& linerest != 0
|
||||||
@@ -1738,9 +1692,7 @@ failed:
|
|||||||
}
|
}
|
||||||
no_wait_return--; // may wait for return now
|
no_wait_return--; // may wait for return now
|
||||||
|
|
||||||
/*
|
// In recovery mode everything but autocommands is skipped.
|
||||||
* In recovery mode everything but autocommands is skipped.
|
|
||||||
*/
|
|
||||||
if (!recoverymode) {
|
if (!recoverymode) {
|
||||||
// need to delete the last line, which comes from the empty buffer
|
// need to delete the last line, which comes from the empty buffer
|
||||||
if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY)) {
|
if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY)) {
|
||||||
@@ -1767,11 +1719,9 @@ failed:
|
|||||||
appended_lines_mark(from, linecnt);
|
appended_lines_mark(from, linecnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we were reading from the same terminal as where messages go,
|
||||||
* If we were reading from the same terminal as where messages go,
|
// the screen will have been messed up.
|
||||||
* the screen will have been messed up.
|
// Switch on raw mode now and clear the screen.
|
||||||
* Switch on raw mode now and clear the screen.
|
|
||||||
*/
|
|
||||||
if (read_stdin) {
|
if (read_stdin) {
|
||||||
screenclear();
|
screenclear();
|
||||||
}
|
}
|
||||||
@@ -1878,10 +1828,8 @@ failed:
|
|||||||
|
|
||||||
u_clearline(); // cannot use "U" command after adding lines
|
u_clearline(); // cannot use "U" command after adding lines
|
||||||
|
|
||||||
/*
|
// In Ex mode: cursor at last new line.
|
||||||
* In Ex mode: cursor at last new line.
|
// Otherwise: cursor at first new line.
|
||||||
* Otherwise: cursor at first new line.
|
|
||||||
*/
|
|
||||||
if (exmode_active) {
|
if (exmode_active) {
|
||||||
curwin->w_cursor.lnum = from + linecnt;
|
curwin->w_cursor.lnum = from + linecnt;
|
||||||
} else {
|
} else {
|
||||||
@@ -1900,17 +1848,13 @@ failed:
|
|||||||
}
|
}
|
||||||
msg_scroll = msg_save;
|
msg_scroll = msg_save;
|
||||||
|
|
||||||
/*
|
// Get the marks before executing autocommands, so they can be used there.
|
||||||
* Get the marks before executing autocommands, so they can be used there.
|
|
||||||
*/
|
|
||||||
check_marks_read();
|
check_marks_read();
|
||||||
|
|
||||||
/*
|
// We remember if the last line of the read didn't have
|
||||||
* We remember if the last line of the read didn't have
|
// an eol even when 'binary' is off, to support turning 'fixeol' off,
|
||||||
* an eol even when 'binary' is off, to support turning 'fixeol' off,
|
// or writing the read again with 'binary' on. The latter is required
|
||||||
* or writing the read again with 'binary' on. The latter is required
|
// for ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
|
||||||
* for ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
|
|
||||||
*/
|
|
||||||
curbuf->b_no_eol_lnum = read_no_eol_lnum;
|
curbuf->b_no_eol_lnum = read_no_eol_lnum;
|
||||||
|
|
||||||
// When reloading a buffer put the cursor at the first line that is
|
// When reloading a buffer put the cursor at the first line that is
|
||||||
@@ -1919,9 +1863,7 @@ failed:
|
|||||||
u_find_first_changed();
|
u_find_first_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When opening a new file locate undo info and read it.
|
||||||
* When opening a new file locate undo info and read it.
|
|
||||||
*/
|
|
||||||
if (read_undo_file) {
|
if (read_undo_file) {
|
||||||
char_u hash[UNDO_HASH_SIZE];
|
char_u hash[UNDO_HASH_SIZE];
|
||||||
|
|
||||||
@@ -1939,11 +1881,9 @@ failed:
|
|||||||
save_file_ff(curbuf);
|
save_file_ff(curbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// The output from the autocommands should not overwrite anything and
|
||||||
* The output from the autocommands should not overwrite anything and
|
// should not be overwritten: Set msg_scroll, restore its value if no
|
||||||
* should not be overwritten: Set msg_scroll, restore its value if no
|
// output was done.
|
||||||
* output was done.
|
|
||||||
*/
|
|
||||||
msg_scroll = true;
|
msg_scroll = true;
|
||||||
if (filtering) {
|
if (filtering) {
|
||||||
apply_autocmds_exarg(EVENT_FILTERREADPOST, NULL, sfname,
|
apply_autocmds_exarg(EVENT_FILTERREADPOST, NULL, sfname,
|
||||||
@@ -2256,10 +2196,8 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Disallow writing from .exrc and .vimrc in current directory for
|
||||||
* Disallow writing from .exrc and .vimrc in current directory for
|
// security reasons.
|
||||||
* security reasons.
|
|
||||||
*/
|
|
||||||
if (check_secure()) {
|
if (check_secure()) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
@@ -2283,13 +2221,11 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
* the line. */
|
* the line. */
|
||||||
ex_no_reprint = true;
|
ex_no_reprint = true;
|
||||||
|
|
||||||
/*
|
// If there is no file name yet, use the one for the written file.
|
||||||
* If there is no file name yet, use the one for the written file.
|
// BF_NOTEDITED is set to reflect this (in case the write fails).
|
||||||
* BF_NOTEDITED is set to reflect this (in case the write fails).
|
// Don't do this when the write is for a filter command.
|
||||||
* Don't do this when the write is for a filter command.
|
// Don't do this when appending.
|
||||||
* Don't do this when appending.
|
// Only do this when 'cpoptions' contains the 'F' flag.
|
||||||
* Only do this when 'cpoptions' contains the 'F' flag.
|
|
||||||
*/
|
|
||||||
if (buf->b_ffname == NULL
|
if (buf->b_ffname == NULL
|
||||||
&& reset_changed
|
&& reset_changed
|
||||||
&& whole
|
&& whole
|
||||||
@@ -2325,9 +2261,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
|
|
||||||
no_wait_return++; // don't wait for return yet
|
no_wait_return++; // don't wait for return yet
|
||||||
|
|
||||||
/*
|
// Set '[ and '] marks to the lines to be written.
|
||||||
* Set '[ and '] marks to the lines to be written.
|
|
||||||
*/
|
|
||||||
buf->b_op_start.lnum = start;
|
buf->b_op_start.lnum = start;
|
||||||
buf->b_op_start.col = 0;
|
buf->b_op_start.col = 0;
|
||||||
buf->b_op_end.lnum = end;
|
buf->b_op_end.lnum = end;
|
||||||
@@ -2344,11 +2278,9 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
int empty_memline = (buf->b_ml.ml_mfp == NULL);
|
int empty_memline = (buf->b_ml.ml_mfp == NULL);
|
||||||
bufref_T bufref;
|
bufref_T bufref;
|
||||||
|
|
||||||
/*
|
// Apply PRE autocommands.
|
||||||
* Apply PRE autocommands.
|
// Set curbuf to the buffer to be written.
|
||||||
* Set curbuf to the buffer to be written.
|
// Careful: The autocommands may call buf_write() recursively!
|
||||||
* Careful: The autocommands may call buf_write() recursively!
|
|
||||||
*/
|
|
||||||
if (ffname == buf->b_ffname) {
|
if (ffname == buf->b_ffname) {
|
||||||
buf_ffname = true;
|
buf_ffname = true;
|
||||||
}
|
}
|
||||||
@@ -2471,12 +2403,10 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// The autocommands may have changed the number of lines in the file.
|
||||||
* The autocommands may have changed the number of lines in the file.
|
// When writing the whole file, adjust the end.
|
||||||
* When writing the whole file, adjust the end.
|
// When writing part of the file, assume that the autocommands only
|
||||||
* When writing part of the file, assume that the autocommands only
|
// changed the number of lines that are to be written (tricky!).
|
||||||
* changed the number of lines that are to be written (tricky!).
|
|
||||||
*/
|
|
||||||
if (buf->b_ml.ml_line_count != old_line_count) {
|
if (buf->b_ml.ml_line_count != old_line_count) {
|
||||||
if (whole) { // write all
|
if (whole) { // write all
|
||||||
end = buf->b_ml.ml_line_count;
|
end = buf->b_ml.ml_line_count;
|
||||||
@@ -2493,10 +2423,8 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// The autocommands may have changed the name of the buffer, which may
|
||||||
* The autocommands may have changed the name of the buffer, which may
|
// be kept in fname, ffname and sfname.
|
||||||
* be kept in fname, ffname and sfname.
|
|
||||||
*/
|
|
||||||
if (buf_ffname) {
|
if (buf_ffname) {
|
||||||
ffname = buf->b_ffname;
|
ffname = buf->b_ffname;
|
||||||
}
|
}
|
||||||
@@ -2543,9 +2471,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
bufsize = BUFSIZE;
|
bufsize = BUFSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get information about original file (if there is one).
|
||||||
* Get information about original file (if there is one).
|
|
||||||
*/
|
|
||||||
FileInfo file_info_old;
|
FileInfo file_info_old;
|
||||||
#if defined(UNIX)
|
#if defined(UNIX)
|
||||||
perm = -1;
|
perm = -1;
|
||||||
@@ -2595,10 +2521,8 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
#endif // !UNIX
|
#endif // !UNIX
|
||||||
|
|
||||||
if (!device && !newfile) {
|
if (!device && !newfile) {
|
||||||
/*
|
// Check if the file is really writable (when renaming the file to
|
||||||
* Check if the file is really writable (when renaming the file to
|
// make a backup we won't discover it later).
|
||||||
* make a backup we won't discover it later).
|
|
||||||
*/
|
|
||||||
file_readonly = !os_file_is_writable(fname);
|
file_readonly = !os_file_is_writable(fname);
|
||||||
|
|
||||||
if (!forceit && file_readonly) {
|
if (!forceit && file_readonly) {
|
||||||
@@ -2610,9 +2534,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check if the timestamp hasn't changed since reading the file.
|
||||||
* Check if the timestamp hasn't changed since reading the file.
|
|
||||||
*/
|
|
||||||
if (overwriting) {
|
if (overwriting) {
|
||||||
retval = check_mtime(buf, &file_info_old);
|
retval = check_mtime(buf, &file_info_old);
|
||||||
if (retval == FAIL) {
|
if (retval == FAIL) {
|
||||||
@@ -2622,41 +2544,33 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_ACL
|
#ifdef HAVE_ACL
|
||||||
/*
|
// For systems that support ACL: get the ACL from the original file.
|
||||||
* For systems that support ACL: get the ACL from the original file.
|
|
||||||
*/
|
|
||||||
if (!newfile) {
|
if (!newfile) {
|
||||||
acl = mch_get_acl((char_u *)fname);
|
acl = mch_get_acl((char_u *)fname);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
// If 'backupskip' is not empty, don't make a backup for some files.
|
||||||
* If 'backupskip' is not empty, don't make a backup for some files.
|
|
||||||
*/
|
|
||||||
dobackup = (p_wb || p_bk || *p_pm != NUL);
|
dobackup = (p_wb || p_bk || *p_pm != NUL);
|
||||||
if (dobackup && *p_bsk != NUL && match_file_list(p_bsk, (char_u *)sfname, (char_u *)ffname)) {
|
if (dobackup && *p_bsk != NUL && match_file_list(p_bsk, (char_u *)sfname, (char_u *)ffname)) {
|
||||||
dobackup = false;
|
dobackup = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Save the value of got_int and reset it. We don't want a previous
|
||||||
* Save the value of got_int and reset it. We don't want a previous
|
// interruption cancel writing, only hitting CTRL-C while writing should
|
||||||
* interruption cancel writing, only hitting CTRL-C while writing should
|
// abort it.
|
||||||
* abort it.
|
|
||||||
*/
|
|
||||||
prev_got_int = got_int;
|
prev_got_int = got_int;
|
||||||
got_int = false;
|
got_int = false;
|
||||||
|
|
||||||
// Mark the buffer as 'being saved' to prevent changed buffer warnings
|
// Mark the buffer as 'being saved' to prevent changed buffer warnings
|
||||||
buf->b_saving = true;
|
buf->b_saving = true;
|
||||||
|
|
||||||
/*
|
// If we are not appending or filtering, the file exists, and the
|
||||||
* If we are not appending or filtering, the file exists, and the
|
// 'writebackup', 'backup' or 'patchmode' option is set, need a backup.
|
||||||
* 'writebackup', 'backup' or 'patchmode' option is set, need a backup.
|
// When 'patchmode' is set also make a backup when appending.
|
||||||
* When 'patchmode' is set also make a backup when appending.
|
//
|
||||||
*
|
// Do not make any backup, if 'writebackup' and 'backup' are both switched
|
||||||
* Do not make any backup, if 'writebackup' and 'backup' are both switched
|
// off. This helps when editing large files on almost-full disks.
|
||||||
* off. This helps when editing large files on almost-full disks.
|
|
||||||
*/
|
|
||||||
if (!(append && *p_pm == NUL) && !filtering && perm >= 0 && dobackup) {
|
if (!(append && *p_pm == NUL) && !filtering && perm >= 0 && dobackup) {
|
||||||
FileInfo file_info;
|
FileInfo file_info;
|
||||||
const bool no_prepend_dot = false;
|
const bool no_prepend_dot = false;
|
||||||
@@ -2666,23 +2580,19 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
} else if ((bkc & BKC_AUTO)) { // "auto"
|
} else if ((bkc & BKC_AUTO)) { // "auto"
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
// Don't rename the file when:
|
||||||
* Don't rename the file when:
|
// - it's a hard link
|
||||||
* - it's a hard link
|
// - it's a symbolic link
|
||||||
* - it's a symbolic link
|
// - we don't have write permission in the directory
|
||||||
* - we don't have write permission in the directory
|
|
||||||
*/
|
|
||||||
if (os_fileinfo_hardlinks(&file_info_old) > 1
|
if (os_fileinfo_hardlinks(&file_info_old) > 1
|
||||||
|| !os_fileinfo_link(fname, &file_info)
|
|| !os_fileinfo_link(fname, &file_info)
|
||||||
|| !os_fileinfo_id_equal(&file_info, &file_info_old)) {
|
|| !os_fileinfo_id_equal(&file_info, &file_info_old)) {
|
||||||
backup_copy = true;
|
backup_copy = true;
|
||||||
} else {
|
} else {
|
||||||
/*
|
// Check if we can create a file and set the owner/group to
|
||||||
* Check if we can create a file and set the owner/group to
|
// the ones from the original file.
|
||||||
* the ones from the original file.
|
// First find a file name that doesn't exist yet (use some
|
||||||
* First find a file name that doesn't exist yet (use some
|
// arbitrary numbers).
|
||||||
* arbitrary numbers).
|
|
||||||
*/
|
|
||||||
STRCPY(IObuff, fname);
|
STRCPY(IObuff, fname);
|
||||||
for (i = 4913;; i += 123) {
|
for (i = 4913;; i += 123) {
|
||||||
char *tail = path_tail((char *)IObuff);
|
char *tail = path_tail((char *)IObuff);
|
||||||
@@ -2714,9 +2624,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Break symlinks and/or hardlinks if we've been asked to.
|
||||||
* Break symlinks and/or hardlinks if we've been asked to.
|
|
||||||
*/
|
|
||||||
if ((bkc & BKC_BREAKSYMLINK) || (bkc & BKC_BREAKHARDLINK)) {
|
if ((bkc & BKC_BREAKSYMLINK) || (bkc & BKC_BREAKHARDLINK)) {
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
bool file_info_link_ok = os_fileinfo_link(fname, &file_info);
|
bool file_info_link_ok = os_fileinfo_link(fname, &file_info);
|
||||||
@@ -2752,23 +2660,19 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
char *rootname;
|
char *rootname;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
/*
|
// Try to make the backup in each directory in the 'bdir' option.
|
||||||
* Try to make the backup in each directory in the 'bdir' option.
|
//
|
||||||
*
|
// Unix semantics has it, that we may have a writable file,
|
||||||
* Unix semantics has it, that we may have a writable file,
|
// that cannot be recreated with a simple open(..., O_CREAT, ) e.g:
|
||||||
* that cannot be recreated with a simple open(..., O_CREAT, ) e.g:
|
// - the directory is not writable,
|
||||||
* - the directory is not writable,
|
// - the file may be a symbolic link,
|
||||||
* - the file may be a symbolic link,
|
// - the file may belong to another user/group, etc.
|
||||||
* - the file may belong to another user/group, etc.
|
//
|
||||||
*
|
// For these reasons, the existing writable file must be truncated
|
||||||
* For these reasons, the existing writable file must be truncated
|
// and reused. Creation of a backup COPY will be attempted.
|
||||||
* and reused. Creation of a backup COPY will be attempted.
|
|
||||||
*/
|
|
||||||
dirp = p_bdir;
|
dirp = p_bdir;
|
||||||
while (*dirp) {
|
while (*dirp) {
|
||||||
/*
|
// Isolate one directory name, using an entry in 'bdir'.
|
||||||
* Isolate one directory name, using an entry in 'bdir'.
|
|
||||||
*/
|
|
||||||
size_t dir_len = copy_option_part(&dirp, (char *)IObuff, IOSIZE, ",");
|
size_t dir_len = copy_option_part(&dirp, (char *)IObuff, IOSIZE, ",");
|
||||||
p = (char *)IObuff + dir_len;
|
p = (char *)IObuff + dir_len;
|
||||||
bool trailing_pathseps = after_pathsep((char *)IObuff, p) && p[-1] == p[-2];
|
bool trailing_pathseps = after_pathsep((char *)IObuff, p) && p[-1] == p[-2];
|
||||||
@@ -2814,9 +2718,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
goto nobackup;
|
goto nobackup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check if backup file already exists.
|
||||||
* Check if backup file already exists.
|
|
||||||
*/
|
|
||||||
if (os_fileinfo(backup, &file_info_new)) {
|
if (os_fileinfo(backup, &file_info_new)) {
|
||||||
if (os_fileinfo_id_equal(&file_info_new, &file_info_old)) {
|
if (os_fileinfo_id_equal(&file_info_new, &file_info_old)) {
|
||||||
//
|
//
|
||||||
@@ -2848,9 +2750,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
}
|
}
|
||||||
xfree(rootname);
|
xfree(rootname);
|
||||||
|
|
||||||
/*
|
// Try to create the backup file
|
||||||
* Try to create the backup file
|
|
||||||
*/
|
|
||||||
if (backup != NULL) {
|
if (backup != NULL) {
|
||||||
// remove old backup, if present
|
// remove old backup, if present
|
||||||
os_remove(backup);
|
os_remove(backup);
|
||||||
@@ -2906,30 +2806,22 @@ nobackup:
|
|||||||
char *p;
|
char *p;
|
||||||
char *rootname;
|
char *rootname;
|
||||||
|
|
||||||
/*
|
// Make a backup by renaming the original file.
|
||||||
* Make a backup by renaming the original file.
|
|
||||||
*/
|
// If 'cpoptions' includes the "W" flag, we don't want to
|
||||||
/*
|
// overwrite a read-only file. But rename may be possible
|
||||||
* If 'cpoptions' includes the "W" flag, we don't want to
|
// anyway, thus we need an extra check here.
|
||||||
* overwrite a read-only file. But rename may be possible
|
|
||||||
* anyway, thus we need an extra check here.
|
|
||||||
*/
|
|
||||||
if (file_readonly && vim_strchr(p_cpo, CPO_FWRITE) != NULL) {
|
if (file_readonly && vim_strchr(p_cpo, CPO_FWRITE) != NULL) {
|
||||||
SET_ERRMSG_NUM("E504", _(err_readonly));
|
SET_ERRMSG_NUM("E504", _(err_readonly));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Form the backup file name - change path/fo.o.h to
|
||||||
*
|
// path/fo.o.h.bak Try all directories in 'backupdir', first one
|
||||||
* Form the backup file name - change path/fo.o.h to
|
// that works is used.
|
||||||
* path/fo.o.h.bak Try all directories in 'backupdir', first one
|
|
||||||
* that works is used.
|
|
||||||
*/
|
|
||||||
dirp = p_bdir;
|
dirp = p_bdir;
|
||||||
while (*dirp) {
|
while (*dirp) {
|
||||||
/*
|
// Isolate one directory name and make the backup file name.
|
||||||
* Isolate one directory name and make the backup file name.
|
|
||||||
*/
|
|
||||||
size_t dir_len = copy_option_part(&dirp, (char *)IObuff, IOSIZE, ",");
|
size_t dir_len = copy_option_part(&dirp, (char *)IObuff, IOSIZE, ",");
|
||||||
p = (char *)IObuff + dir_len;
|
p = (char *)IObuff + dir_len;
|
||||||
bool trailing_pathseps = after_pathsep((char *)IObuff, p) && p[-1] == p[-2];
|
bool trailing_pathseps = after_pathsep((char *)IObuff, p) && p[-1] == p[-2];
|
||||||
@@ -2965,11 +2857,9 @@ nobackup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (backup != NULL) {
|
if (backup != NULL) {
|
||||||
/*
|
// If we are not going to keep the backup file, don't
|
||||||
* If we are not going to keep the backup file, don't
|
// delete an existing one, try to use another name.
|
||||||
* delete an existing one, try to use another name.
|
// Change one character, just before the extension.
|
||||||
* Change one character, just before the extension.
|
|
||||||
*/
|
|
||||||
if (!p_bk && os_path_exists(backup)) {
|
if (!p_bk && os_path_exists(backup)) {
|
||||||
p = backup + STRLEN(backup) - 1 - STRLEN(backup_ext);
|
p = backup + STRLEN(backup) - 1 - STRLEN(backup_ext);
|
||||||
if (p < backup) { // empty file name ???
|
if (p < backup) { // empty file name ???
|
||||||
@@ -3099,11 +2989,9 @@ nobackup:
|
|||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
// When the file needs to be converted with 'charconvert' after
|
||||||
* When the file needs to be converted with 'charconvert' after
|
// writing, write to a temp file instead and let the conversion
|
||||||
* writing, write to a temp file instead and let the conversion
|
// overwrite the original file.
|
||||||
* overwrite the original file.
|
|
||||||
*/
|
|
||||||
if (*p_ccv != NUL) {
|
if (*p_ccv != NUL) {
|
||||||
wfname = (char *)vim_tempname();
|
wfname = (char *)vim_tempname();
|
||||||
if (wfname == NULL) { // Can't write without a tempfile!
|
if (wfname == NULL) { // Can't write without a tempfile!
|
||||||
@@ -3561,10 +3449,8 @@ restore_backup:
|
|||||||
u_update_save_nr(buf);
|
u_update_save_nr(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If written to the current file, update the timestamp of the swap file
|
||||||
* If written to the current file, update the timestamp of the swap file
|
// and reset the BF_WRITE_MASK flags. Also sets buf->b_mtime.
|
||||||
* and reset the BF_WRITE_MASK flags. Also sets buf->b_mtime.
|
|
||||||
*/
|
|
||||||
if (overwriting) {
|
if (overwriting) {
|
||||||
ml_timestamp(buf);
|
ml_timestamp(buf);
|
||||||
if (append) {
|
if (append) {
|
||||||
@@ -3574,18 +3460,14 @@ restore_backup:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we kept a backup until now, and we are in patch mode, then we make
|
||||||
* If we kept a backup until now, and we are in patch mode, then we make
|
// the backup file our 'original' file.
|
||||||
* the backup file our 'original' file.
|
|
||||||
*/
|
|
||||||
if (*p_pm && dobackup) {
|
if (*p_pm && dobackup) {
|
||||||
char *const org = modname(fname, p_pm, false);
|
char *const org = modname(fname, p_pm, false);
|
||||||
|
|
||||||
if (backup != NULL) {
|
if (backup != NULL) {
|
||||||
/*
|
// If the original file does not exist yet
|
||||||
* If the original file does not exist yet
|
// the current backup file becomes the original file
|
||||||
* the current backup file becomes the original file
|
|
||||||
*/
|
|
||||||
if (org == NULL) {
|
if (org == NULL) {
|
||||||
emsg(_("E205: Patchmode: can't save original file"));
|
emsg(_("E205: Patchmode: can't save original file"));
|
||||||
} else if (!os_path_exists(org)) {
|
} else if (!os_path_exists(org)) {
|
||||||
@@ -3597,12 +3479,9 @@ restore_backup:
|
|||||||
(double)file_info_old.stat.st_mtim.tv_sec);
|
(double)file_info_old.stat.st_mtim.tv_sec);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
/*
|
// If there is no backup file, remember that a (new) file was
|
||||||
* If there is no backup file, remember that a (new) file was
|
// created.
|
||||||
* created.
|
|
||||||
*/
|
|
||||||
else {
|
|
||||||
int empty_fd;
|
int empty_fd;
|
||||||
|
|
||||||
if (org == NULL
|
if (org == NULL
|
||||||
@@ -3620,9 +3499,7 @@ restore_backup:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Remove the backup unless 'backup' option is set
|
||||||
* Remove the backup unless 'backup' option is set
|
|
||||||
*/
|
|
||||||
if (!p_bk && backup != NULL
|
if (!p_bk && backup != NULL
|
||||||
&& !write_info.bw_conv_error
|
&& !write_info.bw_conv_error
|
||||||
&& os_remove(backup) != 0) {
|
&& os_remove(backup) != 0) {
|
||||||
@@ -3631,9 +3508,7 @@ restore_backup:
|
|||||||
|
|
||||||
goto nofail;
|
goto nofail;
|
||||||
|
|
||||||
/*
|
// Finish up. We get here either after failure or success.
|
||||||
* Finish up. We get here either after failure or success.
|
|
||||||
*/
|
|
||||||
fail:
|
fail:
|
||||||
no_wait_return--; // may wait for return now
|
no_wait_return--; // may wait for return now
|
||||||
nofail:
|
nofail:
|
||||||
@@ -3698,10 +3573,8 @@ nofail:
|
|||||||
}
|
}
|
||||||
msg_scroll = msg_save;
|
msg_scroll = msg_save;
|
||||||
|
|
||||||
/*
|
// When writing the whole file and 'undofile' is set, also write the undo
|
||||||
* When writing the whole file and 'undofile' is set, also write the undo
|
// file.
|
||||||
* file.
|
|
||||||
*/
|
|
||||||
if (retval == OK && write_undo_file) {
|
if (retval == OK && write_undo_file) {
|
||||||
char hash[UNDO_HASH_SIZE];
|
char hash[UNDO_HASH_SIZE];
|
||||||
|
|
||||||
@@ -3714,10 +3587,8 @@ nofail:
|
|||||||
|
|
||||||
curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read
|
curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read
|
||||||
|
|
||||||
/*
|
// Apply POST autocommands.
|
||||||
* Apply POST autocommands.
|
// Careful: The autocommands may call buf_write() recursively!
|
||||||
* Careful: The autocommands may call buf_write() recursively!
|
|
||||||
*/
|
|
||||||
aucmd_prepbuf(&aco, buf);
|
aucmd_prepbuf(&aco, buf);
|
||||||
|
|
||||||
if (append) {
|
if (append) {
|
||||||
@@ -3918,18 +3789,14 @@ static int buf_write_bytes(struct bw_info *ip)
|
|||||||
int flags = ip->bw_flags; // extra flags
|
int flags = ip->bw_flags; // extra flags
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
// Skip conversion when writing the BOM.
|
||||||
* Skip conversion when writing the BOM.
|
|
||||||
*/
|
|
||||||
if (!(flags & FIO_NOCONVERT)) {
|
if (!(flags & FIO_NOCONVERT)) {
|
||||||
char_u *p;
|
char_u *p;
|
||||||
unsigned c;
|
unsigned c;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (flags & FIO_UTF8) {
|
if (flags & FIO_UTF8) {
|
||||||
/*
|
// Convert latin1 in the buffer to UTF-8 in the file.
|
||||||
* Convert latin1 in the buffer to UTF-8 in the file.
|
|
||||||
*/
|
|
||||||
p = ip->bw_conv_buf; // translate to buffer
|
p = ip->bw_conv_buf; // translate to buffer
|
||||||
for (wlen = 0; wlen < len; wlen++) {
|
for (wlen = 0; wlen < len; wlen++) {
|
||||||
p += utf_char2bytes(buf[wlen], (char *)p);
|
p += utf_char2bytes(buf[wlen], (char *)p);
|
||||||
@@ -3937,10 +3804,8 @@ static int buf_write_bytes(struct bw_info *ip)
|
|||||||
buf = ip->bw_conv_buf;
|
buf = ip->bw_conv_buf;
|
||||||
len = (int)(p - ip->bw_conv_buf);
|
len = (int)(p - ip->bw_conv_buf);
|
||||||
} else if (flags & (FIO_UCS4 | FIO_UTF16 | FIO_UCS2 | FIO_LATIN1)) {
|
} else if (flags & (FIO_UCS4 | FIO_UTF16 | FIO_UCS2 | FIO_LATIN1)) {
|
||||||
/*
|
// Convert UTF-8 bytes in the buffer to UCS-2, UCS-4, UTF-16 or
|
||||||
* Convert UTF-8 bytes in the buffer to UCS-2, UCS-4, UTF-16 or
|
// Latin1 chars in the file.
|
||||||
* Latin1 chars in the file.
|
|
||||||
*/
|
|
||||||
if (flags & FIO_LATIN1) {
|
if (flags & FIO_LATIN1) {
|
||||||
p = buf; // translate in-place (can only get shorter)
|
p = buf; // translate in-place (can only get shorter)
|
||||||
} else {
|
} else {
|
||||||
@@ -4063,9 +3928,7 @@ static int buf_write_bytes(struct bw_info *ip)
|
|||||||
ip->bw_first = false;
|
ip->bw_first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If iconv() has an error or there is not enough room, fail.
|
||||||
* If iconv() has an error or there is not enough room, fail.
|
|
||||||
*/
|
|
||||||
if ((iconv(ip->bw_iconv_fd, (void *)&from, &fromlen, &to, &tolen)
|
if ((iconv(ip->bw_iconv_fd, (void *)&from, &fromlen, &to, &tolen)
|
||||||
== (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL)
|
== (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL)
|
||||||
|| fromlen > CONV_RESTLEN) {
|
|| fromlen > CONV_RESTLEN) {
|
||||||
@@ -4633,11 +4496,9 @@ int vim_rename(const char_u *from, const char_u *to)
|
|||||||
#endif
|
#endif
|
||||||
bool use_tmp_file = false;
|
bool use_tmp_file = false;
|
||||||
|
|
||||||
/*
|
// When the names are identical, there is nothing to do. When they refer
|
||||||
* When the names are identical, there is nothing to do. When they refer
|
// to the same file (ignoring case and slash/backslash differences) but
|
||||||
* to the same file (ignoring case and slash/backslash differences) but
|
// the file name differs we need to go through a temp file.
|
||||||
* the file name differs we need to go through a temp file.
|
|
||||||
*/
|
|
||||||
if (FNAMECMP(from, to) == 0) {
|
if (FNAMECMP(from, to) == 0) {
|
||||||
if (p_fic && (STRCMP(path_tail((char *)from), path_tail((char *)to))
|
if (p_fic && (STRCMP(path_tail((char *)from), path_tail((char *)to))
|
||||||
!= 0)) {
|
!= 0)) {
|
||||||
@@ -4665,10 +4526,8 @@ int vim_rename(const char_u *from, const char_u *to)
|
|||||||
if (use_tmp_file) {
|
if (use_tmp_file) {
|
||||||
char_u tempname[MAXPATHL + 1];
|
char_u tempname[MAXPATHL + 1];
|
||||||
|
|
||||||
/*
|
// Find a name that doesn't exist and is in the same directory.
|
||||||
* Find a name that doesn't exist and is in the same directory.
|
// Rename "from" to "tempname" and then rename "tempname" to "to".
|
||||||
* Rename "from" to "tempname" and then rename "tempname" to "to".
|
|
||||||
*/
|
|
||||||
if (STRLEN(from) >= MAXPATHL - 5) {
|
if (STRLEN(from) >= MAXPATHL - 5) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -4695,24 +4554,18 @@ int vim_rename(const char_u *from, const char_u *to)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Delete the "to" file, this is required on some systems to make the
|
||||||
* Delete the "to" file, this is required on some systems to make the
|
// os_rename() work, on other systems it makes sure that we don't have
|
||||||
* os_rename() work, on other systems it makes sure that we don't have
|
// two files when the os_rename() fails.
|
||||||
* two files when the os_rename() fails.
|
|
||||||
*/
|
|
||||||
|
|
||||||
os_remove((char *)to);
|
os_remove((char *)to);
|
||||||
|
|
||||||
/*
|
// First try a normal rename, return if it works.
|
||||||
* First try a normal rename, return if it works.
|
|
||||||
*/
|
|
||||||
if (os_rename(from, to) == OK) {
|
if (os_rename(from, to) == OK) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Rename() failed, try copying the file.
|
||||||
* Rename() failed, try copying the file.
|
|
||||||
*/
|
|
||||||
perm = os_getperm((const char *)from);
|
perm = os_getperm((const char *)from);
|
||||||
#ifdef HAVE_ACL
|
#ifdef HAVE_ACL
|
||||||
// For systems that support ACL: get the ACL from the original file.
|
// For systems that support ACL: get the ACL from the original file.
|
||||||
@@ -5553,12 +5406,10 @@ bool match_file_pat(char *pattern, regprog_T **prog, char *fname, char *sfname,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Try for a match with the pattern with:
|
||||||
* Try for a match with the pattern with:
|
// 1. the full file name, when the pattern has a '/'.
|
||||||
* 1. the full file name, when the pattern has a '/'.
|
// 2. the short file name, when the pattern has a '/'.
|
||||||
* 2. the short file name, when the pattern has a '/'.
|
// 3. the tail of the file name, when the pattern has no '/'.
|
||||||
* 3. the tail of the file name, when the pattern has no '/'.
|
|
||||||
*/
|
|
||||||
if (regmatch.regprog != NULL
|
if (regmatch.regprog != NULL
|
||||||
&& ((allow_dirs
|
&& ((allow_dirs
|
||||||
&& (vim_regexec(®match, fname, (colnr_T)0)
|
&& (vim_regexec(®match, fname, (colnr_T)0)
|
||||||
|
@@ -8,10 +8,8 @@
|
|||||||
#include "nvim/pos.h"
|
#include "nvim/pos.h"
|
||||||
#include "nvim/types.h"
|
#include "nvim/types.h"
|
||||||
|
|
||||||
/*
|
// Info used to pass info about a fold from the fold-detection code to the
|
||||||
* Info used to pass info about a fold from the fold-detection code to the
|
// code that displays the foldcolumn.
|
||||||
* code that displays the foldcolumn.
|
|
||||||
*/
|
|
||||||
typedef struct foldinfo {
|
typedef struct foldinfo {
|
||||||
linenr_T fi_lnum; // line number where fold starts
|
linenr_T fi_lnum; // line number where fold starts
|
||||||
int fi_level; // level of the fold; when this is zero the
|
int fi_level; // level of the fold; when this is zero the
|
||||||
|
@@ -87,25 +87,23 @@ static int block_redo = false;
|
|||||||
|
|
||||||
static int KeyNoremap = 0; // remapping flags
|
static int KeyNoremap = 0; // remapping flags
|
||||||
|
|
||||||
/*
|
// Variables used by vgetorpeek() and flush_buffers()
|
||||||
* Variables used by vgetorpeek() and flush_buffers()
|
//
|
||||||
*
|
// typebuf.tb_buf[] contains all characters that are not consumed yet.
|
||||||
* typebuf.tb_buf[] contains all characters that are not consumed yet.
|
// typebuf.tb_buf[typebuf.tb_off] is the first valid character.
|
||||||
* typebuf.tb_buf[typebuf.tb_off] is the first valid character.
|
// typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len - 1] is the last valid char.
|
||||||
* typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len - 1] is the last valid char.
|
// typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len] must be NUL.
|
||||||
* typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len] must be NUL.
|
// The head of the buffer may contain the result of mappings, abbreviations
|
||||||
* The head of the buffer may contain the result of mappings, abbreviations
|
// and @a commands. The length of this part is typebuf.tb_maplen.
|
||||||
* and @a commands. The length of this part is typebuf.tb_maplen.
|
// typebuf.tb_silent is the part where <silent> applies.
|
||||||
* typebuf.tb_silent is the part where <silent> applies.
|
// After the head are characters that come from the terminal.
|
||||||
* After the head are characters that come from the terminal.
|
// typebuf.tb_no_abbr_cnt is the number of characters in typebuf.tb_buf that
|
||||||
* typebuf.tb_no_abbr_cnt is the number of characters in typebuf.tb_buf that
|
// should not be considered for abbreviations.
|
||||||
* should not be considered for abbreviations.
|
// Some parts of typebuf.tb_buf may not be mapped. These parts are remembered
|
||||||
* Some parts of typebuf.tb_buf may not be mapped. These parts are remembered
|
// in typebuf.tb_noremap[], which is the same length as typebuf.tb_buf and
|
||||||
* in typebuf.tb_noremap[], which is the same length as typebuf.tb_buf and
|
// contains RM_NONE for the characters that are not to be remapped.
|
||||||
* contains RM_NONE for the characters that are not to be remapped.
|
// typebuf.tb_noremap[typebuf.tb_off] is the first valid flag.
|
||||||
* typebuf.tb_noremap[typebuf.tb_off] is the first valid flag.
|
// (typebuf has been put in globals.h, because check_termcode() needs it).
|
||||||
* (typebuf has been put in globals.h, because check_termcode() needs it).
|
|
||||||
*/
|
|
||||||
#define RM_YES 0 // tb_noremap: remap
|
#define RM_YES 0 // tb_noremap: remap
|
||||||
#define RM_NONE 1 // tb_noremap: don't remap
|
#define RM_NONE 1 // tb_noremap: don't remap
|
||||||
#define RM_SCRIPT 2 // tb_noremap: remap local script mappings
|
#define RM_SCRIPT 2 // tb_noremap: remap local script mappings
|
||||||
@@ -124,9 +122,7 @@ static size_t last_recorded_len = 0; // number of last recorded chars
|
|||||||
# include "getchar.c.generated.h"
|
# include "getchar.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
// Free and clear a buffer.
|
||||||
* Free and clear a buffer.
|
|
||||||
*/
|
|
||||||
void free_buff(buffheader_T *buf)
|
void free_buff(buffheader_T *buf)
|
||||||
{
|
{
|
||||||
buffblock_T *p, *np;
|
buffblock_T *p, *np;
|
||||||
@@ -180,20 +176,16 @@ char_u *get_recorded(void)
|
|||||||
p = get_buffcont(&recordbuff, true);
|
p = get_buffcont(&recordbuff, true);
|
||||||
free_buff(&recordbuff);
|
free_buff(&recordbuff);
|
||||||
|
|
||||||
/*
|
// Remove the characters that were added the last time, these must be the
|
||||||
* Remove the characters that were added the last time, these must be the
|
// (possibly mapped) characters that stopped the recording.
|
||||||
* (possibly mapped) characters that stopped the recording.
|
|
||||||
*/
|
|
||||||
len = STRLEN(p);
|
len = STRLEN(p);
|
||||||
if (len >= last_recorded_len) {
|
if (len >= last_recorded_len) {
|
||||||
len -= last_recorded_len;
|
len -= last_recorded_len;
|
||||||
p[len] = NUL;
|
p[len] = NUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When stopping recording from Insert mode with CTRL-O q, also remove the
|
||||||
* When stopping recording from Insert mode with CTRL-O q, also remove the
|
// CTRL-O.
|
||||||
* CTRL-O.
|
|
||||||
*/
|
|
||||||
if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O) {
|
if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O) {
|
||||||
p[len - 1] = NUL;
|
p[len - 1] = NUL;
|
||||||
}
|
}
|
||||||
@@ -351,9 +343,7 @@ static int read_readbuf(buffheader_T *buf, int advance)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Prepare the read buffers for reading (if they contain something).
|
||||||
* Prepare the read buffers for reading (if they contain something).
|
|
||||||
*/
|
|
||||||
static void start_stuff(void)
|
static void start_stuff(void)
|
||||||
{
|
{
|
||||||
if (readbuf1.bh_first.b_next != NULL) {
|
if (readbuf1.bh_first.b_next != NULL) {
|
||||||
@@ -381,19 +371,15 @@ int readbuf1_empty(void)
|
|||||||
return (readbuf1.bh_first.b_next == NULL);
|
return (readbuf1.bh_first.b_next == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set a typeahead character that won't be flushed.
|
||||||
* Set a typeahead character that won't be flushed.
|
|
||||||
*/
|
|
||||||
void typeahead_noflush(int c)
|
void typeahead_noflush(int c)
|
||||||
{
|
{
|
||||||
typeahead_char = c;
|
typeahead_char = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Remove the contents of the stuff buffer and the mapped characters in the
|
||||||
* Remove the contents of the stuff buffer and the mapped characters in the
|
// typeahead buffer (used in case of an error). If "flush_typeahead" is true,
|
||||||
* typeahead buffer (used in case of an error). If "flush_typeahead" is true,
|
// flush all typeahead characters (used when interrupted by a CTRL-C).
|
||||||
* flush all typeahead characters (used when interrupted by a CTRL-C).
|
|
||||||
*/
|
|
||||||
void flush_buffers(flush_buffers_T flush_typeahead)
|
void flush_buffers(flush_buffers_T flush_typeahead)
|
||||||
{
|
{
|
||||||
init_typebuf();
|
init_typebuf();
|
||||||
@@ -437,10 +423,8 @@ void beep_flush(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// The previous contents of the redo buffer is kept in old_redobuffer.
|
||||||
* The previous contents of the redo buffer is kept in old_redobuffer.
|
// This is used for the CTRL-O <.> command in insert mode.
|
||||||
* This is used for the CTRL-O <.> command in insert mode.
|
|
||||||
*/
|
|
||||||
void ResetRedobuff(void)
|
void ResetRedobuff(void)
|
||||||
{
|
{
|
||||||
if (!block_redo) {
|
if (!block_redo) {
|
||||||
@@ -450,10 +434,8 @@ void ResetRedobuff(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Discard the contents of the redo buffer and restore the previous redo
|
||||||
* Discard the contents of the redo buffer and restore the previous redo
|
// buffer.
|
||||||
* buffer.
|
|
||||||
*/
|
|
||||||
void CancelRedo(void)
|
void CancelRedo(void)
|
||||||
{
|
{
|
||||||
if (!block_redo) {
|
if (!block_redo) {
|
||||||
@@ -559,9 +541,7 @@ void AppendCharToRedobuff(int c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Append a number to the redo buffer.
|
||||||
* Append a number to the redo buffer.
|
|
||||||
*/
|
|
||||||
void AppendNumberToRedobuff(long n)
|
void AppendNumberToRedobuff(long n)
|
||||||
{
|
{
|
||||||
if (!block_redo) {
|
if (!block_redo) {
|
||||||
@@ -615,9 +595,7 @@ void stuffcharReadbuff(int c)
|
|||||||
add_char_buff(&readbuf1, c);
|
add_char_buff(&readbuf1, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Append a number to the stuff buffer.
|
||||||
* Append a number to the stuff buffer.
|
|
||||||
*/
|
|
||||||
void stuffnumReadbuff(long n)
|
void stuffnumReadbuff(long n)
|
||||||
{
|
{
|
||||||
add_num_buff(&readbuf1, n);
|
add_num_buff(&readbuf1, n);
|
||||||
@@ -783,11 +761,9 @@ int start_redo(long count, bool old_redo)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Repeat the last insert (R, o, O, a, A, i or I command) by stuffing
|
||||||
* Repeat the last insert (R, o, O, a, A, i or I command) by stuffing
|
// the redo buffer into readbuf2.
|
||||||
* the redo buffer into readbuf2.
|
// return FAIL for failure, OK otherwise
|
||||||
* return FAIL for failure, OK otherwise
|
|
||||||
*/
|
|
||||||
int start_redo_ins(void)
|
int start_redo_ins(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -818,11 +794,9 @@ void stop_redo_ins(void)
|
|||||||
block_redo = false;
|
block_redo = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Initialize typebuf.tb_buf to point to typebuf_init.
|
||||||
* Initialize typebuf.tb_buf to point to typebuf_init.
|
// alloc() cannot be used here: In out-of-memory situations it would
|
||||||
* alloc() cannot be used here: In out-of-memory situations it would
|
// be impossible to type anything.
|
||||||
* be impossible to type anything.
|
|
||||||
*/
|
|
||||||
static void init_typebuf(void)
|
static void init_typebuf(void)
|
||||||
{
|
{
|
||||||
if (typebuf.tb_buf == NULL) {
|
if (typebuf.tb_buf == NULL) {
|
||||||
@@ -939,14 +913,12 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent)
|
|||||||
val = RM_NONE;
|
val = RM_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Adjust typebuf.tb_noremap[] for the new characters:
|
||||||
* Adjust typebuf.tb_noremap[] for the new characters:
|
// If noremap == REMAP_NONE or REMAP_SCRIPT: new characters are
|
||||||
* If noremap == REMAP_NONE or REMAP_SCRIPT: new characters are
|
// (sometimes) not remappable
|
||||||
* (sometimes) not remappable
|
// If noremap == REMAP_YES: all the new characters are mappable
|
||||||
* If noremap == REMAP_YES: all the new characters are mappable
|
// If noremap > 0: "noremap" characters are not remappable, the rest
|
||||||
* If noremap > 0: "noremap" characters are not remappable, the rest
|
// mappable
|
||||||
* mappable
|
|
||||||
*/
|
|
||||||
if (noremap == REMAP_SKIP) {
|
if (noremap == REMAP_SKIP) {
|
||||||
nrm = 1;
|
nrm = 1;
|
||||||
} else if (noremap < 0) {
|
} else if (noremap < 0) {
|
||||||
@@ -1016,18 +988,14 @@ int typebuf_typed(void)
|
|||||||
return typebuf.tb_maplen == 0;
|
return typebuf.tb_maplen == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return the number of characters that are mapped (or not typed).
|
||||||
* Return the number of characters that are mapped (or not typed).
|
|
||||||
*/
|
|
||||||
int typebuf_maplen(void)
|
int typebuf_maplen(void)
|
||||||
FUNC_ATTR_PURE
|
FUNC_ATTR_PURE
|
||||||
{
|
{
|
||||||
return typebuf.tb_maplen;
|
return typebuf.tb_maplen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// remove "len" characters from typebuf.tb_buf[typebuf.tb_off + offset]
|
||||||
* remove "len" characters from typebuf.tb_buf[typebuf.tb_off + offset]
|
|
||||||
*/
|
|
||||||
void del_typebuf(int len, int offset)
|
void del_typebuf(int len, int offset)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -1038,21 +1006,14 @@ void del_typebuf(int len, int offset)
|
|||||||
|
|
||||||
typebuf.tb_len -= len;
|
typebuf.tb_len -= len;
|
||||||
|
|
||||||
/*
|
// Easy case: Just increase typebuf.tb_off.
|
||||||
* Easy case: Just increase typebuf.tb_off.
|
|
||||||
*/
|
|
||||||
if (offset == 0 && typebuf.tb_buflen - (typebuf.tb_off + len)
|
if (offset == 0 && typebuf.tb_buflen - (typebuf.tb_off + len)
|
||||||
>= 3 * MAXMAPLEN + 3) {
|
>= 3 * MAXMAPLEN + 3) {
|
||||||
typebuf.tb_off += len;
|
typebuf.tb_off += len;
|
||||||
}
|
} else {
|
||||||
/*
|
// Have to move the characters in typebuf.tb_buf[] and typebuf.tb_noremap[]
|
||||||
* Have to move the characters in typebuf.tb_buf[] and typebuf.tb_noremap[]
|
|
||||||
*/
|
|
||||||
else {
|
|
||||||
i = typebuf.tb_off + offset;
|
i = typebuf.tb_off + offset;
|
||||||
/*
|
// Leave some extra room at the end to avoid reallocation.
|
||||||
* Leave some extra room at the end to avoid reallocation.
|
|
||||||
*/
|
|
||||||
if (typebuf.tb_off > MAXMAPLEN) {
|
if (typebuf.tb_off > MAXMAPLEN) {
|
||||||
memmove(typebuf.tb_buf + MAXMAPLEN,
|
memmove(typebuf.tb_buf + MAXMAPLEN,
|
||||||
typebuf.tb_buf + typebuf.tb_off, (size_t)offset);
|
typebuf.tb_buf + typebuf.tb_off, (size_t)offset);
|
||||||
@@ -1101,10 +1062,8 @@ void del_typebuf(int len, int offset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Write typed characters to script file.
|
||||||
* Write typed characters to script file.
|
// If recording is on put the character in the recordbuffer.
|
||||||
* If recording is on put the character in the recordbuffer.
|
|
||||||
*/
|
|
||||||
static void gotchars(const char_u *chars, size_t len)
|
static void gotchars(const char_u *chars, size_t len)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
@@ -1161,14 +1120,12 @@ void ungetchars(int len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Sync undo. Called when typed characters are obtained from the typeahead
|
||||||
* Sync undo. Called when typed characters are obtained from the typeahead
|
// buffer, or when a menu is used.
|
||||||
* buffer, or when a menu is used.
|
// Do not sync:
|
||||||
* Do not sync:
|
// - In Insert mode, unless cursor key has been used.
|
||||||
* - In Insert mode, unless cursor key has been used.
|
// - While reading a script file.
|
||||||
* - While reading a script file.
|
// - When no_u_sync is non-zero.
|
||||||
* - When no_u_sync is non-zero.
|
|
||||||
*/
|
|
||||||
void may_sync_undo(void)
|
void may_sync_undo(void)
|
||||||
{
|
{
|
||||||
if ((!(State & (MODE_INSERT | MODE_CMDLINE)) || arrow_used)
|
if ((!(State & (MODE_INSERT | MODE_CMDLINE)) || arrow_used)
|
||||||
@@ -1177,9 +1134,7 @@ void may_sync_undo(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Make "typebuf" empty and allocate new buffers.
|
||||||
* Make "typebuf" empty and allocate new buffers.
|
|
||||||
*/
|
|
||||||
void alloc_typebuf(void)
|
void alloc_typebuf(void)
|
||||||
{
|
{
|
||||||
typebuf.tb_buf = xmalloc(TYPELEN_INIT);
|
typebuf.tb_buf = xmalloc(TYPELEN_INIT);
|
||||||
@@ -1195,9 +1150,7 @@ void alloc_typebuf(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Free the buffers of "typebuf".
|
||||||
* Free the buffers of "typebuf".
|
|
||||||
*/
|
|
||||||
void free_typebuf(void)
|
void free_typebuf(void)
|
||||||
{
|
{
|
||||||
if (typebuf.tb_buf == typebuf_init) {
|
if (typebuf.tb_buf == typebuf_init) {
|
||||||
@@ -1212,10 +1165,8 @@ void free_typebuf(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When doing ":so! file", the current typeahead needs to be saved, and
|
||||||
* When doing ":so! file", the current typeahead needs to be saved, and
|
// restored when "file" has been read completely.
|
||||||
* restored when "file" has been read completely.
|
|
||||||
*/
|
|
||||||
static typebuf_T saved_typebuf[NSCRIPT];
|
static typebuf_T saved_typebuf[NSCRIPT];
|
||||||
|
|
||||||
void save_typebuf(void)
|
void save_typebuf(void)
|
||||||
@@ -1239,9 +1190,7 @@ static bool can_get_old_char(void)
|
|||||||
return old_char != -1 && (old_KeyStuffed || stuff_empty());
|
return old_char != -1 && (old_KeyStuffed || stuff_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Save all three kinds of typeahead, so that the user must type at a prompt.
|
||||||
* Save all three kinds of typeahead, so that the user must type at a prompt.
|
|
||||||
*/
|
|
||||||
void save_typeahead(tasave_T *tp)
|
void save_typeahead(tasave_T *tp)
|
||||||
{
|
{
|
||||||
tp->save_typebuf = typebuf;
|
tp->save_typebuf = typebuf;
|
||||||
@@ -1257,10 +1206,8 @@ void save_typeahead(tasave_T *tp)
|
|||||||
readbuf2.bh_first.b_next = NULL;
|
readbuf2.bh_first.b_next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Restore the typeahead to what it was before calling save_typeahead().
|
||||||
* Restore the typeahead to what it was before calling save_typeahead().
|
// The allocated memory is freed, can only be called once!
|
||||||
* The allocated memory is freed, can only be called once!
|
|
||||||
*/
|
|
||||||
void restore_typeahead(tasave_T *tp)
|
void restore_typeahead(tasave_T *tp)
|
||||||
{
|
{
|
||||||
if (tp->typebuf_valid) {
|
if (tp->typebuf_valid) {
|
||||||
@@ -1314,12 +1261,10 @@ void openscript(char *name, bool directly)
|
|||||||
}
|
}
|
||||||
save_typebuf();
|
save_typebuf();
|
||||||
|
|
||||||
/*
|
// Execute the commands from the file right now when using ":source!"
|
||||||
* Execute the commands from the file right now when using ":source!"
|
// after ":global" or ":argdo" or in a loop. Also when another command
|
||||||
* after ":global" or ":argdo" or in a loop. Also when another command
|
// follows. This means the display won't be updated. Don't do this
|
||||||
* follows. This means the display won't be updated. Don't do this
|
// always, "make test" would fail.
|
||||||
* always, "make test" would fail.
|
|
||||||
*/
|
|
||||||
if (directly) {
|
if (directly) {
|
||||||
oparg_T oa;
|
oparg_T oa;
|
||||||
int oldcurscript;
|
int oldcurscript;
|
||||||
@@ -1348,9 +1293,7 @@ void openscript(char *name, bool directly)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Close the currently active input script.
|
||||||
* Close the currently active input script.
|
|
||||||
*/
|
|
||||||
static void closescript(void)
|
static void closescript(void)
|
||||||
{
|
{
|
||||||
free_typebuf();
|
free_typebuf();
|
||||||
@@ -1452,10 +1395,8 @@ int vgetc(void)
|
|||||||
garbage_collect(false);
|
garbage_collect(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If a character was put back with vungetc, it was already processed.
|
||||||
* If a character was put back with vungetc, it was already processed.
|
// Return it directly.
|
||||||
* Return it directly.
|
|
||||||
*/
|
|
||||||
if (can_get_old_char()) {
|
if (can_get_old_char()) {
|
||||||
c = old_char;
|
c = old_char;
|
||||||
old_char = -1;
|
old_char = -1;
|
||||||
@@ -1628,11 +1569,9 @@ int vgetc(void)
|
|||||||
last_vgetc_recorded_len = last_recorded_len;
|
last_vgetc_recorded_len = last_recorded_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// In the main loop "may_garbage_collect" can be set to do garbage
|
||||||
* In the main loop "may_garbage_collect" can be set to do garbage
|
// collection in the first next vgetc(). It's disabled after that to
|
||||||
* collection in the first next vgetc(). It's disabled after that to
|
// avoid internally used Lists and Dicts to be freed.
|
||||||
* avoid internally used Lists and Dicts to be freed.
|
|
||||||
*/
|
|
||||||
may_garbage_collect = false;
|
may_garbage_collect = false;
|
||||||
|
|
||||||
// Execute Lua on_key callbacks.
|
// Execute Lua on_key callbacks.
|
||||||
@@ -1641,10 +1580,8 @@ int vgetc(void)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Like vgetc(), but never return a NUL when called recursively, get a key
|
||||||
* Like vgetc(), but never return a NUL when called recursively, get a key
|
// directly from the user (ignoring typeahead).
|
||||||
* directly from the user (ignoring typeahead).
|
|
||||||
*/
|
|
||||||
int safe_vgetc(void)
|
int safe_vgetc(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -1656,10 +1593,8 @@ int safe_vgetc(void)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Like safe_vgetc(), but loop to handle K_IGNORE.
|
||||||
* Like safe_vgetc(), but loop to handle K_IGNORE.
|
// Also ignore scrollbar events.
|
||||||
* Also ignore scrollbar events.
|
|
||||||
*/
|
|
||||||
int plain_vgetc(void)
|
int plain_vgetc(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -1672,12 +1607,10 @@ int plain_vgetc(void)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check if a character is available, such that vgetc() will not block.
|
||||||
* Check if a character is available, such that vgetc() will not block.
|
// If the next character is a special character or multi-byte, the returned
|
||||||
* If the next character is a special character or multi-byte, the returned
|
// character is not valid!.
|
||||||
* character is not valid!.
|
// Returns NUL if no character is available.
|
||||||
* Returns NUL if no character is available.
|
|
||||||
*/
|
|
||||||
int vpeekc(void)
|
int vpeekc(void)
|
||||||
{
|
{
|
||||||
if (can_get_old_char()) {
|
if (can_get_old_char()) {
|
||||||
@@ -1686,11 +1619,9 @@ int vpeekc(void)
|
|||||||
return vgetorpeek(false);
|
return vgetorpeek(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check if any character is available, also half an escape sequence.
|
||||||
* Check if any character is available, also half an escape sequence.
|
// Trick: when no typeahead found, but there is something in the typeahead
|
||||||
* Trick: when no typeahead found, but there is something in the typeahead
|
// buffer, it must be an ESC that is recognized as the start of a key code.
|
||||||
* buffer, it must be an ESC that is recognized as the start of a key code.
|
|
||||||
*/
|
|
||||||
int vpeekc_any(void)
|
int vpeekc_any(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -1702,10 +1633,8 @@ int vpeekc_any(void)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Call vpeekc() without causing anything to be mapped.
|
||||||
* Call vpeekc() without causing anything to be mapped.
|
// Return true if a character is available, false otherwise.
|
||||||
* Return true if a character is available, false otherwise.
|
|
||||||
*/
|
|
||||||
int char_avail(void)
|
int char_avail(void)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
@@ -2851,11 +2780,9 @@ int inchar(char_u *buf, int maxlen, long wait_time)
|
|||||||
ui_flush();
|
ui_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Don't reset these when at the hit-return prompt, otherwise an endless
|
||||||
* Don't reset these when at the hit-return prompt, otherwise an endless
|
// recursive loop may result (write error in swapfile, hit-return, timeout
|
||||||
* recursive loop may result (write error in swapfile, hit-return, timeout
|
// on char wait, flush swapfile, write error....).
|
||||||
* on char wait, flush swapfile, write error....).
|
|
||||||
*/
|
|
||||||
if (State != MODE_HITRETURN) {
|
if (State != MODE_HITRETURN) {
|
||||||
did_outofmem_msg = false; // display out of memory message (again)
|
did_outofmem_msg = false; // display out of memory message (again)
|
||||||
did_swapwrite_msg = false; // display swap file write error again
|
did_swapwrite_msg = false; // display swap file write error again
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
/*
|
// hardcopy.c: printing to paper
|
||||||
* hardcopy.c: printing to paper
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -36,64 +34,62 @@
|
|||||||
#include "nvim/version.h"
|
#include "nvim/version.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
|
|
||||||
/*
|
// To implement printing on a platform, the following functions must be
|
||||||
* To implement printing on a platform, the following functions must be
|
// defined:
|
||||||
* defined:
|
//
|
||||||
*
|
// int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
|
||||||
* int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
|
// Called once. Code should display printer dialogue (if appropriate) and
|
||||||
* Called once. Code should display printer dialogue (if appropriate) and
|
// determine printer font and margin settings. Reset has_color if the printer
|
||||||
* determine printer font and margin settings. Reset has_color if the printer
|
// doesn't support colors at all.
|
||||||
* doesn't support colors at all.
|
// Returns FAIL to abort.
|
||||||
* Returns FAIL to abort.
|
//
|
||||||
*
|
// int mch_print_begin(prt_settings_T *settings)
|
||||||
* int mch_print_begin(prt_settings_T *settings)
|
// Called to start the print job.
|
||||||
* Called to start the print job.
|
// Return false to abort.
|
||||||
* Return false to abort.
|
//
|
||||||
*
|
// int mch_print_begin_page(char_u *msg)
|
||||||
* int mch_print_begin_page(char_u *msg)
|
// Called at the start of each page.
|
||||||
* Called at the start of each page.
|
// "msg" indicates the progress of the print job, can be NULL.
|
||||||
* "msg" indicates the progress of the print job, can be NULL.
|
// Return false to abort.
|
||||||
* Return false to abort.
|
//
|
||||||
*
|
// int mch_print_end_page()
|
||||||
* int mch_print_end_page()
|
// Called at the end of each page.
|
||||||
* Called at the end of each page.
|
// Return false to abort.
|
||||||
* Return false to abort.
|
//
|
||||||
*
|
// int mch_print_blank_page()
|
||||||
* int mch_print_blank_page()
|
// Called to generate a blank page for collated, duplex, multiple copy
|
||||||
* Called to generate a blank page for collated, duplex, multiple copy
|
// document. Return false to abort.
|
||||||
* document. Return false to abort.
|
//
|
||||||
*
|
// void mch_print_end(prt_settings_T *psettings)
|
||||||
* void mch_print_end(prt_settings_T *psettings)
|
// Called at normal end of print job.
|
||||||
* Called at normal end of print job.
|
//
|
||||||
*
|
// void mch_print_cleanup()
|
||||||
* void mch_print_cleanup()
|
// Called if print job ends normally or is abandoned. Free any memory, close
|
||||||
* Called if print job ends normally or is abandoned. Free any memory, close
|
// devices and handles. Also called when mch_print_begin() fails, but not
|
||||||
* devices and handles. Also called when mch_print_begin() fails, but not
|
// when mch_print_init() fails.
|
||||||
* when mch_print_init() fails.
|
//
|
||||||
*
|
// void mch_print_set_font(int Bold, int Italic, int Underline);
|
||||||
* void mch_print_set_font(int Bold, int Italic, int Underline);
|
// Called whenever the font style changes.
|
||||||
* Called whenever the font style changes.
|
//
|
||||||
*
|
// void mch_print_set_bg(uint32_t bgcol);
|
||||||
* void mch_print_set_bg(uint32_t bgcol);
|
// Called to set the background color for the following text. Parameter is an
|
||||||
* Called to set the background color for the following text. Parameter is an
|
// RGB value.
|
||||||
* RGB value.
|
//
|
||||||
*
|
// void mch_print_set_fg(uint32_t fgcol);
|
||||||
* void mch_print_set_fg(uint32_t fgcol);
|
// Called to set the foreground color for the following text. Parameter is an
|
||||||
* Called to set the foreground color for the following text. Parameter is an
|
// RGB value.
|
||||||
* RGB value.
|
//
|
||||||
*
|
// mch_print_start_line(int margin, int page_line)
|
||||||
* mch_print_start_line(int margin, int page_line)
|
// Sets the current position at the start of line "page_line".
|
||||||
* Sets the current position at the start of line "page_line".
|
// If margin is true start in the left margin (for header and line number).
|
||||||
* If margin is true start in the left margin (for header and line number).
|
//
|
||||||
*
|
// int mch_print_text_out(char_u *p, size_t len);
|
||||||
* int mch_print_text_out(char_u *p, size_t len);
|
// Output one character of text p[len] at the current position.
|
||||||
* Output one character of text p[len] at the current position.
|
// Return true if there is no room for another character in the same line.
|
||||||
* Return true if there is no room for another character in the same line.
|
//
|
||||||
*
|
// Note that the generic code has no idea of margins. The machine code should
|
||||||
* Note that the generic code has no idea of margins. The machine code should
|
// simply make the page look smaller! The header and the line numbers are
|
||||||
* simply make the page look smaller! The header and the line numbers are
|
// printed in the margin.
|
||||||
* printed in the margin.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static option_table_T printer_opts[OPT_PRINT_NUM_OPTIONS] = {
|
static option_table_T printer_opts[OPT_PRINT_NUM_OPTIONS] = {
|
||||||
{ "top", true, 0, NULL, 0, false },
|
{ "top", true, 0, NULL, 0, false },
|
||||||
@@ -154,9 +150,7 @@ static option_table_T mbfont_opts[OPT_MBFONT_NUM_OPTIONS] =
|
|||||||
{ "o", false, 0, NULL, 0, false },
|
{ "o", false, 0, NULL, 0, false },
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
// These values determine the print position on a page.
|
||||||
* These values determine the print position on a page.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int lead_spaces; // remaining spaces for a TAB
|
int lead_spaces; // remaining spaces for a TAB
|
||||||
int print_pos; // virtual column for computing TABs
|
int print_pos; // virtual column for computing TABs
|
||||||
@@ -255,33 +249,27 @@ struct prt_resfile_buffer_S {
|
|||||||
# include "hardcopy.c.generated.h"
|
# include "hardcopy.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
// Parse 'printoptions' and set the flags in "printer_opts".
|
||||||
* Parse 'printoptions' and set the flags in "printer_opts".
|
// Returns an error message or NULL;
|
||||||
* Returns an error message or NULL;
|
|
||||||
*/
|
|
||||||
char *parse_printoptions(void)
|
char *parse_printoptions(void)
|
||||||
{
|
{
|
||||||
return parse_list_options((char_u *)p_popt, printer_opts, OPT_PRINT_NUM_OPTIONS);
|
return parse_list_options((char_u *)p_popt, printer_opts, OPT_PRINT_NUM_OPTIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Parse 'printoptions' and set the flags in "printer_opts".
|
||||||
* Parse 'printoptions' and set the flags in "printer_opts".
|
// Returns an error message or NULL;
|
||||||
* Returns an error message or NULL;
|
|
||||||
*/
|
|
||||||
char *parse_printmbfont(void)
|
char *parse_printmbfont(void)
|
||||||
{
|
{
|
||||||
return parse_list_options((char_u *)p_pmfn, mbfont_opts, OPT_MBFONT_NUM_OPTIONS);
|
return parse_list_options((char_u *)p_pmfn, mbfont_opts, OPT_MBFONT_NUM_OPTIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Parse a list of options in the form
|
||||||
* Parse a list of options in the form
|
// option:value,option:value,option:value
|
||||||
* option:value,option:value,option:value
|
//
|
||||||
*
|
// "value" can start with a number which is parsed out, e.g. margin:12mm
|
||||||
* "value" can start with a number which is parsed out, e.g. margin:12mm
|
//
|
||||||
*
|
// Returns an error message for an illegal option, NULL otherwise.
|
||||||
* Returns an error message for an illegal option, NULL otherwise.
|
// Only used for the printer at the moment...
|
||||||
* Only used for the printer at the moment...
|
|
||||||
*/
|
|
||||||
static char *parse_list_options(char_u *option_str, option_table_T *table, size_t table_size)
|
static char *parse_list_options(char_u *option_str, option_table_T *table, size_t table_size)
|
||||||
{
|
{
|
||||||
option_table_T *old_opts;
|
option_table_T *old_opts;
|
||||||
@@ -301,9 +289,7 @@ static char *parse_list_options(char_u *option_str, option_table_T *table, size_
|
|||||||
table[idx].present = false;
|
table[idx].present = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Repeat for all comma separated parts.
|
||||||
* Repeat for all comma separated parts.
|
|
||||||
*/
|
|
||||||
stringp = option_str;
|
stringp = option_str;
|
||||||
while (*stringp) {
|
while (*stringp) {
|
||||||
colonp = (char_u *)vim_strchr((char *)stringp, ':');
|
colonp = (char_u *)vim_strchr((char *)stringp, ':');
|
||||||
@@ -361,10 +347,8 @@ static char *parse_list_options(char_u *option_str, option_table_T *table, size_
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If using a dark background, the colors will probably be too bright to show
|
||||||
* If using a dark background, the colors will probably be too bright to show
|
// up well on white paper, so reduce their brightness.
|
||||||
* up well on white paper, so reduce their brightness.
|
|
||||||
*/
|
|
||||||
static uint32_t darken_rgb(uint32_t rgb)
|
static uint32_t darken_rgb(uint32_t rgb)
|
||||||
{
|
{
|
||||||
return ((rgb >> 17) << 16)
|
return ((rgb >> 17) << 16)
|
||||||
@@ -489,9 +473,7 @@ static void prt_line_number(prt_settings_T *const psettings, const int page_line
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get the currently effective header height.
|
||||||
* Get the currently effective header height.
|
|
||||||
*/
|
|
||||||
int prt_header_height(void)
|
int prt_header_height(void)
|
||||||
{
|
{
|
||||||
if (printer_opts[OPT_PRINT_HEADERHEIGHT].present) {
|
if (printer_opts[OPT_PRINT_HEADERHEIGHT].present) {
|
||||||
@@ -507,10 +489,8 @@ int prt_use_number(void)
|
|||||||
&& TOLOWER_ASC(printer_opts[OPT_PRINT_NUMBER].string[0]) == 'y';
|
&& TOLOWER_ASC(printer_opts[OPT_PRINT_NUMBER].string[0]) == 'y';
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return the unit used in a margin item in 'printoptions'.
|
||||||
* Return the unit used in a margin item in 'printoptions'.
|
// Returns PRT_UNIT_NONE if not recognized.
|
||||||
* Returns PRT_UNIT_NONE if not recognized.
|
|
||||||
*/
|
|
||||||
int prt_get_unit(int idx)
|
int prt_get_unit(int idx)
|
||||||
{
|
{
|
||||||
int u = PRT_UNIT_NONE;
|
int u = PRT_UNIT_NONE;
|
||||||
@@ -546,12 +526,10 @@ static void prt_header(prt_settings_T *const psettings, const int pagenum, const
|
|||||||
linenr_T tmp_lnum, tmp_topline, tmp_botline;
|
linenr_T tmp_lnum, tmp_topline, tmp_botline;
|
||||||
int use_sandbox = false;
|
int use_sandbox = false;
|
||||||
|
|
||||||
/*
|
// Need to (temporarily) set current line number and first/last line
|
||||||
* Need to (temporarily) set current line number and first/last line
|
// number on the 'window'. Since we don't know how long the page is,
|
||||||
* number on the 'window'. Since we don't know how long the page is,
|
// set the first and current line number to the top line, and guess
|
||||||
* set the first and current line number to the top line, and guess
|
// that the page length is 64.
|
||||||
* that the page length is 64.
|
|
||||||
*/
|
|
||||||
tmp_lnum = curwin->w_cursor.lnum;
|
tmp_lnum = curwin->w_cursor.lnum;
|
||||||
tmp_topline = curwin->w_topline;
|
tmp_topline = curwin->w_topline;
|
||||||
tmp_botline = curwin->w_botline;
|
tmp_botline = curwin->w_botline;
|
||||||
@@ -606,9 +584,7 @@ static void prt_header(prt_settings_T *const psettings, const int pagenum, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Display a print status message.
|
||||||
* Display a print status message.
|
|
||||||
*/
|
|
||||||
static void prt_message(char_u *s)
|
static void prt_message(char_u *s)
|
||||||
{
|
{
|
||||||
// TODO(bfredl): delete this
|
// TODO(bfredl): delete this
|
||||||
@@ -644,13 +620,11 @@ void ex_hardcopy(exarg_T *eap)
|
|||||||
settings.arguments = (char_u *)eap->arg;
|
settings.arguments = (char_u *)eap->arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Initialise for printing. Ask the user for settings, unless forceit is
|
||||||
* Initialise for printing. Ask the user for settings, unless forceit is
|
// set.
|
||||||
* set.
|
// The mch_print_init() code should set up margins if applicable. (It may
|
||||||
* The mch_print_init() code should set up margins if applicable. (It may
|
// not be a real printer - for example the engine might generate HTML or
|
||||||
* not be a real printer - for example the engine might generate HTML or
|
// PS.)
|
||||||
* PS.)
|
|
||||||
*/
|
|
||||||
if (mch_print_init(&settings,
|
if (mch_print_init(&settings,
|
||||||
curbuf->b_fname == NULL ? (char_u *)buf_spname(curbuf) : curbuf->b_sfname ==
|
curbuf->b_fname == NULL ? (char_u *)buf_spname(curbuf) : curbuf->b_sfname ==
|
||||||
NULL ? (char_u *)curbuf->b_fname : (char_u *)curbuf->b_sfname,
|
NULL ? (char_u *)curbuf->b_fname : (char_u *)curbuf->b_sfname,
|
||||||
@@ -687,9 +661,7 @@ void ex_hardcopy(exarg_T *eap)
|
|||||||
prt_get_attr(id, &settings.number, settings.modec);
|
prt_get_attr(id, &settings.number, settings.modec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Estimate the total lines to be printed
|
||||||
* Estimate the total lines to be printed
|
|
||||||
*/
|
|
||||||
for (lnum = eap->line1; lnum <= eap->line2; lnum++) {
|
for (lnum = eap->line1; lnum <= eap->line2; lnum++) {
|
||||||
bytes_to_print += STRLEN(skipwhite((char *)ml_get(lnum)));
|
bytes_to_print += STRLEN(skipwhite((char *)ml_get(lnum)));
|
||||||
}
|
}
|
||||||
@@ -717,9 +689,7 @@ void ex_hardcopy(exarg_T *eap)
|
|||||||
goto print_fail_no_begin;
|
goto print_fail_no_begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Loop over collated copies: 1 2 3, 1 2 3, ...
|
||||||
* Loop over collated copies: 1 2 3, 1 2 3, ...
|
|
||||||
*/
|
|
||||||
page_count = 0;
|
page_count = 0;
|
||||||
for (collated_copies = 0;
|
for (collated_copies = 0;
|
||||||
collated_copies < settings.n_collated_copies;
|
collated_copies < settings.n_collated_copies;
|
||||||
@@ -740,9 +710,7 @@ void ex_hardcopy(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Loop over all pages in the print job: 1 2 3 ...
|
||||||
* Loop over all pages in the print job: 1 2 3 ...
|
|
||||||
*/
|
|
||||||
for (page_count = 0; prtpos.file_line <= eap->line2; page_count++) {
|
for (page_count = 0; prtpos.file_line <= eap->line2; page_count++) {
|
||||||
// Loop over uncollated copies: 1 1 1, 2 2 2, 3 3 3, ...
|
// Loop over uncollated copies: 1 1 1, 2 2 2, 3 3 3, ...
|
||||||
// For duplex: 12 12 12 34 34 34, ...
|
// For duplex: 12 12 12 34 34 34, ...
|
||||||
@@ -752,9 +720,7 @@ void ex_hardcopy(exarg_T *eap)
|
|||||||
// Set the print position to the start of this page.
|
// Set the print position to the start of this page.
|
||||||
prtpos = page_prtpos;
|
prtpos = page_prtpos;
|
||||||
|
|
||||||
/*
|
// Do front and rear side of a page.
|
||||||
* Do front and rear side of a page.
|
|
||||||
*/
|
|
||||||
for (side = 0; side <= settings.duplex; side++) {
|
for (side = 0; side <= settings.duplex; side++) {
|
||||||
// Print one page.
|
// Print one page.
|
||||||
|
|
||||||
@@ -780,9 +746,7 @@ void ex_hardcopy(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
prt_message(IObuff);
|
prt_message(IObuff);
|
||||||
|
|
||||||
/*
|
// Output header if required
|
||||||
* Output header if required
|
|
||||||
*/
|
|
||||||
if (prt_header_height() > 0) {
|
if (prt_header_height() > 0) {
|
||||||
prt_header(&settings, page_count + 1 + side,
|
prt_header(&settings, page_count + 1 + side,
|
||||||
prtpos.file_line);
|
prtpos.file_line);
|
||||||
@@ -814,10 +778,8 @@ void ex_hardcopy(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Extra blank page for duplexing with odd number of pages and
|
||||||
* Extra blank page for duplexing with odd number of pages and
|
// more copies to come.
|
||||||
* more copies to come.
|
|
||||||
*/
|
|
||||||
if (prtpos.file_line > eap->line2 && settings.duplex
|
if (prtpos.file_line > eap->line2 && settings.duplex
|
||||||
&& side == 0
|
&& side == 0
|
||||||
&& uncollated_copies + 1 < settings.n_uncollated_copies) {
|
&& uncollated_copies + 1 < settings.n_uncollated_copies) {
|
||||||
@@ -850,10 +812,8 @@ print_fail_no_begin:
|
|||||||
mch_print_cleanup();
|
mch_print_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Print one page line.
|
||||||
* Print one page line.
|
// Return the next column to print, or zero if the line is finished.
|
||||||
* Return the next column to print, or zero if the line is finished.
|
|
||||||
*/
|
|
||||||
static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T *ppos)
|
static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T *ppos)
|
||||||
{
|
{
|
||||||
colnr_T col;
|
colnr_T col;
|
||||||
@@ -881,9 +841,7 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
|
|||||||
mch_print_start_line(false, page_line);
|
mch_print_start_line(false, page_line);
|
||||||
line = (char_u *)ml_get(ppos->file_line);
|
line = (char_u *)ml_get(ppos->file_line);
|
||||||
|
|
||||||
/*
|
// Loop over the columns until the end of the file line or right margin.
|
||||||
* Loop over the columns until the end of the file line or right margin.
|
|
||||||
*/
|
|
||||||
for (col = ppos->column; line[col] != NUL && !need_break; col += outputlen) {
|
for (col = ppos->column; line[col] != NUL && !need_break; col += outputlen) {
|
||||||
if ((outputlen = utfc_ptr2len((char *)line + col)) < 1) {
|
if ((outputlen = utfc_ptr2len((char *)line + col)) < 1) {
|
||||||
outputlen = 1;
|
outputlen = 1;
|
||||||
@@ -908,9 +866,7 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Appropriately expand any tabs to spaces.
|
||||||
* Appropriately expand any tabs to spaces.
|
|
||||||
*/
|
|
||||||
if (line[col] == TAB || tab_spaces != 0) {
|
if (line[col] == TAB || tab_spaces != 0) {
|
||||||
if (tab_spaces == 0) {
|
if (tab_spaces == 0) {
|
||||||
tab_spaces = tabstop_padding(print_pos,
|
tab_spaces = tabstop_padding(print_pos,
|
||||||
@@ -945,10 +901,8 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
|
|||||||
ppos->lead_spaces = tab_spaces;
|
ppos->lead_spaces = tab_spaces;
|
||||||
ppos->print_pos = print_pos;
|
ppos->print_pos = print_pos;
|
||||||
|
|
||||||
/*
|
// Start next line of file if we clip lines, or have reached end of the
|
||||||
* Start next line of file if we clip lines, or have reached end of the
|
// line, unless we are doing a formfeed.
|
||||||
* line, unless we are doing a formfeed.
|
|
||||||
*/
|
|
||||||
if (!ppos->ff
|
if (!ppos->ff
|
||||||
&& (line[col] == NUL
|
&& (line[col] == NUL
|
||||||
|| (printer_opts[OPT_PRINT_WRAP].present
|
|| (printer_opts[OPT_PRINT_WRAP].present
|
||||||
@@ -959,34 +913,32 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
|
|||||||
return col;
|
return col;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// PS printer stuff.
|
||||||
* PS printer stuff.
|
//
|
||||||
*
|
// Sources of information to help maintain the PS printing code:
|
||||||
* Sources of information to help maintain the PS printing code:
|
//
|
||||||
*
|
// 1. PostScript Language Reference, 3rd Edition,
|
||||||
* 1. PostScript Language Reference, 3rd Edition,
|
// Addison-Wesley, 1999, ISBN 0-201-37922-8
|
||||||
* Addison-Wesley, 1999, ISBN 0-201-37922-8
|
// 2. PostScript Language Program Design,
|
||||||
* 2. PostScript Language Program Design,
|
// Addison-Wesley, 1988, ISBN 0-201-14396-8
|
||||||
* Addison-Wesley, 1988, ISBN 0-201-14396-8
|
// 3. PostScript Tutorial and Cookbook,
|
||||||
* 3. PostScript Tutorial and Cookbook,
|
// Addison Wesley, 1985, ISBN 0-201-10179-3
|
||||||
* Addison Wesley, 1985, ISBN 0-201-10179-3
|
// 4. PostScript Language Document Structuring Conventions Specification,
|
||||||
* 4. PostScript Language Document Structuring Conventions Specification,
|
// version 3.0,
|
||||||
* version 3.0,
|
// Adobe Technote 5001, 25th September 1992
|
||||||
* Adobe Technote 5001, 25th September 1992
|
// 5. PostScript Printer Description File Format Specification, Version 4.3,
|
||||||
* 5. PostScript Printer Description File Format Specification, Version 4.3,
|
// Adobe technote 5003, 9th February 1996
|
||||||
* Adobe technote 5003, 9th February 1996
|
// 6. Adobe Font Metrics File Format Specification, Version 4.1,
|
||||||
* 6. Adobe Font Metrics File Format Specification, Version 4.1,
|
// Adobe Technote 5007, 7th October 1998
|
||||||
* Adobe Technote 5007, 7th October 1998
|
// 7. Adobe CMap and CIDFont Files Specification, Version 1.0,
|
||||||
* 7. Adobe CMap and CIDFont Files Specification, Version 1.0,
|
// Adobe Technote 5014, 8th October 1996
|
||||||
* Adobe Technote 5014, 8th October 1996
|
// 8. Adobe CJKV Character Collections and CMaps for CID-Keyed Fonts,
|
||||||
* 8. Adobe CJKV Character Collections and CMaps for CID-Keyed Fonts,
|
// Adoboe Technote 5094, 8th September, 2001
|
||||||
* Adoboe Technote 5094, 8th September, 2001
|
// 9. CJKV Information Processing, 2nd Edition,
|
||||||
* 9. CJKV Information Processing, 2nd Edition,
|
// O'Reilly, 2002, ISBN 1-56592-224-7
|
||||||
* O'Reilly, 2002, ISBN 1-56592-224-7
|
//
|
||||||
*
|
// Some of these documents can be found in PDF form on Adobe's web site -
|
||||||
* Some of these documents can be found in PDF form on Adobe's web site -
|
// http://www.adobe.com
|
||||||
* http://www.adobe.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PRT_PS_DEFAULT_DPI (72) // Default user space resolution
|
#define PRT_PS_DEFAULT_DPI (72) // Default user space resolution
|
||||||
#define PRT_PS_DEFAULT_FONTSIZE (10)
|
#define PRT_PS_DEFAULT_FONTSIZE (10)
|
||||||
@@ -1251,17 +1203,13 @@ static struct prt_dsc_comment_S prt_dsc_table[] =
|
|||||||
PRT_DSC_ENDCOMMENTS_TYPE }
|
PRT_DSC_ENDCOMMENTS_TYPE }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
// Variables for the output PostScript file.
|
||||||
* Variables for the output PostScript file.
|
|
||||||
*/
|
|
||||||
static FILE *prt_ps_fd;
|
static FILE *prt_ps_fd;
|
||||||
static bool prt_file_error;
|
static bool prt_file_error;
|
||||||
static char_u *prt_ps_file_name = NULL;
|
static char_u *prt_ps_file_name = NULL;
|
||||||
|
|
||||||
/*
|
// Various offsets and dimensions in default PostScript user space (points).
|
||||||
* Various offsets and dimensions in default PostScript user space (points).
|
// Used for text positioning calculations
|
||||||
* Used for text positioning calculations
|
|
||||||
*/
|
|
||||||
static double prt_page_width;
|
static double prt_page_width;
|
||||||
static double prt_page_height;
|
static double prt_page_height;
|
||||||
static double prt_left_margin;
|
static double prt_left_margin;
|
||||||
@@ -1276,10 +1224,8 @@ static double prt_bgcol_offset;
|
|||||||
static double prt_pos_x_moveto = 0.0;
|
static double prt_pos_x_moveto = 0.0;
|
||||||
static double prt_pos_y_moveto = 0.0;
|
static double prt_pos_y_moveto = 0.0;
|
||||||
|
|
||||||
/*
|
// Various control variables used to decide when and how to change the
|
||||||
* Various control variables used to decide when and how to change the
|
// PostScript graphics state.
|
||||||
* PostScript graphics state.
|
|
||||||
*/
|
|
||||||
static bool prt_need_moveto;
|
static bool prt_need_moveto;
|
||||||
static bool prt_do_moveto;
|
static bool prt_do_moveto;
|
||||||
static bool prt_need_font;
|
static bool prt_need_font;
|
||||||
@@ -1298,9 +1244,7 @@ static double prt_text_run;
|
|||||||
static int prt_page_num;
|
static int prt_page_num;
|
||||||
static int prt_bufsiz;
|
static int prt_bufsiz;
|
||||||
|
|
||||||
/*
|
// Variables controlling physical printing.
|
||||||
* Variables controlling physical printing.
|
|
||||||
*/
|
|
||||||
static int prt_media;
|
static int prt_media;
|
||||||
static int prt_portrait;
|
static int prt_portrait;
|
||||||
static int prt_num_copies;
|
static int prt_num_copies;
|
||||||
@@ -1308,9 +1252,7 @@ static int prt_duplex;
|
|||||||
static int prt_tumble;
|
static int prt_tumble;
|
||||||
static int prt_collate;
|
static int prt_collate;
|
||||||
|
|
||||||
/*
|
// Buffers used when generating PostScript output
|
||||||
* Buffers used when generating PostScript output
|
|
||||||
*/
|
|
||||||
static char prt_line_buffer[257];
|
static char prt_line_buffer[257];
|
||||||
static garray_T prt_ps_buffer = GA_EMPTY_INIT_VALUE;
|
static garray_T prt_ps_buffer = GA_EMPTY_INIT_VALUE;
|
||||||
|
|
||||||
@@ -1345,36 +1287,28 @@ static void prt_write_file_len(char_u *buffer, size_t bytes)
|
|||||||
prt_write_file_raw_len(buffer, bytes);
|
prt_write_file_raw_len(buffer, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Write a string.
|
||||||
* Write a string.
|
|
||||||
*/
|
|
||||||
static void prt_write_string(char *s)
|
static void prt_write_string(char *s)
|
||||||
{
|
{
|
||||||
vim_snprintf(prt_line_buffer, sizeof(prt_line_buffer), "%s", s);
|
vim_snprintf(prt_line_buffer, sizeof(prt_line_buffer), "%s", s);
|
||||||
prt_write_file(prt_line_buffer);
|
prt_write_file(prt_line_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Write an int and a space.
|
||||||
* Write an int and a space.
|
|
||||||
*/
|
|
||||||
static void prt_write_int(int i)
|
static void prt_write_int(int i)
|
||||||
{
|
{
|
||||||
snprintf(prt_line_buffer, sizeof(prt_line_buffer), "%d ", i);
|
snprintf(prt_line_buffer, sizeof(prt_line_buffer), "%d ", i);
|
||||||
prt_write_file(prt_line_buffer);
|
prt_write_file(prt_line_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Write a boolean and a space.
|
||||||
* Write a boolean and a space.
|
|
||||||
*/
|
|
||||||
static void prt_write_boolean(int b)
|
static void prt_write_boolean(int b)
|
||||||
{
|
{
|
||||||
snprintf(prt_line_buffer, sizeof(prt_line_buffer), "%s ", (b ? "T" : "F"));
|
snprintf(prt_line_buffer, sizeof(prt_line_buffer), "%s ", (b ? "T" : "F"));
|
||||||
prt_write_file(prt_line_buffer);
|
prt_write_file(prt_line_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Write PostScript to re-encode and define the font.
|
||||||
* Write PostScript to re-encode and define the font.
|
|
||||||
*/
|
|
||||||
static void prt_def_font(char *new_name, char *encoding, int height, char *font)
|
static void prt_def_font(char *new_name, char *encoding, int height, char *font)
|
||||||
{
|
{
|
||||||
vim_snprintf(prt_line_buffer, sizeof(prt_line_buffer),
|
vim_snprintf(prt_line_buffer, sizeof(prt_line_buffer),
|
||||||
@@ -1390,9 +1324,7 @@ static void prt_def_font(char *new_name, char *encoding, int height, char *font)
|
|||||||
prt_write_file(prt_line_buffer);
|
prt_write_file(prt_line_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Write a line to define the CID font.
|
||||||
* Write a line to define the CID font.
|
|
||||||
*/
|
|
||||||
static void prt_def_cidfont(char *new_name, int height, char *cidfont)
|
static void prt_def_cidfont(char *new_name, int height, char *cidfont)
|
||||||
{
|
{
|
||||||
vim_snprintf(prt_line_buffer, sizeof(prt_line_buffer),
|
vim_snprintf(prt_line_buffer, sizeof(prt_line_buffer),
|
||||||
@@ -1403,9 +1335,7 @@ static void prt_def_cidfont(char *new_name, int height, char *cidfont)
|
|||||||
prt_write_file(prt_line_buffer);
|
prt_write_file(prt_line_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Write a line to define a duplicate of a CID font
|
||||||
* Write a line to define a duplicate of a CID font
|
|
||||||
*/
|
|
||||||
static void prt_dup_cidfont(char *original_name, char *new_name)
|
static void prt_dup_cidfont(char *original_name, char *new_name)
|
||||||
{
|
{
|
||||||
vim_snprintf(prt_line_buffer, sizeof(prt_line_buffer),
|
vim_snprintf(prt_line_buffer, sizeof(prt_line_buffer),
|
||||||
@@ -1413,11 +1343,9 @@ static void prt_dup_cidfont(char *original_name, char *new_name)
|
|||||||
prt_write_file(prt_line_buffer);
|
prt_write_file(prt_line_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Convert a real value into an integer and fractional part as integers, with
|
||||||
* Convert a real value into an integer and fractional part as integers, with
|
// the fractional part being in the range [0,10^precision). The fractional part
|
||||||
* the fractional part being in the range [0,10^precision). The fractional part
|
// is also rounded based on the precision + 1'th fractional digit.
|
||||||
* is also rounded based on the precision + 1'th fractional digit.
|
|
||||||
*/
|
|
||||||
static void prt_real_bits(double real, int precision, int *pinteger, int *pfraction)
|
static void prt_real_bits(double real, int precision, int *pinteger, int *pfraction)
|
||||||
{
|
{
|
||||||
int integer = (int)real;
|
int integer = (int)real;
|
||||||
@@ -1433,11 +1361,9 @@ static void prt_real_bits(double real, int precision, int *pinteger, int *pfract
|
|||||||
*pfraction = (int)(fraction + 0.5);
|
*pfraction = (int)(fraction + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Write a real and a space. Save bytes if real value has no fractional part!
|
||||||
* Write a real and a space. Save bytes if real value has no fractional part!
|
// We use prt_real_bits() as %f in sprintf uses the locale setting to decide
|
||||||
* We use prt_real_bits() as %f in sprintf uses the locale setting to decide
|
// what decimal point character to use, but PS always requires a '.'.
|
||||||
* what decimal point character to use, but PS always requires a '.'.
|
|
||||||
*/
|
|
||||||
static void prt_write_real(double val, int prec)
|
static void prt_write_real(double val, int prec)
|
||||||
{
|
{
|
||||||
int integer;
|
int integer;
|
||||||
@@ -1463,9 +1389,7 @@ static void prt_write_real(double val, int prec)
|
|||||||
prt_write_file(prt_line_buffer);
|
prt_write_file(prt_line_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Write a line to define a numeric variable.
|
||||||
* Write a line to define a numeric variable.
|
|
||||||
*/
|
|
||||||
static void prt_def_var(char *name, double value, int prec)
|
static void prt_def_var(char *name, double value, int prec)
|
||||||
{
|
{
|
||||||
vim_snprintf(prt_line_buffer, sizeof(prt_line_buffer),
|
vim_snprintf(prt_line_buffer, sizeof(prt_line_buffer),
|
||||||
@@ -2020,9 +1944,7 @@ static double to_device_units(int idx, double physsize, int def_number)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Calculate margins for given width and height from printoptions settings.
|
||||||
* Calculate margins for given width and height from printoptions settings.
|
|
||||||
*/
|
|
||||||
static void prt_page_margins(double width, double height, double *left, double *right, double *top,
|
static void prt_page_margins(double width, double height, double *left, double *right, double *top,
|
||||||
double *bottom)
|
double *bottom)
|
||||||
{
|
{
|
||||||
@@ -2062,18 +1984,14 @@ static void prt_build_cid_fontname(int font, char_u *name, int name_len)
|
|||||||
prt_ps_mb_font.ps_fontname[font] = fontname;
|
prt_ps_mb_font.ps_fontname[font] = fontname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get number of lines of text that fit on a page (excluding the header).
|
||||||
* Get number of lines of text that fit on a page (excluding the header).
|
|
||||||
*/
|
|
||||||
static int prt_get_lpp(void)
|
static int prt_get_lpp(void)
|
||||||
{
|
{
|
||||||
int lpp;
|
int lpp;
|
||||||
|
|
||||||
/*
|
// Calculate offset to lower left corner of background rect based on actual
|
||||||
* Calculate offset to lower left corner of background rect based on actual
|
// font height (based on its bounding box) and the line height, handling the
|
||||||
* font height (based on its bounding box) and the line height, handling the
|
// case where the font height can exceed the line height.
|
||||||
* case where the font height can exceed the line height.
|
|
||||||
*/
|
|
||||||
prt_bgcol_offset = PRT_PS_FONT_TO_USER(prt_line_height,
|
prt_bgcol_offset = PRT_PS_FONT_TO_USER(prt_line_height,
|
||||||
prt_ps_font->bbox_min_y);
|
prt_ps_font->bbox_min_y);
|
||||||
if ((prt_ps_font->bbox_max_y - prt_ps_font->bbox_min_y) < 1000.0) {
|
if ((prt_ps_font->bbox_max_y - prt_ps_font->bbox_min_y) < 1000.0) {
|
||||||
@@ -2270,9 +2188,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
|
|||||||
prt_ps_font = &prt_ps_courier_font;
|
prt_ps_font = &prt_ps_courier_font;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Find the size of the paper and set the margins.
|
||||||
* Find the size of the paper and set the margins.
|
|
||||||
*/
|
|
||||||
prt_portrait = (!printer_opts[OPT_PRINT_PORTRAIT].present
|
prt_portrait = (!printer_opts[OPT_PRINT_PORTRAIT].present
|
||||||
|| TOLOWER_ASC(printer_opts[OPT_PRINT_PORTRAIT].string[0]) ==
|
|| TOLOWER_ASC(printer_opts[OPT_PRINT_PORTRAIT].string[0]) ==
|
||||||
'y');
|
'y');
|
||||||
@@ -2295,13 +2211,11 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
|
|||||||
}
|
}
|
||||||
prt_media = i;
|
prt_media = i;
|
||||||
|
|
||||||
/*
|
// Set PS pagesize based on media dimensions and print orientation.
|
||||||
* Set PS pagesize based on media dimensions and print orientation.
|
// Note: Media and page sizes have defined meanings in PostScript and should
|
||||||
* Note: Media and page sizes have defined meanings in PostScript and should
|
// be kept distinct. Media is the paper (or transparency, or ...) that is
|
||||||
* be kept distinct. Media is the paper (or transparency, or ...) that is
|
// printed on, whereas the page size is the area that the PostScript
|
||||||
* printed on, whereas the page size is the area that the PostScript
|
// interpreter renders into.
|
||||||
* interpreter renders into.
|
|
||||||
*/
|
|
||||||
if (prt_portrait) {
|
if (prt_portrait) {
|
||||||
prt_page_width = prt_mediasize[i].width;
|
prt_page_width = prt_mediasize[i].width;
|
||||||
prt_page_height = prt_mediasize[i].height;
|
prt_page_height = prt_mediasize[i].height;
|
||||||
@@ -2320,9 +2234,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
|
|||||||
prt_top_margin = top;
|
prt_top_margin = top;
|
||||||
prt_bottom_margin = bottom;
|
prt_bottom_margin = bottom;
|
||||||
|
|
||||||
/*
|
// Set up the font size.
|
||||||
* Set up the font size.
|
|
||||||
*/
|
|
||||||
fontsize = PRT_PS_DEFAULT_FONTSIZE;
|
fontsize = PRT_PS_DEFAULT_FONTSIZE;
|
||||||
for (p = (char_u *)p_pfn; (p = (char_u *)vim_strchr((char *)p, ':')) != NULL; p++) {
|
for (p = (char_u *)p_pfn; (p = (char_u *)vim_strchr((char *)p, ':')) != NULL; p++) {
|
||||||
if (p[1] == 'h' && ascii_isdigit(p[2])) {
|
if (p[1] == 'h' && ascii_isdigit(p[2])) {
|
||||||
@@ -2331,10 +2243,8 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
|
|||||||
}
|
}
|
||||||
prt_font_metrics(fontsize);
|
prt_font_metrics(fontsize);
|
||||||
|
|
||||||
/*
|
// Return the number of characters per line, and lines per page for the
|
||||||
* Return the number of characters per line, and lines per page for the
|
// generic print code.
|
||||||
* generic print code.
|
|
||||||
*/
|
|
||||||
psettings->chars_per_line = prt_get_cpl();
|
psettings->chars_per_line = prt_get_cpl();
|
||||||
psettings->lines_per_page = prt_get_lpp();
|
psettings->lines_per_page = prt_get_lpp();
|
||||||
|
|
||||||
@@ -2343,12 +2253,10 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Sort out the number of copies to be printed. PS by default will do
|
||||||
* Sort out the number of copies to be printed. PS by default will do
|
// uncollated copies for you, so once we know how many uncollated copies are
|
||||||
* uncollated copies for you, so once we know how many uncollated copies are
|
// wanted cache it away and lie to the generic code that we only want one
|
||||||
* wanted cache it away and lie to the generic code that we only want one
|
// uncollated copy.
|
||||||
* uncollated copy.
|
|
||||||
*/
|
|
||||||
psettings->n_collated_copies = 1;
|
psettings->n_collated_copies = 1;
|
||||||
psettings->n_uncollated_copies = 1;
|
psettings->n_uncollated_copies = 1;
|
||||||
prt_num_copies = 1;
|
prt_num_copies = 1;
|
||||||
@@ -2364,10 +2272,8 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
|
|||||||
|
|
||||||
psettings->jobname = jobname;
|
psettings->jobname = jobname;
|
||||||
|
|
||||||
/*
|
// Set up printer duplex and tumble based on Duplex option setting - default
|
||||||
* Set up printer duplex and tumble based on Duplex option setting - default
|
// is long sided duplex printing (i.e. no tumble).
|
||||||
* is long sided duplex printing (i.e. no tumble).
|
|
||||||
*/
|
|
||||||
prt_duplex = true;
|
prt_duplex = true;
|
||||||
prt_tumble = false;
|
prt_tumble = false;
|
||||||
psettings->duplex = 1;
|
psettings->duplex = 1;
|
||||||
@@ -2491,9 +2397,7 @@ bool mch_print_begin(prt_settings_T *psettings)
|
|||||||
struct prt_ps_resource_S res_cidfont;
|
struct prt_ps_resource_S res_cidfont;
|
||||||
struct prt_ps_resource_S res_cmap;
|
struct prt_ps_resource_S res_cmap;
|
||||||
|
|
||||||
/*
|
// PS DSC Header comments - no PS code!
|
||||||
* PS DSC Header comments - no PS code!
|
|
||||||
*/
|
|
||||||
prt_dsc_start();
|
prt_dsc_start();
|
||||||
prt_dsc_textline("Title", (char *)psettings->jobname);
|
prt_dsc_textline("Title", (char *)psettings->jobname);
|
||||||
if (os_get_username(buffer, 256) == FAIL) {
|
if (os_get_username(buffer, 256) == FAIL) {
|
||||||
@@ -2685,9 +2589,7 @@ bool mch_print_begin(prt_settings_T *psettings)
|
|||||||
prt_num_copies);
|
prt_num_copies);
|
||||||
prt_dsc_noarg("EndComments");
|
prt_dsc_noarg("EndComments");
|
||||||
|
|
||||||
/*
|
// PS Document page defaults
|
||||||
* PS Document page defaults
|
|
||||||
*/
|
|
||||||
prt_dsc_noarg("BeginDefaults");
|
prt_dsc_noarg("BeginDefaults");
|
||||||
|
|
||||||
// List font resources most likely common to all pages
|
// List font resources most likely common to all pages
|
||||||
@@ -2707,9 +2609,7 @@ bool mch_print_begin(prt_settings_T *psettings)
|
|||||||
|
|
||||||
prt_dsc_noarg("EndDefaults");
|
prt_dsc_noarg("EndDefaults");
|
||||||
|
|
||||||
/*
|
// PS Document prolog inclusion - all required procsets.
|
||||||
* PS Document prolog inclusion - all required procsets.
|
|
||||||
*/
|
|
||||||
prt_dsc_noarg("BeginProlog");
|
prt_dsc_noarg("BeginProlog");
|
||||||
|
|
||||||
// Add required procsets - NOTE: order is important!
|
// Add required procsets - NOTE: order is important!
|
||||||
@@ -2736,9 +2636,7 @@ bool mch_print_begin(prt_settings_T *psettings)
|
|||||||
|
|
||||||
prt_dsc_noarg("EndProlog");
|
prt_dsc_noarg("EndProlog");
|
||||||
|
|
||||||
/*
|
// PS Document setup - must appear after the prolog
|
||||||
* PS Document setup - must appear after the prolog
|
|
||||||
*/
|
|
||||||
prt_dsc_noarg("BeginSetup");
|
prt_dsc_noarg("BeginSetup");
|
||||||
|
|
||||||
// Device setup - page size and number of uncollated copies
|
// Device setup - page size and number of uncollated copies
|
||||||
@@ -2847,9 +2745,7 @@ void mch_print_end(prt_settings_T *psettings)
|
|||||||
{
|
{
|
||||||
prt_dsc_noarg("Trailer");
|
prt_dsc_noarg("Trailer");
|
||||||
|
|
||||||
/*
|
// Output any info we don't know in toto until we finish
|
||||||
* Output any info we don't know in toto until we finish
|
|
||||||
*/
|
|
||||||
prt_dsc_ints("Pages", 1, &prt_page_num);
|
prt_dsc_ints("Pages", 1, &prt_page_num);
|
||||||
|
|
||||||
prt_dsc_noarg("EOF");
|
prt_dsc_noarg("EOF");
|
||||||
|
@@ -8,9 +8,7 @@
|
|||||||
#include "nvim/globals.h" // for TriState
|
#include "nvim/globals.h" // for TriState
|
||||||
#include "nvim/types.h" // for char_u
|
#include "nvim/types.h" // for char_u
|
||||||
|
|
||||||
/*
|
// Structure to hold printing color and font attributes.
|
||||||
* Structure to hold printing color and font attributes.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t fg_color;
|
uint32_t fg_color;
|
||||||
uint32_t bg_color;
|
uint32_t bg_color;
|
||||||
@@ -23,9 +21,7 @@ typedef struct {
|
|||||||
int underdashed;
|
int underdashed;
|
||||||
} prt_text_attr_T;
|
} prt_text_attr_T;
|
||||||
|
|
||||||
/*
|
// Structure passed back to the generic printer code.
|
||||||
* Structure passed back to the generic printer code.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int n_collated_copies;
|
int n_collated_copies;
|
||||||
int n_uncollated_copies;
|
int n_uncollated_copies;
|
||||||
@@ -42,9 +38,7 @@ typedef struct {
|
|||||||
char_u *arguments;
|
char_u *arguments;
|
||||||
} prt_settings_T;
|
} prt_settings_T;
|
||||||
|
|
||||||
/*
|
// Generic option table item, only used for printer at the moment.
|
||||||
* Generic option table item, only used for printer at the moment.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
int hasnum;
|
int hasnum;
|
||||||
|
@@ -1,13 +1,11 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
/*
|
// CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
|
||||||
* CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
|
// Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
|
||||||
* Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
|
//
|
||||||
*
|
// The basic idea/structure of cscope for Vim was borrowed from Nvi. There
|
||||||
* The basic idea/structure of cscope for Vim was borrowed from Nvi. There
|
// might be a few lines of code that look similar to what Nvi has.
|
||||||
* might be a few lines of code that look similar to what Nvi has.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -78,10 +76,8 @@ static enum {
|
|||||||
EXP_CSCOPE_KILL, // expand ":cscope kill" arguments
|
EXP_CSCOPE_KILL, // expand ":cscope kill" arguments
|
||||||
} expand_what;
|
} expand_what;
|
||||||
|
|
||||||
/*
|
// Function given to ExpandGeneric() to obtain the cscope command
|
||||||
* Function given to ExpandGeneric() to obtain the cscope command
|
// expansion.
|
||||||
* expansion.
|
|
||||||
*/
|
|
||||||
char *get_cscope_name(expand_T *xp, int idx)
|
char *get_cscope_name(expand_T *xp, int idx)
|
||||||
{
|
{
|
||||||
int current_idx;
|
int current_idx;
|
||||||
@@ -140,9 +136,7 @@ char *get_cscope_name(expand_T *xp, int idx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Handle command line completion for :cscope command.
|
||||||
* Handle command line completion for :cscope command.
|
|
||||||
*/
|
|
||||||
void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx)
|
void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx)
|
||||||
{
|
{
|
||||||
// Default: expand subcommands.
|
// Default: expand subcommands.
|
||||||
@@ -304,33 +298,31 @@ void cs_print_tags(void)
|
|||||||
cs_manage_matches(NULL, NULL, 0, Print);
|
cs_manage_matches(NULL, NULL, 0, Print);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
|
||||||
* "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
|
//
|
||||||
*
|
// Checks for the existence of a |cscope| connection. If no
|
||||||
* Checks for the existence of a |cscope| connection. If no
|
// parameters are specified, then the function returns:
|
||||||
* parameters are specified, then the function returns:
|
//
|
||||||
*
|
// 0, if cscope was not available (not compiled in), or if there
|
||||||
* 0, if cscope was not available (not compiled in), or if there
|
// are no cscope connections; or
|
||||||
* are no cscope connections; or
|
// 1, if there is at least one cscope connection.
|
||||||
* 1, if there is at least one cscope connection.
|
//
|
||||||
*
|
// If parameters are specified, then the value of {num}
|
||||||
* If parameters are specified, then the value of {num}
|
// determines how existence of a cscope connection is checked:
|
||||||
* determines how existence of a cscope connection is checked:
|
//
|
||||||
*
|
// {num} Description of existence check
|
||||||
* {num} Description of existence check
|
// ----- ------------------------------
|
||||||
* ----- ------------------------------
|
// 0 Same as no parameters (e.g., "cscope_connection()").
|
||||||
* 0 Same as no parameters (e.g., "cscope_connection()").
|
// 1 Ignore {prepend}, and use partial string matches for
|
||||||
* 1 Ignore {prepend}, and use partial string matches for
|
// {dbpath}.
|
||||||
* {dbpath}.
|
// 2 Ignore {prepend}, and use exact string matches for
|
||||||
* 2 Ignore {prepend}, and use exact string matches for
|
// {dbpath}.
|
||||||
* {dbpath}.
|
// 3 Use {prepend}, use partial string matches for both
|
||||||
* 3 Use {prepend}, use partial string matches for both
|
// {dbpath} and {prepend}.
|
||||||
* {dbpath} and {prepend}.
|
// 4 Use {prepend}, use exact string matches for both
|
||||||
* 4 Use {prepend}, use exact string matches for both
|
// {dbpath} and {prepend}.
|
||||||
* {dbpath} and {prepend}.
|
//
|
||||||
*
|
// Note: All string comparisons are case sensitive!
|
||||||
* Note: All string comparisons are case sensitive!
|
|
||||||
*/
|
|
||||||
bool cs_connection(int num, char_u *dbpath, char_u *ppath)
|
bool cs_connection(int num, char_u *dbpath, char_u *ppath)
|
||||||
{
|
{
|
||||||
if (num < 0 || num > 4 || (num > 0 && !dbpath)) {
|
if (num < 0 || num > 4 || (num > 0 && !dbpath)) {
|
||||||
@@ -379,9 +371,8 @@ bool cs_connection(int num, char_u *dbpath, char_u *ppath)
|
|||||||
return false;
|
return false;
|
||||||
} // cs_connection
|
} // cs_connection
|
||||||
|
|
||||||
/*
|
// PRIVATE functions
|
||||||
* PRIVATE functions
|
// **************************************************************************
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/// Add cscope database or a directory name (to look for cscope.out)
|
/// Add cscope database or a directory name (to look for cscope.out)
|
||||||
/// to the cscope connection list.
|
/// to the cscope connection list.
|
||||||
@@ -684,10 +675,8 @@ static int cs_create_connection(size_t i)
|
|||||||
char *prog, *cmd, *ppath = NULL;
|
char *prog, *cmd, *ppath = NULL;
|
||||||
|
|
||||||
#if defined(UNIX)
|
#if defined(UNIX)
|
||||||
/*
|
// Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from
|
||||||
* Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from
|
// from_cs[0] and writes to to_cs[1].
|
||||||
* from_cs[0] and writes to to_cs[1].
|
|
||||||
*/
|
|
||||||
to_cs[0] = to_cs[1] = from_cs[0] = from_cs[1] = -1;
|
to_cs[0] = to_cs[1] = from_cs[0] = from_cs[1] = -1;
|
||||||
if (pipe(to_cs) < 0 || pipe(from_cs) < 0) {
|
if (pipe(to_cs) < 0 || pipe(from_cs) < 0) {
|
||||||
(void)emsg(_("E566: Could not create cscope pipes"));
|
(void)emsg(_("E566: Could not create cscope pipes"));
|
||||||
@@ -896,10 +885,8 @@ static int cs_find(exarg_T *eap)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Let's replace the NULs written by strtok() with spaces - we need the
|
||||||
* Let's replace the NULs written by strtok() with spaces - we need the
|
// spaces to correctly display the quickfix/location list window's title.
|
||||||
* spaces to correctly display the quickfix/location list window's title.
|
|
||||||
*/
|
|
||||||
for (int i = 0; i < eap_arg_len; i++) {
|
for (int i = 0; i < eap_arg_len; i++) {
|
||||||
if (NUL == eap->arg[i]) {
|
if (NUL == eap->arg[i]) {
|
||||||
eap->arg[i] = ' ';
|
eap->arg[i] = ' ';
|
||||||
@@ -1041,10 +1028,8 @@ static bool cs_find_common(char *opt, char *pat, int forceit, int verbose, bool
|
|||||||
|
|
||||||
apply_autocmds(EVENT_QUICKFIXCMDPOST, "cscope", curbuf->b_fname, true, curbuf);
|
apply_autocmds(EVENT_QUICKFIXCMDPOST, "cscope", curbuf->b_fname, true, curbuf);
|
||||||
if (use_ll) {
|
if (use_ll) {
|
||||||
/*
|
// In the location list window, use the displayed location
|
||||||
* In the location list window, use the displayed location
|
// list. Otherwise, use the location list for the window.
|
||||||
* list. Otherwise, use the location list for the window.
|
|
||||||
*/
|
|
||||||
qi = (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)
|
qi = (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)
|
||||||
? wp->w_llist_ref : wp->w_llist;
|
? wp->w_llist_ref : wp->w_llist;
|
||||||
}
|
}
|
||||||
@@ -1431,11 +1416,9 @@ retry:
|
|||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
/*
|
// cscope output is in the following format:
|
||||||
* cscope output is in the following format:
|
//
|
||||||
*
|
// <filename> <context> <line number> <pattern>
|
||||||
* <filename> <context> <line number> <pattern>
|
|
||||||
*/
|
|
||||||
char *saveptr = NULL;
|
char *saveptr = NULL;
|
||||||
if ((name = os_strtok(buf, (const char *)" ", &saveptr)) == NULL) {
|
if ((name = os_strtok(buf, (const char *)" ", &saveptr)) == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1786,9 +1769,7 @@ static int cs_read_prompt(size_t i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(UNIX) && defined(SIGALRM)
|
#if defined(UNIX) && defined(SIGALRM)
|
||||||
/*
|
// Used to catch and ignore SIGALRM below.
|
||||||
* Used to catch and ignore SIGALRM below.
|
|
||||||
*/
|
|
||||||
static void sig_handler(int s)
|
static void sig_handler(int s)
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
@@ -1847,25 +1828,21 @@ static void cs_release_csp(size_t i, bool freefnpp)
|
|||||||
os_delay(50L, false); // sleep 50 ms
|
os_delay(50L, false); // sleep 50 ms
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
/*
|
// If the cscope process is still running: kill it.
|
||||||
* If the cscope process is still running: kill it.
|
// Safety check: If the PID would be zero here, the entire X session
|
||||||
* Safety check: If the PID would be zero here, the entire X session
|
// would be killed. -1 and 1 are dangerous as well.
|
||||||
* would be killed. -1 and 1 are dangerous as well.
|
|
||||||
*/
|
|
||||||
if (pid < 0 && csinfo[i].pid > 1) {
|
if (pid < 0 && csinfo[i].pid > 1) {
|
||||||
# ifdef ECHILD
|
# ifdef ECHILD
|
||||||
bool alive = true;
|
bool alive = true;
|
||||||
|
|
||||||
if (waitpid_errno == ECHILD) {
|
if (waitpid_errno == ECHILD) {
|
||||||
/*
|
// When using 'vim -g', vim is forked and cscope process is
|
||||||
* When using 'vim -g', vim is forked and cscope process is
|
// no longer a child process but a sibling. So waitpid()
|
||||||
* no longer a child process but a sibling. So waitpid()
|
// fails with errno being ECHILD (No child processes).
|
||||||
* fails with errno being ECHILD (No child processes).
|
// Don't send SIGKILL to cscope immediately but wait
|
||||||
* Don't send SIGKILL to cscope immediately but wait
|
// (polling) for it to exit normally as result of sending
|
||||||
* (polling) for it to exit normally as result of sending
|
// the "q" command, hence giving it a chance to clean up
|
||||||
* the "q" command, hence giving it a chance to clean up
|
// its temporary files.
|
||||||
* its temporary files.
|
|
||||||
*/
|
|
||||||
int waited;
|
int waited;
|
||||||
|
|
||||||
sleep(0);
|
sleep(0);
|
||||||
@@ -1974,11 +1951,9 @@ static char *cs_resolve_file(size_t i, char *name)
|
|||||||
char *fullname;
|
char *fullname;
|
||||||
char_u *csdir = NULL;
|
char_u *csdir = NULL;
|
||||||
|
|
||||||
/*
|
// Ppath is freed when we destroy the cscope connection.
|
||||||
* Ppath is freed when we destroy the cscope connection.
|
// Fullname is freed after cs_make_vim_style_matches, after it's been
|
||||||
* Fullname is freed after cs_make_vim_style_matches, after it's been
|
// copied into the tag buffer used by Vim.
|
||||||
* copied into the tag buffer used by Vim.
|
|
||||||
*/
|
|
||||||
size_t len = strlen(name) + 2;
|
size_t len = strlen(name) + 2;
|
||||||
if (csinfo[i].ppath != NULL) {
|
if (csinfo[i].ppath != NULL) {
|
||||||
len += strlen(csinfo[i].ppath);
|
len += strlen(csinfo[i].ppath);
|
||||||
|
1121
src/nvim/indent_c.c
1121
src/nvim/indent_c.c
File diff suppressed because it is too large
Load Diff
@@ -1390,10 +1390,9 @@ scripterror:
|
|||||||
TIME_MSG("parsing arguments");
|
TIME_MSG("parsing arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Many variables are in "params" so that we can pass them to invoked
|
||||||
* Many variables are in "params" so that we can pass them to invoked
|
// functions without a lot of arguments. "argc" and "argv" are also
|
||||||
* functions without a lot of arguments. "argc" and "argv" are also
|
// copied, so that they can be changed.
|
||||||
* copied, so that they can be changed. */
|
|
||||||
static void init_params(mparm_T *paramp, int argc, char **argv)
|
static void init_params(mparm_T *paramp, int argc, char **argv)
|
||||||
{
|
{
|
||||||
CLEAR_POINTER(paramp);
|
CLEAR_POINTER(paramp);
|
||||||
@@ -1465,9 +1464,7 @@ static char_u *get_fname(mparm_T *parmp, char_u *cwd)
|
|||||||
return (char_u *)alist_name(&GARGLIST[0]);
|
return (char_u *)alist_name(&GARGLIST[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Decide about window layout for diff mode after reading vimrc.
|
||||||
* Decide about window layout for diff mode after reading vimrc.
|
|
||||||
*/
|
|
||||||
static void set_window_layout(mparm_T *paramp)
|
static void set_window_layout(mparm_T *paramp)
|
||||||
{
|
{
|
||||||
if (paramp->diff_mode && paramp->window_layout == 0) {
|
if (paramp->diff_mode && paramp->window_layout == 0) {
|
||||||
@@ -1479,10 +1476,8 @@ static void set_window_layout(mparm_T *paramp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// "-q errorfile": Load the error file now.
|
||||||
* "-q errorfile": Load the error file now.
|
// If the error file can't be read, exit before doing anything else.
|
||||||
* If the error file can't be read, exit before doing anything else.
|
|
||||||
*/
|
|
||||||
static void handle_quickfix(mparm_T *paramp)
|
static void handle_quickfix(mparm_T *paramp)
|
||||||
{
|
{
|
||||||
if (paramp->edit_type == EDIT_QF) {
|
if (paramp->edit_type == EDIT_QF) {
|
||||||
@@ -1498,10 +1493,8 @@ static void handle_quickfix(mparm_T *paramp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Need to jump to the tag before executing the '-c command'.
|
||||||
* Need to jump to the tag before executing the '-c command'.
|
// Makes "vim -c '/return' -t main" work.
|
||||||
* Makes "vim -c '/return' -t main" work.
|
|
||||||
*/
|
|
||||||
static void handle_tag(char_u *tagname)
|
static void handle_tag(char_u *tagname)
|
||||||
{
|
{
|
||||||
if (tagname != NULL) {
|
if (tagname != NULL) {
|
||||||
@@ -1540,18 +1533,14 @@ static void read_stdin(void)
|
|||||||
check_swap_exists_action();
|
check_swap_exists_action();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Create the requested number of windows and edit buffers in them.
|
||||||
* Create the requested number of windows and edit buffers in them.
|
// Also does recovery if "recoverymode" set.
|
||||||
* Also does recovery if "recoverymode" set.
|
|
||||||
*/
|
|
||||||
static void create_windows(mparm_T *parmp)
|
static void create_windows(mparm_T *parmp)
|
||||||
{
|
{
|
||||||
int dorewind;
|
int dorewind;
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
|
||||||
/*
|
// Create the number of windows that was requested.
|
||||||
* Create the number of windows that was requested.
|
|
||||||
*/
|
|
||||||
if (parmp->window_count == -1) { // was not set
|
if (parmp->window_count == -1) { // was not set
|
||||||
parmp->window_count = 1;
|
parmp->window_count = 1;
|
||||||
}
|
}
|
||||||
@@ -1670,9 +1659,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
|
|||||||
win_T *win;
|
win_T *win;
|
||||||
char *p_shm_save = NULL;
|
char *p_shm_save = NULL;
|
||||||
|
|
||||||
/*
|
// Don't execute Win/Buf Enter/Leave autocommands here
|
||||||
* Don't execute Win/Buf Enter/Leave autocommands here
|
|
||||||
*/
|
|
||||||
autocmd_no_enter++;
|
autocmd_no_enter++;
|
||||||
autocmd_no_leave++;
|
autocmd_no_leave++;
|
||||||
|
|
||||||
@@ -1781,9 +1768,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Execute the commands from --cmd arguments "cmds[cnt]".
|
||||||
* Execute the commands from --cmd arguments "cmds[cnt]".
|
|
||||||
*/
|
|
||||||
static void exe_pre_commands(mparm_T *parmp)
|
static void exe_pre_commands(mparm_T *parmp)
|
||||||
{
|
{
|
||||||
char **cmds = parmp->pre_commands;
|
char **cmds = parmp->pre_commands;
|
||||||
@@ -1803,18 +1788,14 @@ static void exe_pre_commands(mparm_T *parmp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Execute "+", "-c" and "-S" arguments.
|
||||||
* Execute "+", "-c" and "-S" arguments.
|
|
||||||
*/
|
|
||||||
static void exe_commands(mparm_T *parmp)
|
static void exe_commands(mparm_T *parmp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
// We start commands on line 0, make "vim +/pat file" match a
|
||||||
* We start commands on line 0, make "vim +/pat file" match a
|
// pattern on line 1. But don't move the cursor when an autocommand
|
||||||
* pattern on line 1. But don't move the cursor when an autocommand
|
// with g`" was used.
|
||||||
* with g`" was used.
|
|
||||||
*/
|
|
||||||
msg_scroll = true;
|
msg_scroll = true;
|
||||||
if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1) {
|
if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1) {
|
||||||
curwin->w_cursor.lnum = 0;
|
curwin->w_cursor.lnum = 0;
|
||||||
@@ -2137,11 +2118,9 @@ static void usage(void)
|
|||||||
mch_msg(_("\nSee \":help startup-options\" for all options.\n"));
|
mch_msg(_("\nSee \":help startup-options\" for all options.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check the result of the ATTENTION dialog:
|
||||||
* Check the result of the ATTENTION dialog:
|
// When "Quit" selected, exit Vim.
|
||||||
* When "Quit" selected, exit Vim.
|
// When "Recover" selected, recover the file.
|
||||||
* When "Recover" selected, recover the file.
|
|
||||||
*/
|
|
||||||
static void check_swap_exists_action(void)
|
static void check_swap_exists_action(void)
|
||||||
{
|
{
|
||||||
if (swap_exists_action == SEA_QUIT) {
|
if (swap_exists_action == SEA_QUIT) {
|
||||||
|
133
src/nvim/mark.c
133
src/nvim/mark.c
@@ -1,9 +1,7 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
/*
|
// mark.c: functions for setting marks and jumping to them
|
||||||
* mark.c: functions for setting marks and jumping to them
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -39,17 +37,13 @@
|
|||||||
#include "nvim/ui.h"
|
#include "nvim/ui.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
|
|
||||||
/*
|
// This file contains routines to maintain and manipulate marks.
|
||||||
* This file contains routines to maintain and manipulate marks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
// If a named file mark's lnum is non-zero, it is valid.
|
||||||
* If a named file mark's lnum is non-zero, it is valid.
|
// If a named file mark's fnum is non-zero, it is for an existing buffer,
|
||||||
* If a named file mark's fnum is non-zero, it is for an existing buffer,
|
// otherwise it is from .shada and namedfm[n].fname is the file name.
|
||||||
* otherwise it is from .shada and namedfm[n].fname is the file name.
|
// There are marks 'A - 'Z (set by user) and '0 to '9 (set when writing
|
||||||
* There are marks 'A - 'Z (set by user) and '0 to '9 (set when writing
|
// shada).
|
||||||
* shada).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// Global marks (marks with file number or name)
|
/// Global marks (marks with file number or name)
|
||||||
static xfmark_T namedfm[NGLOBALMARKS];
|
static xfmark_T namedfm[NGLOBALMARKS];
|
||||||
@@ -57,10 +51,9 @@ static xfmark_T namedfm[NGLOBALMARKS];
|
|||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "mark.c.generated.h"
|
# include "mark.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
/*
|
|
||||||
* Set named mark "c" at current cursor position.
|
// Set named mark "c" at current cursor position.
|
||||||
* Returns OK on success, FAIL if bad name given.
|
// Returns OK on success, FAIL if bad name given.
|
||||||
*/
|
|
||||||
int setmark(int c)
|
int setmark(int c)
|
||||||
{
|
{
|
||||||
fmarkv_T view = mark_view_make(curwin->w_topline, curwin->w_cursor);
|
fmarkv_T view = mark_view_make(curwin->w_topline, curwin->w_cursor);
|
||||||
@@ -88,11 +81,9 @@ void clear_fmark(fmark_T *fm)
|
|||||||
CLEAR_POINTER(fm);
|
CLEAR_POINTER(fm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set named mark "c" to position "pos".
|
||||||
* Set named mark "c" to position "pos".
|
// When "c" is upper case use file "fnum".
|
||||||
* When "c" is upper case use file "fnum".
|
// Returns OK on success, FAIL if bad name given.
|
||||||
* Returns OK on success, FAIL if bad name given.
|
|
||||||
*/
|
|
||||||
int setmark_pos(int c, pos_T *pos, int fnum, fmarkv_T *view_pt)
|
int setmark_pos(int c, pos_T *pos, int fnum, fmarkv_T *view_pt)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -166,10 +157,8 @@ int setmark_pos(int c, pos_T *pos, int fnum, fmarkv_T *view_pt)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set the previous context mark to the current position and add it to the
|
||||||
* Set the previous context mark to the current position and add it to the
|
// jump list.
|
||||||
* jump list.
|
|
||||||
*/
|
|
||||||
void setpcmark(void)
|
void setpcmark(void)
|
||||||
{
|
{
|
||||||
xfmark_T *fm;
|
xfmark_T *fm;
|
||||||
@@ -210,12 +199,10 @@ void setpcmark(void)
|
|||||||
SET_XFMARK(fm, curwin->w_pcmark, curbuf->b_fnum, view, NULL);
|
SET_XFMARK(fm, curwin->w_pcmark, curbuf->b_fnum, view, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// To change context, call setpcmark(), then move the current position to
|
||||||
* To change context, call setpcmark(), then move the current position to
|
// where ever, then call checkpcmark(). This ensures that the previous
|
||||||
* where ever, then call checkpcmark(). This ensures that the previous
|
// context will only be changed if the cursor moved to a different line.
|
||||||
* context will only be changed if the cursor moved to a different line.
|
// If pcmark was deleted (with "dG") the previous mark is restored.
|
||||||
* If pcmark was deleted (with "dG") the previous mark is restored.
|
|
||||||
*/
|
|
||||||
void checkpcmark(void)
|
void checkpcmark(void)
|
||||||
{
|
{
|
||||||
if (curwin->w_prev_pcmark.lnum != 0
|
if (curwin->w_prev_pcmark.lnum != 0
|
||||||
@@ -653,20 +640,16 @@ fmark_T *getnextmark(pos_T *startpos, int dir, int begin_line)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// For an xtended filemark: set the fnum from the fname.
|
||||||
* For an xtended filemark: set the fnum from the fname.
|
// This is used for marks obtained from the .shada file. It's postponed
|
||||||
* This is used for marks obtained from the .shada file. It's postponed
|
// until the mark is used to avoid a long startup delay.
|
||||||
* until the mark is used to avoid a long startup delay.
|
|
||||||
*/
|
|
||||||
static void fname2fnum(xfmark_T *fm)
|
static void fname2fnum(xfmark_T *fm)
|
||||||
{
|
{
|
||||||
char_u *p;
|
char_u *p;
|
||||||
|
|
||||||
if (fm->fname != NULL) {
|
if (fm->fname != NULL) {
|
||||||
/*
|
// First expand "~/" in the file name to the home directory.
|
||||||
* First expand "~/" in the file name to the home directory.
|
// Don't expand the whole name, it may contain other '~' chars.
|
||||||
* Don't expand the whole name, it may contain other '~' chars.
|
|
||||||
*/
|
|
||||||
if (fm->fname[0] == '~' && (fm->fname[1] == '/'
|
if (fm->fname[0] == '~' && (fm->fname[1] == '/'
|
||||||
#ifdef BACKSLASH_IN_FILENAME
|
#ifdef BACKSLASH_IN_FILENAME
|
||||||
|| fm->fname[1] == '\\'
|
|| fm->fname[1] == '\\'
|
||||||
@@ -690,11 +673,9 @@ static void fname2fnum(xfmark_T *fm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check all file marks for a name that matches the file name in buf.
|
||||||
* Check all file marks for a name that matches the file name in buf.
|
// May replace the name with an fnum.
|
||||||
* May replace the name with an fnum.
|
// Used for marks that come from the .shada file.
|
||||||
* Used for marks that come from the .shada file.
|
|
||||||
*/
|
|
||||||
void fmarks_check_names(buf_T *buf)
|
void fmarks_check_names(buf_T *buf)
|
||||||
{
|
{
|
||||||
char_u *name = (char_u *)buf->b_ffname;
|
char_u *name = (char_u *)buf->b_ffname;
|
||||||
@@ -792,11 +773,9 @@ void clrallmarks(buf_T *const buf)
|
|||||||
buf->b_changelistlen = 0;
|
buf->b_changelistlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get name of file from a filemark.
|
||||||
* Get name of file from a filemark.
|
// When it's in the current buffer, return the text at the mark.
|
||||||
* When it's in the current buffer, return the text at the mark.
|
// Returns an allocated string.
|
||||||
* Returns an allocated string.
|
|
||||||
*/
|
|
||||||
char_u *fm_getname(fmark_T *fmark, int lead_len)
|
char_u *fm_getname(fmark_T *fmark, int lead_len)
|
||||||
{
|
{
|
||||||
if (fmark->fnum == curbuf->b_fnum) { // current buffer
|
if (fmark->fnum == curbuf->b_fnum) { // current buffer
|
||||||
@@ -831,9 +810,7 @@ static char *mark_line(pos_T *mp, int lead_len)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// print the marks
|
||||||
* print the marks
|
|
||||||
*/
|
|
||||||
void ex_marks(exarg_T *eap)
|
void ex_marks(exarg_T *eap)
|
||||||
{
|
{
|
||||||
char_u *arg = (char_u *)eap->arg;
|
char_u *arg = (char_u *)eap->arg;
|
||||||
@@ -930,9 +907,7 @@ static void show_one_mark(int c, char_u *arg, pos_T *p, char_u *name_arg, int cu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// ":delmarks[!] [marks]"
|
||||||
* ":delmarks[!] [marks]"
|
|
||||||
*/
|
|
||||||
void ex_delmarks(exarg_T *eap)
|
void ex_delmarks(exarg_T *eap)
|
||||||
{
|
{
|
||||||
char_u *p;
|
char_u *p;
|
||||||
@@ -1013,9 +988,7 @@ void ex_delmarks(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// print the jumplist
|
||||||
* print the jumplist
|
|
||||||
*/
|
|
||||||
void ex_jumps(exarg_T *eap)
|
void ex_jumps(exarg_T *eap)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -1068,9 +1041,7 @@ void ex_clearjumps(exarg_T *eap)
|
|||||||
curwin->w_jumplistidx = 0;
|
curwin->w_jumplistidx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// print the changelist
|
||||||
* print the changelist
|
|
||||||
*/
|
|
||||||
void ex_changes(exarg_T *eap)
|
void ex_changes(exarg_T *eap)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -1132,17 +1103,15 @@ void ex_changes(exarg_T *eap)
|
|||||||
*lp += amount_after; \
|
*lp += amount_after; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Adjust marks between line1 and line2 (inclusive) to move 'amount' lines.
|
||||||
* Adjust marks between line1 and line2 (inclusive) to move 'amount' lines.
|
// Must be called before changed_*(), appended_lines() or deleted_lines().
|
||||||
* Must be called before changed_*(), appended_lines() or deleted_lines().
|
// May be called before or after changing the text.
|
||||||
* May be called before or after changing the text.
|
// When deleting lines line1 to line2, use an 'amount' of MAXLNUM: The marks
|
||||||
* When deleting lines line1 to line2, use an 'amount' of MAXLNUM: The marks
|
// within this range are made invalid.
|
||||||
* within this range are made invalid.
|
// If 'amount_after' is non-zero adjust marks after line2.
|
||||||
* If 'amount_after' is non-zero adjust marks after line2.
|
// Example: Delete lines 34 and 35: mark_adjust(34, 35, MAXLNUM, -2);
|
||||||
* Example: Delete lines 34 and 35: mark_adjust(34, 35, MAXLNUM, -2);
|
// Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0);
|
||||||
* Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0);
|
// or: mark_adjust(56, 55, MAXLNUM, 2);
|
||||||
* or: mark_adjust(56, 55, MAXLNUM, 2);
|
|
||||||
*/
|
|
||||||
void mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after,
|
void mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after,
|
||||||
ExtmarkOp op)
|
ExtmarkOp op)
|
||||||
{
|
{
|
||||||
@@ -1237,9 +1206,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
|
|||||||
ONE_ADJUST_NODEL(&(saved_cursor.lnum));
|
ONE_ADJUST_NODEL(&(saved_cursor.lnum));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Adjust items in all windows related to the current buffer.
|
||||||
* Adjust items in all windows related to the current buffer.
|
|
||||||
*/
|
|
||||||
FOR_ALL_TAB_WINDOWS(tab, win) {
|
FOR_ALL_TAB_WINDOWS(tab, win) {
|
||||||
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
|
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
|
||||||
// Marks in the jumplist. When deleting lines, this may create
|
// Marks in the jumplist. When deleting lines, this may create
|
||||||
@@ -1381,9 +1348,7 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long c
|
|||||||
// saved cursor for formatting
|
// saved cursor for formatting
|
||||||
COL_ADJUST(&saved_cursor);
|
COL_ADJUST(&saved_cursor);
|
||||||
|
|
||||||
/*
|
// Adjust items in all windows related to the current buffer.
|
||||||
* Adjust items in all windows related to the current buffer.
|
|
||||||
*/
|
|
||||||
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
|
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
|
||||||
// marks in the jumplist
|
// marks in the jumplist
|
||||||
for (i = 0; i < win->w_jumplistlen; i++) {
|
for (i = 0; i < win->w_jumplistlen; i++) {
|
||||||
@@ -1481,9 +1446,7 @@ void cleanup_jumplist(win_T *wp, bool checktail)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Copy the jumplist from window "from" to window "to".
|
||||||
* Copy the jumplist from window "from" to window "to".
|
|
||||||
*/
|
|
||||||
void copy_jumplist(win_T *from, win_T *to)
|
void copy_jumplist(win_T *from, win_T *to)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -1705,9 +1668,7 @@ bool mark_set_local(const char name, buf_T *const buf, const fmark_T fm, const b
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Free items in the jumplist of window "wp".
|
||||||
* Free items in the jumplist of window "wp".
|
|
||||||
*/
|
|
||||||
void free_jumplist(win_T *wp)
|
void free_jumplist(win_T *wp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@@ -5,10 +5,8 @@
|
|||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/pos.h"
|
#include "nvim/pos.h"
|
||||||
|
|
||||||
/*
|
// marks: positions in a file
|
||||||
* marks: positions in a file
|
// (a normal mark is a lnum/col pair, the same as a file position)
|
||||||
* (a normal mark is a lnum/col pair, the same as a file position)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// Flags for outcomes when moving to a mark.
|
/// Flags for outcomes when moving to a mark.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
242
src/nvim/mbyte.c
242
src/nvim/mbyte.c
@@ -132,10 +132,8 @@ const uint8_t utf8len_tab_zero[] = {
|
|||||||
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0, // F?
|
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0, // F?
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
// Canonical encoding names and their properties.
|
||||||
* Canonical encoding names and their properties.
|
// "iso-8859-n" is handled by enc_canonize() directly.
|
||||||
* "iso-8859-n" is handled by enc_canonize() directly.
|
|
||||||
*/
|
|
||||||
static struct
|
static struct
|
||||||
{ const char *name; int prop; int codepage; }
|
{ const char *name; int prop; int codepage; }
|
||||||
enc_canon_table[] =
|
enc_canon_table[] =
|
||||||
@@ -269,9 +267,7 @@ enc_canon_table[] =
|
|||||||
#define IDX_COUNT 59
|
#define IDX_COUNT 59
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
// Aliases for encoding names.
|
||||||
* Aliases for encoding names.
|
|
||||||
*/
|
|
||||||
static struct
|
static struct
|
||||||
{ const char *name; int canon; }
|
{ const char *name; int canon; }
|
||||||
enc_alias_table[] =
|
enc_alias_table[] =
|
||||||
@@ -342,10 +338,8 @@ enc_alias_table[] =
|
|||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
// Find encoding "name" in the list of canonical encoding names.
|
||||||
* Find encoding "name" in the list of canonical encoding names.
|
// Returns -1 if not found.
|
||||||
* Returns -1 if not found.
|
|
||||||
*/
|
|
||||||
static int enc_canon_search(const char_u *name)
|
static int enc_canon_search(const char_u *name)
|
||||||
FUNC_ATTR_PURE
|
FUNC_ATTR_PURE
|
||||||
{
|
{
|
||||||
@@ -357,10 +351,8 @@ static int enc_canon_search(const char_u *name)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Find canonical encoding "name" in the list and return its properties.
|
||||||
* Find canonical encoding "name" in the list and return its properties.
|
// Returns 0 if not found.
|
||||||
* Returns 0 if not found.
|
|
||||||
*/
|
|
||||||
int enc_canon_props(const char_u *name)
|
int enc_canon_props(const char_u *name)
|
||||||
FUNC_ATTR_PURE
|
FUNC_ATTR_PURE
|
||||||
{
|
{
|
||||||
@@ -375,13 +367,11 @@ int enc_canon_props(const char_u *name)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return the size of the BOM for the current buffer:
|
||||||
* Return the size of the BOM for the current buffer:
|
// 0 - no BOM
|
||||||
* 0 - no BOM
|
// 2 - UCS-2 or UTF-16 BOM
|
||||||
* 2 - UCS-2 or UTF-16 BOM
|
// 4 - UCS-4 BOM
|
||||||
* 4 - UCS-4 BOM
|
// 3 - UTF-8 BOM
|
||||||
* 3 - UTF-8 BOM
|
|
||||||
*/
|
|
||||||
int bomb_size(void)
|
int bomb_size(void)
|
||||||
FUNC_ATTR_PURE
|
FUNC_ATTR_PURE
|
||||||
{
|
{
|
||||||
@@ -401,9 +391,7 @@ int bomb_size(void)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Remove all BOM from "s" by moving remaining text.
|
||||||
* Remove all BOM from "s" by moving remaining text.
|
|
||||||
*/
|
|
||||||
void remove_bom(char_u *s)
|
void remove_bom(char_u *s)
|
||||||
{
|
{
|
||||||
char *p = (char *)s;
|
char *p = (char *)s;
|
||||||
@@ -417,13 +405,11 @@ void remove_bom(char_u *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get class of pointer:
|
||||||
* Get class of pointer:
|
// 0 for blank or NUL
|
||||||
* 0 for blank or NUL
|
// 1 for punctuation
|
||||||
* 1 for punctuation
|
// 2 for an (ASCII) word character
|
||||||
* 2 for an (ASCII) word character
|
// >2 for other word characters
|
||||||
* >2 for other word characters
|
|
||||||
*/
|
|
||||||
int mb_get_class(const char_u *p)
|
int mb_get_class(const char_u *p)
|
||||||
FUNC_ATTR_PURE
|
FUNC_ATTR_PURE
|
||||||
{
|
{
|
||||||
@@ -445,9 +431,7 @@ int mb_get_class_tab(const char_u *p, const uint64_t *const chartab)
|
|||||||
return utf_class_tab(utf_ptr2char((char *)p), chartab);
|
return utf_class_tab(utf_ptr2char((char *)p), chartab);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return true if "c" is in "table".
|
||||||
* Return true if "c" is in "table".
|
|
||||||
*/
|
|
||||||
static bool intable(const struct interval *table, size_t n_items, int c)
|
static bool intable(const struct interval *table, size_t n_items, int c)
|
||||||
FUNC_ATTR_PURE
|
FUNC_ATTR_PURE
|
||||||
{
|
{
|
||||||
@@ -646,22 +630,20 @@ int utf_ptr2char(const char *const p_in)
|
|||||||
return p[0];
|
return p[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Convert a UTF-8 byte sequence to a wide character.
|
||||||
* Convert a UTF-8 byte sequence to a wide character.
|
// String is assumed to be terminated by NUL or after "n" bytes, whichever
|
||||||
* String is assumed to be terminated by NUL or after "n" bytes, whichever
|
// comes first.
|
||||||
* comes first.
|
// The function is safe in the sense that it never accesses memory beyond the
|
||||||
* The function is safe in the sense that it never accesses memory beyond the
|
// first "n" bytes of "s".
|
||||||
* first "n" bytes of "s".
|
//
|
||||||
*
|
// On success, returns decoded codepoint, advances "s" to the beginning of
|
||||||
* On success, returns decoded codepoint, advances "s" to the beginning of
|
// next character and decreases "n" accordingly.
|
||||||
* next character and decreases "n" accordingly.
|
//
|
||||||
*
|
// If end of string was reached, returns 0 and, if "n" > 0, advances "s" past
|
||||||
* If end of string was reached, returns 0 and, if "n" > 0, advances "s" past
|
// NUL byte.
|
||||||
* NUL byte.
|
//
|
||||||
*
|
// If byte sequence is illegal or incomplete, returns -1 and does not advance
|
||||||
* If byte sequence is illegal or incomplete, returns -1 and does not advance
|
// "s".
|
||||||
* "s".
|
|
||||||
*/
|
|
||||||
static int utf_safe_read_char_adv(const char_u **s, size_t *n)
|
static int utf_safe_read_char_adv(const char_u **s, size_t *n)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -701,10 +683,8 @@ static int utf_safe_read_char_adv(const char_u **s, size_t *n)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get character at **pp and advance *pp to the next character.
|
||||||
* Get character at **pp and advance *pp to the next character.
|
// Note: composing characters are skipped!
|
||||||
* Note: composing characters are skipped!
|
|
||||||
*/
|
|
||||||
int mb_ptr2char_adv(const char_u **const pp)
|
int mb_ptr2char_adv(const char_u **const pp)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -714,10 +694,8 @@ int mb_ptr2char_adv(const char_u **const pp)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get character at **pp and advance *pp to the next character.
|
||||||
* Get character at **pp and advance *pp to the next character.
|
// Note: composing characters are returned as separate characters.
|
||||||
* Note: composing characters are returned as separate characters.
|
|
||||||
*/
|
|
||||||
int mb_cptr2char_adv(const char_u **pp)
|
int mb_cptr2char_adv(const char_u **pp)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -784,12 +762,10 @@ int utfc_ptr2char(const char *p_in, int *pcc)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Convert a UTF-8 byte string to a wide character. Also get up to MAX_MCO
|
||||||
* Convert a UTF-8 byte string to a wide character. Also get up to MAX_MCO
|
// composing characters. Use no more than p[maxlen].
|
||||||
* composing characters. Use no more than p[maxlen].
|
//
|
||||||
*
|
// @param [out] pcc: composing chars, last one is 0
|
||||||
* @param [out] pcc: composing chars, last one is 0
|
|
||||||
*/
|
|
||||||
int utfc_ptr2char_len(const char_u *p, int *pcc, int maxlen)
|
int utfc_ptr2char_len(const char_u *p, int *pcc, int maxlen)
|
||||||
{
|
{
|
||||||
assert(maxlen > 0);
|
assert(maxlen > 0);
|
||||||
@@ -845,24 +821,20 @@ int utf_ptr2len(const char *const p_in)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return length of UTF-8 character, obtained from the first byte.
|
||||||
* Return length of UTF-8 character, obtained from the first byte.
|
// "b" must be between 0 and 255!
|
||||||
* "b" must be between 0 and 255!
|
// Returns 1 for an invalid first byte value.
|
||||||
* Returns 1 for an invalid first byte value.
|
|
||||||
*/
|
|
||||||
int utf_byte2len(int b)
|
int utf_byte2len(int b)
|
||||||
{
|
{
|
||||||
return utf8len_tab[b];
|
return utf8len_tab[b];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get the length of UTF-8 byte sequence "p[size]". Does not include any
|
||||||
* Get the length of UTF-8 byte sequence "p[size]". Does not include any
|
// following composing characters.
|
||||||
* following composing characters.
|
// Returns 1 for "".
|
||||||
* Returns 1 for "".
|
// Returns 1 for an illegal byte sequence (also in incomplete byte seq.).
|
||||||
* Returns 1 for an illegal byte sequence (also in incomplete byte seq.).
|
// Returns number > "size" for an incomplete byte sequence.
|
||||||
* Returns number > "size" for an incomplete byte sequence.
|
// Never returns zero.
|
||||||
* Never returns zero.
|
|
||||||
*/
|
|
||||||
int utf_ptr2len_len(const char_u *p, int size)
|
int utf_ptr2len_len(const char_u *p, int size)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
@@ -948,10 +920,8 @@ int utfc_ptr2len_len(const char *p, int size)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check for composing characters. We can handle only the first six, but
|
||||||
* Check for composing characters. We can handle only the first six, but
|
// skip all of them (otherwise the cursor would get stuck).
|
||||||
* skip all of them (otherwise the cursor would get stuck).
|
|
||||||
*/
|
|
||||||
prevlen = 0;
|
prevlen = 0;
|
||||||
while (len < size) {
|
while (len < size) {
|
||||||
int len_next_char;
|
int len_next_char;
|
||||||
@@ -960,10 +930,8 @@ int utfc_ptr2len_len(const char *p, int size)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Next character length should not go beyond size to ensure that
|
||||||
* Next character length should not go beyond size to ensure that
|
// utf_composinglike(...) does not read beyond size.
|
||||||
* utf_composinglike(...) does not read beyond size.
|
|
||||||
*/
|
|
||||||
len_next_char = utf_ptr2len_len((char_u *)p + len, size - len);
|
len_next_char = utf_ptr2len_len((char_u *)p + len, size - len);
|
||||||
if (len_next_char > size - len) {
|
if (len_next_char > size - len) {
|
||||||
break;
|
break;
|
||||||
@@ -1042,20 +1010,16 @@ int utf_char2bytes(const int c, char *const buf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return true if "c" is a composing UTF-8 character. This means it will be
|
||||||
* Return true if "c" is a composing UTF-8 character. This means it will be
|
// drawn on top of the preceding character.
|
||||||
* drawn on top of the preceding character.
|
// Based on code from Markus Kuhn.
|
||||||
* Based on code from Markus Kuhn.
|
|
||||||
*/
|
|
||||||
bool utf_iscomposing(int c)
|
bool utf_iscomposing(int c)
|
||||||
{
|
{
|
||||||
return intable(combining, ARRAY_SIZE(combining), c);
|
return intable(combining, ARRAY_SIZE(combining), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return true for characters that can be displayed in a normal way.
|
||||||
* Return true for characters that can be displayed in a normal way.
|
// Only for characters of 0x100 and above!
|
||||||
* Only for characters of 0x100 and above!
|
|
||||||
*/
|
|
||||||
bool utf_printable(int c)
|
bool utf_printable(int c)
|
||||||
{
|
{
|
||||||
// Sorted list of non-overlapping intervals.
|
// Sorted list of non-overlapping intervals.
|
||||||
@@ -1070,12 +1034,10 @@ bool utf_printable(int c)
|
|||||||
return !intable(nonprint, ARRAY_SIZE(nonprint), c);
|
return !intable(nonprint, ARRAY_SIZE(nonprint), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get class of a Unicode character.
|
||||||
* Get class of a Unicode character.
|
// 0: white space
|
||||||
* 0: white space
|
// 1: punctuation
|
||||||
* 1: punctuation
|
// 2 or bigger: some class of word character.
|
||||||
* 2 or bigger: some class of word character.
|
|
||||||
*/
|
|
||||||
int utf_class(const int c)
|
int utf_class(const int c)
|
||||||
{
|
{
|
||||||
return utf_class_tab(c, curbuf->b_chartab);
|
return utf_class_tab(c, curbuf->b_chartab);
|
||||||
@@ -1204,11 +1166,9 @@ bool utf_ambiguous_width(int c)
|
|||||||
|| intable(emoji_all, ARRAY_SIZE(emoji_all), c));
|
|| intable(emoji_all, ARRAY_SIZE(emoji_all), c));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Generic conversion function for case operations.
|
||||||
* Generic conversion function for case operations.
|
// Return the converted equivalent of "a", which is a UCS-4 character. Use
|
||||||
* Return the converted equivalent of "a", which is a UCS-4 character. Use
|
// the given conversion "table". Uses binary search on "table".
|
||||||
* the given conversion "table". Uses binary search on "table".
|
|
||||||
*/
|
|
||||||
static int utf_convert(int a, const convertStruct *const table, size_t n_items)
|
static int utf_convert(int a, const convertStruct *const table, size_t n_items)
|
||||||
{
|
{
|
||||||
size_t start, mid, end; // indices into table
|
size_t start, mid, end; // indices into table
|
||||||
@@ -1234,10 +1194,8 @@ static int utf_convert(int a, const convertStruct *const table, size_t n_items)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return the folded-case equivalent of "a", which is a UCS-4 character. Uses
|
||||||
* Return the folded-case equivalent of "a", which is a UCS-4 character. Uses
|
// simple case folding.
|
||||||
* simple case folding.
|
|
||||||
*/
|
|
||||||
int utf_fold(int a)
|
int utf_fold(int a)
|
||||||
{
|
{
|
||||||
if (a < 0x80) {
|
if (a < 0x80) {
|
||||||
@@ -1566,10 +1524,8 @@ int mb_stricmp(const char *s1, const char *s2)
|
|||||||
return mb_strnicmp(s1, s2, MAXCOL);
|
return mb_strnicmp(s1, s2, MAXCOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// "g8": show bytes of the UTF-8 char under the cursor. Doesn't matter what
|
||||||
* "g8": show bytes of the UTF-8 char under the cursor. Doesn't matter what
|
// 'encoding' has been set to.
|
||||||
* 'encoding' has been set to.
|
|
||||||
*/
|
|
||||||
void show_utf8(void)
|
void show_utf8(void)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
@@ -1916,9 +1872,7 @@ int utf_cp_head_off(const char_u *base, const char_u *p)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Find the next illegal byte sequence.
|
||||||
* Find the next illegal byte sequence.
|
|
||||||
*/
|
|
||||||
void utf_find_illegal(void)
|
void utf_find_illegal(void)
|
||||||
{
|
{
|
||||||
pos_T pos = curwin->w_cursor;
|
pos_T pos = curwin->w_cursor;
|
||||||
@@ -2008,10 +1962,8 @@ bool utf_valid_string(const char_u *s, const char_u *end)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If the cursor moves on an trail byte, set the cursor on the lead byte.
|
||||||
* If the cursor moves on an trail byte, set the cursor on the lead byte.
|
// Thus it moves left if necessary.
|
||||||
* Thus it moves left if necessary.
|
|
||||||
*/
|
|
||||||
void mb_adjust_cursor(void)
|
void mb_adjust_cursor(void)
|
||||||
{
|
{
|
||||||
mark_mb_adjustpos(curbuf, &curwin->w_cursor);
|
mark_mb_adjustpos(curbuf, &curwin->w_cursor);
|
||||||
@@ -2238,10 +2190,8 @@ static int enc_alias_search(const char_u *name)
|
|||||||
# include <langinfo.h>
|
# include <langinfo.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
// Get the canonicalized encoding of the current locale.
|
||||||
* Get the canonicalized encoding of the current locale.
|
// Returns an allocated string when successful, NULL when not.
|
||||||
* Returns an allocated string when successful, NULL when not.
|
|
||||||
*/
|
|
||||||
char_u *enc_locale(void)
|
char_u *enc_locale(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -2307,12 +2257,10 @@ enc_locale_copy_enc:
|
|||||||
|
|
||||||
#if defined(HAVE_ICONV)
|
#if defined(HAVE_ICONV)
|
||||||
|
|
||||||
/*
|
// Call iconv_open() with a check if iconv() works properly (there are broken
|
||||||
* Call iconv_open() with a check if iconv() works properly (there are broken
|
// versions).
|
||||||
* versions).
|
// Returns (void *)-1 if failed.
|
||||||
* Returns (void *)-1 if failed.
|
// (should return iconv_t, but that causes problems with prototypes).
|
||||||
* (should return iconv_t, but that causes problems with prototypes).
|
|
||||||
*/
|
|
||||||
void *my_iconv_open(char_u *to, char_u *from)
|
void *my_iconv_open(char_u *to, char_u *from)
|
||||||
{
|
{
|
||||||
iconv_t fd;
|
iconv_t fd;
|
||||||
@@ -2328,13 +2276,11 @@ void *my_iconv_open(char_u *to, char_u *from)
|
|||||||
fd = iconv_open(enc_skip((char *)to), enc_skip((char *)from));
|
fd = iconv_open(enc_skip((char *)to), enc_skip((char *)from));
|
||||||
|
|
||||||
if (fd != (iconv_t)-1 && iconv_working == kUnknown) {
|
if (fd != (iconv_t)-1 && iconv_working == kUnknown) {
|
||||||
/*
|
// Do a dummy iconv() call to check if it actually works. There is a
|
||||||
* Do a dummy iconv() call to check if it actually works. There is a
|
// version of iconv() on Linux that is broken. We can't ignore it,
|
||||||
* version of iconv() on Linux that is broken. We can't ignore it,
|
// because it's wide-spread. The symptoms are that after outputting
|
||||||
* because it's wide-spread. The symptoms are that after outputting
|
// the initial shift state the "to" pointer is NULL and conversion
|
||||||
* the initial shift state the "to" pointer is NULL and conversion
|
// stops for no apparent reason after about 8160 characters.
|
||||||
* stops for no apparent reason after about 8160 characters.
|
|
||||||
*/
|
|
||||||
p = (char *)tobuf;
|
p = (char *)tobuf;
|
||||||
tolen = ICONV_TESTLEN;
|
tolen = ICONV_TESTLEN;
|
||||||
(void)iconv(fd, NULL, NULL, &p, &tolen);
|
(void)iconv(fd, NULL, NULL, &p, &tolen);
|
||||||
@@ -2350,13 +2296,11 @@ void *my_iconv_open(char_u *to, char_u *from)
|
|||||||
return (void *)fd;
|
return (void *)fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Convert the string "str[slen]" with iconv().
|
||||||
* Convert the string "str[slen]" with iconv().
|
// If "unconvlenp" is not NULL handle the string ending in an incomplete
|
||||||
* If "unconvlenp" is not NULL handle the string ending in an incomplete
|
// sequence and set "*unconvlenp" to the length of it.
|
||||||
* sequence and set "*unconvlenp" to the length of it.
|
// Returns the converted string in allocated memory. NULL for an error.
|
||||||
* Returns the converted string in allocated memory. NULL for an error.
|
// If resultlenp is not NULL, sets it to the result length in bytes.
|
||||||
* If resultlenp is not NULL, sets it to the result length in bytes.
|
|
||||||
*/
|
|
||||||
static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, size_t slen,
|
static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, size_t slen,
|
||||||
size_t *unconvlenp, size_t *resultlenp)
|
size_t *unconvlenp, size_t *resultlenp)
|
||||||
{
|
{
|
||||||
@@ -2529,11 +2473,9 @@ char *string_convert(const vimconv_T *const vcp, char *ptr, size_t *lenp)
|
|||||||
return (char *)string_convert_ext(vcp, (char_u *)ptr, lenp, NULL);
|
return (char *)string_convert_ext(vcp, (char_u *)ptr, lenp, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Like string_convert(), but when "unconvlenp" is not NULL and there are is
|
||||||
* Like string_convert(), but when "unconvlenp" is not NULL and there are is
|
// an incomplete sequence at the end it is not converted and "*unconvlenp" is
|
||||||
* an incomplete sequence at the end it is not converted and "*unconvlenp" is
|
// set to the number of remaining bytes.
|
||||||
* set to the number of remaining bytes.
|
|
||||||
*/
|
|
||||||
char_u *string_convert_ext(const vimconv_T *const vcp, char_u *ptr, size_t *lenp,
|
char_u *string_convert_ext(const vimconv_T *const vcp, char_u *ptr, size_t *lenp,
|
||||||
size_t *unconvlenp)
|
size_t *unconvlenp)
|
||||||
{
|
{
|
||||||
|
@@ -11,12 +11,10 @@
|
|||||||
#include "nvim/os/os_defs.h" // For indirect
|
#include "nvim/os/os_defs.h" // For indirect
|
||||||
#include "nvim/types.h" // for char_u
|
#include "nvim/types.h" // for char_u
|
||||||
|
|
||||||
/*
|
// Return byte length of character that starts with byte "b".
|
||||||
* Return byte length of character that starts with byte "b".
|
// Returns 1 for a single-byte character.
|
||||||
* Returns 1 for a single-byte character.
|
// MB_BYTE2LEN_CHECK() can be used to count a special key as one byte.
|
||||||
* MB_BYTE2LEN_CHECK() can be used to count a special key as one byte.
|
// Don't call MB_BYTE2LEN(b) with b < 0 or b > 255!
|
||||||
* Don't call MB_BYTE2LEN(b) with b < 0 or b > 255!
|
|
||||||
*/
|
|
||||||
#define MB_BYTE2LEN(b) utf8len_tab[b]
|
#define MB_BYTE2LEN(b) utf8len_tab[b]
|
||||||
#define MB_BYTE2LEN_CHECK(b) (((b) < 0 || (b) > 255) ? 1 : utf8len_tab[b])
|
#define MB_BYTE2LEN_CHECK(b) (((b) < 0 || (b) > 255) ? 1 : utf8len_tab[b])
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -502,10 +502,8 @@ bool striequal(const char *a, const char *b)
|
|||||||
return (a == NULL && b == NULL) || (a && b && STRICMP(a, b) == 0);
|
return (a == NULL && b == NULL) || (a && b && STRICMP(a, b) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Avoid repeating the error message many times (they take 1 second each).
|
||||||
* Avoid repeating the error message many times (they take 1 second each).
|
// Did_outofmem_msg is reset when a character is read.
|
||||||
* Did_outofmem_msg is reset when a character is read.
|
|
||||||
*/
|
|
||||||
void do_outofmem_msg(size_t size)
|
void do_outofmem_msg(size_t size)
|
||||||
{
|
{
|
||||||
if (!did_outofmem_msg) {
|
if (!did_outofmem_msg) {
|
||||||
@@ -675,13 +673,11 @@ char *arena_memdupz(Arena *arena, const char *buf, size_t size)
|
|||||||
# include "nvim/tag.h"
|
# include "nvim/tag.h"
|
||||||
# include "nvim/window.h"
|
# include "nvim/window.h"
|
||||||
|
|
||||||
/*
|
// Free everything that we allocated.
|
||||||
* Free everything that we allocated.
|
// Can be used to detect memory leaks, e.g., with ccmalloc.
|
||||||
* 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
|
||||||
* NOTE: This is tricky! Things are freed that functions depend on. Don't be
|
// surprised if Vim crashes...
|
||||||
* surprised if Vim crashes...
|
// Some things can't be freed, esp. things local to a library function.
|
||||||
* Some things can't be freed, esp. things local to a library function.
|
|
||||||
*/
|
|
||||||
void free_all_mem(void)
|
void free_all_mem(void)
|
||||||
{
|
{
|
||||||
buf_T *buf, *nextbuf;
|
buf_T *buf, *nextbuf;
|
||||||
|
148
src/nvim/menu.c
148
src/nvim/menu.c
@@ -1,10 +1,8 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
/*
|
// Code for menus. Used for the GUI and 'wildmenu'.
|
||||||
* Code for menus. Used for the GUI and 'wildmenu'.
|
// GUI/Motif support by Robert Webb
|
||||||
* GUI/Motif support by Robert Webb
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -141,9 +139,7 @@ void ex_menu(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
pri_tab[MENUDEPTH] = -1; // mark end of the table
|
pri_tab[MENUDEPTH] = -1; // mark end of the table
|
||||||
|
|
||||||
/*
|
// Check for "disable" or "enable" argument.
|
||||||
* Check for "disable" or "enable" argument.
|
|
||||||
*/
|
|
||||||
if (STRNCMP(arg, "enable", 6) == 0 && ascii_iswhite(arg[6])) {
|
if (STRNCMP(arg, "enable", 6) == 0 && ascii_iswhite(arg[6])) {
|
||||||
enable = kTrue;
|
enable = kTrue;
|
||||||
arg = skipwhite(arg + 6);
|
arg = skipwhite(arg + 6);
|
||||||
@@ -152,9 +148,7 @@ void ex_menu(exarg_T *eap)
|
|||||||
arg = skipwhite(arg + 7);
|
arg = skipwhite(arg + 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If there is no argument, display all menus.
|
||||||
* If there is no argument, display all menus.
|
|
||||||
*/
|
|
||||||
if (*arg == NUL) {
|
if (*arg == NUL) {
|
||||||
show_menus(arg, modes);
|
show_menus(arg, modes);
|
||||||
return;
|
return;
|
||||||
@@ -168,9 +162,7 @@ void ex_menu(exarg_T *eap)
|
|||||||
|
|
||||||
map_to = menu_translate_tab_and_shift(arg);
|
map_to = menu_translate_tab_and_shift(arg);
|
||||||
|
|
||||||
/*
|
// If there is only a menu name, display menus with that name.
|
||||||
* If there is only a menu name, display menus with that name.
|
|
||||||
*/
|
|
||||||
if (*map_to == NUL && !unmenu && enable == kNone) {
|
if (*map_to == NUL && !unmenu && enable == kNone) {
|
||||||
show_menus(menu_path, modes);
|
show_menus(menu_path, modes);
|
||||||
goto theend;
|
goto theend;
|
||||||
@@ -200,16 +192,12 @@ void ex_menu(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
menu_enable_recurse(*root_menu_ptr, menu_path, modes, enable);
|
menu_enable_recurse(*root_menu_ptr, menu_path, modes, enable);
|
||||||
} else if (unmenu) {
|
} else if (unmenu) {
|
||||||
/*
|
// Delete menu(s).
|
||||||
* Delete menu(s).
|
|
||||||
*/
|
|
||||||
if (STRCMP(menu_path, "*") == 0) { // meaning: remove all menus
|
if (STRCMP(menu_path, "*") == 0) { // meaning: remove all menus
|
||||||
menu_path = "";
|
menu_path = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// For the PopUp menu, remove a menu for each mode separately.
|
||||||
* For the PopUp menu, remove a menu for each mode separately.
|
|
||||||
*/
|
|
||||||
if (menu_is_popup(menu_path)) {
|
if (menu_is_popup(menu_path)) {
|
||||||
for (i = 0; i < MENU_INDEX_TIP; i++) {
|
for (i = 0; i < MENU_INDEX_TIP; i++) {
|
||||||
if (modes & (1 << i)) {
|
if (modes & (1 << i)) {
|
||||||
@@ -223,10 +211,8 @@ void ex_menu(exarg_T *eap)
|
|||||||
// Careful: remove_menu() changes menu_path
|
// Careful: remove_menu() changes menu_path
|
||||||
remove_menu(root_menu_ptr, menu_path, modes, false);
|
remove_menu(root_menu_ptr, menu_path, modes, false);
|
||||||
} else {
|
} else {
|
||||||
/*
|
// Add menu(s).
|
||||||
* Add menu(s).
|
// Replace special key codes.
|
||||||
* Replace special key codes.
|
|
||||||
*/
|
|
||||||
if (STRICMP(map_to, "<nop>") == 0) { // "<Nop>" means nothing
|
if (STRICMP(map_to, "<nop>") == 0) { // "<Nop>" means nothing
|
||||||
map_to = "";
|
map_to = "";
|
||||||
map_buf = NULL;
|
map_buf = NULL;
|
||||||
@@ -242,9 +228,7 @@ void ex_menu(exarg_T *eap)
|
|||||||
menuarg.silent[0] = silent;
|
menuarg.silent[0] = silent;
|
||||||
add_menu_path(menu_path, &menuarg, pri_tab, map_to);
|
add_menu_path(menu_path, &menuarg, pri_tab, map_to);
|
||||||
|
|
||||||
/*
|
// For the PopUp menu, add a menu for each mode separately.
|
||||||
* For the PopUp menu, add a menu for each mode separately.
|
|
||||||
*/
|
|
||||||
if (menu_is_popup(menu_path)) {
|
if (menu_is_popup(menu_path)) {
|
||||||
for (i = 0; i < MENU_INDEX_TIP; i++) {
|
for (i = 0; i < MENU_INDEX_TIP; i++) {
|
||||||
if (modes & (1 << i)) {
|
if (modes & (1 << i)) {
|
||||||
@@ -384,11 +368,9 @@ static int add_menu_path(const char *const menu_path, vimmenu_T *menuarg, const
|
|||||||
} else {
|
} else {
|
||||||
old_modes = menu->modes;
|
old_modes = menu->modes;
|
||||||
|
|
||||||
/*
|
// If this menu option was previously only available in other
|
||||||
* If this menu option was previously only available in other
|
// modes, then make sure it's available for this one now
|
||||||
* modes, then make sure it's available for this one now
|
// Also enable a menu when it's created or changed.
|
||||||
* Also enable a menu when it's created or changed.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
menu->modes |= modes;
|
menu->modes |= modes;
|
||||||
menu->enabled |= modes;
|
menu->enabled |= modes;
|
||||||
@@ -405,10 +387,8 @@ static int add_menu_path(const char *const menu_path, vimmenu_T *menuarg, const
|
|||||||
}
|
}
|
||||||
xfree(path_name);
|
xfree(path_name);
|
||||||
|
|
||||||
/*
|
// Only add system menu items which have not been defined yet.
|
||||||
* Only add system menu items which have not been defined yet.
|
// First check if this was an ":amenu".
|
||||||
* First check if this was an ":amenu".
|
|
||||||
*/
|
|
||||||
amenu = ((modes & (MENU_NORMAL_MODE | MENU_INSERT_MODE)) ==
|
amenu = ((modes & (MENU_NORMAL_MODE | MENU_INSERT_MODE)) ==
|
||||||
(MENU_NORMAL_MODE | MENU_INSERT_MODE));
|
(MENU_NORMAL_MODE | MENU_INSERT_MODE));
|
||||||
if (sys_menu) {
|
if (sys_menu) {
|
||||||
@@ -491,10 +471,8 @@ erret:
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set the (sub)menu with the given name to enabled or disabled.
|
||||||
* Set the (sub)menu with the given name to enabled or disabled.
|
// Called recursively.
|
||||||
* Called recursively.
|
|
||||||
*/
|
|
||||||
static int menu_enable_recurse(vimmenu_T *menu, char *name, int modes, int enable)
|
static int menu_enable_recurse(vimmenu_T *menu, char *name, int modes, int enable)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
@@ -522,11 +500,9 @@ static int menu_enable_recurse(vimmenu_T *menu, char *name, int modes, int enabl
|
|||||||
menu->enabled &= ~modes;
|
menu->enabled &= ~modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When name is empty, we are doing all menu items for the given
|
||||||
* When name is empty, we are doing all menu items for the given
|
// modes, so keep looping, otherwise we are just doing the named
|
||||||
* modes, so keep looping, otherwise we are just doing the named
|
// menu item (which has been found) so break here.
|
||||||
* menu item (which has been found) so break here.
|
|
||||||
*/
|
|
||||||
if (*name != NUL && *name != '*') {
|
if (*name != NUL && *name != '*') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -577,11 +553,9 @@ static int remove_menu(vimmenu_T **menup, char *name, int modes, bool silent)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When name is empty, we are removing all menu items for the given
|
||||||
* When name is empty, we are removing all menu items for the given
|
// modes, so keep looping, otherwise we are just removing the named
|
||||||
* modes, so keep looping, otherwise we are just removing the named
|
// menu item (which has been found) so break here.
|
||||||
* menu item (which has been found) so break here.
|
|
||||||
*/
|
|
||||||
if (*name != NUL) {
|
if (*name != NUL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -628,9 +602,7 @@ static int remove_menu(vimmenu_T **menup, char *name, int modes, bool silent)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Free the given menu structure and remove it from the linked list.
|
||||||
* Free the given menu structure and remove it from the linked list.
|
|
||||||
*/
|
|
||||||
static void free_menu(vimmenu_T **menup)
|
static void free_menu(vimmenu_T **menup)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -652,9 +624,7 @@ static void free_menu(vimmenu_T **menup)
|
|||||||
xfree(menu);
|
xfree(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Free the menu->string with the given index.
|
||||||
* Free the menu->string with the given index.
|
|
||||||
*/
|
|
||||||
static void free_menu_string(vimmenu_T *menu, int idx)
|
static void free_menu_string(vimmenu_T *menu, int idx)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -909,16 +879,12 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Used when expanding menu names.
|
||||||
* Used when expanding menu names.
|
|
||||||
*/
|
|
||||||
static vimmenu_T *expand_menu = NULL;
|
static vimmenu_T *expand_menu = NULL;
|
||||||
static int expand_modes = 0x0;
|
static int expand_modes = 0x0;
|
||||||
static int expand_emenu; // true for ":emenu" command
|
static int expand_emenu; // true for ":emenu" command
|
||||||
|
|
||||||
/*
|
// Work out what to complete when doing command line completion of menu names.
|
||||||
* Work out what to complete when doing command line completion of menu names.
|
|
||||||
*/
|
|
||||||
char *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char *arg, bool forceit)
|
char *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char *arg, bool forceit)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
@@ -994,10 +960,8 @@ char *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char *arg, bool for
|
|||||||
// Found menu
|
// Found menu
|
||||||
if ((*p != NUL && menu->children == NULL)
|
if ((*p != NUL && menu->children == NULL)
|
||||||
|| ((menu->modes & expand_modes) == 0x0)) {
|
|| ((menu->modes & expand_modes) == 0x0)) {
|
||||||
/*
|
// Menu path continues, but we have reached a leaf.
|
||||||
* Menu path continues, but we have reached a leaf.
|
// Or menu exists only in another mode.
|
||||||
* Or menu exists only in another mode.
|
|
||||||
*/
|
|
||||||
xfree(path_name);
|
xfree(path_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1024,10 +988,8 @@ char *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char *arg, bool for
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Function given to ExpandGeneric() to obtain the list of (sub)menus (not
|
||||||
* Function given to ExpandGeneric() to obtain the list of (sub)menus (not
|
// entries).
|
||||||
* entries).
|
|
||||||
*/
|
|
||||||
char *get_menu_name(expand_T *xp, int idx)
|
char *get_menu_name(expand_T *xp, int idx)
|
||||||
{
|
{
|
||||||
static vimmenu_T *menu = NULL;
|
static vimmenu_T *menu = NULL;
|
||||||
@@ -1073,10 +1035,8 @@ char *get_menu_name(expand_T *xp, int idx)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Function given to ExpandGeneric() to obtain the list of menus and menu
|
||||||
* Function given to ExpandGeneric() to obtain the list of menus and menu
|
// entries.
|
||||||
* entries.
|
|
||||||
*/
|
|
||||||
char *get_menu_names(expand_T *xp, int idx)
|
char *get_menu_names(expand_T *xp, int idx)
|
||||||
{
|
{
|
||||||
static vimmenu_T *menu = NULL;
|
static vimmenu_T *menu = NULL;
|
||||||
@@ -1312,10 +1272,8 @@ static char *get_menu_mode_str(int modes)
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Modify a menu name starting with "PopUp" to include the mode character.
|
||||||
* Modify a menu name starting with "PopUp" to include the mode character.
|
// Returns the name in allocated memory.
|
||||||
* Returns the name in allocated memory.
|
|
||||||
*/
|
|
||||||
static char *popup_mode_name(char *name, int idx)
|
static char *popup_mode_name(char *name, int idx)
|
||||||
{
|
{
|
||||||
size_t len = STRLEN(name);
|
size_t len = STRLEN(name);
|
||||||
@@ -1730,9 +1688,7 @@ theend:
|
|||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Translation of menu names. Just a simple lookup table.
|
||||||
* Translation of menu names. Just a simple lookup table.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *from; // English name
|
char *from; // English name
|
||||||
@@ -1748,11 +1704,9 @@ static garray_T menutrans_ga = GA_EMPTY_INIT_VALUE;
|
|||||||
xfree(_mt->from_noamp); \
|
xfree(_mt->from_noamp); \
|
||||||
xfree(_mt->to)
|
xfree(_mt->to)
|
||||||
|
|
||||||
/*
|
// ":menutrans".
|
||||||
* ":menutrans".
|
// This function is also defined without the +multi_lang feature, in which
|
||||||
* This function is also defined without the +multi_lang feature, in which
|
// case the commands are ignored.
|
||||||
* case the commands are ignored.
|
|
||||||
*/
|
|
||||||
void ex_menutranslate(exarg_T *eap)
|
void ex_menutranslate(exarg_T *eap)
|
||||||
{
|
{
|
||||||
char *arg = eap->arg;
|
char *arg = eap->arg;
|
||||||
@@ -1762,9 +1716,7 @@ void ex_menutranslate(exarg_T *eap)
|
|||||||
ga_init(&menutrans_ga, (int)sizeof(menutrans_T), 5);
|
ga_init(&menutrans_ga, (int)sizeof(menutrans_T), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// ":menutrans clear": clear all translations.
|
||||||
* ":menutrans clear": clear all translations.
|
|
||||||
*/
|
|
||||||
if (STRNCMP(arg, "clear", 5) == 0 && ends_excmd(*skipwhite(arg + 5))) {
|
if (STRNCMP(arg, "clear", 5) == 0 && ends_excmd(*skipwhite(arg + 5))) {
|
||||||
GA_DEEP_CLEAR(&menutrans_ga, menutrans_T, FREE_MENUTRANS);
|
GA_DEEP_CLEAR(&menutrans_ga, menutrans_T, FREE_MENUTRANS);
|
||||||
|
|
||||||
@@ -1796,9 +1748,7 @@ void ex_menutranslate(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Find the character just after one part of a menu name.
|
||||||
* Find the character just after one part of a menu name.
|
|
||||||
*/
|
|
||||||
static char *menu_skip_part(char *p)
|
static char *menu_skip_part(char *p)
|
||||||
{
|
{
|
||||||
while (*p != NUL && *p != '.' && !ascii_iswhite(*p)) {
|
while (*p != NUL && *p != '.' && !ascii_iswhite(*p)) {
|
||||||
@@ -1810,10 +1760,8 @@ static char *menu_skip_part(char *p)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Lookup part of a menu name in the translations.
|
||||||
* Lookup part of a menu name in the translations.
|
// Return a pointer to the translation or NULL if not found.
|
||||||
* Return a pointer to the translation or NULL if not found.
|
|
||||||
*/
|
|
||||||
static char *menutrans_lookup(char *name, int len)
|
static char *menutrans_lookup(char *name, int len)
|
||||||
{
|
{
|
||||||
menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data;
|
menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data;
|
||||||
@@ -1841,9 +1789,7 @@ static char *menutrans_lookup(char *name, int len)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Unescape the name in the translate dictionary table.
|
||||||
* Unescape the name in the translate dictionary table.
|
|
||||||
*/
|
|
||||||
static void menu_unescape_name(char *name)
|
static void menu_unescape_name(char *name)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
@@ -1855,10 +1801,8 @@ static void menu_unescape_name(char *name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Isolate the menu name.
|
||||||
* Isolate the menu name.
|
// Skip the menu name, and translate <Tab> into a real TAB.
|
||||||
* Skip the menu name, and translate <Tab> into a real TAB.
|
|
||||||
*/
|
|
||||||
static char *menu_translate_tab_and_shift(char *arg_start)
|
static char *menu_translate_tab_and_shift(char *arg_start)
|
||||||
{
|
{
|
||||||
char *arg = arg_start;
|
char *arg = arg_start;
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
/*
|
// message.c: functions for displaying messages on the command line
|
||||||
* message.c: functions for displaying messages on the command line
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -48,10 +46,8 @@
|
|||||||
#include "nvim/ui_compositor.h"
|
#include "nvim/ui_compositor.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
|
|
||||||
/*
|
// To be able to scroll back at the "more" and "hit-enter" prompts we need to
|
||||||
* To be able to scroll back at the "more" and "hit-enter" prompts we need to
|
// store the displayed text and remember where screen lines start.
|
||||||
* store the displayed text and remember where screen lines start.
|
|
||||||
*/
|
|
||||||
typedef struct msgchunk_S msgchunk_T;
|
typedef struct msgchunk_S msgchunk_T;
|
||||||
struct msgchunk_S {
|
struct msgchunk_S {
|
||||||
msgchunk_T *sb_next;
|
msgchunk_T *sb_next;
|
||||||
@@ -82,41 +78,39 @@ static int verbose_did_open = false;
|
|||||||
|
|
||||||
bool keep_msg_more = false; // keep_msg was set by msgmore()
|
bool keep_msg_more = false; // keep_msg was set by msgmore()
|
||||||
|
|
||||||
/*
|
// When writing messages to the screen, there are many different situations.
|
||||||
* When writing messages to the screen, there are many different situations.
|
// A number of variables is used to remember the current state:
|
||||||
* A number of variables is used to remember the current state:
|
// msg_didany true when messages were written since the last time the
|
||||||
* msg_didany true when messages were written since the last time the
|
// user reacted to a prompt.
|
||||||
* user reacted to a prompt.
|
// Reset: After hitting a key for the hit-return prompt,
|
||||||
* Reset: After hitting a key for the hit-return prompt,
|
// hitting <CR> for the command line or input().
|
||||||
* hitting <CR> for the command line or input().
|
// Set: When any message is written to the screen.
|
||||||
* Set: When any message is written to the screen.
|
// msg_didout true when something was written to the current line.
|
||||||
* msg_didout true when something was written to the current line.
|
// Reset: When advancing to the next line, when the current
|
||||||
* Reset: When advancing to the next line, when the current
|
// text can be overwritten.
|
||||||
* text can be overwritten.
|
// Set: When any message is written to the screen.
|
||||||
* Set: When any message is written to the screen.
|
// msg_nowait No extra delay for the last drawn message.
|
||||||
* msg_nowait No extra delay for the last drawn message.
|
// Used in normal_cmd() before the mode message is drawn.
|
||||||
* Used in normal_cmd() before the mode message is drawn.
|
// emsg_on_display There was an error message recently. Indicates that there
|
||||||
* emsg_on_display There was an error message recently. Indicates that there
|
// should be a delay before redrawing.
|
||||||
* should be a delay before redrawing.
|
// msg_scroll The next message should not overwrite the current one.
|
||||||
* msg_scroll The next message should not overwrite the current one.
|
// msg_scrolled How many lines the screen has been scrolled (because of
|
||||||
* msg_scrolled How many lines the screen has been scrolled (because of
|
// messages). Used in update_screen() to scroll the screen
|
||||||
* messages). Used in update_screen() to scroll the screen
|
// back. Incremented each time the screen scrolls a line.
|
||||||
* back. Incremented each time the screen scrolls a line.
|
// msg_scrolled_ign true when msg_scrolled is non-zero and msg_puts_attr()
|
||||||
* msg_scrolled_ign true when msg_scrolled is non-zero and msg_puts_attr()
|
// writes something without scrolling should not make
|
||||||
* writes something without scrolling should not make
|
// need_wait_return to be set. This is a hack to make ":ts"
|
||||||
* need_wait_return to be set. This is a hack to make ":ts"
|
// work without an extra prompt.
|
||||||
* work without an extra prompt.
|
// lines_left Number of lines available for messages before the
|
||||||
* lines_left Number of lines available for messages before the
|
// more-prompt is to be given. -1 when not set.
|
||||||
* more-prompt is to be given. -1 when not set.
|
// need_wait_return true when the hit-return prompt is needed.
|
||||||
* need_wait_return true when the hit-return prompt is needed.
|
// Reset: After giving the hit-return prompt, when the user
|
||||||
* Reset: After giving the hit-return prompt, when the user
|
// has answered some other prompt.
|
||||||
* has answered some other prompt.
|
// Set: When the ruler or typeahead display is overwritten,
|
||||||
* Set: When the ruler or typeahead display is overwritten,
|
// scrolling the screen for some message.
|
||||||
* scrolling the screen for some message.
|
// keep_msg Message to be displayed after redrawing the screen, in
|
||||||
* keep_msg Message to be displayed after redrawing the screen, in
|
// main_loop().
|
||||||
* main_loop().
|
// This is an allocated string or NULL when not used.
|
||||||
* This is an allocated string or NULL when not used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Extended msg state, currently used for external UIs with ext_messages
|
// Extended msg state, currently used for external UIs with ext_messages
|
||||||
static const char *msg_ext_kind = NULL;
|
static const char *msg_ext_kind = NULL;
|
||||||
@@ -313,11 +307,9 @@ bool msg_attr_keep(const char *s, int attr, bool keep, bool multiline)
|
|||||||
set_vim_var_string(VV_STATUSMSG, s, -1);
|
set_vim_var_string(VV_STATUSMSG, s, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// It is possible that displaying a messages causes a problem (e.g.,
|
||||||
* It is possible that displaying a messages causes a problem (e.g.,
|
// when redrawing the window), which causes another message, etc.. To
|
||||||
* when redrawing the window), which causes another message, etc.. To
|
// break this loop, limit the recursiveness to 3 levels.
|
||||||
* break this loop, limit the recursiveness to 3 levels.
|
|
||||||
*/
|
|
||||||
if (entered >= 3) {
|
if (entered >= 3) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -483,10 +475,8 @@ void trunc_string(char *s, char *buf, int room_in, int buflen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Note: Caller of smsg() and smsg_attr() must check the resulting string is
|
||||||
* Note: Caller of smsg() and smsg_attr() must check the resulting string is
|
// shorter than IOSIZE!!!
|
||||||
* shorter than IOSIZE!!!
|
|
||||||
*/
|
|
||||||
|
|
||||||
int smsg(const char *s, ...)
|
int smsg(const char *s, ...)
|
||||||
FUNC_ATTR_PRINTF(1, 2)
|
FUNC_ATTR_PRINTF(1, 2)
|
||||||
@@ -522,10 +512,8 @@ int smsg_attr_keep(int attr, const char *s, ...)
|
|||||||
return msg_attr_keep((const char *)IObuff, attr, true, false);
|
return msg_attr_keep((const char *)IObuff, attr, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Remember the last sourcing name/lnum used in an error message, so that it
|
||||||
* Remember the last sourcing name/lnum used in an error message, so that it
|
// isn't printed each time when it didn't change.
|
||||||
* isn't printed each time when it didn't change.
|
|
||||||
*/
|
|
||||||
static int last_sourcing_lnum = 0;
|
static int last_sourcing_lnum = 0;
|
||||||
static char *last_sourcing_name = NULL;
|
static char *last_sourcing_name = NULL;
|
||||||
|
|
||||||
@@ -681,10 +669,8 @@ static bool emsg_multiline(const char *s, bool multiline)
|
|||||||
// set "v:errmsg", also when using ":silent! cmd"
|
// set "v:errmsg", also when using ":silent! cmd"
|
||||||
set_vim_var_string(VV_ERRMSG, s, -1);
|
set_vim_var_string(VV_ERRMSG, s, -1);
|
||||||
|
|
||||||
/*
|
// When using ":silent! cmd" ignore error messages.
|
||||||
* When using ":silent! cmd" ignore error messages.
|
// But do write it to the redirection file.
|
||||||
* But do write it to the redirection file.
|
|
||||||
*/
|
|
||||||
if (emsg_silent != 0) {
|
if (emsg_silent != 0) {
|
||||||
if (!emsg_noredir) {
|
if (!emsg_noredir) {
|
||||||
msg_start();
|
msg_start();
|
||||||
@@ -1156,12 +1142,10 @@ void wait_return(int redraw)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When inside vgetc(), we can't wait for a typed character at all.
|
||||||
* When inside vgetc(), we can't wait for a typed character at all.
|
// With the global command (and some others) we only need one return at
|
||||||
* With the global command (and some others) we only need one return at
|
// the end. Adjust cmdline_row to avoid the next message overwriting the
|
||||||
* the end. Adjust cmdline_row to avoid the next message overwriting the
|
// last one.
|
||||||
* last one.
|
|
||||||
*/
|
|
||||||
if (vgetc_busy > 0) {
|
if (vgetc_busy > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1226,12 +1210,10 @@ void wait_return(int redraw)
|
|||||||
reg_recording = save_reg_recording;
|
reg_recording = save_reg_recording;
|
||||||
scriptout = save_scriptout;
|
scriptout = save_scriptout;
|
||||||
|
|
||||||
/*
|
// Allow scrolling back in the messages.
|
||||||
* Allow scrolling back in the messages.
|
// Also accept scroll-down commands when messages fill the screen,
|
||||||
* Also accept scroll-down commands when messages fill the screen,
|
// to avoid that typing one 'j' too many makes the messages
|
||||||
* to avoid that typing one 'j' too many makes the messages
|
// disappear.
|
||||||
* disappear.
|
|
||||||
*/
|
|
||||||
if (p_more) {
|
if (p_more) {
|
||||||
if (c == 'b' || c == 'k' || c == 'u' || c == 'g'
|
if (c == 'b' || c == 'k' || c == 'u' || c == 'g'
|
||||||
|| c == K_UP || c == K_PAGEUP) {
|
|| c == K_UP || c == K_PAGEUP) {
|
||||||
@@ -1268,9 +1250,7 @@ void wait_return(int redraw)
|
|||||||
|| c == K_MOUSEDOWN || c == K_MOUSEUP
|
|| c == K_MOUSEDOWN || c == K_MOUSEUP
|
||||||
|| c == K_MOUSEMOVE);
|
|| c == K_MOUSEMOVE);
|
||||||
os_breakcheck();
|
os_breakcheck();
|
||||||
/*
|
// Avoid that the mouse-up event causes visual mode to start.
|
||||||
* Avoid that the mouse-up event causes visual mode to start.
|
|
||||||
*/
|
|
||||||
if (c == K_LEFTMOUSE || c == K_MIDDLEMOUSE || c == K_RIGHTMOUSE
|
if (c == K_LEFTMOUSE || c == K_MIDDLEMOUSE || c == K_RIGHTMOUSE
|
||||||
|| c == K_X1MOUSE || c == K_X2MOUSE) {
|
|| c == K_X1MOUSE || c == K_X2MOUSE) {
|
||||||
(void)jump_to_mouse(MOUSE_SETPOS, NULL, 0);
|
(void)jump_to_mouse(MOUSE_SETPOS, NULL, 0);
|
||||||
@@ -1575,10 +1555,8 @@ int msg_outtrans_len_attr(const char *msgstr, int len, int attr)
|
|||||||
msg_puts_attr(" ", attr);
|
msg_puts_attr(" ", attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Go over the string. Special characters are translated and printed.
|
||||||
* Go over the string. Special characters are translated and printed.
|
// Normal characters are printed several at a time.
|
||||||
* Normal characters are printed several at a time.
|
|
||||||
*/
|
|
||||||
while (--len >= 0 && !got_int) {
|
while (--len >= 0 && !got_int) {
|
||||||
// Don't include composing chars after the end.
|
// Don't include composing chars after the end.
|
||||||
mb_l = utfc_ptr2len_len(str, len + 1);
|
mb_l = utfc_ptr2len_len(str, len + 1);
|
||||||
@@ -2250,10 +2228,8 @@ static void msg_puts_display(const char *str, int maxlen, int attr, int recurse)
|
|||||||
cmdline_row--;
|
cmdline_row--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If screen is completely filled and 'more' is set then wait
|
||||||
* If screen is completely filled and 'more' is set then wait
|
// for a character.
|
||||||
* for a character.
|
|
||||||
*/
|
|
||||||
if (lines_left > 0) {
|
if (lines_left > 0) {
|
||||||
lines_left--;
|
lines_left--;
|
||||||
}
|
}
|
||||||
@@ -2828,9 +2804,7 @@ static int do_more_prompt(int typed_char)
|
|||||||
msg_moremsg(false);
|
msg_moremsg(false);
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/*
|
// Get a typed character directly from the user.
|
||||||
* Get a typed character directly from the user.
|
|
||||||
*/
|
|
||||||
if (used_typed_char != NUL) {
|
if (used_typed_char != NUL) {
|
||||||
c = used_typed_char; // was typed at hit-enter prompt
|
c = used_typed_char; // was typed at hit-enter prompt
|
||||||
used_typed_char = NUL;
|
used_typed_char = NUL;
|
||||||
@@ -3170,12 +3144,10 @@ void msg_clr_cmdline(void)
|
|||||||
/// @return true if wait_return() not called.
|
/// @return true if wait_return() not called.
|
||||||
int msg_end(void)
|
int msg_end(void)
|
||||||
{
|
{
|
||||||
/*
|
// If the string is larger than the window,
|
||||||
* If the string is larger than the window,
|
// or the ruler option is set and we run into it,
|
||||||
* or the ruler option is set and we run into it,
|
// we have to redraw the window.
|
||||||
* we have to redraw the window.
|
// Do not do this if we are abandoning the file or editing the command line.
|
||||||
* Do not do this if we are abandoning the file or editing the command line.
|
|
||||||
*/
|
|
||||||
if (!exiting && need_wait_return && !(State & MODE_CMDLINE)) {
|
if (!exiting && need_wait_return && !(State & MODE_CMDLINE)) {
|
||||||
wait_return(false);
|
wait_return(false);
|
||||||
return false;
|
return false;
|
||||||
@@ -3545,10 +3517,8 @@ int do_dialog(int type, char *title, char *message, char *buttons, int dfltbutto
|
|||||||
State = MODE_CONFIRM;
|
State = MODE_CONFIRM;
|
||||||
setmouse();
|
setmouse();
|
||||||
|
|
||||||
/*
|
// Since we wait for a keypress, don't make the
|
||||||
* Since we wait for a keypress, don't make the
|
// user press RETURN as well afterwards.
|
||||||
* user press RETURN as well afterwards.
|
|
||||||
*/
|
|
||||||
no_wait_return++;
|
no_wait_return++;
|
||||||
hotkeys = msg_show_console_dialog(message, buttons, dfltbutton);
|
hotkeys = msg_show_console_dialog(message, buttons, dfltbutton);
|
||||||
|
|
||||||
|
@@ -11,9 +11,7 @@
|
|||||||
#include "nvim/macros.h"
|
#include "nvim/macros.h"
|
||||||
#include "nvim/types.h"
|
#include "nvim/types.h"
|
||||||
|
|
||||||
/*
|
// Types of dialogs passed to do_dialog().
|
||||||
* Types of dialogs passed to do_dialog().
|
|
||||||
*/
|
|
||||||
#define VIM_GENERIC 0
|
#define VIM_GENERIC 0
|
||||||
#define VIM_ERROR 1
|
#define VIM_ERROR 1
|
||||||
#define VIM_WARNING 2
|
#define VIM_WARNING 2
|
||||||
@@ -21,9 +19,7 @@
|
|||||||
#define VIM_QUESTION 4
|
#define VIM_QUESTION 4
|
||||||
#define VIM_LAST_TYPE 4 // sentinel value
|
#define VIM_LAST_TYPE 4 // sentinel value
|
||||||
|
|
||||||
/*
|
// Return values for functions like vim_dialogyesno()
|
||||||
* Return values for functions like vim_dialogyesno()
|
|
||||||
*/
|
|
||||||
#define VIM_YES 2
|
#define VIM_YES 2
|
||||||
#define VIM_NO 3
|
#define VIM_NO 3
|
||||||
#define VIM_CANCEL 4
|
#define VIM_CANCEL 4
|
||||||
|
384
src/nvim/move.c
384
src/nvim/move.c
@@ -1,16 +1,14 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
/*
|
// move.c: Functions for moving the cursor and scrolling text.
|
||||||
* move.c: Functions for moving the cursor and scrolling text.
|
//
|
||||||
*
|
// There are two ways to move the cursor:
|
||||||
* There are two ways to move the cursor:
|
// 1. Move the cursor directly, the text is scrolled to keep the cursor in the
|
||||||
* 1. Move the cursor directly, the text is scrolled to keep the cursor in the
|
// window.
|
||||||
* window.
|
// 2. Scroll the text, the cursor is moved into the text visible in the
|
||||||
* 2. Scroll the text, the cursor is moved into the text visible in the
|
// window.
|
||||||
* window.
|
// The 'scrolloff' option makes this a bit complicated.
|
||||||
* The 'scrolloff' option makes this a bit complicated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -47,19 +45,15 @@ typedef struct {
|
|||||||
# include "move.c.generated.h"
|
# include "move.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
// Compute wp->w_botline for the current wp->w_topline. Can be called after
|
||||||
* Compute wp->w_botline for the current wp->w_topline. Can be called after
|
// wp->w_topline changed.
|
||||||
* wp->w_topline changed.
|
|
||||||
*/
|
|
||||||
static void comp_botline(win_T *wp)
|
static void comp_botline(win_T *wp)
|
||||||
{
|
{
|
||||||
linenr_T lnum;
|
linenr_T lnum;
|
||||||
int done;
|
int done;
|
||||||
|
|
||||||
/*
|
// If w_cline_row is valid, start there.
|
||||||
* If w_cline_row is valid, start there.
|
// Otherwise have to start at w_topline.
|
||||||
* Otherwise have to start at w_topline.
|
|
||||||
*/
|
|
||||||
check_cursor_moved(wp);
|
check_cursor_moved(wp);
|
||||||
if (wp->w_valid & VALID_CROW) {
|
if (wp->w_valid & VALID_CROW) {
|
||||||
lnum = wp->w_cursor.lnum;
|
lnum = wp->w_cursor.lnum;
|
||||||
@@ -133,10 +127,8 @@ static void redraw_for_cursorcolumn(win_T *wp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Update curwin->w_topline and redraw if necessary.
|
||||||
* Update curwin->w_topline and redraw if necessary.
|
// Used to update the screen before printing a message.
|
||||||
* Used to update the screen before printing a message.
|
|
||||||
*/
|
|
||||||
void update_topline_redraw(void)
|
void update_topline_redraw(void)
|
||||||
{
|
{
|
||||||
update_topline(curwin);
|
update_topline(curwin);
|
||||||
@@ -145,9 +137,7 @@ void update_topline_redraw(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Update curwin->w_topline to move the cursor onto the screen.
|
||||||
* Update curwin->w_topline to move the cursor onto the screen.
|
|
||||||
*/
|
|
||||||
void update_topline(win_T *wp)
|
void update_topline(win_T *wp)
|
||||||
{
|
{
|
||||||
linenr_T old_topline;
|
linenr_T old_topline;
|
||||||
@@ -250,14 +240,12 @@ void update_topline(win_T *wp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If the cursor is below the bottom of the window, scroll the window
|
||||||
* If the cursor is below the bottom of the window, scroll the window
|
// to put the cursor on the window.
|
||||||
* to put the cursor on the window.
|
// When w_botline is invalid, recompute it first, to avoid a redraw later.
|
||||||
* When w_botline is invalid, recompute it first, to avoid a redraw later.
|
// If w_botline was approximated, we might need a redraw later in a few
|
||||||
* If w_botline was approximated, we might need a redraw later in a few
|
// cases, but we don't want to spend (a lot of) time recomputing w_botline
|
||||||
* cases, but we don't want to spend (a lot of) time recomputing w_botline
|
// for every small change.
|
||||||
* for every small change.
|
|
||||||
*/
|
|
||||||
if (check_botline) {
|
if (check_botline) {
|
||||||
if (!(wp->w_valid & VALID_BOTLINE_AP)) {
|
if (!(wp->w_valid & VALID_BOTLINE_AP)) {
|
||||||
validate_botline(wp);
|
validate_botline(wp);
|
||||||
@@ -328,9 +316,7 @@ void update_topline(win_T *wp)
|
|||||||
wp->w_viewport_invalid = true;
|
wp->w_viewport_invalid = true;
|
||||||
win_check_anchored_floats(wp);
|
win_check_anchored_floats(wp);
|
||||||
|
|
||||||
/*
|
// Need to redraw when topline changed.
|
||||||
* Need to redraw when topline changed.
|
|
||||||
*/
|
|
||||||
if (wp->w_topline != old_topline
|
if (wp->w_topline != old_topline
|
||||||
|| wp->w_topfill != old_topfill) {
|
|| wp->w_topfill != old_topfill) {
|
||||||
dollar_vcol = -1;
|
dollar_vcol = -1;
|
||||||
@@ -349,9 +335,7 @@ void update_topline(win_T *wp)
|
|||||||
*so_ptr = save_so;
|
*so_ptr = save_so;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Update win->w_topline to move the cursor onto the screen.
|
||||||
* Update win->w_topline to move the cursor onto the screen.
|
|
||||||
*/
|
|
||||||
void update_topline_win(win_T *win)
|
void update_topline_win(win_T *win)
|
||||||
{
|
{
|
||||||
switchwin_T switchwin;
|
switchwin_T switchwin;
|
||||||
@@ -360,11 +344,9 @@ void update_topline_win(win_T *win)
|
|||||||
restore_win(&switchwin, true);
|
restore_win(&switchwin, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return the scrolljump value to use for the current window.
|
||||||
* Return the scrolljump value to use for the current window.
|
// When 'scrolljump' is positive use it as-is.
|
||||||
* When 'scrolljump' is positive use it as-is.
|
// When 'scrolljump' is negative use it as a percentage of the window height.
|
||||||
* When 'scrolljump' is negative use it as a percentage of the window height.
|
|
||||||
*/
|
|
||||||
static int scrolljump_value(void)
|
static int scrolljump_value(void)
|
||||||
{
|
{
|
||||||
long result = p_sj >= 0 ? p_sj : (curwin->w_height_inner * -p_sj) / 100;
|
long result = p_sj >= 0 ? p_sj : (curwin->w_height_inner * -p_sj) / 100;
|
||||||
@@ -372,10 +354,8 @@ static int scrolljump_value(void)
|
|||||||
return (int)result;
|
return (int)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return true when there are not 'scrolloff' lines above the cursor for the
|
||||||
* Return true when there are not 'scrolloff' lines above the cursor for the
|
// current window.
|
||||||
* current window.
|
|
||||||
*/
|
|
||||||
static bool check_top_offset(void)
|
static bool check_top_offset(void)
|
||||||
{
|
{
|
||||||
long so = get_scrolloff_value(curwin);
|
long so = get_scrolloff_value(curwin);
|
||||||
@@ -412,9 +392,7 @@ void update_curswant(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check if the cursor has moved. Set the w_valid flag accordingly.
|
||||||
* Check if the cursor has moved. Set the w_valid flag accordingly.
|
|
||||||
*/
|
|
||||||
void check_cursor_moved(win_T *wp)
|
void check_cursor_moved(win_T *wp)
|
||||||
{
|
{
|
||||||
if (wp->w_cursor.lnum != wp->w_valid_cursor.lnum) {
|
if (wp->w_cursor.lnum != wp->w_valid_cursor.lnum) {
|
||||||
@@ -435,11 +413,9 @@ void check_cursor_moved(win_T *wp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Call this function when some window settings have changed, which require
|
||||||
* Call this function when some window settings have changed, which require
|
// the cursor position, botline and topline to be recomputed and the window to
|
||||||
* the cursor position, botline and topline to be recomputed and the window to
|
// be redrawn. E.g, when changing the 'wrap' option or folding.
|
||||||
* be redrawn. E.g, when changing the 'wrap' option or folding.
|
|
||||||
*/
|
|
||||||
void changed_window_setting(void)
|
void changed_window_setting(void)
|
||||||
{
|
{
|
||||||
changed_window_setting_win(curwin);
|
changed_window_setting_win(curwin);
|
||||||
@@ -453,9 +429,7 @@ void changed_window_setting_win(win_T *wp)
|
|||||||
redraw_later(wp, UPD_NOT_VALID);
|
redraw_later(wp, UPD_NOT_VALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set wp->w_topline to a certain number.
|
||||||
* Set wp->w_topline to a certain number.
|
|
||||||
*/
|
|
||||||
void set_topline(win_T *wp, linenr_T lnum)
|
void set_topline(win_T *wp, linenr_T lnum)
|
||||||
{
|
{
|
||||||
linenr_T prev_topline = wp->w_topline;
|
linenr_T prev_topline = wp->w_topline;
|
||||||
@@ -475,11 +449,9 @@ void set_topline(win_T *wp, linenr_T lnum)
|
|||||||
redraw_later(wp, UPD_VALID);
|
redraw_later(wp, UPD_VALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Call this function when the length of the cursor line (in screen
|
||||||
* Call this function when the length of the cursor line (in screen
|
// characters) has changed, and the change is before the cursor.
|
||||||
* characters) has changed, and the change is before the cursor.
|
// Need to take care of w_botline separately!
|
||||||
* Need to take care of w_botline separately!
|
|
||||||
*/
|
|
||||||
void changed_cline_bef_curs(void)
|
void changed_cline_bef_curs(void)
|
||||||
{
|
{
|
||||||
curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
|
curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
|
||||||
@@ -492,11 +464,9 @@ void changed_cline_bef_curs_win(win_T *wp)
|
|||||||
|VALID_CHEIGHT|VALID_TOPLINE);
|
|VALID_CHEIGHT|VALID_TOPLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Call this function when the length of a line (in screen characters) above
|
||||||
* Call this function when the length of a line (in screen characters) above
|
// the cursor have changed.
|
||||||
* the cursor have changed.
|
// Need to take care of w_botline separately!
|
||||||
* Need to take care of w_botline separately!
|
|
||||||
*/
|
|
||||||
void changed_line_abv_curs(void)
|
void changed_line_abv_curs(void)
|
||||||
{
|
{
|
||||||
curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW
|
curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW
|
||||||
@@ -509,9 +479,7 @@ void changed_line_abv_curs_win(win_T *wp)
|
|||||||
|VALID_CHEIGHT|VALID_TOPLINE);
|
|VALID_CHEIGHT|VALID_TOPLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Make sure the value of curwin->w_botline is valid.
|
||||||
* Make sure the value of curwin->w_botline is valid.
|
|
||||||
*/
|
|
||||||
void validate_botline(win_T *wp)
|
void validate_botline(win_T *wp)
|
||||||
{
|
{
|
||||||
if (!(wp->w_valid & VALID_BOTLINE)) {
|
if (!(wp->w_valid & VALID_BOTLINE)) {
|
||||||
@@ -519,9 +487,7 @@ void validate_botline(win_T *wp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Mark curwin->w_botline as invalid (because of some change in the buffer).
|
||||||
* Mark curwin->w_botline as invalid (because of some change in the buffer).
|
|
||||||
*/
|
|
||||||
void invalidate_botline(void)
|
void invalidate_botline(void)
|
||||||
{
|
{
|
||||||
curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
|
curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
|
||||||
@@ -537,9 +503,7 @@ void approximate_botline_win(win_T *wp)
|
|||||||
wp->w_valid &= ~VALID_BOTLINE;
|
wp->w_valid &= ~VALID_BOTLINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return true if curwin->w_wrow and curwin->w_wcol are valid.
|
||||||
* Return true if curwin->w_wrow and curwin->w_wcol are valid.
|
|
||||||
*/
|
|
||||||
int cursor_valid(void)
|
int cursor_valid(void)
|
||||||
{
|
{
|
||||||
check_cursor_moved(curwin);
|
check_cursor_moved(curwin);
|
||||||
@@ -547,10 +511,8 @@ int cursor_valid(void)
|
|||||||
(VALID_WROW|VALID_WCOL);
|
(VALID_WROW|VALID_WCOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Validate cursor position. Makes sure w_wrow and w_wcol are valid.
|
||||||
* Validate cursor position. Makes sure w_wrow and w_wcol are valid.
|
// w_topline must be valid, you may need to call update_topline() first!
|
||||||
* w_topline must be valid, you may need to call update_topline() first!
|
|
||||||
*/
|
|
||||||
void validate_cursor(void)
|
void validate_cursor(void)
|
||||||
{
|
{
|
||||||
check_cursor_moved(curwin);
|
check_cursor_moved(curwin);
|
||||||
@@ -559,10 +521,8 @@ void validate_cursor(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Compute wp->w_cline_row and wp->w_cline_height, based on the current value
|
||||||
* Compute wp->w_cline_row and wp->w_cline_height, based on the current value
|
// of wp->w_topline.
|
||||||
* of wp->w_topline.
|
|
||||||
*/
|
|
||||||
static void curs_rows(win_T *wp)
|
static void curs_rows(win_T *wp)
|
||||||
{
|
{
|
||||||
// Check if wp->w_lines[].wl_size is invalid
|
// Check if wp->w_lines[].wl_size is invalid
|
||||||
@@ -633,17 +593,13 @@ static void curs_rows(win_T *wp)
|
|||||||
wp->w_valid |= VALID_CROW|VALID_CHEIGHT;
|
wp->w_valid |= VALID_CROW|VALID_CHEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Validate curwin->w_virtcol only.
|
||||||
* Validate curwin->w_virtcol only.
|
|
||||||
*/
|
|
||||||
void validate_virtcol(void)
|
void validate_virtcol(void)
|
||||||
{
|
{
|
||||||
validate_virtcol_win(curwin);
|
validate_virtcol_win(curwin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Validate wp->w_virtcol only.
|
||||||
* Validate wp->w_virtcol only.
|
|
||||||
*/
|
|
||||||
void validate_virtcol_win(win_T *wp)
|
void validate_virtcol_win(win_T *wp)
|
||||||
{
|
{
|
||||||
check_cursor_moved(wp);
|
check_cursor_moved(wp);
|
||||||
@@ -654,9 +610,7 @@ void validate_virtcol_win(win_T *wp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Validate curwin->w_cline_height only.
|
||||||
* Validate curwin->w_cline_height only.
|
|
||||||
*/
|
|
||||||
void validate_cheight(void)
|
void validate_cheight(void)
|
||||||
{
|
{
|
||||||
check_cursor_moved(curwin);
|
check_cursor_moved(curwin);
|
||||||
@@ -668,9 +622,7 @@ void validate_cheight(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Validate w_wcol and w_virtcol only.
|
||||||
* Validate w_wcol and w_virtcol only.
|
|
||||||
*/
|
|
||||||
void validate_cursor_col(void)
|
void validate_cursor_col(void)
|
||||||
{
|
{
|
||||||
validate_virtcol();
|
validate_virtcol();
|
||||||
@@ -697,10 +649,8 @@ void validate_cursor_col(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Compute offset of a window, occupied by absolute or relative line number,
|
||||||
* Compute offset of a window, occupied by absolute or relative line number,
|
// fold column and sign column (these don't move when scrolling horizontally).
|
||||||
* fold column and sign column (these don't move when scrolling horizontally).
|
|
||||||
*/
|
|
||||||
int win_col_off(win_T *wp)
|
int win_col_off(win_T *wp)
|
||||||
{
|
{
|
||||||
return ((wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) + 1 : 0)
|
return ((wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) + 1 : 0)
|
||||||
@@ -714,11 +664,9 @@ int curwin_col_off(void)
|
|||||||
return win_col_off(curwin);
|
return win_col_off(curwin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return the difference in column offset for the second screen line of a
|
||||||
* Return the difference in column offset for the second screen line of a
|
// wrapped line. It's 8 if 'number' or 'relativenumber' is on and 'n' is in
|
||||||
* wrapped line. It's 8 if 'number' or 'relativenumber' is on and 'n' is in
|
// 'cpoptions'.
|
||||||
* 'cpoptions'.
|
|
||||||
*/
|
|
||||||
int win_col_off2(win_T *wp)
|
int win_col_off2(win_T *wp)
|
||||||
{
|
{
|
||||||
if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) != NULL) {
|
if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) != NULL) {
|
||||||
@@ -746,9 +694,7 @@ void curs_columns(win_T *wp, int may_scroll)
|
|||||||
long so = get_scrolloff_value(wp);
|
long so = get_scrolloff_value(wp);
|
||||||
long siso = get_sidescrolloff_value(wp);
|
long siso = get_sidescrolloff_value(wp);
|
||||||
|
|
||||||
/*
|
// First make sure that w_topline is valid (after moving the cursor).
|
||||||
* First make sure that w_topline is valid (after moving the cursor).
|
|
||||||
*/
|
|
||||||
update_topline(wp);
|
update_topline(wp);
|
||||||
|
|
||||||
// Next make sure that w_cline_row is valid.
|
// Next make sure that w_cline_row is valid.
|
||||||
@@ -756,9 +702,7 @@ void curs_columns(win_T *wp, int may_scroll)
|
|||||||
curs_rows(wp);
|
curs_rows(wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Compute the number of virtual columns.
|
||||||
* Compute the number of virtual columns.
|
|
||||||
*/
|
|
||||||
if (wp->w_cline_folded) {
|
if (wp->w_cline_folded) {
|
||||||
// In a folded line the cursor is always in the first column
|
// In a folded line the cursor is always in the first column
|
||||||
startcol = wp->w_virtcol = endcol = wp->w_leftcol;
|
startcol = wp->w_virtcol = endcol = wp->w_leftcol;
|
||||||
@@ -1079,10 +1023,8 @@ bool scrolldown(long line_count, int byfold)
|
|||||||
}
|
}
|
||||||
check_topfill(curwin, true);
|
check_topfill(curwin, true);
|
||||||
|
|
||||||
/*
|
// Compute the row number of the last row of the cursor line
|
||||||
* Compute the row number of the last row of the cursor line
|
// and move the cursor onto the displayed part of the window.
|
||||||
* and move the cursor onto the displayed part of the window.
|
|
||||||
*/
|
|
||||||
int wrow = curwin->w_wrow;
|
int wrow = curwin->w_wrow;
|
||||||
if (curwin->w_p_wrap && curwin->w_width_inner != 0) {
|
if (curwin->w_p_wrap && curwin->w_width_inner != 0) {
|
||||||
validate_virtcol();
|
validate_virtcol();
|
||||||
@@ -1200,10 +1142,8 @@ void check_topfill(win_T *wp, bool down)
|
|||||||
win_check_anchored_floats(curwin);
|
win_check_anchored_floats(curwin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Use as many filler lines as possible for w_topline. Make sure w_topline
|
||||||
* Use as many filler lines as possible for w_topline. Make sure w_topline
|
// is still visible.
|
||||||
* is still visible.
|
|
||||||
*/
|
|
||||||
static void max_topfill(void)
|
static void max_topfill(void)
|
||||||
{
|
{
|
||||||
int n = plines_win_nofill(curwin, curwin->w_topline, true);
|
int n = plines_win_nofill(curwin, curwin->w_topline, true);
|
||||||
@@ -1217,10 +1157,8 @@ static void max_topfill(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Scroll the screen one line down, but don't do it if it would move the
|
||||||
* Scroll the screen one line down, but don't do it if it would move the
|
// cursor off the screen.
|
||||||
* cursor off the screen.
|
|
||||||
*/
|
|
||||||
void scrolldown_clamp(void)
|
void scrolldown_clamp(void)
|
||||||
{
|
{
|
||||||
int can_fill = (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline));
|
int can_fill = (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline));
|
||||||
@@ -1261,10 +1199,8 @@ void scrolldown_clamp(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Scroll the screen one line up, but don't do it if it would move the cursor
|
||||||
* Scroll the screen one line up, but don't do it if it would move the cursor
|
// off the screen.
|
||||||
* off the screen.
|
|
||||||
*/
|
|
||||||
void scrollup_clamp(void)
|
void scrollup_clamp(void)
|
||||||
{
|
{
|
||||||
if (curwin->w_topline == curbuf->b_ml.ml_line_count
|
if (curwin->w_topline == curbuf->b_ml.ml_line_count
|
||||||
@@ -1296,12 +1232,10 @@ void scrollup_clamp(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Add one line above "lp->lnum". This can be a filler line, a closed fold or
|
||||||
* Add one line above "lp->lnum". This can be a filler line, a closed fold or
|
// a (wrapped) text line. Uses and sets "lp->fill".
|
||||||
* a (wrapped) text line. Uses and sets "lp->fill".
|
// Returns the height of the added line in "lp->height".
|
||||||
* Returns the height of the added line in "lp->height".
|
// Lines above the first one are incredibly high: MAXCOL.
|
||||||
* Lines above the first one are incredibly high: MAXCOL.
|
|
||||||
*/
|
|
||||||
static void topline_back(win_T *wp, lineoff_T *lp)
|
static void topline_back(win_T *wp, lineoff_T *lp)
|
||||||
{
|
{
|
||||||
if (lp->fill < win_get_fill(wp, lp->lnum)) {
|
if (lp->fill < win_get_fill(wp, lp->lnum)) {
|
||||||
@@ -1322,12 +1256,10 @@ static void topline_back(win_T *wp, lineoff_T *lp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Add one line below "lp->lnum". This can be a filler line, a closed fold or
|
||||||
* Add one line below "lp->lnum". This can be a filler line, a closed fold or
|
// a (wrapped) text line. Uses and sets "lp->fill".
|
||||||
* a (wrapped) text line. Uses and sets "lp->fill".
|
// Returns the height of the added line in "lp->height".
|
||||||
* Returns the height of the added line in "lp->height".
|
// Lines below the last one are incredibly high.
|
||||||
* Lines below the last one are incredibly high.
|
|
||||||
*/
|
|
||||||
static void botline_forw(win_T *wp, lineoff_T *lp)
|
static void botline_forw(win_T *wp, lineoff_T *lp)
|
||||||
{
|
{
|
||||||
if (lp->fill < win_get_fill(wp, lp->lnum + 1)) {
|
if (lp->fill < win_get_fill(wp, lp->lnum + 1)) {
|
||||||
@@ -1349,11 +1281,9 @@ static void botline_forw(win_T *wp, lineoff_T *lp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Switch from including filler lines below lp->lnum to including filler
|
||||||
* Switch from including filler lines below lp->lnum to including filler
|
// lines above loff.lnum + 1. This keeps pointing to the same line.
|
||||||
* lines above loff.lnum + 1. This keeps pointing to the same line.
|
// When there are no filler lines nothing changes.
|
||||||
* When there are no filler lines nothing changes.
|
|
||||||
*/
|
|
||||||
static void botline_topline(lineoff_T *lp)
|
static void botline_topline(lineoff_T *lp)
|
||||||
{
|
{
|
||||||
if (lp->fill > 0) {
|
if (lp->fill > 0) {
|
||||||
@@ -1362,11 +1292,9 @@ static void botline_topline(lineoff_T *lp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Switch from including filler lines above lp->lnum to including filler
|
||||||
* Switch from including filler lines above lp->lnum to including filler
|
// lines below loff.lnum - 1. This keeps pointing to the same line.
|
||||||
* lines below loff.lnum - 1. This keeps pointing to the same line.
|
// When there are no filler lines nothing changes.
|
||||||
* When there are no filler lines nothing changes.
|
|
||||||
*/
|
|
||||||
static void topline_botline(lineoff_T *lp)
|
static void topline_botline(lineoff_T *lp)
|
||||||
{
|
{
|
||||||
if (lp->fill > 0) {
|
if (lp->fill > 0) {
|
||||||
@@ -1375,11 +1303,9 @@ static void topline_botline(lineoff_T *lp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Recompute topline to put the cursor at the top of the window.
|
||||||
* Recompute topline to put the cursor at the top of the window.
|
// Scroll at least "min_scroll" lines.
|
||||||
* Scroll at least "min_scroll" lines.
|
// If "always" is true, always set topline (for "zt").
|
||||||
* If "always" is true, always set topline (for "zt").
|
|
||||||
*/
|
|
||||||
void scroll_cursor_top(int min_scroll, int always)
|
void scroll_cursor_top(int min_scroll, int always)
|
||||||
{
|
{
|
||||||
int scrolled = 0;
|
int scrolled = 0;
|
||||||
@@ -1394,13 +1320,11 @@ void scroll_cursor_top(int min_scroll, int always)
|
|||||||
off = mouse_dragging - 1;
|
off = mouse_dragging - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Decrease topline until:
|
||||||
* Decrease topline until:
|
// - it has become 1
|
||||||
* - it has become 1
|
// - (part of) the cursor line is moved off the screen or
|
||||||
* - (part of) the cursor line is moved off the screen or
|
// - moved at least 'scrolljump' lines and
|
||||||
* - moved at least 'scrolljump' lines and
|
// - at least 'scrolloff' lines above and below the cursor
|
||||||
* - at least 'scrolloff' lines above and below the cursor
|
|
||||||
*/
|
|
||||||
validate_cheight();
|
validate_cheight();
|
||||||
int used = curwin->w_cline_height; // includes filler lines above
|
int used = curwin->w_cline_height; // includes filler lines above
|
||||||
if (curwin->w_cursor.lnum < curwin->w_topline) {
|
if (curwin->w_cursor.lnum < curwin->w_topline) {
|
||||||
@@ -1421,10 +1345,8 @@ void scroll_cursor_top(int min_scroll, int always)
|
|||||||
// Hide filler lines above cursor line by adding them to "extra".
|
// Hide filler lines above cursor line by adding them to "extra".
|
||||||
int extra = win_get_fill(curwin, curwin->w_cursor.lnum);
|
int extra = win_get_fill(curwin, curwin->w_cursor.lnum);
|
||||||
|
|
||||||
/*
|
// Check if the lines from "top" to "bot" fit in the window. If they do,
|
||||||
* Check if the lines from "top" to "bot" fit in the window. If they do,
|
// set new_topline and advance "top" and "bot" to include more lines.
|
||||||
* set new_topline and advance "top" and "bot" to include more lines.
|
|
||||||
*/
|
|
||||||
while (top > 0) {
|
while (top > 0) {
|
||||||
int i = hasFolding(top, &top, NULL)
|
int i = hasFolding(top, &top, NULL)
|
||||||
? 1 // count one logical line for a sequence of folded lines
|
? 1 // count one logical line for a sequence of folded lines
|
||||||
@@ -1445,9 +1367,7 @@ void scroll_cursor_top(int min_scroll, int always)
|
|||||||
scrolled += i;
|
scrolled += i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If scrolling is needed, scroll at least 'sj' lines.
|
||||||
* If scrolling is needed, scroll at least 'sj' lines.
|
|
||||||
*/
|
|
||||||
if ((new_topline >= curwin->w_topline || scrolled > min_scroll)
|
if ((new_topline >= curwin->w_topline || scrolled > min_scroll)
|
||||||
&& extra >= off) {
|
&& extra >= off) {
|
||||||
break;
|
break;
|
||||||
@@ -1459,18 +1379,14 @@ void scroll_cursor_top(int min_scroll, int always)
|
|||||||
bot++;
|
bot++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we don't have enough space, put cursor in the middle.
|
||||||
* If we don't have enough space, put cursor in the middle.
|
// This makes sure we get the same position when using "k" and "j"
|
||||||
* This makes sure we get the same position when using "k" and "j"
|
// in a small window.
|
||||||
* in a small window.
|
|
||||||
*/
|
|
||||||
if (used > curwin->w_height_inner) {
|
if (used > curwin->w_height_inner) {
|
||||||
scroll_cursor_halfway(false);
|
scroll_cursor_halfway(false);
|
||||||
} else {
|
} else {
|
||||||
/*
|
// If "always" is false, only adjust topline to a lower value, higher
|
||||||
* If "always" is false, only adjust topline to a lower value, higher
|
// value may happen with wrapping lines
|
||||||
* value may happen with wrapping lines
|
|
||||||
*/
|
|
||||||
if (new_topline < curwin->w_topline || always) {
|
if (new_topline < curwin->w_topline || always) {
|
||||||
curwin->w_topline = new_topline;
|
curwin->w_topline = new_topline;
|
||||||
}
|
}
|
||||||
@@ -1495,10 +1411,8 @@ void scroll_cursor_top(int min_scroll, int always)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set w_empty_rows and w_filler_rows for window "wp", having used up "used"
|
||||||
* Set w_empty_rows and w_filler_rows for window "wp", having used up "used"
|
// screen lines for text lines.
|
||||||
* screen lines for text lines.
|
|
||||||
*/
|
|
||||||
void set_empty_rows(win_T *wp, int used)
|
void set_empty_rows(win_T *wp, int used)
|
||||||
{
|
{
|
||||||
wp->w_filler_rows = 0;
|
wp->w_filler_rows = 0;
|
||||||
@@ -1577,13 +1491,11 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Stop counting lines to scroll when
|
||||||
* Stop counting lines to scroll when
|
// - hitting start of the file
|
||||||
* - hitting start of the file
|
// - scrolled nothing or at least 'sj' lines
|
||||||
* - scrolled nothing or at least 'sj' lines
|
// - at least 'so' lines below the cursor
|
||||||
* - at least 'so' lines below the cursor
|
// - lines between botline and cursor have been counted
|
||||||
* - lines between botline and cursor have been counted
|
|
||||||
*/
|
|
||||||
if (!hasFolding(curwin->w_cursor.lnum, &loff.lnum, &boff.lnum)) {
|
if (!hasFolding(curwin->w_cursor.lnum, &loff.lnum, &boff.lnum)) {
|
||||||
loff.lnum = cln;
|
loff.lnum = cln;
|
||||||
boff.lnum = cln;
|
boff.lnum = cln;
|
||||||
@@ -1673,21 +1585,17 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Scroll up if the cursor is off the bottom of the screen a bit.
|
||||||
* Scroll up if the cursor is off the bottom of the screen a bit.
|
// Otherwise put it at 1/2 of the screen.
|
||||||
* Otherwise put it at 1/2 of the screen.
|
|
||||||
*/
|
|
||||||
if (line_count >= curwin->w_height_inner && line_count > min_scroll) {
|
if (line_count >= curwin->w_height_inner && line_count > min_scroll) {
|
||||||
scroll_cursor_halfway(false);
|
scroll_cursor_halfway(false);
|
||||||
} else {
|
} else {
|
||||||
scrollup(line_count, true);
|
scrollup(line_count, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If topline didn't change we need to restore w_botline and w_empty_rows
|
||||||
* If topline didn't change we need to restore w_botline and w_empty_rows
|
// (we changed them).
|
||||||
* (we changed them).
|
// If topline did change, update_screen() will set botline.
|
||||||
* If topline did change, update_screen() will set botline.
|
|
||||||
*/
|
|
||||||
if (curwin->w_topline == old_topline && set_topbot) {
|
if (curwin->w_topline == old_topline && set_topbot) {
|
||||||
curwin->w_botline = old_botline;
|
curwin->w_botline = old_botline;
|
||||||
curwin->w_empty_rows = old_empty_rows;
|
curwin->w_empty_rows = old_empty_rows;
|
||||||
@@ -1760,18 +1668,14 @@ void scroll_cursor_halfway(int atend)
|
|||||||
curwin->w_valid |= VALID_TOPLINE;
|
curwin->w_valid |= VALID_TOPLINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Correct the cursor position so that it is in a part of the screen at least
|
||||||
* Correct the cursor position so that it is in a part of the screen at least
|
// 'so' lines from the top and bottom, if possible.
|
||||||
* 'so' lines from the top and bottom, if possible.
|
// If not possible, put it at the same position as scroll_cursor_halfway().
|
||||||
* If not possible, put it at the same position as scroll_cursor_halfway().
|
// When called topline must be valid!
|
||||||
* When called topline must be valid!
|
|
||||||
*/
|
|
||||||
void cursor_correct(void)
|
void cursor_correct(void)
|
||||||
{
|
{
|
||||||
/*
|
// How many lines we would like to have above/below the cursor depends on
|
||||||
* How many lines we would like to have above/below the cursor depends on
|
// whether the first/last line of the file is on screen.
|
||||||
* whether the first/last line of the file is on screen.
|
|
||||||
*/
|
|
||||||
int above_wanted = (int)get_scrolloff_value(curwin);
|
int above_wanted = (int)get_scrolloff_value(curwin);
|
||||||
int below_wanted = (int)get_scrolloff_value(curwin);
|
int below_wanted = (int)get_scrolloff_value(curwin);
|
||||||
if (mouse_dragging > 0) {
|
if (mouse_dragging > 0) {
|
||||||
@@ -1795,10 +1699,8 @@ void cursor_correct(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If there are sufficient file-lines above and below the cursor, we can
|
||||||
* If there are sufficient file-lines above and below the cursor, we can
|
// return now.
|
||||||
* return now.
|
|
||||||
*/
|
|
||||||
linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number
|
linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number
|
||||||
if (cln >= curwin->w_topline + above_wanted
|
if (cln >= curwin->w_topline + above_wanted
|
||||||
&& cln < curwin->w_botline - below_wanted
|
&& cln < curwin->w_botline - below_wanted
|
||||||
@@ -1806,12 +1708,10 @@ void cursor_correct(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Narrow down the area where the cursor can be put by taking lines from
|
||||||
* Narrow down the area where the cursor can be put by taking lines from
|
// the top and the bottom until:
|
||||||
* the top and the bottom until:
|
// - the desired context lines are found
|
||||||
* - the desired context lines are found
|
// - the lines from the top is past the lines from the bottom
|
||||||
* - the lines from the top is past the lines from the bottom
|
|
||||||
*/
|
|
||||||
linenr_T topline = curwin->w_topline;
|
linenr_T topline = curwin->w_topline;
|
||||||
linenr_T botline = curwin->w_botline - 1;
|
linenr_T botline = curwin->w_botline - 1;
|
||||||
// count filler lines as context
|
// count filler lines as context
|
||||||
@@ -1860,11 +1760,9 @@ void cursor_correct(void)
|
|||||||
curwin->w_viewport_invalid = true;
|
curwin->w_viewport_invalid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// move screen 'count' pages up or down and update screen
|
||||||
* move screen 'count' pages up or down and update screen
|
//
|
||||||
*
|
// return FAIL for failure, OK otherwise
|
||||||
* return FAIL for failure, OK otherwise
|
|
||||||
*/
|
|
||||||
int onepage(Direction dir, long count)
|
int onepage(Direction dir, long count)
|
||||||
{
|
{
|
||||||
long n;
|
long n;
|
||||||
@@ -2044,18 +1942,16 @@ int onepage(Direction dir, long count)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Decide how much overlap to use for page-up or page-down scrolling.
|
||||||
* Decide how much overlap to use for page-up or page-down scrolling.
|
// This is symmetric, so that doing both keeps the same lines displayed.
|
||||||
* This is symmetric, so that doing both keeps the same lines displayed.
|
// Three lines are examined:
|
||||||
* Three lines are examined:
|
//
|
||||||
*
|
// before CTRL-F after CTRL-F / before CTRL-B
|
||||||
* before CTRL-F after CTRL-F / before CTRL-B
|
// etc. l1
|
||||||
* etc. l1
|
// l1 last but one line ------------
|
||||||
* l1 last but one line ------------
|
// l2 last text line l2 top text line
|
||||||
* l2 last text line l2 top text line
|
// ------------- l3 second text line
|
||||||
* ------------- l3 second text line
|
// l3 etc.
|
||||||
* l3 etc.
|
|
||||||
*/
|
|
||||||
static void get_scroll_overlap(lineoff_T *lp, int dir)
|
static void get_scroll_overlap(lineoff_T *lp, int dir)
|
||||||
{
|
{
|
||||||
int min_height = curwin->w_height_inner - 2;
|
int min_height = curwin->w_height_inner - 2;
|
||||||
@@ -2125,9 +2021,7 @@ void halfpage(bool flag, linenr_T Prenum)
|
|||||||
validate_botline(curwin);
|
validate_botline(curwin);
|
||||||
int room = curwin->w_empty_rows + curwin->w_filler_rows;
|
int room = curwin->w_empty_rows + curwin->w_filler_rows;
|
||||||
if (flag) {
|
if (flag) {
|
||||||
/*
|
// scroll the text up
|
||||||
* scroll the text up
|
|
||||||
*/
|
|
||||||
while (n > 0 && curwin->w_botline <= curbuf->b_ml.ml_line_count) {
|
while (n > 0 && curwin->w_botline <= curbuf->b_ml.ml_line_count) {
|
||||||
if (curwin->w_topfill > 0) {
|
if (curwin->w_topfill > 0) {
|
||||||
i = 1;
|
i = 1;
|
||||||
@@ -2185,9 +2079,7 @@ void halfpage(bool flag, linenr_T Prenum)
|
|||||||
check_cursor_lnum();
|
check_cursor_lnum();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
// scroll the text down
|
||||||
* scroll the text down
|
|
||||||
*/
|
|
||||||
while (n > 0 && curwin->w_topline > 1) {
|
while (n > 0 && curwin->w_topline > 1) {
|
||||||
if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) {
|
if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) {
|
||||||
i = 1;
|
i = 1;
|
||||||
@@ -2247,9 +2139,7 @@ void do_check_cursorbind(void)
|
|||||||
int old_VIsual_select = VIsual_select;
|
int old_VIsual_select = VIsual_select;
|
||||||
int old_VIsual_active = VIsual_active;
|
int old_VIsual_active = VIsual_active;
|
||||||
|
|
||||||
/*
|
// loop through the cursorbound windows
|
||||||
* loop through the cursorbound windows
|
|
||||||
*/
|
|
||||||
VIsual_select = VIsual_active = 0;
|
VIsual_select = VIsual_active = 0;
|
||||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||||
curwin = wp;
|
curwin = wp;
|
||||||
@@ -2294,9 +2184,7 @@ void do_check_cursorbind(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// reset current-window
|
||||||
* reset current-window
|
|
||||||
*/
|
|
||||||
VIsual_select = old_VIsual_select;
|
VIsual_select = old_VIsual_select;
|
||||||
VIsual_active = old_VIsual_active;
|
VIsual_active = old_VIsual_active;
|
||||||
curwin = old_curwin;
|
curwin = old_curwin;
|
||||||
|
@@ -22,9 +22,7 @@ typedef enum {
|
|||||||
kMTUnknown = -1, ///< Unknown or invalid motion type
|
kMTUnknown = -1, ///< Unknown or invalid motion type
|
||||||
} MotionType;
|
} MotionType;
|
||||||
|
|
||||||
/*
|
// Arguments for operators.
|
||||||
* Arguments for operators.
|
|
||||||
*/
|
|
||||||
typedef struct oparg_S {
|
typedef struct oparg_S {
|
||||||
int op_type; // current pending operator type
|
int op_type; // current pending operator type
|
||||||
int regname; // register to use for the operator
|
int regname; // register to use for the operator
|
||||||
@@ -53,9 +51,7 @@ typedef struct oparg_S {
|
|||||||
// block
|
// block
|
||||||
} oparg_T;
|
} oparg_T;
|
||||||
|
|
||||||
/*
|
// Arguments for Normal mode commands.
|
||||||
* Arguments for Normal mode commands.
|
|
||||||
*/
|
|
||||||
typedef struct cmdarg_S {
|
typedef struct cmdarg_S {
|
||||||
oparg_T *oap; // Operator arguments
|
oparg_T *oap; // Operator arguments
|
||||||
int prechar; // prefix character (optional, always 'g')
|
int prechar; // prefix character (optional, always 'g')
|
||||||
|
166
src/nvim/ops.c
166
src/nvim/ops.c
@@ -1,10 +1,8 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
/*
|
// ops.c: implementation of various operators: op_shift, op_delete, op_tilde,
|
||||||
* ops.c: implementation of various operators: op_shift, op_delete, op_tilde,
|
// op_change, op_yank, do_put, do_join
|
||||||
* op_change, op_yank, do_put, do_join
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -67,10 +65,8 @@ static bool clipboard_delay_update = false; // delay clipboard update
|
|||||||
static bool clipboard_needs_update = false; // clipboard was updated
|
static bool clipboard_needs_update = false; // clipboard was updated
|
||||||
static bool clipboard_didwarn = false;
|
static bool clipboard_didwarn = false;
|
||||||
|
|
||||||
/*
|
// structure used by block_prep, op_delete and op_yank for blockwise operators
|
||||||
* structure used by block_prep, op_delete and op_yank for blockwise operators
|
// also op_change, op_shift, op_insert, op_replace - AKelly
|
||||||
* also op_change, op_shift, op_insert, op_replace - AKelly
|
|
||||||
*/
|
|
||||||
struct block_def {
|
struct block_def {
|
||||||
int startspaces; // 'extra' cols before first char
|
int startspaces; // 'extra' cols before first char
|
||||||
int endspaces; // 'extra' cols after last char
|
int endspaces; // 'extra' cols after last char
|
||||||
@@ -96,11 +92,9 @@ struct block_def {
|
|||||||
#define OPF_LINES 1 // operator always works on lines
|
#define OPF_LINES 1 // operator always works on lines
|
||||||
#define OPF_CHANGE 2 // operator changes text
|
#define OPF_CHANGE 2 // operator changes text
|
||||||
|
|
||||||
/*
|
// The names of operators.
|
||||||
* The names of operators.
|
// IMPORTANT: Index must correspond with defines in vim.h!!!
|
||||||
* IMPORTANT: Index must correspond with defines in vim.h!!!
|
// The third field indicates whether the operator always works on lines.
|
||||||
* The third field indicates whether the operator always works on lines.
|
|
||||||
*/
|
|
||||||
static char opchars[][3] =
|
static char opchars[][3] =
|
||||||
{
|
{
|
||||||
{ NUL, NUL, 0 }, // OP_NOP
|
{ NUL, NUL, 0 }, // OP_NOP
|
||||||
@@ -361,12 +355,10 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
int startcol, oldlen, newlen;
|
int startcol, oldlen, newlen;
|
||||||
|
|
||||||
if (!left) {
|
if (!left) {
|
||||||
/*
|
// 1. Get start vcol
|
||||||
* 1. Get start vcol
|
// 2. Total ws vcols
|
||||||
* 2. Total ws vcols
|
// 3. Divvy into TABs & spp
|
||||||
* 3. Divvy into TABs & spp
|
// 4. Construct new string
|
||||||
* 4. Construct new string
|
|
||||||
*/
|
|
||||||
total += bd.pre_whitesp; // all virtual WS up to & incl a split TAB
|
total += bd.pre_whitesp; // all virtual WS up to & incl a split TAB
|
||||||
colnr_T ws_vcol = bd.start_vcol - bd.pre_whitesp;
|
colnr_T ws_vcol = bd.start_vcol - bd.pre_whitesp;
|
||||||
char_u *old_textstart = bd.textstart;
|
char_u *old_textstart = bd.textstart;
|
||||||
@@ -428,13 +420,11 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
// block shift
|
// block shift
|
||||||
char_u *non_white = bd.textstart;
|
char_u *non_white = bd.textstart;
|
||||||
|
|
||||||
/*
|
// Firstly, let's find the first non-whitespace character that is
|
||||||
* Firstly, let's find the first non-whitespace character that is
|
// displayed after the block's start column and the character's column
|
||||||
* displayed after the block's start column and the character's column
|
// number. Also, let's calculate the width of all the whitespace
|
||||||
* number. Also, let's calculate the width of all the whitespace
|
// characters that are displayed in the block and precede the searched
|
||||||
* characters that are displayed in the block and precede the searched
|
// non-whitespace character.
|
||||||
* non-whitespace character.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// If "bd.startspaces" is set, "bd.textstart" points to the character,
|
// If "bd.startspaces" is set, "bd.textstart" points to the character,
|
||||||
// the part of which is displayed at the block's beginning. Let's start
|
// the part of which is displayed at the block's beginning. Let's start
|
||||||
@@ -715,9 +705,7 @@ void op_reindent(oparg_T *oap, Indenter how)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Keep the last expression line here, for repeating.
|
||||||
* Keep the last expression line here, for repeating.
|
|
||||||
*/
|
|
||||||
static char_u *expr_line = NULL;
|
static char_u *expr_line = NULL;
|
||||||
|
|
||||||
/// Get an expression for the "\"=expr1" or "CTRL-R =expr1"
|
/// Get an expression for the "\"=expr1" or "CTRL-R =expr1"
|
||||||
@@ -1165,9 +1153,7 @@ int do_execreg(int regname, int colon, int addcr, int silent)
|
|||||||
// Disallow remapping for ":@r".
|
// Disallow remapping for ":@r".
|
||||||
int remap = colon ? REMAP_NONE : REMAP_YES;
|
int remap = colon ? REMAP_NONE : REMAP_YES;
|
||||||
|
|
||||||
/*
|
// Insert lines into typeahead buffer, from last one to first one.
|
||||||
* Insert lines into typeahead buffer, from last one to first one.
|
|
||||||
*/
|
|
||||||
put_reedit_in_typebuf(silent);
|
put_reedit_in_typebuf(silent);
|
||||||
char *escaped;
|
char *escaped;
|
||||||
for (size_t i = reg->y_size; i-- > 0;) { // from y_size - 1 to 0 included
|
for (size_t i = reg->y_size; i-- > 0;) { // from y_size - 1 to 0 included
|
||||||
@@ -1277,11 +1263,9 @@ int insert_reg(int regname, bool literally_arg)
|
|||||||
bool allocated;
|
bool allocated;
|
||||||
const bool literally = literally_arg || is_literal_register(regname);
|
const bool literally = literally_arg || is_literal_register(regname);
|
||||||
|
|
||||||
/*
|
// It is possible to get into an endless loop by having CTRL-R a in
|
||||||
* It is possible to get into an endless loop by having CTRL-R a in
|
// register a and then, in insert mode, doing CTRL-R a.
|
||||||
* register a and then, in insert mode, doing CTRL-R a.
|
// If you hit CTRL-C, the loop will be broken here.
|
||||||
* If you hit CTRL-C, the loop will be broken here.
|
|
||||||
*/
|
|
||||||
os_breakcheck();
|
os_breakcheck();
|
||||||
if (got_int) {
|
if (got_int) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -1503,11 +1487,9 @@ int op_delete(oparg_T *oap)
|
|||||||
|
|
||||||
mb_adjust_opend(oap);
|
mb_adjust_opend(oap);
|
||||||
|
|
||||||
/*
|
// Imitate the strange Vi behaviour: If the delete spans more than one
|
||||||
* Imitate the strange Vi behaviour: If the delete spans more than one
|
// line and motion_type == kMTCharWise and the result is a blank line, make the
|
||||||
* line and motion_type == kMTCharWise and the result is a blank line, make the
|
// delete linewise. Don't do this for the change command or Visual mode.
|
||||||
* delete linewise. Don't do this for the change command or Visual mode.
|
|
||||||
*/
|
|
||||||
if (oap->motion_type == kMTCharWise
|
if (oap->motion_type == kMTCharWise
|
||||||
&& !oap->is_VIsual
|
&& !oap->is_VIsual
|
||||||
&& oap->line_count > 1
|
&& oap->line_count > 1
|
||||||
@@ -1523,10 +1505,8 @@ int op_delete(oparg_T *oap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check for trying to delete (e.g. "D") in an empty line.
|
||||||
* Check for trying to delete (e.g. "D") in an empty line.
|
// Note: For the change operator it is ok.
|
||||||
* Note: For the change operator it is ok.
|
|
||||||
*/
|
|
||||||
if (oap->motion_type != kMTLineWise
|
if (oap->motion_type != kMTLineWise
|
||||||
&& oap->line_count == 1
|
&& oap->line_count == 1
|
||||||
&& oap->op_type == OP_DELETE
|
&& oap->op_type == OP_DELETE
|
||||||
@@ -1544,11 +1524,9 @@ int op_delete(oparg_T *oap)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Do a yank of whatever we're about to delete.
|
||||||
* Do a yank of whatever we're about to delete.
|
// If a yank register was specified, put the deleted text into that
|
||||||
* If a yank register was specified, put the deleted text into that
|
// register. For the black hole register '_' don't yank anything.
|
||||||
* register. For the black hole register '_' don't yank anything.
|
|
||||||
*/
|
|
||||||
if (oap->regname != '_') {
|
if (oap->regname != '_') {
|
||||||
yankreg_T *reg = NULL;
|
yankreg_T *reg = NULL;
|
||||||
int did_yank = false;
|
int did_yank = false;
|
||||||
@@ -1592,9 +1570,7 @@ int op_delete(oparg_T *oap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// block mode delete
|
||||||
* block mode delete
|
|
||||||
*/
|
|
||||||
if (oap->motion_type == kMTBlockWise) {
|
if (oap->motion_type == kMTBlockWise) {
|
||||||
if (u_save((linenr_T)(oap->start.lnum - 1),
|
if (u_save((linenr_T)(oap->start.lnum - 1),
|
||||||
(linenr_T)(oap->end.lnum + 1)) == FAIL) {
|
(linenr_T)(oap->end.lnum + 1)) == FAIL) {
|
||||||
@@ -1873,9 +1849,7 @@ static int op_replace(oparg_T *oap, int c)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// block mode replace
|
||||||
* block mode replace
|
|
||||||
*/
|
|
||||||
if (oap->motion_type == kMTBlockWise) {
|
if (oap->motion_type == kMTBlockWise) {
|
||||||
bd.is_MAX = (curwin->w_curswant == MAXCOL);
|
bd.is_MAX = (curwin->w_curswant == MAXCOL);
|
||||||
for (; curwin->w_cursor.lnum <= oap->end.lnum; curwin->w_cursor.lnum++) {
|
for (; curwin->w_cursor.lnum <= oap->end.lnum; curwin->w_cursor.lnum++) {
|
||||||
@@ -2409,10 +2383,8 @@ void op_insert(oparg_T *oap, long count1)
|
|||||||
bd.textlen = bd2.textlen;
|
bd.textlen = bd2.textlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Subsequent calls to ml_get() flush the firstline data - take a
|
||||||
* Subsequent calls to ml_get() flush the firstline data - take a
|
// copy of the required string.
|
||||||
* copy of the required string.
|
|
||||||
*/
|
|
||||||
firstline = ml_get(oap->start.lnum);
|
firstline = ml_get(oap->start.lnum);
|
||||||
const size_t len = STRLEN(firstline);
|
const size_t len = STRLEN(firstline);
|
||||||
colnr_T add = bd.textcol;
|
colnr_T add = bd.textcol;
|
||||||
@@ -2510,11 +2482,9 @@ int op_change(oparg_T *oap)
|
|||||||
|
|
||||||
retval = edit(NUL, false, (linenr_T)1);
|
retval = edit(NUL, false, (linenr_T)1);
|
||||||
|
|
||||||
/*
|
// In Visual block mode, handle copying the new text to all lines of the
|
||||||
* In Visual block mode, handle copying the new text to all lines of the
|
// block.
|
||||||
* block.
|
// Don't repeat the insert when Insert mode ended with CTRL-C.
|
||||||
* Don't repeat the insert when Insert mode ended with CTRL-C.
|
|
||||||
*/
|
|
||||||
if (oap->motion_type == kMTBlockWise
|
if (oap->motion_type == kMTBlockWise
|
||||||
&& oap->start.lnum != oap->end.lnum && !got_int) {
|
&& oap->start.lnum != oap->end.lnum && !got_int) {
|
||||||
// Auto-indenting may have changed the indent. If the cursor was past
|
// Auto-indenting may have changed the indent. If the cursor was past
|
||||||
@@ -2973,10 +2943,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
|
|||||||
curbuf->b_op_start = curwin->w_cursor; // default for '[ mark
|
curbuf->b_op_start = curwin->w_cursor; // default for '[ mark
|
||||||
curbuf->b_op_end = curwin->w_cursor; // default for '] mark
|
curbuf->b_op_end = curwin->w_cursor; // default for '] mark
|
||||||
|
|
||||||
/*
|
// Using inserted text works differently, because the register includes
|
||||||
* Using inserted text works differently, because the register includes
|
// special characters (newlines, etc.).
|
||||||
* special characters (newlines, etc.).
|
|
||||||
*/
|
|
||||||
if (regname == '.' && !reg) {
|
if (regname == '.' && !reg) {
|
||||||
bool non_linewise_vis = (VIsual_active && VIsual_mode != 'V');
|
bool non_linewise_vis = (VIsual_active && VIsual_mode != 'V');
|
||||||
|
|
||||||
@@ -3056,10 +3024,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// For special registers '%' (file name), '#' (alternate file name) and
|
||||||
* For special registers '%' (file name), '#' (alternate file name) and
|
// ':' (last command line), etc. we have to create a fake yank register.
|
||||||
* ':' (last command line), etc. we have to create a fake yank register.
|
|
||||||
*/
|
|
||||||
if (!reg && get_spec_reg(regname, &insert_string, &allocated, true)) {
|
if (!reg && get_spec_reg(regname, &insert_string, &allocated, true)) {
|
||||||
if (insert_string == NULL) {
|
if (insert_string == NULL) {
|
||||||
return;
|
return;
|
||||||
@@ -3232,9 +3198,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
|
|||||||
lnum = curwin->w_cursor.lnum;
|
lnum = curwin->w_cursor.lnum;
|
||||||
col = curwin->w_cursor.col;
|
col = curwin->w_cursor.col;
|
||||||
|
|
||||||
/*
|
// Block mode
|
||||||
* Block mode
|
|
||||||
*/
|
|
||||||
if (y_type == kMTBlockWise) {
|
if (y_type == kMTBlockWise) {
|
||||||
int c = gchar_cursor();
|
int c = gchar_cursor();
|
||||||
colnr_T endcol2 = 0;
|
colnr_T endcol2 = 0;
|
||||||
@@ -4129,13 +4093,11 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions
|
|||||||
cend = newp + sumsize;
|
cend = newp + sumsize;
|
||||||
*cend = 0;
|
*cend = 0;
|
||||||
|
|
||||||
/*
|
// Move affected lines to the new long one.
|
||||||
* Move affected lines to the new long one.
|
//
|
||||||
*
|
// Move marks from each deleted line to the joined line, adjusting the
|
||||||
* Move marks from each deleted line to the joined line, adjusting the
|
// column. This is not Vi compatible, but Vi deletes the marks, thus that
|
||||||
* column. This is not Vi compatible, but Vi deletes the marks, thus that
|
// should not really be a problem.
|
||||||
* should not really be a problem.
|
|
||||||
*/
|
|
||||||
|
|
||||||
curbuf_splice_pending++;
|
curbuf_splice_pending++;
|
||||||
|
|
||||||
@@ -4185,11 +4147,9 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions
|
|||||||
changed_lines(curwin->w_cursor.lnum, currsize,
|
changed_lines(curwin->w_cursor.lnum, currsize,
|
||||||
curwin->w_cursor.lnum + 1, 0L, true);
|
curwin->w_cursor.lnum + 1, 0L, true);
|
||||||
|
|
||||||
/*
|
// Delete following lines. To do this we move the cursor there
|
||||||
* Delete following lines. To do this we move the cursor there
|
// briefly, and then move it back. After del_lines() the cursor may
|
||||||
* briefly, and then move it back. After del_lines() the cursor may
|
// have moved up (last line deleted), so the current lnum is kept in t.
|
||||||
* have moved up (last line deleted), so the current lnum is kept in t.
|
|
||||||
*/
|
|
||||||
t = curwin->w_cursor.lnum;
|
t = curwin->w_cursor.lnum;
|
||||||
curwin->w_cursor.lnum++;
|
curwin->w_cursor.lnum++;
|
||||||
del_lines((long)count - 1, false);
|
del_lines((long)count - 1, false);
|
||||||
@@ -4197,11 +4157,9 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions
|
|||||||
curbuf_splice_pending--;
|
curbuf_splice_pending--;
|
||||||
curbuf->deleted_bytes2 = 0;
|
curbuf->deleted_bytes2 = 0;
|
||||||
|
|
||||||
/*
|
// Set the cursor column:
|
||||||
* Set the cursor column:
|
// Vi compatible: use the column of the first join
|
||||||
* Vi compatible: use the column of the first join
|
// vim: use the column of the last join
|
||||||
* vim: use the column of the last join
|
|
||||||
*/
|
|
||||||
curwin->w_cursor.col =
|
curwin->w_cursor.col =
|
||||||
(vim_strchr(p_cpo, CPO_JOINCOL) != NULL ? currsize : col);
|
(vim_strchr(p_cpo, CPO_JOINCOL) != NULL ? currsize : col);
|
||||||
check_cursor_col();
|
check_cursor_col();
|
||||||
@@ -4963,16 +4921,12 @@ void *get_reg_contents(int regname, int flags)
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Compute length of resulting string.
|
||||||
* Compute length of resulting string.
|
|
||||||
*/
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
for (size_t i = 0; i < reg->y_size; i++) {
|
for (size_t i = 0; i < reg->y_size; i++) {
|
||||||
len += STRLEN(reg->y_array[i]);
|
len += STRLEN(reg->y_array[i]);
|
||||||
/*
|
// Insert a newline between lines and after last line if
|
||||||
* Insert a newline between lines and after last line if
|
// y_type is kMTLineWise.
|
||||||
* y_type is kMTLineWise.
|
|
||||||
*/
|
|
||||||
if (reg->y_type == kMTLineWise || i < reg->y_size - 1) {
|
if (reg->y_type == kMTLineWise || i < reg->y_size - 1) {
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
@@ -4980,18 +4934,14 @@ void *get_reg_contents(int regname, int flags)
|
|||||||
|
|
||||||
retval = xmalloc(len + 1);
|
retval = xmalloc(len + 1);
|
||||||
|
|
||||||
/*
|
// Copy the lines of the yank register into the string.
|
||||||
* Copy the lines of the yank register into the string.
|
|
||||||
*/
|
|
||||||
len = 0;
|
len = 0;
|
||||||
for (size_t i = 0; i < reg->y_size; i++) {
|
for (size_t i = 0; i < reg->y_size; i++) {
|
||||||
STRCPY(retval + len, reg->y_array[i]);
|
STRCPY(retval + len, reg->y_array[i]);
|
||||||
len += STRLEN(retval + len);
|
len += STRLEN(retval + len);
|
||||||
|
|
||||||
/*
|
// Insert a NL between lines and after the last line if y_type is
|
||||||
* Insert a NL between lines and after the last line if y_type is
|
// kMTLineWise.
|
||||||
* kMTLineWise.
|
|
||||||
*/
|
|
||||||
if (reg->y_type == kMTLineWise || i < reg->y_size - 1) {
|
if (reg->y_type == kMTLineWise || i < reg->y_size - 1) {
|
||||||
retval[len++] = '\n';
|
retval[len++] = '\n';
|
||||||
}
|
}
|
||||||
|
@@ -23,15 +23,13 @@ typedef int (*Indenter)(void);
|
|||||||
#define PUT_LINE_FORWARD 32 // put linewise register below Visual sel.
|
#define PUT_LINE_FORWARD 32 // put linewise register below Visual sel.
|
||||||
#define PUT_BLOCK_INNER 64 // in block mode, do not add trailing spaces
|
#define PUT_BLOCK_INNER 64 // in block mode, do not add trailing spaces
|
||||||
|
|
||||||
/*
|
// Registers:
|
||||||
* Registers:
|
// 0 = register for latest (unnamed) yank
|
||||||
* 0 = register for latest (unnamed) yank
|
// 1..9 = registers '1' to '9', for deletes
|
||||||
* 1..9 = registers '1' to '9', for deletes
|
// 10..35 = registers 'a' to 'z'
|
||||||
* 10..35 = registers 'a' to 'z'
|
// 36 = delete register '-'
|
||||||
* 36 = delete register '-'
|
// 37 = selection register '*'
|
||||||
* 37 = selection register '*'
|
// 38 = clipboard register '+'
|
||||||
* 38 = clipboard register '+'
|
|
||||||
*/
|
|
||||||
#define DELETION_REGISTER 36
|
#define DELETION_REGISTER 36
|
||||||
#define NUM_SAVED_REGISTERS 37
|
#define NUM_SAVED_REGISTERS 37
|
||||||
// The following registers should not be saved in ShaDa file:
|
// The following registers should not be saved in ShaDa file:
|
||||||
|
@@ -106,14 +106,12 @@ static char e_number_required_after_equal[]
|
|||||||
static char e_preview_window_already_exists[]
|
static char e_preview_window_already_exists[]
|
||||||
= N_("E590: A preview window already exists");
|
= N_("E590: A preview window already exists");
|
||||||
|
|
||||||
/*
|
// The options that are local to a window or buffer have "indir" set to one of
|
||||||
* The options that are local to a window or buffer have "indir" set to one of
|
// these values. Special values:
|
||||||
* these values. Special values:
|
// PV_NONE: global option.
|
||||||
* PV_NONE: global option.
|
// PV_WIN is added: window-local option
|
||||||
* PV_WIN is added: window-local option
|
// PV_BUF is added: buffer-local option
|
||||||
* PV_BUF is added: buffer-local option
|
// PV_BOTH is added: global option which also has a local value.
|
||||||
* PV_BOTH is added: global option which also has a local value.
|
|
||||||
*/
|
|
||||||
#define PV_BOTH 0x1000
|
#define PV_BOTH 0x1000
|
||||||
#define PV_WIN 0x2000
|
#define PV_WIN 0x2000
|
||||||
#define PV_BUF 0x4000
|
#define PV_BUF 0x4000
|
||||||
@@ -128,10 +126,8 @@ typedef enum {
|
|||||||
PV_MAXVAL = 0xffff, // to avoid warnings for value out of range
|
PV_MAXVAL = 0xffff, // to avoid warnings for value out of range
|
||||||
} idopt_T;
|
} idopt_T;
|
||||||
|
|
||||||
/*
|
// Options local to a window have a value local to a buffer and global to all
|
||||||
* Options local to a window have a value local to a buffer and global to all
|
// buffers. Indicate this by setting "var" to VAR_WIN.
|
||||||
* buffers. Indicate this by setting "var" to VAR_WIN.
|
|
||||||
*/
|
|
||||||
#define VAR_WIN ((char_u *)-1)
|
#define VAR_WIN ((char_u *)-1)
|
||||||
|
|
||||||
static char *p_term = NULL;
|
static char *p_term = NULL;
|
||||||
@@ -164,14 +160,12 @@ typedef struct vimoption {
|
|||||||
LastSet last_set; // script in which the option was last set
|
LastSet last_set; // script in which the option was last set
|
||||||
} vimoption_T;
|
} vimoption_T;
|
||||||
|
|
||||||
/*
|
// options[] is initialized here.
|
||||||
* options[] is initialized here.
|
// The order of the options MUST be alphabetic for ":set all" and findoption().
|
||||||
* The order of the options MUST be alphabetic for ":set all" and findoption().
|
// All option names MUST start with a lowercase letter (for findoption()).
|
||||||
* All option names MUST start with a lowercase letter (for findoption()).
|
// Exception: "t_" options are at the end.
|
||||||
* Exception: "t_" options are at the end.
|
// The options with a NULL variable are 'hidden': a set command for them is
|
||||||
* The options with a NULL variable are 'hidden': a set command for them is
|
// ignored and they are not printed.
|
||||||
* ignored and they are not printed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "options.generated.h"
|
# include "options.generated.h"
|
||||||
@@ -197,10 +191,8 @@ void set_init_1(bool clean_arg)
|
|||||||
|
|
||||||
langmap_init();
|
langmap_init();
|
||||||
|
|
||||||
/*
|
// Find default value for 'shell' option.
|
||||||
* Find default value for 'shell' option.
|
// Don't use it if it is empty.
|
||||||
* Don't use it if it is empty.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
const char *shell = os_getenv("SHELL");
|
const char *shell = os_getenv("SHELL");
|
||||||
if (shell != NULL) {
|
if (shell != NULL) {
|
||||||
@@ -215,10 +207,8 @@ void set_init_1(bool clean_arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set the default for 'backupskip' to include environment variables for
|
||||||
* Set the default for 'backupskip' to include environment variables for
|
// temp files.
|
||||||
* temp files.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
static char *(names[4]) = { "", "TMPDIR", "TEMP", "TMP" };
|
static char *(names[4]) = { "", "TMPDIR", "TEMP", "TMP" };
|
||||||
@@ -354,10 +344,8 @@ void set_init_1(bool clean_arg)
|
|||||||
rtp = NULL; // ownership taken
|
rtp = NULL; // ownership taken
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set all the options (except the terminal options) to their default
|
||||||
* Set all the options (except the terminal options) to their default
|
// value. Also set the global value for local options.
|
||||||
* value. Also set the global value for local options.
|
|
||||||
*/
|
|
||||||
set_options_default(0);
|
set_options_default(0);
|
||||||
|
|
||||||
curbuf->b_p_initialized = true;
|
curbuf->b_p_initialized = true;
|
||||||
@@ -380,15 +368,13 @@ void set_init_1(bool clean_arg)
|
|||||||
// didset_options() because it only depends on 'encoding'.
|
// didset_options() because it only depends on 'encoding'.
|
||||||
init_spell_chartab();
|
init_spell_chartab();
|
||||||
|
|
||||||
/*
|
// Expand environment variables and things like "~" for the defaults.
|
||||||
* Expand environment variables and things like "~" for the defaults.
|
// If option_expand() returns non-NULL the variable is expanded. This can
|
||||||
* If option_expand() returns non-NULL the variable is expanded. This can
|
// only happen for non-indirect options.
|
||||||
* only happen for non-indirect options.
|
// Also set the default to the expanded value, so ":set" does not list
|
||||||
* Also set the default to the expanded value, so ":set" does not list
|
// them.
|
||||||
* them.
|
// Don't set the P_ALLOCED flag, because we don't want to free the
|
||||||
* Don't set the P_ALLOCED flag, because we don't want to free the
|
// default.
|
||||||
* default.
|
|
||||||
*/
|
|
||||||
for (opt_idx = 0; options[opt_idx].fullname; opt_idx++) {
|
for (opt_idx = 0; options[opt_idx].fullname; opt_idx++) {
|
||||||
if (options[opt_idx].flags & P_NO_DEF_EXP) {
|
if (options[opt_idx].flags & P_NO_DEF_EXP) {
|
||||||
continue;
|
continue;
|
||||||
@@ -635,10 +621,8 @@ void set_init_2(bool headless)
|
|||||||
}
|
}
|
||||||
comp_col();
|
comp_col();
|
||||||
|
|
||||||
/*
|
// 'window' is only for backwards compatibility with Vi.
|
||||||
* 'window' is only for backwards compatibility with Vi.
|
// Default is Rows - 1.
|
||||||
* Default is Rows - 1.
|
|
||||||
*/
|
|
||||||
if (!option_was_set("window")) {
|
if (!option_was_set("window")) {
|
||||||
p_window = Rows - 1;
|
p_window = Rows - 1;
|
||||||
}
|
}
|
||||||
@@ -758,11 +742,9 @@ void set_title_defaults(void)
|
|||||||
{
|
{
|
||||||
int idx1;
|
int idx1;
|
||||||
|
|
||||||
/*
|
// If GUI is (going to be) used, we can always set the window title and
|
||||||
* If GUI is (going to be) used, we can always set the window title and
|
// icon name. Saves a bit of time, because the X11 display server does
|
||||||
* icon name. Saves a bit of time, because the X11 display server does
|
// not need to be contacted.
|
||||||
* not need to be contacted.
|
|
||||||
*/
|
|
||||||
idx1 = findoption("title");
|
idx1 = findoption("title");
|
||||||
if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) {
|
if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) {
|
||||||
options[idx1].def_val = (char_u *)(intptr_t)0;
|
options[idx1].def_val = (char_u *)(intptr_t)0;
|
||||||
@@ -837,10 +819,8 @@ int do_set(char *arg, int opt_flags)
|
|||||||
|
|
||||||
if (STRNCMP(arg, "all", 3) == 0 && !isalpha(arg[3])
|
if (STRNCMP(arg, "all", 3) == 0 && !isalpha(arg[3])
|
||||||
&& !(opt_flags & OPT_MODELINE)) {
|
&& !(opt_flags & OPT_MODELINE)) {
|
||||||
/*
|
// ":set all" show all options.
|
||||||
* ":set all" show all options.
|
// ":set all&" set all options to their default value.
|
||||||
* ":set all&" set all options to their default value.
|
|
||||||
*/
|
|
||||||
arg += 3;
|
arg += 3;
|
||||||
if (*arg == '&') {
|
if (*arg == '&') {
|
||||||
arg++;
|
arg++;
|
||||||
@@ -1016,9 +996,7 @@ int do_set(char *arg, int opt_flags)
|
|||||||
|| (prefix == 1
|
|| (prefix == 1
|
||||||
&& vim_strchr("=:&<", nextchar) == NULL
|
&& vim_strchr("=:&<", nextchar) == NULL
|
||||||
&& !(flags & P_BOOL))) {
|
&& !(flags & P_BOOL))) {
|
||||||
/*
|
// print value
|
||||||
* print value
|
|
||||||
*/
|
|
||||||
if (did_show) {
|
if (did_show) {
|
||||||
msg_putchar('\n'); // cursor below last one
|
msg_putchar('\n'); // cursor below last one
|
||||||
} else {
|
} else {
|
||||||
@@ -1057,11 +1035,9 @@ int do_set(char *arg, int opt_flags)
|
|||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// ":set opt!": invert
|
||||||
* ":set opt!": invert
|
// ":set opt&": reset to default value
|
||||||
* ":set opt&": reset to default value
|
// ":set opt<": reset to global value
|
||||||
* ":set opt<": reset to global value
|
|
||||||
*/
|
|
||||||
if (nextchar == '!') {
|
if (nextchar == '!') {
|
||||||
value = *(int *)(varp) ^ 1;
|
value = *(int *)(varp) ^ 1;
|
||||||
} else if (nextchar == '&') {
|
} else if (nextchar == '&') {
|
||||||
@@ -1076,10 +1052,8 @@ int do_set(char *arg, int opt_flags)
|
|||||||
OPT_GLOBAL);
|
OPT_GLOBAL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
// ":set invopt": invert
|
||||||
* ":set invopt": invert
|
// ":set opt" or ":set noopt": set or reset
|
||||||
* ":set opt" or ":set noopt": set or reset
|
|
||||||
*/
|
|
||||||
if (nextchar != NUL && !ascii_iswhite(afterchar)) {
|
if (nextchar != NUL && !ascii_iswhite(afterchar)) {
|
||||||
errmsg = e_trailing;
|
errmsg = e_trailing;
|
||||||
goto skip;
|
goto skip;
|
||||||
@@ -1289,11 +1263,10 @@ int do_set(char *arg, int opt_flags)
|
|||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Copy the new string into allocated memory.
|
||||||
* Copy the new string into allocated memory.
|
// Can't use set_string_option_direct(), because
|
||||||
* Can't use set_string_option_direct(), because
|
// we need to remove the backslashes.
|
||||||
* we need to remove the backslashes.
|
|
||||||
*/
|
|
||||||
// get a bit too much
|
// get a bit too much
|
||||||
newlen = (unsigned)STRLEN(arg) + 1;
|
newlen = (unsigned)STRLEN(arg) + 1;
|
||||||
if (adding || prepending || removing) {
|
if (adding || prepending || removing) {
|
||||||
@@ -1302,14 +1275,12 @@ int do_set(char *arg, int opt_flags)
|
|||||||
newval = xmalloc(newlen);
|
newval = xmalloc(newlen);
|
||||||
s = newval;
|
s = newval;
|
||||||
|
|
||||||
/*
|
// Copy the string, skip over escaped chars.
|
||||||
* Copy the string, skip over escaped chars.
|
// For WIN32 backslashes before normal
|
||||||
* For WIN32 backslashes before normal
|
// file name characters are not removed, and keep
|
||||||
* file name characters are not removed, and keep
|
// backslash at start, for "\\machine\path", but
|
||||||
* backslash at start, for "\\machine\path", but
|
// do remove it for "\\\\machine\\path".
|
||||||
* do remove it for "\\\\machine\\path".
|
// The reverse is found in ExpandOldSetting().
|
||||||
* The reverse is found in ExpandOldSetting().
|
|
||||||
*/
|
|
||||||
while (*arg && !ascii_iswhite(*arg)) {
|
while (*arg && !ascii_iswhite(*arg)) {
|
||||||
if (*arg == '\\' && arg[1] != NUL
|
if (*arg == '\\' && arg[1] != NUL
|
||||||
#ifdef BACKSLASH_IN_FILENAME
|
#ifdef BACKSLASH_IN_FILENAME
|
||||||
@@ -1335,11 +1306,9 @@ int do_set(char *arg, int opt_flags)
|
|||||||
}
|
}
|
||||||
*s = NUL;
|
*s = NUL;
|
||||||
|
|
||||||
/*
|
// Expand environment variables and ~.
|
||||||
* Expand environment variables and ~.
|
// Don't do it when adding without inserting a
|
||||||
* Don't do it when adding without inserting a
|
// comma.
|
||||||
* comma.
|
|
||||||
*/
|
|
||||||
if (!(adding || prepending || removing)
|
if (!(adding || prepending || removing)
|
||||||
|| (flags & P_COMMA)) {
|
|| (flags & P_COMMA)) {
|
||||||
s = option_expand(opt_idx, newval);
|
s = option_expand(opt_idx, newval);
|
||||||
@@ -1521,12 +1490,10 @@ int do_set(char *arg, int opt_flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
/*
|
// Advance to next argument.
|
||||||
* Advance to next argument.
|
// - skip until a blank found, taking care of backslashes
|
||||||
* - skip until a blank found, taking care of backslashes
|
// - skip blanks
|
||||||
* - skip blanks
|
// - skip one "=val" argument (for hidden options ":set gfn =xx")
|
||||||
* - skip one "=val" argument (for hidden options ":set gfn =xx")
|
|
||||||
*/
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
while (*arg != NUL && !ascii_iswhite(*arg)) {
|
while (*arg != NUL && !ascii_iswhite(*arg)) {
|
||||||
if (*arg++ == '\\' && *arg != NUL) {
|
if (*arg++ == '\\' && *arg != NUL) {
|
||||||
@@ -1629,10 +1596,8 @@ void did_set_title(void)
|
|||||||
/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
|
/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
|
||||||
void set_options_bin(int oldval, int newval, int opt_flags)
|
void set_options_bin(int oldval, int newval, int opt_flags)
|
||||||
{
|
{
|
||||||
/*
|
// The option values that are changed when 'bin' changes are
|
||||||
* The option values that are changed when 'bin' changes are
|
// copied when 'bin is set and restored when 'bin' is reset.
|
||||||
* copied when 'bin is set and restored when 'bin' is reset.
|
|
||||||
*/
|
|
||||||
if (newval) {
|
if (newval) {
|
||||||
if (!oldval) { // switched on
|
if (!oldval) { // switched on
|
||||||
if (!(opt_flags & OPT_GLOBAL)) {
|
if (!(opt_flags & OPT_GLOBAL)) {
|
||||||
@@ -1735,12 +1700,10 @@ static char_u *option_expand(int opt_idx, char_u *val)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Expanding this with NameBuff, expand_env() must not be passed IObuff.
|
||||||
* Expanding this with NameBuff, expand_env() must not be passed IObuff.
|
// Escape spaces when expanding 'tags', they are used to separate file
|
||||||
* Escape spaces when expanding 'tags', they are used to separate file
|
// names.
|
||||||
* names.
|
// For 'spellsuggest' expand after "file:".
|
||||||
* For 'spellsuggest' expand after "file:".
|
|
||||||
*/
|
|
||||||
expand_env_esc(val, (char_u *)NameBuff, MAXPATHL,
|
expand_env_esc(val, (char_u *)NameBuff, MAXPATHL,
|
||||||
(char_u **)options[opt_idx].var == &p_tags, false,
|
(char_u **)options[opt_idx].var == &p_tags, false,
|
||||||
(char_u **)options[opt_idx].var == (char_u **)&p_sps ? (char_u *)"file:" :
|
(char_u **)options[opt_idx].var == (char_u **)&p_sps ? (char_u *)"file:" :
|
||||||
@@ -2153,9 +2116,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
|
|||||||
|
|
||||||
if ((int *)varp == &curwin->w_p_arab) {
|
if ((int *)varp == &curwin->w_p_arab) {
|
||||||
if (curwin->w_p_arab) {
|
if (curwin->w_p_arab) {
|
||||||
/*
|
// 'arabic' is set, handle various sub-settings.
|
||||||
* 'arabic' is set, handle various sub-settings.
|
|
||||||
*/
|
|
||||||
if (!p_tbidi) {
|
if (!p_tbidi) {
|
||||||
// set rightleft mode
|
// set rightleft mode
|
||||||
if (!curwin->w_p_rl) {
|
if (!curwin->w_p_rl) {
|
||||||
@@ -2186,9 +2147,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
|
|||||||
// Force-set the necessary keymap for arabic.
|
// Force-set the necessary keymap for arabic.
|
||||||
errmsg = set_option_value("keymap", 0L, "arabic", OPT_LOCAL);
|
errmsg = set_option_value("keymap", 0L, "arabic", OPT_LOCAL);
|
||||||
} else {
|
} else {
|
||||||
/*
|
// 'arabic' is reset, handle various sub-settings.
|
||||||
* 'arabic' is reset, handle various sub-settings.
|
|
||||||
*/
|
|
||||||
if (!p_tbidi) {
|
if (!p_tbidi) {
|
||||||
// reset rightleft mode
|
// reset rightleft mode
|
||||||
if (curwin->w_p_rl) {
|
if (curwin->w_p_rl) {
|
||||||
@@ -2209,9 +2168,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// End of handling side effects for bool options.
|
||||||
* End of handling side effects for bool options.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// after handling side effects, call autocommand
|
// after handling side effects, call autocommand
|
||||||
|
|
||||||
@@ -3328,9 +3285,7 @@ static void showoptions(int all, int opt_flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// display the items
|
||||||
* display the items
|
|
||||||
*/
|
|
||||||
if (run == 1) {
|
if (run == 1) {
|
||||||
assert(Columns <= INT_MAX - GAP
|
assert(Columns <= INT_MAX - GAP
|
||||||
&& Columns + GAP >= INT_MIN + 3
|
&& Columns + GAP >= INT_MIN + 3
|
||||||
@@ -3467,15 +3422,13 @@ int makeset(FILE *fd, int opt_flags, int local_only)
|
|||||||
int round;
|
int round;
|
||||||
int pri;
|
int pri;
|
||||||
|
|
||||||
/*
|
// Some options are never written:
|
||||||
* Some options are never written:
|
// - Options that don't have a default (terminal name, columns, lines).
|
||||||
* - Options that don't have a default (terminal name, columns, lines).
|
// - Terminal options.
|
||||||
* - Terminal options.
|
// - Hidden options.
|
||||||
* - Hidden options.
|
//
|
||||||
*
|
// Do the loop over "options[]" twice: once for options with the
|
||||||
* Do the loop over "options[]" twice: once for options with the
|
// P_PRI_MKRC flag and once without.
|
||||||
* P_PRI_MKRC flag and once without.
|
|
||||||
*/
|
|
||||||
for (pri = 1; pri >= 0; pri--) {
|
for (pri = 1; pri >= 0; pri--) {
|
||||||
for (p = &options[0]; p->fullname; p++) {
|
for (p = &options[0]; p->fullname; p++) {
|
||||||
if (!(p->flags & P_NO_MKRC)
|
if (!(p->flags & P_NO_MKRC)
|
||||||
@@ -4400,10 +4353,8 @@ void buf_copy_options(buf_T *buf, int flags)
|
|||||||
int dont_do_help;
|
int dont_do_help;
|
||||||
int did_isk = false;
|
int did_isk = false;
|
||||||
|
|
||||||
/*
|
// Skip this when the option defaults have not been set yet. Happens when
|
||||||
* Skip this when the option defaults have not been set yet. Happens when
|
// main() allocates the first buffer.
|
||||||
* main() allocates the first buffer.
|
|
||||||
*/
|
|
||||||
if (p_cpo != NULL) {
|
if (p_cpo != NULL) {
|
||||||
//
|
//
|
||||||
// Always copy when entering and 'cpo' contains 'S'.
|
// Always copy when entering and 'cpo' contains 'S'.
|
||||||
@@ -4617,12 +4568,10 @@ void buf_copy_options(buf_T *buf, int flags)
|
|||||||
buf->b_p_lw = empty_option;
|
buf->b_p_lw = empty_option;
|
||||||
buf->b_p_menc = empty_option;
|
buf->b_p_menc = empty_option;
|
||||||
|
|
||||||
/*
|
// Don't copy the options set by ex_help(), use the saved values,
|
||||||
* Don't copy the options set by ex_help(), use the saved values,
|
// when going from a help buffer to a non-help buffer.
|
||||||
* when going from a help buffer to a non-help buffer.
|
// Don't touch these at all when BCO_NOHELP is used and going from
|
||||||
* Don't touch these at all when BCO_NOHELP is used and going from
|
// or to a help buffer.
|
||||||
* or to a help buffer.
|
|
||||||
*/
|
|
||||||
if (dont_do_help) {
|
if (dont_do_help) {
|
||||||
buf->b_p_isk = (char *)save_p_isk;
|
buf->b_p_isk = (char *)save_p_isk;
|
||||||
if (p_vts && p_vts != empty_option && !buf->b_p_vts_array) {
|
if (p_vts && p_vts != empty_option && !buf->b_p_vts_array) {
|
||||||
@@ -4652,10 +4601,8 @@ void buf_copy_options(buf_T *buf, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When the options should be copied (ignoring BCO_ALWAYS), set the
|
||||||
* When the options should be copied (ignoring BCO_ALWAYS), set the
|
// flag that indicates that the options have been initialized.
|
||||||
* flag that indicates that the options have been initialized.
|
|
||||||
*/
|
|
||||||
if (should_copy) {
|
if (should_copy) {
|
||||||
buf->b_p_initialized = true;
|
buf->b_p_initialized = true;
|
||||||
}
|
}
|
||||||
@@ -4947,9 +4894,7 @@ void ExpandOldSetting(int *num_file, char ***file)
|
|||||||
*num_file = 0;
|
*num_file = 0;
|
||||||
*file = xmalloc(sizeof(char_u *));
|
*file = xmalloc(sizeof(char_u *));
|
||||||
|
|
||||||
/*
|
// For a terminal key code expand_option_idx is < 0.
|
||||||
* For a terminal key code expand_option_idx is < 0.
|
|
||||||
*/
|
|
||||||
if (expand_option_idx < 0) {
|
if (expand_option_idx < 0) {
|
||||||
expand_option_idx = findoption((const char *)expand_option_name);
|
expand_option_idx = findoption((const char *)expand_option_name);
|
||||||
}
|
}
|
||||||
@@ -5055,10 +5000,8 @@ static void paste_option_changed(void)
|
|||||||
static int save_hkmap = 0;
|
static int save_hkmap = 0;
|
||||||
|
|
||||||
if (p_paste) {
|
if (p_paste) {
|
||||||
/*
|
// Paste switched from off to on.
|
||||||
* Paste switched from off to on.
|
// Save the current values, so they can be restored later.
|
||||||
* Save the current values, so they can be restored later.
|
|
||||||
*/
|
|
||||||
if (!old_p_paste) {
|
if (!old_p_paste) {
|
||||||
// save options for each buffer
|
// save options for each buffer
|
||||||
FOR_ALL_BUFFERS(buf) {
|
FOR_ALL_BUFFERS(buf) {
|
||||||
|
@@ -379,9 +379,7 @@ enum {
|
|||||||
#define LISPWORD_VALUE \
|
#define LISPWORD_VALUE \
|
||||||
"defun,define,defmacro,set!,lambda,if,case,let,flet,let*,letrec,do,do*,define-syntax,let-syntax,letrec-syntax,destructuring-bind,defpackage,defparameter,defstruct,deftype,defvar,do-all-symbols,do-external-symbols,do-symbols,dolist,dotimes,ecase,etypecase,eval-when,labels,macrolet,multiple-value-bind,multiple-value-call,multiple-value-prog1,multiple-value-setq,prog1,progv,typecase,unless,unwind-protect,when,with-input-from-string,with-open-file,with-open-stream,with-output-to-string,with-package-iterator,define-condition,handler-bind,handler-case,restart-bind,restart-case,with-simple-restart,store-value,use-value,muffle-warning,abort,continue,with-slots,with-slots*,with-accessors,with-accessors*,defclass,defmethod,print-unreadable-object"
|
"defun,define,defmacro,set!,lambda,if,case,let,flet,let*,letrec,do,do*,define-syntax,let-syntax,letrec-syntax,destructuring-bind,defpackage,defparameter,defstruct,deftype,defvar,do-all-symbols,do-external-symbols,do-symbols,dolist,dotimes,ecase,etypecase,eval-when,labels,macrolet,multiple-value-bind,multiple-value-call,multiple-value-prog1,multiple-value-setq,prog1,progv,typecase,unless,unwind-protect,when,with-input-from-string,with-open-file,with-open-stream,with-output-to-string,with-package-iterator,define-condition,handler-bind,handler-case,restart-bind,restart-case,with-simple-restart,store-value,use-value,muffle-warning,abort,continue,with-slots,with-slots*,with-accessors,with-accessors*,defclass,defmethod,print-unreadable-object"
|
||||||
|
|
||||||
/*
|
// The following are actual variables for the options
|
||||||
* The following are actual variables for the options
|
|
||||||
*/
|
|
||||||
|
|
||||||
EXTERN long p_aleph; // 'aleph'
|
EXTERN long p_aleph; // 'aleph'
|
||||||
EXTERN char *p_ambw; ///< 'ambiwidth'
|
EXTERN char *p_ambw; ///< 'ambiwidth'
|
||||||
@@ -924,11 +922,9 @@ enum {
|
|||||||
BV_COUNT, // must be the last one
|
BV_COUNT, // must be the last one
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
// "indir" values for window-local options.
|
||||||
* "indir" values for window-local options.
|
// These need to be defined globally, so that the WV_COUNT can be used in the
|
||||||
* These need to be defined globally, so that the WV_COUNT can be used in the
|
// window structure.
|
||||||
* window structure.
|
|
||||||
*/
|
|
||||||
enum {
|
enum {
|
||||||
WV_LIST = 0,
|
WV_LIST = 0,
|
||||||
WV_ARAB,
|
WV_ARAB,
|
||||||
|
140
src/nvim/path.c
140
src/nvim/path.c
@@ -248,9 +248,7 @@ int vim_ispathsep(int c)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Like vim_ispathsep(c), but exclude the colon for MS-Windows.
|
||||||
* Like vim_ispathsep(c), but exclude the colon for MS-Windows.
|
|
||||||
*/
|
|
||||||
int vim_ispathsep_nocolon(int c)
|
int vim_ispathsep_nocolon(int c)
|
||||||
{
|
{
|
||||||
return vim_ispathsep(c)
|
return vim_ispathsep(c)
|
||||||
@@ -532,9 +530,7 @@ bool path_has_wildcard(const char *p)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Unix style wildcard expansion code.
|
||||||
* Unix style wildcard expansion code.
|
|
||||||
*/
|
|
||||||
static int pstrcmp(const void *a, const void *b)
|
static int pstrcmp(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return pathcmp(*(char **)a, *(char **)b, -1);
|
return pathcmp(*(char **)a, *(char **)b, -1);
|
||||||
@@ -779,10 +775,8 @@ static size_t do_path_expand(garray_T *gap, const char_u *path, size_t wildoff,
|
|||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Moves "*psep" back to the previous path separator in "path".
|
||||||
* Moves "*psep" back to the previous path separator in "path".
|
// Returns FAIL is "*psep" ends up at the beginning of "path".
|
||||||
* Returns FAIL is "*psep" ends up at the beginning of "path".
|
|
||||||
*/
|
|
||||||
static int find_previous_pathsep(char_u *path, char_u **psep)
|
static int find_previous_pathsep(char_u *path, char_u **psep)
|
||||||
{
|
{
|
||||||
// skip the current separator
|
// skip the current separator
|
||||||
@@ -825,15 +819,13 @@ static bool is_unique(char_u *maybe_unique, garray_T *gap, int i)
|
|||||||
return true; // no match found
|
return true; // no match found
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Split the 'path' option into an array of strings in garray_T. Relative
|
||||||
* Split the 'path' option into an array of strings in garray_T. Relative
|
// paths are expanded to their equivalent fullpath. This includes the "."
|
||||||
* paths are expanded to their equivalent fullpath. This includes the "."
|
// (relative to current buffer directory) and empty path (relative to current
|
||||||
* (relative to current buffer directory) and empty path (relative to current
|
// directory) notations.
|
||||||
* directory) notations.
|
//
|
||||||
*
|
// TODO(vim): handle upward search (;) and path limiter (**N) notations by
|
||||||
* TODO: handle upward search (;) and path limiter (**N) notations by
|
// expanding each into their equivalent path(s).
|
||||||
* expanding each into their equivalent path(s).
|
|
||||||
*/
|
|
||||||
static void expand_path_option(char_u *curdir, garray_T *gap)
|
static void expand_path_option(char_u *curdir, garray_T *gap)
|
||||||
{
|
{
|
||||||
char_u *path_option = *curbuf->b_p_path == NUL ? p_path : (char_u *)curbuf->b_p_path;
|
char_u *path_option = *curbuf->b_p_path == NUL ? p_path : (char_u *)curbuf->b_p_path;
|
||||||
@@ -883,14 +875,12 @@ static void expand_path_option(char_u *curdir, garray_T *gap)
|
|||||||
xfree(buf);
|
xfree(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Returns a pointer to the file or directory name in "fname" that matches the
|
||||||
* Returns a pointer to the file or directory name in "fname" that matches the
|
// longest path in "ga"p, or NULL if there is no match. For example:
|
||||||
* longest path in "ga"p, or NULL if there is no match. For example:
|
//
|
||||||
*
|
// path: /foo/bar/baz
|
||||||
* path: /foo/bar/baz
|
// fname: /foo/bar/baz/quux.txt
|
||||||
* fname: /foo/bar/baz/quux.txt
|
// returns: ^this
|
||||||
* returns: ^this
|
|
||||||
*/
|
|
||||||
static char_u *get_path_cutoff(char_u *fname, garray_T *gap)
|
static char_u *get_path_cutoff(char_u *fname, garray_T *gap)
|
||||||
{
|
{
|
||||||
int maxlen = 0;
|
int maxlen = 0;
|
||||||
@@ -924,11 +914,9 @@ static char_u *get_path_cutoff(char_u *fname, garray_T *gap)
|
|||||||
return cutoff;
|
return cutoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Sorts, removes duplicates and modifies all the fullpath names in "gap" so
|
||||||
* Sorts, removes duplicates and modifies all the fullpath names in "gap" so
|
// that they are unique with respect to each other while conserving the part
|
||||||
* that they are unique with respect to each other while conserving the part
|
// that matches the pattern. Beware, this is at least O(n^2) wrt "gap->ga_len".
|
||||||
* that matches the pattern. Beware, this is at least O(n^2) wrt "gap->ga_len".
|
|
||||||
*/
|
|
||||||
static void uniquefy_paths(garray_T *gap, char_u *pattern)
|
static void uniquefy_paths(garray_T *gap, char_u *pattern)
|
||||||
{
|
{
|
||||||
char_u **fnames = (char_u **)gap->ga_data;
|
char_u **fnames = (char_u **)gap->ga_data;
|
||||||
@@ -1212,26 +1200,23 @@ int gen_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, i
|
|||||||
int add_pat;
|
int add_pat;
|
||||||
bool did_expand_in_path = false;
|
bool did_expand_in_path = false;
|
||||||
|
|
||||||
/*
|
// expand_env() is called to expand things like "~user". If this fails,
|
||||||
* expand_env() is called to expand things like "~user". If this fails,
|
// it calls ExpandOne(), which brings us back here. In this case, always
|
||||||
* it calls ExpandOne(), which brings us back here. In this case, always
|
// call the machine specific expansion function, if possible. Otherwise,
|
||||||
* call the machine specific expansion function, if possible. Otherwise,
|
// return FAIL.
|
||||||
* return FAIL.
|
if (recursive) {
|
||||||
*/
|
|
||||||
if (recursive)
|
|
||||||
#ifdef SPECIAL_WILDCHAR
|
#ifdef SPECIAL_WILDCHAR
|
||||||
{ return os_expand_wildcards(num_pat, pat, num_file, file, flags); }
|
return os_expand_wildcards(num_pat, pat, num_file, file, flags);
|
||||||
#else
|
#else
|
||||||
{ return FAIL; }
|
return FAIL;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SPECIAL_WILDCHAR
|
#ifdef SPECIAL_WILDCHAR
|
||||||
/*
|
// If there are any special wildcard characters which we cannot handle
|
||||||
* If there are any special wildcard characters which we cannot handle
|
// here, call machine specific function for all the expansion. This
|
||||||
* here, call machine specific function for all the expansion. This
|
// avoids starting the shell for each argument separately.
|
||||||
* avoids starting the shell for each argument separately.
|
// For `=expr` do use the internal function.
|
||||||
* For `=expr` do use the internal function.
|
|
||||||
*/
|
|
||||||
for (int i = 0; i < num_pat; i++) {
|
for (int i = 0; i < num_pat; i++) {
|
||||||
if (has_special_wildchar((char_u *)pat[i])
|
if (has_special_wildchar((char_u *)pat[i])
|
||||||
&& !(vim_backtick((char_u *)pat[i]) && pat[i][1] == '=')) {
|
&& !(vim_backtick((char_u *)pat[i]) && pat[i][1] == '=')) {
|
||||||
@@ -1242,9 +1227,7 @@ int gen_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, i
|
|||||||
|
|
||||||
recursive = true;
|
recursive = true;
|
||||||
|
|
||||||
/*
|
// The matching file names are stored in a growarray. Init it empty.
|
||||||
* The matching file names are stored in a growarray. Init it empty.
|
|
||||||
*/
|
|
||||||
ga_init(&ga, (int)sizeof(char_u *), 30);
|
ga_init(&ga, (int)sizeof(char_u *), 30);
|
||||||
|
|
||||||
for (int i = 0; i < num_pat && !got_int; i++) {
|
for (int i = 0; i < num_pat && !got_int; i++) {
|
||||||
@@ -1266,14 +1249,12 @@ int gen_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, i
|
|||||||
p = expand_env_save_opt(p, true);
|
p = expand_env_save_opt(p, true);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
p = (char_u *)pat[i];
|
p = (char_u *)pat[i];
|
||||||
}
|
} else {
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
/*
|
// On Unix, if expand_env() can't expand an environment
|
||||||
* On Unix, if expand_env() can't expand an environment
|
// variable, use the shell to do that. Discard previously
|
||||||
* variable, use the shell to do that. Discard previously
|
// found file names and start all over again.
|
||||||
* found file names and start all over again.
|
if (has_env_var(p) || *p == '~') {
|
||||||
*/
|
|
||||||
else if (has_env_var(p) || *p == '~') {
|
|
||||||
xfree(p);
|
xfree(p);
|
||||||
ga_clear_strings(&ga);
|
ga_clear_strings(&ga);
|
||||||
i = os_expand_wildcards(num_pat, pat, num_file, file,
|
i = os_expand_wildcards(num_pat, pat, num_file, file,
|
||||||
@@ -1283,14 +1264,13 @@ int gen_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, i
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
// If there are wildcards: Expand file names and add each match to
|
||||||
* If there are wildcards: Expand file names and add each match to
|
// the list. If there is no match, and EW_NOTFOUND is given, add
|
||||||
* the list. If there is no match, and EW_NOTFOUND is given, add
|
// the pattern.
|
||||||
* the pattern.
|
// If there are no wildcards: Add the file name if it exists or
|
||||||
* If there are no wildcards: Add the file name if it exists or
|
// when EW_NOTFOUND is given.
|
||||||
* when EW_NOTFOUND is given.
|
|
||||||
*/
|
|
||||||
if (path_has_exp_wildcard(p)) {
|
if (path_has_exp_wildcard(p)) {
|
||||||
if ((flags & EW_PATH)
|
if ((flags & EW_PATH)
|
||||||
&& !path_is_absolute(p)
|
&& !path_is_absolute(p)
|
||||||
@@ -1491,21 +1471,17 @@ void addfile(garray_T *gap, char_u *f, int flags)
|
|||||||
#ifdef BACKSLASH_IN_FILENAME
|
#ifdef BACKSLASH_IN_FILENAME
|
||||||
slash_adjust(p);
|
slash_adjust(p);
|
||||||
#endif
|
#endif
|
||||||
/*
|
// Append a slash or backslash after directory names if none is present.
|
||||||
* Append a slash or backslash after directory names if none is present.
|
|
||||||
*/
|
|
||||||
if (isdir && (flags & EW_ADDSLASH)) {
|
if (isdir && (flags & EW_ADDSLASH)) {
|
||||||
add_pathsep((char *)p);
|
add_pathsep((char *)p);
|
||||||
}
|
}
|
||||||
GA_APPEND(char_u *, gap, p);
|
GA_APPEND(char_u *, gap, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Converts a file name into a canonical form. It simplifies a file name into
|
||||||
* Converts a file name into a canonical form. It simplifies a file name into
|
// its simplest form by stripping out unneeded components, if any. The
|
||||||
* its simplest form by stripping out unneeded components, if any. The
|
// resulting file name is simplified in place and will either be the same
|
||||||
* resulting file name is simplified in place and will either be the same
|
// length as that supplied, or shorter.
|
||||||
* length as that supplied, or shorter.
|
|
||||||
*/
|
|
||||||
void simplify_filename(char_u *filename)
|
void simplify_filename(char_u *filename)
|
||||||
{
|
{
|
||||||
int components = 0;
|
int components = 0;
|
||||||
@@ -1704,10 +1680,8 @@ char *find_file_name_in_path(char *ptr, size_t len, int options, long count, cha
|
|||||||
file_name = (char *)find_file_in_path((char_u *)ptr, len, options & ~FNAME_MESS, true,
|
file_name = (char *)find_file_in_path((char_u *)ptr, len, options & ~FNAME_MESS, true,
|
||||||
(char_u *)rel_fname);
|
(char_u *)rel_fname);
|
||||||
|
|
||||||
/*
|
// If the file could not be found in a normal way, try applying
|
||||||
* If the file could not be found in a normal way, try applying
|
// 'includeexpr' (unless done already).
|
||||||
* 'includeexpr' (unless done already).
|
|
||||||
*/
|
|
||||||
if (file_name == NULL
|
if (file_name == NULL
|
||||||
&& !(options & FNAME_INCL) && *curbuf->b_p_inex != NUL) {
|
&& !(options & FNAME_INCL) && *curbuf->b_p_inex != NUL) {
|
||||||
tofree = eval_includeexpr(ptr, len);
|
tofree = eval_includeexpr(ptr, len);
|
||||||
@@ -1976,11 +1950,9 @@ bool same_directory(char_u *f1, char_u *f2)
|
|||||||
&& pathcmp((char *)ffname, (char *)f2, (int)(t1 - ffname)) == 0;
|
&& pathcmp((char *)ffname, (char *)f2, (int)(t1 - ffname)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Compare path "p[]" to "q[]".
|
||||||
* Compare path "p[]" to "q[]".
|
// If "maxlen" >= 0 compare "p[maxlen]" to "q[maxlen]"
|
||||||
* If "maxlen" >= 0 compare "p[maxlen]" to "q[maxlen]"
|
// Return value like strcmp(p, q), but consider path separators.
|
||||||
* Return value like strcmp(p, q), but consider path separators.
|
|
||||||
*/
|
|
||||||
int pathcmp(const char *p, const char *q, int maxlen)
|
int pathcmp(const char *p, const char *q, int maxlen)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
@@ -2185,9 +2157,7 @@ int expand_wildcards(int num_pat, char **pat, int *num_files, char ***files, int
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Remove names that match 'wildignore'.
|
||||||
* Remove names that match 'wildignore'.
|
|
||||||
*/
|
|
||||||
if (*p_wig) {
|
if (*p_wig) {
|
||||||
char_u *ffname;
|
char_u *ffname;
|
||||||
|
|
||||||
|
@@ -18,8 +18,8 @@
|
|||||||
#define EW_NOERROR 0x200 // no error for bad regexp
|
#define EW_NOERROR 0x200 // no error for bad regexp
|
||||||
#define EW_NOTWILD 0x400 // add match with literal name if exists
|
#define EW_NOTWILD 0x400 // add match with literal name if exists
|
||||||
#define EW_KEEPDOLLAR 0x800 // do not escape $, $var is expanded
|
#define EW_KEEPDOLLAR 0x800 // do not escape $, $var is expanded
|
||||||
/* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
|
// Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
|
||||||
* is used when executing commands and EW_SILENT for interactive expanding. */
|
// is used when executing commands and EW_SILENT for interactive expanding.
|
||||||
#define EW_ALLLINKS 0x1000 // also links not pointing to existing file
|
#define EW_ALLLINKS 0x1000 // also links not pointing to existing file
|
||||||
#define EW_SHELLCMD 0x2000 // called from expand_shellcmd(), don't check
|
#define EW_SHELLCMD 0x2000 // called from expand_shellcmd(), don't check
|
||||||
// if executable is in $PATH
|
// if executable is in $PATH
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
/*
|
// search.c: code for normal mode searching commands
|
||||||
* search.c: code for normal mode searching commands
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -106,10 +104,8 @@ static bool saved_spats_no_hlsearch = false;
|
|||||||
static char_u *mr_pattern = NULL; // pattern used by search_regcomp()
|
static char_u *mr_pattern = NULL; // pattern used by search_regcomp()
|
||||||
static bool mr_pattern_alloced = false; // mr_pattern was allocated
|
static bool mr_pattern_alloced = false; // mr_pattern was allocated
|
||||||
|
|
||||||
/*
|
// Type used by find_pattern_in_path() to remember which included files have
|
||||||
* Type used by find_pattern_in_path() to remember which included files have
|
// been searched already.
|
||||||
* been searched already.
|
|
||||||
*/
|
|
||||||
typedef struct SearchedFile {
|
typedef struct SearchedFile {
|
||||||
FILE *fp; // File pointer
|
FILE *fp; // File pointer
|
||||||
char_u *name; // Full name of file
|
char_u *name; // Full name of file
|
||||||
@@ -139,9 +135,7 @@ int search_regcomp(char_u *pat, int pat_save, int pat_use, int options, regmmatc
|
|||||||
rc_did_emsg = false;
|
rc_did_emsg = false;
|
||||||
magic = p_magic;
|
magic = p_magic;
|
||||||
|
|
||||||
/*
|
// If no pattern given, use a previously defined pattern.
|
||||||
* If no pattern given, use a previously defined pattern.
|
|
||||||
*/
|
|
||||||
if (pat == NULL || *pat == NUL) {
|
if (pat == NULL || *pat == NUL) {
|
||||||
if (pat_use == RE_LAST) {
|
if (pat_use == RE_LAST) {
|
||||||
i = last_idx;
|
i = last_idx;
|
||||||
@@ -176,10 +170,8 @@ int search_regcomp(char_u *pat, int pat_save, int pat_use, int options, regmmatc
|
|||||||
mr_pattern = pat;
|
mr_pattern = pat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Save the currently used pattern in the appropriate place,
|
||||||
* Save the currently used pattern in the appropriate place,
|
// unless the pattern should not be remembered.
|
||||||
* unless the pattern should not be remembered.
|
|
||||||
*/
|
|
||||||
if (!(options & SEARCH_KEEP) && (cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) {
|
if (!(options & SEARCH_KEEP) && (cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) {
|
||||||
// search or global command
|
// search or global command
|
||||||
if (pat_save == RE_SEARCH || pat_save == RE_BOTH) {
|
if (pat_save == RE_SEARCH || pat_save == RE_BOTH) {
|
||||||
@@ -200,9 +192,7 @@ int search_regcomp(char_u *pat, int pat_save, int pat_use, int options, regmmatc
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get search pattern used by search_regcomp().
|
||||||
* Get search pattern used by search_regcomp().
|
|
||||||
*/
|
|
||||||
char_u *get_search_pat(void)
|
char_u *get_search_pat(void)
|
||||||
{
|
{
|
||||||
return mr_pattern;
|
return mr_pattern;
|
||||||
@@ -226,10 +216,8 @@ void save_re_pat(int idx, char_u *pat, int magic)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Save the search patterns, so they can be restored later.
|
||||||
* Save the search patterns, so they can be restored later.
|
// Used before/after executing autocommands and user functions.
|
||||||
* Used before/after executing autocommands and user functions.
|
|
||||||
*/
|
|
||||||
static int save_level = 0;
|
static int save_level = 0;
|
||||||
|
|
||||||
void save_search_patterns(void)
|
void save_search_patterns(void)
|
||||||
@@ -450,19 +438,15 @@ char_u *last_search_pat(void)
|
|||||||
return spats[last_idx].pat;
|
return spats[last_idx].pat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Reset search direction to forward. For "gd" and "gD" commands.
|
||||||
* Reset search direction to forward. For "gd" and "gD" commands.
|
|
||||||
*/
|
|
||||||
void reset_search_dir(void)
|
void reset_search_dir(void)
|
||||||
{
|
{
|
||||||
spats[0].off.dir = '/';
|
spats[0].off.dir = '/';
|
||||||
set_vv_searchforward();
|
set_vv_searchforward();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set the last search pattern. For ":let @/ =" and ShaDa file.
|
||||||
* Set the last search pattern. For ":let @/ =" and ShaDa file.
|
// Also set the saved search pattern, so that this works in an autocommand.
|
||||||
* Also set the saved search pattern, so that this works in an autocommand.
|
|
||||||
*/
|
|
||||||
void set_last_search_pat(const char_u *s, int idx, int magic, int setlast)
|
void set_last_search_pat(const char_u *s, int idx, int magic, int setlast)
|
||||||
{
|
{
|
||||||
free_spat(&spats[idx]);
|
free_spat(&spats[idx]);
|
||||||
@@ -500,11 +484,9 @@ void set_last_search_pat(const char_u *s, int idx, int magic, int setlast)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get a regexp program for the last used search pattern.
|
||||||
* Get a regexp program for the last used search pattern.
|
// This is used for highlighting all matches in a window.
|
||||||
* This is used for highlighting all matches in a window.
|
// Values returned in regmatch->regprog and regmatch->rmm_ic.
|
||||||
* Values returned in regmatch->regprog and regmatch->rmm_ic.
|
|
||||||
*/
|
|
||||||
void last_pat_prog(regmmatch_T *regmatch)
|
void last_pat_prog(regmmatch_T *regmatch)
|
||||||
{
|
{
|
||||||
if (spats[last_idx].pat == NULL) {
|
if (spats[last_idx].pat == NULL) {
|
||||||
@@ -578,9 +560,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// find the string
|
||||||
* find the string
|
|
||||||
*/
|
|
||||||
do { // loop for count
|
do { // loop for count
|
||||||
// When not accepting a match at the start position set "extra_col" to a
|
// When not accepting a match at the start position set "extra_col" to a
|
||||||
// non-zero value. Don't do that when starting at MAXCOL, since MAXCOL + 1
|
// non-zero value. Don't do that when starting at MAXCOL, since MAXCOL + 1
|
||||||
@@ -615,13 +595,11 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
|||||||
at_first_line = false; // not in first line now
|
at_first_line = false; // not in first line now
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Start searching in current line, unless searching backwards and
|
||||||
* Start searching in current line, unless searching backwards and
|
// we're in column 0.
|
||||||
* we're in column 0.
|
// If we are searching backwards, in column 0, and not including the
|
||||||
* If we are searching backwards, in column 0, and not including the
|
// current position, gain some efficiency by skipping back a line.
|
||||||
* current position, gain some efficiency by skipping back a line.
|
// Otherwise begin the search in the current line.
|
||||||
* Otherwise begin the search in the current line.
|
|
||||||
*/
|
|
||||||
if (dir == BACKWARD && start_pos.col == 0
|
if (dir == BACKWARD && start_pos.col == 0
|
||||||
&& (options & SEARCH_START) == 0) {
|
&& (options & SEARCH_START) == 0) {
|
||||||
lnum = pos->lnum - 1;
|
lnum = pos->lnum - 1;
|
||||||
@@ -667,11 +645,9 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
|||||||
ptr = ml_get_buf(buf, lnum + matchpos.lnum, false);
|
ptr = ml_get_buf(buf, lnum + matchpos.lnum, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Forward search in the first line: match should be after
|
||||||
* Forward search in the first line: match should be after
|
// the start position. If not, continue at the end of the
|
||||||
* the start position. If not, continue at the end of the
|
// match (this is vi compatible) or on the next char.
|
||||||
* match (this is vi compatible) or on the next char.
|
|
||||||
*/
|
|
||||||
if (dir == FORWARD && at_first_line) {
|
if (dir == FORWARD && at_first_line) {
|
||||||
match_ok = true;
|
match_ok = true;
|
||||||
// When the match starts in a next line it's certainly
|
// When the match starts in a next line it's certainly
|
||||||
@@ -687,11 +663,9 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
|||||||
: ((int)matchpos.col
|
: ((int)matchpos.col
|
||||||
- (ptr[matchpos.col] == NUL)
|
- (ptr[matchpos.col] == NUL)
|
||||||
< (int)start_pos.col + extra_col))) {
|
< (int)start_pos.col + extra_col))) {
|
||||||
/*
|
// If vi-compatible searching, continue at the end
|
||||||
* If vi-compatible searching, continue at the end
|
// of the match, otherwise continue one position
|
||||||
* of the match, otherwise continue one position
|
// forward.
|
||||||
* forward.
|
|
||||||
*/
|
|
||||||
if (vim_strchr(p_cpo, CPO_SEARCH) != NULL) {
|
if (vim_strchr(p_cpo, CPO_SEARCH) != NULL) {
|
||||||
if (nmatched > 1) {
|
if (nmatched > 1) {
|
||||||
// end is in next line, thus no match in
|
// end is in next line, thus no match in
|
||||||
@@ -744,13 +718,11 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dir == BACKWARD) {
|
if (dir == BACKWARD) {
|
||||||
/*
|
// Now, if there are multiple matches on this line,
|
||||||
* Now, if there are multiple matches on this line,
|
// we have to get the last one. Or the last one before
|
||||||
* we have to get the last one. Or the last one before
|
// the cursor, if we're on that line.
|
||||||
* the cursor, if we're on that line.
|
// When putting the new cursor at the end, compare
|
||||||
* When putting the new cursor at the end, compare
|
// relative to the end of the match.
|
||||||
* relative to the end of the match.
|
|
||||||
*/
|
|
||||||
match_ok = false;
|
match_ok = false;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// Remember a position that is before the start
|
// Remember a position that is before the start
|
||||||
@@ -825,10 +797,8 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
|||||||
ptr = ml_get_buf(buf, lnum + matchpos.lnum, false);
|
ptr = ml_get_buf(buf, lnum + matchpos.lnum, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If there is only a match after the cursor, skip
|
||||||
* If there is only a match after the cursor, skip
|
// this match.
|
||||||
* this match.
|
|
||||||
*/
|
|
||||||
if (!match_ok) {
|
if (!match_ok) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1042,25 +1012,19 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
|
|||||||
size_t len;
|
size_t len;
|
||||||
bool has_offset = false;
|
bool has_offset = false;
|
||||||
|
|
||||||
/*
|
// A line offset is not remembered, this is vi compatible.
|
||||||
* A line offset is not remembered, this is vi compatible.
|
|
||||||
*/
|
|
||||||
if (spats[0].off.line && vim_strchr(p_cpo, CPO_LINEOFF) != NULL) {
|
if (spats[0].off.line && vim_strchr(p_cpo, CPO_LINEOFF) != NULL) {
|
||||||
spats[0].off.line = false;
|
spats[0].off.line = false;
|
||||||
spats[0].off.off = 0;
|
spats[0].off.off = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Save the values for when (options & SEARCH_KEEP) is used.
|
||||||
* Save the values for when (options & SEARCH_KEEP) is used.
|
// (there is no "if ()" around this because gcc wants them initialized)
|
||||||
* (there is no "if ()" around this because gcc wants them initialized)
|
|
||||||
*/
|
|
||||||
old_off = spats[0].off;
|
old_off = spats[0].off;
|
||||||
|
|
||||||
pos = curwin->w_cursor; // start searching at the cursor position
|
pos = curwin->w_cursor; // start searching at the cursor position
|
||||||
|
|
||||||
/*
|
// Find out the direction of the search.
|
||||||
* Find out the direction of the search.
|
|
||||||
*/
|
|
||||||
if (dirc == 0) {
|
if (dirc == 0) {
|
||||||
dirc = (char_u)spats[0].off.dir;
|
dirc = (char_u)spats[0].off.dir;
|
||||||
} else {
|
} else {
|
||||||
@@ -1087,17 +1051,13 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Turn 'hlsearch' highlighting back on.
|
||||||
* Turn 'hlsearch' highlighting back on.
|
|
||||||
*/
|
|
||||||
if (no_hlsearch && !(options & SEARCH_KEEP)) {
|
if (no_hlsearch && !(options & SEARCH_KEEP)) {
|
||||||
redraw_all_later(UPD_SOME_VALID);
|
redraw_all_later(UPD_SOME_VALID);
|
||||||
set_no_hlsearch(false);
|
set_no_hlsearch(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Repeat the search when pattern followed by ';', e.g. "/foo/;?bar".
|
||||||
* Repeat the search when pattern followed by ';', e.g. "/foo/;?bar".
|
|
||||||
*/
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bool show_top_bot_msg = false;
|
bool show_top_bot_msg = false;
|
||||||
|
|
||||||
@@ -1119,10 +1079,8 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pat != NULL && *pat != NUL) { // look for (new) offset
|
if (pat != NULL && *pat != NUL) { // look for (new) offset
|
||||||
/*
|
// Find end of regular expression.
|
||||||
* Find end of regular expression.
|
// If there is a matching '/' or '?', toss it.
|
||||||
* If there is a matching '/' or '?', toss it.
|
|
||||||
*/
|
|
||||||
ps = (char_u *)strcopy;
|
ps = (char_u *)strcopy;
|
||||||
p = (char_u *)skip_regexp((char *)pat, search_delim, p_magic, &strcopy);
|
p = (char_u *)skip_regexp((char *)pat, search_delim, p_magic, &strcopy);
|
||||||
if (strcopy != (char *)ps) {
|
if (strcopy != (char *)ps) {
|
||||||
@@ -1287,13 +1245,11 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If there is a character offset, subtract it from the current
|
||||||
* If there is a character offset, subtract it from the current
|
// position, so we don't get stuck at "?pat?e+2" or "/pat/s-2".
|
||||||
* position, so we don't get stuck at "?pat?e+2" or "/pat/s-2".
|
// Skip this if pos.col is near MAXCOL (closed fold).
|
||||||
* Skip this if pos.col is near MAXCOL (closed fold).
|
// This is not done for a line offset, because then we would not be vi
|
||||||
* This is not done for a line offset, because then we would not be vi
|
// compatible.
|
||||||
* compatible.
|
|
||||||
*/
|
|
||||||
if (!spats[0].off.line && spats[0].off.off && pos.col < MAXCOL - 2) {
|
if (!spats[0].off.line && spats[0].off.off && pos.col < MAXCOL - 2) {
|
||||||
if (spats[0].off.off > 0) {
|
if (spats[0].off.off > 0) {
|
||||||
for (c = spats[0].off.off; c; c--) {
|
for (c = spats[0].off.off; c; c--) {
|
||||||
@@ -1350,9 +1306,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
|
|||||||
apply_autocmds(EVENT_SEARCHWRAPPED, NULL, NULL, false, NULL);
|
apply_autocmds(EVENT_SEARCHWRAPPED, NULL, NULL, false, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Add character and/or line offset
|
||||||
* Add character and/or line offset
|
|
||||||
*/
|
|
||||||
if (!(options & SEARCH_NOOF) || (pat != NULL && *pat == ';')) {
|
if (!(options & SEARCH_NOOF) || (pat != NULL && *pat == ';')) {
|
||||||
pos_T org_pos = pos;
|
pos_T org_pos = pos;
|
||||||
|
|
||||||
@@ -1444,15 +1398,13 @@ end_do_search:
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// search_for_exact_line(buf, pos, dir, pat)
|
||||||
* search_for_exact_line(buf, pos, dir, pat)
|
//
|
||||||
*
|
// Search for a line starting with the given pattern (ignoring leading
|
||||||
* Search for a line starting with the given pattern (ignoring leading
|
// white-space), starting from pos and going in direction "dir". "pos" will
|
||||||
* white-space), starting from pos and going in direction "dir". "pos" will
|
// contain the position of the match found. Blank lines match only if
|
||||||
* contain the position of the match found. Blank lines match only if
|
// ADDING is set. If p_ic is set then the pattern must be in lowercase.
|
||||||
* ADDING is set. If p_ic is set then the pattern must be in lowercase.
|
// Return OK for success, or FAIL if no line found.
|
||||||
* Return OK for success, or FAIL if no line found.
|
|
||||||
*/
|
|
||||||
int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat)
|
int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat)
|
||||||
{
|
{
|
||||||
linenr_T start = 0;
|
linenr_T start = 0;
|
||||||
@@ -1513,9 +1465,7 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Character Searches
|
||||||
* Character Searches
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// Search for a character in a line. If "t_cmd" is false, move to the
|
/// Search for a character in a line. If "t_cmd" is false, move to the
|
||||||
/// position of the character, otherwise move to just before the char.
|
/// position of the character, otherwise move to just before the char.
|
||||||
@@ -1618,15 +1568,11 @@ int searchc(cmdarg_T *cap, int t_cmd)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// "Other" Searches
|
||||||
* "Other" Searches
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
// findmatch - find the matching paren or brace
|
||||||
* findmatch - find the matching paren or brace
|
//
|
||||||
*
|
// Improvement over vi: Braces inside quotes are ignored.
|
||||||
* Improvement over vi: Braces inside quotes are ignored.
|
|
||||||
*/
|
|
||||||
pos_T *findmatch(oparg_T *oap, int initc)
|
pos_T *findmatch(oparg_T *oap, int initc)
|
||||||
{
|
{
|
||||||
return findmatchlimit(oap, initc, 0, 0);
|
return findmatchlimit(oap, initc, 0, 0);
|
||||||
@@ -1725,27 +1671,24 @@ static void find_mps_values(int *initc, int *findc, bool *backwards, bool switch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// findmatchlimit -- find the matching paren or brace, if it exists within
|
||||||
* findmatchlimit -- find the matching paren or brace, if it exists within
|
// maxtravel lines of the cursor. A maxtravel of 0 means search until falling
|
||||||
* maxtravel lines of the cursor. A maxtravel of 0 means search until falling
|
// off the edge of the file.
|
||||||
* off the edge of the file.
|
//
|
||||||
*
|
// "initc" is the character to find a match for. NUL means to find the
|
||||||
* "initc" is the character to find a match for. NUL means to find the
|
// character at or after the cursor. Special values:
|
||||||
* character at or after the cursor. Special values:
|
// '*' look for C-style comment / *
|
||||||
* '*' look for C-style comment / *
|
// '/' look for C-style comment / *, ignoring comment-end
|
||||||
* '/' look for C-style comment / *, ignoring comment-end
|
// '#' look for preprocessor directives
|
||||||
* '#' look for preprocessor directives
|
// 'R' look for raw string start: R"delim(text)delim" (only backwards)
|
||||||
* 'R' look for raw string start: R"delim(text)delim" (only backwards)
|
//
|
||||||
*
|
// flags: FM_BACKWARD search backwards (when initc is '/', '*' or '#')
|
||||||
* flags: FM_BACKWARD search backwards (when initc is '/', '*' or '#')
|
// FM_FORWARD search forwards (when initc is '/', '*' or '#')
|
||||||
* FM_FORWARD search forwards (when initc is '/', '*' or '#')
|
// FM_BLOCKSTOP stop at start/end of block ({ or } in column 0)
|
||||||
* FM_BLOCKSTOP stop at start/end of block ({ or } in column 0)
|
// FM_SKIPCOMM skip comments (not implemented yet!)
|
||||||
* FM_SKIPCOMM skip comments (not implemented yet!)
|
//
|
||||||
*
|
// "oap" is only used to set oap->motion_type for a linewise motion, it can be
|
||||||
* "oap" is only used to set oap->motion_type for a linewise motion, it can be
|
// NULL
|
||||||
* NULL
|
|
||||||
*/
|
|
||||||
|
|
||||||
pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
||||||
{
|
{
|
||||||
static pos_T pos; // current search position
|
static pos_T pos; // current search position
|
||||||
@@ -1783,12 +1726,10 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
|||||||
dir = 0;
|
dir = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// if initc given, look in the table for the matching character
|
||||||
* if initc given, look in the table for the matching character
|
// '/' and '*' are special cases: look for start or end of comment.
|
||||||
* '/' and '*' are special cases: look for start or end of comment.
|
// When '/' is used, we ignore running backwards into a star-slash, for
|
||||||
* When '/' is used, we ignore running backwards into a star-slash, for
|
// "[*" command, we just want to find any comment.
|
||||||
* "[*" command, we just want to find any comment.
|
|
||||||
*/
|
|
||||||
if (initc == '/' || initc == '*' || initc == 'R') {
|
if (initc == '/' || initc == '*' || initc == 'R') {
|
||||||
comment_dir = dir;
|
comment_dir = dir;
|
||||||
if (initc == '/') {
|
if (initc == '/') {
|
||||||
@@ -1806,18 +1747,14 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
// Either initc is '#', or no initc was given and we need to look
|
||||||
* Either initc is '#', or no initc was given and we need to look
|
// under the cursor.
|
||||||
* under the cursor.
|
|
||||||
*/
|
|
||||||
if (initc == '#') {
|
if (initc == '#') {
|
||||||
hash_dir = dir;
|
hash_dir = dir;
|
||||||
} else {
|
} else {
|
||||||
/*
|
// initc was not given, must look for something to match under
|
||||||
* initc was not given, must look for something to match under
|
// or near the cursor.
|
||||||
* or near the cursor.
|
// Only check for special things when 'cpo' doesn't have '%'.
|
||||||
* Only check for special things when 'cpo' doesn't have '%'.
|
|
||||||
*/
|
|
||||||
if (!cpo_match) {
|
if (!cpo_match) {
|
||||||
// Are we before or at #if, #else etc.?
|
// Are we before or at #if, #else etc.?
|
||||||
ptr = (char_u *)skipwhite((char *)linep);
|
ptr = (char_u *)skipwhite((char *)linep);
|
||||||
@@ -1851,16 +1788,12 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we are not on a comment or the # at the start of a line, then
|
||||||
* If we are not on a comment or the # at the start of a line, then
|
// look for brace anywhere on this line after the cursor.
|
||||||
* look for brace anywhere on this line after the cursor.
|
|
||||||
*/
|
|
||||||
if (!hash_dir && !comment_dir) {
|
if (!hash_dir && !comment_dir) {
|
||||||
/*
|
// Find the brace under or after the cursor.
|
||||||
* Find the brace under or after the cursor.
|
// If beyond the end of the line, use the last character in
|
||||||
* If beyond the end of the line, use the last character in
|
// the line.
|
||||||
* the line.
|
|
||||||
*/
|
|
||||||
if (linep[pos.col] == NUL && pos.col) {
|
if (linep[pos.col] == NUL && pos.col) {
|
||||||
pos.col--;
|
pos.col--;
|
||||||
}
|
}
|
||||||
@@ -1896,9 +1829,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hash_dir) {
|
if (hash_dir) {
|
||||||
/*
|
// Look for matching #if, #else, #elif, or #endif
|
||||||
* Look for matching #if, #else, #elif, or #endif
|
|
||||||
*/
|
|
||||||
if (oap != NULL) {
|
if (oap != NULL) {
|
||||||
oap->motion_type = kMTLineWise; // Linewise for this case only
|
oap->motion_type = kMTLineWise; // Linewise for this case only
|
||||||
}
|
}
|
||||||
@@ -1983,10 +1914,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (!got_int) {
|
while (!got_int) {
|
||||||
/*
|
// Go to the next position, forward or backward. We could use
|
||||||
* Go to the next position, forward or backward. We could use
|
// inc() and dec() here, but that is much slower
|
||||||
* inc() and dec() here, but that is much slower
|
|
||||||
*/
|
|
||||||
if (backwards) {
|
if (backwards) {
|
||||||
// char to match is inside of comment, don't search outside
|
// char to match is inside of comment, don't search outside
|
||||||
if (lispcomm && pos.col < (colnr_T)comment_col) {
|
if (lispcomm && pos.col < (colnr_T)comment_col) {
|
||||||
@@ -2067,10 +1996,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
|||||||
return &pos;
|
return &pos;
|
||||||
}
|
}
|
||||||
} else { // Searching backwards
|
} else { // Searching backwards
|
||||||
/*
|
// A comment may contain / * or / /, it may also start or end
|
||||||
* A comment may contain / * or / /, it may also start or end
|
// with / * /. Ignore a / * after / / and after *.
|
||||||
* with / * /. Ignore a / * after / / and after *.
|
|
||||||
*/
|
|
||||||
if (pos.col == 0) {
|
if (pos.col == 0) {
|
||||||
continue;
|
continue;
|
||||||
} else if (raw_string) {
|
} else if (raw_string) {
|
||||||
@@ -2113,18 +2040,14 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If smart matching ('cpoptions' does not contain '%'), braces inside
|
||||||
* If smart matching ('cpoptions' does not contain '%'), braces inside
|
// of quotes are ignored, but only if there is an even number of
|
||||||
* of quotes are ignored, but only if there is an even number of
|
// quotes in the line.
|
||||||
* quotes in the line.
|
|
||||||
*/
|
|
||||||
if (cpo_match) {
|
if (cpo_match) {
|
||||||
do_quotes = 0;
|
do_quotes = 0;
|
||||||
} else if (do_quotes == -1) {
|
} else if (do_quotes == -1) {
|
||||||
/*
|
// Count the number of quotes in the line, skipping \" and '"'.
|
||||||
* Count the number of quotes in the line, skipping \" and '"'.
|
// Watch out for "\\".
|
||||||
* Watch out for "\\".
|
|
||||||
*/
|
|
||||||
at_start = do_quotes;
|
at_start = do_quotes;
|
||||||
for (ptr = linep; *ptr; ptr++) {
|
for (ptr = linep; *ptr; ptr++) {
|
||||||
if (ptr == linep + pos.col + backwards) {
|
if (ptr == linep + pos.col + backwards) {
|
||||||
@@ -2140,10 +2063,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
|||||||
}
|
}
|
||||||
do_quotes &= 1; // result is 1 with even number of quotes
|
do_quotes &= 1; // result is 1 with even number of quotes
|
||||||
|
|
||||||
/*
|
// If we find an uneven count, check current line and previous
|
||||||
* If we find an uneven count, check current line and previous
|
// one for a '\' at the end.
|
||||||
* one for a '\' at the end.
|
|
||||||
*/
|
|
||||||
if (!do_quotes) {
|
if (!do_quotes) {
|
||||||
inquote = false;
|
inquote = false;
|
||||||
if (ptr[-1] == '\\') {
|
if (ptr[-1] == '\\') {
|
||||||
@@ -2179,17 +2100,15 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
|||||||
start_in_quotes = kFalse;
|
start_in_quotes = kFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If 'smartmatch' is set:
|
||||||
* If 'smartmatch' is set:
|
// Things inside quotes are ignored by setting 'inquote'. If we
|
||||||
* Things inside quotes are ignored by setting 'inquote'. If we
|
// find a quote without a preceding '\' invert 'inquote'. At the
|
||||||
* find a quote without a preceding '\' invert 'inquote'. At the
|
// end of a line not ending in '\' we reset 'inquote'.
|
||||||
* end of a line not ending in '\' we reset 'inquote'.
|
//
|
||||||
*
|
// In lines with an uneven number of quotes (without preceding '\')
|
||||||
* In lines with an uneven number of quotes (without preceding '\')
|
// we do not know which part to ignore. Therefore we only set
|
||||||
* we do not know which part to ignore. Therefore we only set
|
// inquote if the number of quotes in a line is even, unless this
|
||||||
* inquote if the number of quotes in a line is even, unless this
|
// line or the previous one ends in a '\'. Complicated, isn't it?
|
||||||
* line or the previous one ends in a '\'. Complicated, isn't it?
|
|
||||||
*/
|
|
||||||
const int c = utf_ptr2char((char *)linep + pos.col);
|
const int c = utf_ptr2char((char *)linep + pos.col);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case NUL:
|
case NUL:
|
||||||
@@ -2218,13 +2137,11 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
// If smart matching ('cpoptions' does not contain '%'):
|
||||||
* If smart matching ('cpoptions' does not contain '%'):
|
// Skip things in single quotes: 'x' or '\x'. Be careful for single
|
||||||
* Skip things in single quotes: 'x' or '\x'. Be careful for single
|
// single quotes, eg jon's. Things like '\233' or '\x3f' are not
|
||||||
* single quotes, eg jon's. Things like '\233' or '\x3f' are not
|
// skipped, there is never a brace in them.
|
||||||
* skipped, there is never a brace in them.
|
// Ignore this when finding matches for `'.
|
||||||
* Ignore this when finding matches for `'.
|
|
||||||
*/
|
|
||||||
case '\'':
|
case '\'':
|
||||||
if (!cpo_match && initc != '\'' && findc != '\'') {
|
if (!cpo_match && initc != '\'' && findc != '\'') {
|
||||||
if (backwards) {
|
if (backwards) {
|
||||||
@@ -2252,10 +2169,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
|||||||
FALLTHROUGH;
|
FALLTHROUGH;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/*
|
// For Lisp skip over backslashed (), {} and [].
|
||||||
* For Lisp skip over backslashed (), {} and [].
|
// (actually, we skip #\( et al)
|
||||||
* (actually, we skip #\( et al)
|
|
||||||
*/
|
|
||||||
if (curbuf->b_p_lisp
|
if (curbuf->b_p_lisp
|
||||||
&& vim_strchr("(){}[]", c) != NULL
|
&& vim_strchr("(){}[]", c) != NULL
|
||||||
&& pos.col > 1
|
&& pos.col > 1
|
||||||
@@ -2367,9 +2282,7 @@ void showmatch(int c)
|
|||||||
colnr_T save_dollar_vcol;
|
colnr_T save_dollar_vcol;
|
||||||
char_u *p;
|
char_u *p;
|
||||||
|
|
||||||
/*
|
// Only show match for chars in the 'matchpairs' option.
|
||||||
* Only show match for chars in the 'matchpairs' option.
|
|
||||||
*/
|
|
||||||
// 'matchpairs' is "x:y,x:y"
|
// 'matchpairs' is "x:y,x:y"
|
||||||
for (p = (char_u *)curbuf->b_p_mps; *p != NUL; p++) {
|
for (p = (char_u *)curbuf->b_p_mps; *p != NUL; p++) {
|
||||||
if (utf_ptr2char((char *)p) == c && (curwin->w_p_rl ^ p_ri)) {
|
if (utf_ptr2char((char *)p) == c && (curwin->w_p_rl ^ p_ri)) {
|
||||||
@@ -2425,10 +2338,8 @@ void showmatch(int c)
|
|||||||
// and has a higher column number.
|
// and has a higher column number.
|
||||||
dollar_vcol = save_dollar_vcol;
|
dollar_vcol = save_dollar_vcol;
|
||||||
|
|
||||||
/*
|
// brief pause, unless 'm' is present in 'cpo' and a character is
|
||||||
* brief pause, unless 'm' is present in 'cpo' and a character is
|
// available.
|
||||||
* available.
|
|
||||||
*/
|
|
||||||
if (vim_strchr(p_cpo, CPO_SHOWMATCH) != NULL) {
|
if (vim_strchr(p_cpo, CPO_SHOWMATCH) != NULL) {
|
||||||
os_delay((uint64_t)p_mat * 100L + 8, true);
|
os_delay((uint64_t)p_mat * 100L + 8, true);
|
||||||
} else if (!char_avail()) {
|
} else if (!char_avail()) {
|
||||||
@@ -3667,10 +3578,8 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo
|
|||||||
// 'includeexpr' is set.
|
// 'includeexpr' is set.
|
||||||
msg_outtrans_attr((char *)new_fname, HL_ATTR(HLF_D));
|
msg_outtrans_attr((char *)new_fname, HL_ATTR(HLF_D));
|
||||||
} else {
|
} else {
|
||||||
/*
|
// Isolate the file name.
|
||||||
* Isolate the file name.
|
// Include the surrounding "" or <> if present.
|
||||||
* Include the surrounding "" or <> if present.
|
|
||||||
*/
|
|
||||||
if (inc_opt != NULL
|
if (inc_opt != NULL
|
||||||
&& strstr(inc_opt, "\\zs") != NULL) {
|
&& strstr(inc_opt, "\\zs") != NULL) {
|
||||||
// pattern contains \zs, use the match
|
// pattern contains \zs, use the match
|
||||||
@@ -3763,9 +3672,7 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
// Check if the line is a define (type == FIND_DEFINE)
|
||||||
* Check if the line is a define (type == FIND_DEFINE)
|
|
||||||
*/
|
|
||||||
p = line;
|
p = line;
|
||||||
search_line:
|
search_line:
|
||||||
define_matched = false;
|
define_matched = false;
|
||||||
@@ -3781,10 +3688,8 @@ search_line:
|
|||||||
define_matched = true;
|
define_matched = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Look for a match. Don't do this if we are looking for a
|
||||||
* Look for a match. Don't do this if we are looking for a
|
// define and this line didn't match define_prog above.
|
||||||
* define and this line didn't match define_prog above.
|
|
||||||
*/
|
|
||||||
if (def_regmatch.regprog == NULL || define_matched) {
|
if (def_regmatch.regprog == NULL || define_matched) {
|
||||||
if (define_matched || compl_status_sol()) {
|
if (define_matched || compl_status_sol()) {
|
||||||
// compare the first "len" chars from "ptr"
|
// compare the first "len" chars from "ptr"
|
||||||
@@ -3812,12 +3717,10 @@ search_line:
|
|||||||
matched = false;
|
matched = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Also check for a "/ *" or "/ /" before the match.
|
||||||
* Also check for a "/ *" or "/ /" before the match.
|
// Skips lines like "int backwards; / * normal index
|
||||||
* Skips lines like "int backwards; / * normal index
|
// * /" when looking for "normal".
|
||||||
* * /" when looking for "normal".
|
// Note: Doesn't skip "/ *" in comments.
|
||||||
* Note: Doesn't skip "/ *" in comments.
|
|
||||||
*/
|
|
||||||
p = (char_u *)skipwhite((char *)line);
|
p = (char_u *)skipwhite((char *)line);
|
||||||
if (matched
|
if (matched
|
||||||
|| (p[0] == '/' && p[1] == '*') || p[0] == '*') {
|
|| (p[0] == '/' && p[1] == '*') || p[0] == '*') {
|
||||||
@@ -4033,11 +3936,9 @@ exit_matched:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Read the next line. When reading an included file and encountering
|
||||||
* Read the next line. When reading an included file and encountering
|
// end-of-file, close the file and continue in the file that included
|
||||||
* end-of-file, close the file and continue in the file that included
|
// it.
|
||||||
* it.
|
|
||||||
*/
|
|
||||||
while (depth >= 0 && !already
|
while (depth >= 0 && !already
|
||||||
&& vim_fgets(line = file_line, LSIZE, files[depth].fp)) {
|
&& vim_fgets(line = file_line, LSIZE, files[depth].fp)) {
|
||||||
fclose(files[depth].fp);
|
fclose(files[depth].fp);
|
||||||
|
@@ -65,28 +65,22 @@ char *xstrnsave(const char *string, size_t len)
|
|||||||
return strncpy(xmallocz(len), string, len); // NOLINT(runtime/printf)
|
return strncpy(xmallocz(len), string, len); // NOLINT(runtime/printf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Same as vim_strsave(), but any characters found in esc_chars are preceded
|
||||||
* Same as vim_strsave(), but any characters found in esc_chars are preceded
|
// by a backslash.
|
||||||
* by a backslash.
|
|
||||||
*/
|
|
||||||
char_u *vim_strsave_escaped(const char_u *string, const char_u *esc_chars)
|
char_u *vim_strsave_escaped(const char_u *string, const char_u *esc_chars)
|
||||||
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
return vim_strsave_escaped_ext(string, esc_chars, '\\', false);
|
return vim_strsave_escaped_ext(string, esc_chars, '\\', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Same as vim_strsave_escaped(), but when "bsl" is true also escape
|
||||||
* Same as vim_strsave_escaped(), but when "bsl" is true also escape
|
// characters where rem_backslash() would remove the backslash.
|
||||||
* characters where rem_backslash() would remove the backslash.
|
// Escape the characters with "cc".
|
||||||
* Escape the characters with "cc".
|
|
||||||
*/
|
|
||||||
char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars, char_u cc, bool bsl)
|
char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars, char_u cc, bool bsl)
|
||||||
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
/*
|
// First count the number of backslashes required.
|
||||||
* First count the number of backslashes required.
|
// Then allocate the memory and insert them.
|
||||||
* Then allocate the memory and insert them.
|
|
||||||
*/
|
|
||||||
size_t length = 1; // count the trailing NUL
|
size_t length = 1; // count the trailing NUL
|
||||||
for (const char_u *p = string; *p; p++) {
|
for (const char_u *p = string; *p; p++) {
|
||||||
const size_t l = (size_t)(utfc_ptr2len((char *)p));
|
const size_t l = (size_t)(utfc_ptr2len((char *)p));
|
||||||
@@ -169,16 +163,14 @@ char *vim_strnsave_unquoted(const char *const string, const size_t length)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Escape "string" for use as a shell argument with system().
|
||||||
* Escape "string" for use as a shell argument with system().
|
// This uses single quotes, except when we know we need to use double quotes
|
||||||
* This uses single quotes, except when we know we need to use double quotes
|
// (MS-Windows without 'shellslash' set).
|
||||||
* (MS-Windows without 'shellslash' set).
|
// Escape a newline, depending on the 'shell' option.
|
||||||
* Escape a newline, depending on the 'shell' option.
|
// When "do_special" is true also replace "!", "%", "#" and things starting
|
||||||
* When "do_special" is true also replace "!", "%", "#" and things starting
|
// with "<" like "<cfile>".
|
||||||
* with "<" like "<cfile>".
|
// When "do_newline" is false do not escape newline unless it is csh shell.
|
||||||
* When "do_newline" is false do not escape newline unless it is csh shell.
|
// Returns the result in allocated memory.
|
||||||
* Returns the result in allocated memory.
|
|
||||||
*/
|
|
||||||
char_u *vim_strsave_shellescape(const char_u *string, bool do_special, bool do_newline)
|
char_u *vim_strsave_shellescape(const char_u *string, bool do_special, bool do_newline)
|
||||||
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
@@ -295,10 +287,8 @@ char_u *vim_strsave_shellescape(const char_u *string, bool do_special, bool do_n
|
|||||||
return escaped_string;
|
return escaped_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Like vim_strsave(), but make all characters uppercase.
|
||||||
* Like vim_strsave(), but make all characters uppercase.
|
// This uses ASCII lower-to-upper case translation, language independent.
|
||||||
* This uses ASCII lower-to-upper case translation, language independent.
|
|
||||||
*/
|
|
||||||
char_u *vim_strsave_up(const char_u *string)
|
char_u *vim_strsave_up(const char_u *string)
|
||||||
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
@@ -319,9 +309,7 @@ char *vim_strnsave_up(const char *string, size_t len)
|
|||||||
return p1;
|
return p1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// ASCII lower-to-upper case translation, language independent.
|
||||||
* ASCII lower-to-upper case translation, language independent.
|
|
||||||
*/
|
|
||||||
void vim_strup(char_u *p)
|
void vim_strup(char_u *p)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
@@ -375,9 +363,7 @@ char *strcase_save(const char *const orig, bool upper)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// delete spaces at the end of a string
|
||||||
* delete spaces at the end of a string
|
|
||||||
*/
|
|
||||||
void del_trailing_spaces(char_u *ptr)
|
void del_trailing_spaces(char_u *ptr)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
@@ -402,11 +388,9 @@ size_t xstrnlen(const char *s, size_t n)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP))
|
#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP))
|
||||||
/*
|
// Compare two strings, ignoring case, using current locale.
|
||||||
* Compare two strings, ignoring case, using current locale.
|
// Doesn't work for multi-byte characters.
|
||||||
* Doesn't work for multi-byte characters.
|
// return 0 for match, < 0 for smaller, > 0 for bigger
|
||||||
* return 0 for match, < 0 for smaller, > 0 for bigger
|
|
||||||
*/
|
|
||||||
int vim_stricmp(const char *s1, const char *s2)
|
int vim_stricmp(const char *s1, const char *s2)
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
|
||||||
{
|
{
|
||||||
@@ -428,11 +412,9 @@ int vim_stricmp(const char *s1, const char *s2)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (!defined(HAVE_STRNCASECMP) && !defined(HAVE_STRNICMP))
|
#if (!defined(HAVE_STRNCASECMP) && !defined(HAVE_STRNICMP))
|
||||||
/*
|
// Compare two strings, for length "len", ignoring case, using current locale.
|
||||||
* Compare two strings, for length "len", ignoring case, using current locale.
|
// Doesn't work for multi-byte characters.
|
||||||
* Doesn't work for multi-byte characters.
|
// return 0 for match, < 0 for smaller, > 0 for bigger
|
||||||
* return 0 for match, < 0 for smaller, > 0 for bigger
|
|
||||||
*/
|
|
||||||
int vim_strnicmp(const char *s1, const char *s2, size_t len)
|
int vim_strnicmp(const char *s1, const char *s2, size_t len)
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
|
||||||
{
|
{
|
||||||
@@ -477,9 +459,7 @@ char *vim_strchr(const char *const string, const int c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Sort an array of strings.
|
||||||
* Sort an array of strings.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "strings.c.generated.h"
|
# include "strings.c.generated.h"
|
||||||
@@ -495,10 +475,8 @@ void sort_strings(char **files, int count)
|
|||||||
qsort((void *)files, (size_t)count, sizeof(char *), sort_compare);
|
qsort((void *)files, (size_t)count, sizeof(char *), sort_compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return true if string "s" contains a non-ASCII character (128 or higher).
|
||||||
* Return true if string "s" contains a non-ASCII character (128 or higher).
|
// When "s" is NULL false is returned.
|
||||||
* When "s" is NULL false is returned.
|
|
||||||
*/
|
|
||||||
bool has_non_ascii(const char_u *s)
|
bool has_non_ascii(const char_u *s)
|
||||||
FUNC_ATTR_PURE
|
FUNC_ATTR_PURE
|
||||||
{
|
{
|
||||||
|
1046
src/nvim/syntax.c
1046
src/nvim/syntax.c
File diff suppressed because it is too large
Load Diff
341
src/nvim/tag.c
341
src/nvim/tag.c
@@ -1,9 +1,7 @@
|
|||||||
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
// This is an open source non-commercial project. Dear PVS-Studio, please check
|
||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
/*
|
// Code to handle tags and the tag stack
|
||||||
* Code to handle tags and the tag stack
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -51,9 +49,7 @@
|
|||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
#include "nvim/window.h"
|
#include "nvim/window.h"
|
||||||
|
|
||||||
/*
|
// Structure to hold pointers to various items in a tag line.
|
||||||
* Structure to hold pointers to various items in a tag line.
|
|
||||||
*/
|
|
||||||
typedef struct tag_pointers {
|
typedef struct tag_pointers {
|
||||||
// filled in by parse_tag_line():
|
// filled in by parse_tag_line():
|
||||||
char_u *tagname; // start of tag name (skip "file:")
|
char_u *tagname; // start of tag name (skip "file:")
|
||||||
@@ -73,9 +69,7 @@ typedef struct tag_pointers {
|
|||||||
linenr_T tagline; // "line:" value
|
linenr_T tagline; // "line:" value
|
||||||
} tagptrs_T;
|
} tagptrs_T;
|
||||||
|
|
||||||
/*
|
// Structure to hold info about the tag pattern being used.
|
||||||
* Structure to hold info about the tag pattern being used.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char_u *pat; // the pattern
|
char_u *pat; // the pattern
|
||||||
int len; // length of pat[]
|
int len; // length of pat[]
|
||||||
@@ -117,10 +111,8 @@ static char_u *tfu_inv_ret_msg
|
|||||||
|
|
||||||
static char_u *tagmatchname = NULL; // name of last used tag
|
static char_u *tagmatchname = NULL; // name of last used tag
|
||||||
|
|
||||||
/*
|
// Tag for preview window is remembered separately, to avoid messing up the
|
||||||
* Tag for preview window is remembered separately, to avoid messing up the
|
// normal tagstack.
|
||||||
* normal tagstack.
|
|
||||||
*/
|
|
||||||
static taggy_T ptag_entry = { NULL, INIT_FMARK, 0, 0, NULL };
|
static taggy_T ptag_entry = { NULL, INIT_FMARK, 0, 0, NULL };
|
||||||
|
|
||||||
static int tfu_in_use = false; // disallow recursive call of tagfunc
|
static int tfu_in_use = false; // disallow recursive call of tagfunc
|
||||||
@@ -243,10 +235,8 @@ bool do_tag(char_u *tag, int type, int count, int forceit, int verbose)
|
|||||||
ptag_entry.tagname = (char *)vim_strsave(tag);
|
ptag_entry.tagname = (char *)vim_strsave(tag);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
// If the last used entry is not at the top, delete all tag
|
||||||
* If the last used entry is not at the top, delete all tag
|
// stack entries above it.
|
||||||
* stack entries above it.
|
|
||||||
*/
|
|
||||||
while (tagstackidx < tagstacklen) {
|
while (tagstackidx < tagstacklen) {
|
||||||
tagstack_clear_entry(&tagstack[--tagstacklen]);
|
tagstack_clear_entry(&tagstack[--tagstacklen]);
|
||||||
}
|
}
|
||||||
@@ -300,10 +290,8 @@ bool do_tag(char_u *tag, int type, int count, int forceit, int verbose)
|
|||||||
// tagstack before it's used.
|
// tagstack before it's used.
|
||||||
saved_fmark = tagstack[tagstackidx].fmark;
|
saved_fmark = tagstack[tagstackidx].fmark;
|
||||||
if (saved_fmark.fnum != curbuf->b_fnum) {
|
if (saved_fmark.fnum != curbuf->b_fnum) {
|
||||||
/*
|
// Jump to other file. If this fails (e.g. because the
|
||||||
* Jump to other file. If this fails (e.g. because the
|
// file was changed) keep original position in tag stack.
|
||||||
* file was changed) keep original position in tag stack.
|
|
||||||
*/
|
|
||||||
if (buflist_getfile(saved_fmark.fnum, saved_fmark.mark.lnum,
|
if (buflist_getfile(saved_fmark.fnum, saved_fmark.mark.lnum,
|
||||||
GETF_SETMARK, forceit) == FAIL) {
|
GETF_SETMARK, forceit) == FAIL) {
|
||||||
tagstackidx = oldtagstackidx; // back to old posn
|
tagstackidx = oldtagstackidx; // back to old posn
|
||||||
@@ -340,11 +328,9 @@ bool do_tag(char_u *tag, int type, int count, int forceit, int verbose)
|
|||||||
// ":tag" (no argument): go to newer pattern
|
// ":tag" (no argument): go to newer pattern
|
||||||
save_pos = true; // save the cursor position below
|
save_pos = true; // save the cursor position below
|
||||||
if ((tagstackidx += count - 1) >= tagstacklen) {
|
if ((tagstackidx += count - 1) >= tagstacklen) {
|
||||||
/*
|
// Beyond the last one, just give an error message and
|
||||||
* Beyond the last one, just give an error message and
|
// go to the last one. Don't store the cursor
|
||||||
* go to the last one. Don't store the cursor
|
// position.
|
||||||
* position.
|
|
||||||
*/
|
|
||||||
tagstackidx = tagstacklen - 1;
|
tagstackidx = tagstacklen - 1;
|
||||||
emsg(_(topmsg));
|
emsg(_(topmsg));
|
||||||
save_pos = false;
|
save_pos = false;
|
||||||
@@ -401,9 +387,7 @@ bool do_tag(char_u *tag, int type, int count, int forceit, int verbose)
|
|||||||
ptag_entry.cur_fnum = cur_fnum;
|
ptag_entry.cur_fnum = cur_fnum;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
// For ":tag [arg]" or ":tselect" remember position before the jump.
|
||||||
* For ":tag [arg]" or ":tselect" remember position before the jump.
|
|
||||||
*/
|
|
||||||
saved_fmark = tagstack[tagstackidx].fmark;
|
saved_fmark = tagstack[tagstackidx].fmark;
|
||||||
if (save_pos) {
|
if (save_pos) {
|
||||||
tagstack[tagstackidx].fmark.mark = curwin->w_cursor;
|
tagstack[tagstackidx].fmark.mark = curwin->w_cursor;
|
||||||
@@ -432,9 +416,7 @@ bool do_tag(char_u *tag, int type, int count, int forceit, int verbose)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Repeat searching for tags, when a file has not been found.
|
||||||
* Repeat searching for tags, when a file has not been found.
|
|
||||||
*/
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int other_name;
|
int other_name;
|
||||||
char_u *name;
|
char_u *name;
|
||||||
@@ -598,10 +580,8 @@ bool do_tag(char_u *tag, int type, int count, int forceit, int verbose)
|
|||||||
ptag_entry.cur_fnum = cur_fnum;
|
ptag_entry.cur_fnum = cur_fnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Only when going to try the next match, report that the previous
|
||||||
* Only when going to try the next match, report that the previous
|
// file didn't exist. Otherwise an emsg() is given below.
|
||||||
* file didn't exist. Otherwise an emsg() is given below.
|
|
||||||
*/
|
|
||||||
if (nofile_fname != NULL && error_cur_match != cur_match) {
|
if (nofile_fname != NULL && error_cur_match != cur_match) {
|
||||||
smsg(_("File \"%s\" does not exist"), nofile_fname);
|
smsg(_("File \"%s\" does not exist"), nofile_fname);
|
||||||
}
|
}
|
||||||
@@ -640,9 +620,7 @@ bool do_tag(char_u *tag, int type, int count, int forceit, int verbose)
|
|||||||
vim_snprintf((char *)IObuff, IOSIZE, ":ta %s\r", name);
|
vim_snprintf((char *)IObuff, IOSIZE, ":ta %s\r", name);
|
||||||
set_vim_var_string(VV_SWAPCOMMAND, (char *)IObuff, -1);
|
set_vim_var_string(VV_SWAPCOMMAND, (char *)IObuff, -1);
|
||||||
|
|
||||||
/*
|
// Jump to the desired match.
|
||||||
* Jump to the desired match.
|
|
||||||
*/
|
|
||||||
i = jumpto_tag((char_u *)matches[cur_match], forceit, type != DT_CSCOPE);
|
i = jumpto_tag((char_u *)matches[cur_match], forceit, type != DT_CSCOPE);
|
||||||
|
|
||||||
set_vim_var_string(VV_SWAPCOMMAND, NULL, -1);
|
set_vim_var_string(VV_SWAPCOMMAND, NULL, -1);
|
||||||
@@ -1005,9 +983,7 @@ static int add_llist_tags(char_u *tag, int num_matches, char **matches)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Free cached tags.
|
||||||
* Free cached tags.
|
|
||||||
*/
|
|
||||||
void tag_freematch(void)
|
void tag_freematch(void)
|
||||||
{
|
{
|
||||||
XFREE_CLEAR(tagmatchname);
|
XFREE_CLEAR(tagmatchname);
|
||||||
@@ -1023,9 +999,7 @@ static void taglen_advance(int l)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Print the tag stack
|
||||||
* Print the tag stack
|
|
||||||
*/
|
|
||||||
void do_tags(exarg_T *eap)
|
void do_tags(exarg_T *eap)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -1061,11 +1035,9 @@ void do_tags(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Compare two strings, for length "len", ignoring case the ASCII way.
|
||||||
* Compare two strings, for length "len", ignoring case the ASCII way.
|
// return 0 for match, < 0 for smaller, > 0 for bigger
|
||||||
* return 0 for match, < 0 for smaller, > 0 for bigger
|
// Make sure case is folded to uppercase in comparison (like for 'sort -f')
|
||||||
* Make sure case is folded to uppercase in comparison (like for 'sort -f')
|
|
||||||
*/
|
|
||||||
static int tag_strnicmp(char_u *s1, char_u *s2, size_t len)
|
static int tag_strnicmp(char_u *s1, char_u *s2, size_t len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -1085,9 +1057,7 @@ static int tag_strnicmp(char_u *s1, char_u *s2, size_t len)
|
|||||||
return 0; // strings match
|
return 0; // strings match
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Extract info from the tag search pattern "pats->pat".
|
||||||
* Extract info from the tag search pattern "pats->pat".
|
|
||||||
*/
|
|
||||||
static void prepare_pats(pat_T *pats, int has_re)
|
static void prepare_pats(pat_T *pats, int has_re)
|
||||||
{
|
{
|
||||||
pats->head = pats->pat;
|
pats->head = pats->pat;
|
||||||
@@ -1472,9 +1442,7 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
|
|||||||
orgpat.regmatch.regprog = NULL;
|
orgpat.regmatch.regprog = NULL;
|
||||||
vimconv.vc_type = CONV_NONE;
|
vimconv.vc_type = CONV_NONE;
|
||||||
|
|
||||||
/*
|
// Allocate memory for the buffers that are used
|
||||||
* Allocate memory for the buffers that are used
|
|
||||||
*/
|
|
||||||
lbuf = xmalloc((size_t)lbuf_size);
|
lbuf = xmalloc((size_t)lbuf_size);
|
||||||
tag_fname = xmalloc(MAXPATHL + 1);
|
tag_fname = xmalloc(MAXPATHL + 1);
|
||||||
for (mtt = 0; mtt < MT_COUNT; mtt++) {
|
for (mtt = 0; mtt < MT_COUNT; mtt++) {
|
||||||
@@ -1484,9 +1452,7 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
|
|||||||
|
|
||||||
STRCPY(tag_fname, "from cscope"); // for error messages
|
STRCPY(tag_fname, "from cscope"); // for error messages
|
||||||
|
|
||||||
/*
|
// Initialize a few variables
|
||||||
* Initialize a few variables
|
|
||||||
*/
|
|
||||||
if (help_only) { // want tags from help file
|
if (help_only) { // want tags from help file
|
||||||
curbuf->b_help = true; // will be restored later
|
curbuf->b_help = true; // will be restored later
|
||||||
} else if (use_cscope) {
|
} else if (use_cscope) {
|
||||||
@@ -1534,16 +1500,15 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When finding a specified number of matches, first try with matching
|
||||||
* When finding a specified number of matches, first try with matching
|
// case, so binary search can be used, and try ignore-case matches in a
|
||||||
* case, so binary search can be used, and try ignore-case matches in a
|
// second loop.
|
||||||
* second loop.
|
// When finding all matches, 'tagbsearch' is off, or there is no fixed
|
||||||
* When finding all matches, 'tagbsearch' is off, or there is no fixed
|
// string to look for, ignore case right away to avoid going though the
|
||||||
* string to look for, ignore case right away to avoid going though the
|
// tags files twice.
|
||||||
* tags files twice.
|
// When the tag file is case-fold sorted, it is either one or the other.
|
||||||
* When the tag file is case-fold sorted, it is either one or the other.
|
// Only ignore case when TAG_NOIC not used or 'ignorecase' set.
|
||||||
* Only ignore case when TAG_NOIC not used or 'ignorecase' set.
|
|
||||||
*/
|
|
||||||
// Set a flag if the file extension is .txt
|
// Set a flag if the file extension is .txt
|
||||||
if ((flags & TAG_KEEP_LANG)
|
if ((flags & TAG_KEEP_LANG)
|
||||||
&& help_lang_find == NULL
|
&& help_lang_find == NULL
|
||||||
@@ -1634,9 +1599,7 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
|
|||||||
|
|
||||||
state = TS_START; // we're at the start of the file
|
state = TS_START; // we're at the start of the file
|
||||||
|
|
||||||
/*
|
// Read and parse the lines in the file one by one
|
||||||
* Read and parse the lines in the file one by one
|
|
||||||
*/
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// check for CTRL-C typed, more often when jumping around
|
// check for CTRL-C typed, more often when jumping around
|
||||||
if (state == TS_BINARY || state == TS_SKIP_BACK) {
|
if (state == TS_BINARY || state == TS_SKIP_BACK) {
|
||||||
@@ -1661,9 +1624,7 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
|
|||||||
if (get_it_again) {
|
if (get_it_again) {
|
||||||
goto line_read_in;
|
goto line_read_in;
|
||||||
}
|
}
|
||||||
/*
|
// For binary search: compute the next offset to use.
|
||||||
* For binary search: compute the next offset to use.
|
|
||||||
*/
|
|
||||||
if (state == TS_BINARY) {
|
if (state == TS_BINARY) {
|
||||||
offset = search_info.low_offset + ((search_info.high_offset
|
offset = search_info.low_offset + ((search_info.high_offset
|
||||||
- search_info.low_offset) / 2);
|
- search_info.low_offset) / 2);
|
||||||
@@ -1682,10 +1643,8 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When jumping around in the file, first read a line to find the
|
||||||
* When jumping around in the file, first read a line to find the
|
// start of the next line.
|
||||||
* start of the next line.
|
|
||||||
*/
|
|
||||||
if (state == TS_BINARY || state == TS_SKIP_BACK) {
|
if (state == TS_BINARY || state == TS_SKIP_BACK) {
|
||||||
// Adjust the search file offset to the correct position
|
// Adjust the search file offset to the correct position
|
||||||
search_info.curr_offset_used = search_info.curr_offset;
|
search_info.curr_offset_used = search_info.curr_offset;
|
||||||
@@ -1714,11 +1673,9 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
|
|||||||
search_info.curr_offset = search_info.curr_offset_used;
|
search_info.curr_offset = search_info.curr_offset_used;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
/*
|
// Not jumping around in the file: Read the next line.
|
||||||
* Not jumping around in the file: Read the next line.
|
|
||||||
*/
|
|
||||||
else {
|
|
||||||
// skip empty and blank lines
|
// skip empty and blank lines
|
||||||
do {
|
do {
|
||||||
eof = use_cscope
|
eof = use_cscope
|
||||||
@@ -1754,10 +1711,8 @@ line_read_in:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When still at the start of the file, check for Emacs tags file
|
||||||
* When still at the start of the file, check for Emacs tags file
|
// format, and for "not sorted" flag.
|
||||||
* format, and for "not sorted" flag.
|
|
||||||
*/
|
|
||||||
if (state == TS_START) {
|
if (state == TS_START) {
|
||||||
// The header ends when the line sorts below "!_TAG_". When
|
// The header ends when the line sorts below "!_TAG_". When
|
||||||
// case is folded lower case letters sort before "_".
|
// case is folded lower case letters sort before "_".
|
||||||
@@ -1768,9 +1723,7 @@ line_read_in:
|
|||||||
goto parse_line;
|
goto parse_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Read header line.
|
||||||
* Read header line.
|
|
||||||
*/
|
|
||||||
if (STRNCMP(lbuf, "!_TAG_FILE_SORTED\t", 18) == 0) {
|
if (STRNCMP(lbuf, "!_TAG_FILE_SORTED\t", 18) == 0) {
|
||||||
tag_file_sorted = lbuf[18];
|
tag_file_sorted = lbuf[18];
|
||||||
}
|
}
|
||||||
@@ -1788,15 +1741,13 @@ line_read_in:
|
|||||||
|
|
||||||
// Headers ends.
|
// Headers ends.
|
||||||
|
|
||||||
/*
|
// When there is no tag head, or ignoring case, need to do a
|
||||||
* When there is no tag head, or ignoring case, need to do a
|
// linear search.
|
||||||
* linear search.
|
// When no "!_TAG_" is found, default to binary search. If
|
||||||
* When no "!_TAG_" is found, default to binary search. If
|
// the tag file isn't sorted, the second loop will find it.
|
||||||
* the tag file isn't sorted, the second loop will find it.
|
// When "!_TAG_FILE_SORTED" found: start binary search if
|
||||||
* When "!_TAG_FILE_SORTED" found: start binary search if
|
// flag set.
|
||||||
* flag set.
|
// For cscope, it's always linear.
|
||||||
* For cscope, it's always linear.
|
|
||||||
*/
|
|
||||||
if (linear || use_cscope) {
|
if (linear || use_cscope) {
|
||||||
state = TS_LINEAR;
|
state = TS_LINEAR;
|
||||||
} else if (tag_file_sorted == NUL) {
|
} else if (tag_file_sorted == NUL) {
|
||||||
@@ -1871,10 +1822,8 @@ parse_line:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Skip this line if the length of the tag is different and
|
||||||
* Skip this line if the length of the tag is different and
|
// there is no regexp, or the tag is too short.
|
||||||
* there is no regexp, or the tag is too short.
|
|
||||||
*/
|
|
||||||
cmplen = (int)(tagp.tagname_end - tagp.tagname);
|
cmplen = (int)(tagp.tagname_end - tagp.tagname);
|
||||||
if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength'
|
if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength'
|
||||||
cmplen = (int)p_tl;
|
cmplen = (int)p_tl;
|
||||||
@@ -1886,9 +1835,7 @@ parse_line:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state == TS_BINARY) {
|
if (state == TS_BINARY) {
|
||||||
/*
|
// Simplistic check for unsorted tags file.
|
||||||
* Simplistic check for unsorted tags file.
|
|
||||||
*/
|
|
||||||
i = (int)tagp.tagname[0];
|
i = (int)tagp.tagname[0];
|
||||||
if (sortic) {
|
if (sortic) {
|
||||||
i = TOUPPER_ASC(tagp.tagname[0]);
|
i = TOUPPER_ASC(tagp.tagname[0]);
|
||||||
@@ -1897,9 +1844,7 @@ parse_line:
|
|||||||
sort_error = true;
|
sort_error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Compare the current tag with the searched tag.
|
||||||
* Compare the current tag with the searched tag.
|
|
||||||
*/
|
|
||||||
if (sortic) {
|
if (sortic) {
|
||||||
tagcmp = tag_strnicmp(tagp.tagname, orgpat.head,
|
tagcmp = tag_strnicmp(tagp.tagname, orgpat.head,
|
||||||
(size_t)cmplen);
|
(size_t)cmplen);
|
||||||
@@ -1907,10 +1852,8 @@ parse_line:
|
|||||||
tagcmp = STRNCMP(tagp.tagname, orgpat.head, cmplen);
|
tagcmp = STRNCMP(tagp.tagname, orgpat.head, cmplen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// A match with a shorter tag means to search forward.
|
||||||
* A match with a shorter tag means to search forward.
|
// A match with a longer tag means to search backward.
|
||||||
* A match with a longer tag means to search backward.
|
|
||||||
*/
|
|
||||||
if (tagcmp == 0) {
|
if (tagcmp == 0) {
|
||||||
if (cmplen < orgpat.headlen) {
|
if (cmplen < orgpat.headlen) {
|
||||||
tagcmp = -1;
|
tagcmp = -1;
|
||||||
@@ -1998,10 +1941,8 @@ parse_line:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// First try matching with the pattern literally (also when it is
|
||||||
* First try matching with the pattern literally (also when it is
|
// a regexp).
|
||||||
* a regexp).
|
|
||||||
*/
|
|
||||||
cmplen = (int)(tagp.tagname_end - tagp.tagname);
|
cmplen = (int)(tagp.tagname_end - tagp.tagname);
|
||||||
if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength'
|
if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength'
|
||||||
cmplen = (int)p_tl;
|
cmplen = (int)p_tl;
|
||||||
@@ -2022,9 +1963,7 @@ parse_line:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Has a regexp: Also find tags matching regexp.
|
||||||
* Has a regexp: Also find tags matching regexp.
|
|
||||||
*/
|
|
||||||
match_re = false;
|
match_re = false;
|
||||||
if (!match && orgpat.regmatch.regprog != NULL) {
|
if (!match && orgpat.regmatch.regprog != NULL) {
|
||||||
int cc;
|
int cc;
|
||||||
@@ -2211,9 +2150,7 @@ parse_line:
|
|||||||
sort_error = false;
|
sort_error = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Stop searching if sufficient tags have been found.
|
||||||
* Stop searching if sufficient tags have been found.
|
|
||||||
*/
|
|
||||||
if (match_count >= mincount) {
|
if (match_count >= mincount) {
|
||||||
retval = OK;
|
retval = OK;
|
||||||
stop_searching = true;
|
stop_searching = true;
|
||||||
@@ -2251,10 +2188,8 @@ findtag_end:
|
|||||||
vim_regfree(orgpat.regmatch.regprog);
|
vim_regfree(orgpat.regmatch.regprog);
|
||||||
xfree(tag_fname);
|
xfree(tag_fname);
|
||||||
|
|
||||||
/*
|
// Move the matches from the ga_match[] arrays into one list of
|
||||||
* Move the matches from the ga_match[] arrays into one list of
|
// matches. When retval == FAIL, free the matches.
|
||||||
* matches. When retval == FAIL, free the matches.
|
|
||||||
*/
|
|
||||||
if (retval == FAIL) {
|
if (retval == FAIL) {
|
||||||
match_count = 0;
|
match_count = 0;
|
||||||
}
|
}
|
||||||
@@ -2303,10 +2238,8 @@ findtag_end:
|
|||||||
|
|
||||||
static garray_T tag_fnames = GA_EMPTY_INIT_VALUE;
|
static garray_T tag_fnames = GA_EMPTY_INIT_VALUE;
|
||||||
|
|
||||||
/*
|
// Callback function for finding all "tags" and "tags-??" files in
|
||||||
* Callback function for finding all "tags" and "tags-??" files in
|
// 'runtimepath' doc directories.
|
||||||
* 'runtimepath' doc directories.
|
|
||||||
*/
|
|
||||||
static void found_tagfile_cb(char *fname, void *cookie)
|
static void found_tagfile_cb(char *fname, void *cookie)
|
||||||
{
|
{
|
||||||
char_u *const tag_fname = vim_strsave((char_u *)fname);
|
char_u *const tag_fname = vim_strsave((char_u *)fname);
|
||||||
@@ -2348,11 +2281,9 @@ int get_tagfname(tagname_T *tnp, int first, char *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (curbuf->b_help) {
|
if (curbuf->b_help) {
|
||||||
/*
|
// For help files it's done in a completely different way:
|
||||||
* For help files it's done in a completely different way:
|
// Find "doc/tags" and "doc/tags-??" in all directories in
|
||||||
* Find "doc/tags" and "doc/tags-??" in all directories in
|
// 'runtimepath'.
|
||||||
* 'runtimepath'.
|
|
||||||
*/
|
|
||||||
if (first) {
|
if (first) {
|
||||||
ga_clear_strings(&tag_fnames);
|
ga_clear_strings(&tag_fnames);
|
||||||
ga_init(&tag_fnames, (int)sizeof(char *), 10);
|
ga_init(&tag_fnames, (int)sizeof(char *), 10);
|
||||||
@@ -2392,12 +2323,10 @@ int get_tagfname(tagname_T *tnp, int first, char *buf)
|
|||||||
tnp->tn_np = (char *)tnp->tn_tags;
|
tnp->tn_np = (char *)tnp->tn_tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Loop until we have found a file name that can be used.
|
||||||
* Loop until we have found a file name that can be used.
|
// There are two states:
|
||||||
* There are two states:
|
// tnp->tn_did_filefind_init == false: setup for next part in 'tags'.
|
||||||
* tnp->tn_did_filefind_init == false: setup for next part in 'tags'.
|
// tnp->tn_did_filefind_init == true: find next file in this part.
|
||||||
* tnp->tn_did_filefind_init == true: find next file in this part.
|
|
||||||
*/
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (tnp->tn_did_filefind_init) {
|
if (tnp->tn_did_filefind_init) {
|
||||||
fname = (char *)vim_findfile(tnp->tn_search_ctx);
|
fname = (char *)vim_findfile(tnp->tn_search_ctx);
|
||||||
@@ -2416,9 +2345,7 @@ int get_tagfname(tagname_T *tnp, int first, char *buf)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Copy next file name into buf.
|
||||||
* Copy next file name into buf.
|
|
||||||
*/
|
|
||||||
buf[0] = NUL;
|
buf[0] = NUL;
|
||||||
(void)copy_option_part(&tnp->tn_np, buf, MAXPATHL - 1, " ,");
|
(void)copy_option_part(&tnp->tn_np, buf, MAXPATHL - 1, " ,");
|
||||||
|
|
||||||
@@ -2445,9 +2372,7 @@ int get_tagfname(tagname_T *tnp, int first, char *buf)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Free the contents of a tagname_T that was filled by get_tagfname().
|
||||||
* Free the contents of a tagname_T that was filled by get_tagfname().
|
|
||||||
*/
|
|
||||||
void tagname_free(tagname_T *tnp)
|
void tagname_free(tagname_T *tnp)
|
||||||
{
|
{
|
||||||
xfree(tnp->tn_tags);
|
xfree(tnp->tn_tags);
|
||||||
@@ -2499,20 +2424,18 @@ static int parse_tag_line(char_u *lbuf, tagptrs_T *tagp)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check if tagname is a static tag
|
||||||
* Check if tagname is a static tag
|
//
|
||||||
*
|
// Static tags produced by the older ctags program have the format:
|
||||||
* Static tags produced by the older ctags program have the format:
|
// 'file:tag file /pattern'.
|
||||||
* 'file:tag file /pattern'.
|
// This is only recognized when both occurrence of 'file' are the same, to
|
||||||
* This is only recognized when both occurrence of 'file' are the same, to
|
// avoid recognizing "string::string" or ":exit".
|
||||||
* avoid recognizing "string::string" or ":exit".
|
//
|
||||||
*
|
// Static tags produced by the new ctags program have the format:
|
||||||
* Static tags produced by the new ctags program have the format:
|
// 'tag file /pattern/;"<Tab>file:' "
|
||||||
* 'tag file /pattern/;"<Tab>file:' "
|
//
|
||||||
*
|
// Return true if it is a static tag and adjust *tagname to the real tag.
|
||||||
* Return true if it is a static tag and adjust *tagname to the real tag.
|
// Return false if it is not a static tag.
|
||||||
* Return false if it is not a static tag.
|
|
||||||
*/
|
|
||||||
static bool test_for_static(tagptrs_T *tagp)
|
static bool test_for_static(tagptrs_T *tagp)
|
||||||
{
|
{
|
||||||
char_u *p;
|
char_u *p;
|
||||||
@@ -2620,11 +2543,9 @@ static int parse_match(char *lbuf, tagptrs_T *tagp)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Find out the actual file name of a tag. Concatenate the tags file name
|
||||||
* Find out the actual file name of a tag. Concatenate the tags file name
|
// with the matching tag file name.
|
||||||
* with the matching tag file name.
|
// Returns an allocated string.
|
||||||
* Returns an allocated string.
|
|
||||||
*/
|
|
||||||
static char_u *tag_full_fname(tagptrs_T *tagp)
|
static char_u *tag_full_fname(tagptrs_T *tagp)
|
||||||
{
|
{
|
||||||
int c = *tagp->fname_end;
|
int c = *tagp->fname_end;
|
||||||
@@ -2688,9 +2609,7 @@ static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help)
|
|||||||
*pbuf_end = NUL;
|
*pbuf_end = NUL;
|
||||||
|
|
||||||
{
|
{
|
||||||
/*
|
// Remove the "<Tab>fieldname:value" stuff; we don't need it here.
|
||||||
* Remove the "<Tab>fieldname:value" stuff; we don't need it here.
|
|
||||||
*/
|
|
||||||
str = pbuf;
|
str = pbuf;
|
||||||
if (find_extra(&str) == OK) {
|
if (find_extra(&str) == OK) {
|
||||||
pbuf_end = str;
|
pbuf_end = str;
|
||||||
@@ -2698,18 +2617,14 @@ static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Expand file name, when needed (for environment variables).
|
||||||
* Expand file name, when needed (for environment variables).
|
// If 'tagrelative' option set, may change file name.
|
||||||
* If 'tagrelative' option set, may change file name.
|
|
||||||
*/
|
|
||||||
fname = expand_tag_fname(fname, tagp.tag_fname, true);
|
fname = expand_tag_fname(fname, tagp.tag_fname, true);
|
||||||
tofree_fname = fname; // free() it later
|
tofree_fname = fname; // free() it later
|
||||||
|
|
||||||
/*
|
// Check if the file with the tag exists before abandoning the current
|
||||||
* Check if the file with the tag exists before abandoning the current
|
// file. Also accept a file name for which there is a matching BufReadCmd
|
||||||
* file. Also accept a file name for which there is a matching BufReadCmd
|
// autocommand event (e.g., http://sys/file).
|
||||||
* autocommand event (e.g., http://sys/file).
|
|
||||||
*/
|
|
||||||
if (!os_path_exists((char *)fname)
|
if (!os_path_exists((char *)fname)
|
||||||
&& !has_autocmd(EVENT_BUFREADCMD, (char *)fname,
|
&& !has_autocmd(EVENT_BUFREADCMD, (char *)fname,
|
||||||
NULL)) {
|
NULL)) {
|
||||||
@@ -2725,19 +2640,15 @@ static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help)
|
|||||||
postponed_split = 0; // don't split again below
|
postponed_split = 0; // don't split again below
|
||||||
curwin_save = curwin; // Save current window
|
curwin_save = curwin; // Save current window
|
||||||
|
|
||||||
/*
|
// If we are reusing a window, we may change dir when
|
||||||
* If we are reusing a window, we may change dir when
|
// entering it (autocommands) so turn the tag filename
|
||||||
* entering it (autocommands) so turn the tag filename
|
// into a fullpath
|
||||||
* into a fullpath
|
|
||||||
*/
|
|
||||||
if (!curwin->w_p_pvw) {
|
if (!curwin->w_p_pvw) {
|
||||||
full_fname = (char_u *)FullName_save((char *)fname, false);
|
full_fname = (char_u *)FullName_save((char *)fname, false);
|
||||||
fname = full_fname;
|
fname = full_fname;
|
||||||
|
|
||||||
/*
|
// Make the preview window the current window.
|
||||||
* Make the preview window the current window.
|
// Open a preview window when needed.
|
||||||
* Open a preview window when needed.
|
|
||||||
*/
|
|
||||||
prepare_tagpreview(true);
|
prepare_tagpreview(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2803,25 +2714,21 @@ static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help)
|
|||||||
// Save value of no_hlsearch, jumping to a tag is not a real search
|
// Save value of no_hlsearch, jumping to a tag is not a real search
|
||||||
const bool save_no_hlsearch = no_hlsearch;
|
const bool save_no_hlsearch = no_hlsearch;
|
||||||
|
|
||||||
/*
|
// If 'cpoptions' contains 't', store the search pattern for the "n"
|
||||||
* If 'cpoptions' contains 't', store the search pattern for the "n"
|
// command. If 'cpoptions' does not contain 't', the search pattern
|
||||||
* command. If 'cpoptions' does not contain 't', the search pattern
|
// is not stored.
|
||||||
* is not stored.
|
|
||||||
*/
|
|
||||||
if (vim_strchr(p_cpo, CPO_TAGPAT) != NULL) {
|
if (vim_strchr(p_cpo, CPO_TAGPAT) != NULL) {
|
||||||
search_options = 0;
|
search_options = 0;
|
||||||
} else {
|
} else {
|
||||||
search_options = SEARCH_KEEP;
|
search_options = SEARCH_KEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If the command is a search, try here.
|
||||||
* If the command is a search, try here.
|
//
|
||||||
*
|
// Reset 'smartcase' for the search, since the search pattern was not
|
||||||
* Reset 'smartcase' for the search, since the search pattern was not
|
// typed by the user.
|
||||||
* typed by the user.
|
// Only use do_search() when there is a full search command, without
|
||||||
* Only use do_search() when there is a full search command, without
|
// anything following.
|
||||||
* anything following.
|
|
||||||
*/
|
|
||||||
str = pbuf;
|
str = pbuf;
|
||||||
if (pbuf[0] == '/' || pbuf[0] == '?') {
|
if (pbuf[0] == '/' || pbuf[0] == '?') {
|
||||||
str = (char_u *)skip_regexp((char *)pbuf + 1, pbuf[0], false, NULL) + 1;
|
str = (char_u *)skip_regexp((char *)pbuf + 1, pbuf[0], false, NULL) + 1;
|
||||||
@@ -2848,9 +2755,7 @@ static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help)
|
|||||||
int found = 1;
|
int found = 1;
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
/*
|
// try again, ignore case now
|
||||||
* try again, ignore case now
|
|
||||||
*/
|
|
||||||
p_ic = true;
|
p_ic = true;
|
||||||
if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, (long)1,
|
if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, (long)1,
|
||||||
search_options, NULL)) {
|
search_options, NULL)) {
|
||||||
@@ -2875,10 +2780,8 @@ static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help)
|
|||||||
emsg(_("E434: Can't find tag pattern"));
|
emsg(_("E434: Can't find tag pattern"));
|
||||||
curwin->w_cursor.lnum = save_lnum;
|
curwin->w_cursor.lnum = save_lnum;
|
||||||
} else {
|
} else {
|
||||||
/*
|
// Only give a message when really guessed, not when 'ic'
|
||||||
* Only give a message when really guessed, not when 'ic'
|
// is set and match found while ignoring case.
|
||||||
* is set and match found while ignoring case.
|
|
||||||
*/
|
|
||||||
if (found == 2 || !save_p_ic) {
|
if (found == 2 || !save_p_ic) {
|
||||||
msg(_("E435: Couldn't find tag, just guessing!"));
|
msg(_("E435: Couldn't find tag, just guessing!"));
|
||||||
if (!msg_scrolled && msg_silent == 0) {
|
if (!msg_scrolled && msg_silent == 0) {
|
||||||
@@ -2927,10 +2830,8 @@ static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (retval == OK) {
|
if (retval == OK) {
|
||||||
/*
|
// For a help buffer: Put the cursor line at the top of the window,
|
||||||
* For a help buffer: Put the cursor line at the top of the window,
|
// the help subject will be below it.
|
||||||
* the help subject will be below it.
|
|
||||||
*/
|
|
||||||
if (curbuf->b_help) {
|
if (curbuf->b_help) {
|
||||||
set_topline(curwin, curwin->w_cursor.lnum);
|
set_topline(curwin, curwin->w_cursor.lnum);
|
||||||
}
|
}
|
||||||
@@ -2976,9 +2877,7 @@ static char_u *expand_tag_fname(char_u *fname, char_u *const tag_fname, const bo
|
|||||||
char_u *expanded_fname = NULL;
|
char_u *expanded_fname = NULL;
|
||||||
expand_T xpc;
|
expand_T xpc;
|
||||||
|
|
||||||
/*
|
// Expand file name (for environment variables) when needed.
|
||||||
* Expand file name (for environment variables) when needed.
|
|
||||||
*/
|
|
||||||
if (expand && path_has_wildcard((char *)fname)) {
|
if (expand && path_has_wildcard((char *)fname)) {
|
||||||
ExpandInit(&xpc);
|
ExpandInit(&xpc);
|
||||||
xpc.xp_context = EXPAND_FILES;
|
xpc.xp_context = EXPAND_FILES;
|
||||||
@@ -2997,9 +2896,7 @@ static char_u *expand_tag_fname(char_u *fname, char_u *const tag_fname, const bo
|
|||||||
STRCPY(retval, tag_fname);
|
STRCPY(retval, tag_fname);
|
||||||
STRLCPY(retval + (p - tag_fname), fname,
|
STRLCPY(retval + (p - tag_fname), fname,
|
||||||
MAXPATHL - (p - tag_fname));
|
MAXPATHL - (p - tag_fname));
|
||||||
/*
|
// Translate names like "src/a/../b/file.c" into "src/b/file.c".
|
||||||
* Translate names like "src/a/../b/file.c" into "src/b/file.c".
|
|
||||||
*/
|
|
||||||
simplify_filename(retval);
|
simplify_filename(retval);
|
||||||
} else {
|
} else {
|
||||||
retval = vim_strsave(fname);
|
retval = vim_strsave(fname);
|
||||||
@@ -3034,10 +2931,8 @@ static int test_for_current(char *fname, char *fname_end, char *tag_fname, char
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Find the end of the tagaddress.
|
||||||
* Find the end of the tagaddress.
|
// Return OK if ";\"" is following, FAIL otherwise.
|
||||||
* Return OK if ";\"" is following, FAIL otherwise.
|
|
||||||
*/
|
|
||||||
static int find_extra(char_u **pp)
|
static int find_extra(char_u **pp)
|
||||||
{
|
{
|
||||||
char_u *str = *pp;
|
char_u *str = *pp;
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user