aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--README.md79
-rw-r--r--autoload/prettier.vim152
-rw-r--r--doc/prettier.txt88
-rw-r--r--ftplugin/javascript.vim6
-rw-r--r--package.json13
-rw-r--r--plugin/prettier.vim42
7 files changed, 383 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f7fb9fb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+TODO
+node_modules
+.yarn_lock
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..71e53d0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,79 @@
+## vim-prettier
+
+A vim plugin wrapper for prettier, pre-configured with custom default prettier settings.
+
+### INSTALL
+
+Install with [vim-plug](https://github.com/junegunn/vim-plug), assumes node and yarn|npm installed globally.
+
+```
+" yarn install | npm install
+Plug 'mitermayer/vim-prettier', { 'do': 'yarn install', 'for': 'javascript' }
+```
+
+If using other vim plugin managers or doing manual setup make sure to have `prettier` installed globally or go to your vim-prettier directory and either do `npm install` or `yarn install`
+
+## Prettier Executable resolution
+
+When installed via vim-plug, a default prettier executable is installed inside vim-prettier.
+
+vim-prettier executable resolution:
+
+1. Tranverse parents and search for Prettier installation inside `node_modules`
+2. Look for a global prettier installation
+3. Use locally installed vim-prettier prettier executable
+
+## USAGE
+
+Formats the entire buffer
+
+```
+:Prettier
+```
+
+Disable auto formatting of javascript files that have "@format" tag
+
+```
+let g:prettier#autoformat = 0
+```
+
+Enable vim-prettier to run in javascript files without the "@format" doc tag
+
+```
+autocmd BufWritePre *.js call prettier#Prettier()
+```
+
+Overwrite default configuration
+
+```
+" max line lengh that prettier will wrap on
+g:prettier#config#print_width = 80
+
+" number of spaces per indentation level
+g:prettier#config#tab_width = 2
+
+" use tabs over spaces
+g:prettier#config#use_tabs = 0
+
+" print semicolons
+g:prettier#config#semi = 1
+
+" single quotes over double quotes
+g:prettier#config#single_quote = 1
+
+" print spaces between brackets
+g:prettier#config#bracket_spacing = 0
+
+" put > on the last line instead of new line
+g:prettier#config#jsx_bracket_same_line = 1
+
+" none|es5|all
+g:prettier#config#trailing_comma = 'all'
+
+" flow|babylon
+g:prettier#config#parser = 'flow'
+
+```
+### REQUIREMENT(S)
+
+If prettier installation can't be found no code formatting will happen
diff --git a/autoload/prettier.vim b/autoload/prettier.vim
new file mode 100644
index 0000000..3cb21ee
--- /dev/null
+++ b/autoload/prettier.vim
@@ -0,0 +1,152 @@
+let s:root_dir = fnamemodify(resolve(expand('<sfile>:p')), ':h')
+
+" TODO => check all &ft comparisons and make sure we use match to protect from compound file types
+function! prettier#Prettier() abort
+ let l:exec = s:Get_Prettier_Exec()
+
+ if &ft !~ 'javascript'
+ return
+ endif
+
+ if exec != -1
+ let l:stdout = split(system(exec . s:Get_Prettier_Exec_Args(), getbufline(bufnr('%'), 1, '$')), '\n')
+
+ " delete all lines on the current buffer
+ silent! execute 1 . ',' . line('$') . 'delete _'
+
+ " replace all lines from the current buffer with output from prettier
+ call setline(1, stdout)
+ else
+ call s:Suggest_Install_Prettier()
+ endif
+endfunction
+
+function! prettier#Autoformat() abort
+ let l:curPos = getpos('.')
+ let l:maxLineLookup = 50
+ let l:maxTimeLookupMs = 500
+ let l:pattern = '@format'
+
+ " we need to move selection to the top before looking up to avoid
+ " scanning a very long file
+ call cursor(1, 1)
+
+ " Search starting at the start of the document
+ if search(pattern, 'n', maxLineLookup, maxTimeLookupMs) > 0
+ call prettier#Prettier()
+ endif
+
+ " Restore the selection and if greater then before it defaults to end
+ call cursor(curPos[1], curPos[2])
+endfunction
+
+" By default we will default to our internal
+" configuration settings for prettier
+function! s:Get_Prettier_Exec_Args() abort
+ let l:cmd = ' --print-width ' .
+ \ g:prettier#config#print_width .
+ \ ' --tab-width ' .
+ \ g:prettier#config#tab_width .
+ \ ' --use-tabs ' .
+ \ g:prettier#config#use_tabs .
+ \ ' --semi ' .
+ \ g:prettier#config#semi .
+ \ ' --single-quote ' .
+ \ g:prettier#config#single_quote .
+ \ ' --bracket-spacing ' .
+ \ g:prettier#config#bracket_spacing .
+ \ ' --jsx-bracket-same-line ' .
+ \ g:prettier#config#jsx_bracket_same_line .
+ \ ' --trailing-comma ' .
+ \ g:prettier#config#trailing_comma .
+ \ ' --parser ' .
+ \ g:prettier#config#parser .
+ \ ' --stdin '
+ return cmd
+endfunction
+
+" By default we will search for the following
+" => locally installed prettier inside node_modules on any parent folder
+" => globally installed prettier
+" => vim-prettier prettier installation
+" => if all fails suggest install
+function! s:Get_Prettier_Exec() abort
+ let l:local_exec = s:Get_Prettier_Local_Exec()
+ if local_exec != -1
+ return local_exec
+ endif
+
+ let l:global_exec = s:Get_Prettier_Global_Exec()
+ global_exec != -1
+ return global_exec
+ endif
+
+ let l:plugin_exec = s:Get_Prettier_Plugin_Exec()
+ if plugin_exec != -1
+ return plugin_exec
+ endif
+
+ return -1
+endfunction
+
+function! s:Get_Prettier_Local_Exec() abort
+ return s:Get_Exec(getcwd())
+endfunction
+
+function! s:Get_Prettier_Global_Exec() abort
+ return s:Get_Exec()
+endfunction
+
+function! s:Get_Prettier_Plugin_Exec() abort
+ return s:Get_Exec(s:root_dir)
+endfunction
+
+function! s:Get_Exec(...) abort
+ let l:rootDir = a:0 > 0 ? a:1 : 0
+ let l:exec = 0
+
+ if rootDir
+ let l:dir = s:Tranverse_Dir_Search(rootDir)
+ if dir != -1
+ let l:exec = s:Get_Path_To_Exec(dir)
+ endif
+ else
+ let l:exec = s:Get_Path_To_Exec()
+ endif
+
+ if executable(exec)
+ return exec
+ endif
+
+ return -1
+endfunction
+
+function! s:Get_Path_To_Exec(...) abort
+ let l:rootDir = a:0 > 0 ? a:1 : -1
+ let l:dir = rootDir != -1 ? rootDir . '/.bin/' : ''
+ return dir . 'prettier'
+endfunction
+
+function! s:Tranverse_Dir_Search(rootDir) abort
+ let l:root = a:rootDir
+ let l:dir = 'node_modules'
+
+ while 1
+ let l:search_dir = root . '/' . dir
+ if isdirectory(search_dir)
+ return search_dir
+ endif
+
+ let l:parent = fnamemodify(root, ':h')
+ if parent == root
+ return -1
+ endif
+
+ let l:root = parent
+ endwhile
+endfunction
+
+" If we can't find any prettier installing we then suggest where to get it from
+function! s:Suggest_Install_Prettier() abort
+ echohl WarningMsg | echom 'Prettier: no prettier executable installation found.' | echohl NONE
+endfunction
diff --git a/doc/prettier.txt b/doc/prettier.txt
new file mode 100644
index 0000000..8c9ed22
--- /dev/null
+++ b/doc/prettier.txt
@@ -0,0 +1,88 @@
+*vim-prettier.txt* A prettier plugin for vim.
+
+CONTENTS *vim-prettier-contents*
+
+Introduction |vim-prettier-introduction|
+Install |vim-prettier-install|
+Usage |vim-prettier-usage|
+Requirements |vim-prettier-requirements|
+
+==============================================================================
+INTRODUCTION *vim-prettier-introduction*
+
+A vim plugin wrapper for prettier, pre-configured with
+custom default prettier settings.
+
+When installed via vim-plug, a default prettier executable is installed inside
+ vim-prettier.
+
+vim-prettier executable resolution:
+
+1. Tranverse parents and search for Prettier installation inside `node_modules`
+2. Look for a global prettier installation
+3. Use locally installed vim-prettier prettier executable
+
+==============================================================================
+INSTALL *vim-prettier-install*
+
+Install with [vim-plug](https://github.com/junegunn/vim-plug), assumes
+node and yarn|npm installed globally.
+>
+ Plug 'mitermayer/vim-prettier', { 'do': 'yarn install', 'for': 'javascript' }
+<
+If using other vim plugin managers or doing manual setup make sure to have
+`prettier` installed globally or go to your vim-prettier directory and
+either do `npm install` or `yarn install`
+
+==============================================================================
+USAGE *vim-prettier-usage*
+
+Formats the entire buffer
+>
+ :Prettier
+<
+Disable auto formatting of javascript files that have "@format" tag
+>
+ let g:prettier#autoformat = 0
+<
+Enable vim-prettier to run in javascript files without the "@format" doc tag
+>
+ autocmd BufWritePre *.js call prettier#Prettier()
+<
+Overwrite default configuration
+>
+ " max line lengh that prettier will wrap on
+ g:prettier#config#print_width = 80
+
+ " number of spaces per indentation level
+ g:prettier#config#tab_width = 2
+
+ " use tabs over spaces
+ g:prettier#config#use_tabs = 0
+
+ " print semicolons
+ g:prettier#config#semi = 1
+
+ " single quotes over double quotes
+ g:prettier#config#single_quote = 1
+
+ " print spaces between brackets
+ g:prettier#config#bracket_spacing = 0
+
+ " put > on the last line instead of new line
+ g:prettier#config#jsx_bracket_same_line = 1
+
+ " none|es5|all
+ g:prettier#config#trailing_comma = 'all'
+
+ " flow|babylon
+ g:prettier#config#parser = 'flow'
+<
+==============================================================================
+REQUIREMENT(S) *vim-prettier-requirements*
+
+If prettier is not installed locally, globally or inside vim-prettier project
+no code formatting will happen
+
+==============================================================================
+vim:tw=78:ts=4:ft=help:norl:noet:fen:noet:
diff --git a/ftplugin/javascript.vim b/ftplugin/javascript.vim
new file mode 100644
index 0000000..bc2aec7
--- /dev/null
+++ b/ftplugin/javascript.vim
@@ -0,0 +1,6 @@
+augroup Prettier
+ autocmd!
+ if g:prettier#autoformat
+ autocmd BufWritePre <buffer> call prettier#Autoformat()
+ endif
+augroup end
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..b3cfd9d
--- /dev/null
+++ b/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "vim-prettier",
+ "author": "Mitermayer Reis <mitermayer.reis@gmail.com>",
+ "version": "0.0.1",
+ "description": "Vim plugin for prettier",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/mitermayer/vim-prettier.git"
+ },
+ "dependencies": {
+ "prettier": "^1.3.1"
+ }
+}
diff --git a/plugin/prettier.vim b/plugin/prettier.vim
new file mode 100644
index 0000000..bbd3607
--- /dev/null
+++ b/plugin/prettier.vim
@@ -0,0 +1,42 @@
+if exists('g:loaded_prettier')
+ finish
+endif
+let g:loaded_prettier = 1
+
+" => Plugin config
+if !exists('g:prettier#autoformat') | let g:prettier#autoformat = 1 | endif
+
+" => Prettier CLI config
+" max line lengh that prettier will wrap on
+if !exists('g:prettier#config#print_width') | let g:prettier#config#print_width = 80 | endif
+
+" number of spaces per indentation level
+if !exists('g:prettier#config#tab_width') | let g:prettier#config#tab_width = 2 | endif
+
+" use tabs over spaces
+if !exists('g:prettier#config#use_tabs') | let g:prettier#config#use_tabs = 0 | endif
+
+" print semicolons
+if !exists('g:prettier#config#semi') | let g:prettier#config#semi = 1 | endif
+
+" single quotes over double quotes
+if !exists('g:prettier#config#single_quote') | let g:prettier#config#single_quote = 1 | endif
+
+" print spaces between brackets
+if !exists('g:prettier#config#bracket_spacing') | let g:prettier#config#bracket_spacing = 0 | endif
+
+" put > on the last line instead of new line
+if !exists('g:prettier#config#jsx_bracket_same_line') | let g:prettier#config#jsx_bracket_same_line = 1 | endif
+
+" none|es5|all
+if !exists('g:prettier#config#trailing_comma') | let g:prettier#config#trailing_comma = 'all' | endif
+
+" flow|babylon
+if !exists('g:prettier#config#parser') | let g:prettier#config#parser = 'flow' | endif
+
+command! Prettier call prettier#Prettier()
+
+if !hasmapto('<Plug>(Prettier)') && maparg('<Leader>p', 'n') ==# ''
+ nmap <unique> <Leader>p <Plug>(Prettier)
+endif
+nnoremap <silent> <Plug>(Prettier) :Prettier<CR>