Wednesday, November 14, 2018

Re: About using vartabstop

From 1be027d3f8afcde323885b19e413a97856a0409e Mon Sep 17 00:00:00 2001
From: Christian Brabandt <cb@256bit.org>
Date: Wed, 14 Nov 2018 16:37:23 +0100
Subject: [PATCH] Return correct tabstop setting when 'sw'=0

When the vartab feature was merged into Vim with v8.1.0105, there was
one feature forgotten. To return the actual tabstop value in effect when
the shiftwidth setting is zero (|'shiftwidth'|)

So fix this and make get_sw_value() return the actual vartabstop setting
in effect, if it is enabled. This basically means, that get_sw_value()
also needs to know the column number for which to return the correct
vartab stop value. Therefore, return the value from the current cursor
position.

This also means, that the `shiftwidth()` function needs to be extended
and returns the vartabstop value for a given position. So extend that
function to use an optional position parameter and add some documentation.
---
runtime/doc/eval.txt | 12 ++++++++++--
src/edit.c | 5 +++--
src/evalfunc.c | 19 ++++++++++++++++++-
src/option.c | 26 +++++++++++++++++++++++++-
src/proto/edit.pro | 1 +
src/proto/option.pro | 1 +
6 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index deeda2e1e..8f615c0e8 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2386,7 +2386,7 @@ sha256({string}) String SHA256 checksum of {string}
shellescape({string} [, {special}])
String escape {string} for use as shell
command argument
-shiftwidth() Number effective value of 'shiftwidth'
+shiftwidth([{list}]) Number effective value of 'shiftwidth'
simplify({filename}) String simplify filename as much as possible
sin({expr}) Float sine of {expr}
sinh({expr}) Float hyperbolic sine of {expr}
@@ -7642,12 +7642,20 @@ shellescape({string} [, {special}]) *shellescape()*
< See also |::S|.


-shiftwidth() *shiftwidth()*
+shiftwidth([{list}]) *shiftwidth()*
Returns the effective value of 'shiftwidth'. This is the
'shiftwidth' value unless it is zero, in which case it is the
'tabstop' value. This function was introduced with patch
7.3.694 in 2012, everybody should have it by now.

+ When there is one argument {list} this is used as position
+ |List| for which to return the 'shiftwidth' value (actually
+ only the column number is relevant). This matters for the
+ 'vartabstop' feature. For the {list} arguments see |cursor()|
+ function. If the 'vartabstop' setting is enabled and no
+ {list} argument is given, the current cursor position is
+ taken into account.
+

simplify({filename}) *simplify()*
Simplify the file name as much as possible without changing
diff --git a/src/edit.c b/src/edit.c
index d85d9cb4c..e9cee6210 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -262,7 +262,6 @@ static int ins_ctrl_ey(int tc);
#ifdef FEAT_SMARTINDENT
static void ins_try_si(int c);
#endif
-static colnr_T get_nolist_virtcol(void);
#if defined(FEAT_EVAL)
static char_u *do_insert_char_pre(int c);
#endif
@@ -10686,9 +10685,11 @@ ins_try_si(int c)
* Get the value that w_virtcol would have when 'list' is off.
* Unless 'cpo' contains the 'L' flag.
*/
- static colnr_T
+ colnr_T
get_nolist_virtcol(void)
{
+ if (curwin->w_buffer == NULL || curwin->w_buffer->b_ml.ml_mfp == NULL)
+ return 0;
if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL)
return getvcol_nolist(&curwin->w_cursor);
validate_virtcol();
diff --git a/src/evalfunc.c b/src/evalfunc.c
index f12eba384..647c12e81 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -835,7 +835,7 @@ static struct fst
{"sha256", 1, 1, f_sha256},
#endif
{"shellescape", 1, 2, f_shellescape},
- {"shiftwidth", 0, 0, f_shiftwidth},
+ {"shiftwidth", 0, 1, f_shiftwidth},
{"simplify", 1, 1, f_simplify},
#ifdef FEAT_FLOAT
{"sin", 1, 1, f_sin},
@@ -11245,6 +11245,23 @@ f_shellescape(typval_T *argvars, typval_T *rettv)
static void
f_shiftwidth(typval_T *argvars UNUSED, typval_T *rettv)
{
+ rettv->vval.v_number = 0;
+ if (argvars[0].v_type != VAR_UNKNOWN)
+ {
+ pos_T pos;
+ colnr_T curswant = -1;
+
+ if (list2fpos(argvars, &pos, NULL, &curswant) == FAIL)
+ {
+ EMSG(_(e_invarg));
+ return;
+ }
+ #ifdef FEAT_VARTABS
+ rettv->vval.v_number = get_sw_value_pos(curbuf, &pos);
+ return;
+ #endif
+ }
+
rettv->vval.v_number = get_sw_value(curbuf);
}

