diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/eval.c | 65 | ||||
| -rw-r--r-- | src/nvim/eval.lua | 1 | ||||
| -rw-r--r-- | src/nvim/fileio.c | 8 | ||||
| -rw-r--r-- | src/nvim/testdir/test_functions.vim | 23 | ||||
| -rw-r--r-- | src/nvim/testdir/test_stat.vim | 93 | 
5 files changed, 179 insertions, 11 deletions
| diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 22cb544f54..86f57ee5a2 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -9874,7 +9874,7 @@ static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr)  # endif  # ifdef S_ISSOCK      else if (S_ISSOCK(mode)) -      t = "fifo"; +      t = "socket";  # endif      else        t = "other"; @@ -17218,6 +17218,69 @@ error:    return;  } +// "trim({expr})" function +static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ +  char buf1[NUMBUFLEN]; +  char buf2[NUMBUFLEN]; +  const char_u *head = (const char_u *)tv_get_string_buf_chk(&argvars[0], buf1); +  const char_u *mask = NULL; +  const char_u *tail; +  const char_u *prev; +  const char_u *p; +  int c1; + +  rettv->v_type = VAR_STRING; +  if (head == NULL) { +    rettv->vval.v_string = NULL; +    return; +  } + +  if (argvars[1].v_type == VAR_STRING) { +    mask = (const char_u *)tv_get_string_buf_chk(&argvars[1], buf2); +  } + +  while (*head != NUL) { +    c1 = PTR2CHAR(head); +    if (mask == NULL) { +      if (c1 > ' ' && c1 != 0xa0) { +        break; +      } +    } else { +      for (p = mask; *p != NUL; MB_PTR_ADV(p)) { +        if (c1 == PTR2CHAR(p)) { +          break; +        } +      } +      if (*p == NUL) { +        break; +      } +    } +    MB_PTR_ADV(head); +  } + +  for (tail = head + STRLEN(head); tail > head; tail = prev) { +    prev = tail; +    MB_PTR_BACK(head, prev); +    c1 = PTR2CHAR(prev); +    if (mask == NULL) { +      if (c1 > ' ' && c1 != 0xa0) { +        break; +      } +    } else { +      for (p = mask; *p != NUL; MB_PTR_ADV(p)) { +        if (c1 == PTR2CHAR(p)) { +          break; +        } +      } +      if (*p == NUL) { +        break; +      } +    } +  } +  rettv->vval.v_string = vim_strnsave(head, (int)(tail - head)); +} +  /*   * "type(expr)" function   */ diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 801d2cc468..23959f348a 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -323,6 +323,7 @@ return {      tolower={args=1},      toupper={args=1},      tr={args=3}, +    trim={args={1,2}},      trunc={args=1, func="float_op_wrapper", data="&trunc"},      type={args=1},      undofile={args=1}, diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 78fac5acf8..8b650d0d5b 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -4892,10 +4892,12 @@ buf_check_timestamp (            )) {      retval = 1; -    /* set b_mtime to stop further warnings (e.g., when executing -     * FileChangedShell autocmd) */ +    // set b_mtime to stop further warnings (e.g., when executing +    // FileChangedShell autocmd)      if (!file_info_ok) { -      buf->b_mtime = 0; +      // When 'autoread' is set we'll check the file again to see if it +      // re-appears. +      buf->b_mtime = buf->b_p_ar;        buf->b_orig_size = 0;        buf->b_orig_mode = 0;      } else { diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 6d0a6b9d5e..e2a035b0b2 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -926,3 +926,26 @@ func Test_redo_in_nested_functions()    delfunc Operator    delfunc Apply  endfunc + +func Test_trim() +  call assert_equal("Testing", trim("  \t\r\r\x0BTesting  \t\n\r\n\t\x0B\x0B")) +  call assert_equal("Testing", trim("  \t  \r\r\n\n\x0BTesting  \t\n\r\n\t\x0B\x0B")) +  call assert_equal("RESERVE", trim("xyz \twwRESERVEzyww \t\t", " wxyz\t")) +  call assert_equal("wRE    \tSERVEzyww", trim("wRE    \tSERVEzyww")) +  call assert_equal("abcd\t     xxxx   tail", trim(" \tabcd\t     xxxx   tail")) +  call assert_equal("\tabcd\t     xxxx   tail", trim(" \tabcd\t     xxxx   tail", " ")) +  call assert_equal(" \tabcd\t     xxxx   tail", trim(" \tabcd\t     xxxx   tail", "abx")) +  call assert_equal("RESERVE", trim("你RESERVE好", "你好")) +  call assert_equal("您R E SER V E早", trim("你好您R E SER V E早好你你", "你好")) +  call assert_equal("你好您R E SER V E早好你你", trim(" \n\r\r   你好您R E SER V E早好你你    \t  \x0B", )) +  call assert_equal("您R E SER V E早好你你    \t  \x0B", trim("    你好您R E SER V E早好你你    \t  \x0B", " 你好")) +  call assert_equal("您R E SER V E早好你你    \t  \x0B", trim("    tteesstttt你好您R E SER V E早好你你    \t  \x0B ttestt", " 你好tes")) +  call assert_equal("您R E SER V E早好你你    \t  \x0B", trim("    tteesstttt你好您R E SER V E早好你你    \t  \x0B ttestt", "   你你你好好好tttsses")) +  call assert_equal("留下", trim("这些些不要这些留下这些", "这些不要")) +  call assert_equal("", trim("", "")) +  call assert_equal("a", trim("a", "")) +  call assert_equal("", trim("", "a")) + +  let chars = join(map(range(1, 0x20) + [0xa0], {n -> nr2char(n)}), '') +  call assert_equal("x", trim(chars . "x" . chars)) +endfunc diff --git a/src/nvim/testdir/test_stat.vim b/src/nvim/testdir/test_stat.vim index 0a09130b0c..c276df0a92 100644 --- a/src/nvim/testdir/test_stat.vim +++ b/src/nvim/testdir/test_stat.vim @@ -43,7 +43,16 @@ func Test_existent_directory()    call assert_equal(0, getfsize(dname))    call assert_equal('dir', getftype(dname)) -  call assert_equal('rwx', getfperm(dname)[0:2]) +  call assert_equal(has('win32') ? 'rw-' : 'rwx', getfperm(dname)[0:2]) +endfunc + +func SleepForTimestamp() +  " FAT has a granularity of 2 seconds, otherwise it's usually 1 second +  if has('win32') +    sleep 2 +  else +    sleep 2 +  endif  endfunc  func Test_checktime() @@ -53,12 +62,7 @@ func Test_checktime()    call writefile(fl, fname)    set autoread    exec 'e' fname -  " FAT has a granularity of 2 seconds, otherwise it's usually 1 second -  if has('win32') -    sleep 2 -  else -    sleep 2 -  endif +  call SleepForTimestamp()    let fl = readfile(fname)    let fl[0] .= ' - checktime'    call writefile(fl, fname) @@ -68,6 +72,46 @@ func Test_checktime()    call delete(fname)  endfunc +func Test_autoread_file_deleted() +  new Xautoread +  set autoread +  call setline(1, 'original') +  w! + +  call SleepForTimestamp() +  if has('win32') +    silent !echo changed > Xautoread +  else +    silent !echo 'changed' > Xautoread +  endif +  checktime +  call assert_equal('changed', trim(getline(1))) + +  call SleepForTimestamp() +  messages clear +  if has('win32') +    silent !del Xautoread +  else +    silent !rm Xautoread +  endif +  checktime +  call assert_match('E211:', execute('messages')) +  call assert_equal('changed', trim(getline(1))) + +  call SleepForTimestamp() +  if has('win32') +    silent !echo recreated > Xautoread +  else +    silent !echo 'recreated' > Xautoread +  endif +  checktime +  call assert_equal('recreated', trim(getline(1))) + +  call delete('Xautoread') +  bwipe! +endfunc + +  func Test_nonexistent_file()    let fname = 'Xtest.tmp' @@ -78,6 +122,41 @@ func Test_nonexistent_file()    call assert_equal('', getfperm(fname))  endfunc +func Test_getftype() +  call assert_equal('file', getftype(v:progpath)) +  call assert_equal('dir',  getftype('.')) + +  if !has('unix') +    return +  endif + +  silent !ln -s Xfile Xlink +  call assert_equal('link', getftype('Xlink')) +  call delete('Xlink') + +  if executable('mkfifo') +    silent !mkfifo Xfifo +    call assert_equal('fifo', getftype('Xfifo')) +    call delete('Xfifo') +  endif + +  for cdevfile in systemlist('find /dev -type c -maxdepth 2 2>/dev/null') +    call assert_equal('cdev', getftype(cdevfile)) +  endfor + +  for bdevfile in systemlist('find /dev -type b -maxdepth 2 2>/dev/null') +    call assert_equal('bdev', getftype(bdevfile)) +  endfor + +  " The /run/ directory typically contains socket files. +  " If it does not, test won't fail but will not test socket files. +  for socketfile in systemlist('find /run -type s -maxdepth 2 2>/dev/null') +    call assert_equal('socket', getftype(socketfile)) +  endfor + +  " TODO: file type 'other' is not tested. How can we test it? +endfunc +  func Test_win32_symlink_dir()    " On Windows, non-admin users cannot create symlinks.    " So we use an existing symlink for this test. | 
