diff --git a/bundle/neomake/.circleci/config.yml b/bundle/neomake/.circleci/config.yml index c4c952d24..e7eac8d30 100644 --- a/bundle/neomake/.circleci/config.yml +++ b/bundle/neomake/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 common: &common docker: - - image: neomake/vims-for-tests:50@sha256:7a9de350cebf98b1d67edc0fc74cc3e925a45b5a956ffbbf26a93d0262ada45d + - image: neomake/vims-for-tests:52@sha256:13ce6994660f92b68281b993604fed7a7ea6be6579c5232bc183d358103a3d43 working_directory: ~/repo steps: - checkout @@ -30,6 +30,10 @@ common: &common - test-results/ jobs: + nvim-050: + <<: *common + environment: + TEST_VIM=/vim-build/bin/neovim-v0.5.0 nvim-038: <<: *common environment: @@ -102,6 +106,7 @@ workflows: version: 2 test: jobs: + - nvim-050 - nvim-038 - nvim-017 - vim-81 @@ -115,6 +120,7 @@ workflows: - coverage: requires: - nvim-master + - nvim-050 - nvim-038 - nvim-017 - vim-master diff --git a/bundle/neomake/Dockerfile.tests b/bundle/neomake/Dockerfile.tests index f6fcbc7d8..cf16f1add 100644 --- a/bundle/neomake/Dockerfile.tests +++ b/bundle/neomake/Dockerfile.tests @@ -1,5 +1,5 @@ # From https://github.com/tweekmonster/vim-testbed. -FROM testbed/vim:18@sha256:2b1872c68b6e9dfbfd8f804ad9727516ee971150142a80df354c244dcafa59c4 +FROM testbed/vim:23@sha256:d92287a56d52af24800f1ad54fa9c8570fee7b2aa748c9d23c219bc93377e401 # Currently tested versions: # - v7.3.429 (Ubuntu Precise, 12.04LTS) @@ -16,9 +16,10 @@ RUN install_vim -tag v7.3.429 -name vim73 --with-features=huge -build \ && rm -rf /vim-build/**/runtime/tutor RUN install_vim -tag v8.1.0622 -name vim81 -build \ -tag neovim:v0.3.8 -py3 -build \ + -tag neovim:v0.5.0 -build \ && rm -rf /vim-build/**/runtime/tutor -ENV NEOMAKE_DOCKERFILE_UPDATE=2020-01-27 +ENV NEOMAKE_DOCKERFILE_UPDATE=2021-09-10 # Git master in a separate layer, since the above is meant to be stable. RUN install_vim -tag master -build \ @@ -38,26 +39,27 @@ RUN curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest # files). grep for checks. ENV NEOMAKE_TESTS_DEP_PLUGINS_DIR=/neomake-deps ENV VIMHELPLINT_DIR=$NEOMAKE_TESTS_DEP_PLUGINS_DIR/vim-vimhelplint -RUN mkdir $NEOMAKE_TESTS_DEP_PLUGINS_DIR -RUN apk --no-cache add git \ +RUN mkdir $NEOMAKE_TESTS_DEP_PLUGINS_DIR \ + && apk --no-cache add git \ && git clone -q --depth=1 -b display-source-with-exceptions https://github.com/blueyed/vader.vim $NEOMAKE_TESTS_DEP_PLUGINS_DIR/vader \ && git clone -q --depth=1 https://github.com/tpope/vim-fugitive $NEOMAKE_TESTS_DEP_PLUGINS_DIR/vim-fugitive \ && git clone -q --depth=1 https://github.com/machakann/vim-vimhelplint $NEOMAKE_TESTS_DEP_PLUGINS_DIR/vim-vimhelplint \ && git clone -q --depth=1 https://github.com/syngan/vim-vimlint /tools/vim-vimlint \ - && git clone -q --depth=1 https://github.com/ynkdir/vim-vimlparser /tools/vim-vimlparser -RUN test -f /vim-build/bin/vim81 && ln -s /vim-build/bin/vim81 /usr/local/bin/vim -RUN printf '#!/bin/sh -x\n/tools/vim-vimlint/bin/vimlint.sh -l /tools/vim-vimlint -p /tools/vim-vimlparser "$@"\n' > /usr/local/bin/vimlint -RUN chmod +x /usr/local/bin/vimlint + && git clone -q --depth=1 https://github.com/ynkdir/vim-vimlparser /tools/vim-vimlparser \ + && test -f /vim-build/bin/vim81 && ln -s /vim-build/bin/vim81 /usr/local/bin/vim \ + && printf '#!/bin/sh -x\n/tools/vim-vimlint/bin/vimlint.sh -l /tools/vim-vimlint -p /tools/vim-vimlparser "$@"\n' > /usr/local/bin/vimlint \ + && chmod +x /usr/local/bin/vimlint # Install covimerage and vint. RUN apk --no-cache add python3 \ - && pip3 install -U pip \ - && pip3 install --no-cache-dir 'coverage<5' python-coveralls covimerage==0.2.1 vim-vint==0.3.21 \ && rm -rf /usr/include /usr/lib/python*/turtle* /usr/lib/python*/tkinter \ - && pip3 uninstall --yes pip \ - && curl https://codecov.io/bash -o /usr/bin/codecov \ - && chmod +x /usr/bin/codecov \ - && cd /usr/bin && ln -s python3 python + && ln -s /usr/bin/python3 /usr/local/bin/python \ + && python -m venv /venv \ + && /venv/bin/pip install covimerage==0.2.2 python-coveralls vim-vint==0.3.21 \ + && ln -s /venv/bin/coverage /venv/bin/coveralls /venv/bin/covimerage /venv/bin/vint /usr/local/bin \ + && curl -L https://github.com/codecov/codecov-bash/releases/download/1.0.5/codecov -o /usr/local/bin/codecov \ + && chmod +x /usr/local/bin/codecov +# Setup non-root user. RUN adduser -D -s /bin/bash neomake USER neomake diff --git a/bundle/neomake/Makefile b/bundle/neomake/Makefile index b7f48e455..1e9cd2224 100644 --- a/bundle/neomake/Makefile +++ b/bundle/neomake/Makefile @@ -183,7 +183,7 @@ vimhelplint: | $(if $(VIMHELPLINT_DIR),,build/vimhelplint) # Run tests in dockerized Vims. DOCKER_REPO:=neomake/vims-for-tests -DOCKER_TAG:=50 +DOCKER_TAG:=52 NEOMAKE_DOCKER_IMAGE?= DOCKER_IMAGE:=$(if $(NEOMAKE_DOCKER_IMAGE),$(NEOMAKE_DOCKER_IMAGE),$(DOCKER_REPO):$(DOCKER_TAG)) DOCKER_STREAMS:=-ti @@ -217,7 +217,7 @@ docker_update_image: @echo "Done. Use 'make docker_push' to push it, and then update .circleci/config.yml." DOCKER_VIMS:=vim73 vim74-trusty vim74-xenial vim80 vim81 \ - neovim-v0.1.7 neovim-v0.3.8 neovim-master vim-master + neovim-v0.1.7 neovim-v0.3.8 neovim-v0.5.0 neovim-master vim-master _DOCKER_VIM_TARGETS:=$(addprefix docker_test-,$(DOCKER_VIMS)) docker_test_all: $(_DOCKER_VIM_TARGETS) diff --git a/bundle/neomake/autoload/neomake.vim b/bundle/neomake/autoload/neomake.vim index 940f53709..5ae5a0f4b 100644 --- a/bundle/neomake/autoload/neomake.vim +++ b/bundle/neomake/autoload/neomake.vim @@ -506,7 +506,7 @@ function! s:MakeJob(make_id, options) abort endif finally call jobinfo.cd_back() - if exists('save_env_file') + if exists('l:save_env_file') call s:restore_env('NEOMAKE_FILE', save_env_file) endif endtry @@ -843,7 +843,7 @@ function! neomake#create_maker_object(maker, ft) abort endif endfor endif - if v:profiling + if exists('s:hack_keep_refs_for_profiling') " might not exist when starting profiling later..! call add(s:hack_keep_refs_for_profiling, maker) endif return maker @@ -2142,7 +2142,7 @@ else if !jobinfo._nvim_in_handler " Trigger previously delayed exit handler. unlet jobinfo._nvim_in_handler - if exists('jobinfo._exited_while_in_handler') + if has_key(jobinfo, '_exited_while_in_handler') call neomake#log#debug('Trigger delayed exit.', jobinfo) call s:exit_handler(jobinfo, jobinfo._exited_while_in_handler) endif @@ -2195,7 +2195,7 @@ function! s:exit_handler(jobinfo, data) abort return endif - if exists('jobinfo._output_while_in_handler') || exists('jobinfo._nvim_in_handler') + if has_key(jobinfo, '_output_while_in_handler') || has_key(jobinfo, '_nvim_in_handler') let jobinfo._exited_while_in_handler = a:data call neomake#log#debug(printf('exit (delayed): %s: %s.', \ maker.name, string(a:data)), jobinfo) @@ -2284,7 +2284,7 @@ endfunction function! s:output_handler_queued(jobinfo, data, event_type, trim_CR) abort let jobinfo = a:jobinfo - if exists('jobinfo._output_while_in_handler') + if has_key(jobinfo, '_output_while_in_handler') call neomake#log#debug(printf('Queuing: %s: %s: %s.', \ a:event_type, jobinfo.maker.name, string(a:data)), jobinfo) let jobinfo._output_while_in_handler += [[jobinfo, a:data, a:event_type, a:trim_CR]] @@ -2298,7 +2298,7 @@ function! s:output_handler_queued(jobinfo, data, event_type, trim_CR) abort " Process queued events that might have arrived by now. " The attribute might be unset here, since output_handler might have " been interrupted. - if exists('jobinfo._output_while_in_handler') + if has_key(jobinfo, '_output_while_in_handler') while has_key(jobinfo, '_output_while_in_handler') && !empty(jobinfo._output_while_in_handler) let args = remove(jobinfo._output_while_in_handler, 0) call call('s:output_handler', args) @@ -2306,7 +2306,7 @@ function! s:output_handler_queued(jobinfo, data, event_type, trim_CR) abort unlet! jobinfo._output_while_in_handler endif " Trigger previously delayed exit handler. - if exists('jobinfo._exited_while_in_handler') + if has_key(jobinfo, '_exited_while_in_handler') call neomake#log#debug('Trigger delayed exit.', jobinfo) call s:exit_handler(jobinfo, jobinfo._exited_while_in_handler) endif diff --git a/bundle/neomake/autoload/neomake/configure.vim b/bundle/neomake/autoload/neomake/configure.vim index 9f9d5add7..c6feec5d6 100644 --- a/bundle/neomake/autoload/neomake/configure.vim +++ b/bundle/neomake/autoload/neomake/configure.vim @@ -578,7 +578,7 @@ function! s:configure_buffer(bufnr, ...) abort if old_config != config call s:debug_log('resetting tick because of config changes') call setbufvar(bufnr, '_neomake_automake_tick', []) - elseif exists('old_registration') + elseif exists('l:old_registration') if old_registration != s:configured_buffers[bufnr] call s:debug_log('resetting tick because of registration changes') call setbufvar(bufnr, '_neomake_automake_tick', []) diff --git a/bundle/neomake/autoload/neomake/list.vim b/bundle/neomake/autoload/neomake/list.vim index 8c9ccdecc..da7cfa5ad 100644 --- a/bundle/neomake/autoload/neomake/list.vim +++ b/bundle/neomake/autoload/neomake/list.vim @@ -588,7 +588,6 @@ function! s:base_list._appendlist(entries, jobinfo) abort let diff = neomake#list#_diff_new_entries(a:entries, added) if !empty(diff) for [k, v] in items(diff) - " TODO: handle valid=1 being added? call neomake#log#debug(printf( \ 'Entry %d differs after adding: %s.', \ k+1, @@ -622,7 +621,7 @@ function! neomake#list#_diff_new_entries(orig, new) abort let r = {} for new in a:new let orig = copy(get(a:orig, i, {})) - for [k, v] in items({'pattern': '', 'module': '', 'valid': 1}) + for [k, v] in items({'pattern': '', 'module': '', 'valid': 1, 'end_lnum': 0, 'end_col': 0}) if has_key(new, k) let orig[k] = v endif diff --git a/bundle/neomake/autoload/neomake/makers/ft/ansible.vim b/bundle/neomake/autoload/neomake/makers/ft/ansible.vim index a1a001f8c..df3ccc7cf 100644 --- a/bundle/neomake/autoload/neomake/makers/ft/ansible.vim +++ b/bundle/neomake/autoload/neomake/makers/ft/ansible.vim @@ -12,6 +12,6 @@ function! neomake#makers#ft#ansible#ansiblelint() abort return { \ 'exe': 'ansible-lint', \ 'args': ['-p', '--nocolor'], - \ 'errorformat': '%f:%l: [%tANSIBLE%n] %m', + \ 'errorformat': '%f:%l: [%t%n] %m,%f:%l: [%tANSIBLE%n] %m', \ } endfunction diff --git a/bundle/neomake/autoload/neomake/makers/ft/clojure.vim b/bundle/neomake/autoload/neomake/makers/ft/clojure.vim new file mode 100644 index 000000000..314e8b8c8 --- /dev/null +++ b/bundle/neomake/autoload/neomake/makers/ft/clojure.vim @@ -0,0 +1,23 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#clojure#EnabledMakers() abort + return ['clj_kondo'] +endfunction + +function! neomake#makers#ft#clojure#clj_kondo() abort + let maker = { + \ 'exe': 'clj-kondo', + \ 'args': ['--lint'], + \ 'errorformat': + \ '%f:%l:%c: Parse %t%*[^:]: %m,'. + \ '%f:%l:%c: %t%*[^:]: %m,'. + \ '%-Glinting took %.%#' + \ } + + function! maker.supports_stdin(_jobinfo) abort + let self.args = ['--filename', '%'] + self.args + return 1 + endfunction + + return maker +endfunction diff --git a/bundle/neomake/autoload/neomake/makers/ft/dockerfile.vim b/bundle/neomake/autoload/neomake/makers/ft/dockerfile.vim index a6d767f80..31238f54f 100644 --- a/bundle/neomake/autoload/neomake/makers/ft/dockerfile.vim +++ b/bundle/neomake/autoload/neomake/makers/ft/dockerfile.vim @@ -6,8 +6,33 @@ function! neomake#makers#ft#dockerfile#hadolint() abort return { \ 'output_stream': 'stdout', \ 'uses_stdin': 1, - \ 'args': ['--format', 'tty'], + \ 'args': ['--format', 'tty', '--no-color'], \ 'errorformat': '%f:%l %m', + \ 'postprocess': [ + \ function('neomake#makers#ft#dockerfile#HadolintProcess'), + \ ], \ } endfunction + +function! neomake#makers#ft#dockerfile#HadolintProcess(entry) abort + let m = matchlist(a:entry.text, '\v^(DL|SC)(\d+) (warning|info|\w+): (.*)') + if !empty(m) + let a:entry.nr = str2nr(m[2]) + let matched_type = '' + if m[3] ==# 'warning' + let matched_type = 'W' + elseif m[3] ==# 'info' + let matched_type = 'I' + endif + if empty(matched_type) + " Guess, but do not adjust text. + let a:entry.type = m[3][0] + else + let a:entry.type = matched_type + " Remove type ("warning"/"info") from text. + let a:entry.text = printf('%s%s: %s', m[1], m[2], m[4]) + endif + endif +endfunction + " vim: ts=4 sw=4 et diff --git a/bundle/neomake/autoload/neomake/makers/ft/javascript.vim b/bundle/neomake/autoload/neomake/makers/ft/javascript.vim index 3f2cd210b..40e4f8eca 100644 --- a/bundle/neomake/autoload/neomake/makers/ft/javascript.vim +++ b/bundle/neomake/autoload/neomake/makers/ft/javascript.vim @@ -36,11 +36,35 @@ function! neomake#makers#ft#javascript#jscs() abort \ } endfunction +function! neomake#makers#ft#javascript#ProcessEslint(context) abort + let entries = [] + for file_data in a:context['json'] + for err in file_data.messages + let type = err.severity == 2 ? 'E' : 'W' + let entry = { + \ 'maker_name': 'eslint', + \ 'filename': file_data.filePath, + \ 'text': err.message, + \ 'lnum': has_key(err, 'line') ? err.line : 0, + \ 'col': has_key(err, 'column') ? err.column : 0, + \ 'type': type, + \ } + + if has_key(err, 'endColumn') + let entry['length'] = err.endColumn - err.column + endif + + call add(entries, entry) + endfor + endfor + return entries +endfunction + function! neomake#makers#ft#javascript#eslint() abort let maker = { - \ 'args': ['--format=compact'], - \ 'errorformat': '%E%f: line %l\, col %c\, Error - %m,' . - \ '%W%f: line %l\, col %c\, Warning - %m,%-G,%-G%*\d problems%#', + \ 'args': ['--format=json'], + \ 'process_json': function('neomake#makers#ft#javascript#ProcessEslint'), + \ 'cwd': '%:p:h', \ 'output_stream': 'stdout', \ } diff --git a/bundle/neomake/autoload/neomake/makers/ft/markdown.vim b/bundle/neomake/autoload/neomake/makers/ft/markdown.vim index 7983816fe..bc37fb3d6 100644 --- a/bundle/neomake/autoload/neomake/makers/ft/markdown.vim +++ b/bundle/neomake/autoload/neomake/makers/ft/markdown.vim @@ -28,7 +28,11 @@ endfunction function! neomake#makers#ft#markdown#markdownlint() abort return { - \ 'errorformat': '%f:%l %m,%f: %l: %m' + \ 'errorformat': + \ '%f:%l:%c %m,' . + \ '%f: %l: %c: %m,' . + \ '%f:%l %m,' . + \ '%f: %l: %m' \ } endfunction diff --git a/bundle/neomake/autoload/neomake/makers/ft/nix.vim b/bundle/neomake/autoload/neomake/makers/ft/nix.vim index f23978964..4c437da8e 100644 --- a/bundle/neomake/autoload/neomake/makers/ft/nix.vim +++ b/bundle/neomake/autoload/neomake/makers/ft/nix.vim @@ -4,11 +4,13 @@ function! neomake#makers#ft#nix#EnabledMakers() abort return ['nix_instantiate'] endfunction +" there is a single %C last in errorformat because nix >= 2.4 emits multiline +" error messages with empty lines in the middle. function! neomake#makers#ft#nix#nix_instantiate() abort return { \ 'exe': 'nix-instantiate', \ 'args': ['--parse-only'], - \ 'errorformat': 'error: %m at %f:%l:%c' + \ 'errorformat': 'error: %m at %f:%l:%c,%Eerror: %m,%Z at %f:%l:%c:,%C' \ } endfunction diff --git a/bundle/neomake/autoload/neomake/makers/ft/python.vim b/bundle/neomake/autoload/neomake/makers/ft/python.vim index 04c5d4ba5..2e2853a1e 100644 --- a/bundle/neomake/autoload/neomake/makers/ft/python.vim +++ b/bundle/neomake/autoload/neomake/makers/ft/python.vim @@ -115,7 +115,6 @@ function! neomake#makers#ft#python#flake8() abort let maker = { \ 'args': ['--format=default'], \ 'errorformat': - \ '%E%f:%l: could not compile,%-Z%p^,' . \ '%A%f:%l:%c: %t%n %m,' . \ '%A%f:%l: %t%n %m,' . \ '%-G%.%#', @@ -125,21 +124,23 @@ function! neomake#makers#ft#python#flake8() abort \ 'filter_output': function('neomake#makers#ft#python#FilterPythonWarnings'), \ } - function! maker.supports_stdin(jobinfo) abort - let self.args += ['--stdin-display-name', '%:p'] - + " With flake8 3.8.0 it is required to change the directory, since it now + " uses cwd to look up config files, not the common base of passed args + " anymore. https://gitlab.com/pycqa/flake8/-/merge_requests/363. + function! maker.InitForJob(jobinfo) abort let bufpath = bufname(a:jobinfo.bufnr) if !empty(bufpath) let bufdir = fnamemodify(bufpath, ':p:h') - if stridx(bufdir, getcwd()) != 0 - " The buffer is not below the current dir, so let's cd for lookup - " of config files etc. - " This avoids running into issues with flake8's per-file-ignores, - " which is handled not relative to the config file currently - " (https://gitlab.com/pycqa/flake8/issues/517). - call a:jobinfo.cd(bufdir) + if isdirectory(bufdir) + let self.cwd = bufdir + else + call neomake#log#debug(printf("buffer's directory does not exist: %s.", bufdir), a:jobinfo) endif endif + endfunction + + function! maker.supports_stdin(_jobinfo) abort + let self.args += ['--stdin-display-name', '%:p'] return 1 endfunction return maker @@ -267,11 +268,12 @@ function! neomake#makers#ft#python#Flake8EntryProcess(entry) abort endfunction function! neomake#makers#ft#python#pyflakes() abort + " NOTE: pyflakes 2.2.0 includes column always, but without trailing colon, + " except for SyntaxErrors. return { \ 'errorformat': - \ '%E%f:%l: could not compile,' . - \ '%-Z%p^,'. \ '%E%f:%l:%c: %m,' . + \ '%E%f:%l:%c %m,' . \ '%E%f:%l: %m,' . \ '%-G%.%#', \ } @@ -428,7 +430,7 @@ function! neomake#makers#ft#python#mypy() abort " Follow imports, but do not emit errors/issues for it, which " would result in errors for other buffers etc. " XXX: dmypy requires "skip" or "error" - call insert(maker.args, '--follow-imports=silent') + call add(maker.args, '--follow-imports=silent') else let project_root = neomake#utils#get_project_root(a:jobinfo.bufnr) if empty(project_root) @@ -440,6 +442,15 @@ function! neomake#makers#ft#python#mypy() abort return maker endfunction function! maker.supports_stdin(jobinfo) abort + if !filereadable(bufname(a:jobinfo.bufnr)) + " mypy cannot handle a non-existing target with --shadow-file, + " resulting in a confusing error about the temporary file not + " being there, although the to be shadowed one is missing + " (https://github.com/python/mypy/issues/4746). + " Therefore only use the extra args if it exists. + call neomake#log#debug('mypy: supports_stdin: buffer is not readable, not using shadow file.', a:jobinfo) + return 0 + endif if !has_key(self, 'tempfile_name') let self.tempfile_name = self._get_default_tempfilename(a:jobinfo) endif diff --git a/bundle/neomake/autoload/neomake/makers/ft/ruby.vim b/bundle/neomake/autoload/neomake/makers/ft/ruby.vim index fb0736291..95b43a7c2 100644 --- a/bundle/neomake/autoload/neomake/makers/ft/ruby.vim +++ b/bundle/neomake/autoload/neomake/makers/ft/ruby.vim @@ -57,7 +57,7 @@ function! neomake#makers#ft#ruby#mri() abort return { \ 'exe': 'ruby', - \ 'args': ['-c', '-T1', '-w'], + \ 'args': ['-c', '-w'], \ 'errorformat': errorformat, \ 'output_stream': 'both', \ } diff --git a/bundle/neomake/autoload/neomake/makers/ft/scss.vim b/bundle/neomake/autoload/neomake/makers/ft/scss.vim index e33ea6fc2..c6ca4dd18 100644 --- a/bundle/neomake/autoload/neomake/makers/ft/scss.vim +++ b/bundle/neomake/autoload/neomake/makers/ft/scss.vim @@ -7,8 +7,8 @@ endfunction function! neomake#makers#ft#scss#sasslint() abort return { \ 'exe': 'sass-lint', - \ 'args': ['--no-exit', '--verbose', '--format', 'compact'], - \ 'errorformat': neomake#makers#ft#javascript#eslint()['errorformat'] + \ 'args': ['--no-exit', '--verbose', '--format', 'json'], + \ 'process_json': function('neomake#makers#ft#javascript#ProcessEslint') \ } endfunction diff --git a/bundle/neomake/autoload/neomake/makers/ft/vue.vim b/bundle/neomake/autoload/neomake/makers/ft/vue.vim index 0378bc780..d9f530312 100644 --- a/bundle/neomake/autoload/neomake/makers/ft/vue.vim +++ b/bundle/neomake/autoload/neomake/makers/ft/vue.vim @@ -6,7 +6,7 @@ endfunction function! neomake#makers#ft#vue#eslint() abort let maker = neomake#makers#ft#javascript#eslint() - call extend(get(maker, 'args', []), ['--plugin', 'vue']) + call extend(get(maker, 'args', []), ['--plugin', 'html']) return maker endfunction @@ -16,13 +16,13 @@ endfunction function! neomake#makers#ft#vue#standard() abort let maker = neomake#makers#ft#javascript#standard() - call extend(get(maker, 'args', []), ['--plugin', 'vue']) + call extend(get(maker, 'args', []), ['--plugin', 'html']) return maker endfunction function! neomake#makers#ft#vue#semistandard() abort let maker = neomake#makers#ft#javascript#semistandard() - call extend(get(maker, 'args', []), ['--plugin', 'vue']) + call extend(get(maker, 'args', []), ['--plugin', 'html']) return maker endfunction diff --git a/bundle/neomake/autoload/neomake/postprocess.vim b/bundle/neomake/autoload/neomake/postprocess.vim index d92a89792..6e7928d9b 100644 --- a/bundle/neomake/autoload/neomake/postprocess.vim +++ b/bundle/neomake/autoload/neomake/postprocess.vim @@ -63,7 +63,7 @@ endfunction let g:neomake#postprocess#remove_duplicates = {} function! g:neomake#postprocess#remove_duplicates.fn(entry) abort - if exists('self._seen_entries') + if has_key(self, '_seen_entries') if index(self._seen_entries, a:entry) != -1 let a:entry.valid = -1 else diff --git a/bundle/neomake/contrib/vim-checks b/bundle/neomake/contrib/vim-checks index c4791d75a..fd9927150 100644 --- a/bundle/neomake/contrib/vim-checks +++ b/bundle/neomake/contrib/vim-checks @@ -111,7 +111,13 @@ check_errors ' \+$' 'Trailing whitespace' check_errors '^ * end\?i\? *$' 'Write endif, not en, end, or endi' check_errors '^(( )*([^ ]|$)|\s+\\)' 'Use four spaces for indentation' -v -E check_errors $'\t' 'Do not use tabs for indentation' -check_errors '^\s*[^" ].*[^&]l:[a-z]' 'Do not use l: prefix for local variables' + +# Disallow local prefix with variables ("l:foo"), but allow it within (single +# quoted) strings, and require it with exists() checks, where `exists('foo')` +# is true for a global variable `foo`. +check_errors "^\s*[^\" ].*[^'&]l:[a-z]" 'Do not use l: prefix for local variables' +check_errors "^\s*[^\" ].* exists\('\w(?!:)" 'Use l: prefix for checking local variables' -P + for arg in "${args[@]}"; do expand_arg "$arg" grep --files-without-match '^"[ ]vim: ts=4 sw=4 et' "${expanded_arg[@]}" \ diff --git a/bundle/neomake/tests/automake.vader b/bundle/neomake/tests/automake.vader index eb234a463..1a69cc8d7 100644 --- a/bundle/neomake/tests/automake.vader +++ b/bundle/neomake/tests/automake.vader @@ -1112,8 +1112,11 @@ Execute (automake: display of error with O during maker run (TextChanged)): let maker1 = copy(g:error_maker) let maker1.name = 'mymaker1' - function! maker1.process_output(...) + function! maker1.process_output(context) let s:error_count += 1 + if !exists('s:make_info') + let s:make_info = neomake#GetStatus().make_info[a:context.jobinfo.make_id] + endif return [{'lnum': 1, 'text': 'error1:'.s:error_count}] endfunction @@ -1139,11 +1142,10 @@ Execute (automake: display of error with O during maker run (TextChanged)): AssertEqual neomake#GetCurrentErrorMsg(), '' NeomakeTestsWaitForMessage '\Vautomake: callback for timer \d\+ (via TextChanged).', 3 - let make_info = values(neomake#GetStatus().make_info)[0] - let make_id = make_info.make_id Assert exists('#neomake_automake_abort') NeomakeTestsWaitForFinishedJobs + let make_info = s:make_info AssertNeomakeMessage 'Processing 1 entries.', 3 AssertNeomakeMessage 'mymaker1: completed with exit code 1.', 3 AssertNeomakeMessage '\V\^Skipping cleaning of make info: 1 active jobs: [''Job \d\+: mymaker2''].', 3, make_info diff --git a/bundle/neomake/tests/compat.vader b/bundle/neomake/tests/compat.vader index e99c2d784..e28835750 100644 --- a/bundle/neomake/tests/compat.vader +++ b/bundle/neomake/tests/compat.vader @@ -30,7 +30,8 @@ Execute (neomake#compat#systemlist): AssertNeomakeMessage "systemlist error: Vim(return):E475: Invalid value for argument cmd: 'echo 1' is not executable.", 0 endif else - AssertEqual r, [&shell.': echo 1: command not found'] + AssertEqual len(r), 1 + Assert r[0] =~# printf('\v%s(: line 1)?: echo 1: command not found$', &shell), r[0] AssertEqual v:shell_error, 127 endif @@ -46,7 +47,9 @@ Execute (neomake#compat#systemlist): Execute (neomake#compat#systemlist with empty args): AssertEqual neomake#compat#systemlist(''), [] AssertEqual neomake#compat#systemlist([]), [] - AssertEqual neomake#compat#systemlist('0'), [&shell.': 0: command not found'] + let output = neomake#compat#systemlist('0') + AssertEqual len(output), 1 + Assert output[0] =~# printf('\v%s(: line 1)?: 0: command not found$', &shell), output[0] Execute (neomake#compat#json_decode): AssertEqual neomake#compat#json_decode(''), g:neomake#compat#json_none @@ -55,7 +58,11 @@ Execute (neomake#compat#json_decode): if has('nvim') let expected_exception = 'Vim(return):E474: Unidentified byte: success' elseif exists('*json_decode') - let expected_exception = 'Vim(return):E474: Invalid argument' + if has('patch-8.2.0800') + let expected_exception = 'Vim(return):E491: json decode error at ''success''' + else + let expected_exception = 'Vim(return):E474: Invalid argument' + endif else let expected_exception = 'Neomake: Failed to parse JSON input: invalid input' endif @@ -108,6 +115,10 @@ Execute (neomake#compat#get_mode): endif Execute (neomake#compat#get_mode with insert mode completion (feedkeys)): + if has('nvim-0.5.0') + NeomakeTestsSkip 'segfaults on neovim (https://github.com/neovim/neovim/issues/14565)' + return + endif if has('timers') new file file_sleep_efm @@ -135,6 +146,10 @@ Execute (neomake#compat#get_mode with insert mode completion (feedkeys)): endif Execute (neomake#compat#get_mode with insert mode completion (imap)): + if has('nvim-0.5.0') + NeomakeTestsSkip 'segfaults on neovim (https://github.com/neovim/neovim/issues/14565)' + return + endif new file file_sleep_efm normal! iword1 diff --git a/bundle/neomake/tests/customqf.vader b/bundle/neomake/tests/customqf.vader index e5d20356c..b57358ffa 100644 --- a/bundle/neomake/tests/customqf.vader +++ b/bundle/neomake/tests/customqf.vader @@ -475,7 +475,7 @@ Execute (neomake#quickfix#FormatQuickfix logs exception from nmcfg)): lopen AssertEqual getline(1), '???? text1 nmcfg:{undefined}' AssertNeomakeMessage 'Error when evaluating nmcfg ({undefined}): Vim(let):E121: Undefined variable: undefined.', 0 - AssertNeomakeMessage '\v\(in function neomake#quickfix#FormatQuickfix, line \d+\)', 3 + AssertNeomakeMessage '\v\(in (command line\.\..{-}\.\.)?function neomake#quickfix#FormatQuickfix, line \d+\)$', 3 lclose bwipe finally diff --git a/bundle/neomake/tests/cwd.vader b/bundle/neomake/tests/cwd.vader index 54c903ccc..48d589488 100644 --- a/bundle/neomake/tests/cwd.vader +++ b/bundle/neomake/tests/cwd.vader @@ -113,7 +113,16 @@ Execute (cwd handles fugitive buffer): edit autoload/neomake/debug.vim let expected_cwd = fnamemodify(bufname('%'), ':p:h') let orig_abs_bufname = expand('%:p') - Gedit + try + Gedit + catch /^Vim\%((\a\+)\)\=:E/ + NeomakeTestsSkip 'error with/through vim-fugitive (not b/c, e.g. neovim-0.1.7)' + bwipe + if exists('*VimFtpluginUndo') + delfunction VimFtpluginUndo + endif + return + endtry Assert bufname('%') =~# '^fugitive://', 'Unexpected bufname: '.bufname('%') let b:neomake_tempfile_enabled = 1 diff --git a/bundle/neomake/tests/fixtures/javascript/eslint_example.json b/bundle/neomake/tests/fixtures/javascript/eslint_example.json new file mode 100644 index 000000000..96f287a90 --- /dev/null +++ b/bundle/neomake/tests/fixtures/javascript/eslint_example.json @@ -0,0 +1 @@ +[{"filePath":"fullOfProblems.js","messages":[{"ruleId":"no-unused-vars","severity":2,"message":"'addOne' is defined but never used.","line":1,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":1,"endColumn":16},{"ruleId":"use-isnan","severity":2,"message":"Use the isNaN function to compare with NaN.","line":2,"column":9,"nodeType":"BinaryExpression","messageId":"comparisonWithNaN","endLine":2,"endColumn":17},{"ruleId":"space-unary-ops","severity":2,"message":"Unexpected space before unary operator '++'.","line":3,"column":16,"nodeType":"UpdateExpression","messageId":"unexpectedBefore","endLine":3,"endColumn":20,"fix":{"range":[57,58],"text":""}},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":3,"column":20,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":4,"endColumn":1,"fix":{"range":[60,60],"text":";"}},{"ruleId":"no-else-return","severity":1,"message":"Unnecessary 'else' after 'return'.","line":4,"column":12,"nodeType":"BlockStatement","messageId":"unexpected","endLine":6,"endColumn":6,"fix":{"range":[0,94],"text":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } \n return\n \n}"}},{"ruleId":"indent","severity":1,"message":"Expected indentation of 8 spaces but found 6.","line":5,"column":1,"nodeType":"Keyword","messageId":"wrongIndentation","endLine":5,"endColumn":7,"fix":{"range":[74,80],"text":" "}},{"ruleId":"consistent-return","severity":2,"message":"Function 'addOne' expected a return value.","line":5,"column":7,"nodeType":"ReturnStatement","messageId":"missingReturnValue","endLine":5,"endColumn":13},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":5,"column":13,"nodeType":"ReturnStatement","messageId":"missingSemi","endLine":6,"endColumn":1,"fix":{"range":[86,86],"text":";"}},{"ruleId":"no-extra-semi","severity":2,"message":"Unnecessary semicolon.","line":7,"column":2,"nodeType":"EmptyStatement","messageId":"unexpected","endLine":7,"endColumn":3,"fix":{"range":[93,95],"text":"}"}}],"errorCount":5,"warningCount":4,"fixableErrorCount":2,"fixableWarningCount":4,"source":"function addOne(i) {\n if (i != NaN) {\n return i ++\n } else {\n return\n }\n};"}] diff --git a/bundle/neomake/tests/ft_clojure.vader b/bundle/neomake/tests/ft_clojure.vader new file mode 100644 index 000000000..f7e934c76 --- /dev/null +++ b/bundle/neomake/tests/ft_clojure.vader @@ -0,0 +1,29 @@ +Include: include/setup.vader + +Execute (clojure: clj_kondo: errorformat): + let maker = NeomakeTestsGetMakerWithOutput(neomake#makers#ft#clojure#clj_kondo(), [ + \ 'file1.clj:2:1: error: unresolved symbol unknown', + \ 'linting took 12ms, errors: 1, warnings: 0', + \ ]) + let maker.name = 'clojure' + new + file file1.clj + CallNeomake 1, [maker] + AssertEqualQf getloclist(0), [ + \ {'lnum': 2, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, + \ 'nr': -1, 'type': 'e', 'pattern': '', + \ 'text': 'unresolved symbol unknown'}] + bwipe + +Execute (clojure: clj_kondo: supports_stdin): + new + noautocmd setfiletype clojure + + let b:neomake = {'clj_kondo': {'exe': 'echo', 'errorformat': '%m'}} + CallNeomake 1, ['clj_kondo'] + AssertNeomakeMessage '\vStarting .{-}: echo --filename '''' --lint -.', 2 + + file file1.clj + CallNeomake 1, ['clj_kondo'] + AssertNeomakeMessage '\vStarting .{-}: echo --filename file1.clj --lint -.', 2 + bwipe diff --git a/bundle/neomake/tests/ft_dockerfile.vader b/bundle/neomake/tests/ft_dockerfile.vader new file mode 100644 index 000000000..d8b7bd475 --- /dev/null +++ b/bundle/neomake/tests/ft_dockerfile.vader @@ -0,0 +1,25 @@ +Include: include/setup.vader + +Execute (dockerfile: hadolint): + let maker = NeomakeTestsGetMakerWithOutput(neomake#makers#ft#dockerfile#hadolint(), [ + \ 'Dockerfile:1 DL3018 warning: Pin versions in apk add. …', + \ 'Dockerfile:2 DL3059 info: Multiple consecutive `RUN` instructions. …', + \ 'Dockerfile:3 SC2086 info: Double quote to prevent globbing and word splitting.', + \ 'Dockerfile:45 DL123 error: invented.', + \ ]) + let maker.name = 'hadolint' + new + let bufnr = bufnr('%') + file Dockerfile + CallNeomake 1, [maker] + AssertEqualQf [getloclist(0)][0], [ + \ {'lnum': 1, 'bufnr': bufnr, 'nr': 3018, 'type': 'W', 'col': 0, + \ 'text': 'DL3018: Pin versions in apk add. …'}, + \ {'lnum': 2, 'bufnr': bufnr, 'nr': 3059, 'type': 'I', 'col': 0, + \ 'text': 'DL3059: Multiple consecutive `RUN` instructions. …'}, + \ {'lnum': 3, 'bufnr': bufnr, 'nr': 2086, 'type': 'I', 'col': 0, + \ 'text': 'SC2086: Double quote to prevent globbing and word splitting.'}, + \ {'lnum': 45, 'bufnr': bufnr, 'nr': 123, 'type': 'e', 'col': 0, + \ 'text': 'DL123 error: invented.'}, + \ ] + bwipe diff --git a/bundle/neomake/tests/ft_javascript.vader b/bundle/neomake/tests/ft_javascript.vader index 68fb84d5d..0b88e7ee1 100644 --- a/bundle/neomake/tests/ft_javascript.vader +++ b/bundle/neomake/tests/ft_javascript.vader @@ -1,58 +1,67 @@ Include: include/setup.vader Execute (javascript: eslint: errorformat): - Save &errorformat - let &errorformat = neomake#makers#ft#javascript#eslint().errorformat new - file errors.js - let bufnr = bufnr('%') + file fullOfProblems.js - let output = [ - \ "errors.js: line 2, col 10, Error - 'some_unused_var' is defined but never used. (no-unused-vars)", - \ '', - \ '1 problem', - \ ] + let eslint = NeomakeTestsGetMakerWithOutput(neomake#makers#ft#javascript#eslint(), + \ 'tests/fixtures/javascript/eslint_example.json') - lgetexpr output + CallNeomake 1, [eslint] AssertEqualQf getloclist(0), [{ - \ 'lnum': 2, - \ 'bufnr': bufnr, - \ 'col': 10, - \ 'valid': 1, - \ 'vcol': 0, - \ 'nr': -1, - \ 'type': 'E', - \ 'pattern': '', - \ 'text': "'some_unused_var' is defined but never used. (no-unused-vars)"}] - - let output = [ - \ "errors.js: line 2, col 10, Error - 'some_unused_var' is defined but never used. (no-unused-vars)", - \ "errors.js: line 3, col 20, Warning - Missing semicolon. (semi)", - \ '', - \ '2 problems', - \ ] - - lgetexpr output - AssertEqualQf getloclist(0), [{ - \ 'lnum': 2, - \ 'bufnr': bufnr, - \ 'col': 10, - \ 'valid': 1, - \ 'vcol': 0, - \ 'nr': -1, - \ 'type': 'E', - \ 'pattern': '', - \ 'text': "'some_unused_var' is defined but never used. (no-unused-vars)", - \ }, { - \ 'lnum': 3, - \ 'bufnr': bufnr, - \ 'col': 20, - \ 'valid': 1, - \ 'vcol': 0, - \ 'nr': -1, - \ 'type': 'W', - \ 'pattern': '', - \ 'text': 'Missing semicolon. (semi)'}] + \ 'lnum': 1, 'bufnr': bufnr('%'), 'col': 10, 'type': 'E', + \ 'text': "'addOne' is defined but never used.", + \ 'pattern': '', 'vcol': 0, 'nr': -1, + \ 'valid': 1, + \ }, + \ { + \ 'lnum': 2, 'bufnr': bufnr('%'), 'col': 9, 'type': 'E', + \ 'text': "Use the isNaN function to compare with NaN.", + \ 'pattern': '', 'vcol': 0, 'nr': -1, + \ 'valid': 1, + \ }, + \ { + \ 'lnum': 3, 'bufnr': bufnr('%'), 'col': 16, 'type': 'E', + \ 'text': "Unexpected space before unary operator '++'.", + \ 'pattern': '', 'vcol': 0, 'nr': -1, + \ 'valid': 1, + \ }, + \ { + \ 'lnum': 3, 'bufnr': bufnr('%'), 'col': 20, 'type': 'W', + \ 'text': "Missing semicolon.", + \ 'pattern': '', 'vcol': 0, 'nr': -1, + \ 'valid': 1, + \ }, + \ { + \ 'lnum': 4, 'bufnr': bufnr('%'), 'col': 12, 'type': 'W', + \ 'text': "Unnecessary 'else' after 'return'.", + \ 'pattern': '', 'vcol': 0, 'nr': -1, + \ 'valid': 1, + \ }, + \ { + \ 'lnum': 5, 'bufnr': bufnr('%'), 'col': 1, 'type': 'W', + \ 'text': "Expected indentation of 8 spaces but found 6.", + \ 'pattern': '', 'vcol': 0, 'nr': -1, + \ 'valid': 1, + \ }, + \ { + \ 'lnum': 5, 'bufnr': bufnr('%'), 'col': 7, 'type': 'E', + \ 'text': "Function 'addOne' expected a return value.", + \ 'pattern': '', 'vcol': 0, 'nr': -1, + \ 'valid': 1, + \ }, + \ { + \ 'lnum': 5, 'bufnr': bufnr('%'), 'col': 13, 'type': 'W', + \ 'text': "Missing semicolon.", + \ 'pattern': '', 'vcol': 0, 'nr': -1, + \ 'valid': 1, + \ }, + \ { + \ 'lnum': 7, 'bufnr': bufnr('%'), 'col': 2, 'type': 'E', + \ 'text': "Unnecessary semicolon.", + \ 'pattern': '', 'vcol': 0, 'nr': -1, + \ 'valid': 1, + \ }] bwipe Execute (javascript: standard: errorformat): diff --git a/bundle/neomake/tests/ft_markdown.vader b/bundle/neomake/tests/ft_markdown.vader index ddf9a48ff..148d64429 100644 --- a/bundle/neomake/tests/ft_markdown.vader +++ b/bundle/neomake/tests/ft_markdown.vader @@ -64,3 +64,35 @@ Execute (markdown: mdl): \ 'text': 'Inline HTML (MD033)', \ }] bwipe + +Execute (markdown: markdownlint): + let maker = NeomakeTestsGetMakerWithOutput(neomake#makers#ft#markdown#markdownlint(), [ + \ 'README.md:66:81 MD013/line-length Line length [Expected: 80; Actual: 83]', + \ 'README.md:122 MD025/single-title/single-h1 Multiple top level headings in the same document [Context: "# Contributing"]', + \ ]) + + new + noautocmd file README.md + CallNeomake 1, [maker] + AssertEqualQf getloclist(0), [{ + \ 'lnum': 66, + \ 'bufnr': bufnr('%'), + \ 'col': 81, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': -1, + \ 'type': 'W', + \ 'pattern': '', + \ 'text': 'MD013/line-length Line length [Expected: 80; Actual: 83]', + \ },{ + \ 'lnum': 122, + \ 'bufnr': bufnr('%'), + \ 'col': 0, + \ 'valid': 1, + \ 'vcol': 0, + \ 'nr': -1, + \ 'type': 'W', + \ 'pattern': '', + \ 'text': 'MD025/single-title/single-h1 Multiple top level headings in the same document [Context: "# Contributing"]', + \ }] + bwipe diff --git a/bundle/neomake/tests/ft_python.vader b/bundle/neomake/tests/ft_python.vader index f706a1083..5c3b98ca3 100644 --- a/bundle/neomake/tests/ft_python.vader +++ b/bundle/neomake/tests/ft_python.vader @@ -241,7 +241,8 @@ Execute (python: flake8: supports_stdin: changes cwd (non-existing)): let b:neomake = {'flake8': {'exe': 'echo', 'errorformat': '%m'}} CallNeomake 1, ['flake8'] - AssertNeomakeMessage printf('\Vjobinfo.cd(): error when trying to change cwd to %s:', tempdir) + AssertNeomakeMessage printf("buffer's directory does not exist: %s.", tempdir), 3 + AssertNeomakeMessage 'Using stdin for unreadable buffer (-).', 3 AssertNeomakeMessage printf('\vStarting .{-}: echo --format\=default --stdin-display-name %s -.', fname), 2 AssertNeomakeMessage printf('cwd: %s.', getcwd()) AssertEqual getloclist(0)[0].text, @@ -263,7 +264,7 @@ Execute (python: flake8: supports_stdin: changes cwd (existing)): \ printf('-1 --format=default --stdin-display-name %s -', fname) bwipe -Execute (python: flake8: supports_stdin: does not change cwd with buffer in subdir): +Execute (python: flake8: supports_stdin: changes cwd also with buffer in subdir): new let cwd = tempname() let fdir = cwd.neomake#utils#Slash().'subdir' @@ -278,11 +279,47 @@ Execute (python: flake8: supports_stdin: does not change cwd with buffer in subd AssertNeomakeMessageAbsent '\Verror when trying to change cwd' AssertNeomakeMessage printf('\vStarting .{-}: echo --format\=default --stdin-display-name %s -.', \ fname), 2 - AssertNeomakeMessage printf('cwd: %s.', cwd) + AssertNeomakeMessage printf('cwd: %s (changed).', fdir) AssertEqual getloclist(0)[0].text, \ printf('-1 --format=default --stdin-display-name %s -', fname) bwipe +Execute (python: pyflakes: SyntaxError): + let maker = NeomakeTestsGetMakerWithOutput(neomake#makers#ft#python#pyflakes(), [ + \ 'test.py:1:8: unexpected EOF while parsing', + \ 'print(n', + \ ' ^', + \ ]) + let maker.name = 'pyflakes' + new + file test.py + CallNeomake 1, [maker] + AssertEqualQf getloclist(0), [ + \ {'lnum': 1, 'bufnr': bufnr('%'), 'col': 8, 'valid': 1, 'vcol': 0, + \ 'nr': -1, 'type': 'E', 'pattern': '', + \ 'text': 'unexpected EOF while parsing'}] + AssertEqual line('.'), 1 + AssertEqual neomake#GetCurrentErrorMsg(), + \ 'pyflakes: unexpected EOF while parsing (E)' + bwipe + +Execute (python: pyflakes: normal errors): + let maker = NeomakeTestsGetMakerWithOutput(neomake#makers#ft#python#pyflakes(), [ + \ "test.py:1:7 undefined name 'n'", + \ ]) + let maker.name = 'pyflakes' + new + file test.py + CallNeomake 1, [maker] + AssertEqualQf getloclist(0), [ + \ {'lnum': 1, 'bufnr': bufnr('%'), 'col': 7, 'valid': 1, 'vcol': 0, + \ 'nr': -1, 'type': 'E', 'pattern': '', + \ 'text': "undefined name 'n'"}] + AssertEqual line('.'), 1 + AssertEqual neomake#GetCurrentErrorMsg(), + \ "pyflakes: undefined name 'n' (E)" + bwipe + Execute (python: pylint): let entry = {'type': 'F', 'col': 1} call neomake#makers#ft#python#PylintEntryProcess(entry) @@ -411,7 +448,7 @@ Execute (python: mypy): let options = {'file_mode': 1} let bound_maker = neomake#core#instantiate_maker(maker, options, 0) - AssertEqual bound_maker.args, ['--follow-imports=silent'] + base_args + AssertEqual bound_maker.args, base_args + ['--follow-imports=silent'] new let b:neomake = {'project_root': 'fake_project_root'} @@ -424,11 +461,21 @@ Execute (python: mypy): let bound_maker = neomake#core#instantiate_maker(maker, options, 0) AssertEqual bound_maker.args, base_args + ['.'] + " supports_stdin: does not inject "--shadow-file" with unreadable buffer. let jobinfo = NeomakeTestsFakeJobinfo() AssertEqual bound_maker.supports_stdin(jobinfo), 0 + AssertEqual bound_maker.args, base_args + ['.'] + AssertNeomakeMessage 'mypy: supports_stdin: buffer is not readable, not using shadow file.', 3 let fname = bound_maker._get_fname_for_buffer(jobinfo) + AssertNeomakeMessage 'mypy: supports_stdin: buffer is not readable, not using shadow file.', 3 AssertNeomakeMessage '\vUsing tempfile for unnamed buffer: "(.*)".', 3 let tmpfile = g:neomake_test_matchlist[1] AssertEqual fname, tmpfile + " supports_stdin: injects "--shadow-file" with readable buffer. + let jobinfo = NeomakeTestsFakeJobinfo() + exe 'write' tempname() + AssertEqual bound_maker.supports_stdin(jobinfo), 0 + AssertEqual bound_maker.args, base_args + ['.', '--shadow-file', '%', bound_maker.tempfile_name] + bwipe diff --git a/bundle/neomake/tests/hooks-queue.vader b/bundle/neomake/tests/hooks-queue.vader index 0fec5322f..d41946987 100644 --- a/bundle/neomake/tests/hooks-queue.vader +++ b/bundle/neomake/tests/hooks-queue.vader @@ -119,18 +119,19 @@ Execute (Does not nest hooks / User autocommands): if NeomakeAsyncTestsSetup() new + let s:uses_action_queue = has('nvim') || !has('patch-8.2.0452') + augroup neomake_tests autocmd User NeomakeJobFinished nested call s:OnNeomakeJobFinished() augroup END function! s:OnNeomakeJobFinished() abort let jobinfo = g:neomake_hook_context.jobinfo - if jobinfo.maker.name == 'maker1' + if jobinfo.maker.name == 'maker1' && s:uses_action_queue NeomakeTestsWaitForMessage '\v^Queuing User autocmd NeomakeCountsChanged for nested invocation ', 3 AssertNeomakeMessage 'Queuing action handle_hook for Timer, BufEnter, WinEnter, InsertLeave, CursorHold, CursorHoldI.', 3 AssertNeomakeMessage '\V\^Retrying Timer event in 10ms', 3 endif - " call neomake#log#debug('OnNeomakeJobFinished finished.') endfunction let maker1 = NeomakeTestsCommandMaker('maker1', 'echo error1; exit 1') @@ -143,9 +144,13 @@ Execute (Does not nest hooks / User autocommands): AssertEqual map(getloclist(0), 'v:val.text'), ['error1', 'error2'] doautocmd WinEnter - AssertNeomakeMessage 'action queue: calling handle_hook.' + if s:uses_action_queue + AssertNeomakeMessage 'action queue: calling handle_hook.' + endif AssertNeomakeMessage '\VCalling User autocmd NeomakeCountsChanged with context: ', 3 - AssertNeomakeMessage 'action queue: calling CleanJobinfo.', 3 + if s:uses_action_queue + AssertNeomakeMessage 'action queue: calling CleanJobinfo.', 3 + endif AssertNeomakeMessage 'Cleaning jobinfo.', 3 AssertNeomakeMessage '\VCalling User autocmd NeomakeJobFinished with context: ', 3 AssertNeomakeMessage '\VCalling User autocmd NeomakeFinished with context: ', 3 diff --git a/bundle/neomake/tests/include/init.vim b/bundle/neomake/tests/include/init.vim index 04119b0b3..6a012cade 100644 --- a/bundle/neomake/tests/include/init.vim +++ b/bundle/neomake/tests/include/init.vim @@ -257,10 +257,19 @@ endfunction command! -nargs=1 AssertNeomakeWarning call s:AssertNeomakeWarning() function! s:AssertEqualQf(actual, expected, ...) abort - let expected = a:expected + let expected = copy(a:expected) if has('patch-8.0.1782') || has('nvim-0.4.0') - let expected = map(copy(expected), "extend(v:val, {'module': ''})") + let expected = map(expected, "extend(v:val, {'module': ''}, 'keep')") endif + + if has('patch-8.2.3019') || has('nvim-0.6.0') + let expected = map(expected, "extend(v:val, {'end_lnum': 0, 'end_col': 0}, 'keep')") + endif + + " Extend with defaults, to make tests shorter. + let expected = map(expected, 'extend(v:val, ' + \ ."{'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1}, 'keep')") + call call('vader#assert#equal', [a:actual, expected] + a:000) endfunction command! -nargs=1 AssertEqualQf call s:AssertEqualQf() @@ -506,7 +515,7 @@ function! s:After() " exit handler, but that is OK. let jobs = filter(neomake#GetJobs(), "!get(v:val, 'canceled', 0)") if !empty(jobs) - call neomake#log#debug('=== teardown: canceling jobs.') + call neomake#log#debug('=== test teardown: canceling jobs.') for job in jobs call neomake#CancelJob(job.id, !neomake#has_async_support()) endfor diff --git a/bundle/neomake/tests/integration.vader b/bundle/neomake/tests/integration.vader index 7ede11fd0..3defeabc9 100644 --- a/bundle/neomake/tests/integration.vader +++ b/bundle/neomake/tests/integration.vader @@ -753,7 +753,7 @@ Execute (Neomake: entry.valid < 0 and configured entry type): call neomake#Make(1, [maker]) NeomakeTestsWaitForFinishedJobs AssertNeomakeMessage 'Processing 4 lines of output.' - AssertNeomakeMessage "\\vRemoving invalid entry: invalid \\(\\{'lnum': 0, 'bufnr': 0, 'col': 0, 'valid': -1, .*\\}\\)." + AssertNeomakeMessage "\\vRemoving invalid entry: invalid \\(\\{'lnum': 0, 'bufnr': 0, .*, 'valid': -1, .*\\}\\)." AssertNeomakeMessage 'Processing 3 entries.' " Without this patch entries are invalid always after setqflist/setloclist. diff --git a/bundle/neomake/tests/log.vader b/bundle/neomake/tests/log.vader index 89931f8b1..fa42658e0 100644 --- a/bundle/neomake/tests/log.vader +++ b/bundle/neomake/tests/log.vader @@ -37,5 +37,7 @@ Execute (neomake#log#debug throws with missing make_options in tests): AssertEqual g:neomake_test_errors, [] call neomake#log#debug('msg1.', {'make_id': -42}) AssertEqual len(g:neomake_test_errors), 1 - Assert g:neomake_test_errors[0] =~# '\v^GetMakeOptions failed: Vim\(let\):E716: Key not present in Dictionary: -42 \(in function .*\)$' + Assert g:neomake_test_errors[0] =~# + \ '\v^GetMakeOptions failed: Vim\(let\):E716: Key not present in Dictionary: "?-42"?' + \ .' \(in .*neomake#GetMakeOptions, line 3\)$' let g:neomake_test_errors = [] diff --git a/bundle/neomake/tests/main.vader b/bundle/neomake/tests/main.vader index f1779615e..578c15e26 100644 --- a/bundle/neomake/tests/main.vader +++ b/bundle/neomake/tests/main.vader @@ -51,8 +51,10 @@ Include (Vim/Neovim behavior): vim_and_neovim_behavior.vader ~ Filetype specific Include (Asciidoc): ft_asciidoc.vader +Include (Clojure): ft_clojure.vader Include (Cs): ft_cs.vader Include (Css): ft_css.vader +Include (Dockerfile): ft_dockerfile.vader Include (Elixir): ft_elixir.vader Include (Elm): ft_elm.vader Include (Erlang): ft_erlang.vader diff --git a/bundle/neomake/tests/makers.vader b/bundle/neomake/tests/makers.vader index b5738562f..7b10b31a8 100644 --- a/bundle/neomake/tests/makers.vader +++ b/bundle/neomake/tests/makers.vader @@ -612,7 +612,7 @@ Execute (Makers: get_list_entries with exception): CallNeomake 1, [maker] AssertNeomakeMessage 'Error during get_list_entries for unnamed_maker: TEST_ERROR.' - AssertNeomakeMessage '\m^(in function .*)$', 3 + AssertNeomakeMessage '\m^(in .*handle_get_list_entries.*, line 1)$', 3 AssertEqual len(g:neomake_test_countschanged), 0 AssertEqual len(g:neomake_test_jobfinished), 1 @@ -646,7 +646,7 @@ Execute (Makers: process_json with invalid JSON): if has('nvim') AssertNeomakeMessage "Failed to decode JSON: Vim(return):E474: Unidentified byte: success (output: 'success').", 0 elseif exists('*json_decode') - AssertNeomakeMessage "Failed to decode JSON: Vim(return):E474: Invalid argument (output: 'success').", 0 + AssertNeomakeMessage '\vFailed to decode JSON: Vim\(return\):(E474|E491): .* \(output: ''success''\).', 0 else AssertNeomakeMessage "Failed to decode JSON: Failed to parse JSON input: invalid input (output: 'success').", 0 endif @@ -690,7 +690,7 @@ Execute (Makers: get_list_entries with sandbox exception): let jobinfo = neomake#Make({'enabled_makers': [maker]})[0] AssertNeomakeMessage '\mError during pcall: Vim(bprevious):E48: Not allowed in sandbox:' - AssertNeomakeMessage '\m^(in function .*)$', 3 + AssertNeomakeMessage '\m^(in .*_handle_get_list_entries.*)$', 3 AssertEqual len(g:neomake_test_countschanged), 0 AssertEqual len(g:neomake_test_jobfinished), 0 AssertEqual len(g:neomake_test_finished), 0 @@ -734,7 +734,7 @@ Execute (pcall aborts after 3 attempts per job): " Calls both makers initially. AssertNeomakeMessage 'maker1: getting entries via get_list_entries.' AssertNeomakeMessage '\mError during pcall: Vim(bprevious):E48: Not allowed in sandbox:', 3, jobs[0] - AssertNeomakeMessage '\m^(in function .*)$', 3 + AssertNeomakeMessage '\m^(in .*_handle_get_list_entries.*)$', 3 if has('timers') AssertNeomakeMessage '\V\^Retrying Timer event in 10ms', 3, jobs[0] else @@ -771,7 +771,7 @@ Execute (pcall aborts after 3 attempts per job): endif NeomakeTestsWaitForMessage 'Giving up handling Timer callbacks after 3 attempts. Please report this. See :messages for more information.', 0, jobs[0] - AssertNeomakeMessage '\m^(in function .*neomake#action_queue#add,.*)$', 3 + AssertNeomakeMessage '\m^(in .*neomake#action_queue#add,.*)$', 3 " Now maker2 gets processed (after giving up on maker1). if has('timers') @@ -786,7 +786,7 @@ Execute (pcall aborts after 3 attempts per job): AssertEqual map(getloclist(0), 'v:val.text'), ['error'] let vim_msgs = NeomakeTestsGetVimMessages() - Assert vim_msgs[-1] =~# '\vNeomake error in: function .*neomake#action_queue#add, line \d+' + Assert vim_msgs[-1] =~# '\vNeomake error in: .*neomake#action_queue#add, line \d+' AssertEqual len(vim_msgs), 1 bwipe diff --git a/bundle/neomake/tests/postprocess.vader b/bundle/neomake/tests/postprocess.vader index d8338ab3b..3d69ba1f3 100644 --- a/bundle/neomake/tests/postprocess.vader +++ b/bundle/neomake/tests/postprocess.vader @@ -405,7 +405,7 @@ Execute (Hook context gets cleaned on error in postprocess): NeomakeTestsWaitForFinishedJobs AssertNeomakeMessage 'Error during output processing for error-maker: error from postprocess.', 0 let vim_msgs = NeomakeTestsGetVimMessages() - Assert vim_msgs[-1] =~# 'Neomake error in: function .*', 'message found' + Assert vim_msgs[-1] =~# 'Neomake error in: .*_AddExprCallback.*, line 1' AssertEqual len(vim_msgs), 1 Assert !exists('g:neomake_postprocess_context'), 'Hook context was cleaned.' diff --git a/bundle/neomake/tests/processing.vader b/bundle/neomake/tests/processing.vader index 725cdb775..8c223bc16 100644 --- a/bundle/neomake/tests/processing.vader +++ b/bundle/neomake/tests/processing.vader @@ -363,6 +363,7 @@ Execute (Sleep in postprocess gets handled correctly): " Reproduces flakiness with https://github.com/neomake/neomake/issues/899. call neomake#statusline#ResetCounts() if NeomakeAsyncTestsSetup() + let uses_delayed_exit = !has('nvim-0.2.0') && !has('patch-8.2.0452') let s:postprocess_count = 0 function! s:postprocess(entry) dict let s:postprocess_count += 1 @@ -380,15 +381,16 @@ Execute (Sleep in postprocess gets handled correctly): let jobinfo = neomake#Make(1, [maker])[0] NeomakeTestsWaitForFinishedJobs AssertNeomakeMessage 'Processing 1 lines of output.', 3, jobinfo - if !has('nvim-0.2.0') + if uses_delayed_exit AssertNeomakeMessage 'exit (delayed): unnamed_maker: 0.', 3, jobinfo AssertNeomakeMessage '\VCalling User autocmd NeomakeCountsChanged with context:', 3 endif - if has('nvim-0.4.0') + if has('nvim-0.4.0') || (!has('nvim') && has('patch-8.2.0452') && !has('patch-8.2.0466')) " Neovim refactored event processing, so that the job's 2nd sleep finishes " before the one in the first postprocessing. " https://github.com/neovim/neovim/commit/d4938743e6aef04c83d02907048768d0d79aaa30 + " Vim showed the same behavior for a small patch range. let expected_final_countchanges = 2 AssertNeomakeMessage "output on stdout: ['out-22', 'out-333', ''].", 3, jobinfo AssertNeomakeMessage 'Processing 2 lines of output.', 3, jobinfo @@ -403,8 +405,10 @@ Execute (Sleep in postprocess gets handled correctly): AssertNeomakeMessage '\VCalling User autocmd NeomakeCountsChanged with context:', 3 endif - if !has('nvim-0.2.0') + if uses_delayed_exit AssertNeomakeMessage 'Trigger delayed exit.', 3, jobinfo + else + AssertNeomakeMessage 'exit: unnamed_maker: 0.', 3, jobinfo endif AssertEqual map(getloclist(0), 'v:val.text'), ['out-1', 'out-22', 'out-333'] diff --git a/bundle/neomake/tests/utils.vader b/bundle/neomake/tests/utils.vader index 3cf5581c7..70f06f4d6 100644 --- a/bundle/neomake/tests/utils.vader +++ b/bundle/neomake/tests/utils.vader @@ -728,7 +728,16 @@ Execute (neomake#utils#fnamemodify handles fugitive buffer): let bufname = bufname('%') let bufname_abs = fnamemodify(bufname, ':p') - Gedit + try + Gedit + catch /^Vim\%((\a\+)\)\=:E/ + NeomakeTestsSkip 'error with/through vim-fugitive (not b/c, e.g. neovim-0.1.7)' + bwipe + if exists('*VimFtpluginUndo') + delfunction VimFtpluginUndo + endif + return + endtry AssertNotEqual bufname, bufname('%') Assert bufname('%') =~# '^fugitive://' diff --git a/docs/bundle-plugins.md b/docs/bundle-plugins.md index fa5041ea0..d34014b2e 100644 --- a/docs/bundle-plugins.md +++ b/docs/bundle-plugins.md @@ -118,6 +118,7 @@ These plugins are changed based on a specific version of origin plugin. #### `checkers` layer - [ale@v3.3.0](https://github.com/dense-analysis/ale/tree/v3.3.0) +- [neomake@584f882b](https://github.com/neomake/neomake/tree/584f882b9f991245374e7e7d7d1f78bae90b7a35) #### `chinese` layer