summaryrefslogtreecommitdiffstats
path: root/src/indent.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-09-02 22:31:11 +0200
committerBram Moolenaar <Bram@vim.org>2019-09-02 22:31:11 +0200
commite677df8d93772a705f40a94f3c871aee78fe4d99 (patch)
tree918556233748a58fbdcaf94d0416d6dcd0449b39 /src/indent.c
parent359ad1a6f92d0d3b4b942ea003fb02dc57bbfc9e (diff)
patch 8.1.1966: some code in options.c fits better elsewherev8.1.1966
Problem: Some code in options.c fits better elsewhere. Solution: Move functions from options.c to other files. (Yegappan Lakshmanan, closes #4889)
Diffstat (limited to 'src/indent.c')
-rw-r--r--src/indent.c358
1 files changed, 358 insertions, 0 deletions
diff --git a/src/indent.c b/src/indent.c
index b74864cb44..dacafcbc02 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -4457,3 +4457,361 @@ fix_indent(void)
}
#endif
+
+#if defined(FEAT_VARTABS) || defined(PROTO)
+
+/*
+ * Set the integer values corresponding to the string setting of 'vartabstop'.
+ * "array" will be set, caller must free it if needed.
+ */
+ int
+tabstop_set(char_u *var, int **array)
+{
+ int valcount = 1;
+ int t;
+ char_u *cp;
+
+ if (var[0] == NUL || (var[0] == '0' && var[1] == NUL))
+ {
+ *array = NULL;
+ return TRUE;
+ }
+
+ for (cp = var; *cp != NUL; ++cp)
+ {
+ if (cp == var || cp[-1] == ',')
+ {
+ char_u *end;
+
+ if (strtol((char *)cp, (char **)&end, 10) <= 0)
+ {
+ if (cp != end)
+ emsg(_(e_positive));
+ else
+ emsg(_(e_invarg));
+ return FALSE;
+ }
+ }
+
+ if (VIM_ISDIGIT(*cp))
+ continue;
+ if (cp[0] == ',' && cp > var && cp[-1] != ',' && cp[1] != NUL)
+ {
+ ++valcount;
+ continue;
+ }
+ emsg(_(e_invarg));
+ return FALSE;
+ }
+
+ *array = ALLOC_MULT(int, valcount + 1);
+ if (*array == NULL)
+ return FALSE;
+ (*array)[0] = valcount;
+
+ t = 1;
+ for (cp = var; *cp != NUL;)
+ {
+ (*array)[t++] = atoi((char *)cp);
+ while (*cp != NUL && *cp != ',')
+ ++cp;
+ if (*cp != NUL)
+ ++cp;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Calculate the number of screen spaces a tab will occupy.
+ * If "vts" is set then the tab widths are taken from that array,
+ * otherwise the value of ts is used.
+ */
+ int
+tabstop_padding(colnr_T col, int ts_arg, int *vts)
+{
+ int ts = ts_arg == 0 ? 8 : ts_arg;
+ int tabcount;
+ colnr_T tabcol = 0;
+ int t;
+ int padding = 0;
+
+ if (vts == NULL || vts[0] == 0)
+ return ts - (col % ts);
+
+ tabcount = vts[0];
+
+ for (t = 1; t <= tabcount; ++t)
+ {
+ tabcol += vts[t];
+ if (tabcol > col)
+ {
+ padding = (int)(tabcol - col);
+ break;
+ }
+ }
+ if (t > tabcount)
+ padding = vts[tabcount] - (int)((col - tabcol) % vts[tabcount]);
+
+ return padding;
+}
+
+/*
+ * Find the size of the tab that covers a particular column.
+ */
+ int
+tabstop_at(colnr_T col, int ts, int *vts)
+{
+ int tabcount;
+ colnr_T tabcol = 0;
+ int t;
+ int tab_size = 0;
+
+ if (vts == 0 || vts[0] == 0)
+ return ts;
+
+ tabcount = vts[0];
+ for (t = 1; t <= tabcount; ++t)
+ {
+ tabcol += vts[t];
+ if (tabcol > col)
+ {
+ tab_size = vts[t];
+ break;
+ }
+ }
+ if (t > tabcount)
+ tab_size = vts[tabcount];
+
+ return tab_size;
+}
+
+/*
+ * Find the column on which a tab starts.
+ */
+ colnr_T
+tabstop_start(colnr_T col, int ts, int *vts)
+{
+ int tabcount;
+ colnr_T tabcol = 0;
+ int t;
+ int excess;
+
+ if (vts == NULL || vts[0] == 0)
+ return (col / ts) * ts;
+
+ tabcount = vts[0];
+ for (t = 1; t <= tabcount; ++t)
+ {
+ tabcol += vts[t];
+ if (tabcol > col)
+ return tabcol - vts[t];
+ }
+
+ excess = tabcol % vts[tabcount];
+ return excess + ((col - excess) / vts[tabcount]) * vts[tabcount];
+}
+
+/*
+ * Find the number of tabs and spaces necessary to get from one column
+ * to another.
+ */
+ void
+tabstop_fromto(
+ colnr_T start_col,
+ colnr_T end_col,
+ int ts_arg,
+ int *vts,
+ int *ntabs,
+ int *nspcs)
+{
+ int spaces = end_col - start_col;
+ colnr_T tabcol = 0;
+ int padding = 0;
+ int tabcount;
+ int t;
+ int ts = ts_arg == 0 ? curbuf->b_p_ts : ts_arg;
+
+ if (vts == NULL || vts[0] == 0)
+ {
+ int tabs = 0;
+ int initspc = 0;
+
+ initspc = ts - (start_col % ts);
+ if (spaces >= initspc)
+ {
+ spaces -= initspc;
+ tabs++;
+ }
+ tabs += spaces / ts;
+ spaces -= (spaces / ts) * ts;
+
+ *ntabs = tabs;
+ *nspcs = spaces;
+ return;
+ }
+
+ // Find the padding needed to reach the next tabstop.
+ tabcount = vts[0];
+ for (t = 1; t <= tabcount; ++t)
+ {
+ tabcol += vts[t];
+ if (tabcol > start_col)
+ {
+ padding = (int)(tabcol - start_col);
+ break;
+ }
+ }
+ if (t > tabcount)
+ padding = vts[tabcount] - (int)((start_col - tabcol) % vts[tabcount]);
+
+ // If the space needed is less than the padding no tabs can be used.
+ if (spaces < padding)
+ {
+ *ntabs = 0;
+ *nspcs = spaces;
+ return;
+ }
+
+ *ntabs = 1;
+ spaces -= padding;
+
+ // At least one tab has been used. See if any more will fit.
+ while (spaces != 0 && ++t <= tabcount)
+ {
+ padding = vts[t];
+ if (spaces < padding)
+ {
+ *nspcs = spaces;
+ return;
+ }
+ ++*ntabs;
+ spaces -= padding;
+ }
+
+ *ntabs += spaces / vts[tabcount];
+ *nspcs = spaces % vts[tabcount];
+}
+
+/*
+ * See if two tabstop arrays contain the same values.
+ */
+ int
+tabstop_eq(int *ts1, int *ts2)
+{
+ int t;
+
+ if ((ts1 == 0 && ts2) || (ts1 && ts2 == 0))
+ return FALSE;
+ if (ts1 == ts2)
+ return TRUE;
+ if (ts1[0] != ts2[0])
+ return FALSE;
+
+ for (t = 1; t <= ts1[0]; ++t)
+ if (ts1[t] != ts2[t])
+ return FALSE;
+
+ return TRUE;
+}
+
+#if defined(FEAT_BEVAL) || defined(PROTO)
+/*
+ * Copy a tabstop array, allocating space for the new array.
+ */
+ int *
+tabstop_copy(int *oldts)
+{
+ int *newts;
+ int t;
+
+ if (oldts == NULL)
+ return NULL;
+ newts = ALLOC_MULT(int, oldts[0] + 1);
+ if (newts != NULL)
+ for (t = 0; t <= oldts[0]; ++t)
+ newts[t] = oldts[t];
+ return newts;
+}
+#endif
+
+/*
+ * Return a count of the number of tabstops.
+ */
+ int
+tabstop_count(int *ts)
+{
+ return ts != NULL ? ts[0] : 0;
+}
+
+/*
+ * Return the first tabstop, or 8 if there are no tabstops defined.
+ */
+ int
+tabstop_first(int *ts)
+{
+ return ts != NULL ? ts[1] : 8;
+}
+
+#endif
+
+/*
+ * Return the effective shiftwidth value for current buffer, using the
+ * 'tabstop' value when 'shiftwidth' is zero.
+ */
+ long
+get_sw_value(buf_T *buf)
+{
+ return get_sw_value_col(buf, 0);
+}
+
+/*
+ * Idem, using "pos".
+ */
+ static long
+get_sw_value_pos(buf_T *buf, pos_T *pos)
+{
+ pos_T save_cursor = curwin->w_cursor;
+ long sw_value;
+
+ curwin->w_cursor = *pos;
+ sw_value = get_sw_value_col(buf, get_nolist_virtcol());
+ curwin->w_cursor = save_cursor;
+ return sw_value;
+}
+
+/*
+ * Idem, using the first non-black in the current line.
+ */
+ long
+get_sw_value_indent(buf_T *buf)
+{
+ pos_T pos = curwin->w_cursor;
+
+ pos.col = getwhitecols_curline();
+ return get_sw_value_pos(buf, &pos);
+}
+
+/*
+ * Idem, using virtual column "col".
+ */
+ long
+get_sw_value_col(buf_T *buf, colnr_T col UNUSED)
+{
+ return buf->b_p_sw ? buf->b_p_sw :
+ #ifdef FEAT_VARTABS
+ tabstop_at(col, buf->b_p_ts, buf->b_p_vts_array);
+ #else
+ buf->b_p_ts;
+ #endif
+}
+
+/*
+ * Return the effective softtabstop value for the current buffer, using the
+ * 'shiftwidth' value when 'softtabstop' is negative.
+ */
+ long
+get_sts_value(void)
+{
+ return curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts;
+}