Skip to content

Commit 6d69f93

Browse files
authored
Merge pull request #136 from agriffis/feat/npx-prettier
feat(prettier): use npx for project-local prettier
2 parents 7098728 + 05614d0 commit 6d69f93

File tree

4 files changed

+62
-19
lines changed

4 files changed

+62
-19
lines changed

autoload/codefmt/prettier.vim

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ let s:supported_filetypes = ['javascript', 'markdown', 'html', 'css', 'yaml',
2020
\ 'jsx', 'less', 'scss', 'mdx', 'vue']
2121

2222

23+
""
24+
" @private
25+
" Invalidates the cached prettier availability detection.
26+
function! codefmt#prettier#InvalidateIsAvailable() abort
27+
unlet! s:prettier_is_available
28+
endfunction
29+
30+
2331
""
2432
" @private
2533
" Formatter: prettier
@@ -30,9 +38,21 @@ function! codefmt#prettier#GetFormatter() abort
3038
\ 'and configure the prettier_executable flag'}
3139

3240
function l:formatter.IsAvailable() abort
33-
let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray(
34-
\ 'prettier_executable')
35-
return !empty(l:cmd) && executable(l:cmd[0])
41+
if !exists('s:prettier_is_available')
42+
let s:prettier_is_available = 0
43+
let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray(
44+
\ 'prettier_executable')
45+
if !empty(l:cmd) && executable(l:cmd[0])
46+
" Unfortunately the availability of npx isn't enough to tell whether
47+
" prettier is available, and npx doesn't have a way of telling us.
48+
" Fetching the prettier version should suffice.
49+
let l:result = maktaba#syscall#Create(l:cmd + ['--version']).Call(0)
50+
if v:shell_error == 0
51+
let s:prettier_is_available = 1
52+
endif
53+
endif
54+
endif
55+
return s:prettier_is_available
3656
endfunction
3757

3858
function l:formatter.AppliesToBuffer() abort
@@ -52,7 +72,7 @@ function! codefmt#prettier#GetFormatter() abort
5272
if @% == ""
5373
call extend(l:cmd, ['--parser', 'babylon'])
5474
else
55-
call extend(l:cmd, ['--stdin-filepath', @%])
75+
call extend(l:cmd, ['--stdin-filepath', expand('%:p')])
5676
endif
5777

5878
call maktaba#ensure#IsNumber(a:startline)
@@ -71,7 +91,13 @@ function! codefmt#prettier#GetFormatter() abort
7191
\ 'prettier_options'))
7292

7393
try
74-
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
94+
let l:syscall = maktaba#syscall#Create(l:cmd).WithStdin(l:input)
95+
if isdirectory(expand('%:p:h'))
96+
" Change to the containing directory so that npx will find
97+
" a project-local prettier in node_modules
98+
let l:syscall = l:syscall.WithCwd(expand('%:p:h'))
99+
endif
100+
let l:result = l:syscall.Call()
75101
let l:formatted = split(l:result.stdout, "\n")
76102
call maktaba#buffer#Overwrite(1, line('$'), l:formatted)
77103
catch /ERROR(ShellError):/

doc/codefmt.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,13 @@ Default: 'shfmt' `
8383
*codefmt:prettier_options*
8484
Command line arguments to feed prettier. Either a list or callable that takes
8585
no args and returns a list with command line arguments.
86-
Default: [ '--single-quote', '--trailing-comma=all', '--arrow-parens=always',
87-
'--print-width=80'] `
86+
Default: [] `
8887

8988
*codefmt:prettier_executable*
90-
The path to the prettier executable.
91-
Default: 'prettier' `
89+
The path to the prettier executable. String, list, or callable that takes no
90+
args and returns a string or a list. The default uses npx if available, so
91+
that the repository-local prettier will have priority.
92+
Default: function('s:LookupPrettierExecutable') `
9293

9394
*codefmt:rustfmt_options*
9495
Command line arguments to feed rustfmt. Either a list or callable that takes

instant/flags.vim

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,24 @@ call s:plugin.Flag('shfmt_executable', 'shfmt')
111111
""
112112
" Command line arguments to feed prettier. Either a list or callable that
113113
" takes no args and returns a list with command line arguments.
114-
call s:plugin.Flag('prettier_options', [
115-
\ '--single-quote', '--trailing-comma=all',
116-
\ '--arrow-parens=always', '--print-width=80'])
114+
call s:plugin.Flag('prettier_options', [])
117115

118116
""
119-
" The path to the prettier executable.
120-
call s:plugin.Flag('prettier_executable', 'prettier')
117+
" @private
118+
function s:LookupPrettierExecutable() abort
119+
return executable('npx') ? ['npx', '--no-install', 'prettier'] : 'prettier'
120+
endfunction
121+
122+
""
123+
" The path to the prettier executable. String, list, or callable that
124+
" takes no args and returns a string or a list. The default uses npx if
125+
" available, so that the repository-local prettier will have priority.
126+
call s:plugin.Flag('prettier_executable', function('s:LookupPrettierExecutable'))
127+
128+
" Invalidate cache of detected prettier availability whenever
129+
" prettier_executable changes.
130+
call s:plugin.flags.prettier_executable.AddCallback(
131+
\ maktaba#function#FromExpr('codefmt#prettier#InvalidateIsAvailable()'), 0)
121132

122133
""
123134
" Command line arguments to feed rustfmt. Either a list or callable that

vroom/prettier.vroom

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@ examples.
1414

1515
:call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0)
1616

17+
The default value of prettier_executable is a function that checks if npx is
18+
available. We need a deterministic result for these tests, so we'll replace that
19+
with a simple string.
20+
21+
:Glaive codefmt prettier_executable='prettier'
1722

1823
The prettier formatter expects the prettier executable to be installed on your system.
1924

2025
% function HelloWorld(){if(!greeting){return null};}
2126
:FormatCode prettier
22-
! prettier .*
27+
! cd .* prettier .*
2328
$ function HelloWorld() {
2429
$ if (!greeting) {
2530
$ return null;
@@ -31,7 +36,7 @@ prettier_executable flag if the default of "prettier" doesn't work.
3136

3237
:Glaive codefmt prettier_executable='myprettier'
3338
:FormatCode prettier
34-
! myprettier .*
39+
! cd .* myprettier .*
3540
$ function HelloWorld() {
3641
$ if (!greeting) {
3742
$ return null;
@@ -46,7 +51,7 @@ You can format any buffer with prettier specifying the formatter explicitly.
4651
% function HelloWorld(){if(!greeting){return null};}
4752

4853
:FormatCode prettier
49-
! prettier .*2>.*
54+
! cd .* prettier .*2>.*
5055
$ function HelloWorld() {
5156
$ if (!greeting) {
5257
$ return null;
@@ -65,7 +70,7 @@ Errors are reported using the quickfix list.
6570
% function foo() {
6671

6772
:FormatCode prettier
68-
! prettier .*2> (.*)
73+
! cd .* prettier .*2> (.*)
6974
$ 2 (status)
7075
$ echo >\1 ' (command)
7176
|[error] stdin: SyntaxError: Unexpected token (2:1)\n
@@ -87,7 +92,7 @@ It can format specific line ranges of code using :FormatLines.
8792
|function Greet(){if(!greeting){return null};}
8893

8994
:1,1FormatLines prettier
90-
! prettier .*--parser babylon --range-end 50.*2>.*
95+
! cd .* prettier .*--parser babylon --range-end 50.*2>.*
9196
$ function HelloWorld() {
9297
$ if (!greeting) {
9398
$ return null;

0 commit comments

Comments
 (0)