Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,54 @@
All notable changes to the Vim Plugin Manager will be documented in this file.


## [Unreleased]

### Performance
- `git#collect_status_local`: worst case reduced from 9 git subprocesses
per module to 7 (6 when a branch is declared in `.gitmodules`). The
branch now comes from the mtime-cached `parse_modules` result instead
of a per-module `git config -f` call, and the sequential
upstream/show-ref cascade collapses into one `git for-each-ref` call
(same selection order; its sha listing also replaces the remote
`rev-parse` for `origin/*` refs - verbatim `.gitmodules` branches keep
their `rev-parse` since they resolve local refs). The direct
`.gitmodules` read is kept when `parse_modules` is unavailable so
hostile branch values still reach `sanitize_branch` (#9 parity).
`tests/perf.vader` pins the subprocess budget as a permanent
regression guard.
- Health check rendering: the 200-line sequential function is now a
table of check Funcrefs; per-check report order and messages are
unchanged (pinned by a characterization test).

### Changed
- Log format: debug/trace entries carry a single level prefix
(`| comp | EXTERNAL | DEBUG:msg`) instead of the doubled
`DEBUG:comp:DEBUG:msg`. The `code` field was previously always
`EXTERNAL` for those entries; the level prefix is the marker.
- `check` opts: the documented `force` option is now real - it always
fetches and leaves the update-check cache untouched, so the next
startup check re-fetches (TTL skipped). It was previously accepted
but ignored.

### Removed
- Dead code: never-read async job state fields (`id`, `started`,
`queued`), the unused `g:plugin_manager_periodic_timer` write, four
sidebar highlight keywords no code emits (`Synced`, `Skipped`,
`timed out`, `Stashing changes`), the `pending` UI glyph key, the
legacy numeric status branch of `ui#get_status_glyph` (all callers
pass keywords), the unreachable replace path of `ui#update_sidebar`,
the list branch of `ui#log_detail`, `ftdetect/pluginmanager.vim` (only
matched a literal file named `PluginManager`) and the `Makefile.test`
forwarding shim.
- Internal refactors with zero behavior change: shared userinfo
sanitizer, shared log level writer, shared update-path helpers
(`s:handle_pin`, `s:skip_status`, `s:pull_cmd`), redundant
`get_config` re-read in backup. Deliberately NOT unified: the
single-plugin and all-plugins update flows (real behavior differences:
pull-step UI text, stash bookkeeping, helptags/auto-commit scope,
batch finalize).


## [2.2.10] - 2026-09-20

### Removed
Expand Down
8 changes: 3 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ The project is organized into several key components:
- `remote.vim`: Remote repository management.

6. **Utility Files**
- `ftdetect/pluginmanager.vim`: Defines filetype detection rules.
- `ftplugin/pluginmanager.vim`: Sets buffer configuration and key mappings.
- `syntax/pluginmanager.vim`: Defines syntax highlighting for the plugin interface.

Expand Down Expand Up @@ -452,7 +451,7 @@ To run vint locally (requires Python):

```bash
pip install vim-vint
vint -e autoload/ plugin/ ftplugin/ ftdetect/ syntax/
vint -e autoload/ plugin/ ftplugin/ syntax/
```

When adding new features or fixing bugs:
Expand Down Expand Up @@ -517,8 +516,6 @@ Understanding the project's complete structure will help you contribute effectiv
│ └── update.vim # Plugin update
├── doc/ # Vim help documentation
│ └── plugin_manager.txt # :help plugin-manager
├── ftdetect/ # Filetype detection
│ └── pluginmanager.vim # Registers the pluginmanager filetype
├── ftplugin/ # Filetype plugin
│ └── pluginmanager.vim # Buffer settings and key mappings
├── plugin/ # Plugin entry point
Expand All @@ -535,6 +532,8 @@ Understanding the project's complete structure will help you contribute effectiv
│ ├── declare.vader # Declarative Plugin/Begin/End blocks
│ ├── dispatch.vader # Command dispatch and tab completion
│ ├── gitmodules.vader # .gitmodules parsing and module lookup
│ ├── health.vader # Health check statuses (characterized)
│ ├── perf.vader # collect_status_local subprocess budget
│ ├── remove.vader # Plugin removal and ambiguity guard
│ ├── restore.vader # Submodule restoration from .gitmodules
│ ├── status.vader # Status block rendering
Expand All @@ -547,7 +546,6 @@ Understanding the project's complete structure will help you contribute effectiv
├── CONTRIBUTING.md # Contribution guidelines (this file)
├── LICENSE # MIT license
├── Makefile # Build, test, and version management
├── Makefile.test # Compatibility shim (delegates to Makefile)
└── README.md # Project overview and usage
```

Expand Down
5 changes: 0 additions & 5 deletions autoload/plugin_manager/async.vim
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,12 @@ function! plugin_manager#async#start_job(cmd, opts) abort
" Promote opts.callback to the top-level 'callback' key so that
" s:process_job_completion can find it without having to dig into opts.
let s:jobs[l:job_id] = {
\ 'id': l:job_id,
\ 'cmd': a:cmd,
\ 'opts': a:opts,
\ 'output': '',
\ 'errors': '',
\ 'status': -1,
\ 'started': 0,
\ 'finished': 0,
\ 'queued': localtime(),
\ 'job': v:null,
\ 'timeout_timer': 0,
\ 'exited': 0,
Expand Down Expand Up @@ -105,8 +102,6 @@ function! s:spawn_job(job_id) abort
endif

let l:job = s:jobs[a:job_id]
let l:opts = l:job.opts
let l:job.started = localtime()

let s:active_count += 1

Expand Down
1 change: 0 additions & 1 deletion autoload/plugin_manager/cmd/backup.vim
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ function! s:backup_vimrc_file() abort
" Copy vimrc
if plugin_manager#core#util#file_exists(l:vimrc_path)
let l:copy_cmd = 'cp ' . shellescape(l:vimrc_path) . ' ' . shellescape(l:local_vimrc)
let l:vim_dir = plugin_manager#core#util#get_config('vim_dir', '')
let l:copy_result = plugin_manager#core#util#run_in_dir(l:copy_cmd, '')
if !l:copy_result.success
call plugin_manager#ui#log_detail('backup',
Expand Down
13 changes: 10 additions & 3 deletions autoload/plugin_manager/cmd/check.vim
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
" @param opts: dict with optional keys:
" - 'silent' : 1 to suppress the sidebar header/progress (background mode)
" - 'on_done' : Funcref called with the list of plugins behind once finished
" - 'force' : 1 to ignore the cache freshness (always fetch)
" - 'force' : 1 to always fetch and leave the update-check cache
" untouched (the next startup check re-fetches)
function! plugin_manager#cmd#check#execute(...) abort
try
call plugin_manager#core#util#require_vim_directory('check')
Expand Down Expand Up @@ -212,8 +213,14 @@ function! s:finalize(ctx) abort
endfunction

function! s:finish(plugins, opts) abort
" Persist to cache so startup checks can skip the network next time
call plugin_manager#core#cache#write(a:plugins)
" Persist to cache so startup checks can skip the network next time -
" unless forced: opts.force means "always fetch and leave the cache
" untouched" (the next startup check re-fetches, TTL skipped).
if !get(a:opts, 'force', 0)
call plugin_manager#core#cache#write(a:plugins)
else
call delete(plugin_manager#core#cache#get_path())
endif

" Notify caller (e.g. auto-update flow)
if has_key(a:opts, 'on_done') && !empty(a:opts.on_done)
Expand Down
Loading
Loading