Code Monkey home page Code Monkey logo

vital.vim's Introduction

vital.vim Matrix Test status codecov

Join the chat at https://gitter.im/vim-jp/vital.vim

A comprehensive Vim utility functions for Vim plugins.

Requirements

Modules in vital.vim basically support Vim 8.2 or later. We guarantee that the following versions of Vim are supported:

  • The latest major version (9.0.*)
  • The previous major version (8.2.*)

And some modules have stricter requirements and additional dependencies. Please read the docs of each module before using them.

Handling libraries in Vim WAS hard

Since Vim script has no built-in module system, using external libraries had been troublesome.

  • If you decide to include the libraries in your plugin repository by copy&paste manually: You are responsible for updating the libraries by yourself. sigh You have to find backward-incompatible changes that can break your plugin from every changes between the previous version you installed in the past. super tedious
  • If you want the plugin users to install the dependent libraries: The users will receive additional steps to get it working with your plugin. not easy Even worse, they may fail to install the dependencies properly. a bad dream

What vital.vim does for the problems

vital.vim will embed libraries into your plugin repository and thus your plugin users don't need to install them separately. Additionally, vital.vim can also resolve the dependencies according to the declaration on vital modules.

Concretely, vital.vim resolves the dependencies among vital modules by the module bundler called vitalizer. vitalizer can bundle only necessary modules and can update an existing bundle. On updating the modules, vitalizer shows any breaking changes to help you migrate to the new version of vital modules.

What vital.vim provides

Module Description
Assertion assertion library
Async.Promise An asynchronous operation like ES6 Promise
Bitwise bitwise operators
Color color conversion library between RGB/HSL/terminal code
ConcurrentProcess manages processes concurrently with vimproc
Data.Base64 base64 utilities library
Data.Base64.RFC4648 base64 RFC4648 utilities library
Data.Base64.URLSafe base64 URLSafe utilities library
Data.Base32 base32 utilities library
Data.Base32.Crockford base32 Crockford utilities library
Data.Base32.Hex base32 Hex utilities library
Data.Base32.RFC4648 base32 RFC4648 utilities library
Data.Base16 base16 utilities library
Data.BigNum multi precision integer library
Data.Closure Provide Closure object
Data.Counter Counter library to support convenient tallies
Data.Dict dictionary utilities library
Data.Either either value library
Data.LazyList lazy list including file io
Data.List list utilities library
Data.List.Closure Data.List provider for Data.Closure
Data.List.Byte Data.List provider for Bytes-List and other bytes-list like data converter.
Data.Optional optional value library
Data.OrderedSet ordered collection library
Data.Set set and frozenset data structure ported from python
Data.String string utilities library
Data.String.Interpolation build string with ${}
Data.Tree tree utilities library
Database.SQLite sqlite utilities library
DateTime date and time library
Experimental.Functor Utilities for functor
Hash.HMAC Hash-based Message Authentication Code
Hash.MD5 MD5 encoding
Hash.SHA1 SHA1 encoding
Interpreter.Brainf__k Brainf**k interpreter
Locale.Message very simple message localization library
Mapping Utilities for mapping
Math Mathematical functions
OptionParser Option parser library for Vim
Prelude crucial functions
Process Utilities for process
Random.Mt19937ar random number generator using mt19937ar
Random.Xor128 random number generator using xor128
Random Random utility frontend library
Stream A streaming library
System.Cache An unified cache system
System.File filesystem utilities library
System.Filepath path string utilities library
System.Process A cross-platform process utilities
Text.CSV CSV library
Text.INI INI file library
Text.LTSV LTSV library
Text.Lexer lexer library
Text.Parser parser library
Text.TOML TOML library
Text.Table Character table library
Vim.BufferManager buffer manager
Vim.Buffer Vim's buffer related stuff in general
Vim.Compat Vim compatibility wrapper functions
Vim.Guard Guard options/variables
Vim.Message Vim message functions
Vim.Python +python/+python3 compatibility functions
Vim.ScriptLocal Get script-local things
Vim.Search Vim's [I like function
Vim.ViewTracer Trace window and tabpage
Vim.WindowLayout lays out windows declaratively
Web.HTML HTML parser written in pure Vim script
Web.HTTP simple HTTP client library
Web.JSON JSON parser written in pure Vim script
Web.URI URI manipulation library
Web.XML XML parser written in pure Vim script

... and you can also create your own vital modules. Please see External vital modules for more information.

Let's get started

Install modules for your own plugin

Use :Vitalize to install modules. Assuming your Vim plugin name is your_plugin_name and plugin directory is your_plugin_dir. Please see the help for more details.

:Vitalize --name=your_plugin_name $HOME/.vim/bundle/your_plugin_dir/

You can also install only specified modules; recommended for making your repository size small, assuming you are going to upload it to a remote repository

:Vitalize --name=your_plugin_name $HOME/.vim/bundle/your_plugin_dir/ Data.String Data.List

Use vital functions

Assuming your Vim plugin name is your_plugin_name. You can define your utility function set your_plugin_name#util just by

let s:Process = vital#your_plugin_name#import('System.Process')

function! your_plugin_name#util#system(...)
  return s:Process.execute(a:000)
endfunction
" run
" echo your_plugin_name#util#system('echo','abc')
" -> $ echo abc

and then you can call functions by your_plugin_name#util#system(), without taking care of vital.vim itself. It's all hidden.

Vital has module system. The below is an example to import/load a module Math and to call a function lcm() of the module.

" Recommended way
let s:M = vital#your_plugin_name#import('Math')
call s:M.lcm([2, 3, 4])
" -> 12

or

" Alternative way
let s:V = vital#your_plugin_name#new()
let s:M = s:V.import('Math')
call s:M.lcm([2, 3, 4])
" -> 12

