diff --git a/etc/soft/nvim/+plugins/neomake/.circleci/config.yml b/etc/soft/nvim/+plugins/neomake/.circleci/config.yml deleted file mode 100644 index 7850eed..0000000 --- a/etc/soft/nvim/+plugins/neomake/.circleci/config.yml +++ /dev/null @@ -1,125 +0,0 @@ -version: 2 - -common: &common - docker: - - image: neomake/vims-for-tests:47@sha256:b540d84bb5ca445ee28625a5c2f72ce790908a23cd9e6f0b05150840ad15e8b3 - working_directory: ~/repo - steps: - - checkout - - run: - name: Run tests - command: | - cc-test-reporter before-build - make --keep-going testcoverage TEST_VIM=$TEST_VIM - - run: - name: Handle coverage - command: | - set -x - mkdir test-results - cp -a .coverage_covimerage test-results/.coverage_covimerage.$CIRCLE_BUILD_NUM - - # Upload to codecov, which handles this per job itself. - coverage xml - # -Z: exit with 1 in case of failures. - codecov -Z -X search -X gcov -X pycov -f coverage.xml \ - -n "$CIRCLE_JOB" -F "${CIRCLE_JOB%%-*}" -e CIRCLE_JOB - set +x - - persist_to_workspace: - root: . - paths: - - test-results/ - -jobs: - nvim-038: - <<: *common - environment: - TEST_VIM=/vim-build/bin/neovim-v0.3.8 - nvim-017: - <<: *common - environment: - TEST_VIM=/vim-build/bin/neovim-v0.1.7 - nvim-master: - <<: *common - environment: - TEST_VIM=/vim-build/bin/neovim-master - vim-master: - <<: *common - environment: - TEST_VIM=/vim-build/bin/vim-master - vim-81: - <<: *common - environment: - TEST_VIM=/vim-build/bin/vim81 - vim-80: - <<: *common - environment: - TEST_VIM=/vim-build/bin/vim80 - vim-74-xenial: - <<: *common - environment: - TEST_VIM=/vim-build/bin/vim74-xenial - vim-74-trusty: - <<: *common - environment: - TEST_VIM=/vim-build/bin/vim74-trusty - vim-73: - <<: *common - environment: - TEST_VIM=/vim-build/bin/vim73 - - checkqa: - <<: *common - steps: - - checkout - - run: make checkqa - - coverage: - <<: *common - steps: - # TODO: checkout only necessary for covimerage plugin?! - # Writing/using .coveragerc only might be enough. - - checkout - - attach_workspace: - at: /tmp/workspace - - run: - name: Upload global coverage results - command: | - set -x - cp -a /tmp/workspace/test-results/.coverage_covimerage.* . - - coverage combine - coverage xml - - # Coveralls. - # Only TRAVIS_JOB_ID is used by python-coveralls. - env -u COVERALLS_PARALLEL TRAVIS_JOB_ID=$CIRCLE_WORKFLOW_ID coveralls - - # Codeclimate. - cc-test-reporter after-build - set +x - -workflows: - version: 2 - test: - jobs: - - nvim-038 - - nvim-017 - - vim-81 - - vim-80 - - vim-74-xenial - - vim-74-trusty - - vim-73 - - nvim-master - - vim-master - - checkqa - - coverage: - requires: - - nvim-master - - nvim-038 - - nvim-017 - - vim-master - - vim-81 - - vim-80 - - vim-74-xenial - - vim-74-trusty - - vim-73 diff --git a/etc/soft/nvim/+plugins/neomake/.coveragerc b/etc/soft/nvim/+plugins/neomake/.coveragerc deleted file mode 100644 index 67e7b5e..0000000 --- a/etc/soft/nvim/+plugins/neomake/.coveragerc +++ /dev/null @@ -1,7 +0,0 @@ -[run] -plugins = covimerage -data_file = .coverage_covimerage - -[report] -include = autoload/*,plugin/*,syntax/*,tests/* -omit = tests/fixtures/vim/* diff --git a/etc/soft/nvim/+plugins/neomake/.dockerignore b/etc/soft/nvim/+plugins/neomake/.dockerignore deleted file mode 100644 index 72e8ffc..0000000 --- a/etc/soft/nvim/+plugins/neomake/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/etc/soft/nvim/+plugins/neomake/.vintrc.yaml b/etc/soft/nvim/+plugins/neomake/.vintrc.yaml deleted file mode 100644 index b371660..0000000 --- a/etc/soft/nvim/+plugins/neomake/.vintrc.yaml +++ /dev/null @@ -1,3 +0,0 @@ -policies: - ProhibitImplicitScopeVariable: - enabled: false diff --git a/etc/soft/nvim/+plugins/neomake/Dockerfile.tests b/etc/soft/nvim/+plugins/neomake/Dockerfile.tests deleted file mode 100644 index 309e7a6..0000000 --- a/etc/soft/nvim/+plugins/neomake/Dockerfile.tests +++ /dev/null @@ -1,63 +0,0 @@ -# From https://github.com/tweekmonster/vim-testbed. -FROM testbed/vim:16@sha256:ce0e3c0407e9af4c41868636199906e3c2a6c6f02b97f6bb3e2767aeba6d5c85 - -# Currently tested versions: -# - v7.3.429 (Ubuntu Precise, 12.04LTS) -# - v7.4.052 (Ubuntu Trusty, 14.04LTS) -# - v7.4.1689 (Ubuntu Xenial, 16.04LTS) -# - v8.0.586 (Updated Vim 8, https://vim.sourceforge.io/download.php) -# TODO: clean up names to make them usable as-is in CircleCI config. -# Uses fixed-profiling patch with vim81 (https://github.com/vim/vim/pull/2499). -RUN install_vim -tag v7.3.429 -name vim73 --with-features=huge -build \ - -tag v7.4.052 -name vim74-trusty --with-features=huge -build \ - -tag v7.4.1689 -name vim74-xenial --with-features=huge -build \ - -tag v8.0.0586 -name vim80 -py2 -build \ - -tag neovim:v0.1.7 -build \ - && rm -rf /vim-build/**/runtime/tutor -RUN install_vim -tag v8.1.0622 -name vim81 -build \ - -tag neovim:v0.3.8 -py3 -build \ - && rm -rf /vim-build/**/runtime/tutor - -ENV NEOMAKE_DOCKERFILE_UPDATE=2019-09-19 - -# Git master in a separate layer, since the above is meant to be stable. -RUN install_vim -tag master -build \ - -tag neovim:master -build \ - && rm -rf /vim-build/**/runtime/tutor - -# Install tools for running tests (busybox's grep does not have --line-number). -# openssh for CircleCI to improve Git checkout. -RUN apk --no-cache add bash curl grep make openssh-client - -# Codeclimate reporter. -RUN curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > /usr/local/bin/cc-test-reporter \ - && chmod +x /usr/local/bin/cc-test-reporter - -# Install dep plugins (test runner and those used during tests). -# Keeps git and installs ssh for CircleCI's checkout (and diffing for changed -# 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 \ - && 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 - -# Install covimerage and vint. -RUN apk --no-cache add python3 \ - && pip3 install -U pip \ - && pip3 install --no-cache-dir python-coveralls covimerage==0.1.7 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 - -RUN adduser -D -s /bin/bash neomake -USER neomake diff --git a/etc/soft/nvim/+plugins/neomake/Makefile b/etc/soft/nvim/+plugins/neomake/Makefile index b3ceee3..0b3a79d 100644 --- a/etc/soft/nvim/+plugins/neomake/Makefile +++ b/etc/soft/nvim/+plugins/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:=47 +DOCKER_TAG:=51 NEOMAKE_DOCKER_IMAGE?= DOCKER_IMAGE:=$(if $(NEOMAKE_DOCKER_IMAGE),$(NEOMAKE_DOCKER_IMAGE),$(DOCKER_REPO):$(DOCKER_TAG)) DOCKER_STREAMS:=-ti diff --git a/etc/soft/nvim/+plugins/neomake/README.md b/etc/soft/nvim/+plugins/neomake/README.md index a4a7f2c..f15bba4 100644 --- a/etc/soft/nvim/+plugins/neomake/README.md +++ b/etc/soft/nvim/+plugins/neomake/README.md @@ -48,7 +48,7 @@ call neomake#configure#automake('nw', 750) " When reading a buffer (after 1s), and when writing (no delay). call neomake#configure#automake('rw', 1000) " Full config: when writing or reading a buffer, and on changes in insert and -" normal mode (after 1s; no delay when writing). +" normal mode (after 500ms; no delay when writing). call neomake#configure#automake('nrwi', 500) ``` @@ -64,7 +64,7 @@ your laptop runs on battery (for MacOS or Linux): function! MyOnBattery() if has('macunix') return match(system('pmset -g batt'), "Now drawing from 'Battery Power'") != -1 - elsif has('unix') + elseif has('unix') return readfile('/sys/class/power_supply/AC/online') == ['0'] endif return 0 diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake.vim index 919e643..5ae5a0f 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake.vim @@ -28,7 +28,9 @@ endif " A list of references to keep when profiling. " Workaround for https://github.com/vim/vim/issues/2350, where " https://github.com/blueyed/vader.vim/commit/e66d91dea is not enough. -let s:hack_keep_refs_for_profiling = [] +if v:profiling + let s:hack_keep_refs_for_profiling = [] +endif " Can Neovim buffer output? let s:nvim_can_buffer_output = has('nvim-0.3.0') ? 1 : 0 @@ -206,8 +208,7 @@ function! neomake#CancelJob(job_id, ...) abort endif if has('nvim') try - call jobstop(job) - let ret = 1 + let ret = jobstop(job) catch /^Vim\%((\a\+)\)\=:\(E474\|E900\):/ call neomake#log#info(printf( \ 'jobstop failed: %s.', v:exception), jobinfo) @@ -505,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 @@ -842,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 @@ -1262,22 +1263,26 @@ function! s:Make(options) abort " @vimlint(EVL102, 1, l:job) for job in jobs let running_already = values(filter(copy(s:jobs), - \ 'v:val.maker == job.maker' + \ '(v:val.maker.name == job.maker.name' + \ .' || (!is_automake && get(v:val, "automake", 0)))' \ .' && v:val.bufnr == job.bufnr' \ .' && v:val.file_mode == job.file_mode' \ ." && !get(v:val, 'canceled')")) if !empty(running_already) - let jobinfo = running_already[0] - call neomake#log#info(printf( - \ 'Canceling already running job (%d.%d) for the same maker.', - \ jobinfo.make_id, jobinfo.id), {'make_id': make_id}) - call neomake#CancelJob(jobinfo.id, 1) + for running_job in running_already + call neomake#log#info(printf( + \ 'Canceling already running job (%d.%d) for the same maker.', + \ running_job.make_id, running_job.id), {'make_id': make_id}) + call neomake#CancelJob(running_job.id, 1) + endfor endif endfor endif " Update automake tick (used to skip unchanged buffers). - call neomake#configure#_update_automake_tick(bufnr, options.ft) + if is_automake + call neomake#configure#_update_automake_tick(bufnr, options.ft) + endif " Start all jobs in the queue (until serialized). let jobinfos = [] @@ -1903,7 +1908,12 @@ function! s:process_pending_output(jobinfo, lines, source, ...) abort return g:neomake#action_queue#processed endif endif - call add(a:jobinfo.pending_output, [a:lines, a:source]) + + if !a:0 + " Remember pending output, but only when not called via action queue. + call add(a:jobinfo.pending_output, [a:lines, a:source]) + endif + if index(neomake#action_queue#get_queued_actions(a:jobinfo), \ ['process_pending_output', retry_events]) == -1 return neomake#action_queue#add(retry_events, [s:function('s:process_pending_output'), [a:jobinfo, [], a:source, retry_events]]) @@ -2132,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 @@ -2185,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) @@ -2274,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]] @@ -2288,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) @@ -2296,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/etc/soft/nvim/+plugins/neomake/autoload/neomake/action_queue.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/action_queue.vim index 4fc3fc1..33b9652 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/action_queue.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/action_queue.vim @@ -131,6 +131,7 @@ function! s:process_action_queue(event) abort endfor call neomake#log#debug(printf('action queue: processing for %s (%d items).', \ a:event, len(q_for_this_event)), {'bufnr': bufnr('%'), 'winnr': winnr()}) + call neomake#log#indent(1) let processed = [] let removed = 0 @@ -228,6 +229,7 @@ function! s:process_action_queue(event) abort endfor call neomake#log#debug(printf('action queue: processed %d items.', \ len(processed)), {'bufnr': bufnr('%')}) + call neomake#log#indent(-1) call s:clean_action_queue_events() endfunction diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/compat.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/compat.vim index d558bf7..d90b822 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/compat.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/compat.vim @@ -153,7 +153,12 @@ function! neomake#compat#systemlist(cmd) abort endtry endif " @vimlint(EVL108, 0) - return systemlist(a:cmd) + try + return systemlist(a:cmd) + catch /^Vim\%((return)\)\=:E475/ + call neomake#log#exception(printf('systemlist error: %s.', v:exception)) + return '' + endtry endif if type(a:cmd) == type([]) diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/config.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/config.vim index 5f03cd1..54860fc 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/config.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/config.vim @@ -1,4 +1,4 @@ -" Config API. +" New-style config API. let g:neomake#config#_defaults = { \ 'maker_defaults': { @@ -11,9 +11,15 @@ lockvar g:neomake#config#_defaults let g:neomake#config#undefined = {} lockvar! g:neomake#config#undefined -" Resolve a:name (split on dots) and (optionally) init a:dict accordingly. -function! s:resolve_name(dict, name, init) abort +" Resolve a:name (list of keys or string (split on dots)) and (optionally) +" init a:dict accordingly. +function! s:resolve_name(dict, name, init, validate) abort let parts = type(a:name) == type([]) ? a:name : split(a:name, '\.') + if a:validate && parts[0] ==# 'neomake' + throw printf( + \ 'Neomake: config: "neomake" is not necessary with new-style config settings (%s).', + \ string(a:name)) + endif let c = a:dict for p in parts[0:-2] if !has_key(c, p) @@ -30,10 +36,11 @@ function! s:resolve_name(dict, name, init) abort return [c, parts[-1]] endfunction -" Get a:name (list of keys) from a:dict, using a:prefixes. +" Get a:name (list of keys or string (split on dots)) from a:dict, +" using a:prefixes. function! s:get(dict, parts, prefixes) abort for prefix in a:prefixes - let [c, k] = s:resolve_name(a:dict, prefix + a:parts[0:-1], 0) + let [c, k] = s:resolve_name(a:dict, prefix + a:parts[0:-1], 0, 1) if has_key(c, k) return [prefix, get(c, k)] endif @@ -141,14 +148,19 @@ function! neomake#config#get_with_source(name, ...) abort endfunction -" Set a:name in a:dict to a:value, after resolving it (split on dots). -function! s:set(dict, name, value) abort - let [c, k] = s:resolve_name(a:dict, a:name, 1) +" Set a:name (list or string (split on dots)) in a:dict to a:value. +function! s:set(dict, name, value, validate) abort + let [c, k] = s:resolve_name(a:dict, a:name, 1, a:validate) let c[k] = a:value return c endfunction -" Set a:name (resolved on dots) to a:value in the config. +" Set a:name to a:value in the config. +" a:name: +" - a list (e.g. `['ft', 'javascript.jsx', 'eslint', 'exe']`, or +" - a string (split on dots, e.g. `'ft.python.enabled_makers'`), where +" `b:` sets a buffer-local setting (via `neomake#config#set_buffer`). +" a:value: the value to set function! neomake#config#set(name, value) abort let parts = type(a:name) == type([]) ? a:name : split(a:name, '\.') if parts[0] =~# '^b:' @@ -158,10 +170,10 @@ function! neomake#config#set(name, value) abort if !has_key(g:, 'neomake') let g:neomake = {} endif - return s:set(g:neomake, parts, a:value) + return s:set(g:neomake, parts, a:value, 1) endfunction -" Set a:name (resolved on dots) to a:value for buffer a:bufnr. +" Set a:name (list or string (split on dots)) to a:value for buffer a:bufnr. function! neomake#config#set_buffer(bufnr, name, value) abort let bufnr = +a:bufnr let bneomake = getbufvar(bufnr, 'neomake') @@ -170,21 +182,21 @@ function! neomake#config#set_buffer(bufnr, name, value) abort let bneomake = {} call setbufvar(bufnr, 'neomake', bneomake) endif - return s:set(bneomake, a:name, a:value) + return s:set(bneomake, a:name, a:value, 1) endfunction -" Set a:name (resolved on dots) to a:value in a:scope. +" Set a:name (list or string (split on dots)) to a:value in a:scope. " This is meant for advanced usage, e.g.: " set_scope(t:, 'neomake.disabled', 1) function! neomake#config#set_dict(dict, name, value) abort - return s:set(a:dict, a:name, a:value) + return s:set(a:dict, a:name, a:value, 0) endfunction -" Unset a:name (resolved on dots). +" Unset a:name (list or string (split on dots)). " This is meant for advanced usage, e.g.: " unset_dict(t:, 'neomake.disabled', 1) function! neomake#config#unset_dict(dict, name) abort - let [c, k] = s:resolve_name(a:dict, a:name, 0) + let [c, k] = s:resolve_name(a:dict, a:name, 0, 0) if has_key(c, k) unlet c[k] endif diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/configure.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/configure.vim index 03053ff..c6feec5 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/configure.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/configure.vim @@ -150,6 +150,9 @@ endfunction function! s:neomake_do_automake(context) abort let bufnr = +a:context.bufnr + if s:skip_for_running_jobs(bufnr) + return + endif if !get(a:context, '_via_timer_cb') && a:context.delay if exists('s:timer_by_bufnr[bufnr]') @@ -398,48 +401,54 @@ function! s:parse_events_from_args(config, string_or_dict_config, ...) abort endif else " Map string config to events dict. - let modes = a:string_or_dict_config + let modes = split(a:string_or_dict_config, '\zs') let events = {} let default_with_delay = {} - " Insert mode. - if modes =~# 'i' - if exists('##TextChangedI') && has('timers') - let events['TextChangedI'] = default_with_delay - else - call s:debug_log('using CursorHoldI instead of TextChangedI') - let events['CursorHoldI'] = (delay != 0 ? {'delay': 0} : {}) - endif - endif - " Normal mode. - if modes =~# 'n' - if exists('##TextChanged') && has('timers') - let events['TextChanged'] = default_with_delay - if !has_key(events, 'TextChangedI') - " Run when leaving insert mode, since only TextChangedI would be triggered - " for `ciw` etc. - let events['InsertLeave'] = default_with_delay + let unknown = [] + for mode in modes + " Insert mode. + if mode ==# 'i' + if exists('##TextChangedI') && has('timers') + let events['TextChangedI'] = default_with_delay + else + call s:debug_log('using CursorHoldI instead of TextChangedI') + let events['CursorHoldI'] = (delay != 0 ? {'delay': 0} : {}) + endif + " Normal mode. + elseif mode ==# 'n' + if exists('##TextChanged') && has('timers') + let events['TextChanged'] = default_with_delay + if !has_key(events, 'TextChangedI') + " Run when leaving insert mode, since only TextChangedI would be triggered + " for `ciw` etc. + let events['InsertLeave'] = default_with_delay + endif + else + call s:debug_log('using CursorHold instead of TextChanged') + let events['CursorHold'] = (delay != 0 ? {'delay': 0} : {}) + let events['InsertLeave'] = (delay != 0 ? {'delay': 0} : {}) endif + " On writes. + elseif mode ==# 'w' + let events['BufWritePost'] = (delay != 0 ? {'delay': 0} : {}) + " On reads. + elseif mode ==# 'r' + let events['BufWinEnter'] = {} + let events['FileType'] = {} + + " When a file was changed outside of Vim. + " TODO: test + let events['FileChangedShellPost'] = {} + " XXX: FileType might work better, at least when wanting to skip filetypes. + " let events['FileType'] = {'delay': a:0 > 1 ? delay : 0} else - call s:debug_log('using CursorHold instead of TextChanged') - let events['CursorHold'] = (delay != 0 ? {'delay': 0} : {}) - let events['InsertLeave'] = (delay != 0 ? {'delay': 0} : {}) + let unknown += [mode] endif - endif - " On writes. - if modes =~# 'w' - let events['BufWritePost'] = (delay != 0 ? {'delay': 0} : {}) - endif - " On reads. - if modes =~# 'r' - let events['BufWinEnter'] = {} - let events['FileType'] = {} - - " When a file was changed outside of Vim. - " TODO: test - let events['FileChangedShellPost'] = {} - " XXX: FileType might work better, at least when wanting to skip filetypes. - " let events['FileType'] = {'delay': a:0 > 1 ? delay : 0} + endfor + if !empty(unknown) + call neomake#log#error(printf('unknown modes in string automake config (%s): %s.', + \ a:string_or_dict_config, join(unknown, ', '))) endif endif @@ -569,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', []) @@ -592,6 +601,20 @@ function! s:maybe_reconfigure_buffer(bufnr) abort endif endfunction +function! s:skip_for_running_jobs(bufnr) abort + let running_jobs = values(filter(copy(neomake#_get_s().jobs), + \ 'v:val.bufnr == a:bufnr' + \ .' && v:val.file_mode == 1' + \ .' && !get(v:val, "automake", 0)' + \ ." && !get(v:val, 'canceled')")) + if !empty(running_jobs) + call s:debug_log(printf('skipping for already running jobs: %s', + \ string(map(running_jobs, 'v:val.as_string()'))), + \ {'bufnr': a:bufnr}) + return 1 + endif +endfunction + " Called from autocommands. function! s:neomake_automake(event, bufnr) abort let disabled = neomake#config#get_with_source('disabled', 0) @@ -628,6 +651,10 @@ function! s:neomake_automake(event, bufnr) abort return endif + if s:skip_for_running_jobs(bufnr) + return + endif + call s:debug_log(printf('automake for event %s', a:event), {'bufnr': bufnr}) let config = s:configured_buffers[bufnr].events_config if !has_key(config, a:event) diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/list.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/list.vim index 120b665..8c9ccde 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/list.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/list.vim @@ -18,19 +18,26 @@ let s:needs_to_replace_qf_for_lwindow = has('patch-7.4.379') " @vimlint(EVL108, 0) let s:needs_to_init_qf_for_lwindow = !has('patch-8.1.0622') -function! neomake#list#ListForMake(make_info) abort - let type = a:make_info.options.file_mode ? 'loclist' : 'quickfix' - let list = neomake#list#List(type) - let list.make_info = a:make_info - if type ==# 'loclist' - let info = get(w:, '_neomake_info', {}) - let info['loclist'] = list - let w:_neomake_info = info +function! s:save_list_ref(list) abort + if a:list.type ==# 'loclist' + for d in [w:, b:] + let info = get(d, '_neomake_info', {}) + let info['loclist'] = a:list + let d['_neomake_info'] = info + endfor else let info = get(g:, '_neomake_info', {}) - let info['qflist'] = list + let info['qflist'] = a:list let g:_neomake_info = info endif +endfunction + +function! neomake#list#ListForMake(make_info) abort + let file_mode = a:make_info.options.file_mode + let type = file_mode ? 'loclist' : 'quickfix' + let list = neomake#list#List(type) + let list.make_info = a:make_info + call s:save_list_ref(list) return list endfunction @@ -330,17 +337,27 @@ function! s:base_list._get_loclist_win(...) abort let loclist_win = 0 let make_id = self.make_info.make_id " NOTE: prefers using 0 for when winid is not supported with - " setloclist() yet (vim74-xenial). + " setloclist() yet (vim74-xenial, patch-7.4.1895). if index(get(w:, 'neomake_make_ids', []), make_id) == -1 - if has_key(self.make_info.options, 'winid') + if has_key(self.make_info.options, 'winid') && has('patch-7.4.1895') + " Can only use it with getloclist after patch-7.4.1895. let loclist_win = self.make_info.options.winid else let [t, w] = neomake#core#get_tabwin_for_makeid(make_id) if [t, w] == [-1, -1] - if a:0 && a:1 - return -1 + for w in range(1, winnr('$')) + if get(get(get(neomake#compat#getwinvar(w, '_neomake_info', {}), 'loclist', {}), 'make_info', {}), 'make_id') == make_id + let loclist_win = w + break + endif + endfor + if loclist_win == 0 + if a:0 && a:1 + return -1 + endif + throw printf('Neomake: could not find location list for make_id %d.', make_id) endif - throw printf('Neomake: could not find location list for make_id %d.', make_id) + return loclist_win endif if t != tabpagenr() if a:0 && a:1 @@ -868,13 +885,25 @@ function! s:base_list.add_lines_with_efm(lines, jobinfo) dict abort return entries endfunction -" Get the current location or quickfix list. -function! neomake#list#get() abort - let winnr = winnr() - let win_info = neomake#compat#getwinvar(winnr, '_neomake_info', {}) +" Get location list from current window, or via buffer. +function! s:get_loclist() abort + let win_info = neomake#compat#getwinvar(winnr(), '_neomake_info', {}) if has_key(win_info, 'loclist') return win_info['loclist'] endif + let buf_info = neomake#compat#getbufvar(bufnr('%'), '_neomake_info', {}) + if has_key(buf_info, 'loclist') + return buf_info['loclist'] + endif + return {} +endfunction + +" Get the current location or quickfix list. +function! neomake#list#get() abort + let loclist = s:get_loclist() + if !empty(loclist) + return loclist + endif let info = get(g:, '_neomake_info', {}) if has_key(info, 'qflist') return info['qflist'] @@ -882,18 +911,16 @@ function! neomake#list#get() abort return {} endfunction -function! neomake#list#get_loclist(...) abort - let winnr = a:0 ? a:1 : winnr() - let info = neomake#compat#getwinvar(winnr, '_neomake_info', {}) - if !has_key(info, 'loclist') +function! neomake#list#get_loclist() abort + let loclist = s:get_loclist() + if empty(loclist) " Create a new list, not bound to a job. call neomake#log#debug('Creating new List object.') - let list = neomake#list#List('loclist') - call list.add_entries(getloclist(winnr)) - let info['loclist'] = list - call setwinvar(winnr, '_neomake_info', info) + let loclist = neomake#list#List('loclist') + call loclist.add_entries(getloclist(0)) + call s:save_list_ref(loclist) endif - return info['loclist'] + return loclist endfunction " TODO: save project-maker quickfix list. diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/log.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/log.vim index fc0c85d..2a3c253 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/log.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/log.vim @@ -3,6 +3,8 @@ let s:name_to_level = {'error': 0, 'warning': 1, 'verbose': 2, 'debug': 3} let s:short_level_to_name = {0: 'E', 1: 'W', 2: 'V', 3: 'D'} let s:is_testing = exists('g:neomake_test_messages') let s:pid = getpid() +let s:indent = 0 +let s:indent_str = '' if !exists('s:last_msg_ts') let s:last_msg_ts = neomake#compat#reltimefloat() @@ -38,6 +40,7 @@ function! s:log(level, msg, ...) abort return endif + let msg = s:indent_str . a:msg if a:0 if has_key(a:1, 'options') let context = copy(a:1.options) @@ -50,9 +53,7 @@ function! s:log(level, msg, ...) abort \ get(context, 'id', '-'), \ get(context, 'bufnr', get(context, 'file_mode', 0) ? '?' : '-'), \ get(context, 'winnr', winnr()), - \ a:msg) - else - let msg = a:msg + \ msg) endif " Use Vader's log for messages during tests. @@ -123,6 +124,14 @@ function! s:log(level, msg, ...) abort " @vimlint(EVL104, 0, l:timediff) endfunction +function! neomake#log#indent(offset) abort + if a:offset < 0 && s:indent <= 0 + throw 'invalid offset (already 0)' + endif + let s:indent += a:offset + let s:indent_str = repeat(' ', s:indent*2) +endfunction + function! neomake#log#error(...) abort call call('s:log', [0] + a:000) endfunction diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/ansible.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/ansible.vim index a1a001f..df3ccc7 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/ansible.vim +++ b/etc/soft/nvim/+plugins/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/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/clojure.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/clojure.vim new file mode 100644 index 0000000..314e8b8 --- /dev/null +++ b/etc/soft/nvim/+plugins/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/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/go.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/go.vim index 93e2004..10c0b9b 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/go.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/go.vim @@ -2,9 +2,7 @@ function! neomake#makers#ft#go#EnabledMakers() abort let makers = ['go'] - if executable('revive') - call add(makers, 'revive') - elseif executable('golangci-lint') + if executable('golangci-lint') call add(makers, 'golangci_lint') elseif executable('gometalinter') call add(makers, 'gometalinter') @@ -14,16 +12,6 @@ function! neomake#makers#ft#go#EnabledMakers() abort return makers endfunction -function! neomake#makers#ft#go#revive() abort - return { - \ 'exe': 'revive', - \ 'cwd': '%:h', - \ 'errorformat': - \ '%f:%l:%c: %m,' . - \ '%f:%l: %m' - \ } -endfunction - function! neomake#makers#ft#go#go() abort return { \ 'args': [ diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/javascriptreact.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/javascriptreact.vim new file mode 100644 index 0000000..d8b20c9 --- /dev/null +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/javascriptreact.vim @@ -0,0 +1,17 @@ +function! neomake#makers#ft#javascriptreact#SupersetOf() abort + return 'javascript' +endfunction + +function! neomake#makers#ft#javascriptreact#EnabledMakers() abort + return ['jshint', executable('eslint_d') ? 'eslint_d' : 'eslint'] +endfunction + +function! neomake#makers#ft#javascriptreact#javascriptreacthint() abort + return neomake#makers#ft#javascript#jshint() +endfunction + +function! neomake#makers#ft#javascriptreact#stylelint() abort + return neomake#makers#ft#css#stylelint() +endfunction + +" vim: ts=4 sw=4 et diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/markdown.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/markdown.vim index 1146488..bc37fb3 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/markdown.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/markdown.vim @@ -28,7 +28,11 @@ endfunction function! neomake#makers#ft#markdown#markdownlint() abort return { - \ 'errorformat': '%f: %l: %m' + \ 'errorformat': + \ '%f:%l:%c %m,' . + \ '%f: %l: %c: %m,' . + \ '%f:%l %m,' . + \ '%f: %l: %m' \ } endfunction diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/python.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/python.vim index 4099800..244c9ec 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/python.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/python.vim @@ -6,14 +6,14 @@ if !exists('s:compile_script') endif function! neomake#makers#ft#python#EnabledMakers() abort - let makers = ['pycodestyle', 'frosted'] + let makers = ['python', 'frosted'] if executable('pylama') call add(makers, 'pylama') else if executable('flake8') call add(makers, 'flake8') else - call extend(makers, ['mypy', 'pyflakes', 'pydocstyle']) + call extend(makers, ['pyflakes', 'pycodestyle', 'pydocstyle']) endif call add(makers, 'pylint') " Last because it is the slowest endif @@ -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%.%#', \ } @@ -363,7 +365,7 @@ endfunction function! neomake#makers#ft#python#python() abort return { \ 'args': [s:compile_script], - \ 'errorformat': '%E%f:%l:%c: %m', + \ 'errorformat': '%E%f:%l:%c: E: %m,%W%f:%l: W: %m', \ 'serialize': 1, \ 'serialize_abort_on_error': 1, \ 'output_stream': 'stdout', @@ -395,6 +397,7 @@ function! neomake#makers#ft#python#mypy() abort " ignore_missing_imports cannot be disabled in a config then though let args = [ \ '--show-column-numbers', + \ '--show-error-codes', \ '--check-untyped-defs', \ '--ignore-missing-imports', \ ] @@ -416,7 +419,9 @@ function! neomake#makers#ft#python#mypy() abort \ '%I%f:%l:%c: note: %m,' . \ '%E%f:%l: error: %m,' . \ '%W%f:%l: warning: %m,' . - \ '%I%f:%l: note: %m', + \ '%I%f:%l: note: %m,' . + \ '%-GSuccess%.%#,' . + \ '%-GFound%.%#,' \ } function! maker.InitForJob(jobinfo) abort let maker = deepcopy(self) @@ -425,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) diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/python/compile.py b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/python/compile.py index d211673..a8ff164 100755 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/python/compile.py +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/python/compile.py @@ -1,14 +1,49 @@ #!/usr/bin/env python from __future__ import print_function -from sys import argv, exit +import warnings +import sys -if len(argv) != 2: - exit(64) -try: - compile(open(argv[1]).read(), argv[1], 'exec', 0, 1) -except SyntaxError as err: - print('%s:%s:%s: %s' % (err.filename, err.lineno, err.offset, err.msg)) - exit(1) +def main(argv): + if len(argv) != 2: + exit(64) + + with open(argv[1]) as fp: + contents = fp.read() + + exitcode = 0 + syntax_err = None + with warnings.catch_warnings(record=True) as wc: + try: + compile(contents, argv[1], "exec", 0, 1) + except SyntaxError as exc: + syntax_err = exc + + # Output any warnings (caught during `compile`). + # This could/should maybe only handle SyntaxWarnings? + for wm in wc: + print( + "%s:%s: W: %s (%s)" + % (wm.filename, wm.lineno, wm.message, wm.category.__name__) + ) + exitcode |= 2 + + # Output any SyntaxError. + if syntax_err: + print( + "%s:%s:%s: E: %s" + % ( + syntax_err.filename, + syntax_err.lineno, + syntax_err.offset, + syntax_err.msg, + ) + ) + exitcode |= 1 + return exitcode + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/rst.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/rst.vim index a7874ec..9d589fb 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/rst.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/rst.vim @@ -77,7 +77,7 @@ function! neomake#makers#ft#rst#sphinx() abort \ 'args': ['-n', '-E', '-q', '-N', '-b', 'dummy', srcdir, s:sphinx_cache], \ 'append_file': 0, \ 'errorformat': - \ '%f:%l: %tARNING: %m,' . + \ '%A%f:%l: %tARNING: %m,' . \ '%EWARNING: %f:%l: (SEVER%t/4) %m,' . \ '%EWARNING: %f:%l: (%tRROR/3) %m,' . \ '%EWARNING: %f:%l: (%tARNING/2) %m,' . diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/terraform.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/terraform.vim new file mode 100644 index 0000000..015c074 --- /dev/null +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/terraform.vim @@ -0,0 +1,139 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#terraform#EnabledMakers() abort + return ['tfsec', 'tflint', 'terrascan', 'tfvalidate'] +endfunction + +function! neomake#makers#ft#terraform#terrascan() abort + return { + \ 'exe' : 'terrascan', + \ 'append_file': 0, + \ 'cwd': '%:p:h', + \ 'args': ['scan', '--use-colors', 'f', '--output', 'json', '--log-level', 'fatal'], + \ 'process_json': function('neomake#makers#ft#terraform#ProcessTerrascan') + \ } +endfunction + +function! neomake#makers#ft#terraform#tfvalidate() abort + return { + \ 'exe' : 'terraform', + \ 'append_file': 0, + \ 'cwd': '%:p:h', + \ 'args': ['validate', '-no-color', '-json'], + \ 'process_json': function('neomake#makers#ft#terraform#ProcessTfvalidateJSON') + \ } +endfunction + +function! neomake#makers#ft#terraform#tflint() abort + return { + \ 'exe' : 'tflint', + \ 'append_file': 0, + \ 'cwd': '%:p:h', + \ 'args': ['--no-color', '--format', 'json'], + \ 'process_json': function('neomake#makers#ft#terraform#ProcessTflintJSON') + \ } +endfunction + +function! neomake#makers#ft#terraform#tfsec() abort + return { + \ 'exe' : 'tfsec', + \ 'append_file': 0, + \ 'cwd': '%:p:h', + \ 'args': ['--format', 'json', '.'], + \ 'process_json': function('neomake#makers#ft#terraform#ProcessTfsecJSON') + \ } +endfunction + +function! neomake#makers#ft#terraform#ProcessTflintJSON(context) abort + let entries = [] + for line in a:context['json']['errors'] + " filename:line,col1-col2: message + let l:msg = split(line['message'], ':') + let l:filename = l:msg[0] + let l:position = split(l:msg[1], ',') + let l:line = l:position[0] + let l:col1 = split(l:position[1], '-')[0] + let l:col2 = split(l:position[1], '-')[1] + + let l:message = l:msg[2] + + let entry = { + \ 'filename': l:filename, + \ 'text': l:message, + \ 'lnum': l:line, + \ 'col': l:col1, + \ 'type': "e", + \ } + call add(entries, entry) + endfor + return entries +endfunction + +function! neomake#makers#ft#terraform#ProcessTfvalidateJSON(context) abort + let entries = [] + + if (!has_key(a:context, 'json') || !has_key(a:context['json'], 'diagnostics')) + return [] + endif + + for line in a:context['json']['diagnostics'] + let l:f = has_key(line, 'range') ? line['range']['filename'] : expand('%:t') + let l:l = has_key(line, 'range') ? line['range']['start']['line'] : 1 + let l:c = has_key(line, 'range') ? line['range']['start']['column'] : 1 + + let entry = { + \ 'filename': l:f, + \ 'text': line['summary'] . (has_key(line, 'detail') ? ': ' . line['detail'] : ''), + \ 'lnum': l:l, + \ 'col': l:c, + \ 'type': line['severity'], + \ } + call add(entries, entry) + endfor + return entries +endfunction + +function! neomake#makers#ft#terraform#ProcessTfsecJSON(context) abort + let entries = [] + + if (type(a:context['json']['results']) != v:t_list) + return [] + endif + + for line in a:context['json']['results'] + let entry = { + \ 'filename': fnamemodify(line['location']['filename'], ':t'), + \ 'text': line['rule_id'] . ': ' . line['description'] . ' ' . line['link'], + \ 'lnum': line['location']['start_line'], + \ 'col': 1, + \ 'type': line['severity'], + \ } + call add(entries, entry) + endfor + return entries +endfunction + +function! neomake#makers#ft#terraform#ProcessTerrascan(context) abort + let entries = [] + + if (!has_key(a:context, 'json') || !has_key(a:context['json'], 'results')) + return [] + endif + + if (type(a:context['json']['results']['violations']) != v:t_list) + return [] + endif + + for line in a:context['json']['results']['violations'] + let entry = { + \ 'filename': fnamemodify(line['file'], ':t'), + \ 'text': line['rule_id'] . ': ' . line['description'], + \ 'lnum': line['line'], + \ 'col': 1, + \ 'type': get({ 'HIGH': 'error', 'MEDIUM': 'warning', 'LOW': 'warning' }, line['severity'], 'info'), + \ } + call add(entries, entry) + endfor + return entries +endfunction + diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/typescriptreact.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/typescriptreact.vim new file mode 100644 index 0000000..d558b59 --- /dev/null +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/makers/ft/typescriptreact.vim @@ -0,0 +1,15 @@ +function! neomake#makers#ft#typescriptreact#SupersetOf() abort + return 'typescript' +endfunction + +function! neomake#makers#ft#typescriptreact#EnabledMakers() abort + return ['tsc', 'tslint'] +endfunction + +function! neomake#makers#ft#typescriptreact#tsc() abort + let config = neomake#makers#ft#typescript#tsc() + let config.args = config.args + ['--jsx', 'preserve'] + return config +endfunction + +" vim: ts=4 sw=4 et diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/postprocess.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/postprocess.vim index d92a897..6e7928d 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/postprocess.vim +++ b/etc/soft/nvim/+plugins/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/etc/soft/nvim/+plugins/neomake/autoload/neomake/statusline.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/statusline.vim index 54d5a68..97f1c53 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/statusline.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/statusline.vim @@ -411,14 +411,14 @@ function! neomake#statusline#DefineHighlights() abort endfor " Default highlight for type counts. - exe 'hi NeomakeStatColorDefault cterm=NONE ctermfg=white ctermbg=blue' + exe 'hi default NeomakeStatColorDefault cterm=NONE ctermfg=white ctermbg=blue' hi link NeomakeStatColorQuickfixDefault NeomakeStatColorDefault " Specific highlights for types. Only used if defined. - exe 'hi NeomakeStatColorTypeE cterm=NONE ctermfg=white ctermbg=red' + exe 'hi default NeomakeStatColorTypeE cterm=NONE ctermfg=white ctermbg=red' hi link NeomakeStatColorQuickfixTypeE NeomakeStatColorTypeE - exe 'hi NeomakeStatColorTypeW cterm=NONE ctermfg=white ctermbg=yellow' + exe 'hi default NeomakeStatColorTypeW cterm=NONE ctermfg=white ctermbg=yellow' hi link NeomakeStatColorQuickfixTypeW NeomakeStatColorTypeW endfunction diff --git a/etc/soft/nvim/+plugins/neomake/autoload/neomake/utils.vim b/etc/soft/nvim/+plugins/neomake/autoload/neomake/utils.vim index 9a360eb..69e2ad4 100644 --- a/etc/soft/nvim/+plugins/neomake/autoload/neomake/utils.vim +++ b/etc/soft/nvim/+plugins/neomake/autoload/neomake/utils.vim @@ -396,6 +396,17 @@ function! neomake#utils#redir(cmd) abort return neomake_redir endfunction +function! s:exparg_subst(bufnr, s, mods) abort + let s = a:s + let mods = a:mods + if s[1:1] ==# '<' + " Convert "%<" to "%:r". + let mods = ':r' . mods + let s = s[0] . s[2:] + endif + return expand(substitute(s, '^%'.a:mods, neomake#utils#fnamemodify(a:bufnr, mods), '')) +endfunction + function! neomake#utils#ExpandArgs(args, jobinfo) abort if has_key(a:jobinfo, 'tempfile') let fname = a:jobinfo.tempfile @@ -414,8 +425,8 @@ function! neomake#utils#ExpandArgs(args, jobinfo) abort " % must be followed with an expansion keyword let ret = map(ret, \ 'substitute(v:val, ' - \ . '''\(\%(\\\@' + endtry + return a:obj +endfunction + function! neomake#utils#fix_self_ref(obj, ...) abort - if type(a:obj) != type({}) - if type(a:obj) == type([]) + let obj_type = type(a:obj) + if has('nvim') && obj_type == 2 + return s:fix_nvim_partial(a:obj) + endif + + if obj_type != type({}) + if obj_type == type([]) return map(copy(a:obj), 'neomake#utils#fix_self_ref(v:val)') endif return a:obj endif - let obj = copy(a:obj) + let obj = a:obj for k in keys(obj) if a:0 let self_ref = filter(copy(a:1), 'v:val[1][0] is obj[k]') if !empty(self_ref) + if obj is a:obj + let obj = copy(a:obj) + endif let obj[k] = printf('', self_ref[0][0], self_ref[0][1][1]) continue endif endif if type(obj[k]) == type({}) - let obj[k] = neomake#utils#fix_self_ref(obj[k], a:0 ? a:1 + [[len(a:1)+1, [a:obj, k]]] : [[1, [a:obj, k]]]) - elseif has('nvim') - " Ensure that it can be used as a string. - " Ref: https://github.com/neovim/neovim/issues/7432 - try - call string(obj[k]) - catch /^Vim(call):E724:/ - let obj[k] = '' - endtry + let fixed = neomake#utils#fix_self_ref(get(obj, k), a:0 ? a:1 + [[len(a:1)+1, [a:obj, k]]] : [[1, [a:obj, k]]]) + if fixed != obj[k] + if obj is a:obj + let obj = copy(a:obj) + endif + let obj[k] = fixed + endif + elseif has('nvim') && type(obj[k]) == 2 + let l:Fixed_partial = s:fix_nvim_partial(get(obj, k)) + if l:Fixed_partial != get(obj, k) + if obj is a:obj + let obj = copy(a:obj) + endif + let obj[k] = l:Fixed_partial + endif endif endfor return obj diff --git a/etc/soft/nvim/+plugins/neomake/contrib/vim-checks b/etc/soft/nvim/+plugins/neomake/contrib/vim-checks index c4791d7..fd99271 100755 --- a/etc/soft/nvim/+plugins/neomake/contrib/vim-checks +++ b/etc/soft/nvim/+plugins/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/etc/soft/nvim/+plugins/neomake/doc/neomake.txt b/etc/soft/nvim/+plugins/neomake/doc/neomake.txt index c24702c..c2692a9 100644 --- a/etc/soft/nvim/+plugins/neomake/doc/neomake.txt +++ b/etc/soft/nvim/+plugins/neomake/doc/neomake.txt @@ -45,7 +45,7 @@ dispatch. :Neomake! [makers] Run a make command with no file as input. If no makers are specified, the default top-level makers will be used. If no default top-level makers exist, - |'makeprg'| will be used. + 'makeprg' will be used. *:NeomakeSh* :NeomakeSh {command} Run {command} in a shell (according to 'shell'). The @@ -108,7 +108,7 @@ status gets displayed. 3. Configuration *neomake-configuration* If you just want an easy way to run |:make| asynchronously, you're all set. -Just set your |'makeprg'| and |'errorformat'| as usual, and run |:Neomake!|. +Just set your 'makeprg' and 'errorformat' as usual, and run |:Neomake!|. If you want more, read on. 3.1 Automaking *neomake-automake* @@ -403,7 +403,7 @@ feedback as early as possible, you can set this to `0`. You can override this for a maker using e.g.: > let g:neomake_ft_test_maker_buffer_output = 0 < -Your results will appear earlier, but if the |'errorformat'| is meant to parse +Your results will appear earlier, but if the 'errorformat' is meant to parse multiline output this will likely cause issues (depending on how the maker flushes its output). @@ -413,7 +413,7 @@ To change the default for all makers use: > *neomake-makers-remove_invalid_entries* Default: 0 This option filters invalid entries from makers from the location/quickfix -list (i.e. entries that do not match the |'errorformat'|, and that would show +list (i.e. entries that do not match the 'errorformat', and that would show up with a `||` prefix in the location/quickfix list): > let g:neomake_ft_maker_remove_invalid_entries = 1 < @@ -616,7 +616,7 @@ Each log level includes all the levels before it. Defaults to 1. -|'verbose'| gets added to this setting, so you can use |:verbose| to increase +'verbose' gets added to this setting, so you can use |:verbose| to increase the verbosity temporarily: > :3verb Neomake < @@ -631,7 +631,7 @@ append, but overwrite the file with each message. *g:neomake_place_signs* This setting enables the placement of signs next to items from the location and quickfix list (i.e. errors/warnings etc recognized from the -|'errorformat'|). Defaults to 1. +'errorformat'). Defaults to 1. *g:neomake_error_sign* *g:neomake_warning_sign* @@ -715,7 +715,7 @@ You can define them yourself: > *g:airline#extensions#neomake#enabled* Shows warning and error counts returned by |neomake#statusline#LoclistCounts| -in the warning and error sections of the vim-airline |'statusline'|. Defaults +in the warning and error sections of the vim-airline 'statusline'. Defaults to 1. ============================================================================== @@ -906,7 +906,7 @@ You can use the following format placeholders: *neomake#statusline#LoclistStatus* *neomake#statusline#QflistStatus* -These functions return text for your |'statusline'|. They each take an +These functions return text for your 'statusline'. They each take an optional first argument, which is the prefix text that will be shown if errors or warnings exist. Example usage: > set statusline+=\ %#ErrorMsg#%{neomake#statusline#QflistStatus('qf:\ ')} diff --git a/etc/soft/nvim/+plugins/neomake/tests/automake.vader b/etc/soft/nvim/+plugins/neomake/tests/automake.vader index e69196b..eb234a4 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/automake.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/automake.vader @@ -82,6 +82,12 @@ Execute (short setup: 'r'): call neomake#configure#automake('r') call NeomakeTestsAssertAutomakeAutocommands(['BufWinEnter', 'FileChangedShellPost', 'FileType']) +Execute (short setup: reports unknown modes): + call neomake#configure#automake('z') + AssertNeomakeMessage 'unknown modes in string automake config (z): z.', 0 + call neomake#configure#automake('Xwz') + AssertNeomakeMessage 'unknown modes in string automake config (Xwz): X, z.', 0 + Execute (setup: short vs. long): call neomake#configure#automake('w', 500) let short_config = copy(g:neomake) @@ -1541,3 +1547,85 @@ Execute (BufWritePost via doautocmd is handled (e.g. vim-fugitive)): update AssertEqual len(g:neomake_test_jobfinished), 2 bwipe! + +Execute (automake: skip automake with manual run (in init)): + if NeomakeAsyncTestsSetup() + call neomake#configure#automake({'BufWritePost': {'delay': 100}}) + + new + let bufnr = bufnr('%') + let g:neomake_test_enabledmakers = [g:entry_maker] + set filetype=neomake_tests + + call neomake#Make(1, [g:sleep_maker]) + doautocmd BufWritePost + AssertNeomakeMessage '\Vautomake: skipping for already running jobs: [''Job \d\+: sleep-maker''].', 3 + + NeomakeTestsWaitForFinishedJobs + let valid = has('patch-8.0.0580') + AssertEqualQf getloclist(0), [ + \ {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': valid, + \ 'vcol': 0, 'nr': -1, 'type': 'W', 'text': 'slept'}] + + " Next automake triggers run (not having updated tick). + doautocmd BufWritePost + AssertNeomakeMessage 'automake: automake for event BufWritePost.', 3 + NeomakeTestsWaitForNextFinishedJob + AssertEqualQf getloclist(0), [ + \ {'lnum': 1, 'bufnr': bufnr, 'col': 0, 'pattern': '', 'valid': 1, + \ 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'error'}] + bwipe! + endif + +Execute (automake: skip automake with manual run (in callback)): + if NeomakeAsyncTestsSetup() + call neomake#configure#automake({'BufWritePost': {'delay': 10}}) + + new + let bufnr = bufnr('%') + let g:neomake_test_enabledmakers = [g:entry_maker] + set filetype=neomake_tests + + doautocmd BufWritePost + AssertNeomakeMessage 'automake: automake for event BufWritePost.', 3 + call neomake#Make(1, [g:sleep_maker]) + + NeomakeTestsWaitForFinishedJobs + AssertNeomakeMessage '\Vautomake: skipping for already running jobs: [''Job \d\+: sleep-maker''].', 3 + let valid = has('patch-8.0.0580') + AssertEqualQf getloclist(0), [ + \ {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': valid, + \ 'vcol': 0, 'nr': -1, 'type': 'W', 'text': 'slept'}] + + " Next automake triggers run (not having updated tick). + doautocmd BufWritePost + AssertNeomakeMessage 'automake: automake for event BufWritePost.', 3 + NeomakeTestsWaitForNextFinishedJob + AssertEqualQf getloclist(0), [ + \ {'lnum': 1, 'bufnr': bufnr, 'col': 0, 'pattern': '', 'valid': 1, + \ 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'error'}] + bwipe! + endif + +Execute (automake: abort automake with manual run): + if NeomakeAsyncTestsSetup() + call neomake#configure#automake({'BufWritePost': {'delay': 100}}) + + new + let bufnr = bufnr('%') + let g:neomake_test_enabledmakers = [g:sleep_maker] + set filetype=neomake_tests + + doautocmd BufWritePost + AssertNeomakeMessage 'automake: automake for event BufWritePost.' + NeomakeTestsWaitForMessage 'Running makers: sleep-maker (auto).' + + call neomake#Make(1, [g:entry_maker]) + let expected_loclist = [ + \ {'lnum': 1, 'bufnr': bufnr, 'col': 0, 'pattern': '', 'valid': 1, + \ 'vcol': 0, 'nr': -1, 'type': 'E', 'text': 'error'}] + AssertEqualQf getloclist(0), expected_loclist + NeomakeTestsWaitForFinishedJobs + AssertEqualQf getloclist(0), expected_loclist + bwipe! + endif diff --git a/etc/soft/nvim/+plugins/neomake/tests/cancellation.vader b/etc/soft/nvim/+plugins/neomake/tests/cancellation.vader index 2c3f59a..09616c7 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/cancellation.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/cancellation.vader @@ -51,7 +51,9 @@ Execute (neomake#CancelJob with invalid job): AssertNeomakeMessageAbsent 'exit: job not found: '.job_id.'.' AssertNeomakeMessage '\v^Stopping \w+ job: .+\.$', 3, jobinfo if has('nvim') - AssertNeomakeMessage '\vjobstop failed: Vim\(call\):E900: Invalid (job|channel) id.', 2, jobinfo + if !has('nvim-0.5') + AssertNeomakeMessage '\vjobstop failed: Vim\(let\):E900: Invalid (job|channel) id.', 2, jobinfo + endif else AssertNeomakeMessage 'job_stop: job was not running anymore.', 2, jobinfo endif @@ -113,7 +115,9 @@ Execute (neomake#CancelJob! with invalid job): AssertNeomakeMessageAbsent 'exit: job not found: '.job_id.'.' AssertNeomakeMessage '\v^Stopping \w+ job: .+\.$', 3, jobinfo if has('nvim') - AssertNeomakeMessage '\vjobstop failed: Vim\(call\):E900: Invalid (job|channel) id.', 2, jobinfo + if !has('nvim-0.5') + AssertNeomakeMessage '\vjobstop failed: Vim\(let\):E900: Invalid (job|channel) id.', 2, jobinfo + endif endif AssertEqual neomake#GetJobs(), [] diff --git a/etc/soft/nvim/+plugins/neomake/tests/compat.vader b/etc/soft/nvim/+plugins/neomake/tests/compat.vader index 9ec9742..1ee47ce 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/compat.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/compat.vader @@ -26,8 +26,12 @@ Execute (neomake#compat#systemlist): let r = neomake#compat#systemlist(['echo 1']) if has('nvim') AssertEqual r, '' + if has('nvim-0.5.0') + 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 @@ -43,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 @@ -52,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 diff --git a/etc/soft/nvim/+plugins/neomake/tests/config.vader b/etc/soft/nvim/+plugins/neomake/tests/config.vader index 3b827c8..ea26708 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/config.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/config.vader @@ -114,6 +114,7 @@ Execute (neomake#config#get with b: prefix, no default and bufnr context): bwipe Execute (neomake#config#set): + Save g:neomake let config = neomake#config#set('foo', 'bar') AssertEqual config, {'foo': 'bar'} AssertEqual g:neomake, {'foo': 'bar'} @@ -122,6 +123,17 @@ Execute (neomake#config#set): call neomake#config#set('automake.ignore_filetypes', ['startify']) AssertEqual g:neomake, {'automake': {'ignore_filetypes': ['startify']}} +Execute (neomake#config#set: warn about unused "neomake" key): + Save g:neomake + AssertThrows call neomake#config#set('b:neomake.foo.bar', ['1']) + AssertEqual g:vader_exception, 'Neomake: config: "neomake" is not necessary with new-style config settings ([''neomake'', ''foo'', ''bar'']).' + + AssertThrows call neomake#config#set('neomake.foo.bar', ['2']) + AssertEqual g:vader_exception, 'Neomake: config: "neomake" is not necessary with new-style config settings ([''neomake'', ''foo'', ''bar'']).' + + AssertEqual b:neomake, {} + AssertEqual g:neomake, {} + Execute (neomake#config#set_buffer): new let bufnr = bufnr('%') diff --git a/etc/soft/nvim/+plugins/neomake/tests/customqf.vader b/etc/soft/nvim/+plugins/neomake/tests/customqf.vader index e5d2035..b57358f 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/customqf.vader +++ b/etc/soft/nvim/+plugins/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/etc/soft/nvim/+plugins/neomake/tests/fixtures/errors.py b/etc/soft/nvim/+plugins/neomake/tests/fixtures/errors.py index 538e1bc..c361281 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/fixtures/errors.py +++ b/etc/soft/nvim/+plugins/neomake/tests/fixtures/errors.py @@ -1,2 +1 @@ -if not this or foo bar: - meh +invalid_syntax( diff --git a/etc/soft/nvim/+plugins/neomake/tests/ft_clojure.vader b/etc/soft/nvim/+plugins/neomake/tests/ft_clojure.vader new file mode 100644 index 0000000..f7e934c --- /dev/null +++ b/etc/soft/nvim/+plugins/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/etc/soft/nvim/+plugins/neomake/tests/ft_markdown.vader b/etc/soft/nvim/+plugins/neomake/tests/ft_markdown.vader index ddf9a48..148d644 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/ft_markdown.vader +++ b/etc/soft/nvim/+plugins/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/etc/soft/nvim/+plugins/neomake/tests/ft_python.vader b/etc/soft/nvim/+plugins/neomake/tests/ft_python.vader index 3fd86f0..99319bc 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/ft_python.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/ft_python.vader @@ -10,13 +10,13 @@ Execute (python: errorformat): AssertEqualQf getloclist(0), [{ \ 'lnum': 1, \ 'bufnr': bufnr('%'), - \ 'col': 22, + \ 'col': 16, \ 'valid': 1, \ 'vcol': 0, \ 'nr': -1, \ 'type': 'E', \ 'pattern': '', - \ 'text': 'invalid syntax'}] + \ 'text': 'unexpected EOF while parsing'}] bwipe Execute (python: pylama: errorformat): @@ -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) @@ -376,6 +413,7 @@ Execute (python: mypy: handles --py2): call g:NeomakeTestsSetPATH('') let base_args = [ \ '--show-column-numbers', + \ '--show-error-codes', \ '--check-untyped-defs', \ '--ignore-missing-imports' \ ] @@ -403,13 +441,14 @@ Execute (python: mypy): let base_args = [ \ '--show-column-numbers', + \ '--show-error-codes', \ '--check-untyped-defs', \ '--ignore-missing-imports' \ ] 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'} diff --git a/etc/soft/nvim/+plugins/neomake/tests/ft_rst.vader b/etc/soft/nvim/+plugins/neomake/tests/ft_rst.vader index c06a98b..f8770d4 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/ft_rst.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/ft_rst.vader @@ -130,3 +130,21 @@ Execute (rst: sphinx: handles docutils warnings and adds first additional line): \ ] exe 'bwipe' unlisted_bufnr bwipe + +Execute (rst: sphinx: errorformat): + new + file foo.rst + let b:neomake = {'sphinx': {'source_dir': 'sphinx_source_dir'}} + + let maker = NeomakeTestsGetMakerWithOutput(neomake#makers#ft#rst#sphinx(), [], [ + \ 'foo.rst:20: WARNING: Problems with "include" directive path:', + \ "InputError: [Errno 2] No such file or directory: '_include.rst'.", + \ ]) + CallNeomake 1, [maker] + + AssertEqualQf getloclist(0), [ + \ {'lnum': 20, 'bufnr': bufnr('%'), 'col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, + \ 'nr': -1, 'type': 'W', + \ 'text': 'Problems with "include" directive path: InputError: [Errno 2] No such file or directory: ''_include.rst''.'}, + \ ] + bwipe diff --git a/etc/soft/nvim/+plugins/neomake/tests/hooks-queue.vader b/etc/soft/nvim/+plugins/neomake/tests/hooks-queue.vader index 0fec532..d419469 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/hooks-queue.vader +++ b/etc/soft/nvim/+plugins/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/etc/soft/nvim/+plugins/neomake/tests/include/init.vim b/etc/soft/nvim/+plugins/neomake/tests/include/init.vim index f3405bf..04119b0 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/include/init.vim +++ b/etc/soft/nvim/+plugins/neomake/tests/include/init.vim @@ -395,6 +395,7 @@ function! s:IncMakerInitForJobs(_jobinfo) dict let cmd .= 'echo b'.g:neomake_test_inc_maker_counter.' '.g:neomake_test_inc_maker_counter.':'.i.': buf: '.shellescape(bufname('%')).'; ' endfor let self.args = s:shell_argv[1:] + [cmd] + let self.name = 'incmaker_' . g:neomake_test_inc_maker_counter endfunction let g:neomake_test_inc_maker = { \ 'name': 'incmaker', @@ -419,17 +420,38 @@ function! NeomakeTestsGetVimMessages() return reverse(msgs[0 : idx-1]) endfunction -function! NeomakeTestsGetMakerWithOutput(base_maker, lines_or_file) abort - if type(a:lines_or_file) == type([]) - let output_file = tempname() - call writefile(a:lines_or_file, output_file) +function! NeomakeTestsGetMakerWithOutput(base_maker, stdout, ...) abort + if type(a:stdout) == type([]) + let stdout_file = tempname() + call writefile(a:stdout, stdout_file) else - let output_file = a:lines_or_file + let stdout_file = a:stdout endif let maker = copy(a:base_maker) - let maker.exe = 'cat' - let maker.args = [output_file] + + if a:0 + let stderr = a:1 + if type(stderr) == type([]) + let stderr_file = tempname() + call writefile(stderr, stderr_file) + else + let stderr_file = a:1 + endif + if a:0 > 1 + let exitcode = a:2 + else + let exitcode = 0 + endif + let maker.exe = &shell + let maker.args = [&shellcmdflag, printf( + \ 'cat %s; cat %s >&2; exit %d', + \ fnameescape(stdout_file), fnameescape(stderr_file), exitcode)] + else + let maker.exe = 'cat' + let maker.args = [stdout_file] + endif + let maker.append_file = 0 let maker.name = printf('%s-mocked', get(a:base_maker, 'name', 'unnamed_maker')) return maker @@ -574,7 +596,7 @@ function! s:After() endtry call add(errors, error) elseif bufname(winbufnr(1)) !=# '[Vader-workbench]' - call add(errors, 'Vader-workbench has been renamed: '.bufname(winbufnr(1))) + call add(errors, 'Vader-workbench has been renamed (too many bwipe commands?): '.bufname(winbufnr(1))) endif " Ensure that all w:neomake_make_ids lists have been removed. @@ -667,7 +689,7 @@ function! s:After() call map(errors, "printf('%d. %s', v:key+1, v:val)") throw len(errors)." error(s) in teardown:\n".join(errors, "\n") else - Log printf('NOTE: %d error(s) in teardown.', len(errors)) + Log printf('NOTE: %d error(s) in teardown (ignored with failing test).', len(errors)) endif endif echom '' diff --git a/etc/soft/nvim/+plugins/neomake/tests/integration.vader b/etc/soft/nvim/+plugins/neomake/tests/integration.vader index 060c0e3..7ede11f 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/integration.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/integration.vader @@ -630,7 +630,9 @@ Execute (Neomake#Make: error with failing job via jobstart/argv): AssertNeomakeMessage "Starting [string]: doesnotexist." endif - if has('nvim-0.1.8') + if has('nvim-0.5') + AssertNeomakeMessage "Failed to start Neovim job: ['doesnotexist']: Vim(let):E475: Invalid value for argument cmd: 'doesnotexist' is not executable.", 0 + elseif has('nvim-0.1.8') AssertNeomakeMessage "Failed to start Neovim job: Executable not found: ['doesnotexist'].", 0 elseif has('nvim') AssertNeomakeMessage 'Failed to start Neovim job: [''doesnotexist'']: ' @@ -669,7 +671,9 @@ Execute (Neomake#Make: error with failing job via jobstart/argv + true): AssertNeomakeMessage "Starting [string]: doesnotexist." endif - if has('nvim-0.1.8') + if has('nvim-0.5') + AssertNeomakeMessage "Failed to start Neovim job: ['doesnotexist']: Vim(let):E475: Invalid value for argument cmd: 'doesnotexist' is not executable.", 0 + elseif has('nvim-0.1.8') AssertNeomakeMessage "Failed to start Neovim job: Executable not found: ['doesnotexist'].", 0 elseif has('nvim') AssertNeomakeMessage 'Failed to start Neovim job: [''doesnotexist'']: ' diff --git a/etc/soft/nvim/+plugins/neomake/tests/isolated/logging.vader b/etc/soft/nvim/+plugins/neomake/tests/isolated/logging.vader index 28478fc..19d8145 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/isolated/logging.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/isolated/logging.vader @@ -110,6 +110,30 @@ Execute (reltime_lastmsg: cover all cases): NeomakeTestsSkip 'only with patch-7.4.503' endif +Execute (neomake#log#indent): + Save g:neomake_verbose + + AssertThrows call neomake#log#indent(-1) + AssertEqual g:vader_exception, 'invalid offset (already 0)' + + call neomake#log#indent(1) + call NeomakeTestsSetVimMessagesMarker() + call neomake#log#error('error1.') + call neomake#log#error('error2.', {'bufnr': 1}) + AssertEqual NeomakeTestsGetVimMessages(), ['Neomake: error1.', 'Neomake: error2.'] + + let g:neomake_verbose = 2 + call NeomakeTestsSetVimMessagesMarker() + call neomake#log#error('error1.') + call neomake#log#error('error2.', {'bufnr': 1}) + AssertEqual NeomakeTestsGetVimMessages(), ['Neomake: error1.', 'Neomake: error2.'] + + let g:neomake_verbose = 3 + call NeomakeTestsSetVimMessagesMarker() + call neomake#log#debug('debug1.') + call neomake#log#debug('debug2.', {'bufnr': 1}) + AssertEqual NeomakeTestsGetVimMessages(), ['Neomake: debug1.', 'Neomake: [-.-:1:1] debug2.'] + " Restore if not profiling. if !v:profiling runtime autoload/neomake/utils.vim diff --git a/etc/soft/nvim/+plugins/neomake/tests/list.vader b/etc/soft/nvim/+plugins/neomake/tests/list.vader index 8a1b942..0099baf 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/list.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/list.vader @@ -39,12 +39,28 @@ Execute (List: basic: loclist): CallNeomake 1, [maker] AssertNeomakeMessage 'Adding 2 list entries.', 3 + let list1 = neomake#list#get() + + " Location list window can be found after make run has finished. + " (via last_make_id without patch-7.4.1895). + if has('patch-7.4.1895') + AssertEqual list1._get_loclist_win(), win_getid() + else + AssertEqual list1._get_loclist_win(), winnr() + endif + AssertEqual getpos('.'), [0, 1, 1, 0] NeomakeNextLoclist AssertEqual getpos('.'), [0, 2, 3, 0] NeomakePrevLoclist AssertEqual getpos('.'), [0, 1, 1, 0] AssertNeomakeMessageAbsent 'Creating new List object.' + + " Knows about loclist in new window for the same buffer. + split + AssertNeomakeMessageAbsent 'Creating new List object.' + AssertEqual neomake#list#get(), list1 + bwipe! Execute (List: basic: quickfix): @@ -170,6 +186,7 @@ Execute (neomake#list#next): \ [[1, 'idx1'], [1, 'idx2'], [2, 'idx3'], [3, 'idx4'], [1, 'idx5']], \ 'Sane lnums' + Assert !exists('b:_neomake_info.loclist') Assert !exists('w:_neomake_info.loclist') AssertEqual getpos('.'), [0, 1, 1, 0] @@ -257,7 +274,14 @@ Execute (list: error handling): " Uses winid from make_info. let list.make_info.options.winid = 1234 - AssertEqual list._get_fn_args('get'), [['getloclist', [1234]]] + if has('patch-7.4.1895') + AssertEqual list._get_fn_args('get'), [['getloclist', [1234]]] + else + let g:list = list + AssertThrows call g:list._get_fn_args('get') + AssertEqual g:vader_exception, 'Neomake: could not find location list for make_id -42.' + unlet g:list + endif unlet list.make_info.options.winid AssertEqual list._get_loclist_win(1), -1 diff --git a/etc/soft/nvim/+plugins/neomake/tests/log.vader b/etc/soft/nvim/+plugins/neomake/tests/log.vader index 34848f3..fa42658 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/log.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/log.vader @@ -11,7 +11,8 @@ Execute (neomake#log#debug writes to logfile always): else let logfile_msg = readfile(g:neomake_logfile)[0] endif - Assert logfile_msg =~# '\v\d\d:\d\d:\d\d \d+ \[D \] msg2.$', 'unexpected msg: '.logfile_msg + " Also allow for small delay (on CI). + Assert logfile_msg =~# '\v\d\d:\d\d:\d\d \d+ \[D (\+0.0\d| )\] msg2.$', 'unexpected msg: '.logfile_msg call neomake#log#debug('msg3.') sleep 10m @@ -36,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/etc/soft/nvim/+plugins/neomake/tests/main.vader b/etc/soft/nvim/+plugins/neomake/tests/main.vader index f177961..51463cc 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/main.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/main.vader @@ -51,6 +51,7 @@ 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 (Elixir): ft_elixir.vader diff --git a/etc/soft/nvim/+plugins/neomake/tests/makers.vader b/etc/soft/nvim/+plugins/neomake/tests/makers.vader index b573856..7b10b31 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/makers.vader +++ b/etc/soft/nvim/+plugins/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/etc/soft/nvim/+plugins/neomake/tests/postprocess.vader b/etc/soft/nvim/+plugins/neomake/tests/postprocess.vader index d8338ab..3d69ba1 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/postprocess.vader +++ b/etc/soft/nvim/+plugins/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/etc/soft/nvim/+plugins/neomake/tests/processing.vader b/etc/soft/nvim/+plugins/neomake/tests/processing.vader index 1b546f1..8c223bc 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/processing.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/processing.vader @@ -239,6 +239,7 @@ Execute (Location list is only cleared in same window on success): Execute (Output is only processed in normal/insert mode (from loclist)): if NeomakeAsyncTestsSetup() new + file file_sleep_efm call neomake#Make(1, [g:sleep_efm_maker]) lopen AssertEqual &buftype, 'quickfix' @@ -253,16 +254,19 @@ Execute (Output is only processed in normal/insert mode (from loclist)): AssertEqual mode(), 'n' doautocmd CursorHold AssertEqual getloclist(0), [] + AssertNeomakeMessage 'action queue: processing for CursorHold (1 items).', 3 + AssertNeomakeMessage 'action queue: calling process_pending_output.', 3 + AssertNeomakeMessage 'Skipped pending job output for another buffer (current='.bufnr('%').').', 3 + wincmd p AssertNeomakeMessage 'Processing 3 lines of output.' AssertEqual map(getloclist(0), 'v:val.text'), ['error message', 'warning', 'error2'] + AssertNeomakeMessage 'Processed 1 pending outputs.', 3 - " NOTE: needs cache busting above ("bust_cache"). let ll_bufnr = bufnr('file_sleep_efm') AssertEqual map(getloclist(0), 'v:val.bufnr'), [ll_bufnr, ll_bufnr, ll_bufnr] lclose bwipe - bwipe file_sleep_efm endif Execute (Output gets not processed while in loclist): @@ -359,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 @@ -376,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 @@ -399,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'] @@ -425,7 +433,7 @@ Execute (Pending output with restarted job when not in normal/insert mode (locli exe "norm! \" call neomake#Make(1, [g:neomake_test_inc_maker]) - " Maker is different because of args. + " Maker is different because of name. AssertNeomakeMessageAbsent 'Canceling already running job (' \ .make_id.'.'.jobinfo1.id.') for the same maker.', 2, {'make_id': make_id+1} AssertNeomakeMessageAbsent 'Removing already finished job', 3, jobinfo1 @@ -460,7 +468,7 @@ Execute (Pending output with restarted job when not in normal/insert mode (quick exe "norm! \" call neomake#Make(0, [g:neomake_test_inc_maker]) - " Maker is different because of args. + " Maker is different because of name. AssertNeomakeMessageAbsent 'Canceling already running job (' \ .make_id.'.'.jobinfo1.id.') for the same maker.', 2, {'make_id': make_id+1} AssertNeomakeMessageAbsent 'Removing already finished job', 3, jobinfo1 @@ -621,6 +629,8 @@ Execute (Already running job gets restarted in case of exception): AssertEqual len(neomake#GetJobs()), 1, 'The job has not been cleaned because of the exception.' " Restart, which should work directly. + let maker.some_new_key = 1 + Assert values(neomake#_get_s().jobs)[0].maker != maker call neomake#Make(1, [maker]) AssertNeomakeMessage printf('Canceling already running job (%d.%d) for the same maker.', diff --git a/etc/soft/nvim/+plugins/neomake/tests/signs.vader b/etc/soft/nvim/+plugins/neomake/tests/signs.vader index 6e31660..ec3d8c9 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/signs.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/signs.vader @@ -37,6 +37,7 @@ Execute (neomake#signs#RedefineErrorSign): call neomake#signs#Reset(bufnr, 'file') call neomake#signs#CleanAllOldSigns('file') AssertNeomakeMessage 'Cleaning 1 old signs.', 3 + AssertEqual neomake#signs#by_lnum(bufnr), {} bwipe Execute (Placing signs in project mode): @@ -56,6 +57,7 @@ Execute (Placing signs in project mode): call neomake#signs#Reset(bufnr, 'project') call neomake#signs#CleanAllOldSigns('project') AssertNeomakeMessage 'Cleaning 1 old signs.', 3, {'bufnr': bufnr} + AssertEqual neomake#signs#by_lnum(bufnr), {} exe 'bwipe' bufnr Execute (Signs are not re-used / wiped across modes): diff --git a/etc/soft/nvim/+plugins/neomake/tests/statusline.vader b/etc/soft/nvim/+plugins/neomake/tests/statusline.vader index 7f50140..3a09a9c 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/statusline.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/statusline.vader @@ -219,3 +219,12 @@ Execute (neomake#statusline#get: use_highlights_with_defaults): AssertEqual neomake#statusline#get(bufnr, {'use_highlights_with_defaults': 1}), \ '%#NeomakeStatusGood#✓%#NeomakeStatReset#' bwipe + +Execute (statusline: uses user-configured highlights): + new + let bufnr = bufnr('%') + hi NeomakeStatColorTypeW ctermfg=Black ctermbg=Black cterm=none + let orig = neomake#utils#redir('hi NeomakeStatColorTypeW') + CallNeomake 1, [g:success_entry_maker] + AssertEqual neomake#utils#redir('hi NeomakeStatColorTypeW'), orig + bwipe diff --git a/etc/soft/nvim/+plugins/neomake/tests/utils.vader b/etc/soft/nvim/+plugins/neomake/tests/utils.vader index 93921e1..3cf5581 100644 --- a/etc/soft/nvim/+plugins/neomake/tests/utils.vader +++ b/etc/soft/nvim/+plugins/neomake/tests/utils.vader @@ -736,6 +736,13 @@ Execute (neomake#utils#fnamemodify handles fugitive buffer): AssertEqual neomake#utils#fnamemodify(bufnr('%'), ':p'), bufname_abs AssertEqual neomake#utils#fnamemodify(bufnr('%'), ':p:h'), fnamemodify(bufname_abs, ':h') + " ExpandArgs handles fugitive buffers also. + let jobinfo = {'bufnr': bufnr('%')} + AssertEqual neomake#utils#ExpandArgs(['%'], jobinfo), [bufname] + AssertEqual neomake#utils#ExpandArgs(['%:e'], jobinfo), ['vim'] + " NOTE: uses absolute path, although bufname is relative. + AssertEqual neomake#utils#ExpandArgs(['%<'], jobinfo), [fnamemodify(bufname, ':p:r')] + exe 'lcd '.fnamemodify(tempname(), ':h') AssertEqual neomake#utils#fnamemodify(bufnr('%'), ''), bufname_abs AssertEqual neomake#utils#fnamemodify(bufnr('%'), ':p'), bufname_abs @@ -821,8 +828,7 @@ Execute (neomake#utils#fix_self_ref): \ 'foo': 1, \ 'bar': {}} let fixed = neomake#utils#fix_self_ref(obj) - Assert fixed isnot obj, 'copies the obj' - AssertEqual fixed, obj + Assert fixed is obj, 'does not copy unnecessarily' let obj.bar.self_ref = obj let exception = '' @@ -862,13 +868,33 @@ Execute (neomake#utils#fix_self_ref): \ }} Execute (neomake#utils#fix_self_ref with obj.func = obj.func): + let string_displays_partial = has('patch-7.4.1608') let maker = {} function maker.args() endfunction + let str_func = string(get(maker, 'args')) let maker.args = maker.args let repr = neomake#utils#fix_self_ref(maker) AssertEqual keys(repr), ['args'] - call string(repr) + + if string_displays_partial + if has('nvim') + AssertEqual string(repr), "{'args': ''}" + AssertEqual neomake#utils#fix_self_ref(maker.args), '' + AssertEqual neomake#utils#fix_self_ref(get(maker, 'args')), '' + else + let str_number = matchstr(str_func, '\d\+') + AssertEqual string(repr), printf( + \ "{'args': function('%d', {...})}", + \ str_number) + AssertEqual neomake#utils#fix_self_ref(maker.args), maker.args + AssertEqual neomake#utils#fix_self_ref(get(maker, 'args')), maker.args + endif + else + AssertEqual string(repr), printf("{'args': %s}", str_func) + AssertEqual neomake#utils#fix_self_ref(maker.args), maker.args + endif + Execute (neomake#utils#fix_self_ref: handles lists): let maker = {} @@ -879,6 +905,22 @@ Execute (neomake#utils#fix_self_ref: handles lists): AssertEqual keys(repr[0]), ['args'] call string(repr) +Execute (neomake#utils#fix_self_ref: uses get(obj, k)): + let make_info = {} + let entries_list = {} + let entries_list.make_info = make_info + let make_info.entries_list = entries_list + AssertEqual neomake#utils#fix_self_ref(make_info), { + \ 'entries_list': {'make_info': ''}} + + " This used to trigger "unrepresentable object" in Neovim. + " (https://github.com/neovim/neovim/issues/7432) + function entries_list.func() abort dict + endfunction + AssertEqual string(neomake#utils#fix_self_ref(make_info)), + \ printf("{'entries_list': {'func': %s, 'make_info': ''}}", + \ string(get(entries_list, 'func'))) + Execute (neomake#utils#Stringify: uses neomake#utils#fix_self_ref): let maker = {} function maker.args()