Squashed 'vim/bundle/tsuquyomi/' content from commit 2a3dcbc90
git-subtree-dir: vim/bundle/tsuquyomi git-subtree-split: 2a3dcbc9085975c3b1c49c382f6c87c69d199a44main
						commit
						19b843f851
					
				@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					*.swp
 | 
				
			||||||
 | 
					*.swo
 | 
				
			||||||
 | 
					*.un~
 | 
				
			||||||
 | 
					node_modules/
 | 
				
			||||||
 | 
					NUL
 | 
				
			||||||
 | 
					.tmp*
 | 
				
			||||||
 | 
					*.log
 | 
				
			||||||
 | 
					neobundle.vim/
 | 
				
			||||||
 | 
					bundle/
 | 
				
			||||||
 | 
					vim/
 | 
				
			||||||
 | 
					local/
 | 
				
			||||||
@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					env:
 | 
				
			||||||
 | 
					  global:
 | 
				
			||||||
 | 
					  - GIT_COMMITTER_NAME=y-kurami
 | 
				
			||||||
 | 
					  - GIT_COMMITTER_EMAIL=yosuke.kurami@gmail.com
 | 
				
			||||||
 | 
					  - GIT_AUTHOR_NAME=Quramy
 | 
				
			||||||
 | 
					  - GIT_AUTHOR_EMAIL=yosuke.kurami@gmail.com
 | 
				
			||||||
 | 
					  - HIDE_VIM=1
 | 
				
			||||||
 | 
					language: node_js
 | 
				
			||||||
 | 
					node_js:
 | 
				
			||||||
 | 
					- '11'
 | 
				
			||||||
 | 
					before_install:
 | 
				
			||||||
 | 
					- 'pushd test/ && yarn install && popd'
 | 
				
			||||||
 | 
					script:
 | 
				
			||||||
 | 
					- bash runtest-all-ts.sh
 | 
				
			||||||
 | 
					cache:
 | 
				
			||||||
 | 
					  yarn: true
 | 
				
			||||||
@ -0,0 +1,336 @@
 | 
				
			|||||||
 | 
					# Tsuquyomi [](https://travis-ci.org/Quramy/tsuquyomi) [](https://greenkeeper.io/)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Make your Vim a TypeScript IDE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tsuquyomi works as a client for **TSServer** (which is an editor service bundled into TypeScript).
 | 
				
			||||||
 | 
					So, installing Tsuquyomi, your vim gets the following features provided by TSServer:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ Completion (omni-completion)
 | 
				
			||||||
 | 
					+ Navigate to the location where a symbol is defined.
 | 
				
			||||||
 | 
					+ Show location(s) where a symbol is referenced.
 | 
				
			||||||
 | 
					+ Display a list of syntax and semantics errors to Vim quickfix window.
 | 
				
			||||||
 | 
					+ and so on,,,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Relevant plugins
 | 
				
			||||||
 | 
					Tsuquyomi does not provide syntax-highlight nor indentation. You can use the following Vim plugins for writing .ts:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* [leafgarland/typescript-vim](https://github.com/leafgarland/typescript-vim) provides syntax highlight.
 | 
				
			||||||
 | 
					* [Quramy/vim-js-pretty-template](https://github.com/Quramy/vim-js-pretty-template) provides syntax highlight for contents in Template Strings.
 | 
				
			||||||
 | 
					* [jason0x43/vim-js-indent](https://github.com/jason0x43/vim-js-indent) provides function of indent for both JavaScript and TypeScript.
 | 
				
			||||||
 | 
					* [Quramy/vim-dtsm](https://github.com/Quramy/vim-dtsm) provides `.d.ts` management for [dtsm](https://github.com/vvakame/dtsm) users.
 | 
				
			||||||
 | 
					* [mhartington/vim-typings](https://github.com/mhartington/vim-typings) provides `.d.ts` management for [typings](https://github.com/typings/typings) users.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## How to install
 | 
				
			||||||
 | 
					Tsuquyomi requires the following:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ [Vim](http://www.vim.org/) (vim7.4 or later)
 | 
				
			||||||
 | 
					+ [Node.js](https://nodejs.org/) & [TypeScript](https://github.com/Microsoft/TypeScript)
 | 
				
			||||||
 | 
					+ [Shougo/vimproc.vim](https://github.com/Shougo/vimproc.vim) (Not required if you use vim8 or later)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Install TypeScript
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					npm -g install typescript
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Install Tsuquyomi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Download zip.file from [here](https://github.com/Quramy/tsuquyomi/archive/master.zip), or use your favorite Vim plugin manager.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Pathogen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See https://github.com/tpope/vim-pathogen for instructions to install pathogen itself
 | 
				
			||||||
 | 
					(very simple one-line install, one-line config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					# create bundle folder if it doesn't exist
 | 
				
			||||||
 | 
					mkdir -p ~/.vim/bundle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Install and compile procvim.vim
 | 
				
			||||||
 | 
					git clone https://github.com/Shougo/vimproc.vim.git ~/.vim/bundle/vimproc.vim
 | 
				
			||||||
 | 
					pushd ~/.vim/bundle/vimproc.vim
 | 
				
			||||||
 | 
					make
 | 
				
			||||||
 | 
					popd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Install tsuquyomi
 | 
				
			||||||
 | 
					git clone https://github.com/Quramy/tsuquyomi.git ~/.vim/bundle/tsuquyomi
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### NeoBundle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you use [NeoBundle](https://github.com/Shougo/neobundle.vim) for Vim plugin management, append the following to your `.vimrc`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```vim
 | 
				
			||||||
 | 
					NeoBundle 'Shougo/vimproc.vim', {
 | 
				
			||||||
 | 
					\ 'build' : {
 | 
				
			||||||
 | 
					\     'windows' : 'tools\\update-dll-mingw',
 | 
				
			||||||
 | 
					\     'cygwin' : 'make -f make_cygwin.mak',
 | 
				
			||||||
 | 
					\     'mac' : 'make -f make_mac.mak',
 | 
				
			||||||
 | 
					\     'linux' : 'make',
 | 
				
			||||||
 | 
					\     'unix' : 'gmake',
 | 
				
			||||||
 | 
					\    },
 | 
				
			||||||
 | 
					\ }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NeoBundle 'Quramy/tsuquyomi'
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					And exec `:NeoBundleInstall`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(About vimproc installation, please see [the original install guide](https://github.com/Shougo/vimproc.vim#install).)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## How to use
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Completion
 | 
				
			||||||
 | 
					Tsuquyomi supports Omni-Completion.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					By the default, type `<C-x> <C-o>` in insert mode, Tsuquyomi shows completions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Customize completion
 | 
				
			||||||
 | 
					You can configure completion with the `completeopt` option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you don't want the popup menu:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```vim
 | 
				
			||||||
 | 
					autocmd FileType typescript setlocal completeopt-=menu
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to show a method's signature in the popup menu, set `g:tsuquyomi_completion_detail`. **Remarks: This option makes completion slow**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```vim
 | 
				
			||||||
 | 
					let g:tsuquyomi_completion_detail = 1
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to show a method's signature in the preview window when you complete this method's arguments (default):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(The preview window isn't shown when completion properties or variables)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```vim
 | 
				
			||||||
 | 
					autocmd FileType typescript setlocal completeopt+=menu,preview
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Navigations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Definition
 | 
				
			||||||
 | 
					Type `<C-]>` in normal mode or visual mode, Tsuquyomi navigates to the location where the symbol under the cursor is defined.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Alternatively, call the Ex command `:TsuquyomiDefinition` or `:TsuDefinition`.
 | 
				
			||||||
 | 
					(All Tsuquyomi's commands have aliases with short prefix `'Tsu'`.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					And type `<C-t>` , Tsuquyomi moves the cursor to the location where the last `<C-]>` was typed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Type Definition
 | 
				
			||||||
 | 
					`:TsuTypeDefinition` command is similar to `:TsuDefinition`. `:TsuTypeDefinition` navigates to the location where the type of the symbol under the cursor is defined.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### References
 | 
				
			||||||
 | 
					Type `<C-^>` in normal mode or visual mode, Tsuquyomi shows a list of location where the symbol under the cursor is referenced.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Alternatively, call the Ex command `:TsuReferences`. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want where an interface is implemented, use `:TsuImplementation`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Keyword search
 | 
				
			||||||
 | 
					Call the Ex command `:TsuSearch {keyword}` to get the list of locations which contain the keyword. This command searches the keyword from opened or referenced files in your project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The search term minimum length can be configured with `let g:tsuquyomi_search_term_min_length = 3`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Disable default mappings
 | 
				
			||||||
 | 
					If you do not want to use the above key mappings please add `let g:tsuquyomi_disable_default_mappings = 1` to your `.vimrc` file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Show compile errors
 | 
				
			||||||
 | 
					When a buffer is saved, Tsuquyomi checks syntax and semantics. Alternatively call the Ex command `:TsuGeterr`.
 | 
				
			||||||
 | 
					And if it contains errors, Tsuquyomi shows them to Vim quickfix window.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If your use TypeScript v1.6.0 or later, you can use `:TsuGeterrProject` command.
 | 
				
			||||||
 | 
					This command shows all compilation errors contained in your project to quickfix window.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Quick fix
 | 
				
			||||||
 | 
					If the cursor is on an error and TypeScript's LanguageService has a code fix for this error, call `:TsuQuickFix`.
 | 
				
			||||||
 | 
					The code fix will be applied.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Configure compile options
 | 
				
			||||||
 | 
					Make [tsconfig.json](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```json
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "compilerOptions": {
 | 
				
			||||||
 | 
					    "noImplicitAny": true,
 | 
				
			||||||
 | 
					    "target": "es5",
 | 
				
			||||||
 | 
					    "module": "commonjs"
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When you change tsconfig.json after opening `*.ts` files, you should exec `:TsuquyomiReloadProject` command.
 | 
				
			||||||
 | 
					So, the changes of tsconfig.json are reflected in the TSServer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Integrate with syntastic
 | 
				
			||||||
 | 
					If you use [syntastic](https://github.com/scrooloose/syntastic), you can use syntastic for displaying syntax and semantics errors instead of vim's default quickfix window. To integrate syntastic, write the following setting to your .vimrc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```vim
 | 
				
			||||||
 | 
					let g:tsuquyomi_disable_quickfix = 1
 | 
				
			||||||
 | 
					let g:syntastic_typescript_checkers = ['tsuquyomi'] " You shouldn't use 'tsc' checker.
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					syntastic has default TypeScript checker whose name is 'tsc'. You shouldn't use it with running Tusuquyomi because they don't share compile options.
 | 
				
			||||||
 | 
					Tusuquyomi's checker whose name is 'tsuquyomi' uses tsserver and your tsconfig.json.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Refactor
 | 
				
			||||||
 | 
					#### Rename symbols
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Using the command `:TsuRenameSymbol`, you can rename the identifier under the cursor to a new name.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to rename identifiers including in comments, you can use `:TsuRenameSymbolC` command.
 | 
				
			||||||
 | 
					For example, this command is useful when you want rename `opt` in the following code: 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```typescript
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* @param opt
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					**/
 | 
				
			||||||
 | 
					var someFunc = (opt: any) => {...};
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This feature does not have the default key mapping.
 | 
				
			||||||
 | 
					If you need, configure your `.vimrc` . For example: 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```vim
 | 
				
			||||||
 | 
					autocmd FileType typescript nmap <buffer> <Leader>e <Plug>(TsuquyomiRenameSymbol)
 | 
				
			||||||
 | 
					autocmd FileType typescript nmap <buffer> <Leader>E <Plug>(TsuquyomiRenameSymbolC)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Tooltip
 | 
				
			||||||
 | 
					Tsuquyomi can display tooltip window about symbol under the mouse cursor. If you want to use this feature, configure `.vimrc` as follows:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```vim
 | 
				
			||||||
 | 
					set ballooneval
 | 
				
			||||||
 | 
					autocmd FileType typescript setlocal balloonexpr=tsuquyomi#balloonexpr()
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `ballonexpr` option is not available in terminal Vim. So, Tsuquyomi also provides a tooltip function `tsuquyomi#hint()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```vim
 | 
				
			||||||
 | 
					autocmd FileType typescript nmap <buffer> <Leader>t : <C-u>echo tsuquyomi#hint()<CR>
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above example works in terminal Vim.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Unite sources
 | 
				
			||||||
 | 
					Tsuquyomi provides some [unite](https://github.com/Shougo/unite.vim) sources.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Show project information(a source of unite)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Execute the following command, your project information is displayed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```vim
 | 
				
			||||||
 | 
					:Unite tsproject
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The project information contains: 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* tsconfig.json which the current buffer use.
 | 
				
			||||||
 | 
					* .ts(or .tsx) source files which TypeScript compiles. These files are determined by tsconfig.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This feature requires TypeScript@1.6.0 or later.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					#### Show outline(an extension of unite-outline)
 | 
				
			||||||
 | 
					This feature requires Vim plugins:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* [unite-outline](https://github.com/Shougo/unite-outline).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you have installed these plugins, calling the following Ex command, the outline of the current buffer is displayed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```vim
 | 
				
			||||||
 | 
					:Unite outline
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Use TypeScript installed locally
 | 
				
			||||||
 | 
					By the default, Tsuquyomi searches locally installed TypeScript. If not hit, Tsuquyomi uses TypeScript installed globally.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					And execute the following command, you can confirm the path of tsserver:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```vim
 | 
				
			||||||
 | 
					:echo tsuquyomi#config#tsscmd()
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Create es6 import declaration
 | 
				
			||||||
 | 
					**It's highly experimental**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example, if your buffer is the following state:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					readFile('hoge', 'utf-8', (err, content) => {
 | 
				
			||||||
 | 
					  if(!err) console.log(content);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Move cursor onto `readFile` and call `:TsuImport`, so Tsuquyomi appends the import declaration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					import { readFile } from 'fs';
 | 
				
			||||||
 | 
					readFile('hoge', 'utf-8', (err, content) => {
 | 
				
			||||||
 | 
					  if(!err) console.log(content);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To allow Tsuquyomi to import the shortest path instead of the complete one (where the initial module declaration is) one, put this in your .vimrc:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					let g:tsuquyomi_shortest_import_path = 1
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example, if your project has the following 2 files, the plugin will use: `import { foo } from './lib';` instead of: `import { foo } from './lib/foo';`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					/* lib/index.ts */
 | 
				
			||||||
 | 
					export * from './foo';
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					/* lib/foo.ts */
 | 
				
			||||||
 | 
					export const foo = 'FOO'
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### More details
 | 
				
			||||||
 | 
					If you want more details, please see [doc](doc/tsuquyomi.txt).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Contribute
 | 
				
			||||||
 | 
					### How to test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Prepare test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```sh
 | 
				
			||||||
 | 
					cd test/
 | 
				
			||||||
 | 
					yarn install
 | 
				
			||||||
 | 
					cd ..
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Run test cases
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```sh
 | 
				
			||||||
 | 
					# Run all test cases with all supported TypeScript version
 | 
				
			||||||
 | 
					./runtest-all-ts.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run all test cases with the latest TypeScript version
 | 
				
			||||||
 | 
					./runtest.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run all test cases with the specified TypeScript version
 | 
				
			||||||
 | 
					VERSION=2.3 ./runtest.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run a test file
 | 
				
			||||||
 | 
					./run-one-test.sh test/path/to/test.spec.vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run a test file with the specified TypeScript version
 | 
				
			||||||
 | 
					VERSION=2.3 ./run-one-test.sh
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## License
 | 
				
			||||||
 | 
					MIT
 | 
				
			||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								@ -0,0 +1,165 @@
 | 
				
			|||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					" FILE: bufManager.vim
 | 
				
			||||||
 | 
					" AUTHOR: Quramy <yosuke.kurami@gmail.com>
 | 
				
			||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:save_cpo = &cpo
 | 
				
			||||||
 | 
					set cpo&vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:buf_info_map = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:normalize(buf_name)
 | 
				
			||||||
 | 
					  return substitute(a:buf_name, '\\', '/', 'g')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#normalizePath(buf_name)
 | 
				
			||||||
 | 
					  return s:normalize(a:buf_name)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#open(file_name)
 | 
				
			||||||
 | 
					  if bufnr(a:file_name) == -1
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let info = {
 | 
				
			||||||
 | 
					        \'is_opened': 1,
 | 
				
			||||||
 | 
					        \'is_dirty': 0,
 | 
				
			||||||
 | 
					        \'bufname': a:file_name,
 | 
				
			||||||
 | 
					        \'nav_def_stack': []
 | 
				
			||||||
 | 
					        \}
 | 
				
			||||||
 | 
					  let s:buf_info_map[s:normalize(a:file_name)] = info
 | 
				
			||||||
 | 
					  return info
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#isNotOpenable(file_name)
 | 
				
			||||||
 | 
					  if (match(a:file_name, '^[^\/]*:\/\/') + 1) && !(match(a:file_name, '^file:\/\/') + 1)
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#openedFiles()
 | 
				
			||||||
 | 
					  return filter(copy(s:buf_info_map), 'v:val.is_opened')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#clearMap()
 | 
				
			||||||
 | 
					  let s:buf_info_map = {}
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#bufName(file_name)
 | 
				
			||||||
 | 
					  let name = s:normalize(a:file_name)
 | 
				
			||||||
 | 
					  if !has_key(s:buf_info_map, name)
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return s:buf_info_map[name].bufname
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#close(file_name)
 | 
				
			||||||
 | 
					  let name = s:normalize(a:file_name)
 | 
				
			||||||
 | 
					  if !has_key(s:buf_info_map, name)
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let s:buf_info_map[name].is_opened = 0
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#isOpened(file_name)
 | 
				
			||||||
 | 
					  let name = s:normalize(a:file_name)
 | 
				
			||||||
 | 
					  if !has_key(s:buf_info_map, name)
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return s:buf_info_map[name].is_opened
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#setDirty(file_name, state)
 | 
				
			||||||
 | 
					  let name = s:normalize(a:file_name)
 | 
				
			||||||
 | 
					  if !has_key(s:buf_info_map, name)
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let s:buf_info_map[name].is_dirty = a:state
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#isDirty(file_name)
 | 
				
			||||||
 | 
					  let name = s:normalize(a:file_name)
 | 
				
			||||||
 | 
					  if !has_key(s:buf_info_map, name)
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return s:buf_info_map[name].is_dirty
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#whichDirty(file_name_list)
 | 
				
			||||||
 | 
					  let result = []
 | 
				
			||||||
 | 
					  for file_name in a:file_name_list
 | 
				
			||||||
 | 
					    if tsuquyomi#bufManager#isDirty(file_name)
 | 
				
			||||||
 | 
					      call add(result, file_name)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return result
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#tmpfile(file_name)
 | 
				
			||||||
 | 
					  let name = s:normalize(a:file_name)
 | 
				
			||||||
 | 
					  if !has_key(s:buf_info_map, name)
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  if !has_key(s:buf_info_map[name], 'tmpfile')
 | 
				
			||||||
 | 
					    let tmpfile = tempname()
 | 
				
			||||||
 | 
					    let s:buf_info_map[name].tmpfile = tmpfile
 | 
				
			||||||
 | 
					    return tmpfile
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return s:buf_info_map[name].tmpfile
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#saveTmp(file_name)
 | 
				
			||||||
 | 
					  let tmpfile = tsuquyomi#bufManager#tmpfile(a:file_name)
 | 
				
			||||||
 | 
					  call writefile(getbufline(a:file_name, 1, '$'), tmpfile)
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#pushNavDef(file_name, loc)
 | 
				
			||||||
 | 
					  let name = s:normalize(a:file_name)
 | 
				
			||||||
 | 
					  if !has_key(s:buf_info_map, name)
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  call add(s:buf_info_map[name].nav_def_stack, a:loc)
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#popNavDef(file_name)
 | 
				
			||||||
 | 
					  let name = s:normalize(a:file_name)
 | 
				
			||||||
 | 
					  if !has_key(s:buf_info_map, name)
 | 
				
			||||||
 | 
					    return {}
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  if len(s:buf_info_map[name].nav_def_stack)
 | 
				
			||||||
 | 
					    return remove(s:buf_info_map[name].nav_def_stack, -1)
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return {}
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:win_nav_map = {}
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#winPushNavDef(winnm, file_name, loc)
 | 
				
			||||||
 | 
					  if !has_key(s:win_nav_map, a:winnm)
 | 
				
			||||||
 | 
					    let s:win_nav_map[a:winnm] = []
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  call add(s:win_nav_map[a:winnm], {'file_name': a:file_name, 'loc': a:loc})
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#bufManager#winPopNavDef(winnm)
 | 
				
			||||||
 | 
					  if !has_key(s:win_nav_map, a:winnm)
 | 
				
			||||||
 | 
					    return [0, {}]
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  if !len(s:win_nav_map[a:winnm])
 | 
				
			||||||
 | 
					    return [0, {}]
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return [1, remove(s:win_nav_map[a:winnm], -1)]
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let &cpo = s:save_cpo
 | 
				
			||||||
 | 
					unlet s:save_cpo
 | 
				
			||||||
@ -0,0 +1,320 @@
 | 
				
			|||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					" FILE: autoload/tsuquyomi/config.vim
 | 
				
			||||||
 | 
					" AUTHOR: Quramy <yosuke.kurami@gmail.com>
 | 
				
			||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:save_cpo = &cpo
 | 
				
			||||||
 | 
					set cpo&vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					let s:P = s:V.import('ProcessManager')
 | 
				
			||||||
 | 
					let s:Process = s:V.import('Process')
 | 
				
			||||||
 | 
					let s:Prelude = s:V.import('Prelude')
 | 
				
			||||||
 | 
					let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					let s:script_dir = expand('<sfile>:p:h')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:tss_cmd = ''
 | 
				
			||||||
 | 
					let s:tss_version = {'is_valid': 0, 'out': '???'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:is_vim8 = has('patch-8.0.1')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#config#preconfig()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if !exists('g:tsuquyomi_is_available')
 | 
				
			||||||
 | 
					    if !s:is_vim8 && !s:P.is_available()
 | 
				
			||||||
 | 
					      " 1. vimproc or vim8 installation check
 | 
				
			||||||
 | 
					      let g:tsuquyomi_is_available = 0
 | 
				
			||||||
 | 
					      call s:deleteCommand()
 | 
				
			||||||
 | 
					      echom '[Tsuquyomi] Shougo/vimproc.vim or vim8 is not installed. Please install it.'
 | 
				
			||||||
 | 
					      return 0
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      " 2. tsserver installation check
 | 
				
			||||||
 | 
					      let s:tss_cmd = tsuquyomi#config#tsscmd()
 | 
				
			||||||
 | 
					      if s:tss_cmd == ''
 | 
				
			||||||
 | 
					        let g:tsuquyomi_is_available = 0
 | 
				
			||||||
 | 
					        call s:deleteCommand()
 | 
				
			||||||
 | 
					        return 0
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      " 3. TypeScript version check
 | 
				
			||||||
 | 
					      call tsuquyomi#config#getVersion()
 | 
				
			||||||
 | 
					      if !s:tss_version.is_valid
 | 
				
			||||||
 | 
					        let g:tsuquyomi_is_available = 0
 | 
				
			||||||
 | 
					        call s:deleteCommand()
 | 
				
			||||||
 | 
					        echom '[Tsuquyomi] Your TypeScript version is invalid. '.s:tss_version.out
 | 
				
			||||||
 | 
					        return 0
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      if !tsuquyomi#config#isHigher(150)
 | 
				
			||||||
 | 
					        let g:tsuquyomi_is_available = 0
 | 
				
			||||||
 | 
					        call s:deleteCommand()
 | 
				
			||||||
 | 
					        echom '[Tsuquyomi] tsuquyomi requires typescript@~1.5.0'
 | 
				
			||||||
 | 
					        return 0
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      let g:tsuquyomi_is_available = 1
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return g:tsuquyomi_is_available
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:deleteCommand()
 | 
				
			||||||
 | 
					  delc TsuquyomiStartServer
 | 
				
			||||||
 | 
					  delc TsuStartServer
 | 
				
			||||||
 | 
					  delc TsuquyomiStopServer
 | 
				
			||||||
 | 
					  delc TsuStopServer
 | 
				
			||||||
 | 
					  delc TsuquyomiStatusServer
 | 
				
			||||||
 | 
					  delc TsuStatusServer
 | 
				
			||||||
 | 
					  delc TsuquyomiReloadProject
 | 
				
			||||||
 | 
					  delc TsuReloadProject
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#config#tssargs()
 | 
				
			||||||
 | 
					  let args = []
 | 
				
			||||||
 | 
					  call add(args, '--locale '.g:tsuquyomi_locale)
 | 
				
			||||||
 | 
					  return join(args, ' ')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Search from cwd upward looking for first directory with package.json
 | 
				
			||||||
 | 
					function! tsuquyomi#config#_path2project_directory_ts()
 | 
				
			||||||
 | 
					  let parent = getcwd()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while 1
 | 
				
			||||||
 | 
					    let path = parent . '/package.json'
 | 
				
			||||||
 | 
					    if filereadable(path)
 | 
				
			||||||
 | 
					      return parent
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    let next = fnamemodify(parent, ':h')
 | 
				
			||||||
 | 
					    if next == parent
 | 
				
			||||||
 | 
					      return ''
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    let parent = next
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#config#tsscmd()
 | 
				
			||||||
 | 
					  if s:tss_cmd !=# ''
 | 
				
			||||||
 | 
					    return s:tss_cmd
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  if g:tsuquyomi_use_local_typescript != 0
 | 
				
			||||||
 | 
					    let l:prj_dir = tsuquyomi#config#_path2project_directory_ts()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if l:prj_dir == ''
 | 
				
			||||||
 | 
					      " Fallback to generic project root search
 | 
				
			||||||
 | 
					      let l:prj_dir = s:Prelude.path2project_directory(getcwd(), 1)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if l:prj_dir !=# ''
 | 
				
			||||||
 | 
					      let l:searched_tsserver_path = s:Filepath.join(l:prj_dir, 'node_modules/typescript/bin/tsserver')
 | 
				
			||||||
 | 
					      if filereadable(l:searched_tsserver_path)
 | 
				
			||||||
 | 
					        return g:tsuquyomi_nodejs_path.' "'.l:searched_tsserver_path.'"'
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  if g:tsuquyomi_use_dev_node_module == 0
 | 
				
			||||||
 | 
					    let l:cmd = 'tsserver'
 | 
				
			||||||
 | 
					    if has('win32') || has('win64')
 | 
				
			||||||
 | 
					      let l:cmd .= '.cmd'
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if !executable(l:cmd)
 | 
				
			||||||
 | 
					      echom '[Tsuquyomi] tsserver is not installed. Try "npm -g install typescript".'
 | 
				
			||||||
 | 
					      return ''
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    if g:tsuquyomi_use_dev_node_module == 1
 | 
				
			||||||
 | 
					      let l:path = s:Filepath.join(s:script_dir, '../../node_modules/typescript/bin/tsserver')
 | 
				
			||||||
 | 
					    elseif g:tsuquyomi_use_dev_node_module == 2
 | 
				
			||||||
 | 
					      let l:path = g:tsuquyomi_tsserver_path
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      echom '[Tsuquyomi] Invalid option value "g:tsuquyomi_use_dev_node_module".'
 | 
				
			||||||
 | 
					      return ''
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if (has('win32') || has('win64')) && l:path !~ '\.cmd$'
 | 
				
			||||||
 | 
					      let l:path .= '.cmd'
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if filereadable(l:path) != 1
 | 
				
			||||||
 | 
					      echom '[Tsuquyomi] tsserver.js does not exist. Try "npm install"., '.l:path
 | 
				
			||||||
 | 
					      return ''
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if !s:is_vim8
 | 
				
			||||||
 | 
					      let l:cmd = g:tsuquyomi_nodejs_path.' "'.l:path.'"'
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let l:cmd = g:tsuquyomi_nodejs_path.' '.l:path
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return l:cmd
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#config#getVersion()
 | 
				
			||||||
 | 
					  if s:tss_version.is_valid
 | 
				
			||||||
 | 
					    return s:tss_version
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let l:cmd = substitute(tsuquyomi#config#tsscmd(), 'tsserver', 'tsc', '')
 | 
				
			||||||
 | 
					  let l:cmd = substitute(l:cmd, "\\", "/", "g")
 | 
				
			||||||
 | 
					  let out = s:Process.system(l:cmd.' --version')
 | 
				
			||||||
 | 
					  let pattern = '\vVersion\s+(\d+)\.(\d+)\.(\d+)-?([^\.\n\s]*)'
 | 
				
			||||||
 | 
					  let matched = matchlist(out, pattern)
 | 
				
			||||||
 | 
					  if !len(matched)
 | 
				
			||||||
 | 
					    let s:tss_version = {'is_valid': 0, 'out': out}
 | 
				
			||||||
 | 
					    return s:tss_version
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let [major, minor, patch] = [str2nr(matched[1]), str2nr(matched[2]), str2nr(matched[3])]
 | 
				
			||||||
 | 
					  let s:tss_version = {
 | 
				
			||||||
 | 
					        \ 'is_valid': 1,
 | 
				
			||||||
 | 
					        \ 'major': major, 'minor': minor, 'patch': patch,
 | 
				
			||||||
 | 
					        \ 'channel': matched[4],
 | 
				
			||||||
 | 
					        \ }
 | 
				
			||||||
 | 
					  return s:tss_version
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#config#isHigher(target)
 | 
				
			||||||
 | 
					  if !s:tss_version.is_valid
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let numeric_version = s:tss_version.major * 100 + s:tss_version.minor * 10 + s:tss_version.patch
 | 
				
			||||||
 | 
					  return numeric_version >= a:target
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#config#createBufLocalCommand()
 | 
				
			||||||
 | 
					  command! -buffer -nargs=* -complete=buffer TsuquyomiOpen    :call tsuquyomi#open(<f-args>)
 | 
				
			||||||
 | 
					  command! -buffer -nargs=* -complete=buffer TsuOpen          :call tsuquyomi#open(<f-args>)
 | 
				
			||||||
 | 
					  command! -buffer -nargs=* -complete=buffer TsuquyomiClose   :call tsuquyomi#close(<f-args>)
 | 
				
			||||||
 | 
					  command! -buffer -nargs=* -complete=buffer TsuClose         :call tsuquyomi#close(<f-args>)
 | 
				
			||||||
 | 
					  command! -buffer -nargs=* -complete=buffer TsuquyomiReload  :call tsuquyomi#reload(<f-args>)
 | 
				
			||||||
 | 
					  command! -buffer -nargs=* -complete=buffer TsuReload        :call tsuquyomi#reload(<f-args>)
 | 
				
			||||||
 | 
					  command! -buffer -nargs=* -complete=buffer TsuquyomiDump    :call tsuquyomi#dump(<f-args>)
 | 
				
			||||||
 | 
					  command! -buffer -nargs=* -complete=buffer TsuDump          :call tsuquyomi#dump(<f-args>)
 | 
				
			||||||
 | 
					  command! -buffer -nargs=1 TsuquyomiSearch                   :call tsuquyomi#navtoByLoclistContain(<f-args>)
 | 
				
			||||||
 | 
					  command! -buffer -nargs=1 TsuSearch                         :call tsuquyomi#navtoByLoclistContain(<f-args>)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiDefinition      :call tsuquyomi#definition()
 | 
				
			||||||
 | 
					  command! -buffer TsuDefinition            :call tsuquyomi#definition()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiSplitDefinition :call tsuquyomi#splitDefinition()
 | 
				
			||||||
 | 
					  command! -buffer TsuSplitDefinition       :call tsuquyomi#splitDefinition()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiGoBack          :call tsuquyomi#goBack()
 | 
				
			||||||
 | 
					  command! -buffer TsuGoBack                :call tsuquyomi#goBack()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiImplementation  :call tsuquyomi#implementation()
 | 
				
			||||||
 | 
					  command! -buffer TsuImplementation        :call tsuquyomi#implementation()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiReferences      :call tsuquyomi#references()
 | 
				
			||||||
 | 
					  command! -buffer TsuReferences            :call tsuquyomi#references()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiTypeDefinition  :call tsuquyomi#typeDefinition()
 | 
				
			||||||
 | 
					  command! -buffer TsuTypeDefinition        :call tsuquyomi#typeDefinition()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiGeterr          :call tsuquyomi#geterr()
 | 
				
			||||||
 | 
					  command! -buffer TsuGeterr                :call tsuquyomi#geterr()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiGeterrProject   :call tsuquyomi#geterrProject()
 | 
				
			||||||
 | 
					  command! -buffer TsuGeterrProject         :call tsuquyomi#geterrProject()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiRenameSymbol    :call tsuquyomi#renameSymbol()
 | 
				
			||||||
 | 
					  command! -buffer TsuRenameSymbol          :call tsuquyomi#renameSymbol()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiRenameSymbolC   :call tsuquyomi#renameSymbolWithComments()
 | 
				
			||||||
 | 
					  command! -buffer TsuRenameSymbolC         :call tsuquyomi#renameSymbolWithComments()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiQuickFix        :call tsuquyomi#quickFix()
 | 
				
			||||||
 | 
					  command! -buffer TsuQuickFix              :call tsuquyomi#quickFix()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiSignatureHelp   :call tsuquyomi#signatureHelp()
 | 
				
			||||||
 | 
					  command! -buffer TsuSignatureHelp         :call tsuquyomi#signatureHelp()
 | 
				
			||||||
 | 
					  command! -buffer TsuAsyncGeterr           :call tsuquyomi#asyncGeterr()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiAsyncGeterr     :call tsuquyomi#asyncGeterr()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  " TODO These commands don't work correctly.
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiRenameSymbolS   :call tsuquyomi#renameSymbolWithStrings()
 | 
				
			||||||
 | 
					  command! -buffer TsuRenameSymbolS         :call tsuquyomi#renameSymbolWithStrings()
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiRenameSymbolCS  :call tsuquyomi#renameSymbolWithCommentsStrings()
 | 
				
			||||||
 | 
					  command! -buffer TsuRenameSymbolCS        :call tsuquyomi#renameSymbolWithCommentsStrings()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  command! -buffer TsuquyomiImport          :call tsuquyomi#es6import#complete()
 | 
				
			||||||
 | 
					  command! -buffer TsuImport                :call tsuquyomi#es6import#complete()
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#config#createBufLocalMap()
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiDefinition)      :TsuquyomiDefinition <CR>
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiSplitDefinition) :TsuquyomiSplitDefinition <CR>
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiTypeDefinition)  :TsuquyomiTypeDefinition <CR>
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiGoBack)          :TsuquyomiGoBack <CR>
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiImplementation)  :TsuquyomiImplementation <CR>
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiReferences)      :TsuquyomiReferences <CR>
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiRenameSymbol)    :TsuquyomiRenameSymbol <CR>
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiRenameSymbolC)   :TsuquyomiRenameSymbolC <CR>
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiQuickFix)        :TsuquyomiQuickFix <CR>
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiSignatureHelp)   :TsuquyomiSignatureHelp <CR>
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiImport)          :TsuquyomiImport <CR>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  " TODO These commands don't work correctly.
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiRenameSymbolS)   :TsuquyomiRenameSymbolS <CR>
 | 
				
			||||||
 | 
					  noremap <silent> <buffer> <Plug>(TsuquyomiRenameSymbolCS)  :TsuquyomiRenameSymbolCS <CR>
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#config#applyBufLocalDefaultMap()
 | 
				
			||||||
 | 
					  if(!exists('g:tsuquyomi_disable_default_mappings'))
 | 
				
			||||||
 | 
					    if !hasmapto('<Plug>(TsuquyomiDefinition)')
 | 
				
			||||||
 | 
					        map <buffer> <C-]> <Plug>(TsuquyomiDefinition)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if !hasmapto('<Plug>(TsuquyomiSplitDefinition)')
 | 
				
			||||||
 | 
					        map <buffer> <C-W>] <Plug>(TsuquyomiSplitDefinition)
 | 
				
			||||||
 | 
					        map <buffer> <C-W><C-]> <Plug>(TsuquyomiSplitDefinition)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if !hasmapto('<Plug>(TsuquyomiGoBack)')
 | 
				
			||||||
 | 
					        map <buffer> <C-t> <Plug>(TsuquyomiGoBack)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if !hasmapto('<Plug>(TsuquyomiReferences)')
 | 
				
			||||||
 | 
					        map <buffer> <C-^> <Plug>(TsuquyomiReferences)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:autocmd_patterns = []
 | 
				
			||||||
 | 
					function! tsuquyomi#config#applyBufLocalAutocmd(pattern)
 | 
				
			||||||
 | 
					  if index(s:autocmd_patterns, a:pattern) == -1
 | 
				
			||||||
 | 
					    call add(s:autocmd_patterns, a:pattern)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let all_patterns = join(s:autocmd_patterns, ",")
 | 
				
			||||||
 | 
					  if !g:tsuquyomi_disable_quickfix
 | 
				
			||||||
 | 
					    augroup tsuquyomi_geterr
 | 
				
			||||||
 | 
					      autocmd!
 | 
				
			||||||
 | 
					      execute 'autocmd BufWritePost '.all_patterns.' silent! call tsuquyomi#reloadAndGeterr()'
 | 
				
			||||||
 | 
					    augroup END
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  augroup tsuquyomi_defaults
 | 
				
			||||||
 | 
					    autocmd!
 | 
				
			||||||
 | 
					    autocmd BufWinEnter * silent! call tsuquyomi#setPreviewOption()
 | 
				
			||||||
 | 
					    execute 'autocmd TextChanged,TextChangedI '.all_patterns.' silent! call tsuquyomi#letDirty()'
 | 
				
			||||||
 | 
					  augroup END
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#config#applyBufLocalFunctions()
 | 
				
			||||||
 | 
					  setlocal omnifunc=tsuquyomi#complete
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if exists('+bexpr')
 | 
				
			||||||
 | 
					    setlocal bexpr=tsuquyomi#balloonexpr()
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#config#registerInitialCallback()
 | 
				
			||||||
 | 
					  call tsuquyomi#tsClient#registerCallback('tsuquyomi#tsClient#readDiagnostics', 'diagnostics')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:async_initialized = 0
 | 
				
			||||||
 | 
					function! tsuquyomi#config#initBuffer(opt)
 | 
				
			||||||
 | 
					  if !has_key(a:opt, 'pattern')
 | 
				
			||||||
 | 
					    echom '[Tsuquyomi] missing options. "pattern"'
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let pattern = a:opt.pattern
 | 
				
			||||||
 | 
					  call tsuquyomi#config#createBufLocalCommand()
 | 
				
			||||||
 | 
					  call tsuquyomi#config#createBufLocalMap()
 | 
				
			||||||
 | 
					  call tsuquyomi#config#applyBufLocalDefaultMap()
 | 
				
			||||||
 | 
					  call tsuquyomi#config#applyBufLocalAutocmd(pattern)
 | 
				
			||||||
 | 
					  call tsuquyomi#config#applyBufLocalFunctions()
 | 
				
			||||||
 | 
					  if g:tsuquyomi_auto_open
 | 
				
			||||||
 | 
					    silent! call tsuquyomi#open()
 | 
				
			||||||
 | 
					    silent! call tsuquyomi#sendConfigure()
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  if s:is_vim8 && g:tsuquyomi_use_vimproc == 0 && s:async_initialized == 0
 | 
				
			||||||
 | 
					    call tsuquyomi#config#registerInitialCallback()
 | 
				
			||||||
 | 
					    let s:async_initialized = 1
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let &cpo = s:save_cpo
 | 
				
			||||||
 | 
					unlet s:save_cpo
 | 
				
			||||||
@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					" FILE: perfLogger.vim
 | 
				
			||||||
 | 
					" AUTHOR: Quramy <yosuke.kurami@gmail.com>
 | 
				
			||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:log_buffer = []
 | 
				
			||||||
 | 
					let s:start_time = reltime()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#perfLogger#reset()
 | 
				
			||||||
 | 
					  let s:log_buffer = []
 | 
				
			||||||
 | 
					  let s:start_time = reltime()
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#perfLogger#getTime()
 | 
				
			||||||
 | 
					  let num_row = len(s:log_buffer)
 | 
				
			||||||
 | 
					  let j = len(s:log_buffer) - num_row + 1
 | 
				
			||||||
 | 
					  while j < num_row
 | 
				
			||||||
 | 
					    let t = s:log_buffer[j]
 | 
				
			||||||
 | 
					    let prev = s:log_buffer[j - 1]
 | 
				
			||||||
 | 
					    echo reltimestr(t.elapse) t.name reltimestr(reltime(prev.elapse, t.elapse))
 | 
				
			||||||
 | 
					    let j = j + 1
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#perfLogger#record(event_name)
 | 
				
			||||||
 | 
					  if g:tsuquyomi_debug
 | 
				
			||||||
 | 
					    call add(s:log_buffer, {'name': a:event_name, 'elapse': reltime(s:start_time)})
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,940 @@
 | 
				
			|||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					" FILE: tsuquyomi.vim
 | 
				
			||||||
 | 
					" AUTHOR: Quramy <yosuke.kurami@gmail.com>
 | 
				
			||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:save_cpo = &cpo
 | 
				
			||||||
 | 
					set cpo&vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if !tsuquyomi#config#preconfig()
 | 
				
			||||||
 | 
					  finish
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:script_dir = expand('<sfile>:p:h')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					let s:JSON = s:V.import('Web.JSON')
 | 
				
			||||||
 | 
					let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:is_vim8 = !has('nvim') && has('patch-8.0.1')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if !s:is_vim8 || g:tsuquyomi_use_vimproc
 | 
				
			||||||
 | 
					  let s:P = s:V.import('ProcessManager')
 | 
				
			||||||
 | 
					  let s:tsq = 'tsuquyomiTSServer'
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  let s:tsq = {'job':0}
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:request_seq = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:ignore_response_conditions = []
 | 
				
			||||||
 | 
					" ignore events configFileDiag triggered by reload event. See also #99
 | 
				
			||||||
 | 
					call add(s:ignore_response_conditions, '"type":"event","event":"configFileDiag"')
 | 
				
			||||||
 | 
					call add(s:ignore_response_conditions, '"type":"event","event":"telemetry"')
 | 
				
			||||||
 | 
					call add(s:ignore_response_conditions, '"type":"event","event":"projectsUpdatedInBackground"')
 | 
				
			||||||
 | 
					call add(s:ignore_response_conditions, '"type":"event","event":"typingsInstallerPid"')
 | 
				
			||||||
 | 
					call add(s:ignore_response_conditions, 'npm notice created a lockfile')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" ### Async variables
 | 
				
			||||||
 | 
					let s:callbacks = {}
 | 
				
			||||||
 | 
					let s:notify_callback = {}
 | 
				
			||||||
 | 
					let s:quickfix_list = []
 | 
				
			||||||
 | 
					" ### }}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" ### Utilites {{{
 | 
				
			||||||
 | 
					function! s:error(msg)
 | 
				
			||||||
 | 
					  echoerr (a:msg)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:debugLog(msg)
 | 
				
			||||||
 | 
					  if g:tsuquyomi_debug
 | 
				
			||||||
 | 
					    echom a:msg
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" ### Utilites }}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" ### Core Functions {{{
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" If not exsiting process of TSServer, create it.
 | 
				
			||||||
 | 
					function! s:startTssVimproc()
 | 
				
			||||||
 | 
					  if s:P.state(s:tsq) == 'existing'
 | 
				
			||||||
 | 
					    return 'existing'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let l:cmd = substitute(tsuquyomi#config#tsscmd(), '\\', '\\\\', 'g').' '.tsuquyomi#config#tssargs()
 | 
				
			||||||
 | 
					  let l:is_new = s:P.touch(s:tsq, l:cmd)
 | 
				
			||||||
 | 
					  if l:is_new == 'new'
 | 
				
			||||||
 | 
					    let [out, err, type] = s:P.read_wait(s:tsq, 0.1, [])
 | 
				
			||||||
 | 
					    let st = tsuquyomi#tsClient#statusTss()
 | 
				
			||||||
 | 
					    if !g:tsuquyomi_tsserver_debug
 | 
				
			||||||
 | 
					      if err != ''
 | 
				
			||||||
 | 
					        call s:error('Fail to start TSServer... '.err)
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return l:is_new
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:startTssVim8()
 | 
				
			||||||
 | 
					  if type(s:tsq['job']) == 8 && job_info(s:tsq['job']).status == 'run'
 | 
				
			||||||
 | 
					    return 'existing'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let l:cmd = substitute(tsuquyomi#config#tsscmd(), '\\', '\\\\', 'g').' '.tsuquyomi#config#tssargs()
 | 
				
			||||||
 | 
					  try
 | 
				
			||||||
 | 
					    let s:tsq['job'] = job_start(l:cmd, {
 | 
				
			||||||
 | 
					      \ 'out_cb': {ch, msg -> tsuquyomi#tsClient#handleMessage(ch, msg)},
 | 
				
			||||||
 | 
					      \ })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let s:tsq['channel'] = job_getchannel(s:tsq['job'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let out = ch_readraw(s:tsq['channel'])
 | 
				
			||||||
 | 
					    let st = tsuquyomi#tsClient#statusTss()
 | 
				
			||||||
 | 
					    if !g:tsuquyomi_tsserver_debug
 | 
				
			||||||
 | 
					      if err != ''
 | 
				
			||||||
 | 
					        call s:error('Fail to start TSServer... '.err)
 | 
				
			||||||
 | 
					        return 0
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  catch
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endtry
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:getEventType(item)
 | 
				
			||||||
 | 
					  if type(a:item) == v:t_dict
 | 
				
			||||||
 | 
					    \ && has_key(a:item, 'type')
 | 
				
			||||||
 | 
					    \ && a:item.type ==# 'event'
 | 
				
			||||||
 | 
					    \ && (a:item.event ==# 'syntaxDiag'
 | 
				
			||||||
 | 
					      \ || a:item.event ==# 'semanticDiag'
 | 
				
			||||||
 | 
					      \ || a:item.event ==# 'requestCompleted')
 | 
				
			||||||
 | 
					    return 'diagnostics'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return 0
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#startTss()
 | 
				
			||||||
 | 
					  if !s:is_vim8 || g:tsuquyomi_use_vimproc
 | 
				
			||||||
 | 
					    return s:startTssVimproc()
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return s:startTssVim8()
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					"Terminate TSServer process if it exsits.
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#stopTss()
 | 
				
			||||||
 | 
					  if tsuquyomi#tsClient#statusTss() != 'dead'
 | 
				
			||||||
 | 
					    if !s:is_vim8 || g:tsuquyomi_use_vimproc
 | 
				
			||||||
 | 
					      let l:res = s:P.term(s:tsq)
 | 
				
			||||||
 | 
					      return l:res
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let l:res = job_stop(s:tsq['job'])
 | 
				
			||||||
 | 
					      return l:res
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#stopTssSync() abort
 | 
				
			||||||
 | 
					  let res = tsuquyomi#tsClient#stopTss()
 | 
				
			||||||
 | 
					  call s:ensureStatus('dead')
 | 
				
			||||||
 | 
					  return res
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Wait for the status to become the argument.
 | 
				
			||||||
 | 
					" Note: It throws an error to avoid infinite loop after 1s.
 | 
				
			||||||
 | 
					function! s:ensureStatus(expected) abort
 | 
				
			||||||
 | 
					  let cnt = 0
 | 
				
			||||||
 | 
					  while v:true
 | 
				
			||||||
 | 
					    let got = tsuquyomi#tsClient#statusTss()
 | 
				
			||||||
 | 
					    if got ==# a:expected
 | 
				
			||||||
 | 
					      return
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if cnt > 100
 | 
				
			||||||
 | 
					      throw "TSServer status does not become " . a:expected . " in 1s. It is " . got . "."
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    let cnt += 1
 | 
				
			||||||
 | 
					    sleep 10m
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" RETURNS: {string} 'run' or 'dead'
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#statusTss()
 | 
				
			||||||
 | 
					  try
 | 
				
			||||||
 | 
					    if !s:is_vim8 || g:tsuquyomi_use_vimproc
 | 
				
			||||||
 | 
					      let stat = s:P.state(s:tsq)
 | 
				
			||||||
 | 
					      if stat == 'undefined'
 | 
				
			||||||
 | 
					        return 'dead'
 | 
				
			||||||
 | 
					      elseif stat == 'reading'
 | 
				
			||||||
 | 
					        return 'run'
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        return stat
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      return job_info(s:tsq['job']).status
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  catch
 | 
				
			||||||
 | 
					    return 'dead'
 | 
				
			||||||
 | 
					  endtry
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					"Read diagnostics and add to QuickList.
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" PARAM: {dict} response
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#readDiagnostics(item)
 | 
				
			||||||
 | 
					  if a:item.event == 'requestCompleted'
 | 
				
			||||||
 | 
					    if has_key(s:notify_callback, 'diagnostics')
 | 
				
			||||||
 | 
					      let Callback = function(s:notify_callback['diagnostics'], [s:quickfix_list])
 | 
				
			||||||
 | 
					      call Callback()
 | 
				
			||||||
 | 
					      let s:quickfix_list = []
 | 
				
			||||||
 | 
					      let s:request_seq = s:request_seq + 1
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    " Cache syntaxDiag and semanticDiag messages until request was completed.
 | 
				
			||||||
 | 
					    let l:qflist = tsuquyomi#parseDiagnosticEvent(a:item, [])
 | 
				
			||||||
 | 
					    let s:quickfix_list += l:qflist
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#registerNotify(callback, key)
 | 
				
			||||||
 | 
					  let s:notify_callback[a:key] = a:callback
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" Handle TSServer responses.
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#handleMessage(ch, msg)
 | 
				
			||||||
 | 
					  if type(a:msg) != 1 || a:msg == ''
 | 
				
			||||||
 | 
					    " Not a string or blank message.
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let l:res_item = substitute(a:msg, 'Content-Length: \d\+', '', 'g')
 | 
				
			||||||
 | 
					  if l:res_item == ''
 | 
				
			||||||
 | 
					    " Ignore content-length.
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  " Ignore messages.
 | 
				
			||||||
 | 
					  let l:to_be_ignored = 0
 | 
				
			||||||
 | 
					  for ignore_reg in s:ignore_response_conditions
 | 
				
			||||||
 | 
					    let l:to_be_ignored = l:to_be_ignored || (l:res_item =~ ignore_reg)
 | 
				
			||||||
 | 
					    if l:to_be_ignored
 | 
				
			||||||
 | 
					      return
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  let l:item = json_decode(l:res_item)
 | 
				
			||||||
 | 
					  let l:eventName = s:getEventType(l:item)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(has_key(s:callbacks, l:eventName))
 | 
				
			||||||
 | 
					    let Callback = function(s:callbacks[l:eventName], [l:item])
 | 
				
			||||||
 | 
					    call Callback()
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#clearCallbacks()
 | 
				
			||||||
 | 
					  let s:callbacks = {}
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#registerCallback(callback, eventName)
 | 
				
			||||||
 | 
					  let s:callbacks[a:eventName] = a:callback
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#sendAsyncRequest(line)
 | 
				
			||||||
 | 
					  if s:is_vim8 && g:tsuquyomi_use_vimproc == 0
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#startTss()
 | 
				
			||||||
 | 
					    call ch_sendraw(s:tsq['channel'], a:line . "\n")
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					"Write to stdin of tsserver proc, and return stdout.
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" PARAM: {string} line Stdin input.
 | 
				
			||||||
 | 
					" PARAM: {float} delay Wait time(sec) after request, until response.
 | 
				
			||||||
 | 
					" PARAM: {int} retry_count Retry count.
 | 
				
			||||||
 | 
					" PARAM: {int} response_length The number of JSONs contained by this response.
 | 
				
			||||||
 | 
					" RETURNS: {list<dict>} A list of response.
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#sendRequest(line, delay, retry_count, response_length)
 | 
				
			||||||
 | 
					  "call s:debugLog('called! '.a:line)
 | 
				
			||||||
 | 
					  call tsuquyomi#tsClient#startTss()
 | 
				
			||||||
 | 
					  if !s:is_vim8 || g:tsuquyomi_use_vimproc
 | 
				
			||||||
 | 
					    call s:P.writeln(s:tsq, a:line)
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    call ch_sendraw(s:tsq['channel'], a:line."\n")
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let l:retry = 0
 | 
				
			||||||
 | 
					  let response_list = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while len(response_list) < a:response_length
 | 
				
			||||||
 | 
					    if !s:is_vim8 || g:tsuquyomi_use_vimproc
 | 
				
			||||||
 | 
					      let [out, err, type] = s:P.read_wait(s:tsq, a:delay, ['Content-Length: \d\+'])
 | 
				
			||||||
 | 
					      call s:debugLog('out: '.out.', type:'.type)
 | 
				
			||||||
 | 
					      if type == 'timedout'
 | 
				
			||||||
 | 
					        let retry_delay = 0.05
 | 
				
			||||||
 | 
					        while l:retry < a:retry_count
 | 
				
			||||||
 | 
					          let [out, err, type] = s:P.read_wait(s:tsq, retry_delay, ['Content-Length: \d\+'])
 | 
				
			||||||
 | 
					          if type == 'matched'
 | 
				
			||||||
 | 
					            call tsuquyomi#perfLogger#record('tssMatched')
 | 
				
			||||||
 | 
					            "call s:debugLog('retry: '.l:retry.', length: '.len(response_list))
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
 | 
					          endif
 | 
				
			||||||
 | 
					          let l:retry = l:retry + 1
 | 
				
			||||||
 | 
					          call tsuquyomi#perfLogger#record('tssRetry:'.l:retry)
 | 
				
			||||||
 | 
					        endwhile
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let out = ch_readraw(s:tsq['channel'])
 | 
				
			||||||
 | 
					      let type = 'matched'
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if type == 'matched'
 | 
				
			||||||
 | 
					      let l:tmp1 = substitute(out, 'Content-Length: \d\+', '', 'g')
 | 
				
			||||||
 | 
					      let l:tmp2 = substitute(l:tmp1, '\r', '', 'g')
 | 
				
			||||||
 | 
					      let l:res_list = split(l:tmp2, '\n\+')
 | 
				
			||||||
 | 
					      for res_item in l:res_list
 | 
				
			||||||
 | 
					        let l:to_be_ignored = 0
 | 
				
			||||||
 | 
					        for ignore_reg in s:ignore_response_conditions + ['"type":"event","event":"requestCompleted"']
 | 
				
			||||||
 | 
					          let l:to_be_ignored = l:to_be_ignored || (res_item =~ ignore_reg)
 | 
				
			||||||
 | 
					          if l:to_be_ignored
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
 | 
					          endif
 | 
				
			||||||
 | 
					        endfor
 | 
				
			||||||
 | 
					        let l:decoded_res_item = s:JSON.decode(res_item)
 | 
				
			||||||
 | 
					        let l:to_be_ignored = l:to_be_ignored || (has_key(l:decoded_res_item, 'request_seq') && l:decoded_res_item.request_seq != s:request_seq)
 | 
				
			||||||
 | 
					        if !l:to_be_ignored
 | 
				
			||||||
 | 
					          call add(response_list, decoded_res_item)
 | 
				
			||||||
 | 
					        endif
 | 
				
			||||||
 | 
					      endfor
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      echom '[Tsuquyomi] TSServer request was timeout:'.a:line
 | 
				
			||||||
 | 
					      return response_list
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					  "call s:debugLog(a:response_length.', '.len(response_list))
 | 
				
			||||||
 | 
					  let s:request_seq = s:request_seq + 1
 | 
				
			||||||
 | 
					  return response_list
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" Send a command to TSServer.
 | 
				
			||||||
 | 
					" This function is called pseudo synchronously.
 | 
				
			||||||
 | 
					" PARAM: {string} cmd Command type. e.g. 'completion', etc...
 | 
				
			||||||
 | 
					" PARAM: {dictionary} args Arguments object. e.g. {'file': 'myApp.ts'}.
 | 
				
			||||||
 | 
					" RETURNS: {list<dictionary>}
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#sendCommandSyncResponse(cmd, args)
 | 
				
			||||||
 | 
					  let l:input = s:JSON.encode({'command': a:cmd, 'arguments': a:args, 'type': 'request', 'seq': s:request_seq})
 | 
				
			||||||
 | 
					  call tsuquyomi#perfLogger#record('beforeCmd:'.a:cmd)
 | 
				
			||||||
 | 
					  let l:stdout_list = tsuquyomi#tsClient#sendRequest(l:input, str2float("0.0001"), 1000, 1)
 | 
				
			||||||
 | 
					  call tsuquyomi#perfLogger#record('afterCmd:'.a:cmd)
 | 
				
			||||||
 | 
					  let l:length = len(l:stdout_list)
 | 
				
			||||||
 | 
					  if l:length == 1
 | 
				
			||||||
 | 
					    "if res.success == 0
 | 
				
			||||||
 | 
					    "  echom '[Tsuquyomi] TSServer command fail. command: '.res.command.', message: '.res.message
 | 
				
			||||||
 | 
					    "endif
 | 
				
			||||||
 | 
					    call tsuquyomi#perfLogger#record('afterDecode:'.a:cmd)
 | 
				
			||||||
 | 
					    return l:stdout_list
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return []
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#sendCommandSyncEvents(cmd, args, delay, length)
 | 
				
			||||||
 | 
					  let l:input = s:JSON.encode({'command': a:cmd, 'arguments': a:args, 'type': 'request', 'seq': s:request_seq})
 | 
				
			||||||
 | 
					  let l:stdout_list = tsuquyomi#tsClient#sendRequest(l:input, a:delay, 2000, a:length)
 | 
				
			||||||
 | 
					  "echo l:stdout_list
 | 
				
			||||||
 | 
					  let l:length = len(l:stdout_list)
 | 
				
			||||||
 | 
					  let l:result_list = []
 | 
				
			||||||
 | 
					  if l:length > 0
 | 
				
			||||||
 | 
					    for res in l:stdout_list
 | 
				
			||||||
 | 
					      if res.type != 'event'
 | 
				
			||||||
 | 
					        "echom '[Tsuquyomi] TSServer return invalid response: '.string(res)
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        call add(l:result_list, res)
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					    endfor
 | 
				
			||||||
 | 
					    return l:result_list
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return []
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#sendCommandOneWay(cmd, args)
 | 
				
			||||||
 | 
					  let l:input = s:JSON.encode({'command': a:cmd, 'arguments': a:args, 'type': 'request', 'seq': s:request_seq})
 | 
				
			||||||
 | 
					  call tsuquyomi#tsClient#sendRequest(l:input, str2float("0.01"), 0, 0)
 | 
				
			||||||
 | 
					  return []
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#getResponseBodyAsList(responses)
 | 
				
			||||||
 | 
					  if len(a:responses) != 1
 | 
				
			||||||
 | 
					    return []
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let response = a:responses[0]
 | 
				
			||||||
 | 
					  if has_key(response, 'success') && response.success && has_key(response, 'body')
 | 
				
			||||||
 | 
					    return response.body
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return []
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#getResponseBodyAsDict(responses)
 | 
				
			||||||
 | 
					  if len(a:responses) != 1
 | 
				
			||||||
 | 
					    return {}
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let response = a:responses[0]
 | 
				
			||||||
 | 
					  if has_key(response, 'success') && response.success && has_key(response, 'body')
 | 
				
			||||||
 | 
					    return response.body
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return {}
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" Send a command to TSServer.
 | 
				
			||||||
 | 
					" This function is called asynchronously.
 | 
				
			||||||
 | 
					" PARAM: {string} cmd Command type. e.g. 'completion', etc...
 | 
				
			||||||
 | 
					" PARAM: {dictionary} args Arguments object. e.g. {'file': 'myApp.ts'}.
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#sendCommandAsyncEvents(cmd, args)
 | 
				
			||||||
 | 
					  let s:quickfix_list = []
 | 
				
			||||||
 | 
					  let l:input = json_encode({'command': a:cmd, 'arguments': a:args, 'type': 'request', 'seq': s:request_seq})
 | 
				
			||||||
 | 
					  " call tsuquyomi#perfLogger#record('beforeCmd:'.a:cmd)
 | 
				
			||||||
 | 
					  call tsuquyomi#tsClient#sendAsyncRequest(l:input)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" ### Core Functions }}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" ### TSServer command wrappers {{{
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" There are client's methods of TSServer.
 | 
				
			||||||
 | 
					" If you want to know details of APIs, see 'typescript/src/server/protocol.d.ts'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" Send oepn command to TSServer.
 | 
				
			||||||
 | 
					" This command does not return any response.
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file}
 | 
				
			||||||
 | 
					  call tsuquyomi#tsClient#sendCommandOneWay('open', l:args)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Send close command to TSServer.
 | 
				
			||||||
 | 
					" This command does not return any response.
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsClose(file)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file}
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#sendCommandOneWay('close', l:args)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Save an opened file to tmpfile.
 | 
				
			||||||
 | 
					" This function can be called for only debugging.
 | 
				
			||||||
 | 
					" This command does not return any response.
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsSaveto(file, tmpfile)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'tmpfile': a:tmpfile}
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#sendCommandOneWay('saveto', l:args)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Fetch keywards to complete from TSServer.
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" PARAM: {string} line The line number of location to complete.
 | 
				
			||||||
 | 
					" PARAM: {string} offset The col number of location to complete.
 | 
				
			||||||
 | 
					" PARAM: {string} prefix Prefix to filter result set.
 | 
				
			||||||
 | 
					" RETURNS: {list} A List of completion info Dictionary.
 | 
				
			||||||
 | 
					"   e.g. :
 | 
				
			||||||
 | 
					"     [
 | 
				
			||||||
 | 
					"       {'name': 'close', 'kindModifiers': 'declare', 'kind': 'function'},
 | 
				
			||||||
 | 
					"       {'name': 'clipboardData', 'kindModifiers': 'declare', 'kind': 'var'}
 | 
				
			||||||
 | 
					"     ]
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsCompletions(file, line, offset, prefix)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'line': a:line, 'offset': a:offset, 'prefix': a:prefix}
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('completions', l:args)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsList(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Emmit to change file to TSServer.
 | 
				
			||||||
 | 
					" Param: {string} file File name to change.
 | 
				
			||||||
 | 
					" Param: {int} line The line number of starting point of range to change.
 | 
				
			||||||
 | 
					" Param: {int} offset The col number of starting point of range to change.
 | 
				
			||||||
 | 
					" Param: {int} endLine The line number of end point of range to change.
 | 
				
			||||||
 | 
					" Param: {int} endOffset The col number of end point of range to change.
 | 
				
			||||||
 | 
					" Param: {string} insertString String after replacing
 | 
				
			||||||
 | 
					" This command does not return any response.
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsChange(file, line, offset, endLine, endOffset, insertString)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'line': a:line, 'offset': a:offset, 'endLine': a:endLine, 'endOffset': a:endOffset, 'insertString': a:insertString}
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#sendCommandOneWay('change', l:args)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Fetch details of completion from TSServer.
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" PARAM: {int} line The line number of location to complete.
 | 
				
			||||||
 | 
					" PARAM: {int} offset The col number of location to complete.
 | 
				
			||||||
 | 
					" PARAM: {list<string>} entryNames A list of names. These names may be fetched by tsuquyomi#tsClient#tsCompletions function.
 | 
				
			||||||
 | 
					" RETURNS: {list} A list of details.
 | 
				
			||||||
 | 
					"   e.g. :
 | 
				
			||||||
 | 
					"     [{
 | 
				
			||||||
 | 
					"       'name': 'DOMError',
 | 
				
			||||||
 | 
					"       'kind': 'var',
 | 
				
			||||||
 | 
					"       'kindModifier': 'declare',
 | 
				
			||||||
 | 
					"       'displayParts': [
 | 
				
			||||||
 | 
					"         {'kind': 'keyword', 'text': 'interface'},
 | 
				
			||||||
 | 
					"         {'kind': 'space', 'text': ' '},
 | 
				
			||||||
 | 
					"         ...
 | 
				
			||||||
 | 
					"         {'kind': 'lineBreak', 'text': '\n'},
 | 
				
			||||||
 | 
					"         ...
 | 
				
			||||||
 | 
					"       ]
 | 
				
			||||||
 | 
					"     }, ...]
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsCompletionEntryDetails(file, line, offset, entryNames)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'line': a:line, 'offset': a:offset, 'entryNames': a:entryNames}
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('completionEntryDetails', l:args)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsList(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Configure editor parameter
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" PARAM: {string} hostInfo Information of Vim
 | 
				
			||||||
 | 
					" PARAM: {dict} formatOptions Options for editor. See the following FormatCodeSetting interface.
 | 
				
			||||||
 | 
					" PARAM: {list} extraFileExtensions List of extensions
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					"    interface FormatCodeSetting {
 | 
				
			||||||
 | 
					"        baseIndentSize?: number;
 | 
				
			||||||
 | 
					"        indentSize?: number;
 | 
				
			||||||
 | 
					"        tabSize?: number;
 | 
				
			||||||
 | 
					"        newLineCharacter?: string;
 | 
				
			||||||
 | 
					"        convertTabsToSpaces?: boolean;
 | 
				
			||||||
 | 
					"        indentStyle?: IndentStyle | ts.IndentStyle;
 | 
				
			||||||
 | 
					"        insertSpaceAfterCommaDelimiter?: boolean;
 | 
				
			||||||
 | 
					"        insertSpaceAfterSemicolonInForStatements?: boolean;
 | 
				
			||||||
 | 
					"        insertSpaceBeforeAndAfterBinaryOperators?: boolean;
 | 
				
			||||||
 | 
					"        insertSpaceAfterConstructor?: boolean;
 | 
				
			||||||
 | 
					"        insertSpaceAfterKeywordsInControlFlowStatements?: boolean;
 | 
				
			||||||
 | 
					"        insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
 | 
				
			||||||
 | 
					"        insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
 | 
				
			||||||
 | 
					"        insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
 | 
				
			||||||
 | 
					"        insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean;
 | 
				
			||||||
 | 
					"        insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
 | 
				
			||||||
 | 
					"        insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
 | 
				
			||||||
 | 
					"        insertSpaceBeforeFunctionParenthesis?: boolean;
 | 
				
			||||||
 | 
					"        placeOpenBraceOnNewLineForFunctions?: boolean;
 | 
				
			||||||
 | 
					"        placeOpenBraceOnNewLineForControlBlocks?: boolean;
 | 
				
			||||||
 | 
					"    }
 | 
				
			||||||
 | 
					let s:NON_BOOLEAN_KEYS_IN_FOPT = [ 'baseIndentSize', 'indentSize', 'tabSize', 'newLineCharacter', 'convertTabsToSpaces', 'indentStyle' ]
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsConfigure(file, hostInfo, formatOptions, extraFileExtensions)
 | 
				
			||||||
 | 
					  let fopt = { }
 | 
				
			||||||
 | 
					  for k in keys(a:formatOptions)
 | 
				
			||||||
 | 
					    if index(s:NON_BOOLEAN_KEYS_IN_FOPT, k) != -1
 | 
				
			||||||
 | 
					      let fopt[k] = a:formatOptions[k]
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let fopt[k] = a:formatOptions[k] ? s:JSON.true : s.JSON.false
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  let l:args = {
 | 
				
			||||||
 | 
					        \ 'file': a:file,
 | 
				
			||||||
 | 
					        \ 'hostInfo': a:hostInfo,
 | 
				
			||||||
 | 
					        \ 'formatOptions': fopt,
 | 
				
			||||||
 | 
					        \ 'extraFileExtensions': a:extraFileExtensions
 | 
				
			||||||
 | 
					        \ }
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#sendCommandOneWay('configure', l:args)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Fetch location where the symbol at cursor(line, offset) in file is defined.
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" PARAM: {int} line The line number of location to complete.
 | 
				
			||||||
 | 
					" PARAM: {int} offset The col number of location to complete.
 | 
				
			||||||
 | 
					" RETURNS: {list<dict>} A list of dictionaries of definition location.
 | 
				
			||||||
 | 
					"   e.g. :
 | 
				
			||||||
 | 
					"     [{'file': 'hogehoge.ts', 'start': {'line': 3, 'offset': 2}, 'end': {'line': 3, 'offset': 10}}]
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsDefinition(file, line, offset)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'line': a:line, 'offset': a:offset}
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('definition', l:args)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsList(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Format = "format";
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsFormat(file, line, offset, endLine, endOffset)
 | 
				
			||||||
 | 
					  call s:error('not implemented!')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Formatonkey = "formatonkey";
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsFormationkey(file, line, offset, key)
 | 
				
			||||||
 | 
					  call s:error('not implemented!')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Get error for files.
 | 
				
			||||||
 | 
					" PARAM: {list<string>} files List of filename
 | 
				
			||||||
 | 
					" PARAM: {int} delay Delay time [msec].
 | 
				
			||||||
 | 
					" PARAM: {list<dict>} error event list
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsGeterr(files, delay)
 | 
				
			||||||
 | 
					  let l:args = {'files': a:files, 'delay': a:delay}
 | 
				
			||||||
 | 
					  let l:delaySec = a:delay * 1.0 / 1000.0
 | 
				
			||||||
 | 
					  let l:typeCount =   tsuquyomi#config#isHigher(280) ? 3 : 2
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncEvents('geterr', l:args, l:delaySec, len(a:files) * l:typeCount)
 | 
				
			||||||
 | 
					  return l:result
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Get errors for project.
 | 
				
			||||||
 | 
					" This command is available only at tsserver ~v.1.6
 | 
				
			||||||
 | 
					" PARAM: {string} file File name in target project.
 | 
				
			||||||
 | 
					" PARAM: {int} delay Delay time [msec].
 | 
				
			||||||
 | 
					" PARAM: {count} count The number of files in the project(you can fetch this from tsProjectInfo).
 | 
				
			||||||
 | 
					" PARAM: {list<dict>} error event list
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsGeterrForProject(file, delay, count)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'delay': a:delay}
 | 
				
			||||||
 | 
					  let l:delaySec = a:delay * 1.0 / 1000.0
 | 
				
			||||||
 | 
					  let l:typeCount =   tsuquyomi#config#isHigher(280) ? 3 : 2
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncEvents('geterrForProject', l:args, l:delaySec, a:count * l:typeCount)
 | 
				
			||||||
 | 
					  return l:result
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Fetch a list of implementations of an interface.
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" PARAM: {int} line The line number of the symbol's position.
 | 
				
			||||||
 | 
					" PARAM: {int} offset The col number of the symbol's position.
 | 
				
			||||||
 | 
					" RETURNS: {list<dict>} Reference information.
 | 
				
			||||||
 | 
					"   e.g. :
 | 
				
			||||||
 | 
					"     [
 | 
				
			||||||
 | 
					"       {
 | 
				
			||||||
 | 
					"         'file': 'SomeClass.ts',
 | 
				
			||||||
 | 
					"         'start': {'offset': 11, 'line': 23}, 'end': {'offset': 5, 'line': 35}
 | 
				
			||||||
 | 
					"       }, {
 | 
				
			||||||
 | 
					"         'file': 'OtherClass.ts',
 | 
				
			||||||
 | 
					"         'start': {'offset': 31, 'line': 26}, 'end': {'offset': 68, 'line': 26}
 | 
				
			||||||
 | 
					"       }
 | 
				
			||||||
 | 
					"     ]
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsImplementation(file, line, offset)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'line': a:line, 'offset': a:offset}
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('implementation', l:args)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsList(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Fetch navigation list from TSServer.
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" RETURNS: {list<dict>} Navigation info
 | 
				
			||||||
 | 
					"   e.g. :
 | 
				
			||||||
 | 
					"     [{
 | 
				
			||||||
 | 
					"       'text': 'ModName',
 | 
				
			||||||
 | 
					"       'kind': 'module',
 | 
				
			||||||
 | 
					"       'kindModifiers: '',
 | 
				
			||||||
 | 
					"       'spans': [{
 | 
				
			||||||
 | 
					"         'start': {'line': 1, 'offset': 5},
 | 
				
			||||||
 | 
					"         'end': {'line': 1, 'offset': 12},
 | 
				
			||||||
 | 
					"       }],
 | 
				
			||||||
 | 
					"       childItems: [
 | 
				
			||||||
 | 
					"         ...   " REMAKS: childItems contains a recursive structure.
 | 
				
			||||||
 | 
					"       ]
 | 
				
			||||||
 | 
					"     }]
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsNavBar(file)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file}
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('navbar', l:args)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsList(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Navto = "navto";
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsNavto(file, searchValue, maxResultCount)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'searchValue': a:searchValue, 'maxResultCount': a:maxResultCount}
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('navto', l:args)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsList(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Fetch quickinfo from TSServer.
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" PARAM: {int} line The line number of the symbol's position.
 | 
				
			||||||
 | 
					" PARAM: {int} offset The col number of the symbol's position.
 | 
				
			||||||
 | 
					" RETURNS:  {dict}
 | 
				
			||||||
 | 
					"   e.g. :
 | 
				
			||||||
 | 
					"     {
 | 
				
			||||||
 | 
					"       'kind': 'method',
 | 
				
			||||||
 | 
					"       'kindModifiers': '',
 | 
				
			||||||
 | 
					"       'displayString': '(method) SimpleModule.MyClass.say(): string',
 | 
				
			||||||
 | 
					"       'start': {'line': 2, 'offset': 2},
 | 
				
			||||||
 | 
					"       'start': {'line': 2, 'offset': 9}
 | 
				
			||||||
 | 
					"     }
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsQuickinfo(file, line, offset)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'line': a:line, 'offset': a:offset}
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('quickinfo', l:args)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsDict(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Fetch a list of references.
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" PARAM: {int} line The line number of the symbol's position.
 | 
				
			||||||
 | 
					" PARAM: {int} offset The col number of the symbol's position.
 | 
				
			||||||
 | 
					" RETURNS: {dictionary} Reference information.
 | 
				
			||||||
 | 
					"   e.g. :
 | 
				
			||||||
 | 
					"     {
 | 
				
			||||||
 | 
					"       'symbolName': 'SomeClass',
 | 
				
			||||||
 | 
					"       'symbolDisplayString': 'SomeModule.SomeClass',
 | 
				
			||||||
 | 
					"       'refs': [
 | 
				
			||||||
 | 
					"         {
 | 
				
			||||||
 | 
					"           'file': 'SomeClass.ts', 'isWriteAccess': 1,
 | 
				
			||||||
 | 
					"           'start': {'line': 3', 'offset': 2}, 'end': {'line': 3, 'offset': 20},
 | 
				
			||||||
 | 
					"           'lineText': 'export class SomeClass {'
 | 
				
			||||||
 | 
					"         }, {
 | 
				
			||||||
 | 
					"           'file': 'OtherClass.ts', 'isWriteAccess': 0,
 | 
				
			||||||
 | 
					"           'start': {'line': 5', 'offset': 2}, 'end': {'line': 5, 'offset': 20},
 | 
				
			||||||
 | 
					"           'lineText': 'export class OtherClass extends SomeClass{'
 | 
				
			||||||
 | 
					"         }
 | 
				
			||||||
 | 
					"       ]
 | 
				
			||||||
 | 
					"     }
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsReferences(file, line, offset)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'line': a:line, 'offset': a:offset}
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('references', l:args)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsDict(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Reload an opend file.
 | 
				
			||||||
 | 
					" It can be used for telling change of buffer to TSServer.
 | 
				
			||||||
 | 
					" PARAM: {string} file File name
 | 
				
			||||||
 | 
					" PARAM: {string} tmpfile
 | 
				
			||||||
 | 
					" RETURNS: {0|1}
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsReload(file, tmpfile)
 | 
				
			||||||
 | 
					  let l:arg = {'file': a:file, 'tmpfile': a:tmpfile}
 | 
				
			||||||
 | 
					  " With ts > 2.6 and ts <=1.9, tsserver emit 2 responses by reload request.
 | 
				
			||||||
 | 
					  " ignore 2nd response of reload command. See also #62
 | 
				
			||||||
 | 
					  if tsuquyomi#config#isHigher(260) || !tsuquyomi#config#isHigher(190)
 | 
				
			||||||
 | 
					    let l:res_count = 1
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    let l:res_count = 2
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncEvents('reload', l:arg, 0.01, l:res_count)
 | 
				
			||||||
 | 
					  "echo l:result
 | 
				
			||||||
 | 
					  if(len(l:result) >= 1)
 | 
				
			||||||
 | 
					    if(has_key(l:result[0], 'success'))
 | 
				
			||||||
 | 
					      return l:result[0].success
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      return 0
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Fetch locatoins of symbols to be replaced from TSServer.
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" PARAM: {int} line The line number of the symbol's position.
 | 
				
			||||||
 | 
					" PARAM: {int} offset The col number of the symbol's position.
 | 
				
			||||||
 | 
					" PARAM: {0|1} findInComments Whether result contains word in comments.
 | 
				
			||||||
 | 
					" PARAM: {0|1} findInString Whether result contains word in String literals.
 | 
				
			||||||
 | 
					" RETURNS: {dict} Rename information dictionary.
 | 
				
			||||||
 | 
					"   e.g.:
 | 
				
			||||||
 | 
					"     {
 | 
				
			||||||
 | 
					"       'info': {
 | 
				
			||||||
 | 
					"         'canRename': 1,
 | 
				
			||||||
 | 
					"         'displayName': 'myApp',
 | 
				
			||||||
 | 
					"         'fullDisplayName': 'myApp',
 | 
				
			||||||
 | 
					"         'kind': 'class',
 | 
				
			||||||
 | 
					"         'kindModifiers': '',
 | 
				
			||||||
 | 
					"         'triggerSpan': {
 | 
				
			||||||
 | 
					"           'start': 44,
 | 
				
			||||||
 | 
					"           'length': 5
 | 
				
			||||||
 | 
					"         },
 | 
				
			||||||
 | 
					"       },
 | 
				
			||||||
 | 
					"       'locs': [{
 | 
				
			||||||
 | 
					"         'file': 'hoge.ts'',
 | 
				
			||||||
 | 
					"         'locs': [
 | 
				
			||||||
 | 
					"           {'start':{'line': 3, 'offset': 4}, 'end':{'line': 3, 'offset': 12}},
 | 
				
			||||||
 | 
					"           ...
 | 
				
			||||||
 | 
					"         ]
 | 
				
			||||||
 | 
					"       },
 | 
				
			||||||
 | 
					"       ...,
 | 
				
			||||||
 | 
					"       ]
 | 
				
			||||||
 | 
					"     }
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsRename(file, line, offset, findInComments, findInString)
 | 
				
			||||||
 | 
					  " TODO findInString parameter does not work... why?
 | 
				
			||||||
 | 
					  let l:arg = {'file': a:file, 'line': a:line, 'offset': a:offset,
 | 
				
			||||||
 | 
					        \ 'findInComments': a:findInComments ? s:JSON.true : s:JSON.false,
 | 
				
			||||||
 | 
					        \ 'findInString'  : a:findInString  ? s:JSON.true : s:JSON.false
 | 
				
			||||||
 | 
					        \ }
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('rename', l:arg)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsDict(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Find brace matching pair.
 | 
				
			||||||
 | 
					" Vim has brace matching natively, so Tsuquyomi does not support this method.
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsBrace(file, line, offset)
 | 
				
			||||||
 | 
					  call s:error('not implemented!')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" This command is available only at tsserver ~v.1.6
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsDocumentHighlights(file, line, offset, filesToSearch)
 | 
				
			||||||
 | 
					  call s:error('not implemented!')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Fetch project information.
 | 
				
			||||||
 | 
					" This command is available only at tsserver ~v.1.6
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" PARAM: {0|1} needFileNameList Whether include list of files in response.
 | 
				
			||||||
 | 
					" RETURNS: dict Project information dictionary.
 | 
				
			||||||
 | 
					"   e.g.:
 | 
				
			||||||
 | 
					"     {
 | 
				
			||||||
 | 
					"       'configFileName': '/samplePrjs/prj001/tsconfig.json',
 | 
				
			||||||
 | 
					"       'fileNames': [
 | 
				
			||||||
 | 
					"         '/PATH_TO_TYPESCRIPT/node_modules/typescript/lib/lib.d.ts',
 | 
				
			||||||
 | 
					"         '/samplePrjs/prj001/main.ts'
 | 
				
			||||||
 | 
					"       ]
 | 
				
			||||||
 | 
					"     }
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsProjectInfo(file, needFileNameList)
 | 
				
			||||||
 | 
					  let l:arg = {'file': a:file,
 | 
				
			||||||
 | 
					        \ 'needFileNameList': a:needFileNameList ? s:JSON.true : s:JSON.false
 | 
				
			||||||
 | 
					        \ }
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('projectInfo', l:arg)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsDict(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Fetch method signature information from TSServer.
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" PARAM: {int} line The line number of the symbol's position.
 | 
				
			||||||
 | 
					" PARAM: {int} offset The col number of the symbol's position.
 | 
				
			||||||
 | 
					" RETURNS:  {dict}
 | 
				
			||||||
 | 
					"   e.g. :
 | 
				
			||||||
 | 
					"     {
 | 
				
			||||||
 | 
					"       'selectedItemIndex': 0,
 | 
				
			||||||
 | 
					"       'argumentCount': 1,
 | 
				
			||||||
 | 
					"       'argumentIndex': 0,
 | 
				
			||||||
 | 
					"       'applicableSpan': {
 | 
				
			||||||
 | 
					"         'start': { 'offset': 27, 'line': 25 }, 'end': { 'offset': 40, 'line': 25 }
 | 
				
			||||||
 | 
					"       },
 | 
				
			||||||
 | 
					"       'items': [{
 | 
				
			||||||
 | 
					"         'tags': [],
 | 
				
			||||||
 | 
					"         'separatorDisplayParts': [
 | 
				
			||||||
 | 
					"           { 'kind': 'punctuation', 'text': ',' },
 | 
				
			||||||
 | 
					"           { 'kind': 'space', 'text': ' ' }
 | 
				
			||||||
 | 
					"         ],
 | 
				
			||||||
 | 
					"         'prefixDisplayParts': [
 | 
				
			||||||
 | 
					"           { 'kind': 'methodName', 'text': 'deleteTerms' },
 | 
				
			||||||
 | 
					"           { 'kind': 'punctuation', 'text': '(' }
 | 
				
			||||||
 | 
					"         ],
 | 
				
			||||||
 | 
					"         'parameters': [
 | 
				
			||||||
 | 
					"           {
 | 
				
			||||||
 | 
					"             'isOptional': 0,
 | 
				
			||||||
 | 
					"             'name': 'id',
 | 
				
			||||||
 | 
					"             'documentation': [],
 | 
				
			||||||
 | 
					"             'displayParts': [
 | 
				
			||||||
 | 
					"               { 'kind': 'parameterName', 'text': 'id' },
 | 
				
			||||||
 | 
					"               { 'kind': 'punctuation', 'text': ':' },
 | 
				
			||||||
 | 
					"               { 'kind': 'space', 'text': ' ' },
 | 
				
			||||||
 | 
					"               { 'kind': 'keyword', 'text': 'number' }
 | 
				
			||||||
 | 
					"             ]
 | 
				
			||||||
 | 
					"           }
 | 
				
			||||||
 | 
					"         ],
 | 
				
			||||||
 | 
					"         'suffixDisplayParts': [
 | 
				
			||||||
 | 
					"           { 'kind': 'punctuation', 'text': ')' },
 | 
				
			||||||
 | 
					"           { 'kind': 'punctuation', 'text': ':' },
 | 
				
			||||||
 | 
					"           { 'kind': 'space', 'text': ' ' },
 | 
				
			||||||
 | 
					"           { 'kind': 'className', 'text': 'Observable' },
 | 
				
			||||||
 | 
					"           { 'kind': 'punctuation', 'text': '<' },
 | 
				
			||||||
 | 
					"           { 'kind': 'interfaceName', 'text': 'ApiResponseData' },
 | 
				
			||||||
 | 
					"           { 'kind': 'punctuation', 'text': '>' }
 | 
				
			||||||
 | 
					"         ],
 | 
				
			||||||
 | 
					"         'isVariadic': 0,
 | 
				
			||||||
 | 
					"         'documentation': []
 | 
				
			||||||
 | 
					"       }]
 | 
				
			||||||
 | 
					"     }
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" This can be combined into a simple signature like this:
 | 
				
			||||||
 | 
					"     deleteTerms(id: number): Observable<ApiResponseData>
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsSignatureHelp(file, line, offset)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'line': a:line, 'offset': a:offset}
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('signatureHelp', l:args)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsDict(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Fetch location where the type of the symbol at cursor(line, offset) in file is defined.
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" PARAM: {int} line The line number of location to complete.
 | 
				
			||||||
 | 
					" PARAM: {int} offset The col number of location to complete.
 | 
				
			||||||
 | 
					" RETURNS: {list<dict>} A list of dictionaries of type definition location.
 | 
				
			||||||
 | 
					"   e.g. :
 | 
				
			||||||
 | 
					"     [{'file': 'hogehoge.ts', 'start': {'line': 3, 'offset': 2}, 'end': {'line': 3, 'offset': 10}}]
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsTypeDefinition(file, line, offset)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'line': a:line, 'offset': a:offset}
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('typeDefinition', l:args)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsList(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Reload prjects.
 | 
				
			||||||
 | 
					" This command is available only at tsserver ~v.1.6
 | 
				
			||||||
 | 
					" This command does not return any response.
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsReloadProjects()
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#sendCommandOneWay('reloadProjects', {})
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" This command is available only at tsserver ~v.2.1
 | 
				
			||||||
 | 
					" PARAM: {string} file File name.
 | 
				
			||||||
 | 
					" PARAM: {number} startLine The line number for the req
 | 
				
			||||||
 | 
					" PARAM: {number} startOffset The character offset for the req
 | 
				
			||||||
 | 
					" PARAM: {number} endLine The line number for the req
 | 
				
			||||||
 | 
					" PARAM: {number} endOffset The character offset for the req
 | 
				
			||||||
 | 
					" PARAM: {list<number>} errorCodes Error codes we want to get the fixes for
 | 
				
			||||||
 | 
					" RETURNS: {list<dict>}
 | 
				
			||||||
 | 
					"   e.g.:
 | 
				
			||||||
 | 
					"     [
 | 
				
			||||||
 | 
					"       {
 | 
				
			||||||
 | 
					"         'description': 'Add missing ''super()'' call.',
 | 
				
			||||||
 | 
					"         'changes': [
 | 
				
			||||||
 | 
					"           {
 | 
				
			||||||
 | 
					"             'fileName': '/SamplePrj/codeFixesTest.ts',
 | 
				
			||||||
 | 
					"             'textChanges': [
 | 
				
			||||||
 | 
					"               {
 | 
				
			||||||
 | 
					"                 'start': {'offset': 20, 'line': 6},
 | 
				
			||||||
 | 
					"                 'end': {'offset': 20, 'line': 6},
 | 
				
			||||||
 | 
					"                 'newText': 'super();'
 | 
				
			||||||
 | 
					"               }
 | 
				
			||||||
 | 
					"             ]
 | 
				
			||||||
 | 
					"           }
 | 
				
			||||||
 | 
					"         ]
 | 
				
			||||||
 | 
					"       }
 | 
				
			||||||
 | 
					"     ]
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsGetCodeFixes(file, startLine, startOffset, endLine, endOffset, errorCodes)
 | 
				
			||||||
 | 
					  let l:arg = {
 | 
				
			||||||
 | 
					        \ 'file': a:file,
 | 
				
			||||||
 | 
					        \ 'startLine': a:startLine, 'startOffset': a:startOffset,
 | 
				
			||||||
 | 
					        \ 'endLine': a:endLine, 'endOffset': a:endOffset,
 | 
				
			||||||
 | 
					        \ 'errorCodes': a:errorCodes
 | 
				
			||||||
 | 
					        \ }
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('getCodeFixes', l:arg)
 | 
				
			||||||
 | 
					  return tsuquyomi#tsClient#getResponseBodyAsList(l:result)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Get available code fixes list
 | 
				
			||||||
 | 
					" This command is available only at tsserver ~v.2.1
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsGetSupportedCodeFixes()
 | 
				
			||||||
 | 
					  let l:result = tsuquyomi#tsClient#sendCommandSyncResponse('getSupportedCodeFixes', {})
 | 
				
			||||||
 | 
					  let l:body = tsuquyomi#tsClient#getResponseBodyAsDict(l:result)
 | 
				
			||||||
 | 
					  if (type(l:body) != v:t_list)
 | 
				
			||||||
 | 
					    return []
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return l:body
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" Emmit to change file to TSServer.
 | 
				
			||||||
 | 
					" Param: {string} file File name to change.
 | 
				
			||||||
 | 
					" Param: {int} line The line number of starting point of range to change.
 | 
				
			||||||
 | 
					" Param: {int} offset The col number of starting point of range to change.
 | 
				
			||||||
 | 
					" Param: {int} endLine The line number of end point of range to change.
 | 
				
			||||||
 | 
					" Param: {int} endOffset The col number of end point of range to change.
 | 
				
			||||||
 | 
					" Param: {string} insertString String after replacing
 | 
				
			||||||
 | 
					" This command does not return any response.
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsAsyncChange(file, line, offset, endLine, endOffset, insertString)
 | 
				
			||||||
 | 
					  let l:args = {'file': a:file, 'line': a:line, 'offset': a:offset, 'endLine': a:endLine, 'endOffset': a:endOffset, 'insertString': a:insertString}
 | 
				
			||||||
 | 
					  call tsuquyomi#tsClient#sendCommandAsyncEvents('change', l:args)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" Get error for files.
 | 
				
			||||||
 | 
					" PARAM: {list<string>} files List of filename
 | 
				
			||||||
 | 
					" PARAM: {int} delay Delay time [msec].
 | 
				
			||||||
 | 
					function! tsuquyomi#tsClient#tsAsyncGeterr(files, delay)
 | 
				
			||||||
 | 
					  let l:args = {'files': a:files, 'delay': a:delay}
 | 
				
			||||||
 | 
					  let l:delaySec = a:delay * 1.0 / 1000.0
 | 
				
			||||||
 | 
					  let l:typeCount = tsuquyomi#config#isHigher(280) ? 3 : 2
 | 
				
			||||||
 | 
					  call tsuquyomi#tsClient#sendCommandAsyncEvents('geterr', l:args)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" ### TSServer command wrappers }}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let &cpo = s:save_cpo
 | 
				
			||||||
 | 
					unlet s:save_cpo
 | 
				
			||||||
@ -0,0 +1,66 @@
 | 
				
			|||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					" FILE: autoload/unite/sources/outline/typescript.vim
 | 
				
			||||||
 | 
					" AUTHOR: Quramy <yosuke.kurami@gmail.com>
 | 
				
			||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Tsuquyomi outline info for TypeScript.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! unite#sources#outline#typescript#outline_info()
 | 
				
			||||||
 | 
					  return s:outline_info
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:Tree = unite#sources#outline#import('Tree')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:outline_info = {
 | 
				
			||||||
 | 
					      \ 'is_volatile': 1,
 | 
				
			||||||
 | 
					      \ 'auto_update': 0,
 | 
				
			||||||
 | 
					      \ 'highlight_rules': [
 | 
				
			||||||
 | 
					      \   {'name': 'package', 
 | 
				
			||||||
 | 
					      \     'pattern': '/\S\+\s\+:module/'},
 | 
				
			||||||
 | 
					      \   {'name': 'method', 
 | 
				
			||||||
 | 
					      \     'pattern': '/\S\+\s\+:\%(method\|call\|construct\)/'},
 | 
				
			||||||
 | 
					      \   {'name': 'id', 
 | 
				
			||||||
 | 
					      \     'pattern': '/\S\+\s\+:\%(var\|alias\)/'},
 | 
				
			||||||
 | 
					      \   {'name': 'expanded', 
 | 
				
			||||||
 | 
					      \     'pattern': '/\S\+\s\+:\%(property\|index\)/'},
 | 
				
			||||||
 | 
					      \   {'name': 'type', 
 | 
				
			||||||
 | 
					      \     'pattern': '/\S\+\s\+:\%(class\|interface\)/'}
 | 
				
			||||||
 | 
					      \   ]
 | 
				
			||||||
 | 
					      \ }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:createHeadingFromNavitem(navitem)
 | 
				
			||||||
 | 
					  let heading = {}
 | 
				
			||||||
 | 
					  let heading.word = a:navitem.text."\t:".a:navitem.kind
 | 
				
			||||||
 | 
					  let heading.type = a:navitem.kind
 | 
				
			||||||
 | 
					  if has_key(a:navitem, 'spans') && len(a:navitem.spans)
 | 
				
			||||||
 | 
					    let heading.lnum = a:navitem.spans[0].start.line
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return heading
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:createNodeRecursive(parent_node, navitem_list)
 | 
				
			||||||
 | 
					  for navitem in a:navitem_list
 | 
				
			||||||
 | 
					    let heading = s:createHeadingFromNavitem(navitem)
 | 
				
			||||||
 | 
					    call s:Tree.append_child(a:parent_node, heading)
 | 
				
			||||||
 | 
					    if has_key(navitem, 'childItems') && len(navitem.childItems)
 | 
				
			||||||
 | 
					      call s:createNodeRecursive(heading, navitem.childItems)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return a:parent_node
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:outline_info.extract_headings(context)
 | 
				
			||||||
 | 
					  let root = s:Tree.new()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  " 1. Fetch navigation info from TSServer.
 | 
				
			||||||
 | 
					  let [navbar_list, is_success] = tsuquyomi#navBar()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if is_success
 | 
				
			||||||
 | 
					    let root = s:createNodeRecursive(root, navbar_list)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return root
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,66 @@
 | 
				
			|||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					" FILE: autoload/unite/sources/tsproject.vim
 | 
				
			||||||
 | 
					" AUTHOR: Quramy <yosuke.kurami@gmail.com>
 | 
				
			||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:source = {
 | 
				
			||||||
 | 
					      \ 'name': 'tsproject',
 | 
				
			||||||
 | 
					      \ 'is_grouped': 1,
 | 
				
			||||||
 | 
					      \ 'description': 'TypeScript project information',
 | 
				
			||||||
 | 
					      \ }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:source.gather_candidates(args, context)
 | 
				
			||||||
 | 
					  if len(a:args)
 | 
				
			||||||
 | 
					    let selected_group_name = a:args[0]
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    let selected_group_name = '.'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let buf_name = expand('%:p')
 | 
				
			||||||
 | 
					  let pinfo = tsuquyomi#projectInfo(buf_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let result = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if has_key(pinfo, 'configFileName')
 | 
				
			||||||
 | 
					    call add(result, {
 | 
				
			||||||
 | 
					          \ 'group': 'tsconfig',
 | 
				
			||||||
 | 
					          \ 'kind': 'file',
 | 
				
			||||||
 | 
					          \ 'action__path': pinfo.configFileName,
 | 
				
			||||||
 | 
					          \ 'word': pinfo.configFileName,
 | 
				
			||||||
 | 
					          \ 'abbr': "\t".pinfo.configFileName,
 | 
				
			||||||
 | 
					          \ 'source': 'tsproject'
 | 
				
			||||||
 | 
					          \ })
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    call add(result, {
 | 
				
			||||||
 | 
					          \ 'group': 'tsconfig',
 | 
				
			||||||
 | 
					          \ 'kind': 'common',
 | 
				
			||||||
 | 
					          \ 'is_dummy': 1,
 | 
				
			||||||
 | 
					          \ 'word': '(your project does not have tsconfig.json)',
 | 
				
			||||||
 | 
					          \ 'abbr': "\t(your project does not have tsconfig.json)",
 | 
				
			||||||
 | 
					          \ 'source': 'tsproject'
 | 
				
			||||||
 | 
					          \ })
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if has_key(pinfo, 'filteredFileNames')
 | 
				
			||||||
 | 
					    for fileName in sort(copy(pinfo.filteredFileNames))
 | 
				
			||||||
 | 
					      call add(result, {
 | 
				
			||||||
 | 
					            \ 'group': 'files',
 | 
				
			||||||
 | 
					            \ 'word': fileName,
 | 
				
			||||||
 | 
					            \ 'abbr': "\t".fileName,
 | 
				
			||||||
 | 
					            \ 'kind': 'file',
 | 
				
			||||||
 | 
					            \ 'action__path': fileName,
 | 
				
			||||||
 | 
					            \ 'source': 'tsproject'
 | 
				
			||||||
 | 
					            \ })
 | 
				
			||||||
 | 
					    endfor
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return result
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! unite#sources#tsproject#define()
 | 
				
			||||||
 | 
					  if tsuquyomi#config#isHigher(160)
 | 
				
			||||||
 | 
					    return s:source
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					function! vital#of(name) abort
 | 
				
			||||||
 | 
					  let files = globpath(&runtimepath, 'autoload/vital/' . a:name . '.vital', 1)
 | 
				
			||||||
 | 
					  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#_{substitute(ver[0], '\W', '', 'g')}#new()
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					let s:_plugin_name = expand('<sfile>:t:r')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! vital#{s:_plugin_name}#new() abort
 | 
				
			||||||
 | 
					  return vital#{s:_plugin_name[1:]}#new()
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
@ -0,0 +1,457 @@
 | 
				
			|||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					" NOTE: lines between '" ___vital___' is generated by :Vitalize.
 | 
				
			||||||
 | 
					" Do not mofidify the code nor insert new lines before '" ___vital___'
 | 
				
			||||||
 | 
					if v:version > 703 || v:version == 703 && has('patch1170')
 | 
				
			||||||
 | 
					  function! vital#_tsuquyomi#Data#List#import() abort
 | 
				
			||||||
 | 
					    return map({'combinations': '', 'and': '', 'sort_by': '', 'foldr1': '', 'sort': '', 'flatten': '', 'has_index': '', 'find_indices': '', 'any': '', 'unshift': '', 'span': '', 'pop': '', 'binary_search': '', 'uniq_by': '', 'or': '', 'all': '', 'zip': '', 'find_last_index': '', 'find': '', 'partition': '', 'map_accum': '', 'permutations': '', 'break': '', 'max_by': '', 'foldl': '', 'foldr': '', 'find_index': '', 'group_by': '', 'take_while': '', 'conj': '', 'push': '', 'char_range': '', 'cons': '', 'foldl1': '', 'intersect': '', 'concat': '', 'shift': '', 'clear': '', 'has_common_items': '', 'product': '', 'zip_fill': '', 'uniq': '', 'has': '', 'min_by': '', 'with_index': ''},  'function("s:" . v:key)')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:_SID() abort
 | 
				
			||||||
 | 
					    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					  execute join(['function! vital#_tsuquyomi#Data#List#import() abort', printf("return map({'combinations': '', 'and': '', 'sort_by': '', 'foldr1': '', 'sort': '', 'flatten': '', 'has_index': '', 'find_indices': '', 'any': '', 'unshift': '', 'span': '', 'pop': '', 'binary_search': '', 'uniq_by': '', 'or': '', 'all': '', 'zip': '', 'find_last_index': '', 'find': '', 'partition': '', 'map_accum': '', 'permutations': '', 'break': '', 'max_by': '', 'foldl': '', 'foldr': '', 'find_index': '', 'group_by': '', 'take_while': '', 'conj': '', 'push': '', 'char_range': '', 'cons': '', 'foldl1': '', 'intersect': '', 'concat': '', 'shift': '', 'clear': '', 'has_common_items': '', 'product': '', 'zip_fill': '', 'uniq': '', 'has': '', 'min_by': '', 'with_index': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
 | 
				
			||||||
 | 
					  delfunction s:_SID
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					" Utilities for list.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:save_cpo = &cpo
 | 
				
			||||||
 | 
					set cpo&vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:pop(list) abort
 | 
				
			||||||
 | 
					  return remove(a:list, -1)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:push(list, val) abort
 | 
				
			||||||
 | 
					  call add(a:list, a:val)
 | 
				
			||||||
 | 
					  return a:list
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:shift(list) abort
 | 
				
			||||||
 | 
					  return remove(a:list, 0)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:unshift(list, val) abort
 | 
				
			||||||
 | 
					  return insert(a:list, a:val)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:cons(x, xs) abort
 | 
				
			||||||
 | 
					  return [a:x] + a:xs
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:conj(xs, x) abort
 | 
				
			||||||
 | 
					  return a:xs + [a:x]
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Removes duplicates from a list.
 | 
				
			||||||
 | 
					function! s:uniq(list) abort
 | 
				
			||||||
 | 
					  return s:uniq_by(a:list, 'v:val')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Removes duplicates from a list.
 | 
				
			||||||
 | 
					function! s:uniq_by(list, f) abort
 | 
				
			||||||
 | 
					  let list = map(copy(a:list), printf('[v:val, %s]', a:f))
 | 
				
			||||||
 | 
					  let i = 0
 | 
				
			||||||
 | 
					  let seen = {}
 | 
				
			||||||
 | 
					  while i < len(list)
 | 
				
			||||||
 | 
					    let key = string(list[i][1])
 | 
				
			||||||
 | 
					    if has_key(seen, key)
 | 
				
			||||||
 | 
					      call remove(list, i)
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let seen[key] = 1
 | 
				
			||||||
 | 
					      let i += 1
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					  return map(list, 'v:val[0]')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:clear(list) abort
 | 
				
			||||||
 | 
					  if !empty(a:list)
 | 
				
			||||||
 | 
					    unlet! a:list[0 : len(a:list) - 1]
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return a:list
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Concatenates a list of lists.
 | 
				
			||||||
 | 
					" XXX: Should we verify the input?
 | 
				
			||||||
 | 
					function! s:concat(list) abort
 | 
				
			||||||
 | 
					  let memo = []
 | 
				
			||||||
 | 
					  for Value in a:list
 | 
				
			||||||
 | 
					    let memo += Value
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return memo
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Take each elements from lists to a new list.
 | 
				
			||||||
 | 
					function! s:flatten(list, ...) abort
 | 
				
			||||||
 | 
					  let limit = a:0 > 0 ? a:1 : -1
 | 
				
			||||||
 | 
					  let memo = []
 | 
				
			||||||
 | 
					  if limit == 0
 | 
				
			||||||
 | 
					    return a:list
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let limit -= 1
 | 
				
			||||||
 | 
					  for Value in a:list
 | 
				
			||||||
 | 
					    let memo +=
 | 
				
			||||||
 | 
					          \ type(Value) == type([]) ?
 | 
				
			||||||
 | 
					          \   s:flatten(Value, limit) :
 | 
				
			||||||
 | 
					          \   [Value]
 | 
				
			||||||
 | 
					    unlet! Value
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return memo
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Sorts a list with expression to compare each two values.
 | 
				
			||||||
 | 
					" a:a and a:b can be used in {expr}.
 | 
				
			||||||
 | 
					function! s:sort(list, expr) abort
 | 
				
			||||||
 | 
					  if type(a:expr) == type(function('function'))
 | 
				
			||||||
 | 
					    return sort(a:list, a:expr)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let s:expr = a:expr
 | 
				
			||||||
 | 
					  return sort(a:list, 's:_compare')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_compare(a, b) abort
 | 
				
			||||||
 | 
					  return eval(s:expr)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Sorts a list using a set of keys generated by mapping the values in the list
 | 
				
			||||||
 | 
					" through the given expr.
 | 
				
			||||||
 | 
					" v:val is used in {expr}
 | 
				
			||||||
 | 
					function! s:sort_by(list, expr) abort
 | 
				
			||||||
 | 
					  let pairs = map(a:list, printf('[v:val, %s]', a:expr))
 | 
				
			||||||
 | 
					  return map(s:sort(pairs,
 | 
				
			||||||
 | 
					  \      'a:a[1] ==# a:b[1] ? 0 : a:a[1] ># a:b[1] ? 1 : -1'), 'v:val[0]')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Returns a maximum value in {list} through given {expr}.
 | 
				
			||||||
 | 
					" Returns 0 if {list} is empty.
 | 
				
			||||||
 | 
					" v:val is used in {expr}
 | 
				
			||||||
 | 
					function! s:max_by(list, expr) abort
 | 
				
			||||||
 | 
					  if empty(a:list)
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let list = map(copy(a:list), a:expr)
 | 
				
			||||||
 | 
					  return a:list[index(list, max(list))]
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Returns a minimum value in {list} through given {expr}.
 | 
				
			||||||
 | 
					" Returns 0 if {list} is empty.
 | 
				
			||||||
 | 
					" v:val is used in {expr}
 | 
				
			||||||
 | 
					" FIXME: -0x80000000 == 0x80000000
 | 
				
			||||||
 | 
					function! s:min_by(list, expr) abort
 | 
				
			||||||
 | 
					  return s:max_by(a:list, '-(' . a:expr . ')')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Returns List of character sequence between [a:from, a:to]
 | 
				
			||||||
 | 
					" e.g.: s:char_range('a', 'c') returns ['a', 'b', 'c']
 | 
				
			||||||
 | 
					function! s:char_range(from, to) abort
 | 
				
			||||||
 | 
					  return map(
 | 
				
			||||||
 | 
					  \   range(char2nr(a:from), char2nr(a:to)),
 | 
				
			||||||
 | 
					  \   'nr2char(v:val)'
 | 
				
			||||||
 | 
					  \)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Returns true if a:list has a:value.
 | 
				
			||||||
 | 
					" Returns false otherwise.
 | 
				
			||||||
 | 
					function! s:has(list, value) abort
 | 
				
			||||||
 | 
					  return index(a:list, a:value) isnot -1
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Returns true if a:list[a:index] exists.
 | 
				
			||||||
 | 
					" Returns false otherwise.
 | 
				
			||||||
 | 
					" NOTE: Returns false when a:index is negative number.
 | 
				
			||||||
 | 
					function! s:has_index(list, index) abort
 | 
				
			||||||
 | 
					  " Return true when negative index?
 | 
				
			||||||
 | 
					  " let index = a:index >= 0 ? a:index : len(a:list) + a:index
 | 
				
			||||||
 | 
					  return 0 <= a:index && a:index < len(a:list)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Haskell's Data.List.span
 | 
				
			||||||
 | 
					function! s:span(f, xs) abort
 | 
				
			||||||
 | 
					  let border = len(a:xs)
 | 
				
			||||||
 | 
					  for i in range(len(a:xs))
 | 
				
			||||||
 | 
					    if !eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
 | 
				
			||||||
 | 
					      let border = i
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return border == 0 ? [[], copy(a:xs)] : [a:xs[: border - 1], a:xs[border :]]
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Haskell's Data.List.break
 | 
				
			||||||
 | 
					function! s:break(f, xs) abort
 | 
				
			||||||
 | 
					  return s:span(printf('!(%s)', a:f), a:xs)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Haskell's Data.List.takeWhile
 | 
				
			||||||
 | 
					function! s:take_while(f, xs) abort
 | 
				
			||||||
 | 
					  return s:span(a:f, a:xs)[0]
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Haskell's Data.List.partition
 | 
				
			||||||
 | 
					function! s:partition(f, xs) abort
 | 
				
			||||||
 | 
					  return [filter(copy(a:xs), a:f), filter(copy(a:xs), '!(' . a:f . ')')]
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Haskell's Prelude.all
 | 
				
			||||||
 | 
					function! s:all(f, xs) abort
 | 
				
			||||||
 | 
					  return !s:any(printf('!(%s)', a:f), a:xs)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Haskell's Prelude.any
 | 
				
			||||||
 | 
					function! s:any(f, xs) abort
 | 
				
			||||||
 | 
					  return !empty(filter(map(copy(a:xs), a:f), 'v:val'))
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Haskell's Prelude.and
 | 
				
			||||||
 | 
					function! s:and(xs) abort
 | 
				
			||||||
 | 
					  return s:all('v:val', a:xs)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Haskell's Prelude.or
 | 
				
			||||||
 | 
					function! s:or(xs) abort
 | 
				
			||||||
 | 
					  return s:any('v:val', a:xs)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:map_accum(expr, xs, init) abort
 | 
				
			||||||
 | 
					  let memo = []
 | 
				
			||||||
 | 
					  let init = a:init
 | 
				
			||||||
 | 
					  for x in a:xs
 | 
				
			||||||
 | 
					    let expr = substitute(a:expr, 'v:memo', init, 'g')
 | 
				
			||||||
 | 
					    let expr = substitute(expr, 'v:val', x, 'g')
 | 
				
			||||||
 | 
					    let [tmp, init] = eval(expr)
 | 
				
			||||||
 | 
					    call add(memo, tmp)
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return memo
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Haskell's Prelude.foldl
 | 
				
			||||||
 | 
					function! s:foldl(f, init, xs) abort
 | 
				
			||||||
 | 
					  let memo = a:init
 | 
				
			||||||
 | 
					  for x in a:xs
 | 
				
			||||||
 | 
					    let expr = substitute(a:f, 'v:val', string(x), 'g')
 | 
				
			||||||
 | 
					    let expr = substitute(expr, 'v:memo', string(memo), 'g')
 | 
				
			||||||
 | 
					    unlet memo
 | 
				
			||||||
 | 
					    let memo = eval(expr)
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return memo
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Haskell's Prelude.foldl1
 | 
				
			||||||
 | 
					function! s:foldl1(f, xs) abort
 | 
				
			||||||
 | 
					  if len(a:xs) == 0
 | 
				
			||||||
 | 
					    throw 'vital: Data.List: foldl1'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return s:foldl(a:f, a:xs[0], a:xs[1:])
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Haskell's Prelude.foldr
 | 
				
			||||||
 | 
					function! s:foldr(f, init, xs) abort
 | 
				
			||||||
 | 
					  return s:foldl(a:f, a:init, reverse(copy(a:xs)))
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Haskell's Prelude.fold11
 | 
				
			||||||
 | 
					function! s:foldr1(f, xs) abort
 | 
				
			||||||
 | 
					  if len(a:xs) == 0
 | 
				
			||||||
 | 
					    throw 'vital: Data.List: foldr1'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return s:foldr(a:f, a:xs[-1], a:xs[0:-2])
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to python's zip()
 | 
				
			||||||
 | 
					function! s:zip(...) abort
 | 
				
			||||||
 | 
					  return map(range(min(map(copy(a:000), 'len(v:val)'))), "map(copy(a:000), 'v:val['.v:val.']')")
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to zip(), but goes until the longer one.
 | 
				
			||||||
 | 
					function! s:zip_fill(xs, ys, filler) abort
 | 
				
			||||||
 | 
					  if empty(a:xs) && empty(a:ys)
 | 
				
			||||||
 | 
					    return []
 | 
				
			||||||
 | 
					  elseif empty(a:ys)
 | 
				
			||||||
 | 
					    return s:cons([a:xs[0], a:filler], s:zip_fill(a:xs[1 :], [], a:filler))
 | 
				
			||||||
 | 
					  elseif empty(a:xs)
 | 
				
			||||||
 | 
					    return s:cons([a:filler, a:ys[0]], s:zip_fill([], a:ys[1 :], a:filler))
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return s:cons([a:xs[0], a:ys[0]], s:zip_fill(a:xs[1 :], a:ys[1: ], a:filler))
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Inspired by Ruby's with_index method.
 | 
				
			||||||
 | 
					function! s:with_index(list, ...) abort
 | 
				
			||||||
 | 
					  let base = a:0 > 0 ? a:1 : 0
 | 
				
			||||||
 | 
					  return map(copy(a:list), '[v:val, v:key + base]')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Ruby's detect or Haskell's find.
 | 
				
			||||||
 | 
					function! s:find(list, default, f) abort
 | 
				
			||||||
 | 
					  for x in a:list
 | 
				
			||||||
 | 
					    if eval(substitute(a:f, 'v:val', string(x), 'g'))
 | 
				
			||||||
 | 
					      return x
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return a:default
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Returns the index of the first element which satisfies the given expr.
 | 
				
			||||||
 | 
					function! s:find_index(xs, f, ...) abort
 | 
				
			||||||
 | 
					  let len = len(a:xs)
 | 
				
			||||||
 | 
					  let start = a:0 > 0 ? (a:1 < 0 ? len + a:1 : a:1) : 0
 | 
				
			||||||
 | 
					  let default = a:0 > 1 ? a:2 : -1
 | 
				
			||||||
 | 
					  if start >=# len || start < 0
 | 
				
			||||||
 | 
					    return default
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  for i in range(start, len - 1)
 | 
				
			||||||
 | 
					    if eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
 | 
				
			||||||
 | 
					      return i
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return default
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Returns the index of the last element which satisfies the given expr.
 | 
				
			||||||
 | 
					function! s:find_last_index(xs, f, ...) abort
 | 
				
			||||||
 | 
					  let len = len(a:xs)
 | 
				
			||||||
 | 
					  let start = a:0 > 0 ? (a:1 < 0 ? len + a:1 : a:1) : len - 1
 | 
				
			||||||
 | 
					  let default = a:0 > 1 ? a:2 : -1
 | 
				
			||||||
 | 
					  if start >=# len || start < 0
 | 
				
			||||||
 | 
					    return default
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  for i in range(start, 0, -1)
 | 
				
			||||||
 | 
					    if eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
 | 
				
			||||||
 | 
					      return i
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return default
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Similar to find_index but returns the list of indices satisfying the given expr.
 | 
				
			||||||
 | 
					function! s:find_indices(xs, f, ...) abort
 | 
				
			||||||
 | 
					  let len = len(a:xs)
 | 
				
			||||||
 | 
					  let start = a:0 > 0 ? (a:1 < 0 ? len + a:1 : a:1) : 0
 | 
				
			||||||
 | 
					  let result = []
 | 
				
			||||||
 | 
					  if start >=# len || start < 0
 | 
				
			||||||
 | 
					    return result
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  for i in range(start, len - 1)
 | 
				
			||||||
 | 
					    if eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
 | 
				
			||||||
 | 
					      call add(result, i)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return result
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Return non-zero if a:list1 and a:list2 have any common item(s).
 | 
				
			||||||
 | 
					" Return zero otherwise.
 | 
				
			||||||
 | 
					function! s:has_common_items(list1, list2) abort
 | 
				
			||||||
 | 
					  return !empty(filter(copy(a:list1), 'index(a:list2, v:val) isnot -1'))
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:intersect(list1, list2) abort
 | 
				
			||||||
 | 
					  let items = []
 | 
				
			||||||
 | 
					  " for funcref
 | 
				
			||||||
 | 
					  for X in a:list1
 | 
				
			||||||
 | 
					    if index(a:list2, X) != -1 && index(items, X) == -1
 | 
				
			||||||
 | 
					      let items += [X]
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return items
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" similar to Ruby's group_by.
 | 
				
			||||||
 | 
					function! s:group_by(xs, f) abort
 | 
				
			||||||
 | 
					  let result = {}
 | 
				
			||||||
 | 
					  let list = map(copy(a:xs), printf('[v:val, %s]', a:f))
 | 
				
			||||||
 | 
					  for x in list
 | 
				
			||||||
 | 
					    let Val = x[0]
 | 
				
			||||||
 | 
					    let key = type(x[1]) !=# type('') ? string(x[1]) : x[1]
 | 
				
			||||||
 | 
					    if has_key(result, key)
 | 
				
			||||||
 | 
					      call add(result[key], Val)
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let result[key] = [Val]
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    unlet Val
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return result
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_default_compare(a, b) abort
 | 
				
			||||||
 | 
					  return a:a <# a:b ? -1 : a:a ># a:b ? 1 : 0
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:binary_search(list, value, ...) abort
 | 
				
			||||||
 | 
					  let Predicate = a:0 >= 1 ? a:1 : 's:_default_compare'
 | 
				
			||||||
 | 
					  let dic = a:0 >= 2 ? a:2 : {}
 | 
				
			||||||
 | 
					  let start = 0
 | 
				
			||||||
 | 
					  let end = len(a:list) - 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while 1
 | 
				
			||||||
 | 
					    if start > end
 | 
				
			||||||
 | 
					      return -1
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let middle = (start + end) / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let compared = call(Predicate, [a:value, a:list[middle]], dic)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if compared < 0
 | 
				
			||||||
 | 
					      let end = middle - 1
 | 
				
			||||||
 | 
					    elseif compared > 0
 | 
				
			||||||
 | 
					      let start = middle + 1
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      return middle
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:product(lists) abort
 | 
				
			||||||
 | 
					  let result = [[]]
 | 
				
			||||||
 | 
					  for pool in a:lists
 | 
				
			||||||
 | 
					    let tmp = []
 | 
				
			||||||
 | 
					    for x in result
 | 
				
			||||||
 | 
					      let tmp += map(copy(pool), 'x + [v:val]')
 | 
				
			||||||
 | 
					    endfor
 | 
				
			||||||
 | 
					    let result = tmp
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return result
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:permutations(list, ...) abort
 | 
				
			||||||
 | 
					  if a:0 > 1
 | 
				
			||||||
 | 
					    throw 'vital: Data.List: too many arguments'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let r = a:0 == 1 ? a:1 : len(a:list)
 | 
				
			||||||
 | 
					  if r > len(a:list)
 | 
				
			||||||
 | 
					    return []
 | 
				
			||||||
 | 
					  elseif r < 0
 | 
				
			||||||
 | 
					    throw 'vital: Data.List: {r} must be non-negative integer'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let n = len(a:list)
 | 
				
			||||||
 | 
					  let result = []
 | 
				
			||||||
 | 
					  for indices in s:product(map(range(r), 'range(n)'))
 | 
				
			||||||
 | 
					    if len(s:uniq(indices)) == r
 | 
				
			||||||
 | 
					      call add(result, map(indices, 'a:list[v:val]'))
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return result
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:combinations(list, r) abort
 | 
				
			||||||
 | 
					  if a:r > len(a:list)
 | 
				
			||||||
 | 
					    return []
 | 
				
			||||||
 | 
					  elseif a:r < 0
 | 
				
			||||||
 | 
					    throw 'vital: Data:List: {r} must be non-negative integer'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let n = len(a:list)
 | 
				
			||||||
 | 
					  let result = []
 | 
				
			||||||
 | 
					  for indices in s:permutations(range(n), a:r)
 | 
				
			||||||
 | 
					    if s:sort(copy(indices), 'a:a - a:b') == indices
 | 
				
			||||||
 | 
					      call add(result, map(indices, 'a:list[v:val]'))
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return result
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let &cpo = s:save_cpo
 | 
				
			||||||
 | 
					unlet s:save_cpo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" vim:set et ts=2 sts=2 sw=2 tw=0:
 | 
				
			||||||
@ -0,0 +1,633 @@
 | 
				
			|||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					" NOTE: lines between '" ___vital___' is generated by :Vitalize.
 | 
				
			||||||
 | 
					" Do not mofidify the code nor insert new lines before '" ___vital___'
 | 
				
			||||||
 | 
					if v:version > 703 || v:version == 703 && has('patch1170')
 | 
				
			||||||
 | 
					  function! vital#_tsuquyomi#Data#String#import() abort
 | 
				
			||||||
 | 
					    return map({'starts_with': '', 'split3': '', 'replace_first': '', 'chop': '', 'unescape': '', 'split_posix_text': '', 'replace': '', 'scan': '', 'strwidthpart': '', 'common_head': '', 'reverse': '', 'escape_pattern': '', 'trim_end': '', '_vital_depends': '', 'wrap': '', 'join_posix_lines': '', 'contains_multibyte': '', 'truncate_skipping': '', 'split_leftright': '', 'ends_with': '', 'nsplit': '', 'strwidthpart_reverse': '', 'unescape_pattern': '', 'levenshtein_distance': '', 'trim_start': '', 'justify_equal_spacing': '', 'nr2hex': '', 'iconv': '', 'pad_left': '', 'nr2enc_char': '', 'lines': '', 'repair_posix_text': '', 'nr2byte': '', 'trim': '', 'diffidx': '', 'truncate': '', 'split_by_displaywidth': '', '_vital_created': '', 'padding_by_displaywidth': '', 'hash': '', 'chomp': '', 'pad_between_letters': '', 'dstring': '', 'pad_both_sides': '', 'substitute_last': '', 'pad_right': '', 'remove_ansi_sequences': '', '_vital_loaded': ''},  'function("s:" . v:key)')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:_SID() abort
 | 
				
			||||||
 | 
					    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					  execute join(['function! vital#_tsuquyomi#Data#String#import() abort', printf("return map({'starts_with': '', 'split3': '', 'replace_first': '', 'chop': '', 'unescape': '', 'split_posix_text': '', 'replace': '', 'scan': '', 'strwidthpart': '', 'common_head': '', 'reverse': '', 'escape_pattern': '', 'trim_end': '', '_vital_depends': '', 'wrap': '', 'join_posix_lines': '', 'contains_multibyte': '', 'truncate_skipping': '', 'split_leftright': '', 'ends_with': '', 'nsplit': '', 'strwidthpart_reverse': '', 'unescape_pattern': '', 'levenshtein_distance': '', 'trim_start': '', 'justify_equal_spacing': '', 'nr2hex': '', 'iconv': '', 'pad_left': '', 'nr2enc_char': '', 'lines': '', 'repair_posix_text': '', 'nr2byte': '', 'trim': '', 'diffidx': '', 'truncate': '', 'split_by_displaywidth': '', '_vital_created': '', 'padding_by_displaywidth': '', 'hash': '', 'chomp': '', 'pad_between_letters': '', 'dstring': '', 'pad_both_sides': '', 'substitute_last': '', 'pad_right': '', 'remove_ansi_sequences': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
 | 
				
			||||||
 | 
					  delfunction s:_SID
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					" Utilities for string.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:save_cpo = &cpo
 | 
				
			||||||
 | 
					set cpo&vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_vital_loaded(V) abort
 | 
				
			||||||
 | 
					  let s:V = a:V
 | 
				
			||||||
 | 
					  let s:L = s:V.import('Data.List')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_vital_depends() abort
 | 
				
			||||||
 | 
					  return ['Data.List']
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_vital_created(module) abort
 | 
				
			||||||
 | 
					  " Expose script-local funcref
 | 
				
			||||||
 | 
					  if exists('s:strchars')
 | 
				
			||||||
 | 
					    let a:module.strchars = s:strchars
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  if exists('s:wcswidth')
 | 
				
			||||||
 | 
					    let a:module.wcswidth = s:wcswidth
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Substitute a:from => a:to by string.
 | 
				
			||||||
 | 
					" To substitute by pattern, use substitute() instead.
 | 
				
			||||||
 | 
					function! s:replace(str, from, to) abort
 | 
				
			||||||
 | 
					  return s:_replace(a:str, a:from, a:to, 'g')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Substitute a:from => a:to only once.
 | 
				
			||||||
 | 
					" cf. s:replace()
 | 
				
			||||||
 | 
					function! s:replace_first(str, from, to) abort
 | 
				
			||||||
 | 
					  return s:_replace(a:str, a:from, a:to, '')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" implement of replace() and replace_first()
 | 
				
			||||||
 | 
					function! s:_replace(str, from, to, flags) abort
 | 
				
			||||||
 | 
					  return substitute(a:str, '\V'.escape(a:from, '\'), escape(a:to, '\'), a:flags)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:scan(str, pattern) abort
 | 
				
			||||||
 | 
					  let list = []
 | 
				
			||||||
 | 
					  call substitute(a:str, a:pattern, '\=add(list, submatch(0)) == [] ? "" : ""', 'g')
 | 
				
			||||||
 | 
					  return list
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:reverse(str) abort
 | 
				
			||||||
 | 
					  return join(reverse(split(a:str, '.\zs')), '')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:starts_with(str, prefix) abort
 | 
				
			||||||
 | 
					  return stridx(a:str, a:prefix) == 0
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:ends_with(str, suffix) abort
 | 
				
			||||||
 | 
					  let idx = strridx(a:str, a:suffix)
 | 
				
			||||||
 | 
					  return 0 <= idx && idx + len(a:suffix) == len(a:str)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:common_head(strs) abort
 | 
				
			||||||
 | 
					  if empty(a:strs)
 | 
				
			||||||
 | 
					    return ''
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let len = len(a:strs)
 | 
				
			||||||
 | 
					  if len == 1
 | 
				
			||||||
 | 
					    return a:strs[0]
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let strs = len == 2 ? a:strs : sort(copy(a:strs))
 | 
				
			||||||
 | 
					  let pat = substitute(strs[0], '.', '\="[" . escape(submatch(0), "^\\") . "]"', 'g')
 | 
				
			||||||
 | 
					  return pat ==# '' ? '' : matchstr(strs[-1], '\C^\%[' . pat . ']')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Split to two elements of List. ([left, right])
 | 
				
			||||||
 | 
					" e.g.: s:split3('neocomplcache', 'compl') returns ['neo', 'compl', 'cache']
 | 
				
			||||||
 | 
					function! s:split_leftright(expr, pattern) abort
 | 
				
			||||||
 | 
					  let [left, _, right] = s:split3(a:expr, a:pattern)
 | 
				
			||||||
 | 
					  return [left, right]
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:split3(expr, pattern) abort
 | 
				
			||||||
 | 
					  let ERROR = ['', '', '']
 | 
				
			||||||
 | 
					  if a:expr ==# '' || a:pattern ==# ''
 | 
				
			||||||
 | 
					    return ERROR
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let begin = match(a:expr, a:pattern)
 | 
				
			||||||
 | 
					  if begin is -1
 | 
				
			||||||
 | 
					    return ERROR
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let end   = matchend(a:expr, a:pattern)
 | 
				
			||||||
 | 
					  let left  = begin <=# 0 ? '' : a:expr[: begin - 1]
 | 
				
			||||||
 | 
					  let right = a:expr[end :]
 | 
				
			||||||
 | 
					  return [left, a:expr[begin : end-1], right]
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Slices into strings determines the number of substrings.
 | 
				
			||||||
 | 
					" e.g.: s:nsplit("neo compl cache", 2, '\s') returns ['neo', 'compl cache']
 | 
				
			||||||
 | 
					function! s:nsplit(expr, n, ...) abort
 | 
				
			||||||
 | 
					  let pattern = get(a:000, 0, '\s')
 | 
				
			||||||
 | 
					  let keepempty = get(a:000, 1, 1)
 | 
				
			||||||
 | 
					  let ret = []
 | 
				
			||||||
 | 
					  let expr = a:expr
 | 
				
			||||||
 | 
					  if a:n <= 1
 | 
				
			||||||
 | 
					    return [expr]
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  while 1
 | 
				
			||||||
 | 
					    let pos = match(expr, pattern)
 | 
				
			||||||
 | 
					    if pos == -1
 | 
				
			||||||
 | 
					      if expr !~ pattern || keepempty
 | 
				
			||||||
 | 
					        call add(ret, expr)
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
 | 
					    elseif pos >= 0
 | 
				
			||||||
 | 
					      let left = pos > 0 ? expr[:pos-1] : ''
 | 
				
			||||||
 | 
					      if pos > 0 || keepempty
 | 
				
			||||||
 | 
					        call add(ret, left)
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      let ml = len(matchstr(expr, pattern))
 | 
				
			||||||
 | 
					      if pos == 0 && ml == 0
 | 
				
			||||||
 | 
					        let pos = 1
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      let expr = expr[pos+ml :]
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if len(expr) == 0
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if len(ret) == a:n - 1
 | 
				
			||||||
 | 
					      call add(ret, expr)
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					  return ret
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Returns the number of character in a:str.
 | 
				
			||||||
 | 
					" NOTE: This returns proper value
 | 
				
			||||||
 | 
					" even if a:str contains multibyte character(s).
 | 
				
			||||||
 | 
					" s:strchars(str) {{{
 | 
				
			||||||
 | 
					if exists('*strchars')
 | 
				
			||||||
 | 
					  let s:strchars = function('strchars')
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:strchars(str) abort
 | 
				
			||||||
 | 
					    return strlen(substitute(copy(a:str), '.', 'x', 'g'))
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif "}}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Returns the bool of contains any multibyte character in s:str
 | 
				
			||||||
 | 
					function! s:contains_multibyte(str) abort "{{{
 | 
				
			||||||
 | 
					  return strlen(a:str) != s:strchars(a:str)
 | 
				
			||||||
 | 
					endfunction "}}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Remove last character from a:str.
 | 
				
			||||||
 | 
					" NOTE: This returns proper value
 | 
				
			||||||
 | 
					" even if a:str contains multibyte character(s).
 | 
				
			||||||
 | 
					function! s:chop(str) abort "{{{
 | 
				
			||||||
 | 
					  return substitute(a:str, '.$', '', '')
 | 
				
			||||||
 | 
					endfunction "}}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Remove last \r,\n,\r\n from a:str.
 | 
				
			||||||
 | 
					function! s:chomp(str) abort "{{{
 | 
				
			||||||
 | 
					  return substitute(a:str, '\%(\r\n\|[\r\n]\)$', '', '')
 | 
				
			||||||
 | 
					endfunction "}}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" wrap() and its internal functions
 | 
				
			||||||
 | 
					" * _split_by_wcswidth_once()
 | 
				
			||||||
 | 
					" * _split_by_wcswidth()
 | 
				
			||||||
 | 
					" * _concat()
 | 
				
			||||||
 | 
					" * wrap()
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" NOTE _concat() is just a copy of Data.List.concat().
 | 
				
			||||||
 | 
					" FIXME don't repeat yourself
 | 
				
			||||||
 | 
					function! s:_split_by_wcswidth_once(body, x) abort
 | 
				
			||||||
 | 
					  let fst = s:strwidthpart(a:body, a:x)
 | 
				
			||||||
 | 
					  let snd = s:strwidthpart_reverse(a:body, s:wcswidth(a:body) - s:wcswidth(fst))
 | 
				
			||||||
 | 
					  return [fst, snd]
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_split_by_wcswidth(body, x) abort
 | 
				
			||||||
 | 
					  let memo = []
 | 
				
			||||||
 | 
					  let body = a:body
 | 
				
			||||||
 | 
					  while s:wcswidth(body) > a:x
 | 
				
			||||||
 | 
					    let [tmp, body] = s:_split_by_wcswidth_once(body, a:x)
 | 
				
			||||||
 | 
					    call add(memo, tmp)
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					  call add(memo, body)
 | 
				
			||||||
 | 
					  return memo
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:trim(str) abort
 | 
				
			||||||
 | 
					  return matchstr(a:str,'^\s*\zs.\{-}\ze\s*$')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:trim_start(str) abort
 | 
				
			||||||
 | 
					  return matchstr(a:str,'^\s*\zs.\{-}$')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:trim_end(str) abort
 | 
				
			||||||
 | 
					  return matchstr(a:str,'^.\{-}\ze\s*$')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:wrap(str,...) abort
 | 
				
			||||||
 | 
					  let _columns = a:0 > 0 ? a:1 : &columns
 | 
				
			||||||
 | 
					  return s:L.concat(
 | 
				
			||||||
 | 
					        \ map(split(a:str, '\r\n\|[\r\n]'), 's:_split_by_wcswidth(v:val, _columns - 1)'))
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:nr2byte(nr) abort
 | 
				
			||||||
 | 
					  if a:nr < 0x80
 | 
				
			||||||
 | 
					    return nr2char(a:nr)
 | 
				
			||||||
 | 
					  elseif a:nr < 0x800
 | 
				
			||||||
 | 
					    return nr2char(a:nr/64+192).nr2char(a:nr%64+128)
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return nr2char(a:nr/4096%16+224).nr2char(a:nr/64%64+128).nr2char(a:nr%64+128)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:nr2enc_char(charcode) abort
 | 
				
			||||||
 | 
					  if &encoding ==# 'utf-8'
 | 
				
			||||||
 | 
					    return nr2char(a:charcode)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let char = s:nr2byte(a:charcode)
 | 
				
			||||||
 | 
					  if strlen(char) > 1
 | 
				
			||||||
 | 
					    let char = strtrans(iconv(char, 'utf-8', &encoding))
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return char
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:nr2hex(nr) abort
 | 
				
			||||||
 | 
					  let n = a:nr
 | 
				
			||||||
 | 
					  let r = ''
 | 
				
			||||||
 | 
					  while n
 | 
				
			||||||
 | 
					    let r = '0123456789ABCDEF'[n % 16] . r
 | 
				
			||||||
 | 
					    let n = n / 16
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					  return r
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" If a ==# b, returns -1.
 | 
				
			||||||
 | 
					" If a !=# b, returns first index of different character.
 | 
				
			||||||
 | 
					function! s:diffidx(a, b) abort
 | 
				
			||||||
 | 
					  return a:a ==# a:b ? -1 : strlen(s:common_head([a:a, a:b]))
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:substitute_last(expr, pat, sub) abort
 | 
				
			||||||
 | 
					  return substitute(a:expr, printf('.*\zs%s', a:pat), a:sub, '')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:dstring(expr) abort
 | 
				
			||||||
 | 
					  let x = substitute(string(a:expr), "^'\\|'$", '', 'g')
 | 
				
			||||||
 | 
					  let x = substitute(x, "''", "'", 'g')
 | 
				
			||||||
 | 
					  return printf('"%s"', escape(x, '"'))
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:lines(str) abort
 | 
				
			||||||
 | 
					  return split(a:str, '\r\?\n')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_pad_with_char(str, left, right, char) abort
 | 
				
			||||||
 | 
					  return repeat(a:char, a:left). a:str. repeat(a:char, a:right)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:pad_left(str, width, ...) abort
 | 
				
			||||||
 | 
					  let char = get(a:, 1, ' ')
 | 
				
			||||||
 | 
					  if strdisplaywidth(char) != 1
 | 
				
			||||||
 | 
					    throw "vital: Data.String: Can't use non-half-width characters for padding."
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let left = max([0, a:width - strdisplaywidth(a:str)])
 | 
				
			||||||
 | 
					  return s:_pad_with_char(a:str, left, 0, char)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:pad_right(str, width, ...) abort
 | 
				
			||||||
 | 
					  let char = get(a:, 1, ' ')
 | 
				
			||||||
 | 
					  if strdisplaywidth(char) != 1
 | 
				
			||||||
 | 
					    throw "vital: Data.String: Can't use non-half-width characters for padding."
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let right = max([0, a:width - strdisplaywidth(a:str)])
 | 
				
			||||||
 | 
					  return s:_pad_with_char(a:str, 0, right, char)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:pad_both_sides(str, width, ...) abort
 | 
				
			||||||
 | 
					  let char = get(a:, 1, ' ')
 | 
				
			||||||
 | 
					  if strdisplaywidth(char) != 1
 | 
				
			||||||
 | 
					    throw "vital: Data.String: Can't use non-half-width characters for padding."
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let space = max([0, a:width - strdisplaywidth(a:str)])
 | 
				
			||||||
 | 
					  let left = space / 2
 | 
				
			||||||
 | 
					  let right = space - left
 | 
				
			||||||
 | 
					  return s:_pad_with_char(a:str, left, right, char)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:pad_between_letters(str, width, ...) abort
 | 
				
			||||||
 | 
					  let char = get(a:, 1, ' ')
 | 
				
			||||||
 | 
					  if strdisplaywidth(char) != 1
 | 
				
			||||||
 | 
					    throw "vital: Data.String: Can't use non-half-width characters for padding."
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let letters = split(a:str, '\zs')
 | 
				
			||||||
 | 
					  let each_width = a:width / len(letters)
 | 
				
			||||||
 | 
					  let str = join(map(letters, 's:pad_both_sides(v:val, each_width, char)'), '')
 | 
				
			||||||
 | 
					  if a:width - strdisplaywidth(str) > 0
 | 
				
			||||||
 | 
					    return char. s:pad_both_sides(str, a:width - 1, char)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return str
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:justify_equal_spacing(str, width, ...) abort
 | 
				
			||||||
 | 
					  let char = get(a:, 1, ' ')
 | 
				
			||||||
 | 
					  if strdisplaywidth(char) != 1
 | 
				
			||||||
 | 
					    throw "vital: Data.String: Can't use non-half-width characters for padding."
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let letters = split(a:str, '\zs')
 | 
				
			||||||
 | 
					  let first_letter = letters[0]
 | 
				
			||||||
 | 
					  " {width w/o the first letter} / {length w/o the first letter}
 | 
				
			||||||
 | 
					  let each_width = (a:width - strdisplaywidth(first_letter)) / (len(letters) - 1)
 | 
				
			||||||
 | 
					  let remainder = (a:width - strdisplaywidth(first_letter)) % (len(letters) - 1)
 | 
				
			||||||
 | 
					  return first_letter. join(s:L.concat([
 | 
				
			||||||
 | 
					\     map(letters[1:remainder], 's:pad_left(v:val, each_width + 1, char)'),
 | 
				
			||||||
 | 
					\     map(letters[remainder + 1:], 's:pad_left(v:val, each_width, char)')
 | 
				
			||||||
 | 
					\   ]), '')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:levenshtein_distance(str1, str2) abort
 | 
				
			||||||
 | 
					  let letters1 = split(a:str1, '\zs')
 | 
				
			||||||
 | 
					  let letters2 = split(a:str2, '\zs')
 | 
				
			||||||
 | 
					  let length1 = len(letters1)
 | 
				
			||||||
 | 
					  let length2 = len(letters2)
 | 
				
			||||||
 | 
					  let distances = map(range(1, length1 + 1), 'map(range(1, length2 + 1), ''0'')')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for i1 in range(0, length1)
 | 
				
			||||||
 | 
					    let distances[i1][0] = i1
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  for i2 in range(0, length2)
 | 
				
			||||||
 | 
					    let distances[0][i2] = i2
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for i1 in range(1, length1)
 | 
				
			||||||
 | 
					    for i2 in range(1, length2)
 | 
				
			||||||
 | 
					      let cost = (letters1[i1 - 1] ==# letters2[i2 - 1]) ? 0 : 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      let distances[i1][i2] = min([
 | 
				
			||||||
 | 
					      \ distances[i1 - 1][i2    ] + 1,
 | 
				
			||||||
 | 
					      \ distances[i1    ][i2 - 1] + 1,
 | 
				
			||||||
 | 
					      \ distances[i1 - 1][i2 - 1] + cost,
 | 
				
			||||||
 | 
					      \])
 | 
				
			||||||
 | 
					    endfor
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return distances[length1][length2]
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:padding_by_displaywidth(expr, width, float) abort
 | 
				
			||||||
 | 
					  let padding_char = ' '
 | 
				
			||||||
 | 
					  let n = a:width - strdisplaywidth(a:expr)
 | 
				
			||||||
 | 
					  if n <= 0
 | 
				
			||||||
 | 
					    let n = 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  if a:float < 0
 | 
				
			||||||
 | 
					    return a:expr . repeat(padding_char, n)
 | 
				
			||||||
 | 
					  elseif 0 < a:float
 | 
				
			||||||
 | 
					    return repeat(padding_char, n) . a:expr
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    if n % 2 is 0
 | 
				
			||||||
 | 
					      return repeat(padding_char, n / 2) . a:expr . repeat(padding_char, n / 2)
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      return repeat(padding_char, (n - 1) / 2) . a:expr . repeat(padding_char, (n - 1) / 2) . padding_char
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:split_by_displaywidth(expr, width, float, is_wrap) abort
 | 
				
			||||||
 | 
					  if a:width is 0
 | 
				
			||||||
 | 
					    return ['']
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let lines = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let cs = split(a:expr, '\zs')
 | 
				
			||||||
 | 
					  let cs_index = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let text = ''
 | 
				
			||||||
 | 
					  while cs_index < len(cs)
 | 
				
			||||||
 | 
					    if cs[cs_index] is# "\n"
 | 
				
			||||||
 | 
					      let text = s:padding_by_displaywidth(text, a:width, a:float)
 | 
				
			||||||
 | 
					      let lines += [text]
 | 
				
			||||||
 | 
					      let text = ''
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let w = strdisplaywidth(text . cs[cs_index])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if w < a:width
 | 
				
			||||||
 | 
					        let text .= cs[cs_index]
 | 
				
			||||||
 | 
					      elseif a:width < w
 | 
				
			||||||
 | 
					        let text = s:padding_by_displaywidth(text, a:width, a:float)
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        let text .= cs[cs_index]
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if a:width <= w
 | 
				
			||||||
 | 
					        let lines += [text]
 | 
				
			||||||
 | 
					        let text = ''
 | 
				
			||||||
 | 
					        if a:is_wrap
 | 
				
			||||||
 | 
					          if a:width < w
 | 
				
			||||||
 | 
					            if a:width < strdisplaywidth(cs[cs_index])
 | 
				
			||||||
 | 
					              while get(cs, cs_index, "\n") isnot# "\n"
 | 
				
			||||||
 | 
					                let cs_index += 1
 | 
				
			||||||
 | 
					              endwhile
 | 
				
			||||||
 | 
					              continue
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					              let text = cs[cs_index]
 | 
				
			||||||
 | 
					            endif
 | 
				
			||||||
 | 
					          endif
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          while get(cs, cs_index, "\n") isnot# "\n"
 | 
				
			||||||
 | 
					            let cs_index += 1
 | 
				
			||||||
 | 
					          endwhile
 | 
				
			||||||
 | 
					          continue
 | 
				
			||||||
 | 
					        endif
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    let cs_index += 1
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if !empty(text)
 | 
				
			||||||
 | 
					    let lines += [ s:padding_by_displaywidth(text, a:width, a:float) ]
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return lines
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:hash(str) abort
 | 
				
			||||||
 | 
					  if exists('*sha256')
 | 
				
			||||||
 | 
					    return sha256(a:str)
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    " This gives up sha256ing but just adds up char with index.
 | 
				
			||||||
 | 
					    let sum = 0
 | 
				
			||||||
 | 
					    for i in range(len(a:str))
 | 
				
			||||||
 | 
					      let sum += char2nr(a:str[i]) * (i + 1)
 | 
				
			||||||
 | 
					    endfor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return printf('%x', sum)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:truncate(str, width) abort
 | 
				
			||||||
 | 
					  " Original function is from mattn.
 | 
				
			||||||
 | 
					  " http://github.com/mattn/googlereader-vim/tree/master
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if a:str =~# '^[\x00-\x7f]*$'
 | 
				
			||||||
 | 
					    return len(a:str) < a:width
 | 
				
			||||||
 | 
					          \ ? printf('%-' . a:width . 's', a:str)
 | 
				
			||||||
 | 
					          \ : strpart(a:str, 0, a:width)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let ret = a:str
 | 
				
			||||||
 | 
					  let width = s:wcswidth(a:str)
 | 
				
			||||||
 | 
					  if width > a:width
 | 
				
			||||||
 | 
					    let ret = s:strwidthpart(ret, a:width)
 | 
				
			||||||
 | 
					    let width = s:wcswidth(ret)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if width < a:width
 | 
				
			||||||
 | 
					    let ret .= repeat(' ', a:width - width)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return ret
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:truncate_skipping(str, max, footer_width, separator) abort
 | 
				
			||||||
 | 
					  let width = s:wcswidth(a:str)
 | 
				
			||||||
 | 
					  if width <= a:max
 | 
				
			||||||
 | 
					    let ret = a:str
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    let header_width = a:max - s:wcswidth(a:separator) - a:footer_width
 | 
				
			||||||
 | 
					    let ret = s:strwidthpart(a:str, header_width) . a:separator
 | 
				
			||||||
 | 
					          \ . s:strwidthpart_reverse(a:str, a:footer_width)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return s:truncate(ret, a:max)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:strwidthpart(str, width) abort
 | 
				
			||||||
 | 
					  let str = tr(a:str, "\t", ' ')
 | 
				
			||||||
 | 
					  let vcol = a:width + 2
 | 
				
			||||||
 | 
					  return matchstr(str, '.*\%<' . (vcol < 0 ? 0 : vcol) . 'v')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:strwidthpart_reverse(str, width) abort
 | 
				
			||||||
 | 
					  let str = tr(a:str, "\t", ' ')
 | 
				
			||||||
 | 
					  let vcol = s:wcswidth(str) - a:width
 | 
				
			||||||
 | 
					  return matchstr(str, '\%>' . (vcol < 0 ? 0 : vcol) . 'v.*')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if v:version >= 703
 | 
				
			||||||
 | 
					  " Use builtin function.
 | 
				
			||||||
 | 
					  let s:wcswidth = function('strwidth')
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:wcswidth(str) abort
 | 
				
			||||||
 | 
					    if a:str =~# '^[\x00-\x7f]*$'
 | 
				
			||||||
 | 
					      return strlen(a:str)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    let mx_first = '^\(.\)'
 | 
				
			||||||
 | 
					    let str = a:str
 | 
				
			||||||
 | 
					    let width = 0
 | 
				
			||||||
 | 
					    while 1
 | 
				
			||||||
 | 
					      let ucs = char2nr(substitute(str, mx_first, '\1', ''))
 | 
				
			||||||
 | 
					      if ucs == 0
 | 
				
			||||||
 | 
					        break
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      let width += s:_wcwidth(ucs)
 | 
				
			||||||
 | 
					      let str = substitute(str, mx_first, '', '')
 | 
				
			||||||
 | 
					    endwhile
 | 
				
			||||||
 | 
					    return width
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  " UTF-8 only.
 | 
				
			||||||
 | 
					  function! s:_wcwidth(ucs) abort
 | 
				
			||||||
 | 
					    let ucs = a:ucs
 | 
				
			||||||
 | 
					    if (ucs >= 0x1100
 | 
				
			||||||
 | 
					          \  && (ucs <= 0x115f
 | 
				
			||||||
 | 
					          \  || ucs == 0x2329
 | 
				
			||||||
 | 
					          \  || ucs == 0x232a
 | 
				
			||||||
 | 
					          \  || (ucs >= 0x2e80 && ucs <= 0xa4cf
 | 
				
			||||||
 | 
					          \      && ucs != 0x303f)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0xac00 && ucs <= 0xd7a3)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0xf900 && ucs <= 0xfaff)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0xfe30 && ucs <= 0xfe6f)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0xff00 && ucs <= 0xff60)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0xffe0 && ucs <= 0xffe6)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0x20000 && ucs <= 0x2fffd)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0x30000 && ucs <= 0x3fffd)
 | 
				
			||||||
 | 
					          \  ))
 | 
				
			||||||
 | 
					      return 2
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:remove_ansi_sequences(text) abort
 | 
				
			||||||
 | 
					  return substitute(a:text, '\e\[\%(\%(\d;\)\?\d\{1,2}\)\?[mK]', '', 'g')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:escape_pattern(str) abort
 | 
				
			||||||
 | 
					  " escape characters for no-magic
 | 
				
			||||||
 | 
					  return escape(a:str, '^$~.*[]\')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:unescape_pattern(str) abort
 | 
				
			||||||
 | 
					  " unescape characters for no-magic
 | 
				
			||||||
 | 
					  return s:unescape(a:str, '^$~.*[]\')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:unescape(str, chars) abort
 | 
				
			||||||
 | 
					  let chars = map(split(a:chars, '\zs'), 'escape(v:val, ''^$~.*[]\'')')
 | 
				
			||||||
 | 
					  return substitute(a:str, '\\\(' . join(chars, '\|') . '\)', '\1', 'g')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:iconv(expr, from, to) abort
 | 
				
			||||||
 | 
					  if a:from ==# '' || a:to ==# '' || a:from ==? a:to
 | 
				
			||||||
 | 
					    return a:expr
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let result = iconv(a:expr, a:from, a:to)
 | 
				
			||||||
 | 
					  return empty(result) ? a:expr : result
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" NOTE:
 | 
				
			||||||
 | 
					" A definition of a TEXT file is "A file that contains characters organized
 | 
				
			||||||
 | 
					" into one or more lines."
 | 
				
			||||||
 | 
					" A definition of a LINE is "A sequence of zero or more non- <newline>s
 | 
				
			||||||
 | 
					" plus a terminating <newline>"
 | 
				
			||||||
 | 
					" That's why {stdin} always ends with <newline> ideally. However, there are
 | 
				
			||||||
 | 
					" some programs which does not follow the POSIX rule and a Vim's way to join
 | 
				
			||||||
 | 
					" List into TEXT; join({text}, "\n"); does not add <newline> to the end of
 | 
				
			||||||
 | 
					" the last line.
 | 
				
			||||||
 | 
					" That's why add a trailing <newline> if it does not exist.
 | 
				
			||||||
 | 
					" REF:
 | 
				
			||||||
 | 
					" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_392
 | 
				
			||||||
 | 
					" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_205
 | 
				
			||||||
 | 
					" :help split()
 | 
				
			||||||
 | 
					" NOTE:
 | 
				
			||||||
 | 
					" it does nothing if the text is a correct POSIX text
 | 
				
			||||||
 | 
					function! s:repair_posix_text(text, ...) abort
 | 
				
			||||||
 | 
					  let newline = get(a:000, 0, "\n")
 | 
				
			||||||
 | 
					  return a:text =~# '\n$' ? a:text : a:text . newline
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" NOTE:
 | 
				
			||||||
 | 
					" A definition of a TEXT file is "A file that contains characters organized
 | 
				
			||||||
 | 
					" into one or more lines."
 | 
				
			||||||
 | 
					" A definition of a LINE is "A sequence of zero or more non- <newline>s
 | 
				
			||||||
 | 
					" plus a terminating <newline>"
 | 
				
			||||||
 | 
					" REF:
 | 
				
			||||||
 | 
					" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_392
 | 
				
			||||||
 | 
					" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_205
 | 
				
			||||||
 | 
					function! s:join_posix_lines(lines, ...) abort
 | 
				
			||||||
 | 
					  let newline = get(a:000, 0, "\n")
 | 
				
			||||||
 | 
					  return join(a:lines, newline) . newline
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" NOTE:
 | 
				
			||||||
 | 
					" A definition of a TEXT file is "A file that contains characters organized
 | 
				
			||||||
 | 
					" into one or more lines."
 | 
				
			||||||
 | 
					" A definition of a LINE is "A sequence of zero or more non- <newline>s
 | 
				
			||||||
 | 
					" plus a terminating <newline>"
 | 
				
			||||||
 | 
					" TEXT into List; split({text}, '\r\?\n', 1); add an extra empty line at the
 | 
				
			||||||
 | 
					" end of List because the end of TEXT ends with <newline> and keepempty=1 is
 | 
				
			||||||
 | 
					" specified. (btw. keepempty=0 cannot be used because it will remove
 | 
				
			||||||
 | 
					" emptylines in the head and the tail).
 | 
				
			||||||
 | 
					" That's why removing a trailing <newline> before proceeding to 'split' is required
 | 
				
			||||||
 | 
					" REF:
 | 
				
			||||||
 | 
					" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_392
 | 
				
			||||||
 | 
					" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_205
 | 
				
			||||||
 | 
					function! s:split_posix_text(text, ...) abort
 | 
				
			||||||
 | 
					  let newline = get(a:000, 0, '\r\?\n')
 | 
				
			||||||
 | 
					  let text = substitute(a:text, newline . '$', '', '')
 | 
				
			||||||
 | 
					  return split(text, newline, 1)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let &cpo = s:save_cpo
 | 
				
			||||||
 | 
					unlet s:save_cpo
 | 
				
			||||||
 | 
					" vim:set et ts=2 sts=2 sw=2 tw=0:
 | 
				
			||||||
@ -0,0 +1,409 @@
 | 
				
			|||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					" NOTE: lines between '" ___vital___' is generated by :Vitalize.
 | 
				
			||||||
 | 
					" Do not mofidify the code nor insert new lines before '" ___vital___'
 | 
				
			||||||
 | 
					if v:version > 703 || v:version == 703 && has('patch1170')
 | 
				
			||||||
 | 
					  function! vital#_tsuquyomi#Prelude#import() abort
 | 
				
			||||||
 | 
					    return map({'escape_pattern': '', 'is_funcref': '', 'path2directory': '', 'wcswidth': '', 'is_string': '', 'input_helper': '', 'is_number': '', 'is_cygwin': '', 'path2project_directory': '', 'strwidthpart_reverse': '', 'input_safe': '', 'is_list': '', 'truncate_skipping': '', 'glob': '', 'truncate': '', 'is_dict': '', 'set_default': '', 'is_numeric': '', 'getchar_safe': '', 'substitute_path_separator': '', 'is_mac': '', 'strwidthpart': '', 'getchar': '', 'is_unix': '', 'is_windows': '', 'globpath': '', 'escape_file_searching': '', 'is_float': '', 'smart_execute_command': ''},  'function("s:" . v:key)')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:_SID() abort
 | 
				
			||||||
 | 
					    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					  execute join(['function! vital#_tsuquyomi#Prelude#import() abort', printf("return map({'escape_pattern': '', 'is_funcref': '', 'path2directory': '', 'wcswidth': '', 'is_string': '', 'input_helper': '', 'is_number': '', 'is_cygwin': '', 'path2project_directory': '', 'strwidthpart_reverse': '', 'input_safe': '', 'is_list': '', 'truncate_skipping': '', 'glob': '', 'truncate': '', 'is_dict': '', 'set_default': '', 'is_numeric': '', 'getchar_safe': '', 'substitute_path_separator': '', 'is_mac': '', 'strwidthpart': '', 'getchar': '', 'is_unix': '', 'is_windows': '', 'globpath': '', 'escape_file_searching': '', 'is_float': '', 'smart_execute_command': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
 | 
				
			||||||
 | 
					  delfunction s:_SID
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					let s:save_cpo = &cpo
 | 
				
			||||||
 | 
					set cpo&vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if v:version > 703 ||
 | 
				
			||||||
 | 
					\  (v:version == 703 && has('patch465'))
 | 
				
			||||||
 | 
					  function! s:glob(expr) abort
 | 
				
			||||||
 | 
					    return glob(a:expr, 1, 1)
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:glob(expr) abort
 | 
				
			||||||
 | 
					    return split(glob(a:expr, 1), '\n')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if v:version > 704 ||
 | 
				
			||||||
 | 
					\  (v:version == 704 && has('patch279'))
 | 
				
			||||||
 | 
					  function! s:globpath(path, expr) abort
 | 
				
			||||||
 | 
					    return globpath(a:path, a:expr, 1, 1)
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:globpath(path, expr) abort
 | 
				
			||||||
 | 
					    return split(globpath(a:path, a:expr, 1), '\n')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Wrapper functions for type().
 | 
				
			||||||
 | 
					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({}),
 | 
				
			||||||
 | 
					      \   has('float') ? type(str2float('0')) : -1]
 | 
				
			||||||
 | 
					" __TYPE_FLOAT = -1 when -float
 | 
				
			||||||
 | 
					" This doesn't match to anything.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Number or Float
 | 
				
			||||||
 | 
					function! s:is_numeric(Value) abort
 | 
				
			||||||
 | 
					  let _ = type(a:Value)
 | 
				
			||||||
 | 
					  return _ ==# s:__TYPE_NUMBER
 | 
				
			||||||
 | 
					  \   || _ ==# s:__TYPE_FLOAT
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Number
 | 
				
			||||||
 | 
					function! s:is_number(Value) abort
 | 
				
			||||||
 | 
					  return type(a:Value) ==# s:__TYPE_NUMBER
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Float
 | 
				
			||||||
 | 
					function! s:is_float(Value) abort
 | 
				
			||||||
 | 
					  return type(a:Value) ==# s:__TYPE_FLOAT
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					" String
 | 
				
			||||||
 | 
					function! s:is_string(Value) abort
 | 
				
			||||||
 | 
					  return type(a:Value) ==# s:__TYPE_STRING
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					" Funcref
 | 
				
			||||||
 | 
					function! s:is_funcref(Value) abort
 | 
				
			||||||
 | 
					  return type(a:Value) ==# s:__TYPE_FUNCREF
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					" List
 | 
				
			||||||
 | 
					function! s:is_list(Value) abort
 | 
				
			||||||
 | 
					  return type(a:Value) ==# s:__TYPE_LIST
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					" Dictionary
 | 
				
			||||||
 | 
					function! s:is_dict(Value) abort
 | 
				
			||||||
 | 
					  return type(a:Value) ==# s:__TYPE_DICT
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:truncate_skipping(str, max, footer_width, separator) abort
 | 
				
			||||||
 | 
					  call s:_warn_deprecated('truncate_skipping', 'Data.String.truncate_skipping')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let width = s:wcswidth(a:str)
 | 
				
			||||||
 | 
					  if width <= a:max
 | 
				
			||||||
 | 
					    let ret = a:str
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    let header_width = a:max - s:wcswidth(a:separator) - a:footer_width
 | 
				
			||||||
 | 
					    let ret = s:strwidthpart(a:str, header_width) . a:separator
 | 
				
			||||||
 | 
					          \ . s:strwidthpart_reverse(a:str, a:footer_width)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return s:truncate(ret, a:max)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:truncate(str, width) abort
 | 
				
			||||||
 | 
					  " Original function is from mattn.
 | 
				
			||||||
 | 
					  " http://github.com/mattn/googlereader-vim/tree/master
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  call s:_warn_deprecated('truncate', 'Data.String.truncate')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if a:str =~# '^[\x00-\x7f]*$'
 | 
				
			||||||
 | 
					    return len(a:str) < a:width ?
 | 
				
			||||||
 | 
					          \ printf('%-'.a:width.'s', a:str) : strpart(a:str, 0, a:width)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let ret = a:str
 | 
				
			||||||
 | 
					  let width = s:wcswidth(a:str)
 | 
				
			||||||
 | 
					  if width > a:width
 | 
				
			||||||
 | 
					    let ret = s:strwidthpart(ret, a:width)
 | 
				
			||||||
 | 
					    let width = s:wcswidth(ret)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if width < a:width
 | 
				
			||||||
 | 
					    let ret .= repeat(' ', a:width - width)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return ret
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:strwidthpart(str, width) abort
 | 
				
			||||||
 | 
					  call s:_warn_deprecated('strwidthpart', 'Data.String.strwidthpart')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if a:width <= 0
 | 
				
			||||||
 | 
					    return ''
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let ret = a:str
 | 
				
			||||||
 | 
					  let width = s:wcswidth(a:str)
 | 
				
			||||||
 | 
					  while width > a:width
 | 
				
			||||||
 | 
					    let char = matchstr(ret, '.$')
 | 
				
			||||||
 | 
					    let ret = ret[: -1 - len(char)]
 | 
				
			||||||
 | 
					    let width -= s:wcswidth(char)
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return ret
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					function! s:strwidthpart_reverse(str, width) abort
 | 
				
			||||||
 | 
					  call s:_warn_deprecated('strwidthpart_reverse', 'Data.String.strwidthpart_reverse')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if a:width <= 0
 | 
				
			||||||
 | 
					    return ''
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let ret = a:str
 | 
				
			||||||
 | 
					  let width = s:wcswidth(a:str)
 | 
				
			||||||
 | 
					  while width > a:width
 | 
				
			||||||
 | 
					    let char = matchstr(ret, '^.')
 | 
				
			||||||
 | 
					    let ret = ret[len(char) :]
 | 
				
			||||||
 | 
					    let width -= s:wcswidth(char)
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return ret
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if v:version >= 703
 | 
				
			||||||
 | 
					  " Use builtin function.
 | 
				
			||||||
 | 
					  function! s:wcswidth(str) abort
 | 
				
			||||||
 | 
					    call s:_warn_deprecated('wcswidth', 'Data.String.wcswidth')
 | 
				
			||||||
 | 
					    return strwidth(a:str)
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:wcswidth(str) abort
 | 
				
			||||||
 | 
					    call s:_warn_deprecated('wcswidth', 'Data.String.wcswidth')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if a:str =~# '^[\x00-\x7f]*$'
 | 
				
			||||||
 | 
					      return strlen(a:str)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mx_first = '^\(.\)'
 | 
				
			||||||
 | 
					    let str = a:str
 | 
				
			||||||
 | 
					    let width = 0
 | 
				
			||||||
 | 
					    while 1
 | 
				
			||||||
 | 
					      let ucs = char2nr(substitute(str, mx_first, '\1', ''))
 | 
				
			||||||
 | 
					      if ucs == 0
 | 
				
			||||||
 | 
					        break
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      let width += s:_wcwidth(ucs)
 | 
				
			||||||
 | 
					      let str = substitute(str, mx_first, '', '')
 | 
				
			||||||
 | 
					    endwhile
 | 
				
			||||||
 | 
					    return width
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  " UTF-8 only.
 | 
				
			||||||
 | 
					  function! s:_wcwidth(ucs) abort
 | 
				
			||||||
 | 
					    let ucs = a:ucs
 | 
				
			||||||
 | 
					    if (ucs >= 0x1100
 | 
				
			||||||
 | 
					          \  && (ucs <= 0x115f
 | 
				
			||||||
 | 
					          \  || ucs == 0x2329
 | 
				
			||||||
 | 
					          \  || ucs == 0x232a
 | 
				
			||||||
 | 
					          \  || (ucs >= 0x2e80 && ucs <= 0xa4cf
 | 
				
			||||||
 | 
					          \      && ucs != 0x303f)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0xac00 && ucs <= 0xd7a3)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0xf900 && ucs <= 0xfaff)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0xfe30 && ucs <= 0xfe6f)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0xff00 && ucs <= 0xff60)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0xffe0 && ucs <= 0xffe6)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0x20000 && ucs <= 0x2fffd)
 | 
				
			||||||
 | 
					          \  || (ucs >= 0x30000 && ucs <= 0x3fffd)
 | 
				
			||||||
 | 
					          \  ))
 | 
				
			||||||
 | 
					      return 2
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:is_windows = has('win16') || has('win32') || has('win64') || has('win95')
 | 
				
			||||||
 | 
					let s:is_cygwin = has('win32unix')
 | 
				
			||||||
 | 
					let s:is_mac = !s:is_windows && !s:is_cygwin
 | 
				
			||||||
 | 
					      \ && (has('mac') || has('macunix') || has('gui_macvim') ||
 | 
				
			||||||
 | 
					      \   (!isdirectory('/proc') && executable('sw_vers')))
 | 
				
			||||||
 | 
					let s:is_unix = has('unix')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:is_windows() abort
 | 
				
			||||||
 | 
					  return s:is_windows
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:is_cygwin() abort
 | 
				
			||||||
 | 
					  return s:is_cygwin
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:is_mac() abort
 | 
				
			||||||
 | 
					  return s:is_mac
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:is_unix() abort
 | 
				
			||||||
 | 
					  return s:is_unix
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_warn_deprecated(name, alternative) abort
 | 
				
			||||||
 | 
					  try
 | 
				
			||||||
 | 
					    echohl Error
 | 
				
			||||||
 | 
					    echomsg 'Prelude.' . a:name . ' is deprecated!  Please use ' . a:alternative . ' instead.'
 | 
				
			||||||
 | 
					  finally
 | 
				
			||||||
 | 
					    echohl None
 | 
				
			||||||
 | 
					  endtry
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:smart_execute_command(action, word) abort
 | 
				
			||||||
 | 
					  execute a:action . ' ' . (a:word ==# '' ? '' : '`=a:word`')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:escape_file_searching(buffer_name) abort
 | 
				
			||||||
 | 
					  return escape(a:buffer_name, '*[]?{}, ')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:escape_pattern(str) abort
 | 
				
			||||||
 | 
					  call s:_warn_deprecated(
 | 
				
			||||||
 | 
					        \ 'escape_pattern',
 | 
				
			||||||
 | 
					        \ 'Data.String.escape_pattern',
 | 
				
			||||||
 | 
					        \)
 | 
				
			||||||
 | 
					  return escape(a:str, '~"\.^$[]*')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:getchar(...) abort
 | 
				
			||||||
 | 
					  let c = call('getchar', a:000)
 | 
				
			||||||
 | 
					  return type(c) == type(0) ? nr2char(c) : c
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:getchar_safe(...) abort
 | 
				
			||||||
 | 
					  let c = s:input_helper('getchar', a:000)
 | 
				
			||||||
 | 
					  return type(c) == type('') ? c : nr2char(c)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:input_safe(...) abort
 | 
				
			||||||
 | 
					  return s:input_helper('input', a:000)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:input_helper(funcname, args) abort
 | 
				
			||||||
 | 
					  let success = 0
 | 
				
			||||||
 | 
					  if inputsave() !=# success
 | 
				
			||||||
 | 
					    throw 'vital: Prelude: inputsave() failed'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  try
 | 
				
			||||||
 | 
					    return call(a:funcname, a:args)
 | 
				
			||||||
 | 
					  finally
 | 
				
			||||||
 | 
					    if inputrestore() !=# success
 | 
				
			||||||
 | 
					      throw 'vital: Prelude: inputrestore() failed'
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endtry
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:set_default(var, val) abort
 | 
				
			||||||
 | 
					  if !exists(a:var) || type({a:var}) != type(a:val)
 | 
				
			||||||
 | 
					    let {a:var} = a:val
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:substitute_path_separator(path) abort
 | 
				
			||||||
 | 
					  return s:is_windows ? substitute(a:path, '\\', '/', 'g') : a:path
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:path2directory(path) abort
 | 
				
			||||||
 | 
					  return s:substitute_path_separator(isdirectory(a:path) ? a:path : fnamemodify(a:path, ':p:h'))
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_path2project_directory_git(path) abort
 | 
				
			||||||
 | 
					  let parent = a:path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while 1
 | 
				
			||||||
 | 
					    let path = parent . '/.git'
 | 
				
			||||||
 | 
					    if isdirectory(path) || filereadable(path)
 | 
				
			||||||
 | 
					      return parent
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    let next = fnamemodify(parent, ':h')
 | 
				
			||||||
 | 
					    if next == parent
 | 
				
			||||||
 | 
					      return ''
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    let parent = next
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_path2project_directory_svn(path) abort
 | 
				
			||||||
 | 
					  let search_directory = a:path
 | 
				
			||||||
 | 
					  let directory = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let find_directory = s:escape_file_searching(search_directory)
 | 
				
			||||||
 | 
					  let d = finddir('.svn', find_directory . ';')
 | 
				
			||||||
 | 
					  if d ==# ''
 | 
				
			||||||
 | 
					    return ''
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let directory = fnamemodify(d, ':p:h:h')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  " Search parent directories.
 | 
				
			||||||
 | 
					  let parent_directory = s:path2directory(
 | 
				
			||||||
 | 
					        \ fnamemodify(directory, ':h'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if parent_directory !=# ''
 | 
				
			||||||
 | 
					    let d = finddir('.svn', parent_directory . ';')
 | 
				
			||||||
 | 
					    if d !=# ''
 | 
				
			||||||
 | 
					      let directory = s:_path2project_directory_svn(parent_directory)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return directory
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_path2project_directory_others(vcs, path) abort
 | 
				
			||||||
 | 
					  let vcs = a:vcs
 | 
				
			||||||
 | 
					  let search_directory = a:path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let find_directory = s:escape_file_searching(search_directory)
 | 
				
			||||||
 | 
					  let d = finddir(vcs, find_directory . ';')
 | 
				
			||||||
 | 
					  if d ==# ''
 | 
				
			||||||
 | 
					    return ''
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return fnamemodify(d, ':p:h:h')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:path2project_directory(path, ...) abort
 | 
				
			||||||
 | 
					  let is_allow_empty = get(a:000, 0, 0)
 | 
				
			||||||
 | 
					  let search_directory = s:path2directory(a:path)
 | 
				
			||||||
 | 
					  let directory = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  " Search VCS directory.
 | 
				
			||||||
 | 
					  for vcs in ['.git', '.bzr', '.hg', '.svn']
 | 
				
			||||||
 | 
					    if vcs ==# '.git'
 | 
				
			||||||
 | 
					      let directory = s:_path2project_directory_git(search_directory)
 | 
				
			||||||
 | 
					    elseif vcs ==# '.svn'
 | 
				
			||||||
 | 
					      let directory = s:_path2project_directory_svn(search_directory)
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let directory = s:_path2project_directory_others(vcs, search_directory)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if directory !=# ''
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  " Search project file.
 | 
				
			||||||
 | 
					  if directory ==# ''
 | 
				
			||||||
 | 
					    for d in ['build.xml', 'prj.el', '.project', 'pom.xml', 'package.json',
 | 
				
			||||||
 | 
					          \ 'Makefile', 'configure', 'Rakefile', 'NAnt.build',
 | 
				
			||||||
 | 
					          \ 'P4CONFIG', 'tags', 'gtags']
 | 
				
			||||||
 | 
					      let d = findfile(d, s:escape_file_searching(search_directory) . ';')
 | 
				
			||||||
 | 
					      if d !=# ''
 | 
				
			||||||
 | 
					        let directory = fnamemodify(d, ':p:h')
 | 
				
			||||||
 | 
					        break
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					    endfor
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if directory ==# ''
 | 
				
			||||||
 | 
					    " Search /src/ directory.
 | 
				
			||||||
 | 
					    let base = s:substitute_path_separator(search_directory)
 | 
				
			||||||
 | 
					    if base =~# '/src/'
 | 
				
			||||||
 | 
					      let directory = base[: strridx(base, '/src/') + 3]
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if directory ==# '' && !is_allow_empty
 | 
				
			||||||
 | 
					    " Use original path.
 | 
				
			||||||
 | 
					    let directory = search_directory
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return s:substitute_path_separator(directory)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let &cpo = s:save_cpo
 | 
				
			||||||
 | 
					unlet s:save_cpo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" vim:set et ts=2 sts=2 sw=2 tw=0:
 | 
				
			||||||
@ -0,0 +1,181 @@
 | 
				
			|||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					" NOTE: lines between '" ___vital___' is generated by :Vitalize.
 | 
				
			||||||
 | 
					" Do not mofidify the code nor insert new lines before '" ___vital___'
 | 
				
			||||||
 | 
					if v:version > 703 || v:version == 703 && has('patch1170')
 | 
				
			||||||
 | 
					  function! vital#_tsuquyomi#Process#import() abort
 | 
				
			||||||
 | 
					    return map({'shellescape': '', 'has_vimproc': '', 'system': '', 'iconv': '', 'spawn': '', 'get_last_status': ''},  'function("s:" . v:key)')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:_SID() abort
 | 
				
			||||||
 | 
					    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					  execute join(['function! vital#_tsuquyomi#Process#import() abort', printf("return map({'shellescape': '', 'has_vimproc': '', 'system': '', 'iconv': '', 'spawn': '', 'get_last_status': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
 | 
				
			||||||
 | 
					  delfunction s:_SID
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					" TODO: move all comments to doc file.
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
 | 
					" FIXME: This module name should be Vital.System ?
 | 
				
			||||||
 | 
					" But the name has been already taken.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:save_cpo = &cpo
 | 
				
			||||||
 | 
					set cpo&vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" FIXME: Unfortunately, can't use s:_vital_loaded() for this purpose.
 | 
				
			||||||
 | 
					" Because these variables are used when this script file is loaded.
 | 
				
			||||||
 | 
					let s:is_windows = has('win16') || has('win32') || has('win64') || has('win95')
 | 
				
			||||||
 | 
					let s:is_unix = has('unix')
 | 
				
			||||||
 | 
					" As of 7.4.122, the system()'s 1st argument is converted internally by Vim.
 | 
				
			||||||
 | 
					" Note that Patch 7.4.122 does not convert system()'s 2nd argument and
 | 
				
			||||||
 | 
					" return-value. We must convert them manually.
 | 
				
			||||||
 | 
					let s:need_trans = v:version < 704 || (v:version == 704 && !has('patch122'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:TYPE_DICT = type({})
 | 
				
			||||||
 | 
					let s:TYPE_LIST = type([])
 | 
				
			||||||
 | 
					let s:TYPE_STRING = type('')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:spawn(expr, ...) abort
 | 
				
			||||||
 | 
					  let shellslash = 0
 | 
				
			||||||
 | 
					  if s:is_windows
 | 
				
			||||||
 | 
					    let shellslash = &l:shellslash
 | 
				
			||||||
 | 
					    setlocal noshellslash
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  try
 | 
				
			||||||
 | 
					    if type(a:expr) is s:TYPE_LIST
 | 
				
			||||||
 | 
					      let special = 1
 | 
				
			||||||
 | 
					      let cmdline = join(map(a:expr, 'shellescape(v:val, special)'), ' ')
 | 
				
			||||||
 | 
					    elseif type(a:expr) is s:TYPE_STRING
 | 
				
			||||||
 | 
					      let cmdline = a:expr
 | 
				
			||||||
 | 
					      if a:0 && a:1
 | 
				
			||||||
 | 
					        " for :! command
 | 
				
			||||||
 | 
					        let cmdline = substitute(cmdline, '\([!%#]\|<[^<>]\+>\)', '\\\1', 'g')
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      throw 'Process.spawn(): invalid argument (value type:'.type(a:expr).')'
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    if s:is_windows
 | 
				
			||||||
 | 
					      silent execute '!start' cmdline
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      silent execute '!' cmdline '&'
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  finally
 | 
				
			||||||
 | 
					    if s:is_windows
 | 
				
			||||||
 | 
					      let &l:shellslash = shellslash
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endtry
 | 
				
			||||||
 | 
					  return ''
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" iconv() wrapper for safety.
 | 
				
			||||||
 | 
					function! s:iconv(expr, from, to) abort
 | 
				
			||||||
 | 
					  if a:from ==# '' || a:to ==# '' || a:from ==? a:to
 | 
				
			||||||
 | 
					    return a:expr
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let result = iconv(a:expr, a:from, a:to)
 | 
				
			||||||
 | 
					  return result !=# '' ? result : a:expr
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Check vimproc.
 | 
				
			||||||
 | 
					function! s:has_vimproc() abort
 | 
				
			||||||
 | 
					  if !exists('s:exists_vimproc')
 | 
				
			||||||
 | 
					    try
 | 
				
			||||||
 | 
					      call vimproc#version()
 | 
				
			||||||
 | 
					      let s:exists_vimproc = 1
 | 
				
			||||||
 | 
					    catch
 | 
				
			||||||
 | 
					      let s:exists_vimproc = 0
 | 
				
			||||||
 | 
					    endtry
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return s:exists_vimproc
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" * {command} [, {input} [, {timeout}]]
 | 
				
			||||||
 | 
					" * {command} [, {dict}]
 | 
				
			||||||
 | 
					"   {dict} = {
 | 
				
			||||||
 | 
					"     use_vimproc: bool,
 | 
				
			||||||
 | 
					"     input: string,
 | 
				
			||||||
 | 
					"     timeout: bool,
 | 
				
			||||||
 | 
					"     background: bool,
 | 
				
			||||||
 | 
					"   }
 | 
				
			||||||
 | 
					function! s:system(str, ...) abort
 | 
				
			||||||
 | 
					  " Process optional arguments at first
 | 
				
			||||||
 | 
					  " because use_vimproc is required later
 | 
				
			||||||
 | 
					  " for a:str argument.
 | 
				
			||||||
 | 
					  let input = ''
 | 
				
			||||||
 | 
					  let use_vimproc = s:has_vimproc()
 | 
				
			||||||
 | 
					  let background = 0
 | 
				
			||||||
 | 
					  let args = []
 | 
				
			||||||
 | 
					  if a:0 ==# 1
 | 
				
			||||||
 | 
					    " {command} [, {dict}]
 | 
				
			||||||
 | 
					    " a:1 = {dict}
 | 
				
			||||||
 | 
					    if type(a:1) is s:TYPE_DICT
 | 
				
			||||||
 | 
					      if has_key(a:1, 'use_vimproc')
 | 
				
			||||||
 | 
					        let use_vimproc = a:1.use_vimproc
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      if has_key(a:1, 'input')
 | 
				
			||||||
 | 
					        let args += [s:iconv(a:1.input, &encoding, 'char')]
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      if use_vimproc && has_key(a:1, 'timeout')
 | 
				
			||||||
 | 
					        " ignores timeout unless you have vimproc.
 | 
				
			||||||
 | 
					        let args += [a:1.timeout]
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      if has_key(a:1, 'background')
 | 
				
			||||||
 | 
					        let background = a:1.background
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					    elseif type(a:1) is s:TYPE_STRING
 | 
				
			||||||
 | 
					      let args += [s:iconv(a:1, &encoding, 'char')]
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      throw 'Process.system(): invalid argument (value type:'.type(a:1).')'
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  elseif a:0 >= 2
 | 
				
			||||||
 | 
					    " {command} [, {input} [, {timeout}]]
 | 
				
			||||||
 | 
					    " a:000 = [{input} [, {timeout}]]
 | 
				
			||||||
 | 
					    let [input; rest] = a:000
 | 
				
			||||||
 | 
					    let input   = s:iconv(input, &encoding, 'char')
 | 
				
			||||||
 | 
					    let args += [input] + rest
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  " Process a:str argument.
 | 
				
			||||||
 | 
					  if type(a:str) is s:TYPE_LIST
 | 
				
			||||||
 | 
					    let expr = use_vimproc ? '"''" . v:val . "''"' : 's:shellescape(v:val)'
 | 
				
			||||||
 | 
					    let command = join(map(copy(a:str), expr), ' ')
 | 
				
			||||||
 | 
					  elseif type(a:str) is s:TYPE_STRING
 | 
				
			||||||
 | 
					    let command = a:str
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    throw 'Process.system(): invalid argument (value type:'.type(a:str).')'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  if s:need_trans
 | 
				
			||||||
 | 
					    let command = s:iconv(command, &encoding, 'char')
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let args = [command] + args
 | 
				
			||||||
 | 
					  if background && (use_vimproc || !s:is_windows)
 | 
				
			||||||
 | 
					    let args[0] = args[0] . ' &'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let funcname = use_vimproc ? 'vimproc#system' : 'system'
 | 
				
			||||||
 | 
					  let output = call(funcname, args)
 | 
				
			||||||
 | 
					  let output = s:iconv(output, 'char', &encoding)
 | 
				
			||||||
 | 
					  return output
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:get_last_status() abort
 | 
				
			||||||
 | 
					  return s:has_vimproc() ?
 | 
				
			||||||
 | 
					        \ vimproc#get_last_status() : v:shell_error
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if s:is_windows
 | 
				
			||||||
 | 
					  function! s:shellescape(command) abort
 | 
				
			||||||
 | 
					    return substitute(a:command, '[&()[\]{}^=;!''+,`~]', '^\0', 'g')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:shellescape(...) abort
 | 
				
			||||||
 | 
					    return call('shellescape', a:000)
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let &cpo = s:save_cpo
 | 
				
			||||||
 | 
					unlet s:save_cpo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" vim:set et ts=2 sts=2 sw=2 tw=0:
 | 
				
			||||||
@ -0,0 +1,147 @@
 | 
				
			|||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					" NOTE: lines between '" ___vital___' is generated by :Vitalize.
 | 
				
			||||||
 | 
					" Do not mofidify the code nor insert new lines before '" ___vital___'
 | 
				
			||||||
 | 
					if v:version > 703 || v:version == 703 && has('patch1170')
 | 
				
			||||||
 | 
					  function! vital#_tsuquyomi#ProcessManager#import() abort
 | 
				
			||||||
 | 
					    return map({'read': '', '_vital_depends': '', 'touch': '', 'read_wait': '', 'writeln': '', 'write': '', 'kill': '', 'state': '', 'term': '', 'is_available': '', 'debug_processes': '', 'status': '', '_vital_loaded': ''},  'function("s:" . v:key)')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:_SID() abort
 | 
				
			||||||
 | 
					    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					  execute join(['function! vital#_tsuquyomi#ProcessManager#import() abort', printf("return map({'read': '', '_vital_depends': '', 'touch': '', 'read_wait': '', 'writeln': '', 'write': '', 'kill': '', 'state': '', 'term': '', 'is_available': '', 'debug_processes': '', 'status': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
 | 
				
			||||||
 | 
					  delfunction s:_SID
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					let s:save_cpo = &cpo
 | 
				
			||||||
 | 
					set cpo&vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:_processes = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_vital_loaded(V) abort
 | 
				
			||||||
 | 
					  let s:V = a:V
 | 
				
			||||||
 | 
					  let s:S = s:V.import('Data.String')
 | 
				
			||||||
 | 
					  let s:P = s:V.import('Process')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_vital_depends() abort
 | 
				
			||||||
 | 
					  return ['Data.String', 'Process']
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:is_available() abort
 | 
				
			||||||
 | 
					  return s:P.has_vimproc()
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:touch(name, cmd) abort
 | 
				
			||||||
 | 
					  if has_key(s:_processes, a:name)
 | 
				
			||||||
 | 
					    return 'existing'
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    let p = vimproc#popen3(a:cmd)
 | 
				
			||||||
 | 
					    let s:_processes[a:name] = p
 | 
				
			||||||
 | 
					    return 'new'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_stop(i, ...) abort
 | 
				
			||||||
 | 
					  let p = s:_processes[a:i]
 | 
				
			||||||
 | 
					  call p.kill(get(a:000, 0, 0) ? g:vimproc#SIGKILL : g:vimproc#SIGTERM)
 | 
				
			||||||
 | 
					  " call p.waitpid()
 | 
				
			||||||
 | 
					  unlet s:_processes[a:i]
 | 
				
			||||||
 | 
					  if has_key(s:state, a:i)
 | 
				
			||||||
 | 
					    unlet s:state[a:i]
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:term(i) abort
 | 
				
			||||||
 | 
					  return s:_stop(a:i, 0)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:kill(i) abort
 | 
				
			||||||
 | 
					  return s:_stop(a:i, 1)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:read(i, endpatterns) abort
 | 
				
			||||||
 | 
					  return s:read_wait(a:i, 0.05, a:endpatterns)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:state = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:read_wait(i, wait, endpatterns) abort
 | 
				
			||||||
 | 
					  if !has_key(s:_processes, a:i)
 | 
				
			||||||
 | 
					    throw printf("vital: ProcessManager: doesn't know about %s", a:i)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let p = s:_processes[a:i]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if s:status(a:i) ==# 'inactive'
 | 
				
			||||||
 | 
					    let s:state[a:i] = 'inactive'
 | 
				
			||||||
 | 
					    return [p.stdout.read(), p.stderr.read(), 'inactive']
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let out_memo = ''
 | 
				
			||||||
 | 
					  let err_memo = ''
 | 
				
			||||||
 | 
					  let lastchanged = reltime()
 | 
				
			||||||
 | 
					  while 1
 | 
				
			||||||
 | 
					    let [x, y] = [p.stdout.read(-1, 0), p.stderr.read(-1, 0)]
 | 
				
			||||||
 | 
					    if x ==# '' && y ==# ''
 | 
				
			||||||
 | 
					      if str2float(reltimestr(reltime(lastchanged))) > a:wait
 | 
				
			||||||
 | 
					        let s:state[a:i] = 'reading'
 | 
				
			||||||
 | 
					        return [out_memo, err_memo, 'timedout']
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let lastchanged = reltime()
 | 
				
			||||||
 | 
					      let out_memo .= x
 | 
				
			||||||
 | 
					      let err_memo .= y
 | 
				
			||||||
 | 
					      for pattern in a:endpatterns
 | 
				
			||||||
 | 
					        if out_memo =~ ("\\(^\\|\n\\)" . pattern)
 | 
				
			||||||
 | 
					          let s:state[a:i] = 'idle'
 | 
				
			||||||
 | 
					          return [s:S.substitute_last(out_memo, pattern, ''), err_memo, 'matched']
 | 
				
			||||||
 | 
					        endif
 | 
				
			||||||
 | 
					      endfor
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endwhile
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:state(i) abort
 | 
				
			||||||
 | 
					  return get(s:state, a:i, 'undefined')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:write(i, str) abort
 | 
				
			||||||
 | 
					  if !has_key(s:_processes, a:i)
 | 
				
			||||||
 | 
					    throw printf("vital: ProcessManager: doesn't know about %s", a:i)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  if s:status(a:i) ==# 'inactive'
 | 
				
			||||||
 | 
					    return 'inactive'
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let p = s:_processes[a:i]
 | 
				
			||||||
 | 
					  call p.stdin.write(a:str)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 'active'
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:writeln(i, str) abort
 | 
				
			||||||
 | 
					  return s:write(a:i, a:str . "\n")
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:status(i) abort
 | 
				
			||||||
 | 
					  if !has_key(s:_processes, a:i)
 | 
				
			||||||
 | 
					    throw printf("vital: ProcessManager: doesn't know about %s", a:i)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let p = s:_processes[a:i]
 | 
				
			||||||
 | 
					  " vimproc.kill isn't to stop but to ask for the current state.
 | 
				
			||||||
 | 
					  " return p.kill(0) ? 'inactive' : 'active'
 | 
				
			||||||
 | 
					  " ... checkpid() checks if the process is running AND does waitpid() in C,
 | 
				
			||||||
 | 
					  " so it solves zombie processes.
 | 
				
			||||||
 | 
					  return get(p.checkpid(), 0, '') ==# 'run'
 | 
				
			||||||
 | 
					        \ ? 'active'
 | 
				
			||||||
 | 
					        \ : 'inactive'
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:debug_processes() abort
 | 
				
			||||||
 | 
					  return s:_processes
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let &cpo = s:save_cpo
 | 
				
			||||||
 | 
					unlet s:save_cpo
 | 
				
			||||||
 | 
					" vim:set et ts=2 sts=2 sw=2 tw=0:
 | 
				
			||||||
@ -0,0 +1,265 @@
 | 
				
			|||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					" NOTE: lines between '" ___vital___' is generated by :Vitalize.
 | 
				
			||||||
 | 
					" Do not mofidify the code nor insert new lines before '" ___vital___'
 | 
				
			||||||
 | 
					if v:version > 703 || v:version == 703 && has('patch1170')
 | 
				
			||||||
 | 
					  function! vital#_tsuquyomi#System#Filepath#import() abort
 | 
				
			||||||
 | 
					    return map({'path_separator': '', 'is_case_tolerant': '', 'dirname': '', 'abspath': '', 'relpath': '', 'realpath': '', 'unify_separator': '', 'is_root_directory': '', 'split': '', 'path_extensions': '', 'unixpath': '', 'which': '', 'winpath': '', 'join': '', 'separator': '', 'is_relative': '', 'basename': '', 'remove_last_separator': '', 'is_absolute': '', 'contains': ''},  'function("s:" . v:key)')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:_SID() abort
 | 
				
			||||||
 | 
					    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					  execute join(['function! vital#_tsuquyomi#System#Filepath#import() abort', printf("return map({'path_separator': '', 'is_case_tolerant': '', 'dirname': '', 'abspath': '', 'relpath': '', 'realpath': '', 'unify_separator': '', 'is_root_directory': '', 'split': '', 'path_extensions': '', 'unixpath': '', 'which': '', 'winpath': '', 'join': '', 'separator': '', 'is_relative': '', 'basename': '', 'remove_last_separator': '', 'is_absolute': '', 'contains': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
 | 
				
			||||||
 | 
					  delfunction s:_SID
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					" You should check the following related builtin functions.
 | 
				
			||||||
 | 
					" fnamemodify()
 | 
				
			||||||
 | 
					" resolve()
 | 
				
			||||||
 | 
					" simplify()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:save_cpo = &cpo
 | 
				
			||||||
 | 
					set cpo&vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:path_sep_pattern = (exists('+shellslash') ? '[\\/]' : '/') . '\+'
 | 
				
			||||||
 | 
					let s:is_windows = has('win16') || has('win32') || has('win64') || has('win95')
 | 
				
			||||||
 | 
					let s:is_cygwin = has('win32unix')
 | 
				
			||||||
 | 
					let s:is_mac = !s:is_windows && !s:is_cygwin
 | 
				
			||||||
 | 
					      \ && (has('mac') || has('macunix') || has('gui_macvim') ||
 | 
				
			||||||
 | 
					      \   (!isdirectory('/proc') && executable('sw_vers')))
 | 
				
			||||||
 | 
					let s:is_case_tolerant = filereadable(expand('<sfile>:r') . '.VIM')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Get the directory separator.
 | 
				
			||||||
 | 
					function! s:separator() abort
 | 
				
			||||||
 | 
					  return fnamemodify('.', ':p')[-1 :]
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Get the path separator.
 | 
				
			||||||
 | 
					let s:path_separator = s:is_windows ? ';' : ':'
 | 
				
			||||||
 | 
					function! s:path_separator() abort
 | 
				
			||||||
 | 
					  return s:path_separator
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Get the path extensions
 | 
				
			||||||
 | 
					function! s:path_extensions() abort
 | 
				
			||||||
 | 
					  if !exists('s:path_extensions')
 | 
				
			||||||
 | 
					    if s:is_windows
 | 
				
			||||||
 | 
					      if exists('$PATHEXT')
 | 
				
			||||||
 | 
					        let pathext = $PATHEXT
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        " get default PATHEXT
 | 
				
			||||||
 | 
					        let pathext = matchstr(system('set pathext'), '\C^pathext=\zs.*\ze\n', 'i')
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      let s:path_extensions = map(split(pathext, s:path_separator), 'tolower(v:val)')
 | 
				
			||||||
 | 
					    elseif s:is_cygwin
 | 
				
			||||||
 | 
					      " cygwin is not use $PATHEXT
 | 
				
			||||||
 | 
					      let s:path_extensions = ['', '.exe']
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let s:path_extensions = ['']
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return s:path_extensions
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Convert all directory separators to "/".
 | 
				
			||||||
 | 
					function! s:unify_separator(path) abort
 | 
				
			||||||
 | 
					  return substitute(a:path, s:path_sep_pattern, '/', 'g')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Get the full path of command.
 | 
				
			||||||
 | 
					if exists('*exepath')
 | 
				
			||||||
 | 
					  function! s:which(str) abort
 | 
				
			||||||
 | 
					    return exepath(a:str)
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:which(command, ...) abort
 | 
				
			||||||
 | 
					    let pathlist = a:command =~# s:path_sep_pattern ? [''] :
 | 
				
			||||||
 | 
					    \              !a:0                  ? split($PATH, s:path_separator) :
 | 
				
			||||||
 | 
					    \              type(a:1) == type([]) ? copy(a:1) :
 | 
				
			||||||
 | 
					    \                                      split(a:1, s:path_separator)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let pathext = s:path_extensions()
 | 
				
			||||||
 | 
					    if index(pathext, '.' . tolower(fnamemodify(a:command, ':e'))) != -1
 | 
				
			||||||
 | 
					      let pathext = ['']
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let dirsep = s:separator()
 | 
				
			||||||
 | 
					    for dir in pathlist
 | 
				
			||||||
 | 
					      let head = dir ==# '' ? '' : dir . dirsep
 | 
				
			||||||
 | 
					      for ext in pathext
 | 
				
			||||||
 | 
					        let full = fnamemodify(head . a:command . ext, ':p')
 | 
				
			||||||
 | 
					        if filereadable(full)
 | 
				
			||||||
 | 
					          if s:is_case_tolerant()
 | 
				
			||||||
 | 
					            let full = glob(substitute(
 | 
				
			||||||
 | 
					            \               toupper(full), '\u:\@!', '[\0\L\0]', 'g'), 1)
 | 
				
			||||||
 | 
					          endif
 | 
				
			||||||
 | 
					          if full !=# ''
 | 
				
			||||||
 | 
					            return full
 | 
				
			||||||
 | 
					          endif
 | 
				
			||||||
 | 
					        endif
 | 
				
			||||||
 | 
					      endfor
 | 
				
			||||||
 | 
					    endfor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ''
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Split the path with directory separator.
 | 
				
			||||||
 | 
					" Note that this includes the drive letter of MS Windows.
 | 
				
			||||||
 | 
					function! s:split(path) abort
 | 
				
			||||||
 | 
					  return split(a:path, s:path_sep_pattern)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Join the paths.
 | 
				
			||||||
 | 
					" join('foo', 'bar')            => 'foo/bar'
 | 
				
			||||||
 | 
					" join('foo/', 'bar')           => 'foo/bar'
 | 
				
			||||||
 | 
					" join('/foo/', ['bar', 'buz/']) => '/foo/bar/buz/'
 | 
				
			||||||
 | 
					function! s:join(...) abort
 | 
				
			||||||
 | 
					  let sep = s:separator()
 | 
				
			||||||
 | 
					  let path = ''
 | 
				
			||||||
 | 
					  for part in a:000
 | 
				
			||||||
 | 
					    let path .= sep .
 | 
				
			||||||
 | 
					    \ (type(part) is type([]) ? call('s:join', part) :
 | 
				
			||||||
 | 
					    \                           part)
 | 
				
			||||||
 | 
					    unlet part
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return substitute(path[1 :], s:path_sep_pattern, sep, 'g')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Check if the path is absolute path.
 | 
				
			||||||
 | 
					if s:is_windows
 | 
				
			||||||
 | 
					  function! s:is_absolute(path) abort
 | 
				
			||||||
 | 
					    return a:path =~# '^[a-zA-Z]:[/\\]'
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:is_absolute(path) abort
 | 
				
			||||||
 | 
					    return a:path[0] ==# '/'
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:is_relative(path) abort
 | 
				
			||||||
 | 
					  return !s:is_absolute(a:path)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Return the parent directory of the path.
 | 
				
			||||||
 | 
					" NOTE: fnamemodify(path, ':h') does not return the parent directory
 | 
				
			||||||
 | 
					" when path[-1] is the separator.
 | 
				
			||||||
 | 
					function! s:dirname(path) abort
 | 
				
			||||||
 | 
					  let path = a:path
 | 
				
			||||||
 | 
					  let orig = a:path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let path = s:remove_last_separator(path)
 | 
				
			||||||
 | 
					  if path ==# ''
 | 
				
			||||||
 | 
					    return orig    " root directory
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let path = fnamemodify(path, ':h')
 | 
				
			||||||
 | 
					  return path
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Return the basename of the path.
 | 
				
			||||||
 | 
					" NOTE: fnamemodify(path, ':h') does not return basename
 | 
				
			||||||
 | 
					" when path[-1] is the separator.
 | 
				
			||||||
 | 
					function! s:basename(path) abort
 | 
				
			||||||
 | 
					  let path = a:path
 | 
				
			||||||
 | 
					  let orig = a:path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let path = s:remove_last_separator(path)
 | 
				
			||||||
 | 
					  if path ==# ''
 | 
				
			||||||
 | 
					    return orig    " root directory
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let path = fnamemodify(path, ':t')
 | 
				
			||||||
 | 
					  return path
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Remove the separator at the end of a:path.
 | 
				
			||||||
 | 
					function! s:remove_last_separator(path) abort
 | 
				
			||||||
 | 
					  let sep = s:separator()
 | 
				
			||||||
 | 
					  let pat = escape(sep, '\') . '\+$'
 | 
				
			||||||
 | 
					  return substitute(a:path, pat, '', '')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Return true if filesystem ignores alphabetic case of a filename.
 | 
				
			||||||
 | 
					" Return false otherwise.
 | 
				
			||||||
 | 
					function! s:is_case_tolerant() abort
 | 
				
			||||||
 | 
					  return s:is_case_tolerant
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:abspath(path) abort
 | 
				
			||||||
 | 
					  if s:is_absolute(a:path)
 | 
				
			||||||
 | 
					    return a:path
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  " Note:
 | 
				
			||||||
 | 
					  "   the behavior of ':p' for non existing file path is not defined
 | 
				
			||||||
 | 
					  return filereadable(a:path)
 | 
				
			||||||
 | 
					        \ ? fnamemodify(a:path, ':p')
 | 
				
			||||||
 | 
					        \ : s:join(fnamemodify(getcwd(), ':p'), a:path)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:relpath(path) abort
 | 
				
			||||||
 | 
					  if s:is_relative(a:path)
 | 
				
			||||||
 | 
					    return a:path
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return fnamemodify(a:path, ':~:.')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:unixpath(path) abort
 | 
				
			||||||
 | 
					  return fnamemodify(a:path, ':gs?\\?/?')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:winpath(path) abort
 | 
				
			||||||
 | 
					  return fnamemodify(a:path, ':gs?/?\\?')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if s:is_windows
 | 
				
			||||||
 | 
					  function! s:realpath(path) abort
 | 
				
			||||||
 | 
					    if exists('&shellslash') && &shellslash
 | 
				
			||||||
 | 
					      return s:unixpath(a:path)
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      return s:winpath(a:path)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:realpath(path) abort
 | 
				
			||||||
 | 
					    return s:unixpath(a:path)
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if s:is_windows
 | 
				
			||||||
 | 
					  function! s:is_root_directory(path) abort
 | 
				
			||||||
 | 
					    return a:path =~# '^[a-zA-Z]:[/\\]$'
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:is_root_directory(path) abort
 | 
				
			||||||
 | 
					    return a:path ==# '/'
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:contains(path, base) abort
 | 
				
			||||||
 | 
					  if a:path ==# '' || a:base ==# ''
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let pathlist = s:split(a:path)
 | 
				
			||||||
 | 
					  let baselist = s:split(a:base)
 | 
				
			||||||
 | 
					  let pathlistlen = len(pathlist)
 | 
				
			||||||
 | 
					  let baselistlen = len(baselist)
 | 
				
			||||||
 | 
					  if pathlistlen < baselistlen
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  if baselistlen == 0
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  if s:is_case_tolerant
 | 
				
			||||||
 | 
					    call map(pathlist, 'tolower(v:val)')
 | 
				
			||||||
 | 
					    call map(baselist, 'tolower(v:val)')
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return pathlist[: baselistlen - 1] ==# baselist
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let &cpo = s:save_cpo
 | 
				
			||||||
 | 
					unlet s:save_cpo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" vim:set et ts=2 sts=2 sw=2 tw=0:
 | 
				
			||||||
@ -0,0 +1,184 @@
 | 
				
			|||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					" NOTE: lines between '" ___vital___' is generated by :Vitalize.
 | 
				
			||||||
 | 
					" Do not mofidify the code nor insert new lines before '" ___vital___'
 | 
				
			||||||
 | 
					if v:version > 703 || v:version == 703 && has('patch1170')
 | 
				
			||||||
 | 
					  function! vital#_tsuquyomi#Web#JSON#import() abort
 | 
				
			||||||
 | 
					    return map({'decode': '', '_vital_depends': '', '_vital_created': '', 'encode': '', '_vital_loaded': ''},  'function("s:" . v:key)')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:_SID() abort
 | 
				
			||||||
 | 
					    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					  execute join(['function! vital#_tsuquyomi#Web#JSON#import() abort', printf("return map({'decode': '', '_vital_depends': '', '_vital_created': '', 'encode': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
 | 
				
			||||||
 | 
					  delfunction s:_SID
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					" ___vital___
 | 
				
			||||||
 | 
					let s:save_cpo = &cpo
 | 
				
			||||||
 | 
					set cpo&vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_true() abort
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_false() abort
 | 
				
			||||||
 | 
					  return 0
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_null() abort
 | 
				
			||||||
 | 
					  return 0
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_resolve(val, prefix) abort
 | 
				
			||||||
 | 
					  let t = type(a:val)
 | 
				
			||||||
 | 
					  if t == type('')
 | 
				
			||||||
 | 
					    let m = matchlist(a:val, '^' . a:prefix . '\(null\|true\|false\)$')
 | 
				
			||||||
 | 
					    if !empty(m)
 | 
				
			||||||
 | 
					      return s:const[m[1]]
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  elseif t == type([]) || t == type({})
 | 
				
			||||||
 | 
					    return map(a:val, 's:_resolve(v:val, a:prefix)')
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return a:val
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_vital_created(module) abort
 | 
				
			||||||
 | 
					  " define constant variables
 | 
				
			||||||
 | 
					  if !exists('s:const')
 | 
				
			||||||
 | 
					    let s:const = {}
 | 
				
			||||||
 | 
					    let s:const.true = function('s:_true')
 | 
				
			||||||
 | 
					    let s:const.false = function('s:_false')
 | 
				
			||||||
 | 
					    let s:const.null = function('s:_null')
 | 
				
			||||||
 | 
					    lockvar s:const
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  call extend(a:module, s:const)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_vital_loaded(V) abort
 | 
				
			||||||
 | 
					  let s:V = a:V
 | 
				
			||||||
 | 
					  let s:string = s:V.import('Data.String')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_vital_depends() abort
 | 
				
			||||||
 | 
					  return ['Data.String']
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" @vimlint(EVL102, 1, l:null)
 | 
				
			||||||
 | 
					" @vimlint(EVL102, 1, l:true)
 | 
				
			||||||
 | 
					" @vimlint(EVL102, 1, l:false)
 | 
				
			||||||
 | 
					function! s:decode(json, ...) abort
 | 
				
			||||||
 | 
					  let settings = extend({
 | 
				
			||||||
 | 
					        \ 'use_token': 0,
 | 
				
			||||||
 | 
					        \}, get(a:000, 0, {}))
 | 
				
			||||||
 | 
					  let json = iconv(a:json, 'utf-8', &encoding)
 | 
				
			||||||
 | 
					  let json = join(split(json, "\n"), '')
 | 
				
			||||||
 | 
					  let json = substitute(json, '\\u34;', '\\"', 'g')
 | 
				
			||||||
 | 
					  let json = substitute(json, '\\u\(\x\x\x\x\)', '\=s:string.nr2enc_char("0x".submatch(1))', 'g')
 | 
				
			||||||
 | 
					  if settings.use_token
 | 
				
			||||||
 | 
					    let prefix = '__Web.JSON__'
 | 
				
			||||||
 | 
					    while stridx(json, prefix) != -1
 | 
				
			||||||
 | 
					      let prefix .= '_'
 | 
				
			||||||
 | 
					    endwhile
 | 
				
			||||||
 | 
					    let [null,true,false] = map(['null','true','false'], 'prefix . v:val')
 | 
				
			||||||
 | 
					    sandbox return s:_resolve(eval(json), prefix)
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    let [null,true,false] = [s:const.null(),s:const.true(),s:const.false()]
 | 
				
			||||||
 | 
					    sandbox return eval(json)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					" @vimlint(EVL102, 0, l:null)
 | 
				
			||||||
 | 
					" @vimlint(EVL102, 0, l:true)
 | 
				
			||||||
 | 
					" @vimlint(EVL102, 0, l:false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:encode(val, ...) abort
 | 
				
			||||||
 | 
					  let settings = extend({
 | 
				
			||||||
 | 
					        \ 'indent': 0,
 | 
				
			||||||
 | 
					        \}, get(a:000, 0, {})
 | 
				
			||||||
 | 
					        \)
 | 
				
			||||||
 | 
					  if type(a:val) == 0
 | 
				
			||||||
 | 
					    return a:val
 | 
				
			||||||
 | 
					  elseif type(a:val) == 1
 | 
				
			||||||
 | 
					    let json = '"' . escape(a:val, '\"') . '"'
 | 
				
			||||||
 | 
					    let json = substitute(json, "\r", '\\r', 'g')
 | 
				
			||||||
 | 
					    let json = substitute(json, "\n", '\\n', 'g')
 | 
				
			||||||
 | 
					    let json = substitute(json, "\t", '\\t', 'g')
 | 
				
			||||||
 | 
					    return iconv(json, &encoding, 'utf-8')
 | 
				
			||||||
 | 
					  elseif type(a:val) == 2
 | 
				
			||||||
 | 
					    if s:const.true == a:val
 | 
				
			||||||
 | 
					      return 'true'
 | 
				
			||||||
 | 
					    elseif s:const.false == a:val
 | 
				
			||||||
 | 
					      return 'false'
 | 
				
			||||||
 | 
					    elseif s:const.null == a:val
 | 
				
			||||||
 | 
					      return 'null'
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      " backward compatibility
 | 
				
			||||||
 | 
					      return string(a:val)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  elseif type(a:val) == 3
 | 
				
			||||||
 | 
					    return s:_encode_list(a:val, settings)
 | 
				
			||||||
 | 
					  elseif type(a:val) == 4
 | 
				
			||||||
 | 
					    return s:_encode_dict(a:val, settings)
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return string(a:val)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" @vimlint(EVL102, 1, l:ns)
 | 
				
			||||||
 | 
					function! s:_encode_list(val, settings) abort
 | 
				
			||||||
 | 
					  if empty(a:val)
 | 
				
			||||||
 | 
					    return '[]'
 | 
				
			||||||
 | 
					  elseif !a:settings.indent
 | 
				
			||||||
 | 
					    let encoded_candidates = map(copy(a:val), 's:encode(v:val, a:settings)')
 | 
				
			||||||
 | 
					    return printf('[%s]', join(encoded_candidates, ','))
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    let previous_indent = get(a:settings, '_previous_indent')
 | 
				
			||||||
 | 
					    let indent = previous_indent + a:settings.indent
 | 
				
			||||||
 | 
					    let ns = extend(copy(a:settings), {
 | 
				
			||||||
 | 
					          \ '_previous_indent': indent,
 | 
				
			||||||
 | 
					          \})
 | 
				
			||||||
 | 
					    let encoded_candidates = map(
 | 
				
			||||||
 | 
					          \ copy(a:val),
 | 
				
			||||||
 | 
					          \ printf('''%s'' . s:encode(v:val, ns)', repeat(' ', indent)),
 | 
				
			||||||
 | 
					          \)
 | 
				
			||||||
 | 
					    return printf(
 | 
				
			||||||
 | 
					          \ "[\n%s\n%s]",
 | 
				
			||||||
 | 
					          \ join(encoded_candidates, ",\n"),
 | 
				
			||||||
 | 
					          \ repeat(' ', previous_indent)
 | 
				
			||||||
 | 
					          \)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					" @vimlint(EVL102, 0, l:ns)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" @vimlint(EVL102, 1, l:ns)
 | 
				
			||||||
 | 
					function! s:_encode_dict(val, settings) abort
 | 
				
			||||||
 | 
					  if empty(a:val)
 | 
				
			||||||
 | 
					    return '{}'
 | 
				
			||||||
 | 
					  elseif !a:settings.indent
 | 
				
			||||||
 | 
					    let encoded_candidates = map(keys(a:val),
 | 
				
			||||||
 | 
					          \ 's:encode(v:val, a:settings) . '':'' . s:encode(a:val[v:val], a:settings)'
 | 
				
			||||||
 | 
					          \)
 | 
				
			||||||
 | 
					    return printf('{%s}', join(encoded_candidates, ','))
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    let previous_indent = get(a:settings, '_previous_indent')
 | 
				
			||||||
 | 
					    let indent = previous_indent + a:settings.indent
 | 
				
			||||||
 | 
					    let ns = extend(copy(a:settings), {
 | 
				
			||||||
 | 
					          \ '_previous_indent': indent,
 | 
				
			||||||
 | 
					          \})
 | 
				
			||||||
 | 
					    let encoded_candidates = map(keys(a:val),
 | 
				
			||||||
 | 
					          \ printf(
 | 
				
			||||||
 | 
					          \   '''%s'' . s:encode(v:val, ns) . '': '' . s:encode(a:val[v:val], ns)',
 | 
				
			||||||
 | 
					          \   repeat(' ', indent),
 | 
				
			||||||
 | 
					          \ ),
 | 
				
			||||||
 | 
					          \)
 | 
				
			||||||
 | 
					    return printf("{\n%s\n%s}",
 | 
				
			||||||
 | 
					          \ join(encoded_candidates, ",\n"),
 | 
				
			||||||
 | 
					          \ repeat(' ', previous_indent),
 | 
				
			||||||
 | 
					          \)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					" @vimlint(EVL102, 0, l:ns)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let &cpo = s:save_cpo
 | 
				
			||||||
 | 
					unlet s:save_cpo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" vim:set et ts=2 sts=2 sw=2 tw=0:
 | 
				
			||||||
@ -0,0 +1,339 @@
 | 
				
			|||||||
 | 
					let s:plugin_name = expand('<sfile>:t:r')
 | 
				
			||||||
 | 
					let s:vital_base_dir = expand('<sfile>:h')
 | 
				
			||||||
 | 
					let s:project_root = expand('<sfile>:h:h:h')
 | 
				
			||||||
 | 
					let s:is_vital_vim = s:plugin_name is# 'vital'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:loaded = {}
 | 
				
			||||||
 | 
					let s:cache_sid = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" function() wrapper
 | 
				
			||||||
 | 
					if v:version > 703 || v:version == 703 && has('patch1170')
 | 
				
			||||||
 | 
					  function! s:_function(fstr) abort
 | 
				
			||||||
 | 
					    return function(a:fstr)
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:_SID() abort
 | 
				
			||||||
 | 
					    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					  let s:_s = '<SNR>' . s:_SID() . '_'
 | 
				
			||||||
 | 
					  function! s:_function(fstr) abort
 | 
				
			||||||
 | 
					    return function(substitute(a:fstr, 's:', s:_s, 'g'))
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! vital#{s:plugin_name}#new() abort
 | 
				
			||||||
 | 
					  return s:new(s:plugin_name)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! vital#{s:plugin_name}#import(...) abort
 | 
				
			||||||
 | 
					  if !exists('s:V')
 | 
				
			||||||
 | 
					    let s:V = s:new(s:plugin_name)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return call(s:V.import, a:000, s:V)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:Vital = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:new(plugin_name) abort
 | 
				
			||||||
 | 
					  let base = deepcopy(s:Vital)
 | 
				
			||||||
 | 
					  let base._plugin_name = a:plugin_name
 | 
				
			||||||
 | 
					  return base
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:vital_files() abort
 | 
				
			||||||
 | 
					  if !exists('s:vital_files')
 | 
				
			||||||
 | 
					    let s:vital_files = map(
 | 
				
			||||||
 | 
					    \   s:is_vital_vim ? s:_global_vital_files() : s:_self_vital_files(),
 | 
				
			||||||
 | 
					    \   'fnamemodify(v:val, ":p:gs?[\\\\/]?/?")')
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return copy(s:vital_files)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					let s:Vital.vital_files = s:_function('s:vital_files')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:import(name, ...) abort dict
 | 
				
			||||||
 | 
					  let target = {}
 | 
				
			||||||
 | 
					  let functions = []
 | 
				
			||||||
 | 
					  for a in a:000
 | 
				
			||||||
 | 
					    if type(a) == type({})
 | 
				
			||||||
 | 
					      let target = a
 | 
				
			||||||
 | 
					    elseif type(a) == type([])
 | 
				
			||||||
 | 
					      let functions = a
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    unlet a
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  let module = self._import(a:name)
 | 
				
			||||||
 | 
					  if empty(functions)
 | 
				
			||||||
 | 
					    call extend(target, module, 'keep')
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    for f in functions
 | 
				
			||||||
 | 
					      if has_key(module, f) && !has_key(target, f)
 | 
				
			||||||
 | 
					        let target[f] = module[f]
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					    endfor
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return target
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					let s:Vital.import = s:_function('s:import')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:load(...) abort dict
 | 
				
			||||||
 | 
					  for arg in a:000
 | 
				
			||||||
 | 
					    let [name; as] = type(arg) == type([]) ? arg[: 1] : [arg, arg]
 | 
				
			||||||
 | 
					    let target = split(join(as, ''), '\W\+')
 | 
				
			||||||
 | 
					    let dict = self
 | 
				
			||||||
 | 
					    let dict_type = type({})
 | 
				
			||||||
 | 
					    while !empty(target)
 | 
				
			||||||
 | 
					      let ns = remove(target, 0)
 | 
				
			||||||
 | 
					      if !has_key(dict, ns)
 | 
				
			||||||
 | 
					        let dict[ns] = {}
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      if type(dict[ns]) == dict_type
 | 
				
			||||||
 | 
					        let dict = dict[ns]
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        unlet dict
 | 
				
			||||||
 | 
					        break
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					    endwhile
 | 
				
			||||||
 | 
					    if exists('dict')
 | 
				
			||||||
 | 
					      call extend(dict, self._import(name))
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    unlet arg
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return self
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					let s:Vital.load = s:_function('s:load')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:unload() abort dict
 | 
				
			||||||
 | 
					  let s:loaded = {}
 | 
				
			||||||
 | 
					  let s:cache_sid = {}
 | 
				
			||||||
 | 
					  unlet! s:vital_files
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					let s:Vital.unload = s:_function('s:unload')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:exists(name) abort dict
 | 
				
			||||||
 | 
					  if a:name !~# '\v^\u\w*%(\.\u\w*)*$'
 | 
				
			||||||
 | 
					    throw 'vital: Invalid module name: ' . a:name
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return s:_module_path(a:name) isnot# ''
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					let s:Vital.exists = s:_function('s:exists')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:search(pattern) abort dict
 | 
				
			||||||
 | 
					  let paths = s:_extract_files(a:pattern, self.vital_files())
 | 
				
			||||||
 | 
					  let modules = sort(map(paths, 's:_file2module(v:val)'))
 | 
				
			||||||
 | 
					  return s:_uniq(modules)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					let s:Vital.search = s:_function('s:search')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:plugin_name() abort dict
 | 
				
			||||||
 | 
					  return self._plugin_name
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					let s:Vital.plugin_name = s:_function('s:plugin_name')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_self_vital_files() abort
 | 
				
			||||||
 | 
					  let builtin = printf('%s/__%s__/', s:vital_base_dir, s:plugin_name)
 | 
				
			||||||
 | 
					  let installed = printf('%s/_%s/', s:vital_base_dir, s:plugin_name)
 | 
				
			||||||
 | 
					  let base = builtin . ',' . installed
 | 
				
			||||||
 | 
					  return split(globpath(base, '**/*.vim', 1), "\n")
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_global_vital_files() abort
 | 
				
			||||||
 | 
					  let pattern = 'autoload/vital/__*__/**/*.vim'
 | 
				
			||||||
 | 
					  return split(globpath(&runtimepath, pattern, 1), "\n")
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_extract_files(pattern, files) abort
 | 
				
			||||||
 | 
					  let tr = {'.': '/', '*': '[^/]*', '**': '.*'}
 | 
				
			||||||
 | 
					  let target = substitute(a:pattern, '\.\|\*\*\?', '\=tr[submatch(0)]', 'g')
 | 
				
			||||||
 | 
					  let regexp = printf('autoload/vital/[^/]\+/%s.vim$', target)
 | 
				
			||||||
 | 
					  return filter(a:files, 'v:val =~# regexp')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_file2module(file) abort
 | 
				
			||||||
 | 
					  let filename = fnamemodify(a:file, ':p:gs?[\\/]?/?')
 | 
				
			||||||
 | 
					  let tail = matchstr(filename, 'autoload/vital/_\w\+/\zs.*\ze\.vim$')
 | 
				
			||||||
 | 
					  return join(split(tail, '[\\/]\+'), '.')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" @param {string} name e.g. Data.List
 | 
				
			||||||
 | 
					function! s:_import(name) abort dict
 | 
				
			||||||
 | 
					  if has_key(s:loaded, a:name)
 | 
				
			||||||
 | 
					    return copy(s:loaded[a:name])
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let module = self._get_module(a:name)
 | 
				
			||||||
 | 
					  if has_key(module, '_vital_created')
 | 
				
			||||||
 | 
					    call module._vital_created(module)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let export_module = filter(copy(module), 'v:key =~# "^\\a"')
 | 
				
			||||||
 | 
					  " Cache module before calling module.vital_loaded() to avoid cyclic
 | 
				
			||||||
 | 
					  " dependences but remove the cache if module._vital_loaded() fails.
 | 
				
			||||||
 | 
					  " let s:loaded[a:name] = export_module
 | 
				
			||||||
 | 
					  let s:loaded[a:name] = export_module
 | 
				
			||||||
 | 
					  if has_key(module, '_vital_loaded')
 | 
				
			||||||
 | 
					    try
 | 
				
			||||||
 | 
					      call module._vital_loaded(vital#{s:plugin_name}#new())
 | 
				
			||||||
 | 
					    catch
 | 
				
			||||||
 | 
					      unlet s:loaded[a:name]
 | 
				
			||||||
 | 
					      throw 'vital: fail to call ._vital_loaded(): ' . v:exception
 | 
				
			||||||
 | 
					    endtry
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return copy(s:loaded[a:name])
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					let s:Vital._import = s:_function('s:_import')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" s:_get_module() returns module object wihch has all script local functions.
 | 
				
			||||||
 | 
					function! s:_get_module(name) abort dict
 | 
				
			||||||
 | 
					  let funcname = s:_import_func_name(self.plugin_name(), a:name)
 | 
				
			||||||
 | 
					  if s:_exists_autoload_func_with_source(funcname)
 | 
				
			||||||
 | 
					    return call(funcname, [])
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return s:_get_builtin_module(a:name)
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_get_builtin_module(name) abort
 | 
				
			||||||
 | 
					 return s:sid2sfuncs(s:_module_sid(a:name))
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if s:is_vital_vim
 | 
				
			||||||
 | 
					  " For vital.vim, we can use s:_get_builtin_module directly
 | 
				
			||||||
 | 
					  let s:Vital._get_module = s:_function('s:_get_builtin_module')
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  let s:Vital._get_module = s:_function('s:_get_module')
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_import_func_name(plugin_name, module_name) abort
 | 
				
			||||||
 | 
					  return printf('vital#_%s#%s#import', a:plugin_name, s:_dot_to_sharp(a:module_name))
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_module_sid(name) abort
 | 
				
			||||||
 | 
					  let path = s:_module_path(a:name)
 | 
				
			||||||
 | 
					  if !filereadable(path)
 | 
				
			||||||
 | 
					    throw 'vital: module not found: ' . a:name
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  let vital_dir = s:is_vital_vim ? '__\w\+__' : printf('_\{1,2}%s\%%(__\)\?', s:plugin_name)
 | 
				
			||||||
 | 
					  let base = join([vital_dir, ''], '[/\\]\+')
 | 
				
			||||||
 | 
					  let p = base . substitute('' . a:name, '\.', '[/\\\\]\\+', 'g')
 | 
				
			||||||
 | 
					  let sid = s:_sid(path, p)
 | 
				
			||||||
 | 
					  if !sid
 | 
				
			||||||
 | 
					    call s:_source(path)
 | 
				
			||||||
 | 
					    let sid = s:_sid(path, p)
 | 
				
			||||||
 | 
					    if !sid
 | 
				
			||||||
 | 
					      throw printf('vital: cannot get <SID> from path: %s', path)
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  return sid
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_module_path(name) abort
 | 
				
			||||||
 | 
					  return get(s:_extract_files(a:name, s:vital_files()), 0, '')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_module_sid_base_dir() abort
 | 
				
			||||||
 | 
					  return s:is_vital_vim ? &rtp : s:project_root
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_dot_to_sharp(name) abort
 | 
				
			||||||
 | 
					  return substitute(a:name, '\.', '#', 'g')
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" It will sources autoload file if a given func is not already defined.
 | 
				
			||||||
 | 
					function! s:_exists_autoload_func_with_source(funcname) abort
 | 
				
			||||||
 | 
					  if exists('*' . a:funcname)
 | 
				
			||||||
 | 
					    " Return true if a given func is already defined
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  " source a file which may include a given func definition and try again.
 | 
				
			||||||
 | 
					  let path = 'autoload/' . substitute(substitute(a:funcname, '#[^#]*$', '.vim', ''), '#', '/', 'g')
 | 
				
			||||||
 | 
					  call s:_runtime(path)
 | 
				
			||||||
 | 
					  return exists('*' . a:funcname)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_runtime(path) abort
 | 
				
			||||||
 | 
					  execute 'runtime' fnameescape(a:path)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_source(path) abort
 | 
				
			||||||
 | 
					  execute 'source' fnameescape(a:path)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" @vimlint(EVL102, 1, l:_)
 | 
				
			||||||
 | 
					" @vimlint(EVL102, 1, l:__)
 | 
				
			||||||
 | 
					function! s:_sid(path, filter_pattern) abort
 | 
				
			||||||
 | 
					  let unified_path = s:_unify_path(a:path)
 | 
				
			||||||
 | 
					  if has_key(s:cache_sid, unified_path)
 | 
				
			||||||
 | 
					    return s:cache_sid[unified_path]
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					  for line in filter(split(s:_redir(':scriptnames'), "\n"), 'v:val =~# a:filter_pattern')
 | 
				
			||||||
 | 
					    let [_, sid, path; __] = matchlist(line, '^\s*\(\d\+\):\s\+\(.\+\)\s*$')
 | 
				
			||||||
 | 
					    if s:_unify_path(path) is# unified_path
 | 
				
			||||||
 | 
					      let s:cache_sid[unified_path] = sid
 | 
				
			||||||
 | 
					      return s:cache_sid[unified_path]
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return 0
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! s:_redir(cmd) abort
 | 
				
			||||||
 | 
					  let [save_verbose, save_verbosefile] = [&verbose, &verbosefile]
 | 
				
			||||||
 | 
					  set verbose=0 verbosefile=
 | 
				
			||||||
 | 
					  redir => res
 | 
				
			||||||
 | 
					    silent! execute a:cmd
 | 
				
			||||||
 | 
					  redir END
 | 
				
			||||||
 | 
					  let [&verbose, &verbosefile] = [save_verbose, save_verbosefile]
 | 
				
			||||||
 | 
					  return res
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if filereadable(expand('<sfile>:r') . '.VIM') " is case-insensitive or not
 | 
				
			||||||
 | 
					  let s:_unify_path_cache = {}
 | 
				
			||||||
 | 
					  " resolve() is slow, so we cache results.
 | 
				
			||||||
 | 
					  " Note: On windows, vim can't expand path names from 8.3 formats.
 | 
				
			||||||
 | 
					  " So if getting full path via <sfile> and $HOME was set as 8.3 format,
 | 
				
			||||||
 | 
					  " vital load duplicated scripts. Below's :~ avoid this issue.
 | 
				
			||||||
 | 
					  function! s:_unify_path(path) abort
 | 
				
			||||||
 | 
					    if has_key(s:_unify_path_cache, a:path)
 | 
				
			||||||
 | 
					      return s:_unify_path_cache[a:path]
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    let value = tolower(fnamemodify(resolve(fnamemodify(
 | 
				
			||||||
 | 
					    \                   a:path, ':p')), ':~:gs?[\\/]?/?'))
 | 
				
			||||||
 | 
					    let s:_unify_path_cache[a:path] = value
 | 
				
			||||||
 | 
					    return value
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:_unify_path(path) abort
 | 
				
			||||||
 | 
					    return resolve(fnamemodify(a:path, ':p:gs?[\\/]?/?'))
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" copied and modified from Vim.ScriptLocal
 | 
				
			||||||
 | 
					let s:SNR = join(map(range(len("\<SNR>")), '"[\\x" . printf("%0x", char2nr("\<SNR>"[v:val])) . "]"'), '')
 | 
				
			||||||
 | 
					function! s:sid2sfuncs(sid) abort
 | 
				
			||||||
 | 
					  let fs = split(s:_redir(printf(':function /^%s%s_', s:SNR, a:sid)), "\n")
 | 
				
			||||||
 | 
					  let r = {}
 | 
				
			||||||
 | 
					  let pattern = printf('\m^function\s<SNR>%d_\zs\w\{-}\ze(', a:sid)
 | 
				
			||||||
 | 
					  for fname in map(fs, 'matchstr(v:val, pattern)')
 | 
				
			||||||
 | 
					    let r[fname] = function(s:_sfuncname(a:sid, fname))
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return r
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"" Return funcname of script local functions with SID
 | 
				
			||||||
 | 
					function! s:_sfuncname(sid, funcname) abort
 | 
				
			||||||
 | 
					  return printf('<SNR>%s_%s', a:sid, a:funcname)
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if exists('*uniq')
 | 
				
			||||||
 | 
					  function! s:_uniq(list) abort
 | 
				
			||||||
 | 
					    return uniq(a:list)
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  function! s:_uniq(list) abort
 | 
				
			||||||
 | 
					    let i = len(a:list) - 1
 | 
				
			||||||
 | 
					    while 0 < i
 | 
				
			||||||
 | 
					      if a:list[i] ==# a:list[i - 1]
 | 
				
			||||||
 | 
					        call remove(a:list, i)
 | 
				
			||||||
 | 
					      endif
 | 
				
			||||||
 | 
					      let i -= 1
 | 
				
			||||||
 | 
					    endwhile
 | 
				
			||||||
 | 
					    return a:list
 | 
				
			||||||
 | 
					  endfunction
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					tsuquyomi
 | 
				
			||||||
 | 
					bd6fd747ba07d5124619347efa32c2f068e22318
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Web.JSON
 | 
				
			||||||
 | 
					ProcessManager
 | 
				
			||||||
 | 
					System.Filepath
 | 
				
			||||||
 | 
					Prelude
 | 
				
			||||||
											
												Binary file not shown.
											
										
									
								| 
		 After Width: | Height: | Size: 75 KiB  | 
@ -0,0 +1,519 @@
 | 
				
			|||||||
 | 
					*tsuquyomi* はTypeScript向けのVim plugin です.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Version: 0.5.1
 | 
				
			||||||
 | 
					Author : Quramy <yosuke.kurami@gmail.com>
 | 
				
			||||||
 | 
					License: MIT license  {{{
 | 
				
			||||||
 | 
					    Permission is hereby granted, free of charge, to any person obtaining
 | 
				
			||||||
 | 
					    a copy of this software and associated documentation files (the
 | 
				
			||||||
 | 
					    "Software"), to deal in the Software without restriction, including
 | 
				
			||||||
 | 
					    without limitation the rights to use, copy, modify, merge, publish,
 | 
				
			||||||
 | 
					    distribute, sublicense, and/or sell copies of the Software, and to
 | 
				
			||||||
 | 
					    permit persons to whom the Software is furnished to do so, subject to
 | 
				
			||||||
 | 
					    the following conditions:
 | 
				
			||||||
 | 
					    The above copyright notice and this permission notice shall be included
 | 
				
			||||||
 | 
					    in all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
				
			||||||
 | 
					    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
				
			||||||
 | 
					    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
				
			||||||
 | 
					    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
				
			||||||
 | 
					    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
				
			||||||
 | 
					    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 | 
					}}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					目次 						*tsuquyomi-contents*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					概要			|tsuquyomi-introduction|
 | 
				
			||||||
 | 
					インストール		|tsuquyomi-install|
 | 
				
			||||||
 | 
					インターフェイス	|tsuquyomi-interface|
 | 
				
			||||||
 | 
					  コマンド 		  |tsuquyomi-commands|
 | 
				
			||||||
 | 
					  オプション 		  |tsuquyomi-variables|
 | 
				
			||||||
 | 
					  キーマッピング	  |tsuquyomi-key-mappings|
 | 
				
			||||||
 | 
					  関数			  |tsuquyomi-functions|
 | 
				
			||||||
 | 
					設定例			|tsuquyomi-examples|
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					概要 						*tsuquyomi-introduction*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tsuquyomi は TSServer のclient として動作します
 | 
				
			||||||
 | 
					(TSServerはTypeScriptにバンドルされているエディタ向けツールです).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tsuquyomi は以下の機能を提供します.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ TSServer からソースコードが持つ情報を参照します.
 | 
				
			||||||
 | 
					  (補完, 定義/参照箇所, エラー, etc...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ TSServerの起動や停止を行う機能
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					インストール 						*tsuquyomi-install*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tsuquyomiのインストールには下記が必要です.
 | 
				
			||||||
 | 
					* Vim (v.7.4.0 or later)
 | 
				
			||||||
 | 
					* Shougo/vimproc.vim (https://github.com/Shougo/vimproc.vim)
 | 
				
			||||||
 | 
					  (vim8 もしくはそれ以降をお使いならば必要ありません)
 | 
				
			||||||
 | 
					* Node.js and TypeScript (v.1.5.0 or later)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					最初に, |vimproc|が未インストールであれば, インストールしてください.
 | 
				
			||||||
 | 
					(インストール方法は https://github.com/Shougo/vimproc.vim を参考にしてください)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					次に,  最新の TypeScript をインストールします.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Prompt:
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
					    	$ npm -g install typescript
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
					最後に, tsuquyomiをVim plugin用のディレクトリに配置します.
 | 
				
			||||||
 | 
					もし |NeoBundle| でプラグイン管理をしているのであれば,
 | 
				
			||||||
 | 
					`.vimrc` に以下を追記します
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
						NeoBundle 'Shougo/vimproc.vim', {
 | 
				
			||||||
 | 
						\ 'build' : {
 | 
				
			||||||
 | 
						\     'windows' : 'tools\\update-dll-mingw',
 | 
				
			||||||
 | 
						\     'cygwin' : 'make -f make_cygwin.mak',
 | 
				
			||||||
 | 
						\     'mac' : 'make -f make_mac.mak',
 | 
				
			||||||
 | 
						\     'linux' : 'make',
 | 
				
			||||||
 | 
						\     'unix' : 'gmake',
 | 
				
			||||||
 | 
						\    },
 | 
				
			||||||
 | 
						\ }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NeoBundle 'Quramy/tsuquyomi'
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
					|:NeoBundleInstall| を実行し,  プラグインをインストールしてください.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					また, tsuquyomi は|unite-outline|の拡張機能を提供します.
 | 
				
			||||||
 | 
					|unite| と |unite-outline| がインストールされていれば, |:Unite outline| を実行
 | 
				
			||||||
 | 
					することでカレントバッファをOutline 表示できます.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					インターフェイス 				*tsuquyomi-interface*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					コマンド 					*tsuquyomi-commands*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiStartServer*
 | 
				
			||||||
 | 
											*:TsuStartServer*
 | 
				
			||||||
 | 
					:TsuquyomiStartServer
 | 
				
			||||||
 | 
							TSServerのプロセスを起動します.
 | 
				
			||||||
 | 
							すでにプロセスが起動している場合は何もしません.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiStopServer*
 | 
				
			||||||
 | 
											*:TsuStopServer*
 | 
				
			||||||
 | 
					:TsuquyomiStopServer
 | 
				
			||||||
 | 
							TSServerのプロセスが存在する場合, 停止させます.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiStatusServer*
 | 
				
			||||||
 | 
											*:TsuStatusServer*
 | 
				
			||||||
 | 
					:TsuquyomiStatusServer
 | 
				
			||||||
 | 
							TSServerの起動状態を表示します.
 | 
				
			||||||
 | 
							TSServerが起動している場合, "reading" のメッセージが
 | 
				
			||||||
 | 
							表示されます.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiOpen*
 | 
				
			||||||
 | 
											*:TsuOpen*
 | 
				
			||||||
 | 
					:TsuquyomiOpen [{file} ...]
 | 
				
			||||||
 | 
							TSServerで{file}を開きます.
 | 
				
			||||||
 | 
							TSServerでファイルを開くと, ファイルに対する様々な処理が
 | 
				
			||||||
 | 
							行えるようになります.
 | 
				
			||||||
 | 
							引数{file}を省略すると, TSServerはカレントバッファのファイルを
 | 
				
			||||||
 | 
							開きます.
 | 
				
			||||||
 | 
							デフォルトでは, |g:tsuquyomi_auto_open| が有効化されています.
 | 
				
			||||||
 | 
							このため, 通常は明示的にこのコマンドを実行する必要は
 | 
				
			||||||
 | 
							ありません.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiClose*
 | 
				
			||||||
 | 
											*:TsuClose*
 | 
				
			||||||
 | 
					:TsuquyomiClose [{file} ...]
 | 
				
			||||||
 | 
							既に開いている{file}をTSServer上でクローズします.
 | 
				
			||||||
 | 
							引数{file}を省略すると, TSServerはカレントバッファに紐づいた
 | 
				
			||||||
 | 
							ファイルをクローズします.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiReload*
 | 
				
			||||||
 | 
											*:TsuReload*
 | 
				
			||||||
 | 
					:TsuquyomiReload [{file} ...]
 | 
				
			||||||
 | 
							TSServerに{file}をリロードさせます.
 | 
				
			||||||
 | 
							引数{file}を省略すると, TSServerにカレントバッファを
 | 
				
			||||||
 | 
							リロードさせます.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiDump*
 | 
				
			||||||
 | 
											*:TsuDump*
 | 
				
			||||||
 | 
					:TsuquyomiDump [{file} ...]
 | 
				
			||||||
 | 
							TSServerのバッファをファイルに保存します.
 | 
				
			||||||
 | 
							デバッグのために利用します.
 | 
				
			||||||
 | 
							引数{file}を省略すると, カレントバッファに紐づくファイルを
 | 
				
			||||||
 | 
							ダンプします.
 | 
				
			||||||
 | 
							Note: ダンプされるファイル名は下記となります:
 | 
				
			||||||
 | 
							      `オリジナルファイル名` + `'.dump'`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiDefinition*
 | 
				
			||||||
 | 
											*:TsuDefinition*
 | 
				
			||||||
 | 
					:TsuquyomiDefinition
 | 
				
			||||||
 | 
							シンボルが定義された場所へ遷移させます.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiSplitDefinition*
 | 
				
			||||||
 | 
											*:TsuSplitDefinition*
 | 
				
			||||||
 | 
					:TsuquyomiSplitDefinition
 | 
				
			||||||
 | 
					                現在のウィンドウを2つに分割し、片方にシンボルが定義された
 | 
				
			||||||
 | 
							場所を表示します.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiTypeDefinition*
 | 
				
			||||||
 | 
											*:TsuTypeDefinition*
 | 
				
			||||||
 | 
					:TsuquyomiTypeDefinition
 | 
				
			||||||
 | 
							シンボルの型が定義されている場所へ遷移させます.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiGoBack*
 | 
				
			||||||
 | 
											*:TsuGoBack*
 | 
				
			||||||
 | 
					:TsuquyomiGoBack
 | 
				
			||||||
 | 
							最後に|:TsuquyomiDefinition|, |:TsuTypeDefinition|
 | 
				
			||||||
 | 
							を実行した箇所へカーソルを移動させます.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiImplementation*
 | 
				
			||||||
 | 
											*:TsuImplementation*
 | 
				
			||||||
 | 
					:TsuquyomiImplementation
 | 
				
			||||||
 | 
							interfaceの実装箇所へナビゲートします.
 | 
				
			||||||
 | 
							参照箇所の結果は|location-list|に表示されます.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiReferences*
 | 
				
			||||||
 | 
											*:TsuReferences*
 | 
				
			||||||
 | 
					:TsuquyomiReferences
 | 
				
			||||||
 | 
							シンボルを参照している箇所へナビゲートします.
 | 
				
			||||||
 | 
							参照箇所の結果は|location-list|に表示されます.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiRenameSymbol*
 | 
				
			||||||
 | 
											*:TsuRenameSymbol*
 | 
				
			||||||
 | 
					:TsuquyomiRenameSymbol
 | 
				
			||||||
 | 
							カーソル直下の識別子を別名に変更します.
 | 
				
			||||||
 | 
							対象の識別子が別の.tsファイルから参照されている場合,
 | 
				
			||||||
 | 
							このコマンドを実行するより前に対象ファイルをバッファに
 | 
				
			||||||
 | 
							開いておく必要があります.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiRenameSymbolC*
 | 
				
			||||||
 | 
											*:TsuRenameSymbolC*
 | 
				
			||||||
 | 
					:TsuquyomiRenameSymbolC
 | 
				
			||||||
 | 
							カーソル直下の識別子を別名に変更します.
 | 
				
			||||||
 | 
							コメントに含まれている識別子も含めて変更されます.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiReloadProject*
 | 
				
			||||||
 | 
											*:TsuReloadProject*
 | 
				
			||||||
 | 
					:TsuquyomiReloadProject
 | 
				
			||||||
 | 
							TSServerで開かれている全てのファイルを一度閉じ,
 | 
				
			||||||
 | 
							再度開きます.
 | 
				
			||||||
 | 
							`*.ts`をバッファに開いた後に, `tsconfig.json` を編集した場合,
 | 
				
			||||||
 | 
							このコマンドを実行する必要があります.
 | 
				
			||||||
 | 
							このコマンドを実行すると, `tsconfig.json` の変更が
 | 
				
			||||||
 | 
							TSServerに反映されます.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiGeterr*
 | 
				
			||||||
 | 
											*:TsuGeterr*
 | 
				
			||||||
 | 
					:TsuquyomiGeterr
 | 
				
			||||||
 | 
							カレントバッファのコンパイルエラー情報をQuickFixウィンドウへ
 | 
				
			||||||
 | 
							表示します.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiGeterrProject*
 | 
				
			||||||
 | 
											*:TsuGeterrProject*
 | 
				
			||||||
 | 
					:TsuquyomiGeterrProject
 | 
				
			||||||
 | 
							プロジェクトのコンパイルエラー情報全てをQuickFixウィンドウへ
 | 
				
			||||||
 | 
							表示します.
 | 
				
			||||||
 | 
							このコマンドにはTypeScript@v1.6.0以上が必要です.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiAsyncGeterr*
 | 
				
			||||||
 | 
											*:TsuAsyncGeterr*
 | 
				
			||||||
 | 
					:TsuquyomiAsyncGeterr
 | 
				
			||||||
 | 
							カレントバッファのコンパイルエラー情報を非同期で
 | 
				
			||||||
 | 
							QuickFixウィンドウへ表示します.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiSeaarch*
 | 
				
			||||||
 | 
											*:TsuSearch*
 | 
				
			||||||
 | 
					:TsuquyomiSearch {keyword}
 | 
				
			||||||
 | 
							プロジェクトで {keyword} を含んでいる箇所を検索します.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiQuickFix*
 | 
				
			||||||
 | 
											*:TsuQuickFix*
 | 
				
			||||||
 | 
					:TsuquyomiQuickFix
 | 
				
			||||||
 | 
							カーソル配下にエラーが存在し、且つ適用可能なQuickFixが
 | 
				
			||||||
 | 
							存在する場合に、このQuickFixを適用します.
 | 
				
			||||||
 | 
							このコマンドにはTypeScript@v2.1.0以上が必要です.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiSignatureHelp*
 | 
				
			||||||
 | 
											*:TsuSignatureHelp*
 | 
				
			||||||
 | 
					:TsuquyomiSignatureHelp
 | 
				
			||||||
 | 
							カーソル上のメソッドのシグネチャを、プレビューウィンドウへ表示
 | 
				
			||||||
 | 
							します。もし複数のオーバーロードされた候補が存在する場合は、
 | 
				
			||||||
 | 
							それらをドキュメントと共に表示します。
 | 
				
			||||||
 | 
							Note
 | 
				
			||||||
 | 
							カーソルはメソッド呼び出しのカッコの間にあるか、少なくとも書き
 | 
				
			||||||
 | 
							かけのメソッド呼び出しの開きカッコの後になければいけません。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					オプション						*tsuquyomi-variables*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_auto_open*
 | 
				
			||||||
 | 
					g:tsuquyomi_auto_open		(デフォルト値 1)
 | 
				
			||||||
 | 
							Vimでバッファを開く際にTSServerでそのファイルを開くかどうか.
 | 
				
			||||||
 | 
							この値を0とした場合, バッファを開いた後に|:TsuquyomiOpen|
 | 
				
			||||||
 | 
							コマンドを実行すると必要があります.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*g:tsuquyomi_use_local_typescript*
 | 
				
			||||||
 | 
					g:tsuquyomi_use_local_typescript (default 1)
 | 
				
			||||||
 | 
							プロジェクト用にローカルインストールした`tsserver.js` を
 | 
				
			||||||
 | 
							利用するかどうか.
 | 
				
			||||||
 | 
							* 0: tsuquyomiは `tsserver.js`の探索を行いません.
 | 
				
			||||||
 | 
							* 1: tsuquyomiはカレントディレクトリを起点にプロジェクトの
 | 
				
			||||||
 | 
							     ルートディレクトリ(`package.json`を含むディレクトリ)を
 | 
				
			||||||
 | 
							     探索します. 次にプロジェクトルートから
 | 
				
			||||||
 | 
							     `node_modules/typescript/bin/tsserver.js`
 | 
				
			||||||
 | 
					                     を探索します. 見つからない場合は,
 | 
				
			||||||
 | 
							     |g:tsuquyomi_use_dev_node_module| に従って`tsserver.js`の
 | 
				
			||||||
 | 
							     パスを決定します.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*g:tsuquyomi_use_dev_node_module*
 | 
				
			||||||
 | 
					g:tsuquyomi_use_dev_node_module	(デフォルト値 0)
 | 
				
			||||||
 | 
							手動でインストールした`tsserver.js` を利用するかどうか.
 | 
				
			||||||
 | 
							* 0: tsuquyomi はグローバルインストールされた
 | 
				
			||||||
 | 
							     `tsserver` コマンドを利用します(デフォルト).
 | 
				
			||||||
 | 
							* 1: tsuquyomiは
 | 
				
			||||||
 | 
							     `tsuquyomi/node_modules/typescript/bin/tsserver.js` .
 | 
				
			||||||
 | 
							     を利用します.
 | 
				
			||||||
 | 
							     このモードを利用する場合,  下記を実行してください:
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
							     :cd ~/.vim/bundle/tsuquyomi
 | 
				
			||||||
 | 
							     :!npm install
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
							* 2: tsuquyomiは|g:tsuquyomi_tsserver_path| で指定された
 | 
				
			||||||
 | 
							     `tsserver.js` を利用します.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_tsserver_path*
 | 
				
			||||||
 | 
					g:tsuquyomi_tsserver_path	(デフォルト値 `''`)
 | 
				
			||||||
 | 
							|g:tsuquyomi_use_dev_node_module|を`2`とした場合,
 | 
				
			||||||
 | 
							このオプションで`tsserver.js`のパスを設定する必要があります.
 | 
				
			||||||
 | 
							設定例:
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
							let g:tsuquyomi_use_dev_node_module = 2
 | 
				
			||||||
 | 
							let g:tsuquyomi_tsserver_path =
 | 
				
			||||||
 | 
							\ '~/typescript/built/local/tsserver.js'
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_nodejs_path*
 | 
				
			||||||
 | 
					g:tsuquyomi_nodejs_path		(デフォルト値 "node")
 | 
				
			||||||
 | 
							Node.js の実行パス.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_definition_split*
 | 
				
			||||||
 | 
					g:tsuquyomi_definition_split	(デフォルト値 0)
 | 
				
			||||||
 | 
							|:TsuquyomiDefinition| にて別ファイル定義への遷移時,
 | 
				
			||||||
 | 
							ウィンドウをどのように開くか.
 | 
				
			||||||
 | 
							* 0: |:edit|
 | 
				
			||||||
 | 
							* 1: |:split|
 | 
				
			||||||
 | 
							* 2: |:vsplit|
 | 
				
			||||||
 | 
							* 3: |:tabedit|
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*g:tsuquyomi_completion_detail*
 | 
				
			||||||
 | 
					g:tsuquyomi_completion_detail		(デフォルト値 0)
 | 
				
			||||||
 | 
							|tsuquyomi#complete|実行時に詳細な補完メニューを作成するかどうか.
 | 
				
			||||||
 | 
							このオプションは 'completeopt' に "menu" が含まれるときにのみ
 | 
				
			||||||
 | 
							意味を持つ.
 | 
				
			||||||
 | 
							NOTE: このオプションを1に設定した場合, 補完速度は遅くなる
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*g:tsuquyomi_completion_case_sensitive*
 | 
				
			||||||
 | 
					g:tsuquyomi_completion_case_sensitive	(デフォルト値 0)
 | 
				
			||||||
 | 
							|tsuquyomi#complete|実行時に補完候補をcase-sensitiveに
 | 
				
			||||||
 | 
							探索するかどうか.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*g:tsuquyomi_case_sensitive_imports*
 | 
				
			||||||
 | 
					g:tsuquyomi_case_sensitive_imports	(default 0)
 | 
				
			||||||
 | 
							|tsuquyomi#es6import#complete|実行時に補完候補をcase-sensitive
 | 
				
			||||||
 | 
							に探索するかどうか.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*g:tsuquyomi_completion_preview*
 | 
				
			||||||
 | 
					g:tsuquyomi_completion_preview		(デフォルト値 0)
 | 
				
			||||||
 | 
							|tsuquyomi#complete|実行時にシグネチャの情報をプレビューに表示
 | 
				
			||||||
 | 
							するかどうか.
 | 
				
			||||||
 | 
							このオプションは 'completeopt' に "menu" と "preview" が含まれ
 | 
				
			||||||
 | 
							るときにのみ意味を持つ.
 | 
				
			||||||
 | 
							NOTE: このオプションを1に設定した場合, 補完速度は少し遅くなる
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_disable_default_mappings*
 | 
				
			||||||
 | 
					g:tsuquyomi_disable_default_mappings	(デフォルト値 0)
 | 
				
			||||||
 | 
							デフォルトキーマッピングを適用するかどうか.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_disable_quickfix*
 | 
				
			||||||
 | 
					g:tsuquyomi_disable_quickfix	(デフォルト値 0)
 | 
				
			||||||
 | 
							値をセットするとバッファ保存時に |:TsuquyomiGeterr| が
 | 
				
			||||||
 | 
							実行されなくなる.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_save_onrename*
 | 
				
			||||||
 | 
					g:tsuquyomi_save_onrename	(デフォルト値 0)
 | 
				
			||||||
 | 
							値をセットすると |:TsuquyomiRenameSymbol| の実行時に書き換え
 | 
				
			||||||
 | 
							られたファイルが自動で保存される.
 | 
				
			||||||
 | 
							値がセットされていない場合は, 書き換えられたファイルを|:split|
 | 
				
			||||||
 | 
							で表示すため, ユーザは変更箇所を確認してから, ファイルを
 | 
				
			||||||
 | 
							|:wa| 等で保存すればよい.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_single_quote_import*
 | 
				
			||||||
 | 
					g:tsuquyomi_single_quote_import		(デフォルト値 0)
 | 
				
			||||||
 | 
							値をセットすると、|:TsuquyomiImport| 利用時にダブルクォートで
 | 
				
			||||||
 | 
							はなくシングルクォートを使って import blockが生成される.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					g:tsuquyomi_semicolon_import		(default 1)
 | 
				
			||||||
 | 
							値をセットすると、|:TsuquyomiImport| 利用時に行末にセミコロン
 | 
				
			||||||
 | 
							を追加して import blockが生成される.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_baseurl_import_path*
 | 
				
			||||||
 | 
					g:tsuquyomi_baseurl_import_path		(default 0)
 | 
				
			||||||
 | 
							値をセットすると、|:TsuquyomiImport|が tsconfig.jsonで指定され
 | 
				
			||||||
 | 
							た`baseUrl`からの相対パスをモジュールのパスとして使用するよう
 | 
				
			||||||
 | 
							になる.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_javascript_support*
 | 
				
			||||||
 | 
					g:tsuquyomi_javascript_support	(デフォルト値 0)
 | 
				
			||||||
 | 
							値をセットすると、JavaScriptファイルに対しても動作するようになる
 | 
				
			||||||
 | 
							tsconfig.jsonやjsconfig.jsonによる詳細設定が可能。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_ignore_missing_modules*
 | 
				
			||||||
 | 
					g:tsuquyomi_ignore_missing_modules (デフォルト値 0)
 | 
				
			||||||
 | 
							値をセットすると、"Cannot find module"で始まる
 | 
				
			||||||
 | 
							エラーメッセージを無視するようになる。
 | 
				
			||||||
 | 
							import対象の型定義ファイルが存在していないケースで有用。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_use_vimproc*
 | 
				
			||||||
 | 
					g:tsuquyomi_use_vimproc (default 0)
 | 
				
			||||||
 | 
							値をセットすると、Vim8のjob機能の代わりに |vimproc| を使用する.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_locale*
 | 
				
			||||||
 | 
					g:tsuquyomi_locale (デフォルト値 "en")
 | 
				
			||||||
 | 
							エラーメッセージのLCID。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					キーマッピング					*tsuquyomi-key-mappings*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ノーマルモードのキーマッピング:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiDefinition)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiDefinition)
 | 
				
			||||||
 | 
							カーソル直下のシンボルが定義された箇所へ遷移.
 | 
				
			||||||
 | 
							|:TsuquyomiDefinition|を参照のこと.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiSplitDefinition)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiSplitDefinition)
 | 
				
			||||||
 | 
							カーソル直下のシンボルが定義された箇所へ遷移.
 | 
				
			||||||
 | 
							|:TsuquyomiSplitDefinition|を参照のこと.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*<Plug>(TsuquyomiTypeDefinition)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiTypeDefinition)
 | 
				
			||||||
 | 
							カーソル直下のシンボルの型定義箇所へ遷移.
 | 
				
			||||||
 | 
							|:TsuquyomiTypeDefinition|を参照のこと.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiGoBack)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiGoBack)
 | 
				
			||||||
 | 
							|:TsuquyomiGoBack|を参照のこと.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiImplementation)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiImplementation)
 | 
				
			||||||
 | 
							カーソル直下のinerfaceが実装されている場所の一覧を表示.
 | 
				
			||||||
 | 
							|:TsuquyomiImplementation|を参照のこと.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiReferences)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiReferences)
 | 
				
			||||||
 | 
							カーソル直下のシンボルが参照されている場所の一覧を表示.
 | 
				
			||||||
 | 
							|:TsuquyomiReferences| を参照のこと.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*<Plug>(TsuquyomiRenameSymbol)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiRenameSymbol)
 | 
				
			||||||
 | 
							カーソル直下のシンボルを別名に変更する.
 | 
				
			||||||
 | 
							|:TsuquyomiRenameSymbol|を参照のこと.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*<Plug>(TsuquyomiRenameSymbolC)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiRenameSymbolC)
 | 
				
			||||||
 | 
							カーソル直下のシンボルをコメントも含めて別名に変更する.
 | 
				
			||||||
 | 
							|:TsuquyomiRenameSymbolC|を参照のこと.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiQuickFix)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiQuickFix)
 | 
				
			||||||
 | 
							カーソル直下でQuickFixが適用可能な場合に、これを適用する.
 | 
				
			||||||
 | 
							|:TsuquyomiQuickFix|を参照のこと.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiImport)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiImport)
 | 
				
			||||||
 | 
							カーソル直下のシンボルに対応するES6 import文を生成する.
 | 
				
			||||||
 | 
							|:TsuquyomiImport|を参照のこと.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiSignatureHelp)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiSignatureHelp)
 | 
				
			||||||
 | 
							カーソル下のメソッド引数のシグネチャを表示.
 | 
				
			||||||
 | 
							|:TsuquyomiSignatureHelp|を参照のこと.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					デフォルトキーマップは下記の通り:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ノーマルモード:
 | 
				
			||||||
 | 
					{lhs}			{rhs}
 | 
				
			||||||
 | 
					--------		-----------------------------
 | 
				
			||||||
 | 
					<C-]>			<Plug>(TsuquyomiDefinition)
 | 
				
			||||||
 | 
					<C-W>]			<Plug>(TsuquyomiSplitDefinition)
 | 
				
			||||||
 | 
					<C-t>			<Plug>(TsuquyomiGoBack)
 | 
				
			||||||
 | 
					<C-^>			<Plug>(TsuquyomiReferences)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					関数 							*tsuquyomi-functions*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tsuquyomi#complete					*tsuquyomi#complete*
 | 
				
			||||||
 | 
							'completefunc' や 'omnifunc' オプションに適用可能な関数.
 | 
				
			||||||
 | 
							デフォルトでは, 'omnifunc' オプションにこの関数をセットしてい
 | 
				
			||||||
 | 
							る補完の挙動をカスタマイズする場合,
 | 
				
			||||||
 | 
							|tsuquyomi-examples-complete| を参照の事.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tsuquyomi#balloonexpr	 			*tsuquyomi#balloonexpr*
 | 
				
			||||||
 | 
							マウスカーソル直下のシンボルについて, ツールチップにシンボルの
 | 
				
			||||||
 | 
							情報を表示させる.  'balloonexpr' にセットして利用する.
 | 
				
			||||||
 | 
							設定例:
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
							set ballooneval
 | 
				
			||||||
 | 
							autocmd BufNewFile,BufRead *.ts
 | 
				
			||||||
 | 
							\ setlocal balloonexpr=tsuquyomi#balloonexpr()
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
							Note: この関数はVimが|+balloon_eval| オプション付きでコンパイル
 | 
				
			||||||
 | 
							      されている場合のみ利用可能である.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tsuquyomi#hint					*tsuquyomi#hint*
 | 
				
			||||||
 | 
							カーソル上のシンボルの情報を返却する. |tsuquyomi#balloonexpr|
 | 
				
			||||||
 | 
							と似ているが, この関数はGVim, 端末上のVimのどちらでも動作する.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							設定例:
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
							autocmd FileType typescript nmap <buffer> <Leader>t :
 | 
				
			||||||
 | 
							\ <C-u>echo tsuquyomi#hint()<CR>
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
							Note: This function works in not only GVim but also
 | 
				
			||||||
 | 
							      terminal Vim.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tsuquyomi#getSupportedCodeFixes		 *tsuquyomi#getSupportedCodeFixes*
 | 
				
			||||||
 | 
							QuickFixが利用可能なコード値のリストを返却する.
 | 
				
			||||||
 | 
							このリストに属するコードのエラーは|:TsuquyomiQuickFix|により
 | 
				
			||||||
 | 
							修正可能である.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Todo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					EXAMPLES					*tsuquyomi-examples*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*tsuquyomi-examples-complete*
 | 
				
			||||||
 | 
					補完の挙動は 'completeopt' オプションで設定する.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						メソッド呼び出しの補完時, メソッド定義をプレビューウィンドウに表示.
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
						autocmd FileType typescript setlocal completeopt+=preview
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
						補完時, ポップアップメニューを表示しない.
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
						autocmd FileType typescript setlocal completeopt-=menu
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*tsuquyomi-examples-async*
 | 
				
			||||||
 | 
					Vim8 の Job / Channel を利用し非同期でカレントバッファのコンパイルエラー情報を
 | 
				
			||||||
 | 
					QuickFixウィンドウへ表示します.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
						autocmd InsertLeave,BufWritePost *.ts,*.tsx call tsuquyomi#asyncGeterr()
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					vim:tw=78:ts=8:ft=help:norl:noet:fen:
 | 
				
			||||||
@ -0,0 +1,511 @@
 | 
				
			|||||||
 | 
					*tsuquyomi* is a Vim plugin for TypeScript.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Version: 0.6.0
 | 
				
			||||||
 | 
					Author : Quramy <yosuke.kurami@gmail.com>
 | 
				
			||||||
 | 
					License: MIT license  {{{
 | 
				
			||||||
 | 
					    Permission is hereby granted, free of charge, to any person obtaining
 | 
				
			||||||
 | 
					    a copy of this software and associated documentation files (the
 | 
				
			||||||
 | 
					    "Software"), to deal in the Software without restriction, including
 | 
				
			||||||
 | 
					    without limitation the rights to use, copy, modify, merge, publish,
 | 
				
			||||||
 | 
					    distribute, sublicense, and/or sell copies of the Software, and to
 | 
				
			||||||
 | 
					    permit persons to whom the Software is furnished to do so, subject to
 | 
				
			||||||
 | 
					    the following conditions:
 | 
				
			||||||
 | 
					    The above copyright notice and this permission notice shall be included
 | 
				
			||||||
 | 
					    in all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | 
				
			||||||
 | 
					    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
				
			||||||
 | 
					    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
				
			||||||
 | 
					    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
				
			||||||
 | 
					    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
				
			||||||
 | 
					    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 | 
					}}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CONTENTS 					*tsuquyomi-contents*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Introduction		|tsuquyomi-introduction|
 | 
				
			||||||
 | 
					Install			|tsuquyomi-install|
 | 
				
			||||||
 | 
					Interface		|tsuquyomi-interface|
 | 
				
			||||||
 | 
					  Commands		  |tsuquyomi-commands|
 | 
				
			||||||
 | 
					  Variables		  |tsuquyomi-variables|
 | 
				
			||||||
 | 
					  Key Mappings		  |tsuquyomi-key-mappings|
 | 
				
			||||||
 | 
					  Functions		  |tsuquyomi-functions|
 | 
				
			||||||
 | 
					Examples		|tsuquyomi-examples|
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					INTRODUCTION					*tsuquyomi-introduction*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tsuquyomi works as a client for TSServer(which is an editor service bundled into TypeScript).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This plugin provides the following functions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ Functions to fetch information of your source codes from TSServer.
 | 
				
			||||||
 | 
					  (compeletions, locations of definition or references, error, etc...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ Functions to start or stop the TSServer process.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					INSTALL						*tsuquyomi-install*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tsuquyomi requires the following:
 | 
				
			||||||
 | 
					* Vim (v.7.4.0 or later)
 | 
				
			||||||
 | 
					* Shougo/vimproc.vim (https://github.com/Shougo/vimproc.vim)
 | 
				
			||||||
 | 
					  (Not required if you use vim8 or later)
 | 
				
			||||||
 | 
					* Node.js and TypeScript (v.1.5.0 or later)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					First of all, if you haven't installed |vimproc|, please install it.
 | 
				
			||||||
 | 
					(Please see https://github.com/Shougo/vimproc.vim)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Secondly, install the latest version of TypeScript.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Prompt:
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
					    	$ npm -g install typescript
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
					Thirdly, locate Tsuquyomi to your Vim plugin directory.
 | 
				
			||||||
 | 
					If you use |NeoBundle| for plugin management, append the following to `.vimrc` .
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
						NeoBundle 'Shougo/vimproc.vim', {
 | 
				
			||||||
 | 
						\ 'build' : {
 | 
				
			||||||
 | 
						\     'windows' : 'tools\\update-dll-mingw',
 | 
				
			||||||
 | 
						\     'cygwin' : 'make -f make_cygwin.mak',
 | 
				
			||||||
 | 
						\     'mac' : 'make -f make_mac.mak',
 | 
				
			||||||
 | 
						\     'linux' : 'make',
 | 
				
			||||||
 | 
						\     'unix' : 'gmake',
 | 
				
			||||||
 | 
						\    },
 | 
				
			||||||
 | 
						\ }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NeoBundle 'Quramy/tsuquyomi'
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
					And execute the Ex command |:NeoBundleInstall| .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also, Tsuquyomi is an extension of |unite-outline|.
 | 
				
			||||||
 | 
					If you have installed |unite| and |unite-outline| , you can get the outline of
 | 
				
			||||||
 | 
					the current buffer calling ':Unite outline'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					INTERFACE					*tsuquyomi-interface*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					COMMANDS					*tsuquyomi-commands*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiStartServer*
 | 
				
			||||||
 | 
											*:TsuStartServer*
 | 
				
			||||||
 | 
					:TsuquyomiStartServer
 | 
				
			||||||
 | 
							Start TSServer process.
 | 
				
			||||||
 | 
							If the process is already running, this command doesn't
 | 
				
			||||||
 | 
							do anything.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiStopServer*
 | 
				
			||||||
 | 
											*:TsuStopServer*
 | 
				
			||||||
 | 
					:TsuquyomiStopServer
 | 
				
			||||||
 | 
							Stop TSServer process if it exists.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiStatusServer*
 | 
				
			||||||
 | 
											*:TsuStatusServer*
 | 
				
			||||||
 | 
					:TsuquyomiStatusServer
 | 
				
			||||||
 | 
							Show TSServer status.
 | 
				
			||||||
 | 
							When TSServer is running, the message "reading" will be
 | 
				
			||||||
 | 
							displayed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiOpen*
 | 
				
			||||||
 | 
											*:TsuOpen*
 | 
				
			||||||
 | 
					:TsuquyomiOpen [{file} ...]
 | 
				
			||||||
 | 
							Let TSServer open {file}s.
 | 
				
			||||||
 | 
							Once TSServer opens files, you can start a variety of
 | 
				
			||||||
 | 
							operations on them.
 | 
				
			||||||
 | 
							If you omit the argument {file}, TSServer opens the current
 | 
				
			||||||
 | 
							buffer.
 | 
				
			||||||
 | 
							By default, |g:tsuquyomi_auto_open| is enabled,
 | 
				
			||||||
 | 
							so usually users don't need to exec this command manually.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiClose*
 | 
				
			||||||
 | 
											*:TsuClose*
 | 
				
			||||||
 | 
					:TsuquyomiClose [{file} ...]
 | 
				
			||||||
 | 
							Let TSServer release opened {file}s.
 | 
				
			||||||
 | 
							If you omit the argument {file}, TSServer closes the file
 | 
				
			||||||
 | 
							related to the current buffer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiReload*
 | 
				
			||||||
 | 
											*:TsuReload*
 | 
				
			||||||
 | 
					:TsuquyomiReload [{file} ...]
 | 
				
			||||||
 | 
							Let TSServer reload files.
 | 
				
			||||||
 | 
							If you omit the argument {file}, TSServer reloads the current
 | 
				
			||||||
 | 
							buffer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiDump*
 | 
				
			||||||
 | 
											*:TsuDump*
 | 
				
			||||||
 | 
					:TsuquyomiDump [{file} ...]
 | 
				
			||||||
 | 
							Save TSServer's buffer to files.
 | 
				
			||||||
 | 
							This command can be executed only for debugging purposes.
 | 
				
			||||||
 | 
							If you omit the argument {file}, TSServer saves the file
 | 
				
			||||||
 | 
							related to the current buffer.
 | 
				
			||||||
 | 
							Note: Dumped filename is `originalFileName` + `'.dump'` .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiDefinition*
 | 
				
			||||||
 | 
											*:TsuDefinition*
 | 
				
			||||||
 | 
					:TsuquyomiDefinition
 | 
				
			||||||
 | 
							Navigate to the location where the symbol is defined.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiSplitDefinition*
 | 
				
			||||||
 | 
											*:TsuSplitDefinition*
 | 
				
			||||||
 | 
					:TsuquyomiSplitDefinition
 | 
				
			||||||
 | 
							Split current window in two. Navigate to the location where
 | 
				
			||||||
 | 
							the symbol is defined.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiTypeDefinition*
 | 
				
			||||||
 | 
											*:TsuTypeDefinition*
 | 
				
			||||||
 | 
					:TsuquyomiTypeDefinition
 | 
				
			||||||
 | 
							Navigate to the location where the type of the symbol is
 | 
				
			||||||
 | 
							defined.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiGoBack*
 | 
				
			||||||
 | 
											*:TsuGoBack*
 | 
				
			||||||
 | 
					:TsuquyomiGoBack
 | 
				
			||||||
 | 
							Move the cursor position to the location where
 | 
				
			||||||
 | 
							the last |:TsuquyomiDefinition| or |:TsuquyomiTypeDefinition|
 | 
				
			||||||
 | 
							was called.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiImplementation*
 | 
				
			||||||
 | 
											*:TsuImplementation*
 | 
				
			||||||
 | 
					:TsuquyomiImplementation
 | 
				
			||||||
 | 
							Navigate to the locations where an interface is implemented.
 | 
				
			||||||
 | 
							The result is loaded into the |location-list| .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiReferences*
 | 
				
			||||||
 | 
											*:TsuReferences*
 | 
				
			||||||
 | 
					:TsuquyomiReferences
 | 
				
			||||||
 | 
							Navigate to the locations where the symbol is referenced.
 | 
				
			||||||
 | 
							The result is loaded into the |location-list| .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiRenameSymbol*
 | 
				
			||||||
 | 
											*:TsuRenameSymbol*
 | 
				
			||||||
 | 
					:TsuquyomiRenameSymbol
 | 
				
			||||||
 | 
							Rename the identifier under the cursor to a new name.
 | 
				
			||||||
 | 
							If the identifier is referenced by other .ts files,
 | 
				
			||||||
 | 
							you should open them before executing this command.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiRenameSymbolC*
 | 
				
			||||||
 | 
											*:TsuRenameSymbolC*
 | 
				
			||||||
 | 
					:TsuquyomiRenameSymbolC
 | 
				
			||||||
 | 
							Rename the identifier under the cursor to a new name.
 | 
				
			||||||
 | 
							This command renames the identifiers including comments.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiReloadProject*
 | 
				
			||||||
 | 
											*:TsuReloadProject*
 | 
				
			||||||
 | 
					:TsuquyomiReloadProject
 | 
				
			||||||
 | 
							Close and re-open all files opened by |:TsuquyomiOpen|.
 | 
				
			||||||
 | 
							If you change your `tsconfig.json` after opening any `*.ts` files,
 | 
				
			||||||
 | 
							you should execute this command so the changes of `tsconfig.json`
 | 
				
			||||||
 | 
							are reflected in the TSServer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiGeterr*
 | 
				
			||||||
 | 
											*:TsuGeterr*
 | 
				
			||||||
 | 
					:TsuquyomiGeterr
 | 
				
			||||||
 | 
							Show compilation errors of current buffer in QuickFix window.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiAsynGeterr*
 | 
				
			||||||
 | 
											*:TsuAsyncGeterr*
 | 
				
			||||||
 | 
					:TsuquyomiAsyncGeterr
 | 
				
			||||||
 | 
							Show compilation errors of current buffer in QuickFix window
 | 
				
			||||||
 | 
							asynchronous.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiGeterrProject*
 | 
				
			||||||
 | 
											*:TsuGeterrProject*
 | 
				
			||||||
 | 
					:TsuquyomiGeterrProject
 | 
				
			||||||
 | 
							Show all compilation errors of your project in QuickFix window.
 | 
				
			||||||
 | 
							This command requires TypeScript@v1.6.0 or later.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiSeaarch*
 | 
				
			||||||
 | 
											*:TsuSearch*
 | 
				
			||||||
 | 
					:TsuquyomiSearch {keyword}
 | 
				
			||||||
 | 
							Search locations which contain {keyword} from project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiQuickFix*
 | 
				
			||||||
 | 
											*:TsuQuickFix*
 | 
				
			||||||
 | 
					:TsuquyomiQuickFix
 | 
				
			||||||
 | 
							If the cursor is over an error and there is a  quick fix is
 | 
				
			||||||
 | 
							for it, apply it.
 | 
				
			||||||
 | 
							This command requires TypeScript@v2.1.0 or later.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*:TsuquyomiSignatureHelp*
 | 
				
			||||||
 | 
											*:TsuSignatureHelp*
 | 
				
			||||||
 | 
					:TsuquyomiSignatureHelp
 | 
				
			||||||
 | 
							Display signature help for the method signature the cursor is
 | 
				
			||||||
 | 
							currently inside, and display the output in the preview
 | 
				
			||||||
 | 
							window. If there are multiple, overloads they will be
 | 
				
			||||||
 | 
							displayed along with any documentation.
 | 
				
			||||||
 | 
							Note that the cursor must be between the method parentheses,
 | 
				
			||||||
 | 
							or at least after the opening parenthesis of a partially
 | 
				
			||||||
 | 
							written method call.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					VARIABLES					*tsuquyomi-variables*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_auto_open*
 | 
				
			||||||
 | 
					g:tsuquyomi_auto_open		(default 1)
 | 
				
			||||||
 | 
							Whether TSServer automatically opens the file of the current
 | 
				
			||||||
 | 
							buffer when the buffer is opened in Vim.
 | 
				
			||||||
 | 
							If you set this option to 0, you should manually exec the
 | 
				
			||||||
 | 
							|:TsuquyomiOpen| command after opening buffers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*g:tsuquyomi_use_local_typescript*
 | 
				
			||||||
 | 
					g:tsuquyomi_use_local_typescript (default 1)
 | 
				
			||||||
 | 
							Whether to use `tsserver.js`that was installed for project
 | 
				
			||||||
 | 
							locally.
 | 
				
			||||||
 | 
							* 0: Tsuquyomi does not search `tsserver.js`.
 | 
				
			||||||
 | 
							* 1: Tsuquyomi searches the root directory(which has
 | 
				
			||||||
 | 
							     `package.json`) of the project from the current directory.
 | 
				
			||||||
 | 
							     Then, it searches
 | 
				
			||||||
 | 
							     `node_modules/typescript/bin/tsserver.js` from the
 | 
				
			||||||
 | 
							     project root.
 | 
				
			||||||
 | 
							     If not hit, Tsuquyomi determines `tsserver.js` path from
 | 
				
			||||||
 | 
							     |g:tsuquyomi_use_dev_node_module| option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*g:tsuquyomi_use_dev_node_module*
 | 
				
			||||||
 | 
					g:tsuquyomi_use_dev_node_module	(default 0)
 | 
				
			||||||
 | 
							Whether to use `tsserver.js` that was installed manually.
 | 
				
			||||||
 | 
							* 0: Tsuquyomi uses global installed `tsserver` command(default).
 | 
				
			||||||
 | 
							* 1: Tsuquyomi uses
 | 
				
			||||||
 | 
							     `tsuquyomi/node_modules/typescript/bin/tsserver.js` .
 | 
				
			||||||
 | 
							     If you use this mode, exec the following:
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
							     :cd ~/.vim/bundle/tsuquyomi
 | 
				
			||||||
 | 
							     :!npm install
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
							* 2: Tsuquyomi uses `tsserver.js` whose path is
 | 
				
			||||||
 | 
							     |g:tsuquyomi_tsserver_path| .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_tsserver_path*
 | 
				
			||||||
 | 
					g:tsuquyomi_tsserver_path	(default `''`)
 | 
				
			||||||
 | 
							If |g:tsuquyomi_use_dev_node_module| equals `2`,
 | 
				
			||||||
 | 
							user should set path of `tsserver.js` to this variable.
 | 
				
			||||||
 | 
							For example,
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
							let g:tsuquyomi_use_dev_node_module = 2
 | 
				
			||||||
 | 
							let g:tsuquyomi_tsserver_path =
 | 
				
			||||||
 | 
							\ '~/typescript/built/local/tsserver.js'
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_nodejs_path*
 | 
				
			||||||
 | 
					g:tsuquyomi_nodejs_path		(default "node")
 | 
				
			||||||
 | 
							A path to Node.js.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_definition_split*
 | 
				
			||||||
 | 
					g:tsuquyomi_definition_split	(default 0)
 | 
				
			||||||
 | 
							A way to open a target file when navigating with
 | 
				
			||||||
 | 
							|:TsuquyomiDefinition| or |:TsuquyomiTypeDefinition|.
 | 
				
			||||||
 | 
							* 0: |:edit|
 | 
				
			||||||
 | 
							* 1: |:split|
 | 
				
			||||||
 | 
							* 2: |:vsplit|
 | 
				
			||||||
 | 
							* 3: |:tabedit|
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*g:tsuquyomi_completion_detail*
 | 
				
			||||||
 | 
					g:tsuquyomi_completion_detail		(default 0)
 | 
				
			||||||
 | 
							Whether to show details of complete menu when |tsuquyomi#complete|.
 | 
				
			||||||
 | 
							This option makes sense when 'completeopt' includes "menu".
 | 
				
			||||||
 | 
							NOTE: If it's set, completions get slow.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*g:tsuquyomi_completion_case_sensitive*
 | 
				
			||||||
 | 
					g:tsuquyomi_completion_case_sensitive	(default 0)
 | 
				
			||||||
 | 
							Whether to search completion case-sensitively when
 | 
				
			||||||
 | 
							|tsuquyomi#complete|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*g:tsuquyomi_case_sensitive_imports*
 | 
				
			||||||
 | 
					g:tsuquyomi_case_sensitive_imports	(default 0)
 | 
				
			||||||
 | 
							Whether to search imports case-sensitively when
 | 
				
			||||||
 | 
							|tsuquyomi#es6import#complete|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*g:tsuquyomi_completion_preview*
 | 
				
			||||||
 | 
					g:tsuquyomi_completion_preview		(default 0)
 | 
				
			||||||
 | 
							Whether to show signature in preview when |tsuquyomi#complete|.
 | 
				
			||||||
 | 
							This option makes sense when 'completeopt' includes "menu"
 | 
				
			||||||
 | 
							and "preview".
 | 
				
			||||||
 | 
							NOTE: If it's set, completions get a little slow.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_disable_default_mappings*
 | 
				
			||||||
 | 
					g:tsuquyomi_disable_default_mappings	(default 0)
 | 
				
			||||||
 | 
							If set no keys are mapped.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_disable_quickfix*
 | 
				
			||||||
 | 
					g:tsuquyomi_disable_quickfix	(default 0)
 | 
				
			||||||
 | 
							If set, |:TsuquyomiGeterr| isn't called when you save buffers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_save_onrename*
 | 
				
			||||||
 | 
					g:tsuquyomi_save_onrename	(default 0)
 | 
				
			||||||
 | 
							If set, Tsuquyomi automatically saves files in which symbols
 | 
				
			||||||
 | 
							are replaced when |:TsuquyomiRenameSymbol| is used.
 | 
				
			||||||
 | 
							If not set, Tsuquyomi shows replaced files with |:split|.
 | 
				
			||||||
 | 
							You can save them with |:wa| after your review changes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_single_quote_import*
 | 
				
			||||||
 | 
					g:tsuquyomi_single_quote_import		(default 0)
 | 
				
			||||||
 | 
							If set, Tsuquyomi generates import blocks using single quotes
 | 
				
			||||||
 | 
							instead of double quotes when |:TsuquyomiImport|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_semicolon_import*
 | 
				
			||||||
 | 
					g:tsuquyomi_semicolon_import		(default 1)
 | 
				
			||||||
 | 
							If set, Tsuquyomi generates import block using a semicolon at
 | 
				
			||||||
 | 
							the end when |:TsuquyomiImport|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_baseurl_import_path*
 | 
				
			||||||
 | 
					g:tsuquyomi_baseurl_import_path		(default 0)
 | 
				
			||||||
 | 
							If set, |:TsuquyomiImport| will use module paths relative to
 | 
				
			||||||
 | 
							`baseUrl` setting in tsconfig.json.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_javascript_support*
 | 
				
			||||||
 | 
					g:tsuquyomi_javascript_support	(default 0)
 | 
				
			||||||
 | 
							If set, Tsuquyomi will also be enabled for JavaScript files.
 | 
				
			||||||
 | 
							You can further configure tsserver's behavior using
 | 
				
			||||||
 | 
							tsconfig.json or jsconfig.json in your project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_ignore_missing_modules*
 | 
				
			||||||
 | 
					g:tsuquyomi_ignore_missing_modules (default 0)
 | 
				
			||||||
 | 
							If set, Tsuquyomi will ignore any error that starts with
 | 
				
			||||||
 | 
							"Cannot find module". Useful when you don't have type
 | 
				
			||||||
 | 
							definitions for all of your imports.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_use_vimproc*
 | 
				
			||||||
 | 
					g:tsuquyomi_use_vimproc (default 0)
 | 
				
			||||||
 | 
							If set, Tsuquyomi will use |vimproc| instead of vim8 default
 | 
				
			||||||
 | 
							jobs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*g:tsuquyomi_locale*
 | 
				
			||||||
 | 
					g:tsuquyomi_locale (default "en")
 | 
				
			||||||
 | 
							LCID for deagonistics localization.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					KEY MAPPINGS					*tsuquyomi-key-mappings*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Normal mode key mappings.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiDefinition)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiDefinition)
 | 
				
			||||||
 | 
							Navigate to the location where the symbol under the cursor is
 | 
				
			||||||
 | 
							defined. See |:TsuquyomiDefinition|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiSplitDefinition)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiSplitDefinition)
 | 
				
			||||||
 | 
							Split current window in two. Navigate to the location where
 | 
				
			||||||
 | 
							the symbol under the cursor is defined. See
 | 
				
			||||||
 | 
							|:TsuquyomiSplitDefinition|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiTypeDefinition)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiTypeDefinition)
 | 
				
			||||||
 | 
							Navigate to the location where the type of the symbol under the
 | 
				
			||||||
 | 
							cursor is defined. See |:TsuquyomiTypeDefinition|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiGoBack)				*<Plug>(TsuquyomiGoBack)*
 | 
				
			||||||
 | 
							See |:TsuquyomiGoBack|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiImplementation)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiImplementation)
 | 
				
			||||||
 | 
							Show a list of locations where the interface under the cursor is
 | 
				
			||||||
 | 
							implemented. See |:TsuquyomiImplementation|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiReferences)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiReferences)
 | 
				
			||||||
 | 
							Show a list of locations where the symbol under the cursor is
 | 
				
			||||||
 | 
							referenced. See |:TsuquyomiReferences|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*<Plug>(TsuquyomiRenameSymbol)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiRenameSymbol)
 | 
				
			||||||
 | 
							Rename the identifier under the cursor to a new name.
 | 
				
			||||||
 | 
							See |:TsuquyomiRenameSymbol|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										*<Plug>(TsuquyomiRenameSymbolC)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiRenameSymbolC)
 | 
				
			||||||
 | 
							Rename the identifier under the cursor to a new name.
 | 
				
			||||||
 | 
							See |:TsuquyomiRenameSymbolC|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiQuickFix)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiQuickFix)
 | 
				
			||||||
 | 
							Apply quick fix under the cursor if it's available.
 | 
				
			||||||
 | 
							See |:TsuquyomiQuickFix|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiImport)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiImport)
 | 
				
			||||||
 | 
							Generate ES6 import declaration whose alias is under
 | 
				
			||||||
 | 
							the cursor. See |:TsuquyomiImport|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*<Plug>(TsuquyomiSignatureHelp)*
 | 
				
			||||||
 | 
					<Plug>(TsuquyomiSignatureHelp)
 | 
				
			||||||
 | 
							Display signature help for the method arguments under the
 | 
				
			||||||
 | 
							cursor. See |:TsuquyomiSignatureHelp|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following keymappings are default keymappings.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Normal mode default mappings.
 | 
				
			||||||
 | 
					{lhs}			{rhs}
 | 
				
			||||||
 | 
					--------		-----------------------------
 | 
				
			||||||
 | 
					<C-]>			<Plug>(TsuquyomiDefinition)
 | 
				
			||||||
 | 
					<C-W>]			<Plug>(TsuquyomiSplitDefinition)
 | 
				
			||||||
 | 
					<C-W><C-]>		<Plug>(TsuquyomiSplitDefinition)
 | 
				
			||||||
 | 
					<C-t>			<Plug>(TsuquyomiGoBack)
 | 
				
			||||||
 | 
					<C-^>			<Plug>(TsuquyomiReferences)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					FUNCTIONS					*tsuquyomi-functions*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tsuquyomi#complete				*tsuquyomi#complete*
 | 
				
			||||||
 | 
							It's applicable for the 'completefunc' or 'omnifunc' option.
 | 
				
			||||||
 | 
							By default, Tsuquyomi sets this function to the 'omnifunc'
 | 
				
			||||||
 | 
							option.
 | 
				
			||||||
 | 
							If you want to customize completions, see
 | 
				
			||||||
 | 
							|tsuquyomi-examples-complete|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tsuquyomi#balloonexpr	 			*tsuquyomi#balloonexpr*
 | 
				
			||||||
 | 
							Returns information about the symbol under the mouse cursor for
 | 
				
			||||||
 | 
							tooltip popover window.
 | 
				
			||||||
 | 
							This is used as the rhs for 'balloonexpr'.
 | 
				
			||||||
 | 
							For example,
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
							set ballooneval
 | 
				
			||||||
 | 
							autocmd BufNewFile,BufRead *.ts
 | 
				
			||||||
 | 
							\ setlocal balloonexpr=tsuquyomi#balloonexpr()
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
							Note: This function works only if your Vim is compiled with
 | 
				
			||||||
 | 
							      |+balloon_eval|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tsuquyomi#hint					*tsuquyomi#hint*
 | 
				
			||||||
 | 
							Returns information about the symbol under the cursor. This
 | 
				
			||||||
 | 
							function is similar to |tsuquyomi#balloonexpr|, but
 | 
				
			||||||
 | 
							works not only in GVim but also in terminal Vim.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							For example,
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
							autocmd FileType typescript nmap <buffer> <Leader>t :
 | 
				
			||||||
 | 
							\ <C-u>echo tsuquyomi#hint()<CR>
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
					tsuquyomi#getSupportedCodeFixes		 *tsuquyomi#getSupportedCodeFixes*
 | 
				
			||||||
 | 
							Returns a list of all code quick fixes available.
 | 
				
			||||||
 | 
							An error whose code is in this list can be fixed via
 | 
				
			||||||
 | 
							|:TsuquyomiQuickFix| command.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Todo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					EXAMPLES					*tsuquyomi-examples*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											*tsuquyomi-examples-complete*
 | 
				
			||||||
 | 
					You can configure tsuquyomi completion, using 'completeopt' .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						When completion in call of some method, show the method signature to
 | 
				
			||||||
 | 
						the preview window.
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
						autocmd FileType typescript setlocal completeopt+=preview
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
						When completion, don't show the popup menu of completions.
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
						autocmd FileType typescript setlocal completeopt-=menu
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
					Show compile errors to QuickFix window asynchronous by Vim8's Job/Channel
 | 
				
			||||||
 | 
					feature.
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
						autocmd InsertLeave,BufWritePost *.ts,*.tsx call tsuquyomi#asyncGeterr()
 | 
				
			||||||
 | 
					<
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					vim:tw=78:ts=8:ft=help:norl:noet:fen:
 | 
				
			||||||
@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					autocmd BufNewFile,BufRead *.ts,*.tsx setfiletype typescript
 | 
				
			||||||
@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					" FILE: ftplugin/javascript.vim
 | 
				
			||||||
 | 
					" AUTHOR: Quramy <yosuke.kurami@gmail.com>
 | 
				
			||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if !g:tsuquyomi_javascript_support
 | 
				
			||||||
 | 
					  finish
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if !tsuquyomi#config#preconfig()
 | 
				
			||||||
 | 
					  finish
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					call tsuquyomi#config#initBuffer({ 'pattern': '*.js,*.jsx' })
 | 
				
			||||||
@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					" FILE: ftplugin/typescript.vim
 | 
				
			||||||
 | 
					" AUTHOR: Quramy <yosuke.kurami@gmail.com>
 | 
				
			||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if !tsuquyomi#config#preconfig()
 | 
				
			||||||
 | 
					  finish
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					call tsuquyomi#config#initBuffer({ 'pattern': '*.ts,*.tsx' })
 | 
				
			||||||
@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "name": "tsuquyomi",
 | 
				
			||||||
 | 
					  "version": "0.7.0",
 | 
				
			||||||
 | 
					  "description": "Vim plugin for typescript",
 | 
				
			||||||
 | 
					  "directories": {
 | 
				
			||||||
 | 
					    "test": "vest"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "repository": "https://github.com/Quramy/tsuquyomi.git",
 | 
				
			||||||
 | 
					  "devDependencies": {
 | 
				
			||||||
 | 
					    "typescript": "~3.0.1"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "scripts": {
 | 
				
			||||||
 | 
					    "test": "bash runtest.sh"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "author": "Quramy",
 | 
				
			||||||
 | 
					  "license": "MIT"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					" FILE: tsuquyomi.vim
 | 
				
			||||||
 | 
					" AUTHOR: Quramy <yosuke.kurami@gmail.com>
 | 
				
			||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Preprocessing {{{
 | 
				
			||||||
 | 
					if exists('g:loaded_tsuquyomi')
 | 
				
			||||||
 | 
					  finish
 | 
				
			||||||
 | 
					elseif v:version < 704
 | 
				
			||||||
 | 
					  echoerr 'Tsuquyomi does not work this version of Vim "' . v:version . '".'
 | 
				
			||||||
 | 
					  finish
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let g:loaded_tsuquyomi = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:save_cpo = &cpo
 | 
				
			||||||
 | 
					set cpo&vim
 | 
				
			||||||
 | 
					" Preprocessing }}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Global options defintion. {{{
 | 
				
			||||||
 | 
					let g:tsuquyomi_auto_open =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_auto_open', 1)
 | 
				
			||||||
 | 
					let g:tsuquyomi_use_local_typescript =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_use_local_typescript', 1)
 | 
				
			||||||
 | 
					let g:tsuquyomi_use_dev_node_module =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_use_dev_node_module', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_tsserver_path =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_tsserver_path', '')
 | 
				
			||||||
 | 
					let g:tsuquyomi_debug = 
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_debug', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_tsserver_debug = 
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_tsserver_debug', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_nodejs_path = 
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_nodejs_path', 'node')
 | 
				
			||||||
 | 
					let g:tsuquyomi_waittime_after_open = 
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_waittime_after_open', str2float("0.01"))
 | 
				
			||||||
 | 
					let g:tsuquyomi_completion_chunk_size = 
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_completion_chunk_size', 20)
 | 
				
			||||||
 | 
					let g:tsuquyomi_completion_detail = 
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_completion_detail', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_completion_case_sensitive = 
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_completion_case_sensitive', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_case_sensitive_imports =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_case_sensitive_imports', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_completion_preview = 
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_completion_preview', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_definition_split =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_definition_split', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_disable_quickfix =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_disable_quickfix', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_save_onrename =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_save_onrename', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_single_quote_import =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_single_quote_import', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_semicolon_import =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_semicolon_import', 1)
 | 
				
			||||||
 | 
					let g:tsuquyomi_import_curly_spacing =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_import_curly_spacing', 1)
 | 
				
			||||||
 | 
					let g:tsuquyomi_javascript_support =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_javascript_support', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_ignore_missing_modules =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_ignore_missing_modules', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_shortest_import_path = 
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_shortest_import_path', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_baseurl_import_path = 
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_baseurl_import_path', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_use_vimproc =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_use_vimproc', 0)
 | 
				
			||||||
 | 
					let g:tsuquyomi_locale =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_locale', 'en')
 | 
				
			||||||
 | 
					let g:tsuquyomi_search_term_min_length =
 | 
				
			||||||
 | 
					      \ get(g:, 'tsuquyomi_search_term_min_length', 3)
 | 
				
			||||||
 | 
					" Global options defintion. }}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" augroup tsuquyomi_global_command_group
 | 
				
			||||||
 | 
					"   autocmd!
 | 
				
			||||||
 | 
					" augroup END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Define commands to operate TSServer
 | 
				
			||||||
 | 
					command! TsuquyomiStartServer  : call tsuquyomi#startServer()
 | 
				
			||||||
 | 
					command! TsuStartServer        : call tsuquyomi#startServer()
 | 
				
			||||||
 | 
					command! TsuquyomiStatusServer : echom tsuquyomi#statusServer()
 | 
				
			||||||
 | 
					command! TsuStatusServer       : echom tsuquyomi#statusServer()
 | 
				
			||||||
 | 
					command! TsuquyomiStopServer   : call tsuquyomi#stopServer()
 | 
				
			||||||
 | 
					command! TsuStopServer         : call tsuquyomi#stopServer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Close and re-open all buffers
 | 
				
			||||||
 | 
					command! TsuquyomiReloadProject : call tsuquyomi#reloadProject()
 | 
				
			||||||
 | 
					command! TsuReloadProject       : call tsuquyomi#reloadProject()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let &cpo = s:save_cpo
 | 
				
			||||||
 | 
					unlet s:save_cpo
 | 
				
			||||||
@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set -xe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ "${VERSION}" == "" ]; then
 | 
				
			||||||
 | 
					  VERSION=3.2
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TSSERVER_PATH="$(pwd)/test/node_modules/typescript-${VERSION}/bin/tsserver"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vim -u test/.vimrc \
 | 
				
			||||||
 | 
					  -c 'let g:tsuquyomi_use_local_typescript = 0' \
 | 
				
			||||||
 | 
					  -c 'let g:tsuquyomi_use_dev_node_module = 2' \
 | 
				
			||||||
 | 
					  -c "let g:tsuquyomi_tsserver_path = \"${TSSERVER_PATH}\""  \
 | 
				
			||||||
 | 
					  -c 'call vesting#load()' \
 | 
				
			||||||
 | 
					  -c 'call vesting#init()' \
 | 
				
			||||||
 | 
					  -c "so $1" -c 'echom string(vesting#get_result())'
 | 
				
			||||||
@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set -xe
 | 
				
			||||||
 | 
					VERSION=2.0 ./runtest.sh
 | 
				
			||||||
 | 
					VERSION=2.1 ./runtest.sh
 | 
				
			||||||
 | 
					VERSION=2.2 ./runtest.sh
 | 
				
			||||||
 | 
					VERSION=2.3 ./runtest.sh
 | 
				
			||||||
 | 
					VERSION=2.4 ./runtest.sh
 | 
				
			||||||
 | 
					VERSION=2.5 ./runtest.sh
 | 
				
			||||||
 | 
					VERSION=2.6 ./runtest.sh
 | 
				
			||||||
 | 
					VERSION=2.7 ./runtest.sh
 | 
				
			||||||
 | 
					VERSION=2.8 ./runtest.sh
 | 
				
			||||||
 | 
					VERSION=2.9 ./runtest.sh
 | 
				
			||||||
 | 
					VERSION=3.0 ./runtest.sh
 | 
				
			||||||
 | 
					VERSION=3.1 ./runtest.sh
 | 
				
			||||||
 | 
					VERSION=3.2 ./runtest.sh
 | 
				
			||||||
@ -0,0 +1,104 @@
 | 
				
			|||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VIMRC_FILE="test/.vimrc"
 | 
				
			||||||
 | 
					DRIVER_FILE="test/_runner"
 | 
				
			||||||
 | 
					RESULT_FILE="test/test_result.log"
 | 
				
			||||||
 | 
					VIM_BUILD=1
 | 
				
			||||||
 | 
					VIM_INSTALL_DIR=`pwd`/local
 | 
				
			||||||
 | 
					if [ "${VERSION}" == "" ]; then
 | 
				
			||||||
 | 
					  VERSION=3.2
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					TSSERVER_PATH="$(pwd)/test/node_modules/typescript-${VERSION}/bin/tsserver"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo "Run test with ${TSSERVER_PATH}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ "${VIM_BUILD}" -eq 1 ]; then
 | 
				
			||||||
 | 
					  echo "`date "+[%Y-%m-%dT%H:%M:%S]"` Use local Vim."
 | 
				
			||||||
 | 
					  if [ ! -d "./local" ]; then
 | 
				
			||||||
 | 
					    echo "`date "+[%Y-%m-%dT%H:%M:%S]"` Installing Vim"
 | 
				
			||||||
 | 
					    if [ ! -d "./vim" ]; then
 | 
				
			||||||
 | 
					      echo "`date "+[%Y-%m-%dT%H:%M:%S]"` Clonning Vim source from Github"
 | 
				
			||||||
 | 
					      git clone --depth 1 https://github.com/vim/vim.git
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    cd vim
 | 
				
			||||||
 | 
					    ./configure --prefix=${VIM_INSTALL_DIR}
 | 
				
			||||||
 | 
					    if [ ! $? -eq 0 ]; then
 | 
				
			||||||
 | 
					      exit $?
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    make
 | 
				
			||||||
 | 
					    if [ ! $? -eq 0 ]; then
 | 
				
			||||||
 | 
					      exit $?
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    make install
 | 
				
			||||||
 | 
					    if [ ! $? -eq 0 ]; then
 | 
				
			||||||
 | 
					      exit $?
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    echo "`date "+[%Y-%m-%dT%H:%M:%S]"` Vim was created successfully."
 | 
				
			||||||
 | 
					    cd ..
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  VIM_CMD="${VIM_INSTALL_DIR}/bin/vim"
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  echo "`date "+[%Y-%m-%dT%H:%M:%S]"` Use system Vim."
 | 
				
			||||||
 | 
					  VIM_CMD="vim"
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					${VIM_CMD} --version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ ! -d "./neobundle.vim" ]; then
 | 
				
			||||||
 | 
					  echo "`date "+[%Y-%m-%dT%H:%M:%S]"` Installing neobundle"
 | 
				
			||||||
 | 
					  git clone --depth 1 https://github.com/Shougo/neobundle.vim
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ "${HIDE_VIM}" == "" ]; then
 | 
				
			||||||
 | 
					  ${VIM_CMD} -u ${VIMRC_FILE} -c NeoBundleInstall -c q
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  ${VIM_CMD} -u ${VIMRC_FILE} -c NeoBundleInstall -c q > /dev/null
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ -f "${RESULT_FILE}" ]; then
 | 
				
			||||||
 | 
					  rm ${RESULT_FILE}
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo "`date "+[%Y-%m-%dT%H:%M:%S]"` Run vesting."
 | 
				
			||||||
 | 
					# In CI, displaying Vim UI is meaningless and it makes CI logs dirty.
 | 
				
			||||||
 | 
					# So hide Vim UI.
 | 
				
			||||||
 | 
					if [ "${HIDE_VIM}" == "" ]; then
 | 
				
			||||||
 | 
					  ${VIM_CMD} \
 | 
				
			||||||
 | 
					    -c 'let g:tsuquyomi_use_local_typescript = 0' \
 | 
				
			||||||
 | 
					    -c 'let g:tsuquyomi_use_dev_node_module = 2' \
 | 
				
			||||||
 | 
					    -c "let g:tsuquyomi_tsserver_path = \"${TSSERVER_PATH}\""  \
 | 
				
			||||||
 | 
					    -u ${VIMRC_FILE} \
 | 
				
			||||||
 | 
					    -s ${DRIVER_FILE}
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  ${VIM_CMD} \
 | 
				
			||||||
 | 
					    -c 'let g:tsuquyomi_use_local_typescript = 0' \
 | 
				
			||||||
 | 
					    -c 'let g:tsuquyomi_use_dev_node_module = 2' \
 | 
				
			||||||
 | 
					    -c "let g:tsuquyomi_tsserver_path = \"${TSSERVER_PATH}\""  \
 | 
				
			||||||
 | 
					    -u ${VIMRC_FILE} \
 | 
				
			||||||
 | 
					    -s ${DRIVER_FILE} > /dev/null
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					if [ $? -ne 0 ]; then
 | 
				
			||||||
 | 
					  echo "Vim exited with non-zero status."
 | 
				
			||||||
 | 
					  exit 1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					echo "`date "+[%Y-%m-%dT%H:%M:%S]"` Done."
 | 
				
			||||||
 | 
					echo "`date "+[%Y-%m-%dT%H:%M:%S]"` Result: (${RESULT_FILE})"
 | 
				
			||||||
 | 
					cat ${RESULT_FILE}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					grep -E "\[Fail\]" ${RESULT_FILE} > /dev/null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ $? -eq 0 ]; then
 | 
				
			||||||
 | 
					  echo "`date "+[%Y-%m-%dT%H:%M:%S]"` Test was failed."
 | 
				
			||||||
 | 
					  exit 1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					grep -E "\[Error\]" ${RESULT_FILE} > /dev/null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ $? -eq 0 ]; then
 | 
				
			||||||
 | 
					  echo "`date "+[%Y-%m-%dT%H:%M:%S]"` Test was failed."
 | 
				
			||||||
 | 
					  exit 1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo "`date "+[%Y-%m-%dT%H:%M:%S]"` Test was succeeded."
 | 
				
			||||||
 | 
					exit 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
											
												Binary file not shown.
											
										
									
								| 
		 After Width: | Height: | Size: 391 KiB  | 
@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					" FILE: syntax_checkers/typescript/tsuquyomi.vim
 | 
				
			||||||
 | 
					" AUTHOR: Quramy <yosuke.kurami@gmail.com>
 | 
				
			||||||
 | 
					"============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" Preprocessing {{{
 | 
				
			||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					if exists('g:loaded_syntastic_tsuquyomi_syntax_checker')
 | 
				
			||||||
 | 
					  finish
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let g:loaded_syntastic_tsuquyomi_syntax_checker = 1
 | 
				
			||||||
 | 
					let s:save_cpo = &cpo
 | 
				
			||||||
 | 
					set cpo&vim
 | 
				
			||||||
 | 
					" Preprocessing }}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! SyntaxCheckers_typescript_tsuquyomi_IsAvailable() dict abort
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function! SyntaxCheckers_typescript_tsuquyomi_GetLocList() dict abort
 | 
				
			||||||
 | 
					  let quickfix_list = tsuquyomi#createFixlist()
 | 
				
			||||||
 | 
					  for qf in quickfix_list
 | 
				
			||||||
 | 
					    let qf.valid = 1
 | 
				
			||||||
 | 
					    let qf.bufnr = bufnr('%')
 | 
				
			||||||
 | 
					  endfor
 | 
				
			||||||
 | 
					  return quickfix_list
 | 
				
			||||||
 | 
					endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					call g:SyntasticRegistry.CreateAndRegisterChecker({
 | 
				
			||||||
 | 
					      \ 'filetype': 'typescript',
 | 
				
			||||||
 | 
					      \ 'name': 'tsuquyomi'
 | 
				
			||||||
 | 
					      \ })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let &cpo = s:save_cpo
 | 
				
			||||||
 | 
					unlet s:save_cpo
 | 
				
			||||||
@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					set nocompatible
 | 
				
			||||||
 | 
					let s:basedir = expand('<sfile>:p:h').'/../'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					execute('set runtimepath+='.s:basedir)
 | 
				
			||||||
 | 
					execute('set runtimepath+='.s:basedir.'neobundle.vim')
 | 
				
			||||||
 | 
					call neobundle#begin(expand(s:basedir.'bundle'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NeoBundle 'Shougo/unite.vim'
 | 
				
			||||||
 | 
					NeoBundle 'Shougo/vesting'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NeoBundle 'Shougo/vimproc.vim', {
 | 
				
			||||||
 | 
					      \ 'build' : {
 | 
				
			||||||
 | 
					      \     'windows' : 'tools\\update-dll-mingw',
 | 
				
			||||||
 | 
					      \     'cygwin' : 'make -f make_cygwin.mak',
 | 
				
			||||||
 | 
					      \     'mac' : 'make -f make_mac.mak',
 | 
				
			||||||
 | 
					      \     'linux' : 'make',
 | 
				
			||||||
 | 
					      \     'unix' : 'gmake',
 | 
				
			||||||
 | 
					      \    },
 | 
				
			||||||
 | 
					      \ }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					call neobundle#end()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let g:tsuquyomi_use_dev_node_module = 1
 | 
				
			||||||
 | 
					source plugin/tsuquyomi.vim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					:Unite vesting:./test/tsClient
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					:call unite#action#do('start')
 | 
				
			||||||
 | 
					k
 | 
				
			||||||
 | 
					ygg
 | 
				
			||||||
 | 
					:winc j
 | 
				
			||||||
 | 
					p
 | 
				
			||||||
 | 
					:%s/\n\s*\[OK\].*\s/+/g
 | 
				
			||||||
 | 
					:%s/\s\+/ /g
 | 
				
			||||||
 | 
					:%s/^\s\+\[Vest\]/[Vest]/g
 | 
				
			||||||
 | 
					:w! test/test_result.log
 | 
				
			||||||
 | 
					gg
 | 
				
			||||||
 | 
					dG
 | 
				
			||||||
 | 
					:winc k
 | 
				
			||||||
 | 
					q
 | 
				
			||||||
 | 
					q
 | 
				
			||||||
 | 
					:Unite vesting:./test/es6import
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					:call unite#action#do('start')
 | 
				
			||||||
 | 
					k
 | 
				
			||||||
 | 
					ygg
 | 
				
			||||||
 | 
					:winc j
 | 
				
			||||||
 | 
					p
 | 
				
			||||||
 | 
					:%s/\n\s*\[OK\].*\s/+/g
 | 
				
			||||||
 | 
					:%s/\s\+/ /g
 | 
				
			||||||
 | 
					:%s/^\s\+\[Vest\]/[Vest]/g
 | 
				
			||||||
 | 
					:w! >> test/test_result.log
 | 
				
			||||||
 | 
					:quitall!
 | 
				
			||||||
 | 
					vim:ft=vim
 | 
				
			||||||
@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					let s:script_dir = s:Filepath.join(tsuquyomi#rootDir(), 'test/es6import/vest')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" FIXME
 | 
				
			||||||
 | 
					" Context tsuquyomi#es6import#checkExternalModule(moduleName, file, no_use_cache)
 | 
				
			||||||
 | 
					"   let s:input_file = s:Filepath.join(s:script_dir, 'resources/variousModules.d.ts')
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   It returns 0 when the file does not have the given module
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#tsOpen(s:input_file)
 | 
				
			||||||
 | 
					"     let code = tsuquyomi#es6import#checkExternalModule('__NO_MODULE__', s:input_file, 1)
 | 
				
			||||||
 | 
					"     Should code == 0
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   It returns 1 when the file has single-quated module
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#tsOpen(s:input_file)
 | 
				
			||||||
 | 
					"     let code = tsuquyomi#es6import#checkExternalModule('external-module', s:input_file, 1)
 | 
				
			||||||
 | 
					"     Should code == 1
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   It returns 1 when the file has a double-quated module
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#tsOpen(s:input_file)
 | 
				
			||||||
 | 
					"     let code = tsuquyomi#es6import#checkExternalModule('external-module/alt', s:input_file, 1)
 | 
				
			||||||
 | 
					"     Should code == 1
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   It returns 0 when the file has a namespace
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#tsOpen(s:input_file)
 | 
				
			||||||
 | 
					"     let code = tsuquyomi#es6import#checkExternalModule('NS', s:input_file, 1)
 | 
				
			||||||
 | 
					"     Should code == 0
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   It returns 0 when the file has an internal module
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#tsOpen(s:input_file)
 | 
				
			||||||
 | 
					"     let code = tsuquyomi#es6import#checkExternalModule('InternalModule', s:input_file, 1)
 | 
				
			||||||
 | 
					"     Should code == 0
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					" End
 | 
				
			||||||
@ -0,0 +1,125 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					let s:script_dir = s:Filepath.join(tsuquyomi#rootDir(), 'test/es6import/vest')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					" FIXME
 | 
				
			||||||
 | 
					" Context tsuquyomi#es6import#getImportDeclarations(file)
 | 
				
			||||||
 | 
					"   let s:resource_dir = s:Filepath.join(s:script_dir, 'resources/importDecPatterns')
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   " It returns 'no_nav_bar' reason when input files is empty
 | 
				
			||||||
 | 
					"   "   let s:file = s:Filepath.join(s:resource_dir, 'empty.ts')
 | 
				
			||||||
 | 
					"   "   call tsuquyomi#tsClient#tsOpen(s:file)
 | 
				
			||||||
 | 
					"   "   let [result_list, position, reason] = tsuquyomi#es6import#getImportDeclarations(s:file, readfile(s:file))
 | 
				
			||||||
 | 
					"   "   Should reason ==# 'no_module_info'
 | 
				
			||||||
 | 
					"   "   call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   " End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   " It returns 'no_module_info' reason and position info when input file doesn't have aliases
 | 
				
			||||||
 | 
					"   "   let s:file = s:Filepath.join(s:resource_dir, 'noDec.ts')
 | 
				
			||||||
 | 
					"   "   call tsuquyomi#tsClient#tsOpen(s:file)
 | 
				
			||||||
 | 
					"   "   let [result_list, position, reason] = tsuquyomi#es6import#getImportDeclarations(s:file, readfile(s:file))
 | 
				
			||||||
 | 
					"   "   Should reason ==# 'no_module_info'
 | 
				
			||||||
 | 
					"   "   Should position.start.line == 1
 | 
				
			||||||
 | 
					"   "   Should position.end.line == 3
 | 
				
			||||||
 | 
					"   "   call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   " End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   It returns position when input file has import declaration and other declarations
 | 
				
			||||||
 | 
					"     let s:file = s:Filepath.join(s:resource_dir, 'decAndOther.ts')
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#tsOpen(s:file)
 | 
				
			||||||
 | 
					"     let [result_list, position, reason] = tsuquyomi#es6import#getImportDeclarations(s:file, readfile(s:file))
 | 
				
			||||||
 | 
					"     Should reason ==# ''
 | 
				
			||||||
 | 
					"     Should position.start.line == 1
 | 
				
			||||||
 | 
					"     Should position.end.line == 1
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   It returns position when input file has import declaration and expression
 | 
				
			||||||
 | 
					"     let s:file = s:Filepath.join(s:resource_dir, 'decAndFunction.ts')
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#tsOpen(s:file)
 | 
				
			||||||
 | 
					"     let [result_list, position, reason] = tsuquyomi#es6import#getImportDeclarations(s:file, readfile(s:file))
 | 
				
			||||||
 | 
					"     Should reason ==# ''
 | 
				
			||||||
 | 
					"     Should position.start.line == 1
 | 
				
			||||||
 | 
					"     Should position.end.line == 1
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   It returns declaration_info list
 | 
				
			||||||
 | 
					"     let s:file = s:Filepath.join(s:resource_dir, 'simple.ts')
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#tsOpen(s:file)
 | 
				
			||||||
 | 
					"     let [result_list, position, reason] = tsuquyomi#es6import#getImportDeclarations(s:file, readfile(s:file))
 | 
				
			||||||
 | 
					"     Should reason ==# ''
 | 
				
			||||||
 | 
					"     Should position.start.line == 1
 | 
				
			||||||
 | 
					"     Should position.end.line == 1
 | 
				
			||||||
 | 
					"     Should len(result_list) == 1
 | 
				
			||||||
 | 
					"     Should result_list[0].is_oneliner == 1
 | 
				
			||||||
 | 
					"     Should result_list[0].module.name ==# './some-module'
 | 
				
			||||||
 | 
					"     Should result_list[0].module.start.line == 1
 | 
				
			||||||
 | 
					"     Should result_list[0].module.end.line == 1
 | 
				
			||||||
 | 
					"     Should result_list[0].has_brace == 1
 | 
				
			||||||
 | 
					"     Should result_list[0].brace.end.line == 1
 | 
				
			||||||
 | 
					"     Should result_list[0].brace.end.offset == 18
 | 
				
			||||||
 | 
					"     Should result_list[0].has_from == 1
 | 
				
			||||||
 | 
					"     Should result_list[0].from_span.start.offset == 20 
 | 
				
			||||||
 | 
					"     Should result_list[0].from_span.start.line == 1
 | 
				
			||||||
 | 
					"     Should result_list[0].from_span.end.offset == 23 
 | 
				
			||||||
 | 
					"     Should result_list[0].from_span.end.line == 1
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   It returns a info whose 'is_oneliner' is 0 when input declaration contains multipule lines
 | 
				
			||||||
 | 
					"     let s:file = s:Filepath.join(s:resource_dir, 'multiline.ts')
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#tsOpen(s:file)
 | 
				
			||||||
 | 
					"     let [result_list, position, reason] = tsuquyomi#es6import#getImportDeclarations(s:file, readfile(s:file))
 | 
				
			||||||
 | 
					"     Should reason ==# ''
 | 
				
			||||||
 | 
					"     Should position.start.line == 1
 | 
				
			||||||
 | 
					"     Should position.end.line == 7
 | 
				
			||||||
 | 
					"     Should result_list[0].is_oneliner == 0
 | 
				
			||||||
 | 
					"     Should result_list[0].module.start.line == 7
 | 
				
			||||||
 | 
					"     Should result_list[0].module.end.line == 7
 | 
				
			||||||
 | 
					"     Should result_list[0].has_brace == 1
 | 
				
			||||||
 | 
					"     Should result_list[0].brace.end.line == 3
 | 
				
			||||||
 | 
					"     Should result_list[0].brace.end.offset == 13
 | 
				
			||||||
 | 
					"     Should result_list[0].has_from == 1
 | 
				
			||||||
 | 
					"     Should result_list[0].from_span.start.offset == 1
 | 
				
			||||||
 | 
					"     Should result_list[0].from_span.start.line == 5
 | 
				
			||||||
 | 
					"     Should result_list[0].from_span.end.offset == 4
 | 
				
			||||||
 | 
					"     Should result_list[0].from_span.end.line == 5
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   It returns the list whoes has multiple module infos when input declaration contains multiple aliases in one module
 | 
				
			||||||
 | 
					"     let s:file = s:Filepath.join(s:resource_dir, 'multiAlias.ts')
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#tsOpen(s:file)
 | 
				
			||||||
 | 
					"     let [result_list, position, reason] = tsuquyomi#es6import#getImportDeclarations(s:file, readfile(s:file))
 | 
				
			||||||
 | 
					"     Should len(result_list) == 2
 | 
				
			||||||
 | 
					"     Should result_list[0].alias_info.text ==# 'altVar'
 | 
				
			||||||
 | 
					"     Should result_list[1].alias_info.text ==# 'someVar'
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   It returns the list whoes has multiple module infos when input has 2 declaration
 | 
				
			||||||
 | 
					"     let s:file = s:Filepath.join(s:resource_dir, 'multiDec.ts')
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#tsOpen(s:file)
 | 
				
			||||||
 | 
					"     let [result_list, position, reason] = tsuquyomi#es6import#getImportDeclarations(s:file, readfile(s:file))
 | 
				
			||||||
 | 
					"     Should len(result_list) == 2
 | 
				
			||||||
 | 
					"     Should result_list[0].alias_info.text ==# 'altVar'
 | 
				
			||||||
 | 
					"     Should result_list[1].alias_info.text ==# 'someVar'
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					"   It returns explict alias info when declarations use 'as' keyword
 | 
				
			||||||
 | 
					"     let s:file = s:Filepath.join(s:resource_dir, 'explictAlias.ts')
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#tsOpen(s:file)
 | 
				
			||||||
 | 
					"     let [result_list, position, reason] = tsuquyomi#es6import#getImportDeclarations(s:file, readfile(s:file))
 | 
				
			||||||
 | 
					"     Should len(result_list) == 2
 | 
				
			||||||
 | 
					"     Should result_list[0].alias_info.text ==# '$var'
 | 
				
			||||||
 | 
					"     Should result_list[0].has_brace == 0
 | 
				
			||||||
 | 
					"     Should result_list[1].alias_info.text ==# '_var'
 | 
				
			||||||
 | 
					"     Should result_list[1].has_brace == 1
 | 
				
			||||||
 | 
					"     call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					"   End
 | 
				
			||||||
 | 
					" 
 | 
				
			||||||
 | 
					" End
 | 
				
			||||||
@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					import {someVar} from './some-module';
 | 
				
			||||||
 | 
					document.getElementById('myApp');
 | 
				
			||||||
@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					import { someVar } from './some-module';
 | 
				
			||||||
 | 
					class Hoge {
 | 
				
			||||||
 | 
					    private hoge: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					import { someVar as _var } from './some-module';
 | 
				
			||||||
 | 
					import * as $var from './some-module';
 | 
				
			||||||
@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					import {
 | 
				
			||||||
 | 
					    someVar,
 | 
				
			||||||
 | 
					    altVar
 | 
				
			||||||
 | 
					} from './some-module';
 | 
				
			||||||
@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					import { someVar } from './some-module';
 | 
				
			||||||
 | 
					import { altVar } from './some-module';
 | 
				
			||||||
@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					import {
 | 
				
			||||||
 | 
					    someVar
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					'./some-module';
 | 
				
			||||||
@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					///<reference path="./some-module.ts" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"use strict";
 | 
				
			||||||
 | 
					class TestClass {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					import { someVar } from './some-module';
 | 
				
			||||||
@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					export var someVar: any = null;
 | 
				
			||||||
 | 
					export var altVar: any = null;
 | 
				
			||||||
@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "compilerOptions": {
 | 
				
			||||||
 | 
					        "module": "commonjs",
 | 
				
			||||||
 | 
					        "target": "es5",
 | 
				
			||||||
 | 
					        "noImplicitAny": false,
 | 
				
			||||||
 | 
					        "sourceMap": false
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "decAndFunction.ts",
 | 
				
			||||||
 | 
					      "decAndOther.ts",
 | 
				
			||||||
 | 
					      "empty.ts",
 | 
				
			||||||
 | 
					      "explictAlias.ts",
 | 
				
			||||||
 | 
					      "multiAlias.ts",
 | 
				
			||||||
 | 
					      "multiline.ts",
 | 
				
			||||||
 | 
					      "noDec.ts",
 | 
				
			||||||
 | 
					      "simple.ts",
 | 
				
			||||||
 | 
					      "some-module.ts"
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					declare namespace NS {
 | 
				
			||||||
 | 
					    namespace nestedNS {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare namespace NS.nestedNS {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare module InternalModule {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare module InternalModule.SubModule {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare module 'external-module' {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare module "external-module/alt" {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "name": "tsuquyomi-test",
 | 
				
			||||||
 | 
					  "version": "0.0.0",
 | 
				
			||||||
 | 
					  "description": "package.json file for testing tsuquyomi",
 | 
				
			||||||
 | 
					  "main": "index.js",
 | 
				
			||||||
 | 
					  "license": "MIT",
 | 
				
			||||||
 | 
					  "dependencies": {
 | 
				
			||||||
 | 
					    "typescript-2.0": "npm:typescript@2.0",
 | 
				
			||||||
 | 
					    "typescript-2.1": "npm:typescript@2.1",
 | 
				
			||||||
 | 
					    "typescript-2.2": "npm:typescript@2.2",
 | 
				
			||||||
 | 
					    "typescript-2.3": "npm:typescript@2.3",
 | 
				
			||||||
 | 
					    "typescript-2.4": "npm:typescript@2.4",
 | 
				
			||||||
 | 
					    "typescript-2.5": "npm:typescript@2.5",
 | 
				
			||||||
 | 
					    "typescript-2.6": "npm:typescript@2.6",
 | 
				
			||||||
 | 
					    "typescript-2.7": "npm:typescript@2.7",
 | 
				
			||||||
 | 
					    "typescript-2.8": "npm:typescript@2.8",
 | 
				
			||||||
 | 
					    "typescript-2.9": "npm:typescript@2.9",
 | 
				
			||||||
 | 
					    "typescript-3.0": "npm:typescript@3.0",
 | 
				
			||||||
 | 
					    "typescript-3.1": "npm:typescript@3.1",
 | 
				
			||||||
 | 
					    "typescript-3.2": "npm:typescript@3.2"
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					module SimpleModule {
 | 
				
			||||||
 | 
					  export interface Runnable {
 | 
				
			||||||
 | 
					    run: ()=> any;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  export class MyClass implements Runnable{
 | 
				
			||||||
 | 
					    name: string;
 | 
				
			||||||
 | 
					    greeting: string;
 | 
				
			||||||
 | 
					    constructor (options?: {name?: string; priority?: number}) {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    say (): string {
 | 
				
			||||||
 | 
					      return this.greeting;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    run () {
 | 
				
			||||||
 | 
					      this.say()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var myObj = new MyClass();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export function main (): void {
 | 
				
			||||||
 | 
					    myObj.say();
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					module SimpleModule {
 | 
				
			||||||
 | 
					  export interface Runnable {
 | 
				
			||||||
 | 
					    run: ()=> any;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  export class MyClass implements Runnable{
 | 
				
			||||||
 | 
					    name: string;
 | 
				
			||||||
 | 
					    greeting: string;
 | 
				
			||||||
 | 
					    constructor (options?: {name?: string; priority?: number}) {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    say (): string {
 | 
				
			||||||
 | 
					      return this.greeting;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    run () {
 | 
				
			||||||
 | 
					      this.say()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var myObj = new MyClass();
 | 
				
			||||||
 | 
					  myObj.s
 | 
				
			||||||
 | 
					  export function main (): void {
 | 
				
			||||||
 | 
					    myObj.say();
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					class Hoge {
 | 
				
			||||||
 | 
					    constructor() { }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Foo extends Hoge {
 | 
				
			||||||
 | 
					    constructor() {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					class App { }
 | 
				
			||||||
 | 
					var app = new App();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					module ReferenceTest {
 | 
				
			||||||
 | 
					  export class SomeClass {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export class OtherClass extends SomeClass{
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					/// <reference path="referencesTestA.ts" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module ReferenceTest {
 | 
				
			||||||
 | 
					  export class AnotherClass extends SomeClass{
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					module Test {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var hoge = 1, foo = hoge;
 | 
				
			||||||
 | 
					    var x = hoge;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param bar An argument
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     **/
 | 
				
			||||||
 | 
					    var someFunc = (bar: string) => { };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var otherFunc = () => {
 | 
				
			||||||
 | 
					        var prefix;
 | 
				
			||||||
 | 
					        console.log(' prefix  ');
 | 
				
			||||||
 | 
					        console.log("   prefix ");
 | 
				
			||||||
 | 
					        console.log(`  prefix `);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					interface Hoge {
 | 
				
			||||||
 | 
					    id: any;
 | 
				
			||||||
 | 
					    // syntaxerror
 | 
				
			||||||
 | 
					    foo: {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					class Foo extends InvalidBaseClass {}
 | 
				
			||||||
@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "compilerOptions": {
 | 
				
			||||||
 | 
					    "noImplicitAny": true,
 | 
				
			||||||
 | 
					    "module": "commonjs"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "files": ["main.ts", "sub.ts"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					module main {
 | 
				
			||||||
 | 
					    interface IBase {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class BaseClazz implements IBase {}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "compilerOptions": {
 | 
				
			||||||
 | 
					    "noImplicitAny": true
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "files": ["main.ts"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					module SignatureHelpTest {
 | 
				
			||||||
 | 
					  function add (a:number, b:number): number;
 | 
				
			||||||
 | 
					  function add (a:string, b:string): string;
 | 
				
			||||||
 | 
					  function add (a:any, b:any): any {
 | 
				
			||||||
 | 
					    return a + b;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var sum = add(1, 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					module SignatureHelpTest {
 | 
				
			||||||
 | 
					  export class Calc {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * An add method.
 | 
				
			||||||
 | 
					     * It's is useful for calc.
 | 
				
			||||||
 | 
					     * @param a A operand.
 | 
				
			||||||
 | 
					     *          It is the first operand.
 | 
				
			||||||
 | 
					     * @param b Another operand.
 | 
				
			||||||
 | 
					     * @returns Summation of a and b.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     **/
 | 
				
			||||||
 | 
					    add(a: number, b: number): number {
 | 
				
			||||||
 | 
					      return a + b;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var calc = new Calc();
 | 
				
			||||||
 | 
					  calc.add( 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks to sendCommandOneWay successfully
 | 
				
			||||||
 | 
					    Should tsuquyomi#tsClient#sendCommandOneWay('open', {'file': 'myApp.ts'}) == []
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks to sendCommandSyncResponse successfully
 | 
				
			||||||
 | 
					    let res_list = tsuquyomi#tsClient#sendCommandSyncResponse('completions', {})
 | 
				
			||||||
 | 
					    Should len(res_list) == 1
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks to sendCommandSyncResponse successfully
 | 
				
			||||||
 | 
					    let res_list = tsuquyomi#tsClient#sendCommandSyncEvents('geterr', {'files': ['hoge'], 'delay': 50}, str2float("0.01"), 0)
 | 
				
			||||||
 | 
					    Should len(res_list) == 0
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					  It checks to sendRequest successfully
 | 
				
			||||||
 | 
					    let res = tsuquyomi#tsClient#sendRequest('{"command": "open", "arguments": { "file": "test/resrouces/SimpleModule.ts"}}', str2float("0.01"), 0, 0)
 | 
				
			||||||
 | 
					    Should res == []
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks TSServer's status after startTss.
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#startTss()
 | 
				
			||||||
 | 
					    Should tsuquyomi#tsClient#statusTss() == 'run'
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks TSServer's status after stopTssSync
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#startTss()
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#startTss()
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					    Should tsuquyomi#tsClient#statusTss() == 'dead'
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'completionEntryDetails' command.
 | 
				
			||||||
 | 
					    let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/SimpleModule_writing.ts')
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					    let res_list = tsuquyomi#tsClient#tsCompletionEntryDetails(file, 19, 9, ['say', 'greeting'])
 | 
				
			||||||
 | 
					    Should len(res_list) == 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let display_texts = []
 | 
				
			||||||
 | 
					    for result in res_list
 | 
				
			||||||
 | 
					      let display = ''
 | 
				
			||||||
 | 
					      for part in result.displayParts
 | 
				
			||||||
 | 
					        let display = display.part.text
 | 
				
			||||||
 | 
					      endfor
 | 
				
			||||||
 | 
					      call add(display_texts, display)
 | 
				
			||||||
 | 
					    endfor
 | 
				
			||||||
 | 
					    Should display_texts[0] == '(method) SimpleModule.MyClass.say(): string'
 | 
				
			||||||
 | 
					    Should display_texts[1] == '(property) SimpleModule.MyClass.greeting: string'
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'completions' command.
 | 
				
			||||||
 | 
					    let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/SimpleModule.ts')
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					    let res_list = tsuquyomi#tsClient#tsCompletions(file, 17, 0, 'setT')
 | 
				
			||||||
 | 
					    Should len(res_list) == 1
 | 
				
			||||||
 | 
					    Should res_list[0].name == 'setTimeout'
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'completions' command with non-existing keyword.
 | 
				
			||||||
 | 
					    let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/SimpleModule.ts')
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					    let res_list = tsuquyomi#tsClient#tsCompletions(file, 11, 0, 'NO_EXSIT_KEYWORD_XXXXXXX') 
 | 
				
			||||||
 | 
					    Should len(res_list) == 0
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let b:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					  let s:result = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'definition' command.
 | 
				
			||||||
 | 
					    let file = b:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/definitionTest.ts')
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					    let b:result= tsuquyomi#tsClient#tsDefinition(file, 2, 15) 
 | 
				
			||||||
 | 
					    Should len(b:result) == 1
 | 
				
			||||||
 | 
					    Should b:Filepath.basename(b:result[0].file) == 'definitionTest.ts'
 | 
				
			||||||
 | 
					    Should has_key(b:result[0], 'start') != 0 
 | 
				
			||||||
 | 
					    Should has_key(b:result[0].start, 'line')
 | 
				
			||||||
 | 
					    Should has_key(b:result[0].start, 'offset') != 0 
 | 
				
			||||||
 | 
					    Should has_key(b:result[0], 'end') != 0 
 | 
				
			||||||
 | 
					    Should has_key(b:result[0].end, 'line') != 0 
 | 
				
			||||||
 | 
					    Should has_key(b:result[0].end, 'offset') != 0 
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checkes no definition at no symbol
 | 
				
			||||||
 | 
					    let file = b:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/definitionTest.ts')
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					    let b:result = tsuquyomi#tsClient#tsDefinition(file, 3, 1) 
 | 
				
			||||||
 | 
					    Should b:result == []
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					  let s:ver = tsuquyomi#config#getVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'getSupportedCodeFixes' command.
 | 
				
			||||||
 | 
					    if s:ver.major == 2 && s:ver.minor == 0
 | 
				
			||||||
 | 
					      echo "This test is pending on TypeScript 2.0. Please fix this test case!"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/codeFixTest.ts')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					      let result_list = tsuquyomi#tsClient#tsGetCodeFixes(file, 6, 5, 6, 5, [2377])
 | 
				
			||||||
 | 
					      " echo result_list
 | 
				
			||||||
 | 
					      Should len(result_list)
 | 
				
			||||||
 | 
					      Should has_key(result_list[0], 'changes')
 | 
				
			||||||
 | 
					      Should len(result_list[0].changes)
 | 
				
			||||||
 | 
					      Should has_key(result_list[0].changes[0], 'textChanges')
 | 
				
			||||||
 | 
					      Should len(result_list[0].changes[0].textChanges)
 | 
				
			||||||
 | 
					      Should result_list[0].changes[0].textChanges[0].newText =~ 'super();'
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					  let s:ver = tsuquyomi#config#getVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'getSupportedCodeFixes' command.
 | 
				
			||||||
 | 
					    if s:ver.major == 2 && s:ver.minor == 0
 | 
				
			||||||
 | 
					      echo "This test is pending on TypeScript 2.0. Please fix this test case!"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/SimpleModule_writing.ts')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					      let result_list = tsuquyomi#tsClient#tsGetSupportedCodeFixes()
 | 
				
			||||||
 | 
					      Should len(result_list)
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					  let s:ver = tsuquyomi#config#getVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'geterr' command.
 | 
				
			||||||
 | 
					    if s:ver.major == 2 && s:ver.minor < 8
 | 
				
			||||||
 | 
					      echo "This test is pending in between TypeScript 2.0 and 2.7. Please fix this test case!"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/SimpleModule_writing.ts')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					      let files = [file]
 | 
				
			||||||
 | 
					      let result_list = tsuquyomi#tsClient#tsGeterr(files, 10)
 | 
				
			||||||
 | 
					      Should len(result_list) == 3
 | 
				
			||||||
 | 
					      let semanticDiagDict = filter(copy(result_list), 'v:val.event == "semanticDiag"')[0].body
 | 
				
			||||||
 | 
					      let syntaxDiagDict = filter(copy(result_list), 'v:val.event == "syntaxDiag"')[0].body
 | 
				
			||||||
 | 
					      Should has_key(semanticDiagDict, 'diagnostics')
 | 
				
			||||||
 | 
					      Should has_key(semanticDiagDict, 'file')
 | 
				
			||||||
 | 
					      Should len(semanticDiagDict.diagnostics) > 0
 | 
				
			||||||
 | 
					      Should has_key(semanticDiagDict.diagnostics[0], 'text')
 | 
				
			||||||
 | 
					      Should has_key(semanticDiagDict.diagnostics[0], 'start')
 | 
				
			||||||
 | 
					      Should has_key(semanticDiagDict.diagnostics[0].start, 'line')
 | 
				
			||||||
 | 
					      Should has_key(semanticDiagDict.diagnostics[0].start, 'offset')
 | 
				
			||||||
 | 
					      Should has_key(semanticDiagDict.diagnostics[0], 'end')
 | 
				
			||||||
 | 
					      Should has_key(semanticDiagDict.diagnostics[0].end, 'line')
 | 
				
			||||||
 | 
					      Should has_key(semanticDiagDict.diagnostics[0].end, 'offset')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					  let s:ver = tsuquyomi#config#getVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'geterr' command.
 | 
				
			||||||
 | 
					    if (s:ver.major == 2 && s:ver.minor < 8) ||
 | 
				
			||||||
 | 
					    \  (s:ver.major == 3 && s:ver.minor == 2)
 | 
				
			||||||
 | 
					      echo "This test is pending in between TypeScript 2.0 and 2.7, or 3.2. Please fix this test case!"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/samplePrjs/errorPrj/main.ts')
 | 
				
			||||||
 | 
					      let sub_file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/samplePrjs/errorPrj/sub.ts')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					      let result_list = tsuquyomi#tsClient#tsGeterrForProject(file, 10, 2)
 | 
				
			||||||
 | 
					      Should len(result_list) == 6
 | 
				
			||||||
 | 
					      Should sort(map(copy(result_list), 'v:val.body.file')) == [file, file, file, sub_file, sub_file, sub_file]
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					  let s:ver = tsuquyomi#config#getVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'navbar' command.
 | 
				
			||||||
 | 
					    if s:ver.major == 3 && s:ver.minor == 2
 | 
				
			||||||
 | 
					      echo "This test is pending on TypeScript 3.2. Please fix this test case!"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let file = substitute(s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/SimpleModule.ts'), '\\', '/', 'g')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					      let res_list = tsuquyomi#tsClient#tsNavBar(file)
 | 
				
			||||||
 | 
					      " echo res_list
 | 
				
			||||||
 | 
					      Should len(res_list) > 0
 | 
				
			||||||
 | 
					      Should has_key(res_list[1], 'text')
 | 
				
			||||||
 | 
					      Should res_list[1].text == 'SimpleModule'
 | 
				
			||||||
 | 
					      Should has_key(res_list[1], 'kind')
 | 
				
			||||||
 | 
					      Should res_list[1].kind == 'module'
 | 
				
			||||||
 | 
					      Should has_key(res_list[1], 'kindModifiers')
 | 
				
			||||||
 | 
					      Should has_key(res_list[1], 'spans')
 | 
				
			||||||
 | 
					      Should len(res_list[1].spans) > 0
 | 
				
			||||||
 | 
					      Should has_key(res_list[1].spans[0], 'start')
 | 
				
			||||||
 | 
					      Should has_key(res_list[1].spans[0].start, 'line')
 | 
				
			||||||
 | 
					      Should has_key(res_list[1].spans[0].start, 'offset')
 | 
				
			||||||
 | 
					      Should has_key(res_list[1].spans[0], 'end')
 | 
				
			||||||
 | 
					      Should has_key(res_list[1].spans[0].end, 'line')
 | 
				
			||||||
 | 
					      Should has_key(res_list[1].spans[0].end, 'offset')
 | 
				
			||||||
 | 
					      Should has_key(res_list[1], 'childItems')
 | 
				
			||||||
 | 
					      Should len(res_list[1].childItems) > 0
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					  let s:ver = tsuquyomi#config#getVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'navbar' command.
 | 
				
			||||||
 | 
					    if s:ver.major == 3 && s:ver.minor == 2
 | 
				
			||||||
 | 
					      echo "This test is pending on TypeScript 3.2. Please fix this test case!"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let file = substitute(s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/SimpleModule.ts'), '\\', '/', 'g')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					      let res_list = tsuquyomi#tsClient#tsNavto(file, 'encodeURIComponent', 100)
 | 
				
			||||||
 | 
					      " echo res_list
 | 
				
			||||||
 | 
					      Should len(res_list) > 0
 | 
				
			||||||
 | 
					      Should has_key(res_list[0], 'file')
 | 
				
			||||||
 | 
					      Should has_key(res_list[0], 'name')
 | 
				
			||||||
 | 
					      Should res_list[0].name == 'encodeURIComponent'
 | 
				
			||||||
 | 
					      Should has_key(res_list[0], 'kind')
 | 
				
			||||||
 | 
					      Should res_list[0].kind == 'function'
 | 
				
			||||||
 | 
					      Should has_key(res_list[0], 'matchKind')
 | 
				
			||||||
 | 
					      Should res_list[0].matchKind == 'exact'
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					  let s:ver = tsuquyomi#config#getVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of response of 'projectInfo' command
 | 
				
			||||||
 | 
					    if s:ver.major == 3 && s:ver.minor == 2
 | 
				
			||||||
 | 
					      echo "This test is pending on TypeScript 3.2. Please fix this test case!"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let file = substitute(s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/samplePrjs/prj001/main.ts'), '\\', '/', 'g')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					      let res_projectInfo_dict = tsuquyomi#tsClient#tsProjectInfo(file, 1)
 | 
				
			||||||
 | 
					      Should has_key(res_projectInfo_dict, 'configFileName')
 | 
				
			||||||
 | 
					      Should has_key(res_projectInfo_dict, 'fileNames')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'quickinfo' command.
 | 
				
			||||||
 | 
					    let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/SimpleModule.ts')
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					    let res_dict = tsuquyomi#tsClient#tsQuickinfo(file, 14, 13) 
 | 
				
			||||||
 | 
					    Should has_key(res_dict, 'start')
 | 
				
			||||||
 | 
					    Should has_key(res_dict.start, 'line')
 | 
				
			||||||
 | 
					    Should has_key(res_dict.start, 'offset')
 | 
				
			||||||
 | 
					    Should has_key(res_dict, 'end')
 | 
				
			||||||
 | 
					    Should has_key(res_dict.end, 'line')
 | 
				
			||||||
 | 
					    Should has_key(res_dict.end, 'offset')
 | 
				
			||||||
 | 
					    Should has_key(res_dict, 'displayString')
 | 
				
			||||||
 | 
					    Should has_key(res_dict, 'kind')
 | 
				
			||||||
 | 
					    Should has_key(res_dict, 'kindModifiers')
 | 
				
			||||||
 | 
					    Should res_dict.displayString == '(method) SimpleModule.MyClass.say(): string'
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'references' command.
 | 
				
			||||||
 | 
					    let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/referencesTestA.ts')
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					    let res_reference_list = tsuquyomi#tsClient#tsReferences(file, 2, 16) 
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list, 'refs')
 | 
				
			||||||
 | 
					    " res_reference_list.refs contains self definition.
 | 
				
			||||||
 | 
					    Should len(res_reference_list.refs) == 2
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0], 'file')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0], 'isWriteAccess')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0], 'lineText')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0], 'start')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0].start, 'line')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0].start, 'offset')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0], 'end')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0].end, 'line')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0].end, 'offset')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list, 'symbolName')
 | 
				
			||||||
 | 
					    Should res_reference_list.symbolName == 'SomeClass'
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list, 'symbolDisplayString')
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks the reference from other files
 | 
				
			||||||
 | 
					    let fileA = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/referencesTestA.ts')
 | 
				
			||||||
 | 
					    let fileB = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/referencesTestB.ts')
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(fileA)
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(fileB)
 | 
				
			||||||
 | 
					    let res_reference_list = tsuquyomi#tsClient#tsReferences(fileA, 2, 16) 
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list, 'refs')
 | 
				
			||||||
 | 
					    " res_reference_list.refs contains self definition , fileA reference and fileB reference.
 | 
				
			||||||
 | 
					    Should len(res_reference_list.refs) == 3
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0], 'file')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0], 'isWriteAccess')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0], 'lineText')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0], 'start')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0].start, 'line')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0].start, 'offset')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0], 'end')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0].end, 'line')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list.refs[0].end, 'offset')
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list, 'symbolName')
 | 
				
			||||||
 | 
					    Should res_reference_list.symbolName == 'SomeClass'
 | 
				
			||||||
 | 
					    Should has_key(res_reference_list, 'symbolDisplayString')
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					  let s:ver = tsuquyomi#config#getVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'reload' command.
 | 
				
			||||||
 | 
					    if v:true
 | 
				
			||||||
 | 
					      echo 'this test fails with all TypeScript versions. Please fix this test!'
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/SimpleModule.ts')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					      Should tsuquyomi#tsClient#tsReload(file, file) == 1
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					    End
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
@ -0,0 +1,98 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					  let s:ver = tsuquyomi#config#getVersion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'rename' command.
 | 
				
			||||||
 | 
					    if s:ver.major == 3
 | 
				
			||||||
 | 
					      echo "This test is pending in between TypeScript 3. Please fix this test case!"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/SimpleModule.ts')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					      let result_rename_dict = tsuquyomi#tsClient#tsRename(file, 5, 16, 0, 0) 
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict, 'info')
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.info, 'canRename')
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.info, 'displayName')
 | 
				
			||||||
 | 
					      Should result_rename_dict.info.displayName == 'MyClass'
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.info, 'fullDisplayName')
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.info, 'kind')
 | 
				
			||||||
 | 
					      Should result_rename_dict.info.kind == 'class'
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.info, 'triggerSpan')
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.info.triggerSpan, 'start')
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.info.triggerSpan, 'length')
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict, 'locs')
 | 
				
			||||||
 | 
					      Should len(result_rename_dict.locs) == 1
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.locs[0], 'file')
 | 
				
			||||||
 | 
					      Should result_rename_dict.locs[0].file != 'test/tsClient/vest/resources/SimpleModule.ts'
 | 
				
			||||||
 | 
					      Should stridx(result_rename_dict.locs[0].file, 'test/tsClient/vest/resources/SimpleModule.ts')
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.locs[0], 'locs')
 | 
				
			||||||
 | 
					      Should len(result_rename_dict.locs[0].locs) == 2
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.locs[0].locs[0], 'start')
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.locs[0].locs[0].start, 'line')
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.locs[0].locs[0].start, 'offset')
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.locs[0].locs[0], 'end')
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.locs[0].locs[0].end, 'line')
 | 
				
			||||||
 | 
					      Should has_key(result_rename_dict.locs[0].locs[0].end, 'offset')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks rename command within symbol occurred across multiple files.
 | 
				
			||||||
 | 
					    let fileA = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/referencesTestA.ts')
 | 
				
			||||||
 | 
					    let fileB = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/referencesTestB.ts')
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(fileA)
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(fileB)
 | 
				
			||||||
 | 
					    let result_rename_dict = tsuquyomi#tsClient#tsRename(fileA, 2, 16, 0, 0) 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Should len(result_rename_dict.locs) == 2
 | 
				
			||||||
 | 
					    Should stridx(result_rename_dict.locs[0].file, 'test/tsClient/vest/resources/referencesTestA.ts')
 | 
				
			||||||
 | 
					    Should stridx(result_rename_dict.locs[1].file, 'test/tsClient/vest/resources/referencesTestB.ts')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It can rename when a line has two symbols. Should to that the result is sorted by reverse order.
 | 
				
			||||||
 | 
					    if s:ver.major == 3
 | 
				
			||||||
 | 
					      echo "This test is pending in between TypeScript 3. Please fix this test case!"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/renameTest.ts')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					      let result_rename_dict = tsuquyomi#tsClient#tsRename(file, 3, 9, 0, 0) 
 | 
				
			||||||
 | 
					      Should len(result_rename_dict.locs[0].locs) == 3
 | 
				
			||||||
 | 
					      Should result_rename_dict.locs[0].locs[0].start.line == 4
 | 
				
			||||||
 | 
					      Should result_rename_dict.locs[0].locs[0].start.offset == 13
 | 
				
			||||||
 | 
					      Should result_rename_dict.locs[0].locs[1].start.line == 3
 | 
				
			||||||
 | 
					      Should result_rename_dict.locs[0].locs[1].start.offset == 25 
 | 
				
			||||||
 | 
					      Should result_rename_dict.locs[0].locs[2].start.line == 3
 | 
				
			||||||
 | 
					      Should result_rename_dict.locs[0].locs[2].start.offset == 9 
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It can rename variables in comments.
 | 
				
			||||||
 | 
					    if (s:ver.major == 2 && (s:ver.minor == 4 || s:ver.minor == 5)) ||
 | 
				
			||||||
 | 
					    \  (s:ver.major == 3)
 | 
				
			||||||
 | 
					      echo "This test is pending in between TypeScript 2.4 and 2.5, or TypeScript 3. Please fix this test case!"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/renameTest.ts')
 | 
				
			||||||
 | 
					      call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					      let result_rename_dict = tsuquyomi#tsClient#tsRename(file, 11, 21, 1, 0) 
 | 
				
			||||||
 | 
					      Should len(result_rename_dict.locs[0].locs) == 2
 | 
				
			||||||
 | 
					      Should result_rename_dict.locs[0].locs[1].start.line == 8
 | 
				
			||||||
 | 
					      Should result_rename_dict.locs[0].locs[1].start.offset == 15 
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  " It can rename identifiers in strings.
 | 
				
			||||||
 | 
					  "   let file = s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/renameTest.ts')
 | 
				
			||||||
 | 
					  "   call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					  "   let result_rename_dict = tsuquyomi#tsClient#tsRename(file, 14, 13, 0, 1) 
 | 
				
			||||||
 | 
					  "   Should len(result_rename_dict.locs[0].locs) == 4
 | 
				
			||||||
 | 
					  " End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
@ -0,0 +1,70 @@
 | 
				
			|||||||
 | 
					scriptencoding utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Context Vesting.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let s:V = vital#of('tsuquyomi')
 | 
				
			||||||
 | 
					  let s:Filepath = s:V.import('System.Filepath')
 | 
				
			||||||
 | 
					  let s:script_dir = tsuquyomi#rootDir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It checks interface of responce of 'signatureHelp' command.
 | 
				
			||||||
 | 
					    let file = substitute(s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/signatureHelpTest_writing.ts'), '\\', '/', 'g')
 | 
				
			||||||
 | 
					    "echo l:file
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					    let res_signatureHelp_dict  = tsuquyomi#tsClient#tsSignatureHelp(file, 19, 12) 
 | 
				
			||||||
 | 
					    "echo res_signatureHelp_dict
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict, 'selectedItemIndex')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict, 'argumentCount')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict, 'argumentIndex')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict, 'applicableSpan')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.applicableSpan, 'start')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.applicableSpan.start, 'line')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.applicableSpan.start, 'offset')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.applicableSpan, 'end')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.applicableSpan.end, 'line')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.applicableSpan.end, 'offset')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict, 'items')
 | 
				
			||||||
 | 
					    Should len(res_signatureHelp_dict.items)
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0], 'separatorDisplayParts')
 | 
				
			||||||
 | 
					    Should len(res_signatureHelp_dict.items[0].separatorDisplayParts)
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].separatorDisplayParts[0], 'kind')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].separatorDisplayParts[0], 'text')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0], 'parameters')
 | 
				
			||||||
 | 
					    Should len(res_signatureHelp_dict.items[0].parameters)
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].parameters[0], 'isOptional')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].parameters[0], 'name')
 | 
				
			||||||
 | 
					    Should res_signatureHelp_dict.items[0].parameters[0].name == 'a'
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].parameters[0], 'documentation')
 | 
				
			||||||
 | 
					    Should len(res_signatureHelp_dict.items[0].parameters[0].documentation)
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].parameters[0].documentation[0], 'kind')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].parameters[0].documentation[0], 'text')
 | 
				
			||||||
 | 
					    Should res_signatureHelp_dict.items[0].parameters[0].documentation[0].text =~ 'A operand.'
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].parameters[0], 'displayParts')
 | 
				
			||||||
 | 
					    Should len(res_signatureHelp_dict.items[0].parameters[0].displayParts)
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].parameters[0].displayParts[0], 'kind')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].parameters[0].displayParts[0], 'text')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0], 'prefixDisplayParts')
 | 
				
			||||||
 | 
					    Should len(res_signatureHelp_dict.items[0].prefixDisplayParts)
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].prefixDisplayParts[0], 'kind')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].prefixDisplayParts[0], 'text')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0], 'suffixDisplayParts')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].suffixDisplayParts[0], 'kind')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].suffixDisplayParts[0], 'text')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0], 'documentation')
 | 
				
			||||||
 | 
					    Should len(res_signatureHelp_dict.items[0].documentation)
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].documentation[0], 'kind')
 | 
				
			||||||
 | 
					    Should has_key(res_signatureHelp_dict.items[0].documentation[0], 'text')
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It returns two items when the method is overridden.
 | 
				
			||||||
 | 
					    let file = substitute(s:Filepath.join(s:script_dir, 'test/tsClient/vest/resources/signatureHelpTest_overload.ts'), '\\', '/', 'g')
 | 
				
			||||||
 | 
					    "echo l:file
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#tsOpen(file)
 | 
				
			||||||
 | 
					    let res_signatureHelp_dict  = tsuquyomi#tsClient#tsSignatureHelp(file, 9, 19) 
 | 
				
			||||||
 | 
					    "echo res_signatureHelp_dict
 | 
				
			||||||
 | 
					    Should len(res_signatureHelp_dict.items) == 2
 | 
				
			||||||
 | 
					    call tsuquyomi#tsClient#stopTssSync()
 | 
				
			||||||
 | 
					  End
 | 
				
			||||||
 | 
					End
 | 
				
			||||||
 | 
					Fin
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
 | 
				
			||||||
 | 
					# yarn lockfile v1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-2.0@npm:typescript@2.0":
 | 
				
			||||||
 | 
					  version "2.0.10"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.0.10.tgz#ccdd4ed86fd5550a407101a0814012e1b3fac3dd"
 | 
				
			||||||
 | 
					  integrity sha1-zN1O2G/VVQpAcQGggUAS4bP6w90=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-2.1@npm:typescript@2.1":
 | 
				
			||||||
 | 
					  version "2.1.6"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.1.6.tgz#40c7e6e9e5da7961b7718b55505f9cac9487a607"
 | 
				
			||||||
 | 
					  integrity sha1-QMfm6eXaeWG3cYtVUF+crJSHpgc=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-2.2@npm:typescript@2.2":
 | 
				
			||||||
 | 
					  version "2.2.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.2.2.tgz#606022508479b55ffa368b58fee963a03dfd7b0c"
 | 
				
			||||||
 | 
					  integrity sha1-YGAiUIR5tV/6NotY/uljoD39eww=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-2.3@npm:typescript@2.3":
 | 
				
			||||||
 | 
					  version "2.3.4"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.3.4.tgz#3d38321828231e434f287514959c37a82b629f42"
 | 
				
			||||||
 | 
					  integrity sha1-PTgyGCgjHkNPKHUUlZw3qCtin0I=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-2.4@npm:typescript@2.4":
 | 
				
			||||||
 | 
					  version "2.4.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.4.2.tgz#f8395f85d459276067c988aa41837a8f82870844"
 | 
				
			||||||
 | 
					  integrity sha1-+DlfhdRZJ2BnyYiqQYN6j4KHCEQ=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-2.5@npm:typescript@2.5":
 | 
				
			||||||
 | 
					  version "2.5.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.5.3.tgz#df3dcdc38f3beb800d4bc322646b04a3f6ca7f0d"
 | 
				
			||||||
 | 
					  integrity sha512-ptLSQs2S4QuS6/OD1eAKG+S5G8QQtrU5RT32JULdZQtM1L3WTi34Wsu48Yndzi8xsObRAB9RPt/KhA9wlpEF6w==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-2.6@npm:typescript@2.6":
 | 
				
			||||||
 | 
					  version "2.6.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.2.tgz#3c5b6fd7f6de0914269027f03c0946758f7673a4"
 | 
				
			||||||
 | 
					  integrity sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-2.7@npm:typescript@2.7":
 | 
				
			||||||
 | 
					  version "2.7.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836"
 | 
				
			||||||
 | 
					  integrity sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-2.8@npm:typescript@2.8":
 | 
				
			||||||
 | 
					  version "2.8.4"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.4.tgz#0b1db68e6bdfb0b767fa2ab642136a35b059b199"
 | 
				
			||||||
 | 
					  integrity sha512-IIU5cN1mR5J3z9jjdESJbnxikTrEz3lzAw/D0Tf45jHpBp55nY31UkUvmVHoffCfKHTqJs3fCLPDxknQTTFegQ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-2.9@npm:typescript@2.9":
 | 
				
			||||||
 | 
					  version "2.9.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
 | 
				
			||||||
 | 
					  integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-3.0@npm:typescript@3.0":
 | 
				
			||||||
 | 
					  version "3.0.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.3.tgz#4853b3e275ecdaa27f78fda46dc273a7eb7fc1c8"
 | 
				
			||||||
 | 
					  integrity sha512-kk80vLW9iGtjMnIv11qyxLqZm20UklzuR2tL0QAnDIygIUIemcZMxlMWudl9OOt76H3ntVzcTiddQ1/pAAJMYg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-3.1@npm:typescript@3.1":
 | 
				
			||||||
 | 
					  version "3.1.6"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68"
 | 
				
			||||||
 | 
					  integrity sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"typescript-3.2@npm:typescript@3.2":
 | 
				
			||||||
 | 
					  version "3.2.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5"
 | 
				
			||||||
 | 
					  integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==
 | 
				
			||||||
					Loading…
					
					
				
		Reference in New Issue