├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── assets └── vim-prettier.gif ├── autoload └── prettier.vim ├── doc └── prettier.txt ├── ftplugin └── javascript │ └── prettier.vim └── tests ├── .babelrc ├── .eslintignore ├── .eslintrc.js ├── .flowconfig ├── _template.js ├── package.json ├── prettier.vader ├── run.sh └── vimrc /.gitignore: -------------------------------------------------------------------------------- 1 | .swp 2 | *~ 3 | .DS_Store 4 | tags 5 | tests/vader.vim/ 6 | tests/node_modules/ 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: xenial 3 | language: vim 4 | node_js: stable 5 | 6 | install: 7 | - git clone https://github.com/junegunn/vader.vim.git tests/vader.vim 8 | - git clone https://github.com/vim/vim /tmp/vim 9 | - mkdir ~/bin 10 | - cd /tmp/vim 11 | - sudo apt-get install -y gettext libncurses5-dev libacl1-dev libgpm-dev 12 | - ./configure --with-features=huge --enable-fail-if-missing --enable-pythoninterp --prefix=$HOME/bin/vim 13 | - make && make install 14 | - git clone https://github.com/junegunn/vader.vim.git 15 | - export VIM_EXE=$HOME/bin/vim/bin/vim 16 | - cd $HOME/build/heavenshell/vim-prettier/tests 17 | - npm install 18 | 19 | before_script: 20 | - cd $HOME/build/heavenshell/vim-prettier/tests 21 | 22 | script: 23 | - VIM_EXE=$HOME/bin/vim/bin/vim ./run.sh > /dev/null && echo Success || echo Fail 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017, Shinya Ohyanagi. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of Shinya Ohyanagi, Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from this 16 | software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vim-prettier 2 | 3 | [![Build Status](https://travis-ci.org/heavenshell/vim-prettier.svg?branch=master)](https://travis-ci.org/heavenshell/vim-prettier) 4 | 5 | Prettier for Vim. 6 | 7 | ![Asynchronous format](./assets/vim-prettier.gif) 8 | 9 | `vim-pritter` is a wrapper of [Prettier](https://github.com/prettier/prettier). 10 | 11 | ## Dependencies 12 | 13 | `vim-prettier` use [prettier-eslint-cli](https://github.com/prettier/prettier-eslint-cli). 14 | 15 | Install [prettier-eslint-cli](https://github.com/prettier/prettier-eslint-cli) global or local. 16 | 17 | ## Usage 18 | 19 | ### Invoke manually 20 | 21 | Open JavaScript file and just execute `:Prettier`. 22 | 23 | That's it. 24 | 25 | ### Automatically format on save 26 | 27 | ```viml 28 | autocmd BufWritePost *.js,*.jsx call prettier#run(1) 29 | ``` 30 | 31 | ## Motivation 32 | 33 | Pritter official document recommends like followings. 34 | 35 | ```viml 36 | autocmd FileType javascript set formatprg=prettier\ --stdin 37 | ``` 38 | 39 | `set formatprg` runs sync and it's too slow. 40 | 41 | `vim-pritter` runs asynchronously and doesn't block cursor moving. 42 | 43 | ## License 44 | 45 | New BSD License 46 | -------------------------------------------------------------------------------- /assets/vim-prettier.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heavenshell/vim-prettier/70ece1feb023a8d2e7e08183b533e4b75df2707c/assets/vim-prettier.gif -------------------------------------------------------------------------------- /autoload/prettier.vim: -------------------------------------------------------------------------------- 1 | " File: prettier.vim 2 | " Author: Shinya Ohyanagi 3 | " WebPage: http://github.com/heavenshell/vim-prettier/ 4 | " Description: Prettier for Vim 5 | " License: BSD, see LICENSE for more details. 6 | " 7 | " Error handling was copied from Golang's vim plugin. 8 | " see https://github.com/vim-jp/vim-go-extra/blob/master/ftplugin/go/fmt.vim 9 | " 10 | " Async format was inspiered from haya14busa's vim-gofmt. 11 | " see https://github.com/haya14busa/vim-gofmt 12 | " 13 | " Copyright 2011 The Go Authors. All rights reserved. 14 | " Copyright 2017 haya14busa. All rights reserved. 15 | " Copyright 2017 Shinya Ohyanagi. All rights reserved. 16 | let s:save_cpo = &cpo 17 | set cpo&vim 18 | 19 | let s:root_path = '' 20 | let s:formatted = [] 21 | 22 | function! prettier#detect_root() 23 | if s:root_path != '' 24 | return s:root_path 25 | endif 26 | 27 | let path = expand('%:p') 28 | let root_path = finddir('node_modules', path . ';') 29 | let s:root_path = root_path 30 | 31 | return root_path 32 | endfunction 33 | 34 | function! prettier#bin() 35 | let bin = '' 36 | if executable('prettier-eslint') == 0 37 | let root_path = prettier#detect_root() 38 | let bin = root_path . '/.bin/prettier-eslint' 39 | else 40 | let bin = exepath('prettier-eslint') 41 | endif 42 | 43 | return bin 44 | endfunction 45 | 46 | function! s:callback(ch, msg) 47 | " This function is almost copied from Golang's vim plugin. 48 | " Copyright 2011 The Go Authors. All rights reserved. 49 | " see also 50 | " https://github.com/vim-jp/vim-go-extra/blob/master/ftplugin/go/fmt.vim 51 | if v:shell_error 52 | let errors = [] 53 | for line in getline(1, line('$')) 54 | let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)') 55 | if !empty(tokens) 56 | call add(errors, {"filename": @%, 57 | \"lnum": tokens[2], 58 | \"col": tokens[3], 59 | \"text": tokens[4]}) 60 | endif 61 | endfor 62 | if empty(errors) 63 | % | " Couldn't detect prettier error format, output errors 64 | endif 65 | undo 66 | if !empty(errors) 67 | call setqflist(errors, 'r') 68 | endif 69 | echohl Error | echomsg "Prettier returned error" | echohl None 70 | return 71 | endif 72 | 73 | call add(s:formatted, a:msg) 74 | endfunction 75 | 76 | function! s:error_callback(ch, msg) 77 | echomsg printf('fmt err: %s', a:msg) 78 | endfunction 79 | 80 | function! s:exit_callback(ch, msg, current_bufnr, changedtick, force_write) 81 | " This function is inspiered from haya14busa's gofmt.vim. 82 | " Copyright 2017 haya14busa. All rights reserved. 83 | " see also 84 | " https://github.com/haya14busa/vim-gofmt/blob/master/autoload/gofmt.vim 85 | if b:changedtick != a:changedtick 86 | echohl Error | echomsg 'Format is Canceled. Buffer was edited.' | echohl None 87 | return 88 | endif 89 | if a:current_bufnr != bufnr('%') 90 | echomsg 'Formatted buffer is changed.' 91 | return 92 | endif 93 | 94 | let view = winsaveview() 95 | if a:force_write == 'file' 96 | e! 97 | call winrestview(view) 98 | return 99 | endif 100 | 101 | if len(s:formatted) == 0 102 | return 103 | endif 104 | 105 | silent execute '% delete' 106 | 107 | " Preitter v1.0 add extra blank line. 108 | if s:formatted[len(s:formatted) - 1] == '' 109 | call setline(1, s:formatted[0:len(s:formatted) - 2]) 110 | else 111 | call setline(1, s:formatted) 112 | endif 113 | call winrestview(view) 114 | endfunction 115 | 116 | function! prettier#run(...) 117 | if exists('s:job') && job_status(s:job) != 'stop' 118 | call job_stop(s:job) 119 | endif 120 | let s:formatted = [] 121 | let bin = prettier#bin() 122 | let current_bufnr = bufnr('%') 123 | let changedtick = b:changedtick 124 | 125 | let file = expand('%:p') 126 | let mode = a:0 > 0 ? 'file' : 'buffer' 127 | let cmd = bin . ' --stdin' 128 | if mode == 'file' 129 | let cmd = bin . ' --write ' . file 130 | endif 131 | let s:job = job_start(cmd, { 132 | \ 'callback': {c, m -> s:callback(c, m)}, 133 | \ 'exit_cb': {c, m -> s:exit_callback(c, m, current_bufnr, changedtick, mode)}, 134 | \ 'err_cb': {c, m -> s:error_callback(c, m)}, 135 | \ 'in_io': mode, 136 | \ 'in_name': file, 137 | \ }) 138 | endfunction 139 | 140 | let &cpo = s:save_cpo 141 | unlet s:save_cpo 142 | -------------------------------------------------------------------------------- /doc/prettier.txt: -------------------------------------------------------------------------------- 1 | *prettier* Pritter for Vim. 2 | 3 | Version: 0.2.0 4 | Author: Shinya Ohynagi 5 | Repository: http://github.com/heavenshell/vim-pritter/ 6 | License: BSD, see LICENSE for more details. 7 | 8 | ============================================================================== 9 | CONTENTS *prettier-contents* 10 | 11 | Introduction |prettier-introduction| 12 | Install |prettier-install| 13 | Usage |prettier-usage| 14 | Changelogs |prettier-changelog| 15 | 16 | ============================================================================== 17 | INTRODUCTION *prettier-introduction* 18 | 19 | |pritter| is a wrapper of Pritter. 20 | 21 | Pritter official document recommends like followings. 22 | > 23 | autocmd FileType javascript set formatprg=prettier\ --stdin 24 | < 25 | 26 | `set formatprg` runs sync, but it's too slow. 27 | 28 | |vim-pritter| runs asynchronously and doesn't block editing. 29 | 30 | ============================================================================== 31 | INSTALL *prettier-install* 32 | 33 | Install the distributed files into Vim runtime directory which is usually 34 | ~/.vim/, or $HOME/vimfiles on Windows. 35 | 36 | If you use built in `package`, you should extract the 37 | file into '~/.vim/pack/*/start' directory. 38 | 39 | `vim-prettier` use prettier-eslint-cli. 40 | 41 | Install it global or local. 42 | 43 | ============================================================================== 44 | TUTORIAL *prettier-usage* 45 | 46 | - Invoke manually 47 | 48 | Open JavaScript file and just execute `:Prettier`. 49 | 50 | If bufrer was edited while `Preitter` executing, `Prettier` would be canceled. 51 | 52 | - Automatically format on save 53 | > 54 | autocmd BufWritePost *.js,*.jsx call prettier#run(1) 55 | > 56 | 57 | ============================================================================== 58 | VARIABLES *prettier-variables* 59 | 60 | ============================================================================== 61 | CHANGELOG *prettier-changelog* 62 | 2017-05-09 63 | - Cancel prettier if buffer was edited. 64 | - Add Automatically format on save 65 | 66 | 2017-05-05 67 | - Fix cursor position 68 | 69 | 2017-05-01 70 | - First release 71 | 72 | vim:tw=78:ts=8:ft=help:norl:noet:fen:fdl=0: 73 | -------------------------------------------------------------------------------- /ftplugin/javascript/prettier.vim: -------------------------------------------------------------------------------- 1 | " File: prettier.vim 2 | " Author: Shinya Ohyanagi 3 | " WebPage: http://github.com/heavenshell/vim-prettier/ 4 | " Description: Prettier for Vim 5 | " License: BSD, see LICENSE for more details. 6 | " 7 | " Error handling was copied from Golang's vim plugin. 8 | " see https://github.com/vim-jp/vim-go-extra/blob/master/ftplugin/go/fmt.vim 9 | " 10 | " Async format was inspiered from haya14busa's vim-gofmt. 11 | " see https://github.com/haya14busa/vim-gofmt 12 | " 13 | " Copyright 2011 The Go Authors. All rights reserved. 14 | " Copyright 2017 haya14busa. All rights reserved. 15 | " Copyright 2017 Shinya Ohyanagi. All rights reserved. 16 | 17 | let s:save_cpo = &cpo 18 | set cpo&vim 19 | 20 | " version check 21 | if !has('channel') || !has('job') 22 | echoerr '+channel and +job are required for prettier.vim' 23 | finish 24 | endif 25 | 26 | command! -buffer Prettier :call prettier#run() 27 | 28 | noremap (Prettier) :Prettier 29 | 30 | let &cpo = s:save_cpo 31 | unlet s:save_cpo 32 | -------------------------------------------------------------------------------- /tests/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "react" 4 | ], 5 | "plugins": [ 6 | "transform-flow-strip-types" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /tests/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | flow-typed/ 3 | dist/ 4 | build/ 5 | -------------------------------------------------------------------------------- /tests/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'extends': [ 3 | 'eslint-config-standard', 4 | 'plugin:flowtype/recommended' 5 | ], 6 | 'plugins': [ 7 | 'flowtype' 8 | ] 9 | } 10 | 11 | -------------------------------------------------------------------------------- /tests/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | .*/node_modules/.* 3 | .*/dist/.* 4 | 5 | [include] 6 | 7 | [libs] 8 | 9 | [options] 10 | -------------------------------------------------------------------------------- /tests/_template.js: -------------------------------------------------------------------------------- 1 | function foo(arg1, arg2, arg3, arg4){} 2 | 3 | foo("reallyLongArg","omgSoManyParameters","IShouldRefactorThis","isThereSeriouslyAnotherOne") 4 | -------------------------------------------------------------------------------- /tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vim-prettier", 3 | "version": "1.0.0", 4 | "description": "Prettier for Vim", 5 | "main": "n/a", 6 | "scripts": { 7 | "lint": "eslint .", 8 | "flow": "flow" 9 | }, 10 | "private": true, 11 | "author": "Shinya Ohyanagi", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "babel-eslint": "^7.2.1", 15 | "babel-preset-es2015": "^6.24.0", 16 | "babel-preset-react": "^6.23.0", 17 | "babel-register": "^6.24.0", 18 | "eslint": "^3.18.0", 19 | "eslint-config-standard": "^7.1.0", 20 | "eslint-plugin-flowtype": "^2.30.4", 21 | "eslint-plugin-promise": "^3.5.0", 22 | "eslint-plugin-standard": "^2.1.1", 23 | "flow-bin": "^0.42.0", 24 | "npm-run-all": "^4.0.2", 25 | "prettier-eslint": "^6.1.2", 26 | "prettier-eslint-cli": "^3.4.2" 27 | }, 28 | "dependencies": {} 29 | } 30 | -------------------------------------------------------------------------------- /tests/prettier.vader: -------------------------------------------------------------------------------- 1 | # vim:set et sw=4 ts=4 tw=79: 2 | Before (Setup tests): 3 | call system('cp ./_template.js ./template.js') 4 | 5 | After (Teardown tests): 6 | call delete('./template.js') 7 | 8 | Execute ('Detect prettier-eslint'): 9 | let bin = prettier#bin() 10 | AssertEqual fnamemodify(bin, ':p'), fnamemodify('node_modules/.bin/prettier-eslint', ':p') 11 | 12 | Execute ('Format'): 13 | edit ./template.js 14 | set ft=javascript 15 | Prettier 16 | sleep 2 17 | write! template.js 18 | 19 | Expect javascript: 20 | function foo (arg1, arg2, arg3, arg4) {} 21 | 22 | foo( 23 | 'reallyLongArg', 24 | 'omgSoManyParameters', 25 | 'IShouldRefactorThis', 26 | 'isThereSeriouslyAnotherOne' 27 | ) 28 | -------------------------------------------------------------------------------- /tests/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | : "${VIM_EXE:=vim}" 3 | 4 | # Open Vim just to execute all *.vader tests. 5 | $VIM_EXE -Nu vimrc -c 'Vader! *.vader' 6 | -------------------------------------------------------------------------------- /tests/vimrc: -------------------------------------------------------------------------------- 1 | set nocompatible 2 | filetype off 3 | " Clear all rtp 4 | set rtp=$VIMRUNTIME 5 | 6 | " Add vader.vim to rtp 7 | set rtp+=./vader.vim 8 | set rtp+=../ 9 | filetype plugin indent on 10 | --------------------------------------------------------------------------------