Bram,
On Thu, Mar 24, 2016 at 06:44:39PM +0100, Bram Moolenaar wrote:
>
> Anton Lindqvist wrote:
>
> > Hi,
> > This patch adds a function with the declaration optiontype({option})
> > which returns the type of the given option. I'm currently using it to
> > achieve the following option toggle mapping:
> >
> > " :NMapChangeOption[!] {letter} {option} [enable]
> > "
> > " Create a normal mode option toggle mapping for {option}. The mapping key
> > " sequence will be prefixed with 'co' followed by {letter}.
> > "
> > " By default the option will only be changed in the current buffer. Using
> > [!]
> > " will change the option globally.
> > "
> > " Boolean option example:
> > "
> > " :NMapChangeOption s spell
> > "
> > " Pressing 'cos' will toggle the spell option on and off.
> > "
> > " Non boolean option example:
> > "
> > " :NMapChangeOption y syntax ON
> > "
> > " The optional [enable] argument can be used for string and comma
> > separated
> > " list options. Pressing 'coy' will add/remove 'ON' from the syntax
> > option.
> > "
> > " This functionality is borrowed from Tim Pope's unimpaired.vim plugin.
> > command! -bang -complete=option -nargs=+ NMapChangeOption
> > \ call s:NMapChangeOption(<bang>0, <f-args>)
> > func! s:NMapChangeOption(global, letter, option, ...) abort
> > let set = a:global ? 'set' : 'setlocal'
> > let type = optiontype(a:option)
> > if type == 0 " boolean
> > let rhs = printf(':%s <C-R>=&%s ? "no" : ""<CR>%s<CR>',
> > \ set, a:option, a:option)
> > elseif type == 2 " comma separated list
> > let rhs = printf(':%s %s<C-R>=&%s !~# "%s" ? "+=" : "-="<CR>%s<CR>',
> > \ set, a:option, a:option, a:1, a:1)
> > elseif type == 4 " string
> > let rhs = printf(':%s %s<C-R>=&%s == "%s" ? "&" : "=%s"<CR><CR>',
> > \ set, a:option, a:option, a:1, a:1)
> > endif
> > exe 'nnoremap co' . a:letter rhs
> > endfunc
> >
> > NMapChangeOption c colorcolumn +1
> > NMapChangeOption! h hlsearch
> > NMapChangeOption l list
> > NMapChangeOption! p paste
> > NMapChangeOption s spell
> > NMapChangeOption w wrap
> > NMapChangeOption y syntax ON
> >
> > The patch includes tests and docs.
>
> I can see how this would be useful. But returning just a number is
> limited. There are many more properties of an option, such as whether
> it is window-local, was set or not, can be set from a modeline, etc.
> Not that we need to add all those properties now, but I'm sure someone
> will want to add them later. Perhaps using "optionproperties()" and
> returning a Dictionary?
Great feedback. Attached is a revised patch with you ideas applied.
For now the 'optionproperties()' function returns a Dictionary with only
one entry called 'type'.
--
:wq
--
--
You received this message from the "vim_dev" 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_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 642f0ad..3087938 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2023,6 +2023,7 @@ mode( [expr]) String current editing
mode
mzeval( {expr}) any evaluate |MzScheme| expression
nextnonblank( {lnum}) Number line nr of non-blank line >= {lnum}
nr2char( {expr}[, {utf8}]) String single char with ASCII/UTF8 value {expr}
+optionproperties( {option}) Dict properties of option {option}
or( {expr}, {expr}) Number bitwise OR
pathshorten( {expr}) String shorten directory names in a path
perleval( {expr}) any evaluate |Perl| expression
@@ -5316,6 +5317,20 @@ nr2char({expr}[, {utf8}])
*nr2char()*
characters. nr2char(0) is a real NUL and terminates the
string, thus results in an empty string.
+ *E518*
+optionproperties({option}) *optionproperties()*
+ Return the properties of {option} as a dictionary with the
+ following entries:
+
+ type
+ Boolean: 0
+ Number: 1
+ Comma separated list: 2
+ Char flag list: 3
+ String: 4
+
+ If {option} does not exist, a empty dictionary is returned.
+
or({expr}, {expr}) *or()*
Bitwise OR on the two arguments. The arguments are converted
to a number. A List, Dict or Float argument causes an error.
diff --git a/src/eval.c b/src/eval.c
index 9091f79..8a27ca3 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -684,6 +684,7 @@ static void f_mzeval(typval_T *argvars, typval_T *rettv);
static void f_nextnonblank(typval_T *argvars, typval_T *rettv);
static void f_nr2char(typval_T *argvars, typval_T *rettv);
static void f_or(typval_T *argvars, typval_T *rettv);
+static void f_optionproperties(typval_T *argvars, typval_T *rettv);
static void f_pathshorten(typval_T *argvars, typval_T *rettv);
#ifdef FEAT_PERL
static void f_perleval(typval_T *argvars, typval_T *rettv);
@@ -8371,6 +8372,7 @@ static struct fst
{"nextnonblank", 1, 1, f_nextnonblank},
{"nr2char", 1, 2, f_nr2char},
{"or", 2, 2, f_or},
+ {"optionproperties",1, 1, f_optionproperties},
{"pathshorten", 1, 1, f_pathshorten},
#ifdef FEAT_PERL
{"perleval", 1, 1, f_perleval},
@@ -15921,6 +15923,42 @@ f_or(typval_T *argvars, typval_T *rettv)
}
/*
+ * "optionproperties(option)" function
+ */
+ static void
+f_optionproperties(typval_T *argvars, typval_T *rettv)
+{
+ char_u *p;
+ int flags;
+ int type;
+
+ if (rettv_dict_alloc(rettv) == FAIL)
+ return;
+
+ p = get_tv_string_chk(&argvars[0]);
+ flags = get_option_flags(p);
+ if (flags == -1) {
+ EMSG(_("E518: Unknown option"));
+ return;
+ }
+
+ if (flags & P_BOOL)
+ type = 0;
+ else if (flags & P_NUM)
+ type = 1;
+ else if (flags & P_COMMA || flags & P_ONECOMMA)
+ type = 2;
+ else if (flags & P_FLAGLIST)
+ type = 3;
+ else if (flags & P_STRING)
+ type = 4;
+ else
+ type = 4; /* type unknown, assume string */
+ if (dict_add_nr_str(rettv->vval.v_dict, "type", type, NULL) == FAIL)
+ return;
+}
+
+/*
* "pathshorten()" function
*/
static void
diff --git a/src/option.c b/src/option.c
index 8a706af..58727a2 100644
--- a/src/option.c
+++ b/src/option.c
@@ -410,50 +410,6 @@ struct vimoption
#define VI_DEFAULT 0 /* def_val[VI_DEFAULT] is Vi default value */
#define VIM_DEFAULT 1 /* def_val[VIM_DEFAULT] is Vim default value */
-/*
- * Flags
- */
-#define P_BOOL 0x01 /* the option is boolean */
-#define P_NUM 0x02 /* the option is numeric */
-#define P_STRING 0x04 /* the option is a string */
-#define P_ALLOCED 0x08 /* the string option is in allocated memory,
- must use free_string_option() when
- assigning new value. Not set if default is
- the same. */
-#define P_EXPAND 0x10 /* environment expansion. NOTE: P_EXPAND can
- never be used for local or hidden options! */
-#define P_NODEFAULT 0x40 /* don't set to default value */
-#define P_DEF_ALLOCED 0x80 /* default value is in allocated memory, must
- use vim_free() when assigning new value */
-#define P_WAS_SET 0x100 /* option has been set/reset */
-#define P_NO_MKRC 0x200 /* don't include in :mkvimrc output */
-#define P_VI_DEF 0x400 /* Use Vi default for Vim */
-#define P_VIM 0x800 /* Vim option, reset when 'cp' set */
-
- /* when option changed, what to display: */
-#define P_RSTAT 0x1000 /* redraw status lines */
-#define P_RWIN 0x2000 /* redraw current window */
-#define P_RBUF 0x4000 /* redraw current buffer */
-#define P_RALL 0x6000 /* redraw all windows */
-#define P_RCLR 0x7000 /* clear and redraw all */
-
-#define P_COMMA 0x8000 /* comma separated list */
-#define P_ONECOMMA 0x18000L /* P_COMMA and cannot have two consecutive
- * commas */
-#define P_NODUP 0x20000L /* don't allow duplicate strings */
-#define P_FLAGLIST 0x40000L /* list of single-char flags */
-
-#define P_SECURE 0x80000L /* cannot change in modeline or secure mode */
-#define P_GETTEXT 0x100000L /* expand default value with _() */
-#define P_NOGLOB 0x200000L /* do not use local value for global vimrc */
-#define P_NFNAME 0x400000L /* only normal file name chars allowed */
-#define P_INSECURE 0x800000L /* option was set from a modeline */
-#define P_PRI_MKRC 0x1000000L /* priority for :mkvimrc (setting option has
- side effects) */
-#define P_NO_ML 0x2000000L /* not allowed in modeline */
-#define P_CURSWANT 0x4000000L /* update curswant required; not needed when
- * there is a redraw flag */
-
#define ISK_LATIN1 (char_u *)"@,48-57,_,192-255"
/* 'isprint' for latin1 is also used for MS-Windows cp1252, where 0x80 is used
@@ -12244,3 +12200,19 @@ get_bkc_value(buf_T *buf)
{
return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
}
+
+/*
+ * Get the flags of an option.
+ * Returns -1 when the option is unknown.
+ */
+ int
+get_option_flags(char_u *name)
+{
+ int opt_idx;
+
+ opt_idx = findoption(name);
+ if (opt_idx == -1)
+ return -1;
+ else
+ return options[opt_idx].flags;
+}
diff --git a/src/option.h b/src/option.h
index cf7ba04..518f20b 100644
--- a/src/option.h
+++ b/src/option.h
@@ -11,6 +11,50 @@
*/
/*
+ * Flags
+ */
+#define P_BOOL 0x01 /* the option is boolean */
+#define P_NUM 0x02 /* the option is numeric */
+#define P_STRING 0x04 /* the option is a string */
+#define P_ALLOCED 0x08 /* the string option is in allocated memory,
+ must use free_string_option() when
+ assigning new value. Not set if default is
+ the same. */
+#define P_EXPAND 0x10 /* environment expansion. NOTE: P_EXPAND can
+ never be used for local or hidden options! */
+#define P_NODEFAULT 0x40 /* don't set to default value */
+#define P_DEF_ALLOCED 0x80 /* default value is in allocated memory, must
+ use vim_free() when assigning new value */
+#define P_WAS_SET 0x100 /* option has been set/reset */
+#define P_NO_MKRC 0x200 /* don't include in :mkvimrc output */
+#define P_VI_DEF 0x400 /* Use Vi default for Vim */
+#define P_VIM 0x800 /* Vim option, reset when 'cp' set */
+
+ /* when option changed, what to display: */
+#define P_RSTAT 0x1000 /* redraw status lines */
+#define P_RWIN 0x2000 /* redraw current window */
+#define P_RBUF 0x4000 /* redraw current buffer */
+#define P_RALL 0x6000 /* redraw all windows */
+#define P_RCLR 0x7000 /* clear and redraw all */
+
+#define P_COMMA 0x8000 /* comma separated list */
+#define P_ONECOMMA 0x18000L /* P_COMMA and cannot have two consecutive
+ * commas */
+#define P_NODUP 0x20000L /* don't allow duplicate strings */
+#define P_FLAGLIST 0x40000L /* list of single-char flags */
+
+#define P_SECURE 0x80000L /* cannot change in modeline or secure mode */
+#define P_GETTEXT 0x100000L /* expand default value with _() */
+#define P_NOGLOB 0x200000L /* do not use local value for global vimrc */
+#define P_NFNAME 0x400000L /* only normal file name chars allowed */
+#define P_INSECURE 0x800000L /* option was set from a modeline */
+#define P_PRI_MKRC 0x1000000L /* priority for :mkvimrc (setting option has
+ side effects) */
+#define P_NO_ML 0x2000000L /* not allowed in modeline */
+#define P_CURSWANT 0x4000000L /* update curswant required; not needed when
+ * there is a redraw flag */
+
+/*
* Default values for 'errorformat'.
* The "%f|%l| %m" one is used for when the contents of the quickfix window is
* written to a file.
diff --git a/src/proto/option.pro b/src/proto/option.pro
index d0ba4ec..f7044da 100644
--- a/src/proto/option.pro
+++ b/src/proto/option.pro
@@ -63,4 +63,5 @@ long get_sw_value(buf_T *buf);
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);
+int get_option_flags(char_u *name);
/* vim: set ft=c : */
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 455ca7b..1db3e58 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -176,6 +176,7 @@ NEW_TESTS = test_arglist.res \
test_increment.res \
test_json.res \
test_langmap.res \
+ test_optionproperties.res \
test_packadd.res \
test_perl.res \
test_quickfix.res \
diff --git a/src/testdir/test_optionproperties.vim
b/src/testdir/test_optionproperties.vim
new file mode 100644
index 0000000..ae13e89
--- /dev/null
+++ b/src/testdir/test_optionproperties.vim
@@ -0,0 +1,14 @@
+" Test for the optionproperties function.
+function Test_optionproperties()
+ call assert_equal(0, optionproperties('antialias').type)
+ call assert_equal(1, optionproperties('cmdheight').type)
+ call assert_equal(2, optionproperties('backspace').type)
+ call assert_equal(2, optionproperties('belloff').type)
+ call assert_equal(3, optionproperties('breakat').type)
+ call assert_equal(4, optionproperties('ambiwidth').type)
+ try
+ call optionproperties('unknown')
+ catch
+ call assert_exception('E518:')
+ endtry
+endfunction