or

" Alternative way only if you rarely use the module
let s:V = vital#your_plugin_name#new()
call s:V.load('Math')
call s:V.Math.lcm([2, 3, 4])
" -> 12

or

" Available, but we don't recommend this very much
let s:V = vital#your_plugin_name#new()
call s:V.import('Math', s:)
call s:lcm([2, 3, 4])
" -> 12

We recommend you to use a capital letter for a Vital module dictionary to assign.

Plugins Using vital.vim

A lot of vim plugins are using vital.vim

Badges

It is not necessary but we recommend adding a badge to your project README to make the vital.vim developers happy ;-) The following is a markdown snippet.

[![Powered by vital.vim](https://img.shields.io/badge/powered%20by-vital.vim-80273f.svg)](https://github.com/vim-jp/vital.vim)

The badge uses Shields.io so you can customize the looks as like:

  • Powered by vital.vim (Default)
  • Powered by vital.vim by adding ?style=plastic
  • Powered by vital.vim by adding ?style=flat
  • Powered by vital.vim by adding ?style=flat-square

If you want to become a vital developer

Become a vital.vim Developer

References

License

NYSL

Japanese original text: http://www.kmonos.net/nysl/

What's NYSL? and Why did we chose it?

NYSL is a very loose license like a Beer License, or more like WTFPL. See NYSL for details. (English and Japanese)

First, vital.vim is a bundling (static) library. We think everyone should be able to use it easily, without worrying about licensing stuff too much.

Second, In Japan, Strict Public Domain might be invalid. You outside Japan may interpret simply the license as Public Domain.

That's why we chose NYSL.

(See #26 about the discussion.)

vital.vim's People

Contributors

aiya000 avatar aomoriringo avatar cohama avatar crazymaster avatar deris avatar github-actions[bot] avatar hattya avatar haya14busa avatar hrsh7th avatar ichizok avatar itchyny avatar k-takata avatar kamichidu avatar lambdalisue avatar mattn avatar milly avatar nicwest avatar raa0121 avatar rbtnn avatar rhysd avatar ryunix avatar shougo avatar syngan avatar thinca avatar tsuyoshicho avatar tyru avatar ujihisa avatar umireon avatar wtsnjp avatar zoncoen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vital.vim's Issues

change parse() in Vital.Lexer to lex(), run() or exec()

Vital.Lexerにあるparse()関数は構文解析するのではなく字句解析、すなわち英語でlexやscanとよばれるものを行います。この関数名は、Vital.Lexerを構文解析器と組み合わせて使う比較的一般的なユースケースにおいて、parse()という名前を用いている部分が構文解析をしているところなのか字句解析しているところなのか非常にわかりにくくなってしまいます。

parse()parse()でない名前に変更することを提案します。同時に、Vital.Lexer-Parserオブジェクト (内部的には辞書) もなんらかの別名になるべきでしょう。こっちはちょっと良い名前が思いつかないですが。

see also: :h Vital.Lexer-Parser

neocomplcacheのvital.vimでエラー

Shougo/neocomplcache.vim#304 にて、vitalが原因なneocomplcacheのエラー報告がありました。

このエラーはなぜ起こるかわかるでしょうか。環境に依存する可能性が高いので、今 .vimrc を送ってもらえるように頼んでいます。

neocomplcacheのvitalは最新版では無いので、最新版では修正されている問題かもしれません。
(最新版のvitalは変更が大きそうなのでまだ試せていません……)

web.http でバイナリファイルを扱えるようにしてほしい

私の勘違い/使用法間違いかもしれませんが,
curl/wget により得られた content を s:_readfile() 内で join しているため,
call writefile(filename, split(string_list, "\n"), "b")
としても \x00 を含むファイルの場合にデータが壊れてしまいます.
バイナリファイル用に join しないモードを追加していただきたいです.

Web.Utils?

When trying to use Web.Http I get error: E605: Exception not caught: vital: module not found: Web.Utils

And there exists no utils.vim file in the web directory so did someone just forget
to check-in a file?

モジュール以外のファイルを vitalize 時に含める

モジュールが使う .py ファイルやデータファイルなど。モジュール以外のファイルが vitalize で含められるようにする。
今のところ、 s:_vital_depends()['./foo.py'] を返すとモジュールからの相対パスでそのファイルが入るようなのをなんとなく考えている。意見があったらください。特になければこの方法でそのうち実装します。

spec がイケてないのをなんとかしたい

現状 vital に同梱されている spec は、

  • 手軽にコマンドラインから実行できない
  • 結果がファイルに出る
  • 結果が見づらい

などの様々な問題を抱えている。テストの実行が面倒だと誰もテストを実行しなくなる。
これを、改善するなり既存の別のテスティングフレームワークに置き換えるなりしたい。

:Vitalizeが失敗する

Windows環境で、:Vitalize ../neocomplcache/によりvitalizeしようと思ったのですが、下記のようなエラーとなりました。

line   22:
Error detected while processing function vitalizer#command..vitalizer#vitalize..<SNR>271_rmdir:
Error detected while processing function vitalizer#command..vitalizer#vitalize:
line   26:
E605: Exception not caught: <96><b3><8c><f8><82>ȃX<83>C<83>b<83>`<82>ł<b7> - "Work"
E171: Missing :endif

Data.List.flatten with depth

autoload/vital/latest/data/list.vim

" Flattens a list.
function! s:flatten(list)
  let list = []
  for Value in a:list
    if type(Value) == type([])
      let list += s:flatten(Value)
    else
      call add(list, Value)
    endif
    unlet! Value
  endfor
  return list
endfunction

現状flatten([1, [2, [3]]])から[1, 2, 3]は得られるけれど[1, 2, [3]]は残念ながら得られないので、どの深さまでflattenするかをオプショナルな第二引数で指定できると実用的だなあと思います。

無指定のときは無限深、つまり現状のままの挙動、ということで後方互換性も保つことができて一石二鳥です。

filepathのwhich()がwildignoreに影響される

filepath.vimの which() 内でglob()が第2引数なしで使われており、wildignoreの影響を受けます。

*.exe なファイルは:edit等での wildmenu からは除外したいため、

set wileignore+=*.exe

という設定はされやすいのかなと思いますが、
これにより which() が *.exe のパスを返さなくなってしまうのは得策ではないと思います。

バイナリデータの url エンコードに失敗する

そもそも対応していないのかもしれませんが。

以下のように、A4 のあとの変換に失敗しています。

:echo g:HTTP.encodeURI("\xA4\xC1\xB9\xE7")
%A4y%E7
:echo g:HTTP.encodeURI(g:VITAL.iconv("ちゅ", &enc, "euc-jp"))
%A4d%E5
:echo g:HTTP.encodeURI(g:VITAL.iconv("ちょ", &enc, "euc-jp"))
%A4d%E7
:echo &enc
utf-8
:echo &fenc
euc-jp

DateTimeのfrom_formatでエラー

環境: windows
テストコード

let s:D = s:V.import('DateTime')
let s:date = s:D.from_format('1 15 02:03:04 +0000 2012','%m %d %H:%M:%S %z %Y')

ログ

Error detected while processing function <SNR>124_from_format..36:
line    4:
E734: Wrong variable type for +=
line    5:
E716: Key not present in Dictionary: _second
E116: Invalid arguments for function s:_divmod(self[key], s:['NUM_' . toupper(unit . 's')])
E15: Invalid expression: s:_divmod(self[key], s:['NUM_' . toupper(unit . 's')])
line    4:
E734: Wrong variable type for +=
line    5:
E716: Key not present in Dictionary: _minute
E116: Invalid arguments for function s:_divmod(self[key], s:['NUM_' . toupper(unit . 's')])
E15: Invalid expression: s:_divmod(self[key], s:['NUM_' . toupper(unit . 's')])
line    4:
E734: Wrong variable type for +=
line    5:
E716: Key not present in Dictionary: _hour
E116: Invalid arguments for function s:_divmod(self[key], s:['NUM_' . toupper(unit . 's')])
E15: Invalid expression: s:_divmod(self[key], s:['NUM_' . toupper(unit . 's')])
line    8:
E734: Wrong variable type for +=
-- More --

autoload/vital.vimに関する新しい仕組みの提案

#40 と関連。

前から言われてたことですが、autoload/vital.vimはvitalモジュールのローダーなので、易々と手を加えられません。
(加えたら全てのvital.vimを使っているプラグインは更新しなければいけない)

autoloadを使うと #40 のような行儀の悪いプラグインがいた場合全てのvitalを使うプラグインに影響が出てしまいます。

そこで、autoloadを使わずFuncUndefinedを使ってリポジトリ内のローダーを探し、それを優先的に使うようにすればいいと思うのですがどうでしょう。
リポジトリ内のローダーは今はautoload/vital.vimです。
ただこれだとautoloadに使われてしまうため、macros/vital_loader.vim的なところに置いて、FuncUndefinedイベント時に(autoloadに頼らず)動的にローダーを探すことで解決できるかと思われます。

vital#of()は互換性のために残しておいて、FuncUndefinedでフックできるようVitalOf()などの関数名を使うようvitalを使うプラグインが変更する必要がありますが。

上記2点について意見を求めたいです。

  1. autoloadを使わずFuncUndefinedでローダーのスクリプトファイルを探す処理を加えるか?
  2. 1に賛成するのなら、新しいAPIのインターフェースはどのようなものが望ましいか。(VitalOf()はなんとなく嫌です...)

Web.HTTP: settings.command

request() の引数のパラメタ command が有効ではないように思います。

  • settings.client の仕様変更(リスト)についていっていない
  • available() で使用していない

モジュールの依存関係の記述について

モジュールの依存関係の記述について議論したいと思います。

背景として、vital に今後モジュールが増えていった場合、全てをプラグインに組み込むのは現実的ではありません。
この場合、必要なモジュールのみを組み込む機構が必要になりますが、この時 vitalizer が依存関係を知る手段がないと、適切に組み込むことができません。
よって、以下の点について考える必要があります。

  • モジュールの依存関係を vitalizer が知る方法
  • モジュールが別のモジュールを参照する方法
    • 現状の方法は動いてない? (未確認)
    • 動いていたとしても、依存関係の記述方法によっては変えた方がいい?
  • ユーザが vitalizer に必要なモジュールのリストを伝える手段

みなさんの意見をください。

deprecatedの仕組みを考える

split_leftrightを消して良いかという意見もあるので、この際今後deprecated扱いな関数をどうするか考えたい。

License

一言で要約

「vital.vimに含まれているコードを書いた人は、"MITかRuby's (= GPL2 || 2条項BSDライセンス)のどちらかのライセンスにする"に同意していただけるかどうかコメントしてください。」

ものすごく今更感がありますが、よくみたらvital.vimのどこみてもライセンスに関する情報がありませんでした。
プラギンに同封するという性質から、ライセンスが明記されていないのはプラギン開発者にとって不便かなあと思います。

GPLだと同封したい人にとって困ったりするのかな? とりあえずMITかRuby's (= GPL2 || 2条項BSDライセンス)のどちらかでどうかなあと。MITに一票。

https://github.com/vim-jp/vital.vim/graphs/contributors

厳密にはここに載っている人すべてと、外部からもってきたコードの元の作者の人すべてから承諾を得られればいい感じなのかな。

ちょっぴり関連するissue: #12

「vitalに」新しいテストモジュールが欲しい

理由:
vitalにテストモジュールがあれば、リポジトリにテストモジュールとテストコードを同梱することで、Vimプラグインのユーザさんに「テストを実行してみてください」と気軽に頼めるようになるはずです。
これによってユーザさんの環境で起こった問題を再現させるのがより楽になると思います。

s:_split_by_wcswidth_once(body, x)でa:bodyに特定の文字列を指定すると1文字欠ける。

たとえば、

" https://github.com/vim-jp/vital.vim/blob/master/autoload/vital/__latest__/data/string.vim#171

echo s:_split_by_wcswidth_once('_このプロジェクトに追加された_WebServices_へのアクセスを提供します。',65)
[' _このプロジェクトに追加された_WebServices_へのアクセスを提供しま', '。']

というように特定の文字列を指定すると一文字欠けてしまいます。(今回の場合は「す」)

ynkdir/vim-funlib の各種ライブラリを取り込みたい

TODOメモ。
概ね public domain だったはずなので、ライセンス上は問題ないはず。
そうは言っても一応本人に確認を取る。
中にはportしたものもあるようなので、一応ライセンスを確認する。
…と言うのを誰かやってくれると嬉しい。(ぉぃ

DateTime.format('%p')の結果がおかしい?

僕の環境(MacVim)では、

echo strftime('%p') " => AM
echo strftime('%P') " => P
echo vital#of('vital').import('DateTime').now().format('%p') " => P
echo vital#of('vital').import('DateTime').now().format('%P') " => AM

のようになります。他の環境ではどうでしょうか

vital.vimのimport時にエラー

最近、vimprocをvitalizeしたのですが、このような報告がありました。

https://twitter.com/shiwano/status/211814573928488960
https://twitter.com/shiwano/status/211816815024807936

http://gyazo.com/28384f360aa2be29257cbcbe2b0d0e20

https://twitter.com/itchyny/status/211801921000964096
https://twitter.com/thinca/status/211835917365805056
https://twitter.com/itchyny/status/211985254318227457

どうやら、vitalを読み込む際に自分自身をうまく除外できていないようです。

現在はvimprocのvitalizeをrevertしたので大きな混乱は避けられていますが、今後vitalizedされたプラグインがvitalをバージョンアップすると同様の問題が起こる可能性があります。

Vitalを使用するライブラリ的なプラグイン(vimproc等)ではredirの入れ子問題が発生する

最近vimprocにVitalが組込まれましたが、vimprocに組込まれているvitalで:redirが使用されるため、

このようなコードで

 function! s:foo()
   redir => bar
   call vimproc#system('ls')
   redir END
   return bar
 endfunction
 echo s:foo()

以下のようなエラーが出ます。

Error detected while processing function vital#of..vital#_06ce4df#new..<SNR>128__scripts..<SNR>128__redir:
line    1:
E121: Undefined variable: bar

quickrun ではverbosefileを使用して回避しているようですが、vimprocのようなライブラリ的に使用されるプラグインの場合、
:redirの入れ子問題が発生してしまいます。

はじめvimprocの方のissuesに挙げようかと思いましたが、根本的に解決できない(vimprocを使用する全ての人に:redirを使わないようにアナウンスするのはあまり良い策とは思えない)ため、vitalの方で解決できないでしょうか。

vital.vimの初期化時にエラー

環境:

  • Mac OS X 10.7
  • vimfilesの場所: ~/.vim/
  • NeoBundleによってneocomplcacheおよびunite.vimを管理している
    ** 両者はどちらも vital 671b6f0 を使用している
  • 配置場所に、特にシンボリックリンクは使用していません

現象

:call vital#of('neocomplcache') " of('unite.vim')でも同様

した際、

/Users/xxxx/.vim/bundle/neocomplcache/autoload/vital/_671b6f0.vim の処理中にエラーが検出されました:
行 150:
E127: 関数 vital#_671b6f0#new を再定義できません: 使用中です

というエラーが出る。

二度目にvital#of('neocomplcache')を読んだ際は、正常に終了する。

分析

vitalの初期化処理で、s:_import()内に次のような処理がある

  if v:version > 702 || v:version == 702 && has('patch51')
    let paths = split(globpath(&runtimepath, tailpath, 1), "\n")
  else
    let paths = split(globpath(&runtimepath, tailpath), "\n")
  endif
  let path = s:_unify_path(get(paths, 0, ''))
  let sid = get(a:scripts, path, 0)
  if !sid
    try
      source `=path`
    catch /^Vim\%((\a\+)\)\?:E484/
    " ...

エラーが発生していたのは、source =pathの行が実行されて_671b6f0.vimがロードされたため。

前の処理でvitalのsidを決定する際に、pathsが複数あった場合のことが考慮されていないのではないか。

処理を修正して

  if v:version > 702 || v:version == 702 && has('patch51')
    let paths = split(globpath(&runtimepath, tailpath, 1), "\n")
  else
    let paths = split(globpath(&runtimepath, tailpath), "\n")
  endif
  let sid = 0
  for raw_path in paths
      let path = s:_unify_path(raw_path)
      if !sid
          let sid = get(a:scripts, path, 0)
      endif
      break
  endfor
  if !sid
    try
      source `=path`
    catch /^Vim\%((\a\+)\)\?:E484/

としたところ、エラーは出なくなりました。

モジュールのファイル名をモジュール名と同じにするのはどうか

現在、モジュール名 DateTime に対してファイル名は date_time.vim のようになってますが、
いっそのことモジュール名と同じにして DateTime.vim のようにするのはどうでしょうか。
こうすることで以下のメリットがあるかと思います。

  • 各所でファイル名<=>モジュール名の変換をする必要がない。
    • ほんの少しですがオーバーヘッドを減らせます。また、コード量も減ります。
  • 大文字が連続するモジュール名を作れる。
    • 例えば JSON のようなモジュールが作りたい場合は、現在だと j_s_o_n_.vim のようにしないといけません。
  • 直感的にわかりやすい。

みなさんの意見をください。

refinements in import() and load()

vital 本体の API のドキュメントを書こうと思ったけど、import() とか load() の仕様の議論がまだ収束してないことに気付くなど。
えーと、load の as 機能について。現状の load(['Foo']) がわかりづらいとの話だった気がする。
個人的には短く書けて気に入っているのだけど。
仕様整理。

  1. load するとモジュールが V に置かれてそこからアクセスできるようになる。

    V.load('Foo.Bar.Buz')
    -> V.Foo.Bar.Buz
    
  2. 複数同時にロード可能

    V.load('Foo.Bar.Buz', 'Hoge', 'Huga')
    -> V.Foo.Bar.Buz
    -> V.Hoge
    -> V.Huga
    
  3. 文字列ではなくリストを渡すと、as として処理される

    V.load(['Foo.Bar.Buz', 'FBB'])
    -> V.FBB
    
  4. as を空文字列にすればトップレベルに直接ロード可能

    V.load(['Foo.Bar.Buz', ''])
    -> V (Foo.Bar.Buz の関数が直接使える)
    
  5. 空文字列の場合は省略可能

    V.load(['Foo.Bar.Buz'])
    -> V (Foo.Bar.Buz の関数が直接使える)
    

ふと思ったのだけど、リストじゃなくて辞書を渡す仕様にして 5. の省略可能をなくすのはどうか。
as としては辞書の方が自然な気もするし。

V.load({'Foo.Bar.Buz': 'FBB'})
-> V.FBB

必然的に複数同時に処理可能。
ここらで人の意見が欲しい。

lingrでのthincaさんの提案を引用しつつ整形。

まず一般的な指針として、vitalのimport/loadは記述の短さよりも記述のわかりやすさを優先すべきと思っています。「このファイルはこれとこれをこのように使う」というのはexplicitである方が読みやすいです。複数の箇所に散らばるものは常に記述が短くあるべきですが、ファイルの先頭で宣言するものの場合、記述の短さはあまり重要でないと思います。

というわけで、thincaさんの「5. の省略可能をなくすのはどうか」は大賛成です。が、それだけでなく、「2. 複数同時にロード可能」をなくすべき、あるいは別名の関数にするべきだと思います。

というわけでこんな新仕様はどうでしょう。

  1. load するとモジュールが V に置かれてそこからアクセスできるようになる。これ以外にload()の使い道はない。

    V.load('Foo.Bar.Buz')
    -> V.Foo.Bar.Buz
    
  2. load_as すると第二引数の名前で参照可能。これ以外にload_as()の使い道はない。

    V.load_as('Foo.Bar.Buz', 'FBB')
    -> V.FBB
    
  3. import_extending すると第1引数の変数を破壊的に書き換え、その中に読み込む関数が注入される。したがって以下のようにすることで、元の提案の4.が実現できる。なお、第二匹数が辞書でなかった場合、エラーとなる。また関数名がかぶった場合、元々存在する関数が上書きされ、あとで読み込ませたものが優先される。なお、import_extendingの第二引数は省略できない、つまりこれ以外にimport_extendingの使い道はない。なお、この関数の名前が長いのは、なるべくimportで別の変数を作ってほしいため。

    V.import_extending(V, 'Foo.Bar.Buz')
    -> V (Foo.Bar.Buz の関数が直接使える)
    
    let B = V.import('Foo.Bar.Baaaa')
    V.import_extending(B, 'Foo.Bar.Booo')
    -> B (Foo.Bar.Booo の関数も直接使える)
    
  4. (導入するとすれば) load_eachで複数同時にロード可能。名前が長いのは、なるべくload()を並べて使ってほしいという想いから。

    V.load_each('Foo.Bar.Buz', 'Hoge', 'Huga')
    -> V.Foo.Bar.Buz
    -> V.Hoge
    -> V.Huga
    
  5. (導入するとすれば) import_extending_eachで複数同時。これも同じく意図的に長い名前で。

  • load_as_eachuse_eachはなし。前者は元の問題の4. や5. などのため。後者はなにが優先されるのかわかりづらいため。

ところで、上記方法で、lingrでmanga_osyoさんが要求していたユースケース: Vなどを経由せずいきなりs:から使えるようにしたいというものも自然に解決できます。実装上の黒魔術はなく、explicitで、かつ十分に短いです。

V.import_extending(s:, 'A.B.C')

以下、実装の。擬似コード。実際には厳しめの引数のチェックとエラー処理が入ります。

function! s:load(x)
  call s:load_as(a:x, a:x)
endfunction

function! s:load_as(x, y)
  ...
endfunction

" function! s:load_each(...)
"   for x in a:000
"     call s:load(x)
"   endfor
" endfunction

function! s:import_extending(x, y)
  call extend(y, s:import(x))
endfunction

コミットログの書き方についての提案

些細なことですが、コミットログの書き方についての提案です。
個人的に実施しているのですが、モジュールに対して変更を行った場合、
コミットログの先頭にモジュール名を書くようにするのはどうでしょうか。
これによって得られるメリットとして以下が挙げられるかと思います。

  • コンテキストが絞られることにより、コメントが書き易くなる。
    • Data.List.uniq() と書く代わりに単に uniq() と書ける。
  • ログをざっと見たときにそれぞれが何に対する変更かわかりやすい。
  • ルール付けすることで(多分)みやすくなる。

ちなみに「grep すれば特定のモジュールの変更だけを見れる」ってのもなくはないですが、
これは git 標準でファイル指定すれば見れるのでメリットにはなりませんね。

また、help だけ、spec だけに変更を行った場合はそれもあるといいかもしれません。

例: c5bb95b

DateTime: help: Fixed typo.

先頭がモジュール名、続いて、help のみの変更だったので help: としています。

その他、書き方に対する修正案、別の案などもあると嬉しいです。
今のところルールがまったくないので、賛同が得られなくても、気に入った人だけが使う、というのもありだと思っています。

Processモジュールの名前とAPIについて

Vimからアプリケーションをバックグラウンドで起動するいくつかの方法

上記記事のバッドノウハウベストプラクティスについて、
@osyo-manga さんがLingrで

http://lingr.com/room/vim/archives/2013/03/14#message-14298001

これ、vimproc とは別に vital.vim にあると便利そう

と言っていたのでモジュール化しました。(module/processブランチ)

それで、Processは汎用的すぎるのでSystemとかに変えたいんですが、System.Filepathとかがいるので使えません...何かいい名前ありませんか?
(あれ?そういえば名前空間の問題ってissue開いてませんでしたっけ?探したけど見つかりません...)

ちなみに今の所アプリケーションをバックグラウンドで開くsystem_bg()しか関数は持ってません。

モジュール名の変更について

以前からあった問題ですが、foo_bar.vimFooBar と扱うのには問題があって、例えば Web.HTTP というモジュール名を提供するには web/h_t_t_p.vim というファイル名にする必要がありました。

現在 devel ブランチに、モジュール名=ファイル名となる変更が入っています。
動いている様なので、皆が良ければ master にマージしたいと思っています。

如何でしょうか。

Web.* の関数名を snake_case に

Web.* のモジュールは元々 webapi.vim からの移植なので、関数名が camelCase になっているが、 vital.vim 全体としては snake_case なのでこちらに合わせたい。
特に反対がなければそのうちやる。

type()実行時にエラーが出る?

私の環境では未確認ですが、neocomplcacheに同梱されているvital.vimでエラーになる環境があるみたいです。

詳しい現象はこちらを参照してください。

Shougo/neocomplcache.vim#142

let [
\   s:__TYPE_NUMBER,
\   s:__TYPE_STRING,
\   s:__TYPE_FUNCREF,
\   s:__TYPE_LIST,
\   s:__TYPE_DICT,
\   s:__TYPE_FLOAT
\] = [
\   type(3),
\   type(""),
\   type(function('tr')),
\   type([]),
\   type({}),
\   type(3.14159)
\]

この、type(3.14159)でエラーになるらしいです。

Error detected while processing /Users/helmuth/github/vim/bundle/neocomplcache/autoload/vital/_f9b384/prelude.vim:
line 28:
E806: using Float as a String
Press ENTER or type command to continue
Error detected while processing /Users/helmuth/github/vim/bundle/neocomplcache/autoload/vital/_f9b384/prelude.vim:
line 28:
E116: Invalid arguments for function type(3.14159)]
Press ENTER or type command to continue
Error detected while processing /Users/helmuth/github/vim/bundle/neocomplcache/autoload/vital/_f9b384/prelude.vim:
line 28:
E15: Invalid expression: [ type(3), type(""), type(function('tr')), type([]),type({}), type(3.14159)]
Press ENTER or type command to continue
Error detected while processing function neocomplcache#enable:
line 421:
E171: Missing :endif

Vim本体のバグのような気もします。

I've just updated neocomplcache and compiled Vim from source (version 7.3.446).
I also tried with a version from Ubuntu official repositories (7.3.154).
It seems to work fine on terminal, but on GVim, whenever I start to type on insert mode, it pops out so many errors that it covers the whole visible screen.
It also works fine at my home computer, which has version 7.3.434-1 of Vim.

とあり、Ubuntuで問題になるみたいですが、私の周囲でそんな報告はありませんし、私の環境ではUbuntuですが動いていますね。GVimでのみ問題になるというのも、よく分からないです。

macvimにてエラー

MacVim 7.3(KaoriYa 20120105)でneocomplcacheを入れて起動した際に下記の様なエラーが表示されました。

エラー内容

.vim/bundle/neocomplcache/autoload/vital/_e8517d.vim の処理中にエラーが検出されました:
行   75:
E127: 関数 99__import を再定義できません: 使用中です

autoload/vital.vimが更新された時の対応を決めたい

#20 の問題でautoload/vital.vimをアップグレードしたので、vital.vimを使っているプラグインは全て更新しないといけませんでした。

しかしemap.vimがずっと古いバージョンを使っていて、runtimepathの順序的にemap.vimの古いautoload/vital.vimが使われてしまい、
Windows環境で*.vitalファイルの改行にまつわるエラーが出てしまっていました。(emap.vimを使っていてもしこのエラー出た方いたらすみません...)

今回羞恥周知目的でこのissueを立てたのですが、言いたかったことは3つあります。

  1. autoload/vital.vimが更新されたらChangesファイルもアップデートするべきだと思われる
  2. autoload/vital.vimが更新されたら全てのvital.vimを使っているプラグインはvital.vimを更新するべき。でないと他のvital.vimを使っているプラグインにまで影響を与える。
  3. autoload/vital.vimが更新されたらvim-jp.orgで「全てのvital.vimを使っているプラグインはvital.vimを更新してください」的なアナウンスメントをするべきだと思われる

1と3については意見を求めたいです。
今後の方針的にも。

vital.vimのインポート時の指定を簡略化できないか

最近のvital.vimは:Vitalizeによってあるモジュールのみインポートすることができるようになりました。
しかし、モジュールを細かく指定していると、vital.vimのバージョンアップ時に非常に手間となります。
ソースコードを毎回参照しながらどのモジュールをインポートするのか調べるのが手間なのです。

自動で処理することはさすがにできないにしても、autoload/vital/unite.vim.moduleのように、何か設定ファイルを用意して
:Vitalizeの引数が省略されたときはその設定ファイルを参照する、くらいはできそうに思います。

自分にとって必要なので、この機能の実装は自分でやる予定です。

コーディングスタイルを決めてほしい

自分はタブ4なのですが、thincaさんは2だったり、けっこうバラつきがあります。(Data.String編集してて気付いた)
コーディングスタイルを決めて、強制するのではなくてmodelineを追加してやんわりと対応、って感じでいきたいです。

web.http でバイナリファイルを扱えるようにしてほしい(送信側

#53 で受信側は対応してもらったのですが、本件は送信側について、です。

背景としては、以下のような状況です。

  1. vital.vim を使って、バイナリファイルの転送をしたい。
  2. "multipart/form-data" に対応していないため、自分でそれを実現する必要がある。
  3. 現在提供されている方法では、"POST data" は文字列渡しにする必要があるため \x00 に対応できない

対応方法としては、以下のどちらかだと思います。

  • POST 時の data をファイル渡し I/F を提供する
  • vital.vim として "multipart/form-data" をサポートする

2 つ目のほうが理想ですが wget がコマンドとして対応していないので完全な対応は大変そうな印象です。

vital.vimのバージョンファイルの読み取り方がおかしい

https://github.com/ujihisa/vital.vim/issues/8

これは上記の一度closeされた問題の派生です。
Windows環境でのgitは初期設定にてLFをCRLFに変換するらしく、vital.vimのバージョンファイルもCRLFに変換されます。

そして、vital#of()では

function! vital#of(name)
  let files = globpath(&runtimepath, 'autoload/vital/' . a:name . '.vital')
  let file = split(files, "\n")
  if empty(file)
    throw 'vital: version file not found: ' . a:name
  endif
  let ver = readfile(file[0], 'b')
  if empty(ver)
    throw 'vital: invalid version file: ' . a:name
  endif
return vital#_{ver[0]}#new()

endfunction

上記のようにreadfile('b')を用いているので、CRLFの改行コードが変換されずCRがついてしまいます。そしてその関数をvital#_{ver[0]}#new()で読み込もうとするので当然エラーとなります。

gitの自動変換をやめて、バージョンファイルをLFのまま保存するようにすれば問題は無いです。

vital#of()は歴史的事情で変えられなかったのだと思いますが、これは修正するべきでしょう。

vital#of("vital") でエラー

下記の Vim scriptファイル を :source した場合にエラーが出力されました。

Vim scriptファイル

let s:v = vital#of("vital")

エラー内容

-   function vital#of の処理中にエラーが検出されました:
-10:
-   E117: 未知の関数です: vital#__latest__^M#new
-   E15: 無効な式です: vital#_{ver[0]}#new()

version

VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Oct 27 2011 08:54:35)
MS-Windows 32 ビット GUI 版
適用済パッチ: 1-353
Modified by koron.kaoriya@gmail.com
Compiled by koron.kaoriya@gmail.com
Big 版 with GUI.  機能の一覧 有効(+)/無効(-)
+arabic +autocmd +balloon_eval +browse ++builtin_terms +byte_offset +cindent +clientserver +clipboard +cmdline_compl +cmdline_hist +cmdline_info +comments +conceal +cryptv +cscope +cursorbind +cursorshape 
+dialog_con_gui +diff +digraphs -dnd -ebcdic +emacs_tags +eval +ex_extra +extra_search +farsi +file_in_path +find_in_path +float +folding -footer +gettext/dyn +guess_encode -hangul_input +iconv/dyn 
+insert_expand +jumplist +keymap +kaoriya +langmap +libcall +linebreak +lispindent +listcmds +localmap +lua/dyn +menu +migemo/dyn +mksession +modify_fname +mouse +mouseshape +multi_byte_ime/dyn +multi_lang 
-mzscheme +netbeans_intg -ole +path_extra +perl/dyn +persistent_undo -postscript +printer -profile +python/dyn +python3/dyn +quickfix +reltime +rightleft +ruby/dyn +scrollbind +signs +smartindent -sniff 
+startuptime +statusline -sun_workshop +syntax +tag_binary +tag_old_static -tag_any_white -tcl -tgetent -termresponse +textobjects +title +toolbar +user_commands +vertsplit +virtualedit +visual +visualextra 
+viminfo +vreplace +wildignore +wildmenu +windows +writebackup -xfontset -xim -xterm_save -xpm_w32 
      システム vimrc: "$VIM\vimrc"
        ユーザ vimrc: "$HOME\_vimrc"2ユーザ vimrc: "$VIM\_vimrc"
         ユーザ exrc: "$HOME\_exrc"2ユーザ exrc: "$VIM\_exrc"
     システム gvimrc: "$VIM\gvimrc"
       ユーザ gvimrc: "$HOME\_gvimrc"2ユーザ gvimrc: "$VIM\_gvimrc"
    システムメニュー: "$VIMRUNTIME\menu.vim"
コンパイル: cl -c /W3 /nologo  -I. -Iproto -DHAVE_PATHDEF -DWIN32   -DFEAT_CSCOPE -DFEAT_NETBEANS_INTG     /DMODIFIED_BY=\"[email protected]\" /DDYNAMIC_MSVCRT_DLL=\"msvcr100.dll\" /DGETTEXT_DLL=\"intl.dll\" /D_BIND_TO_CURRENT_VCLIBS_VERSION=1 -DWINVER=0x0400 -D_WIN32_WINNT=0x0400 /Fo.\Obj\GULYHR-x86/ /Ox /GL -DNDEBUG /MD -DFEAT_MBYTE_IME -DDYNAMIC_IME -DFEAT_GUI_W32 -DDYNAMIC_ICONV -DDYNAMIC_GETTEXT -DDYNAMIC_MIGEMO -DFEAT_LUA -DDYNAMIC_LUA -DDYNAMIC_LUA_DLL=\"lua51.dll\" -DFEAT_PYTHON -DDYNAMIC_PYTHON -DDYNAMIC_PYTHON_DLL=\"python27.dll\" -DFEAT_PYTHON3 -DDYNAMIC_PYTHON3 -DDYNAMIC_PYTHON3_DLL=\"python32.dll\" -DFEAT_PERL -DDYNAMIC_PERL -DDYNAMIC_PERL_DLL=\"perl512.dll\" -DFEAT_RUBY -DDYNAMIC_RUBY -DDYNAMIC_RUBY_VER=192 -DDYNAMIC_RUBY_DLL=\"msvcrt-ruby191.dll\" -DFEAT_BIG /Fd.\Obj\GULYHR-x86/ /Zi
リンク: link /RELEASE /nologo /subsystem:windows /LTCG:STATUS oldnames.lib kernel32.lib advapi32.lib shell32.lib gdi32.lib  comdlg32.lib ole32.lib uuid.lib /machine:i386 /nodefaultlib gdi32.lib version.lib   winspool.lib comctl32.lib advapi32.lib shell32.lib  /machine:i386 /nodefaultlib msvcrt.lib   user32.lib   /nodefaultlib:lua51.lib   /nodefaultlib:python27.lib /nodefaultlib:python32.lib    WSock32.lib  /PDB:gvim.pdb -debug

その他、必要な情報があれば教えて頂けると助かります。

シンボリックリンク対応

#10 #17 を続けるとコメントする度に報告者さんにメールがいくので別でやりましょう。

って事で何かしら考えないかんね。

broken Data.List.flatten() spec

{'Data.List.flatten()': ['.', '.', '.', '.', '.', 'It return list flatten : g:L.flatten([[[''a'']], [[[''b'']], ''c'']], 1) ==# [[[''a'']], [[''b'']], ''c'']', 'It return list flatten : g:L.flatten([[[''a'']], [[[''b'']], ''c'']], 2) ==# [[''a''], [[''b'']], ''c'']', 'It return list flatten : g:L.flatten([[[''a'']], [[[''b'']], ''c'']], 3) ==# [''a'', [''b''], ''c'']', '.', '.'], 'Data.List.max()': ['.', '.', '.'], 'Data.List.foldl()': ['.', '.', '.'], 'Data.List.span()': ['.', '.', '.', '.'], 'Data.List.all()': ['.', '.', '.', '.', '.'], 'Data.List.clear()': ['.', '.', '.'], 'Data.List.shift()': ['.', '.', '.'], 'Data.List.break()': ['.', '.', '.', '.'], 'Data.List.foldl1()': ['.', '.', '.'], 'Data.List.foldr()': ['.', '.', '.'], 'Data.List.with_index()': ['.', '.'], 'Data.List.zip()': ['.', '.', '.'], 'Data.List.any()': ['.', '.', '.', '.', '.'], 'Data.List.pop()': ['.', '.', '.'], 'Data.List.partition()': ['.'], 'Data.List.push()': ['.', '.'], 'data.list.take_while()': ['.', '.', '.', '.'], 'Data.List.min()': ['.', '.', '.'], 'Data.List.unshift()': ['.', '.'], 'Data.List.cons()': ['.', '.', '.'], 'Data.List.and()': ['.', '.', '.', '.', '.', '.', '.', '.'], 'Data.List.uniq()': ['.', '.', '.', '.', '.'], 'Data.List.foldr1()': ['.', '.', '.']}

vitalのモジュールロードについて

私はvitalのモジュール機構がよく分かっていないので質問をいたします。

vitalで一部のモジュールのみvitalizeされた場合、モジュールロードがどうなるのか知りたいのです。

vimshell: Preludeのみvitalize

unite.vim: Prelude, Data.Listをvitalize

だとします。さらにプラグインはvimshell, unite.vimの順番でロードされているとします。
vimshell, unite.vimともにvitalizeしているvitalのバージョンは同じです。

unite.vimがモジュールを検索した場合、先に見つかるvimshellのvitalを使用してしまうということはないのでしょうか。
vimshellのvitalを使用してしまうと、vimshelのvitalにはPreludeモジュールしかないのでエラーになるような気がします。

move vim/buffer/manager.vim to vim/buffer_manager.vim in the future

  • バッファ操作汎用関数をあつめたvim/buffer.vimを作ろうとした
  • vim/buffer/manager.vimがあり、かつvitalの制約でパッケージ名と同じモジュール作れない
  • そもそもvim/の中がbufferしかないのにさらにbuffer/managerって深すぎる・・かなあ
  • かといっていまのbuffer/managerの中身すべてが汎用というわけでもない
  • vim/buffer.vimとvim/buffer_manager.vimに分離すれば解決
  • あ、でも既存のvim/buffer/manager.vim使ってるプラギンが全滅する?

というのが問題です。提案として

  1. まずvim/buffer/manager.vimをvim/buffer_manager.vimにコピー
  2. vim/buffer/manager.vim使うと、動作するものの警告が出る
  3. (このまま3ヶ月くらい寝かせる)
  4. vim/buffer/manager.vimを消し、新たにvim/buffer.vimの導入。

どうでしょうか

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.