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:
Lewis Russell
2022-09-02 17:39:49 +01:00
committed by GitHub
parent 69456f3414
commit 1ffd527c83
38 changed files with 3494 additions and 5838 deletions

View File

@@ -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;

View File

@@ -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];

View File

@@ -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.

View File

@@ -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) {

View File

@@ -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(&regmatch, curwin, || (nmatch = vim_regexec_multi(&regmatch, 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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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(&regmatch, fname, (colnr_T)0) && (vim_regexec(&regmatch, fname, (colnr_T)0)

View File

@@ -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

View File

@@ -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

View File

@@ -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");

View File

@@ -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;

View File

@@ -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);

File diff suppressed because it is too large Load Diff

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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)
{ {

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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')

View File

@@ -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';
} }

View File

@@ -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:

View 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) {

View File

@@ -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,

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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
{ {

File diff suppressed because it is too large Load Diff

View File

@@ -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