aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-11-30 10:12:09 +0800
committerzeertzjq <zeertzjq@outlook.com>2022-11-30 10:12:28 +0800
commite0c7b8955d0193ebbc7df703179ecb035f73fec7 (patch)
tree24633385f252c0fe1659b6c225b2f0d4cd1c4af2
parent3f743c39d3be332eede7fe7a4f6641dd9348b922 (diff)
downloadrneovim-e0c7b8955d0193ebbc7df703179ecb035f73fec7.tar.gz
rneovim-e0c7b8955d0193ebbc7df703179ecb035f73fec7.tar.bz2
rneovim-e0c7b8955d0193ebbc7df703179ecb035f73fec7.zip
refactor: move ex_retab() to indent.c
-rw-r--r--src/nvim/ex_cmds.c186
-rw-r--r--src/nvim/generators/gen_ex_cmds.lua1
-rw-r--r--src/nvim/indent.c189
3 files changed, 190 insertions, 186 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 78d0435c9f..8ae7646268 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -719,192 +719,6 @@ sortend:
}
}
-/// ":retab".
-void ex_retab(exarg_T *eap)
-{
- linenr_T lnum;
- bool got_tab = false;
- long num_spaces = 0;
- long num_tabs;
- long len;
- long col;
- long vcol;
- long start_col = 0; // For start of white-space string
- long start_vcol = 0; // For start of white-space string
- long old_len;
- char *ptr;
- char *new_line = (char *)1; // init to non-NULL
- bool did_undo; // called u_save for current line
- long *new_vts_array = NULL;
- char *new_ts_str; // string value of tab argument
-
- int save_list;
- linenr_T first_line = 0; // first changed line
- linenr_T last_line = 0; // last changed line
-
- save_list = curwin->w_p_list;
- curwin->w_p_list = 0; // don't want list mode here
-
- new_ts_str = eap->arg;
- if (!tabstop_set(eap->arg, &new_vts_array)) {
- return;
- }
- while (ascii_isdigit(*(eap->arg)) || *(eap->arg) == ',') {
- (eap->arg)++;
- }
-
- // This ensures that either new_vts_array and new_ts_str are freshly
- // allocated, or new_vts_array points to an existing array and new_ts_str
- // is null.
- if (new_vts_array == NULL) {
- new_vts_array = curbuf->b_p_vts_array;
- new_ts_str = NULL;
- } else {
- new_ts_str = xstrnsave(new_ts_str, (size_t)(eap->arg - new_ts_str));
- }
- for (lnum = eap->line1; !got_int && lnum <= eap->line2; lnum++) {
- ptr = ml_get(lnum);
- col = 0;
- vcol = 0;
- did_undo = false;
- for (;;) {
- if (ascii_iswhite(ptr[col])) {
- if (!got_tab && num_spaces == 0) {
- // First consecutive white-space
- start_vcol = vcol;
- start_col = col;
- }
- if (ptr[col] == ' ') {
- num_spaces++;
- } else {
- got_tab = true;
- }
- } else {
- if (got_tab || (eap->forceit && num_spaces > 1)) {
- // Retabulate this string of white-space
-
- // len is virtual length of white string
- len = num_spaces = vcol - start_vcol;
- num_tabs = 0;
- if (!curbuf->b_p_et) {
- int t, s;
-
- tabstop_fromto((colnr_T)start_vcol, (colnr_T)vcol,
- curbuf->b_p_ts, new_vts_array, &t, &s);
- num_tabs = t;
- num_spaces = s;
- }
- if (curbuf->b_p_et || got_tab
- || (num_spaces + num_tabs < len)) {
- if (did_undo == false) {
- did_undo = true;
- if (u_save((linenr_T)(lnum - 1),
- (linenr_T)(lnum + 1)) == FAIL) {
- new_line = NULL; // flag out-of-memory
- break;
- }
- }
-
- // len is actual number of white characters used
- len = num_spaces + num_tabs;
- old_len = (long)strlen(ptr);
- const long new_len = old_len - col + start_col + len + 1;
- if (new_len <= 0 || new_len >= MAXCOL) {
- emsg(_(e_resulting_text_too_long));
- break;
- }
- new_line = xmalloc((size_t)new_len);
-
- if (start_col > 0) {
- memmove(new_line, ptr, (size_t)start_col);
- }
- memmove(new_line + start_col + len,
- ptr + col, (size_t)(old_len - col + 1));
- ptr = new_line + start_col;
- for (col = 0; col < len; col++) {
- ptr[col] = (col < num_tabs) ? '\t' : ' ';
- }
- if (ml_replace(lnum, new_line, false) == OK) {
- // "new_line" may have been copied
- new_line = curbuf->b_ml.ml_line_ptr;
- extmark_splice_cols(curbuf, lnum - 1, 0, (colnr_T)old_len,
- (colnr_T)new_len - 1, kExtmarkUndo);
- }
- if (first_line == 0) {
- first_line = lnum;
- }
- last_line = lnum;
- ptr = new_line;
- col = start_col + len;
- }
- }
- got_tab = false;
- num_spaces = 0;
- }
- if (ptr[col] == NUL) {
- break;
- }
- vcol += win_chartabsize(curwin, ptr + col, (colnr_T)vcol);
- if (vcol >= MAXCOL) {
- emsg(_(e_resulting_text_too_long));
- // when not inside a try/catch set got_int to break out of any
- // loop
- if (trylevel == 0) {
- got_int = true;
- }
- break;
- }
- col += utfc_ptr2len(ptr + col);
- }
- if (new_line == NULL) { // out of memory
- break;
- }
- line_breakcheck();
- }
- if (got_int) {
- emsg(_(e_interr));
- }
-
- // If a single value was given then it can be considered equal to
- // either the value of 'tabstop' or the value of 'vartabstop'.
- if (tabstop_count(curbuf->b_p_vts_array) == 0
- && tabstop_count(new_vts_array) == 1
- && curbuf->b_p_ts == tabstop_first(new_vts_array)) {
- // not changed
- } else if (tabstop_count(curbuf->b_p_vts_array) > 0
- && tabstop_eq(curbuf->b_p_vts_array, new_vts_array)) {
- // not changed
- } else {
- redraw_curbuf_later(UPD_NOT_VALID);
- }
- if (first_line != 0) {
- changed_lines(first_line, 0, last_line + 1, 0L, true);
- }
-
- curwin->w_p_list = save_list; // restore 'list'
-
- if (new_ts_str != NULL) { // set the new tabstop
- // If 'vartabstop' is in use or if the value given to retab has more
- // than one tabstop then update 'vartabstop'.
- long *old_vts_ary = curbuf->b_p_vts_array;
-
- if (tabstop_count(old_vts_ary) > 0 || tabstop_count(new_vts_array) > 1) {
- set_string_option_direct("vts", -1, new_ts_str, OPT_FREE | OPT_LOCAL, 0);
- curbuf->b_p_vts_array = new_vts_array;
- xfree(old_vts_ary);
- } else {
- // 'vartabstop' wasn't in use and a single value was given to
- // retab then update 'tabstop'.
- curbuf->b_p_ts = tabstop_first(new_vts_array);
- xfree(new_vts_array);
- }
- xfree(new_ts_str);
- }
- coladvance(curwin->w_curswant);
-
- u_clearline();
-}
-
/// :move command - move lines line1-line2 to line dest
///
/// @return FAIL for failure, OK otherwise
diff --git a/src/nvim/generators/gen_ex_cmds.lua b/src/nvim/generators/gen_ex_cmds.lua
index ac60b9f8e9..3a022d45c8 100644
--- a/src/nvim/generators/gen_ex_cmds.lua
+++ b/src/nvim/generators/gen_ex_cmds.lua
@@ -66,6 +66,7 @@ defsfile:write(string.format([[
#include "nvim/ex_session.h"
#include "nvim/hardcopy.h"
#include "nvim/help.h"
+#include "nvim/indent.h"
#include "nvim/locale.h"
#include "nvim/lua/executor.h"
#include "nvim/mapping.h"
diff --git a/src/nvim/indent.c b/src/nvim/indent.c
index 1905128c3c..32cdf6f2d6 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -13,6 +13,7 @@
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/drawscreen.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/typval_defs.h"
@@ -27,6 +28,8 @@
#include "nvim/message.h"
#include "nvim/move.h"
#include "nvim/option.h"
+#include "nvim/optionstr.h"
+#include "nvim/os/input.h"
#include "nvim/plines.h"
#include "nvim/pos.h"
#include "nvim/regexp.h"
@@ -915,6 +918,192 @@ bool may_do_si(void)
return curbuf->b_p_si && !curbuf->b_p_cin && *curbuf->b_p_inde == NUL && !p_paste;
}
+/// ":retab".
+void ex_retab(exarg_T *eap)
+{
+ linenr_T lnum;
+ bool got_tab = false;
+ long num_spaces = 0;
+ long num_tabs;
+ long len;
+ long col;
+ long vcol;
+ long start_col = 0; // For start of white-space string
+ long start_vcol = 0; // For start of white-space string
+ long old_len;
+ char *ptr;
+ char *new_line = (char *)1; // init to non-NULL
+ bool did_undo; // called u_save for current line
+ long *new_vts_array = NULL;
+ char *new_ts_str; // string value of tab argument
+
+ int save_list;
+ linenr_T first_line = 0; // first changed line
+ linenr_T last_line = 0; // last changed line
+
+ save_list = curwin->w_p_list;
+ curwin->w_p_list = 0; // don't want list mode here
+
+ new_ts_str = eap->arg;
+ if (!tabstop_set(eap->arg, &new_vts_array)) {
+ return;
+ }
+ while (ascii_isdigit(*(eap->arg)) || *(eap->arg) == ',') {
+ (eap->arg)++;
+ }
+
+ // This ensures that either new_vts_array and new_ts_str are freshly
+ // allocated, or new_vts_array points to an existing array and new_ts_str
+ // is null.
+ if (new_vts_array == NULL) {
+ new_vts_array = curbuf->b_p_vts_array;
+ new_ts_str = NULL;
+ } else {
+ new_ts_str = xstrnsave(new_ts_str, (size_t)(eap->arg - new_ts_str));
+ }
+ for (lnum = eap->line1; !got_int && lnum <= eap->line2; lnum++) {
+ ptr = ml_get(lnum);
+ col = 0;
+ vcol = 0;
+ did_undo = false;
+ for (;;) {
+ if (ascii_iswhite(ptr[col])) {
+ if (!got_tab && num_spaces == 0) {
+ // First consecutive white-space
+ start_vcol = vcol;
+ start_col = col;
+ }
+ if (ptr[col] == ' ') {
+ num_spaces++;
+ } else {
+ got_tab = true;
+ }
+ } else {
+ if (got_tab || (eap->forceit && num_spaces > 1)) {
+ // Retabulate this string of white-space
+
+ // len is virtual length of white string
+ len = num_spaces = vcol - start_vcol;
+ num_tabs = 0;
+ if (!curbuf->b_p_et) {
+ int t, s;
+
+ tabstop_fromto((colnr_T)start_vcol, (colnr_T)vcol,
+ curbuf->b_p_ts, new_vts_array, &t, &s);
+ num_tabs = t;
+ num_spaces = s;
+ }
+ if (curbuf->b_p_et || got_tab
+ || (num_spaces + num_tabs < len)) {
+ if (did_undo == false) {
+ did_undo = true;
+ if (u_save((linenr_T)(lnum - 1),
+ (linenr_T)(lnum + 1)) == FAIL) {
+ new_line = NULL; // flag out-of-memory
+ break;
+ }
+ }
+
+ // len is actual number of white characters used
+ len = num_spaces + num_tabs;
+ old_len = (long)strlen(ptr);
+ const long new_len = old_len - col + start_col + len + 1;
+ if (new_len <= 0 || new_len >= MAXCOL) {
+ emsg(_(e_resulting_text_too_long));
+ break;
+ }
+ new_line = xmalloc((size_t)new_len);
+
+ if (start_col > 0) {
+ memmove(new_line, ptr, (size_t)start_col);
+ }
+ memmove(new_line + start_col + len,
+ ptr + col, (size_t)(old_len - col + 1));
+ ptr = new_line + start_col;
+ for (col = 0; col < len; col++) {
+ ptr[col] = (col < num_tabs) ? '\t' : ' ';
+ }
+ if (ml_replace(lnum, new_line, false) == OK) {
+ // "new_line" may have been copied
+ new_line = curbuf->b_ml.ml_line_ptr;
+ extmark_splice_cols(curbuf, lnum - 1, 0, (colnr_T)old_len,
+ (colnr_T)new_len - 1, kExtmarkUndo);
+ }
+ if (first_line == 0) {
+ first_line = lnum;
+ }
+ last_line = lnum;
+ ptr = new_line;
+ col = start_col + len;
+ }
+ }
+ got_tab = false;
+ num_spaces = 0;
+ }
+ if (ptr[col] == NUL) {
+ break;
+ }
+ vcol += win_chartabsize(curwin, ptr + col, (colnr_T)vcol);
+ if (vcol >= MAXCOL) {
+ emsg(_(e_resulting_text_too_long));
+ // when not inside a try/catch set got_int to break out of any
+ // loop
+ if (trylevel == 0) {
+ got_int = true;
+ }
+ break;
+ }
+ col += utfc_ptr2len(ptr + col);
+ }
+ if (new_line == NULL) { // out of memory
+ break;
+ }
+ line_breakcheck();
+ }
+ if (got_int) {
+ emsg(_(e_interr));
+ }
+
+ // If a single value was given then it can be considered equal to
+ // either the value of 'tabstop' or the value of 'vartabstop'.
+ if (tabstop_count(curbuf->b_p_vts_array) == 0
+ && tabstop_count(new_vts_array) == 1
+ && curbuf->b_p_ts == tabstop_first(new_vts_array)) {
+ // not changed
+ } else if (tabstop_count(curbuf->b_p_vts_array) > 0
+ && tabstop_eq(curbuf->b_p_vts_array, new_vts_array)) {
+ // not changed
+ } else {
+ redraw_curbuf_later(UPD_NOT_VALID);
+ }
+ if (first_line != 0) {
+ changed_lines(first_line, 0, last_line + 1, 0L, true);
+ }
+
+ curwin->w_p_list = save_list; // restore 'list'
+
+ if (new_ts_str != NULL) { // set the new tabstop
+ // If 'vartabstop' is in use or if the value given to retab has more
+ // than one tabstop then update 'vartabstop'.
+ long *old_vts_ary = curbuf->b_p_vts_array;
+
+ if (tabstop_count(old_vts_ary) > 0 || tabstop_count(new_vts_array) > 1) {
+ set_string_option_direct("vts", -1, new_ts_str, OPT_FREE | OPT_LOCAL, 0);
+ curbuf->b_p_vts_array = new_vts_array;
+ xfree(old_vts_ary);
+ } else {
+ // 'vartabstop' wasn't in use and a single value was given to
+ // retab then update 'tabstop'.
+ curbuf->b_p_ts = tabstop_first(new_vts_array);
+ xfree(new_vts_array);
+ }
+ xfree(new_ts_str);
+ }
+ coladvance(curwin->w_curswant);
+
+ u_clearline();
+}
+
/// Get indent level from 'indentexpr'.
int get_expr_indent(void)
{