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.

-- 
: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..f411beb 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}
+optiontype( {option})          Number  type 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,15 @@ nr2char({expr}[, {utf8}])                                
*nr2char()*
                characters.  nr2char(0) is a real NUL and terminates the
                string, thus results in an empty string.
 
+optiontype({option})                                   *optiontype()* *E518*
+               Return the type of {option} as a Number:
+                                    Boolean: 0
+                                     Number: 1
+                       Comma separated list: 2
+                             Char flag list: 3
+                                     String: 4
+               If {option} does not exist, -1 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 b233833..38533d8 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -682,6 +682,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_optiontype(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);
@@ -8327,6 +8328,7 @@ static struct fst
     {"nextnonblank",   1, 1, f_nextnonblank},
     {"nr2char",                1, 2, f_nr2char},
     {"or",             2, 2, f_or},
+    {"optiontype",     1, 1, f_optiontype},
     {"pathshorten",    1, 1, f_pathshorten},
 #ifdef FEAT_PERL
     {"perleval",       1, 1, f_perleval},
@@ -15901,6 +15903,22 @@ f_or(typval_T *argvars, typval_T *rettv)
 }
 
 /*
+ * "optiontype(option)" function
+ */
+    static void
+f_optiontype(typval_T *argvars, typval_T *rettv)
+{
+    char_u     *p;
+    int                type;
+
+    p = get_tv_string_chk(&argvars[0]);
+    type = get_option_type(p);
+    if (type == -1)
+       EMSG(_("E518: Unknown option"));
+    rettv->vval.v_number = type;
+}
+
+/*
  * "pathshorten()" function
  */
     static void
diff --git a/src/option.c b/src/option.c
index 8a706af..8b163ca 100644
--- a/src/option.c
+++ b/src/option.c
@@ -12244,3 +12244,28 @@ get_bkc_value(buf_T *buf)
 {
     return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
 }
+
+/*
+ * Get the type of an option.
+ * Returns -1 when the option is unknown.
+ */
+    int
+get_option_type(char_u *name)
+{
+    int            opt_idx;
+
+    opt_idx = findoption(name);
+    if (opt_idx == -1)
+       return -1;
+    if (options[opt_idx].flags & P_BOOL)
+       return 0;
+    if (options[opt_idx].flags & P_NUM)
+       return 1;
+    if (options[opt_idx].flags & P_COMMA || options[opt_idx].flags & 
P_ONECOMMA)
+       return 2;
+    if (options[opt_idx].flags & P_FLAGLIST)
+       return 3;
+    if (options[opt_idx].flags & P_STRING)
+       return 4;
+    return 4; /* type unknown, assume string */
+}
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 455ca7b..ed589bf 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_optiontype.res \
            test_packadd.res \
            test_perl.res \
            test_quickfix.res \
diff --git a/src/testdir/test_optiontype.vim b/src/testdir/test_optiontype.vim
new file mode 100644
index 0000000..7f48a52
--- /dev/null
+++ b/src/testdir/test_optiontype.vim
@@ -0,0 +1,14 @@
+" Test for the optiontype function.
+function Test_optiontype()
+  call assert_equal(0, optiontype('antialias'))
+  call assert_equal(1, optiontype('aleph'))
+  call assert_equal(2, optiontype('backspace'))
+  call assert_equal(2, optiontype('belloff'))
+  call assert_equal(3, optiontype('breakat'))
+  call assert_equal(4, optiontype('ambiwidth'))
+  try
+    call optiontype('unknown')
+  catch
+    call assert_exception('E518:')
+  endtry
+endfunction

Raspunde prin e-mail lui