diff --git a/src/option.c b/src/option.c
index df8b3a662..f0c56ab56 100644
--- a/src/option.c
+++ b/src/option.c
@@ -3339,6 +3339,7 @@ static int check_opt_wim(void);
#ifdef FEAT_LINEBREAK
static int briopt_check(win_T *wp);
#endif
+static long get_sw_value_col(buf_T *buf, colnr_T col);

/*
* Initialize the options, first part.
@@ -13121,7 +13122,30 @@ tabstop_first(int *ts)
long
get_sw_value(buf_T *buf)
{
- return buf->b_p_sw ? buf->b_p_sw : buf->b_p_ts;
+ return get_sw_value_col(buf, get_nolist_virtcol());
+}
+
+ 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;
+}
+
+ static 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
}

/*
diff --git a/src/proto/edit.pro b/src/proto/edit.pro
index 9ba71645b..768af3a48 100644
--- a/src/proto/edit.pro
+++ b/src/proto/edit.pro
@@ -46,4 +46,5 @@ int bracketed_paste(paste_mode_T mode, int drop, garray_T *gap);
void ins_scroll(void);
void ins_horscroll(void);
int ins_copychar(linenr_T lnum);
+colnr_T get_nolist_virtcol(void);
/* vim: set ft=c : */
diff --git a/src/proto/option.pro b/src/proto/option.pro
index 228036587..e66a76057 100644
--- a/src/proto/option.pro
+++ b/src/proto/option.pro
@@ -72,6 +72,7 @@ int *tabstop_copy(int *oldts);
int tabstop_count(int *ts);
int tabstop_first(int *ts);
long get_sw_value(buf_T *buf);
+long get_sw_value_pos(buf_T *buf, pos_T *pos);
long get_sts_value(void);
void find_mps_values(int *initc, int *findc, int *backwards, int switchit);
unsigned int get_bkc_value(buf_T *buf);
--
2.18.0

On Do, 30 Aug 2018, Christian Brabandt wrote:

>
> On Mi, 29 Aug 2018, Lifepillar wrote:
>
> > There's a meme (if it may be called so) circulating on Twitter
> > about using Fibonacci sequences for indentation. Just for fun,
> > I wanted to see if it could be implemented using the vartabs
> > feature. I thought that this would do it (for C files):
> >
> > set shiftwidth=0
> > set noexpandtab
> > set vartabstop=1,1,2,3,5,8,13,21,34
> > set autoindent
> > set smartindent
> > set ft=c
> >
> > With the above settings, it appears that the value of tabstop
> > is used. This seems to agree with shiftwidth's documentation:
> > "When [shiftwidth is] zero the 'ts' value will be used", but
> > not with tabstop's help: "the value of 'tabstop' will be
> > ignored while 'vartabstop' is set". Putting together the two,
> > I would expect the above to use vartabstop.
> >
> > Am I missing something?
>
> I am not sure. It might be, that the functionality of using the tabstop
> setting when shiftwidth is zero is indeed missing from vartabstop,
> because this was done some time after the vartab patch has been created
> and that feature has than not made it back into the vartabs patch.
>
> I'll have a look at it in more detail later.

Indeed, that's the problem. The vartab option is not taken into account
when the shiftwidth option is set to zero.

Attached is a patch, that fixes the issue.

However, it currently fails test86.in with the following error:
--- test86.ok 2018-11-14 13:32:51.652857566 +0100
+++ test86.failed 2018-11-14 16:48:10.638090709 +0100
@@ -297,6 +297,9 @@
wopts2! KeyError
wopts3! KeyError
p/bopts1: 8
+ inv: 3! error
+ bopts1! error
+ bopts2! error
G: 8
W: 1:0 2:2 3:8 4:1
B: 1:0 2:2 3:8 4:1

I don't understand the python code in there to know what this does. Sorry.

Best,
Christian
--
Zeig mir deine Uhr, und ich sage dir, wie spät es ist.

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments: