Compare commits

...

37 Commits

Author SHA1 Message Date
bfredl
6df0163e92
Merge efd1afc6b8 into 0ade8fed14 2024-09-18 01:21:52 +02:00
Gregory Anders
0ade8fed14
Merge pull request #30411 from gpanders/vim-9.1.0734
vim-patch:9.1.{0734,0735}
2024-09-17 17:20:50 -05:00
Gregory Anders
9a3f74c4c7 vim-patch:9.1.0735: filetype: salt files are not recognized
Problem:  filetype: salt files are not recognized
Solution: Detect '*.sls' files as filetype salt,
          include a syntax script (Gregory Anders)

closes: vim/vim#15689

89b9bb4ac8

Co-authored-by: Gregory Anders <greg@gpanders.com>
2024-09-17 14:18:51 -05:00
Gregory Anders
13d6f6cbb2 vim-patch:9.1.0734: filetype: jinja files are not recognized
Problem:  filetype: jinja files are not recognized
Solution: detect '*.jinja' files a jinja filetype,
          include jinja syntax script (Gregory Anders)

related: vim/vim#15689

202c467bb3

Co-authored-by: Gregory Anders <greg@gpanders.com>
2024-09-17 14:17:33 -05:00
glepnir
a0d8c2b86e
docs(eval): update param types of prompt-buffer functions (#30392) 2024-09-16 18:33:35 +08:00
Justin M. Keyes
549c00c791
Merge #29490 feat(vim.ui.open): configurable opener 2024-09-16 03:21:40 -07:00
Justin M. Keyes
23dcd7cd73 test(vim.ui.open): opt.cmd 2024-09-16 11:58:04 +02:00
Matěj Cepl
3f15e57b26 feat(vim.ui): configurable "gx" / vim.ui.open() tool
Problem:
User cannot configure the tool used by `vim.ui.open` (or `gx`). With
netrw this was supported by `g:netrw_browsex_viewer`.

Solution:
Introduce `opts.cmd`. Users that want to set this globally can
monkey-patch `vim.ui.open` in the same way described at `:help vim.paste()`.

Fixes https://github.com/neovim/neovim/issues/29488

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2024-09-16 11:58:02 +02:00
Christian Clason
a9031cc4a6 vim-patch:5e95c8f: runtime(java): Highlight javaConceptKind modifiers with StorageClass
Stop assigning by default the NonText highlighting group for
javaConceptKind modifiers since its colour is hardly
distinguishable from a background colour for a range of
colour schemes.

fixes vim/vim#15237
related vim/vim#15238
closes: vim/vim#15664

5e95c8f637

Co-authored-by: Aliaksei Budavei <0x000c70@gmail.com>
Co-authored-by: Dexter Gaon-Shatford <dexter@gaonshatford.ca>
2024-09-16 08:16:32 +02:00
Christian Clason
5e7933693b vim-patch:0f5effb: runtime(netrw): delete confirmation not strict enough
fixes: vim/vim#15680

0f5effbd1f

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-09-16 08:16:20 +02:00
Christian Clason
f408603f4f vim-patch:9.1.0731: inconsistent case sensitive extension matching
Problem:  inconsistent case sensitive extension matching
Solution: unify case sensitive extension matching (Evgeni Chasnovski).

There are different approaches of how extensions are matched with
respect to case sensitivity. In particular, '\c' flag is used in pattern
whereas in most places case sensitive matching is guarded behind
`has("fname_case")` condition.

Replace all instances of '\c' with an explicit case sensitive pattern
variants guarded by `has("fname_case")`. Strictly speaking, this is a
breaking change because only two (most common and prevailingly tested)
variants are now matched: upper first letter and upper all letters.

closes: vim/vim#15672

59b089c9df

Co-authored-by: Evgeni Chasnovski <evgeni.chasnovski@gmail.com>
2024-09-16 08:16:07 +02:00
zeertzjq
78b8510933
vim-patch:4d427d4: runtime(vim): Update base-syntax, match Vim9 bool/null literal args to :if/:while/:return (#30391)
Match Vim9 boolean and null literals in expression arguments of :if,
:elseif, :while and :return.

closes: vim/vim#15684

4d427d4cab

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2024-09-15 22:57:16 +00:00
Justin M. Keyes
057d27a9d6
refactor: rename "process" => "proc" #30387
Problem:
- "process" is often used as a verb (`multiqueue_process_events`), which
  is ambiguous for cases where it's used as a topic.
- The documented naming convention for processes is "proc".
  - `:help dev-name-common`
- Shorter is better, when it doesn't harm readability or
  discoverability.

Solution:
Rename "process" => "proc" in all C symbols and module names.
2024-09-15 12:20:58 -07:00
Justin M. Keyes
5792546777
refactor(tests): rename terminal/testutil.lua => testterm.lua #30372
This module is generally used by any tests that need the full Nvim TUI
instead of `screen.lua`. Thus it should live in `functional/` instead of
in `functional/terminal/`.
2024-09-15 03:28:14 -07:00
zeertzjq
3b54adc6c6
Merge pull request #30378 from zeertzjq/vim-9.1.0729
vim-patch:9.1.{0729,0730}
2024-09-14 19:51:11 +08:00
zeertzjq
325d349f9d
vim-patch:9.1.0728: [security]: heap-use-after-free in garbage collection with location list user data (#30377)
Problem:  heap-use-after-free in garbage collection with location list
          user data.
Solution: Mark user data as in use when no other window is referencing
          the location list (zeertzjq)

fixes: neovim/neovim#30371
closes: vim/vim#15683

be4bd189d2
2024-09-14 19:38:33 +08:00
zeertzjq
5191a11d66 vim-patch:9.1.0730: Crash with cursor-screenline and narrow window
Problem:  Crash with cursor-screenline and narrow window
          (elig0n)
Solution: Don't set right_col when width2 is 0 (zeertzjq).

fixes: vim/vim#15677
closes: vim/vim#15678

59149f0269
2024-09-14 19:29:40 +08:00
zeertzjq
90585e47fe vim-patch:9.1.0729: Wrong cursor-screenline when resizing window
Problem:  Wrong cursor-screenline when resizing window
Solution: Invalidate saved left_col and right_col when width1 or width2
          change.

closes: vim/vim#15679

86dc4f8b43
2024-09-14 19:29:37 +08:00
Jaehwang Jung
f2173b1aa2
fix(defaults): cannot remove "How-to disable mouse" menu item #30375 2024-09-14 02:18:38 -07:00
dundargoc
67d6b6f27e ci: skip automerge step if backport failed 2024-09-14 01:55:36 +02:00
Mathias Fussenegger
8512f669f0 fix(lsp): handle nil bytes in strings
Problem:

The LSP omnifunc can insert nil bytes, which when read in other places
(like semantic token) could cause an error:

    semantic_tokens.lua:304: Vim:E976: Using a Blob as a String

Solution:

Use `#line` instead of `vim.fn.strlen(line)`. Both return UTF-8 bytes
but the latter can't handle nil bytes.

Completion candidates can currently insert nil bytes, if other parts of
Alternative fix to https://github.com/neovim/neovim/pull/30359

Note that https://github.com/neovim/neovim/pull/30315 will avoid the
insertion of nil bytes from the LSP omnifunc, but the change of this PR
can more easily be backported.
2024-09-13 22:34:49 +02:00
dundargoc
755512ed60 ci: don't add reviewers for PRs created by a bot
This will ensure automatic backports created by the backport action does
not request reviewers (since the commit in question has already been
vetted and merged), but manual backports created by users does request
reviewers as these commits has not been vetted previously.
2024-09-13 16:58:15 +02:00
dundargoc
4c23b83456 ci: add needs:backport label on backport PRs with conflict
This makes it easy to keep track of which backport PRs have failed and
need manual intervention to fix.
2024-09-13 16:49:35 +02:00
dundargoc
5284a2a793 build: bump unibilium to v2.1.2
There is no real practical difference from previous commit except that
this is a tagged release.
2024-09-13 15:56:37 +02:00
Riley Bruins
b9b408a56c
feat(treesitter): start moving get_parser to return nil #30313
**Problem:** `vim.treesitter.get_parser` will throw an error if no parser
can be found.

- This means the caller is responsible for wrapping it in a `pcall`,
  which is easy to forget
- It also makes it slightly harder to potentially memoize `get_parser`
  in the future
- It's a bit unintuitive since many other `get_*` style functions
  conventionally return `nil` if no object is found (e.g. `get_node`,
  `get_lang`, `query.get`, etc.)

**Solution:** Return `nil` if no parser can be found or created

- This requires a function signature change, and some new assertions in
  places where the parser will always (or should always) be found.
- This commit starts by making this change internally, since it is
  breaking. Eventually it will be rolled out to the public API.
2024-09-13 05:09:11 -07:00
James Trew
8654a97006
fix(lsp): handle empty call hierarchy items #30349
Ensure that the function `pick_call_hierarchy_item` correctly handles
the case where `call_hierarchy_items` is nil or an empty table. This
prevents potential errors when the function is called with no items.
2024-09-13 04:59:49 -07:00
dundargoc
057314345a ci: enable automerge by default when backporting
This will automatically merge backported PRs without human intervention
if the tests pass.
2024-09-13 12:31:33 +02:00
Justin M. Keyes
deac7df80a
refactor(stream.c): unused params in stream_close #30356 2024-09-12 09:16:57 -07:00
Christian Clason
ae917dbd06 fix(treesitter): sync queries from upstream 2024-09-12 13:41:15 +02:00
Christian Clason
c65153893a build(deps): bump tree-sitter-c to v0.23.0 2024-09-12 13:41:15 +02:00
Christian Clason
f6cc0394ae build(deps): bump tree-sitter-markdown to v0.3.2 2024-09-12 13:41:15 +02:00
Christian Clason
f347c292d1 build(deps): bump tree-sitter-lua to v0.2.0 2024-09-12 13:41:15 +02:00
zeertzjq
48c14d3544
vim-patch:9.1.0725: filetype: swiftinterface files are not recognized (#30350)
Problem:  filetype: swiftinterface files are not recognized
Solution: Detect '*.swiftinterface' files as swift filetype
          (LosFarmosCTL)

closes: vim/vim#15658

03cac4b70d

Co-authored-by: LosFarmosCTL <80157503+LosFarmosCTL@users.noreply.github.com>
2024-09-12 15:16:58 +08:00
Justin M. Keyes
5931f780e0
feat(log): use "ui" as default name for TUI client #30345
The default "session name" for the builtin TUI is "ui".

before:

    INF 2024-09-10T14:57:35.385 hello.sock os_exit:692: Nvim exit: 1
    INF 2024-09-10T14:57:35.388 ?.4543     os_exit:692: Nvim exit: 1

after:

    INF 2024-09-10T14:59:19.919 hello.sock os_exit:692: Nvim exit: 1
    INF 2024-09-10T14:59:19.922 ui.5684    os_exit:692: Nvim exit: 1
2024-09-11 17:25:00 -07:00
Gregory Anders
98ba65b8be
fix: replace NVIM with Nvim in default titlestring (#30348) 2024-09-11 20:32:08 +00:00
bfredl
efd1afc6b8 gimme config 2024-05-14 11:56:18 +02:00
bfredl
1a5bd70f34 ADVENTURES IN WONDERLAND: build.zig
currently, this works:

zig build nlua0 -- file.lua args
with things like "print(vim.inspect({2,2}))"

and:

zig build wip
ls zig-out/include/

TODO: zig fetch doesn't like  https://www.inf.puc-rio.br/~roberto/lpeg/lpeg-1.0.2.tar.gz
HTTPS/TLS issue
2024-05-14 09:51:26 +02:00
123 changed files with 2103 additions and 594 deletions

View File

@ -26,3 +26,21 @@ jobs:
pull_title: "${pull_title}" pull_title: "${pull_title}"
label_pattern: "^ci:backport ([^ ]+)$" label_pattern: "^ci:backport ([^ ]+)$"
github_token: ${{ steps.app-token.outputs.token }} github_token: ${{ steps.app-token.outputs.token }}
- name: Create failed backport label
if: ${{ steps.backport.outputs.was_successful == 'false' }}
uses: actions/github-script@v7
with:
script: |
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['needs:backport']
})
- name: Enable automerge
if: ${{ steps.backport.outputs.was_successful == 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh pr merge --rebase --auto ${{ steps.backport.outputs.created_pull_numbers }}

View File

@ -5,7 +5,7 @@ on:
workflow_call: workflow_call:
jobs: jobs:
request-reviewer: request-reviewer:
if: github.event.pull_request.state == 'open' && github.event.pull_request.draft == false if: github.event.pull_request.state == 'open' && github.event.pull_request.draft == false && !endsWith(github.actor, '[bot]')
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
pull-requests: write pull-requests: write

View File

@ -46,7 +46,10 @@ jobs:
cmake -S cmake.deps -B .deps -G Ninja cmake -S cmake.deps -B .deps -G Ninja
cmake --build .deps cmake --build .deps
- run: cmake -B build -G Ninja -D CI_LINT=ON - run: |
cmake -B build -G Ninja -D CI_LINT=ON
echo "======= CONFIGZEIT"
cat build/cmake.config/auto/config.h
- if: "!cancelled()" - if: "!cancelled()"
name: Determine if run should be aborted name: Determine if run should be aborted

53
BRANCH_TODO.md Normal file
View File

@ -0,0 +1,53 @@
Dependencies:
- [x] libuv
- [-] lua
- [ ] luajit
- [x] MSGPACK_URL https://github.com/msgpack/msgpack-c/archive/c-6.0.1.tar.gz
- [x] UNIBILIUM_URL https://github.com/neovim/unibilium/archive/d72c3598e7ac5d1ebf86ee268b8b4ed95c0fa628.tar.gz
- [ ] LIBVTERM_URL https://github.com/neovim/libvterm/archive/v0.3.3.tar.gz
- [-] luv
- [-] lpeg
- [x] compat53 (c api part only - but likely enough)
- [x] TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.22.5.tar.gz
non-glibc:
- [ ] GETTEXT_URL https://github.com/neovim/deps/raw/b9bf36eb31f27e8136d907da38fa23518927737e/opt/gettext-0.20.1.tar.gz
- [ ] LIBICONV_URL https://github.com/neovim/deps/raw/b9bf36eb31f27e8136d907da38fa23518927737e/opt/libiconv-1.17.tar.gz
Runtime dependencies:
- [ ] treesitter parsers
- [ ] cat/tee/xxd.exe
- [ ] WIN32YANK_X86_64_URL https://github.com/equalsraf/win32yank/releases/download/v0.1.1/win32yank-x64.zip
Generators (nvim binary):
- [x] gen_api_dispatch.lua
- [x] gen_api_ui_events.lua
- [x] gen_char_blob.lua (partial - LUAC_PRG not supported)
- [x] gen_declarations.lua (partial - some generators generate input for this!)
- [x] gen_eval.lua
- [x] gen_events.lua
- [x] gen_ex_cmds.lua
- [x] gen_options_enum.lua
- [x] gen_options.lua
- [x] gen_unicode_tables.lua
Configuration:
- [x] nvim_version.lua
- [x] versiondef.h
- [ ] src/versiondef.h is a copy where $<CONFIG> has been changed to ${CONFIG}. upstream support for $<foo> ???
- [ ] versiondef_git.h
- [ ] config.h
- [ ] pathdef.h
Generators (Runtime and documentation):
- [ ] gen_vimvim.lua
- [ ] gen_eval_files.lua
- [ ] gen_vimdoc.lua*
- [ ] gen_filetype.lua
- [ ] gen_help_html.lua
- [ ] gen_lsp.lua

577
build.zig Normal file
View File

@ -0,0 +1,577 @@
const std = @import("std");
const LazyPath = std.Build.LazyPath;
const version = struct {
const major = 0;
const minor = 10;
const patch = 0;
const prerelease = "-dev";
const api_level = 12;
const api_level_compat = 0;
const api_prerelease = 0;
};
// TODO: upstreeeeaam
pub fn lazyArtifact(d: *std.Build.Dependency, name: []const u8) ?*std.Build.Step.Compile {
var found: ?*std.Build.Step.Compile = null;
for (d.builder.install_tls.step.dependencies.items) |dep_step| {
const inst = dep_step.cast(std.Build.Step.InstallArtifact) orelse continue;
if (std.mem.eql(u8, inst.artifact.name, name)) {
if (found != null) std.debug.panic("artifact name '{s}' is ambiguous", .{name});
found = inst.artifact;
}
}
return found;
}
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// puc lua 5.1 is not ReleaseSafe "safe"
const optimize_lua = if (optimize == .Debug) .ReleaseSmall else optimize;
const use_luajit = false;
const ziglua = b.dependency("ziglua", .{
.target = target,
.optimize = optimize_lua,
.lang = if (use_luajit) .luajit else .lua51,
.shared = false,
});
const lpeg = b.dependency("lpeg", .{});
// const lua = ziglua.artifact("lua");
const lua = lazyArtifact(ziglua, "lua") orelse return;
const libuv_dep = b.dependency("libuv", .{ .target = target, .optimize = optimize });
const libuv = libuv_dep.artifact("uv");
const libluv = try build_libluv(b, target, optimize, lua, libuv);
const msgpack_c = b.dependency("msgpack_c", .{ .target = target, .optimize = optimize });
const unibilium = b.dependency("unibilium", .{ .target = target, .optimize = optimize });
const treesitter = b.dependency("treesitter", .{ .target = target, .optimize = optimize });
const vterm = b.dependency("vterm", .{ .target = target, .optimize = optimize });
const nlua0 = build_nlua0(b, target, optimize, use_luajit, ziglua, lpeg);
// usual caveat emptor: might need to force a rebuild if the only change is
// addition of new .c files, as those are not seen by any hash
const subdirs = [_][]const u8{
"", // src/nvim itself
"os/",
"api/",
"api/private/",
"msgpack_rpc/",
"tui/",
"event/",
"eval/",
"lua/",
"viml/",
"viml/parser/",
};
// source names _relative_ src/nvim/, not including other src/ subdircs
var nvim_sources = try std.ArrayList(struct { name: []u8, api_export: bool }).initCapacity(b.allocator, 100);
// both source headers and the {module}.h.generated.h files
var api_headers = try std.ArrayList(std.Build.LazyPath).initCapacity(b.allocator, 10);
const windows_only = [_][]const u8{ "pty_process_win.c", "pty_conpty_win.c", "os_win_console.c" };
const is_windows = (target.result.os.tag == .windows);
const src_dir = b.build_root.handle;
for (subdirs) |s| {
var dir = try src_dir.openDir(b.fmt("src/nvim/{s}", .{s}), .{ .iterate = true });
defer dir.close();
var it = dir.iterateAssumeFirstIteration();
const api_export = std.mem.eql(u8, s, "api/");
const os_check = std.mem.eql(u8, s, "os/");
entries: while (try it.next()) |entry| {
if (entry.name.len < 3) continue;
if (entry.name[0] < 'a' or entry.name[0] > 'z') continue;
if (os_check) {
if (!is_windows) {
for (windows_only) |name| {
if (std.mem.eql(u8, name, entry.name)) {
continue :entries;
}
}
}
}
if (std.mem.eql(u8, ".c", entry.name[entry.name.len - 2 ..])) {
try nvim_sources.append(.{ .name = b.fmt("{s}{s}", .{ s, entry.name }), .api_export = api_export });
}
if (api_export) {
if (std.mem.eql(u8, ".h", entry.name[entry.name.len - 2 ..]) and !std.mem.eql(u8, "ui_events.in.h", entry.name)) {
try api_headers.append(b.path(b.fmt("src/nvim/{s}{s}", .{ s, entry.name })));
}
}
}
}
const gen_config = b.addWriteFiles();
const gen_headers = b.addWriteFiles();
const version_lua = gen_config.add("nvim_version.lua", lua_version_info(b));
const versiondef_step = b.addConfigHeader(.{ .style = .{ .cmake = b.path("src/versiondef.h.in") } }, .{
.NVIM_VERSION_MAJOR = version.major,
.NVIM_VERSION_MINOR = version.minor,
.NVIM_VERSION_PATCH = version.patch,
.NVIM_VERSION_PRERELEASE = version.prerelease,
.VERSION_STRING = "TODO", // TODO
.CONFIG = b.fmt("build.zig -Doptimize={s}", .{@tagName(optimize)}), // TODO: include optimize name
});
_ = gen_config.addCopyFile(versiondef_step.getOutput(), "auto/versiondef.h"); // run_preprocessor() workaronnd
// TODO: actually run git :p
const medium = b.fmt("v{}.{}.{}{s}+zig", .{ version.major, version.minor, version.patch, version.prerelease });
const versiondef_git = gen_config.add("auto/versiondef_git.h", b.fmt(
\\#define NVIM_VERSION_MEDIUM "{s}"
\\#define NVIM_VERSION_BUILD "baaaar"
\\
, .{medium}));
// TODO(zig): using getEmittedIncludeTree() is ugly af. we want run_preprocessor()
// to use the std.build.Module include_path thing
const include_path = &.{
b.path("src/"),
b.path("src/includes_fixmelater/"),
gen_config.getDirectory(),
lua.getEmittedIncludeTree(),
libuv.getEmittedIncludeTree(),
libluv.getEmittedIncludeTree(),
msgpack_c.artifact("msgpack_c").getEmittedIncludeTree(),
unibilium.artifact("unibilium").getEmittedIncludeTree(),
treesitter.artifact("tree-sitter").getEmittedIncludeTree(),
vterm.artifact("vterm").getEmittedIncludeTree(),
};
for (nvim_sources.items) |s| {
const api_export = if (s.api_export) &api_headers else null;
const input_file = b.path(b.fmt("src/nvim/{s}", .{s.name}));
_ = try generate_header_for(b, s.name, input_file, api_export, nlua0, include_path, target, gen_headers);
}
{
const gen_step = b.addRunArtifact(nlua0);
gen_step.addFileArg(b.path("src/nvim/generators/gen_ex_cmds.lua"));
_ = gen_header(b, gen_step, "ex_cmds_enum.generated.h", gen_headers);
_ = gen_header(b, gen_step, "ex_cmds_defs.generated.h", gen_headers);
gen_step.addFileArg(b.path("src/nvim/ex_cmds.lua"));
}
{
const gen_step = b.addRunArtifact(nlua0);
gen_step.addFileArg(b.path("src/nvim/generators/gen_options.lua"));
_ = gen_header(b, gen_step, "options.generated.h", gen_headers);
gen_step.addFileArg(b.path("src/nvim/options.lua"));
}
{
const gen_step = b.addRunArtifact(nlua0);
gen_step.addFileArg(b.path("src/nvim/generators/gen_options_enum.lua"));
_ = gen_header(b, gen_step, "options_enum.generated.h", gen_headers);
_ = gen_header(b, gen_step, "options_map.generated.h", gen_headers);
gen_step.addFileArg(b.path("src/nvim/options.lua"));
}
{
const gen_step = b.addRunArtifact(nlua0);
gen_step.addFileArg(b.path("src/nvim/generators/gen_events.lua"));
_ = gen_header(b, gen_step, "auevents_enum.generated.h", gen_headers);
_ = gen_header(b, gen_step, "auevents_name_map.generated.h", gen_headers);
gen_step.addFileArg(b.path("src/nvim/auevents.lua"));
}
{
const gen_step = b.addRunArtifact(nlua0);
gen_step.addFileArg(b.path("src/nvim/generators/gen_unicode_tables.lua"));
gen_step.addDirectoryArg(b.path("src/unicode"));
_ = gen_header(b, gen_step, "unicode_tables.generated.h", gen_headers);
}
{
// TODO: LUAC_PRG is missing. tricky with cross-compiling..
const gen_step = b.addRunArtifact(nlua0);
gen_step.addFileArg(b.path("src/nvim/generators/gen_char_blob.lua"));
gen_step.addArg("-c");
_ = gen_header(b, gen_step, "lua/vim_module.generated.h", gen_headers);
// NB: vim._init_packages and vim.inspect must be be first and second ones
// respectively, otherwise --luamod-dev won't work properly.
const names = [_][]const u8{
"_init_packages",
"inspect",
"_editor",
"filetype",
"fs",
"F",
"keymap",
"loader",
"_defaults",
"_options",
"shared",
};
for (names) |n| {
gen_step.addFileArg(b.path(b.fmt("runtime/lua/vim/{s}.lua", .{n})));
gen_step.addArg(b.fmt("vim.{s}", .{n}));
}
}
const ui_metadata = ui_step: {
const gen_step = b.addRunArtifact(nlua0);
gen_step.addFileArg(b.path("src/nvim/generators/gen_api_ui_events.lua"));
gen_step.addFileArg(b.path("src/nvim/api/ui_events.in.h"));
_ = try gen_header_with_header(b, gen_step, "ui_events_call.generated.h", nlua0, include_path, target, gen_headers);
_ = try gen_header_with_header(b, gen_step, "ui_events_remote.generated.h", nlua0, include_path, target, gen_headers);
const ui_metadata = gen_step.addOutputFileArg("ui_metadata.mpack");
_ = try gen_header_with_header(b, gen_step, "ui_events_client.generated.h", nlua0, include_path, target, gen_headers);
gen_step.addFileArg(b.path("src/nvim/generators/c_grammar.lua"));
break :ui_step ui_metadata;
};
const funcs_metadata = api_step: {
const gen_step = b.addRunArtifact(nlua0);
gen_step.addFileArg(b.path("src/nvim/generators/gen_api_dispatch.lua"));
_ = try gen_header_with_header(b, gen_step, "api/private/dispatch_wrappers.generated.h", nlua0, include_path, target, gen_headers);
_ = gen_header(b, gen_step, "api/private/api_metadata.generated.h", gen_headers);
const funcs_metadata = gen_step.addOutputFileArg("funcs_metadata.mpack");
_ = gen_header(b, gen_step, "lua_api_c_bindings.generated.h", gen_headers);
_ = gen_header(b, gen_step, "keysets_defs.generated.h", gen_headers);
gen_step.addFileArg(ui_metadata);
gen_step.addFileArg(versiondef_git);
gen_step.addFileArg(version_lua);
gen_step.addFileArg(b.path("src/nvim/generators/c_grammar.lua"));
gen_step.addFileArg(b.path("src/nvim/generators/dump_bin_array.lua"));
gen_step.addFileArg(b.path("src/nvim/api/dispatch_deprecated.lua"));
// now follows all .h files with exported functions
for (api_headers.items) |h| {
gen_step.addFileArg(h);
}
break :api_step funcs_metadata;
};
const funcs_data = eval_step: {
const gen_step = b.addRunArtifact(nlua0);
gen_step.addFileArg(b.path("src/nvim/generators/gen_eval.lua"));
_ = gen_header(b, gen_step, "funcs.generated.h", gen_headers);
gen_step.addFileArg(funcs_metadata);
const funcs_data = gen_step.addOutputFileArg("funcs_data.mpack");
gen_step.addFileArg(b.path("src/nvim/eval.lua"));
break :eval_step funcs_data;
};
_ = funcs_data;
const test_gen_step = b.step("gen_sources", "rearrange the power of it all");
test_gen_step.dependOn(&b.addInstallDirectory(.{ .source_dir = gen_config.getDirectory(), .install_dir = .prefix, .install_subdir = "config/" }).step);
test_gen_step.dependOn(&b.addInstallDirectory(.{ .source_dir = gen_headers.getDirectory(), .install_dir = .prefix, .install_subdir = "headers/" }).step);
const nvim_exe = b.addExecutable(.{
.name = "nvim",
.target = target,
.optimize = optimize,
});
nvim_exe.linkLibrary(lua);
nvim_exe.linkLibrary(libuv);
nvim_exe.linkLibrary(libluv);
nvim_exe.linkLibrary(msgpack_c.artifact("msgpack_c"));
nvim_exe.linkLibrary(unibilium.artifact("unibilium"));
nvim_exe.linkLibrary(treesitter.artifact("tree-sitter"));
nvim_exe.linkLibrary(vterm.artifact("vterm"));
nvim_exe.addIncludePath(b.path("src"));
nvim_exe.addIncludePath(b.path("src/includes_fixmelater"));
nvim_exe.addIncludePath(gen_config.getDirectory());
nvim_exe.addIncludePath(gen_headers.getDirectory());
add_lua_modules(&nvim_exe.root_module, lpeg, use_luajit);
const src_paths = try b.allocator.alloc([]u8, nvim_sources.items.len);
for (nvim_sources.items, 0..) |s, i| {
src_paths[i] = b.fmt("src/nvim/{s}", .{s.name});
}
const flags = [_][]const u8{
"-std=gnu99",
"-DINCLUDE_GENERATED_DECLARATIONS",
"-D_GNU_SOURCE",
if (use_luajit) "" else "-DNVIM_VENDOR_BIT",
};
nvim_exe.addCSourceFiles(.{ .files = src_paths, .flags = &flags });
nvim_exe.addCSourceFiles(.{
.files = &.{ "src/termkey/termkey.c", "src/termkey/driver-csi.c", "src/termkey/driver-ti.c" },
.flags = &.{"-DHAVE_UNIBILIUM"},
});
nvim_exe.addCSourceFiles(.{ .files = &.{
"src/xdiff/xdiffi.c",
"src/xdiff/xemit.c",
"src/xdiff/xhistogram.c",
"src/xdiff/xpatience.c",
"src/xdiff/xprepare.c",
"src/xdiff/xutils.c",
"src/cjson/lua_cjson.c",
"src/cjson/fpconv.c",
"src/cjson/strbuf.c",
}, .flags = &flags });
const nvim_exe_step = b.step("nvim_bin", "only the binary (not a fully working install!)");
nvim_exe_step.dependOn(&b.addInstallArtifact(nvim_exe, .{}).step);
}
pub fn lua_version_info(b: *std.Build) []u8 {
const v = version;
return b.fmt(
\\return {{
\\ {{"major", {}}},
\\ {{"minor", {}}},
\\ {{"patch", {}}},
\\ {{"prerelease", {}}},
\\ {{"api_level", {}}},
\\ {{"api_compatible", {}}},
\\ {{"api_prerelease", {}}},
\\}}
, .{ v.major, v.minor, v.patch, v.prerelease.len > 0, v.api_level, v.api_level_compat, v.api_prerelease });
}
pub fn gen_header(
b: *std.Build,
gen_step: *std.Build.Step.Run,
name: []const u8,
gen_headers: *std.Build.Step.WriteFile,
) std.Build.LazyPath {
_ = b;
const header = gen_step.addOutputFileArg(name);
_ = gen_headers.addCopyFile(header, name);
return header;
}
pub fn gen_header_with_header(
b: *std.Build,
gen_step: *std.Build.Step.Run,
name: []const u8,
nlua0: *std.Build.Step.Compile,
include_path: []const LazyPath,
target: ?std.Build.ResolvedTarget,
gen_headers: *std.Build.Step.WriteFile,
) !std.Build.LazyPath {
if (name.len < 12 or !std.mem.eql(u8, ".generated.h", name[name.len - 12 ..])) return error.InvalidBaseName;
const h = gen_header(b, gen_step, name, gen_headers);
_ = try generate_header_for(b, b.fmt("{s}.h", .{name[0 .. name.len - 12]}), h, null, nlua0, include_path, target, gen_headers);
return h;
}
pub const PreprocessorOptions = struct {
include_dirs: []const LazyPath = &.{},
c_macros: []const []const u8 = &.{},
target: ?std.Build.ResolvedTarget = null,
};
// TODO: this should be suggested to upstream
pub fn run_preprocessor(
b: *std.Build,
src: LazyPath,
output_name: []const u8,
options: PreprocessorOptions,
) !LazyPath {
const run_step = std.Build.Step.Run.create(b, b.fmt("preprocess to get {s}", .{output_name}));
run_step.addArgs(&.{ b.graph.zig_exe, "cc", "-E" });
run_step.addFileArg(src);
run_step.addArg("-o");
const output = run_step.addOutputFileArg(output_name);
// TODO: include path logic for addCSourceFiles and TranslateC is _very_ different
for (options.include_dirs) |include_dir| {
run_step.addArg("-I");
run_step.addDirectoryArg(include_dir);
}
for (options.c_macros) |c_macro| {
run_step.addArg(b.fmt("-D{s}", .{c_macro}));
run_step.addArg(c_macro);
}
if (options.target) |t| {
if (!t.query.isNative()) {
run_step.addArgs(&.{
"-target", try t.query.zigTriple(b.allocator),
});
}
}
run_step.addArgs(&.{ "-MMD", "-MF" });
_ = run_step.addDepFileOutputArg(b.fmt("{s}.d", .{output_name}));
return output;
}
pub fn generate_header_for(
b: *std.Build,
name: []const u8,
input_file: std.Build.LazyPath,
api_export: ?*std.ArrayList(LazyPath),
nlua0: *std.Build.Step.Compile,
include_path: []const LazyPath,
target: ?std.Build.ResolvedTarget,
gen_headers: *std.Build.Step.WriteFile,
) !*std.Build.Step.Run {
if (name.len < 2 or !(std.mem.eql(u8, ".c", name[name.len - 2 ..]) or std.mem.eql(u8, ".h", name[name.len - 2 ..]))) return error.InvalidBaseName;
const basename = name[0 .. name.len - 2];
const i_file = try run_preprocessor(b, input_file, b.fmt("{s}.i", .{basename}), .{
.include_dirs = include_path,
.c_macros = &.{ "HAVE_UNIBILIUM", "_GNU_SOURCE" },
.target = target,
});
const run_step = b.addRunArtifact(nlua0);
run_step.addFileArg(b.path("src/nvim/generators/gen_declarations.lua"));
run_step.addFileArg(input_file);
_ = gen_header(b, run_step, b.fmt("{s}.c.generated.h", .{basename}), gen_headers);
const h_file = gen_header(b, run_step, b.fmt("{s}.h.generated.h", .{basename}), gen_headers);
if (api_export) |api_files| {
try api_files.append(h_file);
}
run_step.addFileArg(i_file);
return run_step;
}
pub fn build_nlua0(
b: *std.Build,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
use_luajit: bool,
ziglua: *std.Build.Dependency,
lpeg: *std.Build.Dependency,
) *std.Build.Step.Compile {
const options = b.addOptions();
options.addOption(bool, "use_luajit", use_luajit);
const nlua0_exe = b.addExecutable(.{
.name = "nlua0",
.root_source_file = .{ .path = "src/nlua0.zig" },
.target = target,
.optimize = optimize,
});
const nlua0_mod = &nlua0_exe.root_module;
const exe_unit_tests = b.addTest(.{
.root_source_file = .{ .path = "src/nlua0.zig" },
.target = target,
.optimize = optimize,
});
// TODO: need mod.addLibraryPathFromDependency(ziglua)
// nlua0_mod.include_dirs.append(nlua0_mod.owner.allocator, .{ .other_step = ziglua_mod }) catch @panic("OOM");
const embedded_data = b.addModule("embedded_data", .{
.root_source_file = .{ .path = "runtime/embedded_data.zig" },
});
for ([2]*std.Build.Module{ nlua0_mod, &exe_unit_tests.root_module }) |mod| {
mod.addImport("ziglua", ziglua.module("ziglua"));
mod.addImport("embedded_data", embedded_data);
// addImport already links by itself. but we need headers as well..
mod.linkLibrary(ziglua.artifact("lua"));
mod.addOptions("options", options);
mod.addIncludePath(b.path("src"));
mod.addIncludePath(b.path("src/includes_fixmelater"));
add_lua_modules(mod, lpeg, use_luajit);
}
// for debugging the nlua0 environment
// like this: `zig build nlua0 -- script.lua {args}`
const run_cmd = b.addRunArtifact(nlua0_exe);
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("nlua0", "Run nlua0 build tool");
run_step.dependOn(&run_cmd.step);
b.installArtifact(nlua0_exe); // DEBUG
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
const test_step = b.step("test_nlua0", "Run unit tests for nlua0");
test_step.dependOn(&run_exe_unit_tests.step);
return nlua0_exe;
}
pub fn add_lua_modules(mod: *std.Build.Module, lpeg: *std.Build.Dependency, use_luajit: bool) void {
const flags = [_][]const u8{
// Standard version used in Lua Makefile
"-std=gnu99",
};
mod.addIncludePath(lpeg.path(""));
mod.addCSourceFiles(.{
.files = &.{
"src/mpack/lmpack.c",
"src/mpack/mpack_core.c",
"src/mpack/object.c",
"src/mpack/conv.c",
"src/mpack/rpc.c",
},
.flags = &flags,
});
mod.addCSourceFiles(.{
.root = .{ .dependency = .{ .dependency = lpeg, .sub_path = "" } },
.files = &.{
"lpcap.c",
"lpcode.c",
"lpcset.c",
"lpprint.c",
"lptree.c",
"lpvm.c",
},
.flags = &flags,
});
if (!use_luajit) {
mod.addCSourceFiles(.{
.files = &.{
"src/bit.c",
},
.flags = &flags,
});
}
}
pub fn build_libluv(
b: *std.Build,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
lua: *std.Build.Step.Compile,
libuv: *std.Build.Step.Compile,
) !*std.Build.Step.Compile {
const upstream = b.dependency("libluv", .{});
const compat53 = b.dependency("lua_compat53", .{});
const lib = b.addStaticLibrary(.{
.name = "luv",
.target = target,
.optimize = optimize,
});
lib.linkLibrary(lua);
lib.linkLibrary(libuv);
lib.addIncludePath(upstream.path("src"));
lib.addIncludePath(compat53.path("c-api"));
lib.installHeader(upstream.path("src/luv.h"), "luv/luv.h");
lib.addCSourceFiles(.{ .root = upstream.path("src/"), .files = &.{
"luv.c",
} });
lib.addCSourceFiles(.{ .root = compat53.path("c-api"), .files = &.{
"compat-5.3.c",
} });
return lib;
}

51
build.zig.zon Normal file
View File

@ -0,0 +1,51 @@
.{
.name = "neovim",
.version = "0.0.0",
// This field is optional.
// This is currently advisory only; Zig does not yet do anything
// with this value.
//.minimum_zig_version = "0.12.0",
// lpeg fetching from https://www.inf.puc-rio.br/~roberto/lpeg/lpeg-1.0.2.tar.gz doesn't work, bundlevendor for now
.dependencies = .{
.ziglua = .{
.url = "https://github.com/natecraddock/ziglua/archive/486f51d3acc61d805783f5f07aee34c75ab59a25.tar.gz",
.hash = "12208603e0f51fa6ce7201d8e851c5979b6b78887434623ac87a0f2a5a3dd3e75130",
},
.lpeg = .{
.url = "https://github.com/neovim/deps/raw/d495ee6f79e7962a53ad79670cb92488abe0b9b4/opt/lpeg-1.1.0.tar.gz",
.hash = "122084badadeb91106dd06b2055119a944c340563536caefd8e22d4064182f7cd6e6",
},
.libluv = .{
.url = "https://github.com/luvit/luv/releases/download/1.48.0-2/luv-1.48.0-2.tar.gz",
.hash = "122050b45fc1b2d1e72d30d3e4f446735ab95bbb88658bc1de736e5dc71c3e3cd767",
},
.lua_compat53 = .{
.url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.13.tar.gz",
.hash = "1220e75685f00c242fbf6c1c60e98dd1b24ba99e38277970a10636e44ed08cf2af8a",
},
.treesitter = .{
.url = "https://github.com/bfredl/tree-sitter/archive/1174f67cc6a9661fdd59f847d690ee874d8eaa66.tar.gz",
.hash = "1220cec07c0fd62e3832c13eb1744c4c94f8b9915d86de960ce849f48875fa61dec9",
},
.libuv = .{ .path = "./deps/libuv" },
.msgpack_c = .{ .path = "./deps/msgpack_c/" },
.unibilium = .{ .path = "./deps/unibilium/" },
.vterm = .{ .path = "./deps/vterm/" },
},
.paths = .{
// This makes *all* files, recursively, included in this package. It is generally
// better to explicitly list the files and directories instead, to insure that
// fetching from tarballs, file system paths, and version control all result
// in the same contents hash.
"",
// For example...
//"build.zig",
//"build.zig.zon",
//"src",
//"LICENSE",
//"README.md",
},
}

View File

@ -12,6 +12,6 @@
#endif #endif
#define NVIM_VERSION_CFLAGS "${VERSION_STRING}" #define NVIM_VERSION_CFLAGS "${VERSION_STRING}"
#define NVIM_VERSION_BUILD_TYPE "$<CONFIG>" #define NVIM_VERSION_BUILD_TYPE "${CONFIG}"
#endif // AUTO_VERSIONDEF_H #endif // AUTO_VERSIONDEF_H

View File

@ -7,8 +7,8 @@ LUAJIT_SHA256 2b5514bd6a6573cb6111b43d013e952cbaf46762d14ebe26c872ddb80b5a84e0
LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz
LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333 LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333
UNIBILIUM_URL https://github.com/neovim/unibilium/archive/ab28a2ddb86a144194a798bcf1fef1ab4f981ab7.tar.gz UNIBILIUM_URL https://github.com/neovim/unibilium/archive/v2.1.2.tar.gz
UNIBILIUM_SHA256 7c0386fc48452632868e0dcb8e7ed140d67a3da79e39ceee54c1ba7a495ad625 UNIBILIUM_SHA256 370ecb07fbbc20d91d1b350c55f1c806b06bf86797e164081ccc977fc9b3af7a
LUV_URL https://github.com/luvit/luv/releases/download/1.48.0-2/luv-1.48.0-2.tar.gz LUV_URL https://github.com/luvit/luv/releases/download/1.48.0-2/luv-1.48.0-2.tar.gz
LUV_SHA256 2c3a1ddfebb4f6550293a40ee789f7122e97647eede51511f57203de48c03b7a LUV_SHA256 2c3a1ddfebb4f6550293a40ee789f7122e97647eede51511f57203de48c03b7a
@ -38,18 +38,18 @@ LIBICONV_SHA256 8f74213b56238c85a50a5329f77e06198771e70dd9a739779f4c02f65d971313
UTF8PROC_URL https://github.com/JuliaStrings/utf8proc/archive/3de4596fbe28956855df2ecb3c11c0bbc3535838.tar.gz UTF8PROC_URL https://github.com/JuliaStrings/utf8proc/archive/3de4596fbe28956855df2ecb3c11c0bbc3535838.tar.gz
UTF8PROC_SHA256 fb4a16bb659b58afb7f921fcc8928d0b3c1fcab135366c8a4f9ca7de1b1cfada UTF8PROC_SHA256 fb4a16bb659b58afb7f921fcc8928d0b3c1fcab135366c8a4f9ca7de1b1cfada
TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.21.3.tar.gz TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.23.0.tar.gz
TREESITTER_C_SHA256 75a3780df6114cd37496761c4a7c9fd900c78bee3a2707f590d78c0ca3a24368 TREESITTER_C_SHA256 ee58c925e2e507c23d735aad46bf7fb0af31ca06d6f4f41bc008216d9232b0cb
TREESITTER_LUA_URL https://github.com/tree-sitter-grammars/tree-sitter-lua/archive/v0.1.0.tar.gz TREESITTER_LUA_URL https://github.com/tree-sitter-grammars/tree-sitter-lua/archive/v0.2.0.tar.gz
TREESITTER_LUA_SHA256 230cfcbfa74ed1f7b8149e9a1f34c2efc4c589a71fe0f5dc8560622f8020d722 TREESITTER_LUA_SHA256 6c41227cd0a59047b19d31f0031d4d901f08bfd78d6fc7f55c89e5b8374c794e
TREESITTER_VIM_URL https://github.com/neovim/tree-sitter-vim/archive/v0.4.0.tar.gz TREESITTER_VIM_URL https://github.com/neovim/tree-sitter-vim/archive/v0.4.0.tar.gz
TREESITTER_VIM_SHA256 9f856f8b4a10ab43348550fa2d3cb2846ae3d8e60f45887200549c051c66f9d5 TREESITTER_VIM_SHA256 9f856f8b4a10ab43348550fa2d3cb2846ae3d8e60f45887200549c051c66f9d5
TREESITTER_VIMDOC_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v3.0.0.tar.gz TREESITTER_VIMDOC_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v3.0.0.tar.gz
TREESITTER_VIMDOC_SHA256 a639bf92bf57bfa1cdc90ca16af27bfaf26a9779064776dd4be34c1ef1453f6c TREESITTER_VIMDOC_SHA256 a639bf92bf57bfa1cdc90ca16af27bfaf26a9779064776dd4be34c1ef1453f6c
TREESITTER_QUERY_URL https://github.com/tree-sitter-grammars/tree-sitter-query/archive/v0.4.0.tar.gz TREESITTER_QUERY_URL https://github.com/tree-sitter-grammars/tree-sitter-query/archive/v0.4.0.tar.gz
TREESITTER_QUERY_SHA256 d3a423ab66dc62b2969625e280116678a8a22582b5ff087795222108db2f6a6e TREESITTER_QUERY_SHA256 d3a423ab66dc62b2969625e280116678a8a22582b5ff087795222108db2f6a6e
TREESITTER_MARKDOWN_URL https://github.com/tree-sitter-grammars/tree-sitter-markdown/archive/v0.2.3.tar.gz TREESITTER_MARKDOWN_URL https://github.com/tree-sitter-grammars/tree-sitter-markdown/archive/v0.3.2.tar.gz
TREESITTER_MARKDOWN_SHA256 4909d6023643f1afc3ab219585d4035b7403f3a17849782ab803c5f73c8a31d5 TREESITTER_MARKDOWN_SHA256 5dac48a6d971eb545aab665d59a18180d21963afc781bbf40f9077c06cb82ae5
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.23.0.tar.gz TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.23.0.tar.gz
TREESITTER_SHA256 6403b361b0014999e96f61b9c84d6950d42f0c7d6e806be79382e0232e48a11b TREESITTER_SHA256 6403b361b0014999e96f61b9c84d6950d42f0c7d6e806be79382e0232e48a11b

124
deps/libuv/build.zig vendored Normal file
View File

@ -0,0 +1,124 @@
const std = @import("std");
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const upstream = b.dependency("libuv", .{});
const lib = b.addStaticLibrary(.{
.name = "uv",
.target = target,
.optimize = optimize,
});
lib.addIncludePath(upstream.path("include"));
lib.addIncludePath(upstream.path("src"));
lib.installHeadersDirectory(upstream.path("include"), ".", .{});
if (target.result.os.tag == .windows) {
lib.linkSystemLibrary("psapi");
lib.linkSystemLibrary("user32");
lib.linkSystemLibrary("advapi32");
lib.linkSystemLibrary("iphlpapi");
lib.linkSystemLibrary("userenv");
lib.linkSystemLibrary("ws2_32");
}
if (target.result.os.tag == .linux) {
lib.linkSystemLibrary("pthread");
}
lib.linkLibC();
if (target.result.os.tag != .windows) {
lib.root_module.addCMacro("FILE_OFFSET_BITS", "64");
lib.root_module.addCMacro("_LARGEFILE_SOURCE", "");
}
if (target.result.os.tag == .linux) {
lib.root_module.addCMacro("_GNU_SOURCE", "");
lib.root_module.addCMacro("_POSIX_C_SOURCE", "200112");
}
if (target.result.isDarwin()) {
lib.root_module.addCMacro("_DARWIN_UNLIMITED_SELECT", "1");
lib.root_module.addCMacro("_DARWIN_USE_64_BIT_INODE", "1");
}
const root = upstream.path("");
// C files common to all platforms
lib.addCSourceFiles(.{ .root = root, .files = &.{
"src/fs-poll.c",
"src/idna.c",
"src/inet.c",
"src/random.c",
"src/strscpy.c",
"src/strtok.c",
"src/threadpool.c",
"src/timer.c",
"src/uv-common.c",
"src/uv-data-getter-setters.c",
"src/version.c",
} });
if (target.result.os.tag != .windows) {
lib.addCSourceFiles(.{ .root = root, .files = &.{
"src/unix/async.c",
"src/unix/core.c",
"src/unix/dl.c",
"src/unix/fs.c",
"src/unix/getaddrinfo.c",
"src/unix/getnameinfo.c",
"src/unix/loop-watcher.c",
"src/unix/loop.c",
"src/unix/pipe.c",
"src/unix/poll.c",
"src/unix/process.c",
"src/unix/random-devurandom.c",
"src/unix/signal.c",
"src/unix/stream.c",
"src/unix/tcp.c",
"src/unix/thread.c",
"src/unix/tty.c",
"src/unix/udp.c",
} });
}
if (target.result.os.tag == .linux or target.result.isDarwin()) {
lib.addCSourceFiles(.{ .root = root, .files = &.{
"src/unix/proctitle.c",
} });
}
if (target.result.os.tag == .linux) {
lib.addCSourceFiles(.{ .root = root, .files = &.{
"src/unix/linux.c",
"src/unix/procfs-exepath.c",
"src/unix/random-getrandom.c",
"src/unix/random-sysctl-linux.c",
} });
}
if (target.result.isBSD()) {
lib.addCSourceFiles(.{ .root = root, .files = &.{
"src/unix/bsd-ifaddrs.c",
"src/unix/kqueue.c",
} });
}
if (target.result.isDarwin() or target.result.os.tag == .openbsd) {
lib.addCSourceFiles(.{ .root = root, .files = &.{
"src/unix/random-getentropy.c",
} });
}
if (target.result.isDarwin()) {
lib.addCSourceFiles(.{ .root = root, .files = &.{
"src/unix/darwin-proctitle.c",
"src/unix/darwin.c",
"src/unix/fsevents.c",
} });
}
b.installArtifact(lib);
}

12
deps/libuv/build.zig.zon vendored Normal file
View File

@ -0,0 +1,12 @@
.{
.name = "libuv",
.version = "1.48.0",
.paths = .{""},
.dependencies = .{
.libuv = .{
.url = "https://github.com/libuv/libuv/archive/v1.48.0.tar.gz",
.hash = "1220c2e1269cfee3735a7331f1fa4c13aa3e4f355fca5b402be3ea72a464c76f1324",
},
},
}

47
deps/msgpack_c/build.zig vendored Normal file
View File

@ -0,0 +1,47 @@
const std = @import("std");
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const upstream = b.dependency("msgpack_c", .{});
const lib = b.addStaticLibrary(.{
.name = "msgpack_c",
.target = target,
.optimize = optimize,
});
// via getEmittedIncludeTree to merge in configs properly
// lib.addIncludePath(upstream.path("include"));
lib.addIncludePath(upstream.path("src"));
// TODO: actually detect BIG-lyness of `target`
const sysdep = b.addConfigHeader(.{
.style = .{ .cmake = upstream.path("cmake/sysdep.h.in") },
.include_path = "msgpack/sysdep.h",
}, .{ .MSGPACK_ENDIAN_BIG_BYTE = "0", .MSGPACK_ENDIAN_LITTLE_BYTE = "1" });
lib.addConfigHeader(sysdep);
const pack_template = b.addConfigHeader(.{
.style = .{ .cmake = upstream.path("cmake/pack_template.h.in") },
.include_path = "msgpack/pack_template.h",
}, .{ .MSGPACK_ENDIAN_BIG_BYTE = "0", .MSGPACK_ENDIAN_LITTLE_BYTE = "1" });
lib.addConfigHeader(pack_template);
lib.installHeadersDirectory(upstream.path("include"), ".", .{});
lib.installConfigHeader(sysdep);
lib.installConfigHeader(pack_template);
lib.addIncludePath(lib.getEmittedIncludeTree());
lib.linkLibC();
lib.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{
"src/objectc.c",
"src/unpack.c",
"src/version.c",
"src/vrefbuffer.c",
"src/zone.c",
} });
b.installArtifact(lib);
}

12
deps/msgpack_c/build.zig.zon vendored Normal file
View File

@ -0,0 +1,12 @@
.{
.name = "msgpack_c",
.version = "6.0.1",
.paths = .{""},
.dependencies = .{
.msgpack_c = .{
.url = "https://github.com/msgpack/msgpack-c/archive/c-6.0.1.tar.gz",
.hash = "1220781494e79f4d4351608b6442f9f7814df38dea9e96858dadbb54a65e564134c3",
},
},
}

27
deps/unibilium/build.zig vendored Normal file
View File

@ -0,0 +1,27 @@
const std = @import("std");
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const upstream = b.dependency("unibilium", .{});
const lib = b.addStaticLibrary(.{
.name = "unibilium",
.target = target,
.optimize = optimize,
});
lib.addIncludePath(upstream.path(""));
lib.installHeader(upstream.path("unibilium.h"), "unibilium.h");
lib.linkLibC();
lib.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{
"unibilium.c",
"uninames.c",
"uniutil.c",
}, .flags = &.{"-DTERMINFO_DIRS=\"/etc/terminfo:/usr/share/terminfo\""} });
b.installArtifact(lib);
}

12
deps/unibilium/build.zig.zon vendored Normal file
View File

@ -0,0 +1,12 @@
.{
.name = "unibilium",
.version = "0.0.1",
.paths = .{""},
.dependencies = .{
.unibilium = .{
.url = "https://github.com/neovim/unibilium/archive/d72c3598e7ac5d1ebf86ee268b8b4ed95c0fa628.tar.gz",
.hash = "1220eb029114911f764a2266a8595829343b726d8aa81105a728920fdcba4b482a7d",
},
},
}

36
deps/vterm/build.zig vendored Normal file
View File

@ -0,0 +1,36 @@
const std = @import("std");
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const upstream = b.dependency("vterm", .{});
const lib = b.addStaticLibrary(.{
.name = "vterm",
.target = target,
.optimize = optimize,
});
lib.addIncludePath(upstream.path("src/"));
lib.addIncludePath(upstream.path("include/"));
// local additions: DECdrawing.inc and uk.inc (u w8t m8)
lib.addIncludePath(b.path("include/"));
lib.installHeadersDirectory(upstream.path("include"), ".", .{});
lib.linkLibC();
lib.addCSourceFiles(.{ .root = upstream.path("src"), .files = &.{
"encoding.c",
"keyboard.c",
"mouse.c",
"parser.c",
"pen.c",
"screen.c",
"state.c",
"unicode.c",
"vterm.c",
} });
b.installArtifact(lib);
}

12
deps/vterm/build.zig.zon vendored Normal file
View File

@ -0,0 +1,12 @@
.{
.name = "vterm",
.version = "0.3.3",
.paths = .{""},
.dependencies = .{
.vterm = .{
.url = "https://github.com/neovim/libvterm/archive/v0.3.3.tar.gz",
.hash = "1220184ae54d2331deb1be5d905978205c2731714e4b0ae8587e72c4ce02da317195",
},
},
}

View File

@ -0,0 +1,36 @@
static const struct StaticTableEncoding encoding_DECdrawing = {
{ .decode = &decode_table },
{
[0x60] = 0x25C6,
[0x61] = 0x2592,
[0x62] = 0x2409,
[0x63] = 0x240C,
[0x64] = 0x240D,
[0x65] = 0x240A,
[0x66] = 0x00B0,
[0x67] = 0x00B1,
[0x68] = 0x2424,
[0x69] = 0x240B,
[0x6a] = 0x2518,
[0x6b] = 0x2510,
[0x6c] = 0x250C,
[0x6d] = 0x2514,
[0x6e] = 0x253C,
[0x6f] = 0x23BA,
[0x70] = 0x23BB,
[0x71] = 0x2500,
[0x72] = 0x23BC,
[0x73] = 0x23BD,
[0x74] = 0x251C,
[0x75] = 0x2524,
[0x76] = 0x2534,
[0x77] = 0x252C,
[0x78] = 0x2502,
[0x79] = 0x2A7D,
[0x7a] = 0x2A7E,
[0x7b] = 0x03C0,
[0x7c] = 0x2260,
[0x7d] = 0x00A3,
[0x7e] = 0x00B7,
}
};

6
deps/vterm/include/encoding/uk.inc vendored Normal file
View File

@ -0,0 +1,6 @@
static const struct StaticTableEncoding encoding_uk = {
{ .decode = &decode_table },
{
[0x23] = 0x00a3,
}
};

View File

@ -23,6 +23,7 @@
" 2024 Aug 15 by Vim Project: style changes, prevent E121 (#15501) " 2024 Aug 15 by Vim Project: style changes, prevent E121 (#15501)
" 2024 Aug 22 by Vim Project: fix mf-selection highlight (#15551) " 2024 Aug 22 by Vim Project: fix mf-selection highlight (#15551)
" 2024 Aug 22 by Vim Project: adjust echo output of mx command (#15550) " 2024 Aug 22 by Vim Project: adjust echo output of mx command (#15550)
" 2024 Sep 15 by Vim Project: more strict confirmation dialog (#15680)
" }}} " }}}
" Former Maintainer: Charles E Campbell " Former Maintainer: Charles E Campbell
" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim " GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
@ -11275,7 +11276,7 @@ fun! s:NetrwLocalRm(path) range
let ok= s:NetrwLocalRmFile(a:path,fname,all) let ok= s:NetrwLocalRmFile(a:path,fname,all)
if ok =~# 'q\%[uit]' || ok == "no" if ok =~# 'q\%[uit]' || ok == "no"
break break
elseif ok =~# 'a\%[ll]' elseif ok =~# '^a\%[ll]$'
let all= 1 let all= 1
endif endif
endfor endfor
@ -11304,7 +11305,7 @@ fun! s:NetrwLocalRm(path) range
let ok= s:NetrwLocalRmFile(a:path,curword,all) let ok= s:NetrwLocalRmFile(a:path,curword,all)
if ok =~# 'q\%[uit]' || ok == "no" if ok =~# 'q\%[uit]' || ok == "no"
break break
elseif ok =~# 'a\%[ll]' elseif ok =~# '^a\%[ll]$'
let all= 1 let all= 1
endif endif
let ctr= ctr + 1 let ctr= ctr + 1
@ -11351,12 +11352,12 @@ fun! s:NetrwLocalRmFile(path,fname,all)
" call Decho("response: ok<".ok.">",'~'.expand("<slnum>")) " call Decho("response: ok<".ok.">",'~'.expand("<slnum>"))
let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e') let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
" call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>")) " call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>"))
if ok =~# 'a\%[ll]' if ok =~# '^a\%[ll]$'
let all= 1 let all= 1
endif endif
endif endif
if all || ok =~# 'y\%[es]' || ok == "" if all || ok =~# '^y\%[es]$' || ok == ""
let ret= s:NetrwDelete(rmfile) let ret= s:NetrwDelete(rmfile)
" call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>")) " call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>"))
endif endif
@ -11372,13 +11373,13 @@ fun! s:NetrwLocalRmFile(path,fname,all)
if ok == "" if ok == ""
let ok="no" let ok="no"
endif endif
if ok =~# 'a\%[ll]' if ok =~# '^a\%[ll]$'
let all= 1 let all= 1
endif endif
endif endif
let rmfile= substitute(rmfile,'[\/]$','','e') let rmfile= substitute(rmfile,'[\/]$','','e')
if all || ok =~# 'y\%[es]' || ok == "" if all || ok =~# '^y\%[es]$' || ok == ""
if delete(rmfile,"rf") if delete(rmfile,"rf")
call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103) call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103)
endif endif

View File

@ -2559,7 +2559,7 @@ vim.ui.input({opts}, {on_confirm}) *vim.ui.input()*
typed (it might be an empty string if nothing was typed (it might be an empty string if nothing was
entered), or `nil` if the user aborted the dialog. entered), or `nil` if the user aborted the dialog.
vim.ui.open({path}) *vim.ui.open()* vim.ui.open({path}, {opt}) *vim.ui.open()*
Opens `path` with the system default handler (macOS `open`, Windows Opens `path` with the system default handler (macOS `open`, Windows
`explorer.exe`, Linux `xdg-open`, …), or returns (but does not show) an `explorer.exe`, Linux `xdg-open`, …), or returns (but does not show) an
error message on failure. error message on failure.
@ -2570,6 +2570,8 @@ vim.ui.open({path}) *vim.ui.open()*
-- Asynchronous. -- Asynchronous.
vim.ui.open("https://neovim.io/") vim.ui.open("https://neovim.io/")
vim.ui.open("~/path/to/file") vim.ui.open("~/path/to/file")
-- Use the "osurl" command to handle the path or URL.
vim.ui.open("gh#neovim/neovim!29490", { cmd = { 'osurl' } })
-- Synchronous (wait until the process exits). -- Synchronous (wait until the process exits).
local cmd, err = vim.ui.open("$VIMRUNTIME") local cmd, err = vim.ui.open("$VIMRUNTIME")
if cmd then if cmd then
@ -2579,6 +2581,8 @@ vim.ui.open({path}) *vim.ui.open()*
Parameters: ~ Parameters: ~
• {path} (`string`) Path or URL to open • {path} (`string`) Path or URL to open
• {opt} (`{ cmd?: string[] }?`) Options
• cmd string[]|nil Command used to open the path or URL.
Return (multiple): ~ Return (multiple): ~
(`vim.SystemObj?`) Command object, or nil if not found. (`vim.SystemObj?`) Command object, or nil if not found.

View File

@ -189,11 +189,15 @@ TREESITTER
TUI TUI
• TODO • |log| messages written by the builtin UI client (TUI, |--remote-ui|) are
now prefixed with "ui" instead of "?".
UI UI
• TODO • |vim.ui.open()| (by default bound to |gx|) accepts an `opt.cmd` parameter
which controls the tool used to open the given path or URL. If you want to
globally set this, you can override vim.ui.open using the same approach
described at |vim.paste()|.
============================================================================== ==============================================================================
CHANGED FEATURES *news-changed* CHANGED FEATURES *news-changed*

View File

@ -6713,7 +6713,7 @@ A jump table for the options with a short description can be found at |Q_op|.
global global
When on, the title of the window will be set to the value of When on, the title of the window will be set to the value of
'titlestring' (if it is not empty), or to: 'titlestring' (if it is not empty), or to:
filename [+=-] (path) - NVIM filename [+=-] (path) - Nvim
Where: Where:
filename the name of the file being edited filename the name of the file being edited
- indicates the file cannot be modified, 'ma' off - indicates the file cannot be modified, 'ma' off
@ -6721,7 +6721,7 @@ A jump table for the options with a short description can be found at |Q_op|.
= indicates the file is read-only = indicates the file is read-only
=+ indicates the file is read-only and modified =+ indicates the file is read-only and modified
(path) is the path of the file being edited (path) is the path of the file being edited
- NVIM the server name |v:servername| or "NVIM" - Nvim the server name |v:servername| or "Nvim"
*'titlelen'* *'titlelen'*
'titlelen' number (default 85) 'titlelen' number (default 85)

View File

@ -1683,6 +1683,12 @@ In order to highlight nested parens with different colors, define colors for
or > or >
:hi javaParen ctermfg=blue guifg=#0000ff :hi javaParen ctermfg=blue guifg=#0000ff
Certain modifiers are incompatible with each other, e.g. `abstract` and
`final`: >
:syn list javaConceptKind
and can be differently highlighted as a group than other modifiers with >
:hi link javaConceptKind NonText
If you notice highlighting errors while scrolling backwards, which are fixed If you notice highlighting errors while scrolling backwards, which are fixed
when redrawing with CTRL-L, try setting the "g:java_minlines" variable to when redrawing with CTRL-L, try setting the "g:java_minlines" variable to
a larger number: > a larger number: >

View File

@ -0,0 +1,2 @@
pub const inspect_module = @embedFile("./lua/vim/inspect.lua");
pub const shared_module = @embedFile("./lua/vim/shared.lua");

View File

@ -9,8 +9,8 @@
local function get_commentstring(ref_position) local function get_commentstring(ref_position)
local buf_cs = vim.bo.commentstring local buf_cs = vim.bo.commentstring
local has_ts_parser, ts_parser = pcall(vim.treesitter.get_parser) local ts_parser = vim.treesitter._get_parser()
if not has_ts_parser then if not ts_parser then
return buf_cs return buf_cs
end end

View File

@ -213,23 +213,25 @@ end
--- Default menus --- Default menus
do do
--- Right click popup menu --- Right click popup menu
local function def_menu(ctx) vim.cmd([[
vim.cmd([[ anoremenu PopUp.Go\ to\ definition <Cmd>lua vim.lsp.buf.definition()<CR>
anoremenu PopUp.Go\ to\ definition <Cmd>lua vim.lsp.buf.definition()<CR> amenu PopUp.Open\ in\ web\ browser gx
amenu PopUp.Open\ in\ web\ browser gx anoremenu PopUp.Inspect <Cmd>Inspect<CR>
anoremenu PopUp.Inspect <Cmd>Inspect<CR> anoremenu PopUp.-1- <Nop>
anoremenu PopUp.-1- <Nop> vnoremenu PopUp.Cut "+x
vnoremenu PopUp.Cut "+x vnoremenu PopUp.Copy "+y
vnoremenu PopUp.Copy "+y anoremenu PopUp.Paste "+gP
anoremenu PopUp.Paste "+gP vnoremenu PopUp.Paste "+P
vnoremenu PopUp.Paste "+P vnoremenu PopUp.Delete "_x
vnoremenu PopUp.Delete "_x nnoremenu PopUp.Select\ All ggVG
nnoremenu PopUp.Select\ All ggVG vnoremenu PopUp.Select\ All gg0oG$
vnoremenu PopUp.Select\ All gg0oG$ inoremenu PopUp.Select\ All <C-Home><C-O>VG
inoremenu PopUp.Select\ All <C-Home><C-O>VG anoremenu PopUp.-2- <Nop>
anoremenu PopUp.-2- <Nop> anoremenu PopUp.How-to\ disable\ mouse <Cmd>help disable-mouse<CR>
anoremenu PopUp.How-to\ disable\ mouse <Cmd>help disable-mouse<CR> ]])
local function enable_ctx_menu(ctx)
vim.cmd([[
amenu disable PopUp.Go\ to\ definition amenu disable PopUp.Go\ to\ definition
amenu disable PopUp.Open\ in\ web\ browser amenu disable PopUp.Open\ in\ web\ browser
]]) ]])
@ -240,7 +242,6 @@ do
vim.cmd([[anoremenu enable PopUp.Go\ to\ definition]]) vim.cmd([[anoremenu enable PopUp.Go\ to\ definition]])
end end
end end
def_menu()
local nvim_popupmenu_augroup = vim.api.nvim_create_augroup('nvim_popupmenu', {}) local nvim_popupmenu_augroup = vim.api.nvim_create_augroup('nvim_popupmenu', {})
vim.api.nvim_create_autocmd('MenuPopup', { vim.api.nvim_create_autocmd('MenuPopup', {
@ -252,7 +253,7 @@ do
local urls = require('vim.ui')._get_urls() local urls = require('vim.ui')._get_urls()
local url = vim.startswith(urls[1], 'http') local url = vim.startswith(urls[1], 'http')
local ctx = url and 'url' or (vim.lsp.get_clients({ bufnr = 0 })[1] and 'lsp' or nil) local ctx = url and 'url' or (vim.lsp.get_clients({ bufnr = 0 })[1] and 'lsp' or nil)
def_menu(ctx) enable_ctx_menu(ctx)
end, end,
}) })
end end

View File

@ -7255,7 +7255,7 @@ vim.go.tm = vim.go.timeoutlen
--- When on, the title of the window will be set to the value of --- When on, the title of the window will be set to the value of
--- 'titlestring' (if it is not empty), or to: --- 'titlestring' (if it is not empty), or to:
--- filename [+=-] (path) - NVIM --- filename [+=-] (path) - Nvim
--- Where: --- Where:
--- filename the name of the file being edited --- filename the name of the file being edited
--- - indicates the file cannot be modified, 'ma' off --- - indicates the file cannot be modified, 'ma' off
@ -7263,7 +7263,7 @@ vim.go.tm = vim.go.timeoutlen
--- = indicates the file is read-only --- = indicates the file is read-only
--- =+ indicates the file is read-only and modified --- =+ indicates the file is read-only and modified
--- (path) is the path of the file being edited --- (path) is the path of the file being edited
--- - NVIM the server name `v:servername` or "NVIM" --- - Nvim the server name `v:servername` or "Nvim"
--- ---
--- @type boolean --- @type boolean
vim.o.title = false vim.o.title = false

View File

@ -6703,7 +6703,7 @@ function vim.fn.printf(fmt, expr1) end
--- If the buffer doesn't exist or isn't a prompt buffer, an empty --- If the buffer doesn't exist or isn't a prompt buffer, an empty
--- string is returned. --- string is returned.
--- ---
--- @param buf any --- @param buf integer|string
--- @return any --- @return any
function vim.fn.prompt_getprompt(buf) end function vim.fn.prompt_getprompt(buf) end
@ -6738,8 +6738,8 @@ function vim.fn.prompt_getprompt(buf) end
--- endfunc --- endfunc
--- call prompt_setcallback(bufnr(), function('s:TextEntered')) --- call prompt_setcallback(bufnr(), function('s:TextEntered'))
--- ---
--- @param buf any --- @param buf integer|string
--- @param expr any --- @param expr string|function
--- @return any --- @return any
function vim.fn.prompt_setcallback(buf, expr) end function vim.fn.prompt_setcallback(buf, expr) end
@ -6751,8 +6751,8 @@ function vim.fn.prompt_setcallback(buf, expr) end
--- mode. Without setting a callback Vim will exit Insert mode, --- mode. Without setting a callback Vim will exit Insert mode,
--- as in any buffer. --- as in any buffer.
--- ---
--- @param buf any --- @param buf integer|string
--- @param expr any --- @param expr string|function
--- @return any --- @return any
function vim.fn.prompt_setinterrupt(buf, expr) end function vim.fn.prompt_setinterrupt(buf, expr) end
@ -6763,8 +6763,8 @@ function vim.fn.prompt_setinterrupt(buf, expr) end
--- call prompt_setprompt(bufnr(''), 'command: ') --- call prompt_setprompt(bufnr(''), 'command: ')
--- < --- <
--- ---
--- @param buf any --- @param buf integer|string
--- @param text any --- @param text string
--- @return any --- @return any
function vim.fn.prompt_setprompt(buf, text) end function vim.fn.prompt_setprompt(buf, text) end

View File

@ -280,12 +280,7 @@ local extension = {
cfi = 'cf', cfi = 'cf',
hgrc = 'cfg', hgrc = 'cfg',
cfg = detect.cfg, cfg = detect.cfg,
cfG = detect.cfg,
cFg = detect.cfg,
cFG = detect.cfg,
Cfg = detect.cfg, Cfg = detect.cfg,
CfG = detect.cfg,
CFg = detect.cfg,
CFG = detect.cfg, CFG = detect.cfg,
chf = 'ch', chf = 'ch',
chai = 'chaiscript', chai = 'chaiscript',
@ -370,12 +365,7 @@ local extension = {
drt = 'dart', drt = 'dart',
ds = 'datascript', ds = 'datascript',
dat = detect.dat, dat = detect.dat,
daT = detect.dat,
dAt = detect.dat,
dAT = detect.dat,
Dat = detect.dat, Dat = detect.dat,
DaT = detect.dat,
DAt = detect.dat,
DAT = detect.dat, DAT = detect.dat,
dcd = 'dcd', dcd = 'dcd',
decl = detect.decl, decl = detect.decl,
@ -622,6 +612,7 @@ local extension = {
jsx = 'javascriptreact', jsx = 'javascriptreact',
clp = 'jess', clp = 'jess',
jgr = 'jgraph', jgr = 'jgraph',
jinja = 'jinja',
jjdescription = 'jj', jjdescription = 'jj',
j73 = 'jovial', j73 = 'jovial',
jov = 'jovial', jov = 'jovial',
@ -658,12 +649,7 @@ local extension = {
kt = 'kotlin', kt = 'kotlin',
ktm = 'kotlin', ktm = 'kotlin',
sub = 'krl', sub = 'krl',
suB = 'krl',
sUb = 'krl',
sUB = 'krl',
Sub = 'krl', Sub = 'krl',
SuB = 'krl',
SUb = 'krl',
SUB = 'krl', SUB = 'krl',
ks = 'kscript', ks = 'kscript',
k = 'kwt', k = 'kwt',
@ -699,12 +685,7 @@ local extension = {
lite = 'lite', lite = 'lite',
livemd = 'livebook', livemd = 'livebook',
log = detect.log, log = detect.log,
loG = detect.log,
lOg = detect.log,
lOG = detect.log,
Log = detect.log, Log = detect.log,
LoG = detect.log,
LOg = detect.log,
LOG = detect.log, LOG = detect.log,
lgt = 'logtalk', lgt = 'logtalk',
lotos = 'lotos', lotos = 'lotos',
@ -773,12 +754,7 @@ local extension = {
mmp = 'mmp', mmp = 'mmp',
mms = detect.mms, mms = detect.mms,
mod = detect.mod, mod = detect.mod,
moD = detect.mod,
mOd = detect.mod,
mOD = detect.mod,
Mod = detect.mod, Mod = detect.mod,
MoD = detect.mod,
MOd = detect.mod,
MOD = detect.mod, MOD = detect.mod,
DEF = 'modula2', DEF = 'modula2',
m3 = 'modula3', m3 = 'modula3',
@ -948,12 +924,7 @@ local extension = {
ih = 'ppwiz', ih = 'ppwiz',
action = 'privoxy', action = 'privoxy',
prg = detect.prg, prg = detect.prg,
prG = detect.prg,
pRg = detect.prg,
pRG = detect.prg,
Prg = detect.prg, Prg = detect.prg,
PrG = detect.prg,
PRg = detect.prg,
PRG = detect.prg, PRG = detect.prg,
pc = 'proc', pc = 'proc',
pdb = 'prolog', pdb = 'prolog',
@ -1053,6 +1024,7 @@ local extension = {
rake = 'ruby', rake = 'ruby',
rs = 'rust', rs = 'rust',
sage = 'sage', sage = 'sage',
sls = 'salt',
sas = 'sas', sas = 'sas',
sass = 'sass', sass = 'sass',
sa = 'sather', sa = 'sather',
@ -1133,12 +1105,7 @@ local extension = {
sqr = 'sqr', sqr = 'sqr',
nut = 'squirrel', nut = 'squirrel',
src = detect.src, src = detect.src,
srC = detect.src,
sRc = detect.src,
sRC = detect.src,
Src = detect.src, Src = detect.src,
SrC = detect.src,
SRc = detect.src,
SRC = detect.src, SRC = detect.src,
s28 = 'srec', s28 = 'srec',
s37 = 'srec', s37 = 'srec',
@ -1164,15 +1131,11 @@ local extension = {
svelte = 'svelte', svelte = 'svelte',
svg = 'svg', svg = 'svg',
swift = 'swift', swift = 'swift',
swiftinterface = 'swift',
swig = 'swig', swig = 'swig',
swg = 'swig', swg = 'swig',
sys = detect.sys, sys = detect.sys,
syS = detect.sys,
sYs = detect.sys,
sYS = detect.sys,
Sys = detect.sys, Sys = detect.sys,
SyS = detect.sys,
SYs = detect.sys,
SYS = detect.sys, SYS = detect.sys,
svh = 'systemverilog', svh = 'systemverilog',
sv = 'systemverilog', sv = 'systemverilog',

View File

@ -447,11 +447,9 @@ function M.document_symbol(opts)
request_with_opts(ms.textDocument_documentSymbol, params, opts) request_with_opts(ms.textDocument_documentSymbol, params, opts)
end end
--- @param call_hierarchy_items lsp.CallHierarchyItem[]? --- @param call_hierarchy_items lsp.CallHierarchyItem[]
--- @return lsp.CallHierarchyItem?
local function pick_call_hierarchy_item(call_hierarchy_items) local function pick_call_hierarchy_item(call_hierarchy_items)
if not call_hierarchy_items then
return
end
if #call_hierarchy_items == 1 then if #call_hierarchy_items == 1 then
return call_hierarchy_items[1] return call_hierarchy_items[1]
end end
@ -476,7 +474,7 @@ local function call_hierarchy(method)
vim.notify(err.message, vim.log.levels.WARN) vim.notify(err.message, vim.log.levels.WARN)
return return
end end
if not result then if not result or vim.tbl_isempty(result) then
vim.notify('No item resolved', vim.log.levels.WARN) vim.notify('No item resolved', vim.log.levels.WARN)
return return
end end

View File

@ -154,7 +154,7 @@ end
---@param encoding string utf-8|utf-16|utf-32| defaults to utf-16 ---@param encoding string utf-8|utf-16|utf-32| defaults to utf-16
---@return integer byte (utf-8) index of `encoding` index `index` in `line` ---@return integer byte (utf-8) index of `encoding` index `index` in `line`
function M._str_byteindex_enc(line, index, encoding) function M._str_byteindex_enc(line, index, encoding)
local len = vim.fn.strlen(line) local len = #line
if index > len then if index > len then
-- LSP spec: if character > line length, default to the line length. -- LSP spec: if character > line length, default to the line length.
-- https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#position -- https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#position
@ -167,7 +167,7 @@ function M._str_byteindex_enc(line, index, encoding)
if index then if index then
return index return index
else else
return #line return len
end end
elseif encoding == 'utf-16' then elseif encoding == 'utf-16' then
return vim.str_byteindex(line, index, true) return vim.str_byteindex(line, index, true)

View File

@ -74,14 +74,14 @@ end
--- Returns the parser for a specific buffer and attaches it to the buffer --- Returns the parser for a specific buffer and attaches it to the buffer
--- ---
--- If needed, this will create the parser. --- If needed, this will create the parser. If no parser can be found or created, returns `nil`.
--- ---
---@param bufnr (integer|nil) Buffer the parser should be tied to (default: current buffer) ---@param bufnr (integer|nil) Buffer the parser should be tied to (default: current buffer)
---@param lang (string|nil) Language of this parser (default: from buffer filetype) ---@param lang (string|nil) Language of this parser (default: from buffer filetype)
---@param opts (table|nil) Options to pass to the created language tree ---@param opts (table|nil) Options to pass to the created language tree
--- ---
---@return vim.treesitter.LanguageTree object to use for parsing ---@return vim.treesitter.LanguageTree? object to use for parsing, or `nil` if not found
function M.get_parser(bufnr, lang, opts) function M._get_parser(bufnr, lang, opts)
opts = opts or {} opts = opts or {}
if bufnr == nil or bufnr == 0 then if bufnr == nil or bufnr == 0 then
@ -94,18 +94,14 @@ function M.get_parser(bufnr, lang, opts)
if not valid_lang(lang) then if not valid_lang(lang) then
if not parsers[bufnr] then if not parsers[bufnr] then
error( return nil
string.format(
'There is no parser available for buffer %d and one could not be'
.. ' created because lang could not be determined. Either pass lang'
.. ' or set the buffer filetype',
bufnr
)
)
end end
elseif parsers[bufnr] == nil or parsers[bufnr]:lang() ~= lang then elseif parsers[bufnr] == nil or parsers[bufnr]:lang() ~= lang then
assert(lang, 'lang should be valid') local parser = vim.F.npcall(M._create_parser, bufnr, lang, opts)
parsers[bufnr] = M._create_parser(bufnr, lang, opts) if not parser then
return nil
end
parsers[bufnr] = parser
end end
parsers[bufnr]:register_cbs(opts.buf_attach_cbs) parsers[bufnr]:register_cbs(opts.buf_attach_cbs)
@ -113,6 +109,29 @@ function M.get_parser(bufnr, lang, opts)
return parsers[bufnr] return parsers[bufnr]
end end
--- Returns the parser for a specific buffer and attaches it to the buffer
---
--- If needed, this will create the parser.
---
---@param bufnr (integer|nil) Buffer the parser should be tied to (default: current buffer)
---@param lang (string|nil) Language of this parser (default: from buffer filetype)
---@param opts (table|nil) Options to pass to the created language tree
---
---@return vim.treesitter.LanguageTree object to use for parsing
function M.get_parser(bufnr, lang, opts)
-- TODO(ribru17): Remove _get_parser and move that logic back here once the breaking function
-- signature change is acceptable.
local parser = M._get_parser(bufnr, lang, opts)
if not parser then
vim.notify_once(
'WARNING: vim.treesitter.get_parser will return nil instead of raising an error in Neovim 0.12',
vim.log.levels.WARN
)
error('Parser not found.')
end
return parser
end
--- Returns a string parser --- Returns a string parser
--- ---
---@param str string Text to parse ---@param str string Text to parse
@ -386,7 +405,7 @@ function M.get_node(opts)
local ts_range = { row, col, row, col } local ts_range = { row, col, row, col }
local root_lang_tree = M.get_parser(bufnr, opts.lang) local root_lang_tree = M._get_parser(bufnr, opts.lang)
if not root_lang_tree then if not root_lang_tree then
return return
end end
@ -419,7 +438,11 @@ end
---@param lang (string|nil) Language of the parser (default: from buffer filetype) ---@param lang (string|nil) Language of the parser (default: from buffer filetype)
function M.start(bufnr, lang) function M.start(bufnr, lang)
bufnr = bufnr or api.nvim_get_current_buf() bufnr = bufnr or api.nvim_get_current_buf()
local parser = M.get_parser(bufnr, lang) local parser = M._get_parser(bufnr, lang)
if not parser then
vim.notify('No parser for the given buffer.', vim.log.levels.WARN)
return
end
M.highlighter.new(parser) M.highlighter.new(parser)
end end

View File

@ -114,7 +114,7 @@ local function compute_folds_levels(bufnr, info, srow, erow, parse_injections)
srow = srow or 0 srow = srow or 0
erow = erow or api.nvim_buf_line_count(bufnr) erow = erow or api.nvim_buf_line_count(bufnr)
local parser = ts.get_parser(bufnr) local parser = assert(ts._get_parser(bufnr))
parser:parse(parse_injections and { srow, erow } or nil) parser:parse(parse_injections and { srow, erow } or nil)
@ -392,7 +392,7 @@ function M.foldexpr(lnum)
lnum = lnum or vim.v.lnum lnum = lnum or vim.v.lnum
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
local parser = vim.F.npcall(ts.get_parser, bufnr) local parser = ts._get_parser(bufnr)
if not parser then if not parser then
return '0' return '0'
end end

View File

@ -172,7 +172,7 @@ function M.lint(buf, opts)
--- @type (table|nil) --- @type (table|nil)
local parser_info = vim.F.npcall(vim.treesitter.language.inspect, lang) local parser_info = vim.F.npcall(vim.treesitter.language.inspect, lang)
local parser = vim.treesitter.get_parser(buf) local parser = assert(vim.treesitter._get_parser(buf), 'query parser not found.')
parser:parse() parser:parse()
parser:for_each_tree(function(tree, ltree) parser:for_each_tree(function(tree, ltree)
if ltree:lang() == 'query' then if ltree:lang() == 'query' then

View File

@ -76,10 +76,9 @@ end
--- ---
---@package ---@package
function TSTreeView:new(bufnr, lang) function TSTreeView:new(bufnr, lang)
local ok, parser = pcall(vim.treesitter.get_parser, bufnr or 0, lang) local parser = vim.treesitter._get_parser(bufnr or 0, lang)
if not ok then if not parser then
local err = parser --[[ @as string ]] return nil, 'No parser available for the given buffer.'
return nil, 'No parser available for the given buffer:\n' .. err
end end
-- For each child tree (injected language), find the root of the tree and locate the node within -- For each child tree (injected language), find the root of the tree and locate the node within
@ -539,7 +538,7 @@ local edit_ns = api.nvim_create_namespace('treesitter/dev-edit')
local function update_editor_highlights(query_win, base_win, lang) local function update_editor_highlights(query_win, base_win, lang)
local base_buf = api.nvim_win_get_buf(base_win) local base_buf = api.nvim_win_get_buf(base_win)
local query_buf = api.nvim_win_get_buf(query_win) local query_buf = api.nvim_win_get_buf(query_win)
local parser = vim.treesitter.get_parser(base_buf, lang) local parser = assert(vim.treesitter._get_parser(base_buf, lang))
api.nvim_buf_clear_namespace(base_buf, edit_ns, 0, -1) api.nvim_buf_clear_namespace(base_buf, edit_ns, 0, -1)
local query_content = table.concat(api.nvim_buf_get_lines(query_buf, 0, -1, false), '\n') local query_content = table.concat(api.nvim_buf_get_lines(query_buf, 0, -1, false), '\n')
@ -596,8 +595,8 @@ function M.edit_query(lang)
end end
vim.cmd(cmd) vim.cmd(cmd)
local ok, parser = pcall(vim.treesitter.get_parser, buf, lang) local parser = vim.treesitter._get_parser(buf, lang)
if not ok then if not parser then
return nil, 'No parser available for the given buffer' return nil, 'No parser available for the given buffer'
end end
lang = parser:lang() lang = parser:lang()

View File

@ -117,6 +117,8 @@ end
--- -- Asynchronous. --- -- Asynchronous.
--- vim.ui.open("https://neovim.io/") --- vim.ui.open("https://neovim.io/")
--- vim.ui.open("~/path/to/file") --- vim.ui.open("~/path/to/file")
--- -- Use the "osurl" command to handle the path or URL.
--- vim.ui.open("gh#neovim/neovim!29490", { cmd = { 'osurl' } })
--- -- Synchronous (wait until the process exits). --- -- Synchronous (wait until the process exits).
--- local cmd, err = vim.ui.open("$VIMRUNTIME") --- local cmd, err = vim.ui.open("$VIMRUNTIME")
--- if cmd then --- if cmd then
@ -125,12 +127,14 @@ end
--- ``` --- ```
--- ---
---@param path string Path or URL to open ---@param path string Path or URL to open
---@param opt? { cmd?: string[] } Options
--- - cmd string[]|nil Command used to open the path or URL.
--- ---
---@return vim.SystemObj|nil # Command object, or nil if not found. ---@return vim.SystemObj|nil # Command object, or nil if not found.
---@return nil|string # Error message on failure, or nil on success. ---@return nil|string # Error message on failure, or nil on success.
--- ---
---@see |vim.system()| ---@see |vim.system()|
function M.open(path) function M.open(path, opt)
vim.validate({ vim.validate({
path = { path, 'string' }, path = { path, 'string' },
}) })
@ -139,12 +143,13 @@ function M.open(path)
path = vim.fs.normalize(path) path = vim.fs.normalize(path)
end end
local cmd --- @type string[] opt = opt or {}
local opts --- @type vim.SystemOpts local cmd ---@type string[]
local job_opt = { text = true, detach = true } --- @type vim.SystemOpts
opts = { text = true, detach = true } if opt.cmd then
cmd = vim.list_extend(opt.cmd --[[@as string[] ]], { path })
if vim.fn.has('mac') == 1 then elseif vim.fn.has('mac') == 1 then
cmd = { 'open', path } cmd = { 'open', path }
elseif vim.fn.has('win32') == 1 then elseif vim.fn.has('win32') == 1 then
if vim.fn.executable('rundll32') == 1 then if vim.fn.executable('rundll32') == 1 then
@ -154,8 +159,8 @@ function M.open(path)
end end
elseif vim.fn.executable('xdg-open') == 1 then elseif vim.fn.executable('xdg-open') == 1 then
cmd = { 'xdg-open', path } cmd = { 'xdg-open', path }
opts.stdout = false job_opt.stdout = false
opts.stderr = false job_opt.stderr = false
elseif vim.fn.executable('wslview') == 1 then elseif vim.fn.executable('wslview') == 1 then
cmd = { 'wslview', path } cmd = { 'wslview', path }
elseif vim.fn.executable('explorer.exe') == 1 then elseif vim.fn.executable('explorer.exe') == 1 then
@ -164,7 +169,7 @@ function M.open(path)
return nil, 'vim.ui.open: no handler found (tried: wslview, explorer.exe, xdg-open)' return nil, 'vim.ui.open: no handler found (tried: wslview, explorer.exe, xdg-open)'
end end
return vim.system(cmd, opts), nil return vim.system(cmd, job_opt), nil
end end
--- Returns all URLs at cursor, if any. --- Returns all URLs at cursor, if any.

View File

@ -33,7 +33,7 @@ end
--- Show a table of contents for the help buffer in a loclist --- Show a table of contents for the help buffer in a loclist
function M.show_toc() function M.show_toc()
local bufnr = vim.api.nvim_get_current_buf() local bufnr = vim.api.nvim_get_current_buf()
local parser = vim.treesitter.get_parser(bufnr, 'vimdoc') local parser = assert(vim.treesitter._get_parser(bufnr, 'vimdoc'), 'vimdoc parser not found.')
local query = vim.treesitter.query.parse( local query = vim.treesitter.query.parse(
parser:lang(), parser:lang(),
[[ [[

View File

@ -45,6 +45,11 @@
(link_destination) @_url (link_destination) @_url
(#set! @_label url @_url)) (#set! @_label url @_url))
(image
(image_description) @_label
(link_destination) @_url
(#set! @_label url @_url))
; Conceal image links ; Conceal image links
(image (image
[ [

View File

@ -33,7 +33,10 @@
")" ")"
] @punctuation.bracket ] @punctuation.bracket
":" @punctuation.delimiter [
":"
"/"
] @punctuation.delimiter
[ [
"@" "@"

View File

@ -3,7 +3,7 @@
" Maintainer: Aliaksei Budavei <0x000c70 AT gmail DOT com> " Maintainer: Aliaksei Budavei <0x000c70 AT gmail DOT com>
" Former Maintainer: Claudio Fleiner <claudio@fleiner.com> " Former Maintainer: Claudio Fleiner <claudio@fleiner.com>
" Repository: https://github.com/zzzyxwvut/java-vim.git " Repository: https://github.com/zzzyxwvut/java-vim.git
" Last Change: 2024 Sep 10 " Last Change: 2024 Sep 11
" Please check :help java.vim for comments on some of the options available. " Please check :help java.vim for comments on some of the options available.
@ -663,7 +663,7 @@ hi def link javaStorageClass StorageClass
hi def link javaMethodDecl javaStorageClass hi def link javaMethodDecl javaStorageClass
hi def link javaClassDecl javaStorageClass hi def link javaClassDecl javaStorageClass
hi def link javaScopeDecl javaStorageClass hi def link javaScopeDecl javaStorageClass
hi def link javaConceptKind NonText hi def link javaConceptKind javaStorageClass
hi def link javaBoolean Boolean hi def link javaBoolean Boolean
hi def link javaSpecial Special hi def link javaSpecial Special

86
runtime/syntax/jinja.vim Normal file
View File

@ -0,0 +1,86 @@
" Vim syntax file
" Language: Jinja
" Maintainer: Gregory Anders
" Upstream: https://gitlab.com/HiPhish/jinja.vim
if exists('b:current_syntax')
finish
endif
syntax case match
syntax sync fromstart
" Jinja template built-in tags and parameters (without filter, macro, is and raw, they
" have special threatment)
syn keyword jinjaStatement containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained and if else in not or recursive as import
syn keyword jinjaStatement containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained is filter skipwhite nextgroup=jinjaFilter
syn keyword jinjaStatement containedin=jinjaTagBlock contained macro skipwhite nextgroup=jinjaFunction
syn keyword jinjaStatement containedin=jinjaTagBlock contained block skipwhite nextgroup=jinjaBlockName
" Variable Names
syn match jinjaVariable containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[a-zA-Z_][a-zA-Z0-9_]*/
syn keyword jinjaSpecial containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained false true none False True None loop super caller varargs kwargs
" Filters
syn match jinjaOperator "|" containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained skipwhite nextgroup=jinjaFilter
syn match jinjaFilter contained /[a-zA-Z_][a-zA-Z0-9_]*/
syn match jinjaFunction contained /[a-zA-Z_][a-zA-Z0-9_]*/
syn match jinjaBlockName contained /[a-zA-Z_][a-zA-Z0-9_]*/
" Jinja template constants
syn region jinjaString containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained start=/"/ skip=/\(\\\)\@<!\(\(\\\\\)\@>\)*\\"/ end=/"/
syn region jinjaString containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained start=/'/ skip=/\(\\\)\@<!\(\(\\\\\)\@>\)*\\'/ end=/'/
syn match jinjaNumber containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[0-9]\+\(\.[0-9]\+\)\?/
" Operators
syn match jinjaOperator containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[+\-*\/<>=!,:]/
syn match jinjaPunctuation containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[()\[\]]/
syn match jinjaOperator containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /\./ nextgroup=jinjaAttribute
syn match jinjaAttribute contained /[a-zA-Z_][a-zA-Z0-9_]*/
" Jinja template tag and variable blocks
syn region jinjaNested matchgroup=jinjaOperator start="(" end=")" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained
syn region jinjaNested matchgroup=jinjaOperator start="\[" end="\]" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained
syn region jinjaNested matchgroup=jinjaOperator start="{" end="}" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained
syn region jinjaTagBlock matchgroup=jinjaTagDelim start=/{%-\?/ end=/-\?%}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment
syn region jinjaVarBlock matchgroup=jinjaVarDelim start=/{{-\?/ end=/-\?}}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment
" Jinja template 'raw' tag
syn region jinjaRaw matchgroup=jinjaRawDelim start="{%\s*raw\s*%}" end="{%\s*endraw\s*%}" containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaString,jinjaComment
" Jinja comments
syn region jinjaComment matchgroup=jinjaCommentDelim start="{#" end="#}" containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaString
" Block start keywords. A bit tricker. We only highlight at the start of a
" tag block and only if the name is not followed by a comma or equals sign
" which usually means that we have to deal with an assignment.
syn match jinjaStatement containedin=jinjaTagBlock contained /\({%-\?\s*\)\@<=\<[a-zA-Z_][a-zA-Z0-9_]*\>\(\s*[,=]\)\@!/
" and context modifiers
syn match jinjaStatement containedin=jinjaTagBlock contained /\<with\(out\)\?\s\+context\>/
hi def link jinjaPunctuation jinjaOperator
hi def link jinjaAttribute jinjaVariable
hi def link jinjaFunction jinjaFilter
hi def link jinjaTagDelim jinjaTagBlock
hi def link jinjaVarDelim jinjaVarBlock
hi def link jinjaCommentDelim jinjaComment
hi def link jinjaRawDelim jinja
hi def link jinjaSpecial Special
hi def link jinjaOperator Normal
hi def link jinjaRaw Normal
hi def link jinjaTagBlock PreProc
hi def link jinjaVarBlock PreProc
hi def link jinjaStatement Statement
hi def link jinjaFilter Function
hi def link jinjaBlockName Function
hi def link jinjaVariable Identifier
hi def link jinjaString Constant
hi def link jinjaNumber Constant
hi def link jinjaComment Comment
let b:current_syntax = 'jinja'

16
runtime/syntax/salt.vim Normal file
View File

@ -0,0 +1,16 @@
" Vim syntax file
" Maintainer: Gregory Anders
" Last Changed: 2024-09-16
if exists('b:current_syntax')
finish
endif
" Salt state files are just YAML with embedded Jinja
runtime! syntax/yaml.vim
unlet! b:current_syntax
runtime! syntax/jinja.vim
unlet! b:current_syntax
let b:current_syntax = 'salt'

View File

@ -685,7 +685,7 @@ if !exists("g:vimsyn_noerror") && !exists("g:vimsyn_novimfunctionerror")
syn match vimBufnrWarn /\<bufnr\s*(\s*["']\.['"]\s*)/ syn match vimBufnrWarn /\<bufnr\s*(\s*["']\.['"]\s*)/
endif endif
syn match vimNotFunc "\<if\>\|\<el\%[seif]\>\|\<retu\%[rn]\>\|\<while\>" skipwhite nextgroup=vimOper,vimOperParen,vimVar,vimFunc,vimNotation syn match vimNotFunc "\<if\>\|\<el\%[seif]\>\|\<retu\%[rn]\>\|\<while\>" skipwhite nextgroup=@vimExprList,vimNotation
" Match: {{{2 " Match: {{{2
" ===== " =====

View File

@ -786,7 +786,7 @@ local function parse_buf(fname, parser_path)
if parser_path then if parser_path then
vim.treesitter.language.add('vimdoc', { path = parser_path }) vim.treesitter.language.add('vimdoc', { path = parser_path })
end end
local lang_tree = vim.treesitter.get_parser(buf) local lang_tree = assert(vim.treesitter._get_parser(buf), 'vimdoc parser not found.')
return lang_tree, buf return lang_tree, buf
end end

View File

@ -10,7 +10,7 @@
Memcheck:Leak Memcheck:Leak
fun:malloc fun:malloc
fun:uv_spawn fun:uv_spawn
fun:libuv_process_spawn fun:libuv_proc_spawn
fun:process_spawn fun:proc_spawn
fun:job_start fun:job_start
} }

View File

@ -848,7 +848,7 @@ def CheckIncludes(filename, lines, error):
or filename.endswith('.in.h') or filename.endswith('.in.h')
or FileInfo(filename).RelativePath() in { or FileInfo(filename).RelativePath() in {
'func_attr.h', 'func_attr.h',
'os/pty_process.h', 'os/pty_proc.h',
}): }):
return return
@ -869,7 +869,7 @@ def CheckIncludes(filename, lines, error):
"src/nvim/msgpack_rpc/unpacker.h", "src/nvim/msgpack_rpc/unpacker.h",
"src/nvim/option.h", "src/nvim/option.h",
"src/nvim/os/pty_conpty_win.h", "src/nvim/os/pty_conpty_win.h",
"src/nvim/os/pty_process_win.h", "src/nvim/os/pty_proc_win.h",
] ]
skip_headers = [ skip_headers = [

View File

@ -0,0 +1,55 @@
#pragma once
#define SIZEOF_INT 4
#define SIZEOF_INTMAX_T 8
#define SIZEOF_LONG 8
#define SIZEOF_SIZE_T 8
#if 8 == 8
#define ARCH_64
#elif 8 == 4
#define ARCH_32
#endif
#define PROJECT_NAME "nvim"
/* #undef HAVE__NSGETENVIRON */
#define HAVE_FD_CLOEXEC
#define HAVE_FSEEKO
#define HAVE_LANGINFO_H
#define HAVE_NL_LANGINFO_CODESET
#define HAVE_NL_MSG_CAT_CNTR
#define HAVE_PWD_FUNCS
#define HAVE_READLINK
#define HAVE_STRNLEN
#define HAVE_STRCASECMP
#define HAVE_STRINGS_H
#define HAVE_STRNCASECMP
#define HAVE_STRPTIME
#define HAVE_XATTR
// #define HAVE_SYS_SDT_H
#define HAVE_SYS_UTSNAME_H
/* #undef HAVE_SYS_WAIT_H */
#define HAVE_TERMIOS_H
#define HAVE_WORKING_LIBINTL
#define UNIX
/* #undef CASE_INSENSITIVE_FILENAME */
/* #undef USE_FNAME_CASE */
#define HAVE_SYS_UIO_H
#ifdef HAVE_SYS_UIO_H
#define HAVE_READV
# ifndef HAVE_READV
# undef HAVE_SYS_UIO_H
# endif
#endif
#define HAVE_DIRFD_AND_FLOCK
#define HAVE_FORKPTY
#define HAVE_BE64TOH
/* #undef ORDER_BIG_ENDIAN */
#define ENDIAN_INCLUDE_FILE <endian.h>
#define HAVE_EXECINFO_BACKTRACE
#define HAVE_BUILTIN_ADD_OVERFLOW
#define HAVE_WIMPLICIT_FALLTHROUGH_FLAG
/* #undef HAVE_BITSCANFORWARD64 */

View File

@ -0,0 +1,3 @@
char *default_vim_dir = "/usr/local/share/nvim";
char *default_vimruntime_dir = "";
char *default_lib_dir = "/usr/local/lib/nvim";

113
src/nlua0.zig Normal file
View File

@ -0,0 +1,113 @@
const std = @import("std");
const ziglua = @import("ziglua");
const options = @import("options");
const embedded_data = @import("embedded_data");
const hashy = @embedFile("nvim/generators/hashy.lua");
const Lua = ziglua.Lua;
extern "c" fn luaopen_mpack(ptr: *anyopaque) c_int;
extern "c" fn luaopen_lpeg(ptr: *anyopaque) c_int;
extern "c" fn luaopen_bit(ptr: *anyopaque) c_int;
fn init() !*Lua {
// Initialize the Lua vm
var lua = try Lua.newStateLibc();
lua.openLibs();
// this sets _G.vim by itself, so we don't need to
try lua.loadBuffer(embedded_data.shared_module, "shared.lua");
lua.call(0, 1);
try lua.loadBuffer(embedded_data.inspect_module, "inspect.lua");
lua.call(0, 1);
lua.setField(-2, "inspect");
_ = try lua.getGlobal("package");
_ = lua.getField(-1, "preload");
try lua.loadBuffer(hashy, "hashy.lua"); // [package, preload, hashy]
lua.setField(-2, "generators.hashy");
lua.pop(2);
const retval = luaopen_mpack(lua);
if (retval != 1) return error.LoadError;
_ = lua.getField(-1, "NIL"); // [vim, mpack, NIL]
lua.setField(-3, "NIL"); // vim.NIL = mpack.NIL (wow BOB wow)
lua.setField(-2, "mpack");
const retval2 = luaopen_lpeg(lua);
if (retval2 != 1) return error.LoadError;
lua.setField(-3, "lpeg");
lua.pop(2);
if (!options.use_luajit) {
lua.pop(luaopen_bit(lua));
}
return lua;
}
pub fn main() !void {
const argv = std.os.argv;
const lua = try init();
defer lua.deinit();
if (argv.len < 2) {
std.debug.print("USAGE: nlua0 script.lua args...\n\n", .{});
try lua.doString("print(vim.inspect(vim.uv.os_uname()))");
return;
}
lua.createTable(@intCast(argv.len - 2), 1);
for (0.., argv[1..]) |i, arg| {
_ = lua.pushString(std.mem.span(arg));
lua.rawSetIndex(-2, @intCast(i));
}
lua.setGlobal("arg");
// Create an allocator
// var gpa = std.heap.GeneralPurposeAllocator(.{}){};
// const allocator = gpa.allocator();
// defer _ = gpa.deinit();
//std.debug.print("All your {s} are belong to us.\n", .{argv[1]});
_ = try lua.getGlobal("debug");
_ = lua.getField(-1, "traceback");
try lua.loadFile(std.mem.span(argv[1]));
lua.protectedCall(0, 0, -2) catch |e| {
if (e == error.Runtime) {
const msg = try lua.toString(-1);
std.debug.print("{s}\n", .{msg});
}
return e;
};
}
fn do_ret1(lua: *Lua, str: [:0]const u8) !void {
try lua.loadString(str);
try lua.protectedCall(0, 1, 0);
}
test "simple test" {
const lua = try init();
defer lua.deinit();
try do_ret1(lua, "return vim.isarray({2,3})");
try std.testing.expectEqual(true, lua.toBoolean(-1));
lua.pop(1);
try do_ret1(lua, "return vim.isarray({a=2,b=3})");
try std.testing.expectEqual(false, lua.toBoolean(-1));
lua.pop(1);
try do_ret1(lua, "return vim.inspect(vim.mpack.decode('\\146\\42\\69'))");
try std.testing.expectEqualStrings("{ 42, 69 }", try lua.toString(-1));
lua.pop(1);
try do_ret1(lua, "return require'bit'.band(7,12)");
try std.testing.expectEqualStrings("4", try lua.toString(-1));
lua.pop(1);
}

View File

@ -417,10 +417,10 @@ list(SORT NVIM_HEADERS)
foreach(sfile ${NVIM_SOURCES}) foreach(sfile ${NVIM_SOURCES})
get_filename_component(f ${sfile} NAME) get_filename_component(f ${sfile} NAME)
if(WIN32 AND ${f} MATCHES "^(pty_process_unix.c)$") if(WIN32 AND ${f} MATCHES "^(pty_proc_unix.c)$")
list(REMOVE_ITEM NVIM_SOURCES ${sfile}) list(REMOVE_ITEM NVIM_SOURCES ${sfile})
endif() endif()
if(NOT WIN32 AND ${f} MATCHES "^(pty_process_win.c)$") if(NOT WIN32 AND ${f} MATCHES "^(pty_proc_win.c)$")
list(REMOVE_ITEM NVIM_SOURCES ${sfile}) list(REMOVE_ITEM NVIM_SOURCES ${sfile})
endif() endif()
if(NOT WIN32 AND ${f} MATCHES "^(pty_conpty_win.c)$") if(NOT WIN32 AND ${f} MATCHES "^(pty_conpty_win.c)$")
@ -436,7 +436,7 @@ foreach(hfile ${NVIM_HEADERS})
if(WIN32 AND ${f} MATCHES "^(unix_defs.h)$") if(WIN32 AND ${f} MATCHES "^(unix_defs.h)$")
list(REMOVE_ITEM NVIM_HEADERS ${hfile}) list(REMOVE_ITEM NVIM_HEADERS ${hfile})
endif() endif()
if(WIN32 AND ${f} MATCHES "^(pty_process_unix.h)$") if(WIN32 AND ${f} MATCHES "^(pty_proc_unix.h)$")
list(REMOVE_ITEM NVIM_HEADERS ${hfile}) list(REMOVE_ITEM NVIM_HEADERS ${hfile})
endif() endif()
if(NOT WIN32 AND ${f} MATCHES "^(win_defs.h)$") if(NOT WIN32 AND ${f} MATCHES "^(win_defs.h)$")
@ -590,14 +590,19 @@ add_custom_command(
${LUA_API_C_BINDINGS} ${LUA_API_C_BINDINGS}
${GENERATED_KEYSETS_DEFS} ${GENERATED_KEYSETS_DEFS}
${UI_METADATA} ${UI_METADATA}
${NVIM_VERSION_GIT_H} ${NVIM_VERSION_GIT_H} ${NVIM_VERSION_LUA}
${GENERATOR_C_GRAMMAR}
${GENERATOR_DIR}/dump_bin_array.lua
${CMAKE_CURRENT_LIST_DIR}/api/dispatch_deprecated.lua
${API_HEADERS} ${API_HEADERS}
DEPENDS DEPENDS
${LUA_GEN_DEPS} ${LUA_GEN_DEPS}
${API_HEADERS} ${API_HEADERS}
${MSGPACK_RPC_HEADERS} ${MSGPACK_RPC_HEADERS}
${API_DISPATCH_GENERATOR} ${API_DISPATCH_GENERATOR}
${GENERATOR_C_GRAMMAR} ${GENERATOR_C_GRAMMAR}
${GENERATOR_DIR}/dump_bin_array.lua
${UI_METADATA} ${UI_METADATA}
${NVIM_VERSION_LUA} ${NVIM_VERSION_LUA}
${NVIM_VERSION_GIT_H} ${NVIM_VERSION_GIT_H}
@ -649,6 +654,7 @@ add_custom_command(
${GENERATED_UI_EVENTS_REMOTE} ${GENERATED_UI_EVENTS_REMOTE}
${UI_METADATA} ${UI_METADATA}
${GENERATED_UI_EVENTS_CLIENT} ${GENERATED_UI_EVENTS_CLIENT}
${GENERATOR_C_GRAMMAR}
DEPENDS DEPENDS
${LUA_GEN_DEPS} ${LUA_GEN_DEPS}
${API_UI_EVENTS_GENERATOR} ${API_UI_EVENTS_GENERATOR}
@ -674,29 +680,29 @@ list(APPEND NVIM_GENERATED_FOR_SOURCES
) )
add_custom_command(OUTPUT ${GENERATED_EX_CMDS_ENUM} ${GENERATED_EX_CMDS_DEFS} add_custom_command(OUTPUT ${GENERATED_EX_CMDS_ENUM} ${GENERATED_EX_CMDS_DEFS}
COMMAND ${LUA_GEN} ${EX_CMDS_GENERATOR} ${GENERATED_INCLUDES_DIR} ${GENERATED_DIR} COMMAND ${LUA_GEN} ${EX_CMDS_GENERATOR} ${GENERATED_EX_CMDS_ENUM} ${GENERATED_EX_CMDS_DEFS} ${CMAKE_CURRENT_LIST_DIR}/ex_cmds.lua
DEPENDS ${LUA_GEN_DEPS} ${EX_CMDS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/ex_cmds.lua DEPENDS ${LUA_GEN_DEPS} ${EX_CMDS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/ex_cmds.lua
) )
add_custom_command(OUTPUT ${GENERATED_FUNCS} ${FUNCS_DATA} add_custom_command(OUTPUT ${GENERATED_FUNCS} ${FUNCS_DATA}
COMMAND ${LUA_GEN} ${FUNCS_GENERATOR} ${GENERATED_DIR} ${FUNCS_METADATA} ${FUNCS_DATA} COMMAND ${LUA_GEN} ${FUNCS_GENERATOR} ${GENERATED_FUNCS} ${FUNCS_METADATA} ${FUNCS_DATA} ${CMAKE_CURRENT_LIST_DIR}/eval.lua
DEPENDS ${LUA_GEN_DEPS} ${FUNCS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/eval.lua ${FUNCS_METADATA} DEPENDS ${LUA_GEN_DEPS} ${FUNCS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/eval.lua ${FUNCS_METADATA}
) )
list(APPEND NVIM_GENERATED_FOR_SOURCES list(APPEND NVIM_GENERATED_FOR_SOURCES
"${GENERATED_FUNCS}") "${GENERATED_FUNCS}")
add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP} add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP}
COMMAND ${LUA_GEN} ${EVENTS_GENERATOR} ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP} COMMAND ${LUA_GEN} ${EVENTS_GENERATOR} ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua
DEPENDS ${LUA_GEN_DEPS} ${EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua DEPENDS ${LUA_GEN_DEPS} ${EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua
) )
add_custom_command(OUTPUT ${GENERATED_OPTIONS} add_custom_command(OUTPUT ${GENERATED_OPTIONS}
COMMAND ${LUA_GEN} ${OPTIONS_GENERATOR} ${GENERATED_OPTIONS} COMMAND ${LUA_GEN} ${OPTIONS_GENERATOR} ${GENERATED_OPTIONS} ${CMAKE_CURRENT_LIST_DIR}/options.lua
DEPENDS ${LUA_GEN_DEPS} ${OPTIONS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/options.lua DEPENDS ${LUA_GEN_DEPS} ${OPTIONS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/options.lua
) )
add_custom_command(OUTPUT ${GENERATED_OPTIONS_ENUM} ${GENERATED_OPTIONS_MAP} add_custom_command(OUTPUT ${GENERATED_OPTIONS_ENUM} ${GENERATED_OPTIONS_MAP}
COMMAND ${LUA_GEN} ${OPTIONS_ENUM_GENERATOR} ${GENERATED_OPTIONS_ENUM} ${GENERATED_OPTIONS_MAP} COMMAND ${LUA_GEN} ${OPTIONS_ENUM_GENERATOR} ${GENERATED_OPTIONS_ENUM} ${GENERATED_OPTIONS_MAP} ${CMAKE_CURRENT_LIST_DIR}/options.lua
DEPENDS ${LUA_GEN_DEPS} ${OPTIONS_ENUM_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/options.lua DEPENDS ${LUA_GEN_DEPS} ${OPTIONS_ENUM_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/options.lua
) )
@ -832,12 +838,12 @@ find_program(CLANG_TIDY_PRG clang-tidy)
set(EXCLUDE_CLANG_TIDY typval_encode.c.h ui_events.in.h) set(EXCLUDE_CLANG_TIDY typval_encode.c.h ui_events.in.h)
if(WIN32) if(WIN32)
list(APPEND EXCLUDE_CLANG_TIDY list(APPEND EXCLUDE_CLANG_TIDY
os/pty_process_unix.h os/pty_proc_unix.h
os/unix_defs.h) os/unix_defs.h)
else() else()
list(APPEND EXCLUDE_CLANG_TIDY list(APPEND EXCLUDE_CLANG_TIDY
os/win_defs.h os/win_defs.h
os/pty_process_win.h os/pty_proc_win.h
os/pty_conpty_win.h os/pty_conpty_win.h
os/os_win_console.h) os/os_win_console.h)
endif() endif()

View File

@ -70,7 +70,7 @@
#include "nvim/optionstr.h" #include "nvim/optionstr.h"
#include "nvim/os/input.h" #include "nvim/os/input.h"
#include "nvim/os/os_defs.h" #include "nvim/os/os_defs.h"
#include "nvim/os/process.h" #include "nvim/os/proc.h"
#include "nvim/popupmenu.h" #include "nvim/popupmenu.h"
#include "nvim/pos_defs.h" #include "nvim/pos_defs.h"
#include "nvim/runtime.h" #include "nvim/runtime.h"

View File

@ -3338,7 +3338,7 @@ void maketitle(void)
#define SPACE_FOR_FNAME (sizeof(buf) - 100) #define SPACE_FOR_FNAME (sizeof(buf) - 100)
#define SPACE_FOR_DIR (sizeof(buf) - 20) #define SPACE_FOR_DIR (sizeof(buf) - 20)
#define SPACE_FOR_ARGNR (sizeof(buf) - 10) // At least room for " - NVIM". #define SPACE_FOR_ARGNR (sizeof(buf) - 10) // At least room for " - Nvim".
char *buf_p = buf; char *buf_p = buf;
if (curbuf->b_fname == NULL) { if (curbuf->b_fname == NULL) {
const size_t size = xstrlcpy(buf_p, _("[No Name]"), const size_t size = xstrlcpy(buf_p, _("[No Name]"),
@ -3412,7 +3412,7 @@ void maketitle(void)
append_arg_number(curwin, buf_p, (int)(SPACE_FOR_ARGNR - (size_t)(buf_p - buf))); append_arg_number(curwin, buf_p, (int)(SPACE_FOR_ARGNR - (size_t)(buf_p - buf)));
xstrlcat(buf_p, " - NVIM", (sizeof(buf) - (size_t)(buf_p - buf))); xstrlcat(buf_p, " - Nvim", (sizeof(buf) - (size_t)(buf_p - buf)));
if (maxlen > 0) { if (maxlen > 0) {
// Make it shorter by removing a bit in the middle. // Make it shorter by removing a bit in the middle.

View File

@ -19,7 +19,7 @@
#include "nvim/eval/typval.h" #include "nvim/eval/typval.h"
#include "nvim/event/loop.h" #include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h" #include "nvim/event/multiqueue.h"
#include "nvim/event/process.h" #include "nvim/event/proc.h"
#include "nvim/event/rstream.h" #include "nvim/event/rstream.h"
#include "nvim/event/socket.h" #include "nvim/event/socket.h"
#include "nvim/event/stream.h" #include "nvim/event/stream.h"
@ -88,7 +88,7 @@ void channel_free_all_mem(void)
bool channel_close(uint64_t id, ChannelPart part, const char **error) bool channel_close(uint64_t id, ChannelPart part, const char **error)
{ {
Channel *chan; Channel *chan;
Process *proc; Proc *proc;
const char *dummy; const char *dummy;
if (!error) { if (!error) {
@ -139,8 +139,8 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
if (part == kChannelPartStderr || part == kChannelPartAll) { if (part == kChannelPartStderr || part == kChannelPartAll) {
rstream_may_close(&proc->err); rstream_may_close(&proc->err);
} }
if (proc->type == kProcessTypePty && part == kChannelPartAll) { if (proc->type == kProcTypePty && part == kChannelPartAll) {
pty_process_close_master(&chan->stream.pty); pty_proc_close_master(&chan->stream.pty);
} }
break; break;
@ -289,7 +289,7 @@ static void channel_destroy(Channel *chan)
} }
if (chan->streamtype == kChannelStreamProc) { if (chan->streamtype == kChannelStreamProc) {
process_free(&chan->stream.proc); proc_free(&chan->stream.proc);
} }
callback_reader_free(&chan->on_data); callback_reader_free(&chan->on_data);
@ -376,7 +376,7 @@ Channel *channel_job_start(char **argv, const char *exepath, CallbackReader on_s
*status_out = 0; *status_out = 0;
return NULL; return NULL;
} }
chan->stream.pty = pty_process_init(&main_loop, chan); chan->stream.pty = pty_proc_init(&main_loop, chan);
if (pty_width > 0) { if (pty_width > 0) {
chan->stream.pty.width = pty_width; chan->stream.pty.width = pty_width;
} }
@ -384,22 +384,22 @@ Channel *channel_job_start(char **argv, const char *exepath, CallbackReader on_s
chan->stream.pty.height = pty_height; chan->stream.pty.height = pty_height;
} }
} else { } else {
chan->stream.uv = libuv_process_init(&main_loop, chan); chan->stream.uv = libuv_proc_init(&main_loop, chan);
} }
Process *proc = &chan->stream.proc; Proc *proc = &chan->stream.proc;
proc->argv = argv; proc->argv = argv;
proc->exepath = exepath; proc->exepath = exepath;
proc->cb = channel_process_exit_cb; proc->cb = channel_proc_exit_cb;
proc->events = chan->events; proc->events = chan->events;
proc->detach = detach; proc->detach = detach;
proc->cwd = cwd; proc->cwd = cwd;
proc->env = env; proc->env = env;
proc->overlapped = overlapped; proc->overlapped = overlapped;
char *cmd = xstrdup(process_get_exepath(proc)); char *cmd = xstrdup(proc_get_exepath(proc));
bool has_out, has_err; bool has_out, has_err;
if (proc->type == kProcessTypePty) { if (proc->type == kProcTypePty) {
has_out = true; has_out = true;
has_err = false; has_err = false;
} else { } else {
@ -410,7 +410,7 @@ Channel *channel_job_start(char **argv, const char *exepath, CallbackReader on_s
bool has_in = stdin_mode == kChannelStdinPipe; bool has_in = stdin_mode == kChannelStdinPipe;
int status = process_spawn(proc, has_in, has_out, has_err); int status = proc_spawn(proc, has_in, has_out, has_err);
if (status) { if (status) {
semsg(_(e_jobspawn), os_strerror(status), cmd); semsg(_(e_jobspawn), os_strerror(status), cmd);
xfree(cmd); xfree(cmd);
@ -760,7 +760,7 @@ void channel_reader_callbacks(Channel *chan, CallbackReader *reader)
} }
} }
static void channel_process_exit_cb(Process *proc, int status, void *data) static void channel_proc_exit_cb(Proc *proc, int status, void *data)
{ {
Channel *chan = data; Channel *chan = data;
if (chan->term) { if (chan->term) {
@ -847,7 +847,7 @@ static void term_write(const char *buf, size_t size, void *data)
static void term_resize(uint16_t width, uint16_t height, void *data) static void term_resize(uint16_t width, uint16_t height, void *data)
{ {
Channel *chan = data; Channel *chan = data;
pty_process_resize(&chan->stream.pty, width, height); pty_proc_resize(&chan->stream.pty, width, height);
} }
static inline void term_delayed_free(void **argv) static inline void term_delayed_free(void **argv)
@ -867,7 +867,7 @@ static inline void term_delayed_free(void **argv)
static void term_close(void *data) static void term_close(void *data)
{ {
Channel *chan = data; Channel *chan = data;
process_stop(&chan->stream.proc); proc_stop(&chan->stream.proc);
multiqueue_put(chan->events, term_delayed_free, data); multiqueue_put(chan->events, term_delayed_free, data);
} }
@ -907,7 +907,7 @@ bool channel_job_running(uint64_t id)
Channel *chan = find_channel(id); Channel *chan = find_channel(id);
return (chan return (chan
&& chan->streamtype == kChannelStreamProc && chan->streamtype == kChannelStreamProc
&& !process_is_stopped(&chan->stream.proc)); && !proc_is_stopped(&chan->stream.proc));
} }
Dictionary channel_info(uint64_t id, Arena *arena) Dictionary channel_info(uint64_t id, Arena *arena)
@ -924,8 +924,8 @@ Dictionary channel_info(uint64_t id, Arena *arena)
switch (chan->streamtype) { switch (chan->streamtype) {
case kChannelStreamProc: { case kChannelStreamProc: {
stream_desc = "job"; stream_desc = "job";
if (chan->stream.proc.type == kProcessTypePty) { if (chan->stream.proc.type == kProcTypePty) {
const char *name = pty_process_tty_name(&chan->stream.pty); const char *name = pty_proc_tty_name(&chan->stream.pty);
PUT_C(info, "pty", CSTR_TO_ARENA_OBJ(arena, name)); PUT_C(info, "pty", CSTR_TO_ARENA_OBJ(arena, name));
} }

View File

@ -7,11 +7,11 @@
#include "nvim/channel_defs.h" // IWYU pragma: keep #include "nvim/channel_defs.h" // IWYU pragma: keep
#include "nvim/eval/typval_defs.h" #include "nvim/eval/typval_defs.h"
#include "nvim/event/defs.h" #include "nvim/event/defs.h"
#include "nvim/event/libuv_process.h" #include "nvim/event/libuv_proc.h"
#include "nvim/macros_defs.h" #include "nvim/macros_defs.h"
#include "nvim/map_defs.h" #include "nvim/map_defs.h"
#include "nvim/msgpack_rpc/channel_defs.h" #include "nvim/msgpack_rpc/channel_defs.h"
#include "nvim/os/pty_process.h" #include "nvim/os/pty_proc.h"
#include "nvim/types_defs.h" #include "nvim/types_defs.h"
struct Channel { struct Channel {
@ -21,9 +21,9 @@ struct Channel {
ChannelStreamType streamtype; ChannelStreamType streamtype;
union { union {
Process proc; Proc proc;
LibuvProcess uv; LibuvProc uv;
PtyProcess pty; PtyProc pty;
RStream socket; RStream socket;
StdioPair stdio; StdioPair stdio;
StderrState err; StderrState err;

View File

@ -170,28 +170,26 @@ static void margin_columns_win(win_T *wp, int *left_col, int *right_col)
// cache previous calculations depending on w_virtcol // cache previous calculations depending on w_virtcol
static int saved_w_virtcol; static int saved_w_virtcol;
static win_T *prev_wp; static win_T *prev_wp;
static int prev_width1;
static int prev_width2;
static int prev_left_col; static int prev_left_col;
static int prev_right_col; static int prev_right_col;
static int prev_col_off;
int cur_col_off = win_col_off(wp); int cur_col_off = win_col_off(wp);
int width1; int width1 = wp->w_width_inner - cur_col_off;
int width2; int width2 = width1 + win_col_off2(wp);
if (saved_w_virtcol == wp->w_virtcol && prev_wp == wp if (saved_w_virtcol == wp->w_virtcol && prev_wp == wp
&& prev_col_off == cur_col_off) { && prev_width1 == width1 && prev_width2 == width2) {
*right_col = prev_right_col; *right_col = prev_right_col;
*left_col = prev_left_col; *left_col = prev_left_col;
return; return;
} }
width1 = wp->w_width_inner - cur_col_off;
width2 = width1 + win_col_off2(wp);
*left_col = 0; *left_col = 0;
*right_col = width1; *right_col = width1;
if (wp->w_virtcol >= (colnr_T)width1) { if (wp->w_virtcol >= (colnr_T)width1 && width2 > 0) {
*right_col = width1 + ((wp->w_virtcol - width1) / width2 + 1) * width2; *right_col = width1 + ((wp->w_virtcol - width1) / width2 + 1) * width2;
} }
if (wp->w_virtcol >= (colnr_T)width1 && width2 > 0) { if (wp->w_virtcol >= (colnr_T)width1 && width2 > 0) {
@ -202,8 +200,9 @@ static void margin_columns_win(win_T *wp, int *left_col, int *right_col)
prev_left_col = *left_col; prev_left_col = *left_col;
prev_right_col = *right_col; prev_right_col = *right_col;
prev_wp = wp; prev_wp = wp;
prev_width1 = width1;
prev_width2 = width2;
saved_w_virtcol = wp->w_virtcol; saved_w_virtcol = wp->w_virtcol;
prev_col_off = cur_col_off;
} }
/// Put a single char from an UTF-8 buffer into a line buffer. /// Put a single char from an UTF-8 buffer into a line buffer.

View File

@ -32,7 +32,7 @@
#include "nvim/eval/vars.h" #include "nvim/eval/vars.h"
#include "nvim/event/loop.h" #include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h" #include "nvim/event/multiqueue.h"
#include "nvim/event/process.h" #include "nvim/event/proc.h"
#include "nvim/event/time.h" #include "nvim/event/time.h"
#include "nvim/ex_cmds.h" #include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h" #include "nvim/ex_docmd.h"
@ -8506,7 +8506,7 @@ Channel *find_job(uint64_t id, bool show_error)
{ {
Channel *data = find_channel(id); Channel *data = find_channel(id);
if (!data || data->streamtype != kChannelStreamProc if (!data || data->streamtype != kChannelStreamProc
|| process_is_stopped(&data->stream.proc)) { || proc_is_stopped(&data->stream.proc)) {
if (show_error) { if (show_error) {
if (data && data->streamtype != kChannelStreamProc) { if (data && data->streamtype != kChannelStreamProc) {
emsg(_(e_invchanjob)); emsg(_(e_invchanjob));

View File

@ -8044,7 +8044,7 @@ M.funcs = {
]=], ]=],
name = 'prompt_getprompt', name = 'prompt_getprompt',
params = { { 'buf', 'any' } }, params = { { 'buf', 'integer|string' } },
signature = 'prompt_getprompt({buf})', signature = 'prompt_getprompt({buf})',
}, },
prompt_setcallback = { prompt_setcallback = {
@ -8084,7 +8084,7 @@ M.funcs = {
]=], ]=],
name = 'prompt_setcallback', name = 'prompt_setcallback',
params = { { 'buf', 'any' }, { 'expr', 'any' } }, params = { { 'buf', 'integer|string' }, { 'expr', 'string|function' } },
signature = 'prompt_setcallback({buf}, {expr})', signature = 'prompt_setcallback({buf}, {expr})',
}, },
prompt_setinterrupt = { prompt_setinterrupt = {
@ -8101,7 +8101,7 @@ M.funcs = {
]=], ]=],
name = 'prompt_setinterrupt', name = 'prompt_setinterrupt',
params = { { 'buf', 'any' }, { 'expr', 'any' } }, params = { { 'buf', 'integer|string' }, { 'expr', 'string|function' } },
signature = 'prompt_setinterrupt({buf}, {expr})', signature = 'prompt_setinterrupt({buf}, {expr})',
}, },
prompt_setprompt = { prompt_setprompt = {
@ -8116,7 +8116,7 @@ M.funcs = {
< <
]=], ]=],
name = 'prompt_setprompt', name = 'prompt_setprompt',
params = { { 'buf', 'any' }, { 'text', 'any' } }, params = { { 'buf', 'integer|string' }, { 'text', 'string' } },
signature = 'prompt_setprompt({buf}, {text})', signature = 'prompt_setprompt({buf}, {text})',
}, },
pum_getpos = { pum_getpos = {

View File

@ -49,7 +49,7 @@
#include "nvim/event/defs.h" #include "nvim/event/defs.h"
#include "nvim/event/loop.h" #include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h" #include "nvim/event/multiqueue.h"
#include "nvim/event/process.h" #include "nvim/event/proc.h"
#include "nvim/event/time.h" #include "nvim/event/time.h"
#include "nvim/ex_cmds.h" #include "nvim/ex_cmds.h"
#include "nvim/ex_cmds_defs.h" #include "nvim/ex_cmds_defs.h"
@ -101,7 +101,7 @@
#include "nvim/os/fs.h" #include "nvim/os/fs.h"
#include "nvim/os/os.h" #include "nvim/os/os.h"
#include "nvim/os/os_defs.h" #include "nvim/os/os_defs.h"
#include "nvim/os/pty_process.h" #include "nvim/os/pty_proc.h"
#include "nvim/os/shell.h" #include "nvim/os/shell.h"
#include "nvim/os/stdpaths_defs.h" #include "nvim/os/stdpaths_defs.h"
#include "nvim/os/time.h" #include "nvim/os/time.h"
@ -3770,7 +3770,7 @@ static void f_jobpid(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
return; return;
} }
Process *proc = &data->stream.proc; Proc *proc = &data->stream.proc;
rettv->vval.v_number = proc->pid; rettv->vval.v_number = proc->pid;
} }
@ -3796,13 +3796,13 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
return; return;
} }
if (data->stream.proc.type != kProcessTypePty) { if (data->stream.proc.type != kProcTypePty) {
emsg(_(e_channotpty)); emsg(_(e_channotpty));
return; return;
} }
pty_process_resize(&data->stream.pty, (uint16_t)argvars[1].vval.v_number, pty_proc_resize(&data->stream.pty, (uint16_t)argvars[1].vval.v_number,
(uint16_t)argvars[2].vval.v_number); (uint16_t)argvars[2].vval.v_number);
rettv->vval.v_number = 1; rettv->vval.v_number = 1;
} }
@ -4077,7 +4077,7 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
// Ignore return code, but show error later. // Ignore return code, but show error later.
channel_close(data->id, kChannelPartRpc, &error); channel_close(data->id, kChannelPartRpc, &error);
} }
process_stop(&data->stream.proc); proc_stop(&data->stream.proc);
rettv->vval.v_number = 1; rettv->vval.v_number = 1;
if (error) { if (error) {
emsg(error); emsg(error);
@ -4113,10 +4113,10 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|| !(chan = find_channel((uint64_t)TV_LIST_ITEM_TV(arg)->vval.v_number)) || !(chan = find_channel((uint64_t)TV_LIST_ITEM_TV(arg)->vval.v_number))
|| chan->streamtype != kChannelStreamProc) { || chan->streamtype != kChannelStreamProc) {
jobs[i] = NULL; // Invalid job. jobs[i] = NULL; // Invalid job.
} else if (process_is_stopped(&chan->stream.proc)) { } else if (proc_is_stopped(&chan->stream.proc)) {
// Job is stopped but not fully destroyed. // Job is stopped but not fully destroyed.
// Ensure all callbacks on its event queue are executed. #15402 // Ensure all callbacks on its event queue are executed. #15402
process_wait(&chan->stream.proc, -1, NULL); proc_wait(&chan->stream.proc, -1, NULL);
jobs[i] = NULL; // Invalid job. jobs[i] = NULL; // Invalid job.
} else { } else {
jobs[i] = chan; jobs[i] = chan;
@ -4144,8 +4144,8 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
if (jobs[i] == NULL) { if (jobs[i] == NULL) {
continue; // Invalid job, will assign status=-3 below. continue; // Invalid job, will assign status=-3 below.
} }
int status = process_wait(&jobs[i]->stream.proc, remaining, int status = proc_wait(&jobs[i]->stream.proc, remaining,
waiting_jobs); waiting_jobs);
if (status < 0) { if (status < 0) {
break; // Interrupted (CTRL-C) or timeout, skip remaining jobs. break; // Interrupted (CTRL-C) or timeout, skip remaining jobs.
} }
@ -8207,7 +8207,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
return; return;
} }
int pid = chan->stream.pty.process.pid; int pid = chan->stream.pty.proc.pid;
// "./…" => "/home/foo/…" // "./…" => "/home/foo/…"
vim_FullName(cwd, NameBuff, sizeof(NameBuff), false); vim_FullName(cwd, NameBuff, sizeof(NameBuff), false);

View File

@ -142,30 +142,31 @@ struct socket_watcher {
}; };
typedef enum { typedef enum {
kProcessTypeUv, kProcTypeUv,
kProcessTypePty, kProcTypePty,
} ProcessType; } ProcType;
typedef struct process Process; /// OS process
typedef void (*process_exit_cb)(Process *proc, int status, void *data); typedef struct proc Proc;
typedef void (*internal_process_cb)(Process *proc); typedef void (*proc_exit_cb)(Proc *proc, int status, void *data);
typedef void (*internal_proc_cb)(Proc *proc);
struct process { struct proc {
ProcessType type; ProcType type;
Loop *loop; Loop *loop;
void *data; void *data;
int pid, status, refcount; int pid, status, refcount;
uint8_t exit_signal; // Signal used when killing (on Windows). uint8_t exit_signal; // Signal used when killing (on Windows).
uint64_t stopped_time; // process_stop() timestamp uint64_t stopped_time; // proc_stop() timestamp
const char *cwd; const char *cwd;
char **argv; char **argv;
const char *exepath; const char *exepath;
dict_T *env; dict_T *env;
Stream in; Stream in;
RStream out, err; RStream out, err;
/// Exit handler. If set, user must call process_free(). /// Exit handler. If set, user must call proc_free().
process_exit_cb cb; proc_exit_cb cb;
internal_process_cb internal_exit_cb, internal_close_cb; internal_proc_cb internal_exit_cb, internal_close_cb;
bool closed, detach, overlapped, fwd_err; bool closed, detach, overlapped, fwd_err;
MultiQueue *events; MultiQueue *events;
}; };

View File

@ -5,9 +5,9 @@
#include "nvim/eval/typval.h" #include "nvim/eval/typval.h"
#include "nvim/event/defs.h" #include "nvim/event/defs.h"
#include "nvim/event/libuv_process.h" #include "nvim/event/libuv_proc.h"
#include "nvim/event/loop.h" #include "nvim/event/loop.h"
#include "nvim/event/process.h" #include "nvim/event/proc.h"
#include "nvim/log.h" #include "nvim/log.h"
#include "nvim/os/os.h" #include "nvim/os/os.h"
#include "nvim/os/os_defs.h" #include "nvim/os/os_defs.h"
@ -15,15 +15,15 @@
#include "nvim/ui_client.h" #include "nvim/ui_client.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/libuv_process.c.generated.h" # include "event/libuv_proc.c.generated.h"
#endif #endif
/// @returns zero on success, or negative error code /// @returns zero on success, or negative error code
int libuv_process_spawn(LibuvProcess *uvproc) int libuv_proc_spawn(LibuvProc *uvproc)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
Process *proc = (Process *)uvproc; Proc *proc = (Proc *)uvproc;
uvproc->uvopts.file = process_get_exepath(proc); uvproc->uvopts.file = proc_get_exepath(proc);
uvproc->uvopts.args = proc->argv; uvproc->uvopts.args = proc->argv;
uvproc->uvopts.flags = UV_PROCESS_WINDOWS_HIDE; uvproc->uvopts.flags = UV_PROCESS_WINDOWS_HIDE;
#ifdef MSWIN #ifdef MSWIN
@ -101,7 +101,7 @@ int libuv_process_spawn(LibuvProcess *uvproc)
return status; return status;
} }
void libuv_process_close(LibuvProcess *uvproc) void libuv_proc_close(LibuvProc *uvproc)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(1)
{ {
uv_close((uv_handle_t *)&uvproc->uv, close_cb); uv_close((uv_handle_t *)&uvproc->uv, close_cb);
@ -109,11 +109,11 @@ void libuv_process_close(LibuvProcess *uvproc)
static void close_cb(uv_handle_t *handle) static void close_cb(uv_handle_t *handle)
{ {
Process *proc = handle->data; Proc *proc = handle->data;
if (proc->internal_close_cb) { if (proc->internal_close_cb) {
proc->internal_close_cb(proc); proc->internal_close_cb(proc);
} }
LibuvProcess *uvproc = (LibuvProcess *)proc; LibuvProc *uvproc = (LibuvProc *)proc;
if (uvproc->uvopts.env) { if (uvproc->uvopts.env) {
os_free_fullenv(uvproc->uvopts.env); os_free_fullenv(uvproc->uvopts.env);
} }
@ -121,7 +121,7 @@ static void close_cb(uv_handle_t *handle)
static void exit_cb(uv_process_t *handle, int64_t status, int term_signal) static void exit_cb(uv_process_t *handle, int64_t status, int term_signal)
{ {
Process *proc = handle->data; Proc *proc = handle->data;
#if defined(MSWIN) #if defined(MSWIN)
// Use stored/expected signal. // Use stored/expected signal.
term_signal = proc->exit_signal; term_signal = proc->exit_signal;
@ -130,10 +130,10 @@ static void exit_cb(uv_process_t *handle, int64_t status, int term_signal)
proc->internal_exit_cb(proc); proc->internal_exit_cb(proc);
} }
LibuvProcess libuv_process_init(Loop *loop, void *data) LibuvProc libuv_proc_init(Loop *loop, void *data)
{ {
LibuvProcess rv = { LibuvProc rv = {
.process = process_init(loop, kProcessTypeUv, data) .proc = proc_init(loop, kProcTypeUv, data)
}; };
return rv; return rv;
} }

View File

@ -5,12 +5,12 @@
#include "nvim/event/defs.h" #include "nvim/event/defs.h"
typedef struct { typedef struct {
Process process; Proc proc;
uv_process_t uv; uv_process_t uv;
uv_process_options_t uvopts; uv_process_options_t uvopts;
uv_stdio_container_t uvstdio[4]; uv_stdio_container_t uvstdio[4];
} LibuvProcess; } LibuvProc;
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/libuv_process.h.generated.h" # include "event/libuv_proc.h.generated.h"
#endif #endif

View File

@ -4,24 +4,24 @@
#include <uv.h> #include <uv.h>
#include "klib/klist.h" #include "klib/klist.h"
#include "nvim/event/libuv_process.h" #include "nvim/event/libuv_proc.h"
#include "nvim/event/loop.h" #include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h" #include "nvim/event/multiqueue.h"
#include "nvim/event/process.h" #include "nvim/event/proc.h"
#include "nvim/event/rstream.h" #include "nvim/event/rstream.h"
#include "nvim/event/stream.h" #include "nvim/event/stream.h"
#include "nvim/event/wstream.h" #include "nvim/event/wstream.h"
#include "nvim/globals.h" #include "nvim/globals.h"
#include "nvim/log.h" #include "nvim/log.h"
#include "nvim/main.h" #include "nvim/main.h"
#include "nvim/os/process.h" #include "nvim/os/proc.h"
#include "nvim/os/pty_process.h" #include "nvim/os/pty_proc.h"
#include "nvim/os/shell.h" #include "nvim/os/shell.h"
#include "nvim/os/time.h" #include "nvim/os/time.h"
#include "nvim/ui_client.h" #include "nvim/ui_client.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/process.c.generated.h" # include "event/proc.c.generated.h"
#endif #endif
// Time for a process to exit cleanly before we send KILL. // Time for a process to exit cleanly before we send KILL.
@ -33,13 +33,13 @@
void __gcov_flush(void); void __gcov_flush(void);
#endif #endif
static bool process_is_tearing_down = false; static bool proc_is_tearing_down = false;
// Delay exit until handles are closed, to avoid deadlocks // Delay exit until handles are closed, to avoid deadlocks
static int exit_need_delay = 0; static int exit_need_delay = 0;
/// @returns zero on success, or negative error code /// @returns zero on success, or negative error code
int process_spawn(Process *proc, bool in, bool out, bool err) int proc_spawn(Proc *proc, bool in, bool out, bool err)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
// forwarding stderr contradicts with processing it internally // forwarding stderr contradicts with processing it internally
@ -70,11 +70,11 @@ int process_spawn(Process *proc, bool in, bool out, bool err)
int status; int status;
switch (proc->type) { switch (proc->type) {
case kProcessTypeUv: case kProcTypeUv:
status = libuv_process_spawn((LibuvProcess *)proc); status = libuv_proc_spawn((LibuvProc *)proc);
break; break;
case kProcessTypePty: case kProcTypePty:
status = pty_process_spawn((PtyProcess *)proc); status = pty_proc_spawn((PtyProc *)proc);
break; break;
} }
@ -89,12 +89,12 @@ int process_spawn(Process *proc, bool in, bool out, bool err)
uv_close((uv_handle_t *)&proc->err.s.uv.pipe, NULL); uv_close((uv_handle_t *)&proc->err.s.uv.pipe, NULL);
} }
if (proc->type == kProcessTypeUv) { if (proc->type == kProcTypeUv) {
uv_close((uv_handle_t *)&(((LibuvProcess *)proc)->uv), NULL); uv_close((uv_handle_t *)&(((LibuvProc *)proc)->uv), NULL);
} else { } else {
process_close(proc); proc_close(proc);
} }
process_free(proc); proc_free(proc);
proc->status = -1; proc->status = -1;
return status; return status;
} }
@ -102,52 +102,52 @@ int process_spawn(Process *proc, bool in, bool out, bool err)
if (in) { if (in) {
stream_init(NULL, &proc->in, -1, (uv_stream_t *)&proc->in.uv.pipe); stream_init(NULL, &proc->in, -1, (uv_stream_t *)&proc->in.uv.pipe);
proc->in.internal_data = proc; proc->in.internal_data = proc;
proc->in.internal_close_cb = on_process_stream_close; proc->in.internal_close_cb = on_proc_stream_close;
proc->refcount++; proc->refcount++;
} }
if (out) { if (out) {
stream_init(NULL, &proc->out.s, -1, (uv_stream_t *)&proc->out.s.uv.pipe); stream_init(NULL, &proc->out.s, -1, (uv_stream_t *)&proc->out.s.uv.pipe);
proc->out.s.internal_data = proc; proc->out.s.internal_data = proc;
proc->out.s.internal_close_cb = on_process_stream_close; proc->out.s.internal_close_cb = on_proc_stream_close;
proc->refcount++; proc->refcount++;
} }
if (err) { if (err) {
stream_init(NULL, &proc->err.s, -1, (uv_stream_t *)&proc->err.s.uv.pipe); stream_init(NULL, &proc->err.s, -1, (uv_stream_t *)&proc->err.s.uv.pipe);
proc->err.s.internal_data = proc; proc->err.s.internal_data = proc;
proc->err.s.internal_close_cb = on_process_stream_close; proc->err.s.internal_close_cb = on_proc_stream_close;
proc->refcount++; proc->refcount++;
} }
proc->internal_exit_cb = on_process_exit; proc->internal_exit_cb = on_proc_exit;
proc->internal_close_cb = decref; proc->internal_close_cb = decref;
proc->refcount++; proc->refcount++;
kl_push(WatcherPtr, proc->loop->children, proc); kl_push(WatcherPtr, proc->loop->children, proc);
DLOG("new: pid=%d exepath=[%s]", proc->pid, process_get_exepath(proc)); DLOG("new: pid=%d exepath=[%s]", proc->pid, proc_get_exepath(proc));
return 0; return 0;
} }
void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL void proc_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
{ {
process_is_tearing_down = true; proc_is_tearing_down = true;
kl_iter(WatcherPtr, loop->children, current) { kl_iter(WatcherPtr, loop->children, current) {
Process *proc = (*current)->data; Proc *proc = (*current)->data;
if (proc->detach || proc->type == kProcessTypePty) { if (proc->detach || proc->type == kProcTypePty) {
// Close handles to process without killing it. // Close handles to process without killing it.
CREATE_EVENT(loop->events, process_close_handles, proc); CREATE_EVENT(loop->events, proc_close_handles, proc);
} else { } else {
process_stop(proc); proc_stop(proc);
} }
} }
// Wait until all children exit and all close events are processed. // Wait until all children exit and all close events are processed.
LOOP_PROCESS_EVENTS_UNTIL(loop, loop->events, -1, LOOP_PROCESS_EVENTS_UNTIL(loop, loop->events, -1,
kl_empty(loop->children) && multiqueue_empty(loop->events)); kl_empty(loop->children) && multiqueue_empty(loop->events));
pty_process_teardown(loop); pty_proc_teardown(loop);
} }
void process_close_streams(Process *proc) FUNC_ATTR_NONNULL_ALL void proc_close_streams(Proc *proc) FUNC_ATTR_NONNULL_ALL
{ {
wstream_may_close(&proc->in); wstream_may_close(&proc->in);
rstream_may_close(&proc->out); rstream_may_close(&proc->out);
@ -162,7 +162,7 @@ void process_close_streams(Process *proc) FUNC_ATTR_NONNULL_ALL
/// @return Exit code of the process. proc->status will have the same value. /// @return Exit code of the process. proc->status will have the same value.
/// -1 if the timeout expired while the process is still running. /// -1 if the timeout expired while the process is still running.
/// -2 if the user interrupted the wait. /// -2 if the user interrupted the wait.
int process_wait(Process *proc, int ms, MultiQueue *events) int proc_wait(Proc *proc, int ms, MultiQueue *events)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(1)
{ {
if (!proc->refcount) { if (!proc->refcount) {
@ -186,7 +186,7 @@ int process_wait(Process *proc, int ms, MultiQueue *events)
// Assume that a user hitting CTRL-C does not like the current job. Kill it. // Assume that a user hitting CTRL-C does not like the current job. Kill it.
if (got_int) { if (got_int) {
got_int = false; got_int = false;
process_stop(proc); proc_stop(proc);
if (ms == -1) { if (ms == -1) {
// We can only return if all streams/handles are closed and the job // We can only return if all streams/handles are closed and the job
// exited. // exited.
@ -214,7 +214,7 @@ int process_wait(Process *proc, int ms, MultiQueue *events)
} }
/// Ask a process to terminate and eventually kill if it doesn't respond /// Ask a process to terminate and eventually kill if it doesn't respond
void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL void proc_stop(Proc *proc) FUNC_ATTR_NONNULL_ALL
{ {
bool exited = (proc->status >= 0); bool exited = (proc->status >= 0);
if (exited || proc->stopped_time) { if (exited || proc->stopped_time) {
@ -224,13 +224,13 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
proc->exit_signal = SIGTERM; proc->exit_signal = SIGTERM;
switch (proc->type) { switch (proc->type) {
case kProcessTypeUv: case kProcTypeUv:
os_proc_tree_kill(proc->pid, SIGTERM); os_proc_tree_kill(proc->pid, SIGTERM);
break; break;
case kProcessTypePty: case kProcTypePty:
// close all streams for pty processes to send SIGHUP to the process // close all streams for pty processes to send SIGHUP to the process
process_close_streams(proc); proc_close_streams(proc);
pty_process_close_master((PtyProcess *)proc); pty_proc_close_master((PtyProc *)proc);
break; break;
} }
@ -240,7 +240,7 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
} }
/// Frees process-owned resources. /// Frees process-owned resources.
void process_free(Process *proc) FUNC_ATTR_NONNULL_ALL void proc_free(Proc *proc) FUNC_ATTR_NONNULL_ALL
{ {
if (proc->argv != NULL) { if (proc->argv != NULL) {
shell_free_argv(proc->argv); shell_free_argv(proc->argv);
@ -249,19 +249,19 @@ void process_free(Process *proc) FUNC_ATTR_NONNULL_ALL
} }
/// Sends SIGKILL (or SIGTERM..SIGKILL for PTY jobs) to processes that did /// Sends SIGKILL (or SIGTERM..SIGKILL for PTY jobs) to processes that did
/// not terminate after process_stop(). /// not terminate after proc_stop().
static void children_kill_cb(uv_timer_t *handle) static void children_kill_cb(uv_timer_t *handle)
{ {
Loop *loop = handle->loop->data; Loop *loop = handle->loop->data;
kl_iter(WatcherPtr, loop->children, current) { kl_iter(WatcherPtr, loop->children, current) {
Process *proc = (*current)->data; Proc *proc = (*current)->data;
bool exited = (proc->status >= 0); bool exited = (proc->status >= 0);
if (exited || !proc->stopped_time) { if (exited || !proc->stopped_time) {
continue; continue;
} }
uint64_t term_sent = UINT64_MAX == proc->stopped_time; uint64_t term_sent = UINT64_MAX == proc->stopped_time;
if (kProcessTypePty != proc->type || term_sent) { if (kProcTypePty != proc->type || term_sent) {
proc->exit_signal = SIGKILL; proc->exit_signal = SIGKILL;
os_proc_tree_kill(proc->pid, SIGKILL); os_proc_tree_kill(proc->pid, SIGKILL);
} else { } else {
@ -275,19 +275,19 @@ static void children_kill_cb(uv_timer_t *handle)
} }
} }
static void process_close_event(void **argv) static void proc_close_event(void **argv)
{ {
Process *proc = argv[0]; Proc *proc = argv[0];
if (proc->cb) { if (proc->cb) {
// User (hint: channel_job_start) is responsible for calling // User (hint: channel_job_start) is responsible for calling
// process_free(). // proc_free().
proc->cb(proc, proc->status, proc->data); proc->cb(proc, proc->status, proc->data);
} else { } else {
process_free(proc); proc_free(proc);
} }
} }
static void decref(Process *proc) static void decref(Proc *proc)
{ {
if (--proc->refcount != 0) { if (--proc->refcount != 0) {
return; return;
@ -303,13 +303,13 @@ static void decref(Process *proc)
} }
assert(node); assert(node);
kl_shift_at(WatcherPtr, loop->children, node); kl_shift_at(WatcherPtr, loop->children, node);
CREATE_EVENT(proc->events, process_close_event, proc); CREATE_EVENT(proc->events, proc_close_event, proc);
} }
static void process_close(Process *proc) static void proc_close(Proc *proc)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(1)
{ {
if (process_is_tearing_down && (proc->detach || proc->type == kProcessTypePty) if (proc_is_tearing_down && (proc->detach || proc->type == kProcTypePty)
&& proc->closed) { && proc->closed) {
// If a detached/pty process dies while tearing down it might get closed // If a detached/pty process dies while tearing down it might get closed
// twice. // twice.
@ -319,17 +319,17 @@ static void process_close(Process *proc)
proc->closed = true; proc->closed = true;
if (proc->detach) { if (proc->detach) {
if (proc->type == kProcessTypeUv) { if (proc->type == kProcTypeUv) {
uv_unref((uv_handle_t *)&(((LibuvProcess *)proc)->uv)); uv_unref((uv_handle_t *)&(((LibuvProc *)proc)->uv));
} }
} }
switch (proc->type) { switch (proc->type) {
case kProcessTypeUv: case kProcTypeUv:
libuv_process_close((LibuvProcess *)proc); libuv_proc_close((LibuvProc *)proc);
break; break;
case kProcessTypePty: case kProcTypePty:
pty_process_close((PtyProcess *)proc); pty_proc_close((PtyProc *)proc);
break; break;
} }
} }
@ -338,7 +338,7 @@ static void process_close(Process *proc)
/// ///
/// @param proc Process, for which an output stream should be flushed. /// @param proc Process, for which an output stream should be flushed.
/// @param stream Stream to flush. /// @param stream Stream to flush.
static void flush_stream(Process *proc, RStream *stream) static void flush_stream(Proc *proc, RStream *stream)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(1)
{ {
if (!stream || stream->s.closed) { if (!stream || stream->s.closed) {
@ -382,16 +382,16 @@ static void flush_stream(Process *proc, RStream *stream)
} }
} }
static void process_close_handles(void **argv) static void proc_close_handles(void **argv)
{ {
Process *proc = argv[0]; Proc *proc = argv[0];
exit_need_delay++; exit_need_delay++;
flush_stream(proc, &proc->out); flush_stream(proc, &proc->out);
flush_stream(proc, &proc->err); flush_stream(proc, &proc->err);
process_close_streams(proc); proc_close_streams(proc);
process_close(proc); proc_close(proc);
exit_need_delay--; exit_need_delay--;
} }
@ -426,7 +426,7 @@ void exit_from_channel(int status)
multiqueue_put(main_loop.fast_events, exit_event, (void *)(intptr_t)status); multiqueue_put(main_loop.fast_events, exit_event, (void *)(intptr_t)status);
} }
static void on_process_exit(Process *proc) static void on_proc_exit(Proc *proc)
{ {
Loop *loop = proc->loop; Loop *loop = proc->loop;
ILOG("exited: pid=%d status=%d stoptime=%" PRIu64, proc->pid, proc->status, ILOG("exited: pid=%d status=%d stoptime=%" PRIu64, proc->pid, proc->status,
@ -439,13 +439,13 @@ static void on_process_exit(Process *proc)
// Process has terminated, but there could still be data to be read from the // Process has terminated, but there could still be data to be read from the
// OS. We are still in the libuv loop, so we cannot call code that polls for // OS. We are still in the libuv loop, so we cannot call code that polls for
// more data directly. Instead delay the reading after the libuv loop by // more data directly. Instead delay the reading after the libuv loop by
// queueing process_close_handles() as an event. // queueing proc_close_handles() as an event.
MultiQueue *queue = proc->events ? proc->events : loop->events; MultiQueue *queue = proc->events ? proc->events : loop->events;
CREATE_EVENT(queue, process_close_handles, proc); CREATE_EVENT(queue, proc_close_handles, proc);
} }
static void on_process_stream_close(Stream *stream, void *data) static void on_proc_stream_close(Stream *stream, void *data)
{ {
Process *proc = data; Proc *proc = data;
decref(proc); decref(proc);
} }

View File

@ -6,9 +6,9 @@
#include "nvim/event/defs.h" // IWYU pragma: keep #include "nvim/event/defs.h" // IWYU pragma: keep
#include "nvim/types_defs.h" #include "nvim/types_defs.h"
static inline Process process_init(Loop *loop, ProcessType type, void *data) static inline Proc proc_init(Loop *loop, ProcType type, void *data)
{ {
return (Process) { return (Proc) {
.type = type, .type = type,
.data = data, .data = data,
.loop = loop, .loop = loop,
@ -33,17 +33,17 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data)
} }
/// Get the path to the executable of the process. /// Get the path to the executable of the process.
static inline const char *process_get_exepath(Process *proc) static inline const char *proc_get_exepath(Proc *proc)
{ {
return proc->exepath != NULL ? proc->exepath : proc->argv[0]; return proc->exepath != NULL ? proc->exepath : proc->argv[0];
} }
static inline bool process_is_stopped(Process *proc) static inline bool proc_is_stopped(Proc *proc)
{ {
bool exited = (proc->status >= 0); bool exited = (proc->status >= 0);
return exited || (proc->stopped_time != 0); return exited || (proc->stopped_time != 0);
} }
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/process.h.generated.h" # include "event/proc.h.generated.h"
#endif #endif

View File

@ -94,14 +94,17 @@ void stream_init(Loop *loop, Stream *stream, int fd, uv_stream_t *uvstream)
stream->events = NULL; stream->events = NULL;
} }
void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data, bool rstream) void stream_may_close(Stream *stream, bool rstream)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(1)
{ {
if (stream->closed) {
return;
}
assert(!stream->closed); assert(!stream->closed);
DLOG("closing Stream: %p", (void *)stream); DLOG("closing Stream: %p", (void *)stream);
stream->closed = true; stream->closed = true;
stream->close_cb = on_stream_close; stream->close_cb = NULL;
stream->close_cb_data = data; stream->close_cb_data = NULL;
#ifdef MSWIN #ifdef MSWIN
if (UV_TTY == uv_guess_handle(stream->fd)) { if (UV_TTY == uv_guess_handle(stream->fd)) {
@ -115,13 +118,6 @@ void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data, b
} }
} }
void stream_may_close(Stream *stream, bool rstream)
{
if (!stream->closed) {
stream_close(stream, NULL, NULL, rstream);
}
}
void stream_close_handle(Stream *stream, bool rstream) void stream_close_handle(Stream *stream, bool rstream)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {

View File

@ -2,8 +2,6 @@ local mpack = vim.mpack
local hashy = require 'generators.hashy' local hashy = require 'generators.hashy'
local pre_args = 7
assert(#arg >= pre_args)
-- output h file with generated dispatch functions (dispatch_wrappers.generated.h) -- output h file with generated dispatch functions (dispatch_wrappers.generated.h)
local dispatch_outputf = arg[1] local dispatch_outputf = arg[1]
-- output h file with packed metadata (api_metadata.generated.h) -- output h file with packed metadata (api_metadata.generated.h)
@ -14,6 +12,12 @@ local lua_c_bindings_outputf = arg[4] -- lua_api_c_bindings.generated.c
local keysets_outputf = arg[5] -- keysets_defs.generated.h local keysets_outputf = arg[5] -- keysets_defs.generated.h
local ui_metadata_inputf = arg[6] -- ui events metadata local ui_metadata_inputf = arg[6] -- ui events metadata
local git_version_inputf = arg[7] -- git version header local git_version_inputf = arg[7] -- git version header
local nvim_version_inputf = arg[8] -- nvim version
local c_grammar_inputf = arg[9]
local dump_bin_array_inputf = arg[10]
local dispatch_deprecated_inputf = arg[11]
local pre_args = 11
assert(#arg >= pre_args)
local functions = {} local functions = {}
@ -24,7 +28,7 @@ local headers = {}
-- set of function names, used to detect duplicates -- set of function names, used to detect duplicates
local function_names = {} local function_names = {}
local c_grammar = require('generators.c_grammar') local c_grammar = loadfile(c_grammar_inputf)()
local startswith = vim.startswith local startswith = vim.startswith
@ -143,7 +147,7 @@ end
-- Export functions under older deprecated names. -- Export functions under older deprecated names.
-- These will be removed eventually. -- These will be removed eventually.
local deprecated_aliases = require('api.dispatch_deprecated') local deprecated_aliases = loadfile(dispatch_deprecated_inputf)()
for _, f in ipairs(shallowcopy(functions)) do for _, f in ipairs(shallowcopy(functions)) do
local ismethod = false local ismethod = false
if startswith(f.name, 'nvim_') then if startswith(f.name, 'nvim_') then
@ -235,7 +239,7 @@ for x in string.gmatch(ui_options_text, '"([a-z][a-z_]+)"') do
table.insert(ui_options, x) table.insert(ui_options, x)
end end
local version = require 'nvim_version' local version = loadfile(nvim_version_inputf)()
local git_version = io.open(git_version_inputf):read '*a' local git_version = io.open(git_version_inputf):read '*a'
local version_build = string.match(git_version, '#define NVIM_VERSION_BUILD "([^"]+)"') or vim.NIL local version_build = string.match(git_version, '#define NVIM_VERSION_BUILD "([^"]+)"') or vim.NIL
@ -296,7 +300,7 @@ for i, item in ipairs(types) do
end end
local packed = table.concat(pieces) local packed = table.concat(pieces)
local dump_bin_array = require('generators.dump_bin_array') local dump_bin_array = loadfile(dump_bin_array_inputf)()
dump_bin_array(api_metadata_output, 'packed_api_metadata', packed) dump_bin_array(api_metadata_output, 'packed_api_metadata', packed)
api_metadata_output:close() api_metadata_output:close()

View File

@ -1,13 +1,14 @@
local mpack = vim.mpack local mpack = vim.mpack
assert(#arg == 5) assert(#arg == 6)
local input = io.open(arg[1], 'rb') local input = io.open(arg[1], 'rb')
local call_output = io.open(arg[2], 'wb') local call_output = io.open(arg[2], 'wb')
local remote_output = io.open(arg[3], 'wb') local remote_output = io.open(arg[3], 'wb')
local metadata_output = io.open(arg[4], 'wb') local metadata_output = io.open(arg[4], 'wb')
local client_output = io.open(arg[5], 'wb') local client_output = io.open(arg[5], 'wb')
local c_grammar_inputf = arg[6]
local c_grammar = require('generators.c_grammar') local c_grammar = loadfile(c_grammar_inputf)()
local events = c_grammar.grammar:match(input:read('*all')) local events = c_grammar.grammar:match(input:read('*all'))
local hashy = require 'generators.hashy' local hashy = require 'generators.hashy'

View File

@ -1,10 +1,9 @@
local mpack = vim.mpack local mpack = vim.mpack
local autodir = arg[1] local funcsfname = arg[1]
local metadata_file = arg[2] local metadata_file = arg[2]
local funcs_file = arg[3] local funcs_file = arg[3]
local eval_file = arg[4]
local funcsfname = autodir .. '/funcs.generated.h'
--Will generate funcs.generated.h with definition of functions static const array. --Will generate funcs.generated.h with definition of functions static const array.
@ -46,7 +45,7 @@ hashpipe:write([[
]]) ]])
local funcs = require('eval').funcs local funcs = loadfile(eval_file)().funcs
for _, func in pairs(funcs) do for _, func in pairs(funcs) do
if func.float_func then if func.float_func then
func.func = 'float_op_wrapper' func.func = 'float_op_wrapper'

View File

@ -1,7 +1,8 @@
local fileio_enum_file = arg[1] local fileio_enum_file = arg[1]
local names_file = arg[2] local names_file = arg[2]
local auevents_file = arg[3]
local auevents = require('auevents') local auevents = loadfile(auevents_file)()
local events = auevents.events local events = auevents.events
local aliases = auevents.aliases local aliases = auevents.aliases

View File

@ -1,17 +1,15 @@
local includedir = arg[1]
local autodir = arg[2]
-- Will generate files ex_cmds_enum.generated.h with cmdidx_T enum -- Will generate files ex_cmds_enum.generated.h with cmdidx_T enum
-- and ex_cmds_defs.generated.h with main Ex commands definitions. -- and ex_cmds_defs.generated.h with main Ex commands definitions.
local enumfname = includedir .. '/ex_cmds_enum.generated.h' local enumfname = arg[1] -- '/ex_cmds_enum.generated.h'
local defsfname = autodir .. '/ex_cmds_defs.generated.h' local defsfname = arg[2] -- '/ex_cmds_defs.generated.h'
local ex_cmds_name = arg[3] -- 'ex_cmds.lua'
local enumfile = io.open(enumfname, 'w') local enumfile = io.open(enumfname, 'w')
local defsfile = io.open(defsfname, 'w') local defsfile = io.open(defsfname, 'w')
local bit = require 'bit' local bit = require 'bit'
local ex_cmds = require('ex_cmds') local ex_cmds = loadfile(ex_cmds_name)()
local defs = ex_cmds.cmds local defs = ex_cmds.cmds
local flags = ex_cmds.flags local flags = ex_cmds.flags

View File

@ -1,4 +1,5 @@
local options_file = arg[1] local options_file = arg[1]
local options_input_file = arg[2]
local opt_fd = assert(io.open(options_file, 'w')) local opt_fd = assert(io.open(options_file, 'w'))
@ -11,7 +12,7 @@ local w = function(s)
end end
--- @module 'nvim.options' --- @module 'nvim.options'
local options = require('options') local options = loadfile(options_input_file)()
local cstr = options.cstr local cstr = options.cstr

View File

@ -4,6 +4,8 @@
local options_enum_file = arg[1] local options_enum_file = arg[1]
local options_map_file = arg[2] local options_map_file = arg[2]
local options_input_file = arg[3]
local options_enum_fd = assert(io.open(options_enum_file, 'w')) local options_enum_fd = assert(io.open(options_enum_file, 'w'))
local options_map_fd = assert(io.open(options_map_file, 'w')) local options_map_fd = assert(io.open(options_map_file, 'w'))
@ -27,7 +29,7 @@ local lowercase_to_titlecase = function(s)
end end
--- @type vim.option_meta[] --- @type vim.option_meta[]
local options = require('options').options local options = loadfile(options_input_file)().options
-- Generate BV_ enum constants. -- Generate BV_ enum constants.
enum_w('/// "indir" values for buffer-local options.') enum_w('/// "indir" values for buffer-local options.')

View File

@ -29,6 +29,7 @@
#include "nvim/os/stdpaths_defs.h" #include "nvim/os/stdpaths_defs.h"
#include "nvim/os/time.h" #include "nvim/os/time.h"
#include "nvim/path.h" #include "nvim/path.h"
#include "nvim/ui_client.h"
/// Cached location of the expanded log file path decided by log_path_init(). /// Cached location of the expanded log file path decided by log_path_init().
static char log_file_path[MAXPATHL + 1] = { 0 }; static char log_file_path[MAXPATHL + 1] = { 0 };
@ -322,20 +323,28 @@ static bool v_do_log_to_file(FILE *log_file, int log_level, const char *context,
millis = (int)curtime.tv_usec / 1000; millis = (int)curtime.tv_usec / 1000;
} }
bool ui = !!ui_client_channel_id; // Running as a UI client (--remote-ui).
// Regenerate the name when:
// - UI client (to ensure "ui" is in the name)
// - not set yet
// - no v:servername yet
bool regen = ui || name[0] == NUL || name[0] == '?';
// Get a name for this Nvim instance. // Get a name for this Nvim instance.
// TODO(justinmk): expose this as v:name ? // TODO(justinmk): expose this as v:name ?
if (name[0] == NUL) { if (regen) {
// Parent servername. // Parent servername ($NVIM).
const char *parent = path_tail(os_getenv(ENV_NVIM)); const char *parent = path_tail(os_getenv(ENV_NVIM));
// Servername. Empty until starting=false. // Servername. Empty until starting=false.
const char *serv = path_tail(get_vim_var_str(VV_SEND_SERVER)); const char *serv = path_tail(get_vim_var_str(VV_SEND_SERVER));
if (parent[0] != NUL) { if (parent[0] != NUL) {
snprintf(name, sizeof(name), "%s/c", parent); // "/c" indicates child. snprintf(name, sizeof(name), ui ? "ui/c/%s" : "c/%s", parent); // "c/" = child of $NVIM.
} else if (serv[0] != NUL) { } else if (serv[0] != NUL) {
snprintf(name, sizeof(name), "%s", serv); snprintf(name, sizeof(name), ui ? "ui/%s" : "%s", serv);
} else { } else {
int64_t pid = os_get_pid(); int64_t pid = os_get_pid();
snprintf(name, sizeof(name), "?.%-5" PRId64, pid); snprintf(name, sizeof(name), "%s.%-5" PRId64, ui ? "ui" : "?", pid);
} }
} }
@ -348,10 +357,6 @@ static bool v_do_log_to_file(FILE *log_file, int log_level, const char *context,
log_levels[log_level], date_time, millis, name, log_levels[log_level], date_time, millis, name,
(context == NULL ? "" : context), (context == NULL ? "" : context),
func_name, line_num); func_name, line_num);
if (name[0] == '?') {
// No v:servername yet. Clear `name` so that the next log can try again.
name[0] = NUL;
}
if (rv < 0) { if (rv < 0) {
return false; return false;

View File

@ -660,7 +660,7 @@ static inline void nlua_create_typed_table(lua_State *lstate, const size_t narr,
void nlua_push_String(lua_State *lstate, const String s, int flags) void nlua_push_String(lua_State *lstate, const String s, int flags)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
lua_pushlstring(lstate, s.data, s.size); lua_pushlstring(lstate, s.size ? s.data : "", s.size);
} }
/// Convert given Integer to lua number /// Convert given Integer to lua number

View File

@ -43,7 +43,7 @@
#include "nvim/eval/userfunc.h" #include "nvim/eval/userfunc.h"
#include "nvim/event/loop.h" #include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h" #include "nvim/event/multiqueue.h"
#include "nvim/event/process.h" #include "nvim/event/proc.h"
#include "nvim/event/stream.h" #include "nvim/event/stream.h"
#include "nvim/ex_cmds.h" #include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h" #include "nvim/ex_docmd.h"
@ -174,7 +174,7 @@ bool event_teardown(void)
loop_poll_events(&main_loop, 0); // Drain thread_events, fast_events. loop_poll_events(&main_loop, 0); // Drain thread_events, fast_events.
input_stop(); input_stop();
channel_teardown(); channel_teardown();
process_teardown(&main_loop); proc_teardown(&main_loop);
timer_teardown(); timer_teardown();
server_teardown(); server_teardown();
signal_teardown(); signal_teardown();
@ -2207,7 +2207,7 @@ static void usage(void)
printf(_(" --headless Don't start a user interface\n")); printf(_(" --headless Don't start a user interface\n"));
printf(_(" --listen <address> Serve RPC API from this address\n")); printf(_(" --listen <address> Serve RPC API from this address\n"));
printf(_(" --remote[-subcommand] Execute commands remotely on a server\n")); printf(_(" --remote[-subcommand] Execute commands remotely on a server\n"));
printf(_(" --server <address> Specify RPC server to send commands to\n")); printf(_(" --server <address> Connect to this Nvim server\n"));
printf(_(" --startuptime <file> Write startup timing messages to <file>\n")); printf(_(" --startuptime <file> Write startup timing messages to <file>\n"));
printf(_("\nSee \":help startup-options\" for all options.\n")); printf(_("\nSee \":help startup-options\" for all options.\n"));
} }

View File

@ -84,7 +84,7 @@
#include "nvim/os/input.h" #include "nvim/os/input.h"
#include "nvim/os/os.h" #include "nvim/os/os.h"
#include "nvim/os/os_defs.h" #include "nvim/os/os_defs.h"
#include "nvim/os/process.h" #include "nvim/os/proc.h"
#include "nvim/os/time.h" #include "nvim/os/time.h"
#include "nvim/os/time_defs.h" #include "nvim/os/time_defs.h"
#include "nvim/path.h" #include "nvim/path.h"
@ -743,7 +743,7 @@ static void add_b0_fenc(ZeroBlock *b0p, buf_T *buf)
/// @param swap_fname Name of the swapfile. If it's from before a reboot, the result is 0. /// @param swap_fname Name of the swapfile. If it's from before a reboot, the result is 0.
/// ///
/// @return PID, or 0 if process is not running or the swapfile is from before a reboot. /// @return PID, or 0 if process is not running or the swapfile is from before a reboot.
static int swapfile_process_running(const ZeroBlock *b0p, const char *swap_fname) static int swapfile_proc_running(const ZeroBlock *b0p, const char *swap_fname)
{ {
FileInfo st; FileInfo st;
double uptime; double uptime;
@ -1214,7 +1214,7 @@ void ml_recover(bool checkext)
msg(_("Recovery completed. Buffer contents equals file contents."), 0); msg(_("Recovery completed. Buffer contents equals file contents."), 0);
} }
msg_puts(_("\nYou may want to delete the .swp file now.")); msg_puts(_("\nYou may want to delete the .swp file now."));
if (swapfile_process_running(b0p, fname_used)) { if (swapfile_proc_running(b0p, fname_used)) {
// Warn there could be an active Vim on the same file, the user may // Warn there could be an active Vim on the same file, the user may
// want to kill it. // want to kill it.
msg_puts(_("\nNote: process STILL RUNNING: ")); msg_puts(_("\nNote: process STILL RUNNING: "));
@ -1462,7 +1462,7 @@ char *make_percent_swname(char *dir, char *dir_end, const char *name)
} }
// PID of swapfile owner, or zero if not running. // PID of swapfile owner, or zero if not running.
static int process_running; static int proc_running;
/// For Vimscript "swapinfo()". /// For Vimscript "swapinfo()".
/// ///
@ -1488,7 +1488,7 @@ void swapfile_dict(const char *fname, dict_T *d)
tv_dict_add_str_len(d, S_LEN("fname"), b0.b0_fname, tv_dict_add_str_len(d, S_LEN("fname"), b0.b0_fname,
B0_FNAME_SIZE_ORG); B0_FNAME_SIZE_ORG);
tv_dict_add_nr(d, S_LEN("pid"), swapfile_process_running(&b0, fname)); tv_dict_add_nr(d, S_LEN("pid"), swapfile_proc_running(&b0, fname));
tv_dict_add_nr(d, S_LEN("mtime"), char_to_long(b0.b0_mtime)); tv_dict_add_nr(d, S_LEN("mtime"), char_to_long(b0.b0_mtime));
tv_dict_add_nr(d, S_LEN("dirty"), b0.b0_dirty ? 1 : 0); tv_dict_add_nr(d, S_LEN("dirty"), b0.b0_dirty ? 1 : 0);
tv_dict_add_nr(d, S_LEN("inode"), char_to_long(b0.b0_ino)); tv_dict_add_nr(d, S_LEN("inode"), char_to_long(b0.b0_ino));
@ -1572,7 +1572,7 @@ static time_t swapfile_info(char *fname)
if (char_to_long(b0.b0_pid) != 0) { if (char_to_long(b0.b0_pid) != 0) {
msg_puts(_("\n process ID: ")); msg_puts(_("\n process ID: "));
msg_outnum((int)char_to_long(b0.b0_pid)); msg_outnum((int)char_to_long(b0.b0_pid));
if ((process_running = swapfile_process_running(&b0, fname))) { if ((proc_running = swapfile_proc_running(&b0, fname))) {
msg_puts(_(" (STILL RUNNING)")); msg_puts(_(" (STILL RUNNING)"));
} }
} }
@ -1640,7 +1640,7 @@ static bool swapfile_unchanged(char *fname)
} }
// process must be known and not running. // process must be known and not running.
if (char_to_long(b0.b0_pid) == 0 || swapfile_process_running(&b0, fname)) { if (char_to_long(b0.b0_pid) == 0 || swapfile_proc_running(&b0, fname)) {
ret = false; ret = false;
} }
@ -3399,7 +3399,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
fd = os_open(fname, O_RDONLY, 0); fd = os_open(fname, O_RDONLY, 0);
if (fd >= 0) { if (fd >= 0) {
if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) { if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) {
process_running = swapfile_process_running(&b0, fname); proc_running = swapfile_proc_running(&b0, fname);
// If the swapfile has the same directory as the // If the swapfile has the same directory as the
// buffer don't compare the directory names, they can // buffer don't compare the directory names, they can
@ -3459,7 +3459,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
choice = SEA_CHOICE_READONLY; choice = SEA_CHOICE_READONLY;
} }
process_running = 0; // Set by attention_message..swapfile_info. proc_running = 0; // Set by attention_message..swapfile_info.
if (choice == SEA_CHOICE_NONE) { if (choice == SEA_CHOICE_NONE) {
// Show info about the existing swapfile. // Show info about the existing swapfile.
attention_message(buf, fname); attention_message(buf, fname);
@ -3491,12 +3491,12 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
= do_dialog(VIM_WARNING, = do_dialog(VIM_WARNING,
_("VIM - ATTENTION"), _("VIM - ATTENTION"),
name, name,
process_running proc_running
? _("&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort") ? _("&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort")
: _("&Open Read-Only\n&Edit anyway\n&Recover\n&Delete it\n&Quit\n&Abort"), : _("&Open Read-Only\n&Edit anyway\n&Recover\n&Delete it\n&Quit\n&Abort"),
1, NULL, false); 1, NULL, false);
if (process_running && dialog_result >= 4) { if (proc_running && dialog_result >= 4) {
// compensate for missing "Delete it" button // compensate for missing "Delete it" button
dialog_result++; dialog_result++;
} }

View File

@ -14,7 +14,7 @@
#include "nvim/event/defs.h" #include "nvim/event/defs.h"
#include "nvim/event/loop.h" #include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h" #include "nvim/event/multiqueue.h"
#include "nvim/event/process.h" #include "nvim/event/proc.h"
#include "nvim/event/rstream.h" #include "nvim/event/rstream.h"
#include "nvim/event/wstream.h" #include "nvim/event/wstream.h"
#include "nvim/globals.h" #include "nvim/globals.h"

View File

@ -53,7 +53,7 @@ bool server_init(const char *listen_addr)
int rv = server_start(listen_addr); int rv = server_start(listen_addr);
// TODO(justinmk): this is for logging_spec. Can remove this after nvim_log #7062 is merged. // TODO(justinmk): this is for log_spec. Can remove this after nvim_log #7062 is merged.
if (os_env_exists("__NVIM_TEST_LOG")) { if (os_env_exists("__NVIM_TEST_LOG")) {
ELOG("test log message"); ELOG("test log message");
} }

View File

@ -9047,7 +9047,7 @@ return {
desc = [=[ desc = [=[
When on, the title of the window will be set to the value of When on, the title of the window will be set to the value of
'titlestring' (if it is not empty), or to: 'titlestring' (if it is not empty), or to:
filename [+=-] (path) - NVIM filename [+=-] (path) - Nvim
Where: Where:
filename the name of the file being edited filename the name of the file being edited
- indicates the file cannot be modified, 'ma' off - indicates the file cannot be modified, 'ma' off
@ -9055,11 +9055,11 @@ return {
= indicates the file is read-only = indicates the file is read-only
=+ indicates the file is read-only and modified =+ indicates the file is read-only and modified
(path) is the path of the file being edited (path) is the path of the file being edited
- NVIM the server name |v:servername| or "NVIM" - Nvim the server name |v:servername| or "Nvim"
]=], ]=],
full_name = 'title', full_name = 'title',
scope = { 'global' }, scope = { 'global' },
short_desc = N_('Vim set the title of the window'), short_desc = N_('set the title of the window'),
type = 'boolean', type = 'boolean',
varname = 'p_title', varname = 'p_title',
}, },

View File

@ -344,7 +344,7 @@ char *os_getenvname_at_index(size_t index)
#endif #endif
} }
/// Get the process ID of the Neovim process. /// Get the process ID of the Nvim process.
/// ///
/// @return the process ID. /// @return the process ID.
int64_t os_get_pid(void) int64_t os_get_pid(void)

View File

@ -100,7 +100,7 @@ static void reset_cursorhold_wait(int tb_change_cnt)
/// ///
/// Originally based on the Vim `mch_inchar` function. /// Originally based on the Vim `mch_inchar` function.
/// ///
/// @param buf Buffer to store read input. /// @param buf Buffer to store consumed input.
/// @param maxlen Maximum bytes to read into `buf`, or 0 to skip reading. /// @param maxlen Maximum bytes to read into `buf`, or 0 to skip reading.
/// @param ms Timeout in milliseconds. -1 for indefinite wait, 0 for no wait. /// @param ms Timeout in milliseconds. -1 for indefinite wait, 0 for no wait.
/// @param tb_change_cnt Used to detect when typeahead changes. /// @param tb_change_cnt Used to detect when typeahead changes.
@ -493,7 +493,7 @@ static TriState inbuf_poll(int ms, MultiQueue *events)
blocking = true; blocking = true;
multiqueue_process_events(ch_before_blocking_events); multiqueue_process_events(ch_before_blocking_events);
} }
DLOG("blocking... events=%d pending=%d", !!events, pending_events(events)); DLOG("blocking... events=%s", !!events ? "true" : "false");
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, os_input_ready(events) || input_eof); LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, os_input_ready(events) || input_eof);
blocking = false; blocking = false;

View File

@ -37,24 +37,24 @@
#include "nvim/log.h" #include "nvim/log.h"
#include "nvim/memory.h" #include "nvim/memory.h"
#include "nvim/os/process.h" #include "nvim/os/proc.h"
#ifdef MSWIN #ifdef MSWIN
# include "nvim/api/private/helpers.h" # include "nvim/api/private/helpers.h"
#endif #endif
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/process.c.generated.h" # include "os/proc.c.generated.h"
#endif #endif
#ifdef MSWIN #ifdef MSWIN
static bool os_proc_tree_kill_rec(HANDLE process, int sig) static bool os_proc_tree_kill_rec(HANDLE proc, int sig)
{ {
if (process == NULL) { if (proc == NULL) {
return false; return false;
} }
PROCESSENTRY32 pe; PROCESSENTRY32 pe;
DWORD pid = GetProcessId(process); DWORD pid = GetProcessId(proc);
if (pid != 0) { if (pid != 0) {
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
@ -77,7 +77,7 @@ static bool os_proc_tree_kill_rec(HANDLE process, int sig)
} }
theend: theend:
return (bool)TerminateProcess(process, (unsigned)sig); return (bool)TerminateProcess(proc, (unsigned)sig);
} }
/// Kills process `pid` and its descendants recursively. /// Kills process `pid` and its descendants recursively.
bool os_proc_tree_kill(int pid, int sig) bool os_proc_tree_kill(int pid, int sig)

View File

@ -7,5 +7,5 @@
#endif #endif
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/process.h.generated.h" # include "os/proc.h.generated.h"
#endif #endif

View File

@ -143,7 +143,7 @@ finished:
return conpty_object; return conpty_object;
} }
bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, wchar_t *name, bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *proc_handle, wchar_t *name,
wchar_t *cmd_line, wchar_t *cwd, wchar_t *env) wchar_t *cmd_line, wchar_t *cwd, wchar_t *env)
{ {
PROCESS_INFORMATION pi = { 0 }; PROCESS_INFORMATION pi = { 0 };
@ -159,7 +159,7 @@ bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, wchar_t *n
&pi)) { &pi)) {
return false; return false;
} }
*process_handle = pi.hProcess; *proc_handle = pi.hProcess;
return true; return true;
} }

7
src/nvim/os/pty_proc.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#ifdef MSWIN
# include "nvim/os/pty_proc_win.h"
#else
# include "nvim/os/pty_proc_unix.h"
#endif

View File

@ -34,16 +34,16 @@
#include "nvim/eval/typval.h" #include "nvim/eval/typval.h"
#include "nvim/event/defs.h" #include "nvim/event/defs.h"
#include "nvim/event/loop.h" #include "nvim/event/loop.h"
#include "nvim/event/process.h" #include "nvim/event/proc.h"
#include "nvim/log.h" #include "nvim/log.h"
#include "nvim/os/fs.h" #include "nvim/os/fs.h"
#include "nvim/os/os_defs.h" #include "nvim/os/os_defs.h"
#include "nvim/os/pty_process.h" #include "nvim/os/pty_proc.h"
#include "nvim/os/pty_process_unix.h" #include "nvim/os/pty_proc_unix.h"
#include "nvim/types_defs.h" #include "nvim/types_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/pty_process_unix.c.generated.h" # include "os/pty_proc_unix.c.generated.h"
#endif #endif
#if defined(__sun) && !defined(HAVE_FORKPTY) #if defined(__sun) && !defined(HAVE_FORKPTY)
@ -158,7 +158,7 @@ static pid_t forkpty(int *amaster, char *name, struct termios *termp, struct win
#endif #endif
/// @returns zero on success, or negative error code /// @returns zero on success, or negative error code
int pty_process_spawn(PtyProcess *ptyproc) int pty_proc_spawn(PtyProc *ptyproc)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
// termios initialized at first use // termios initialized at first use
@ -168,7 +168,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
} }
int status = 0; // zero or negative error code (libuv convention) int status = 0; // zero or negative error code (libuv convention)
Process *proc = (Process *)ptyproc; Proc *proc = (Proc *)ptyproc;
assert(proc->err.s.closed); assert(proc->err.s.closed);
uv_signal_start(&proc->loop->children_watcher, chld_handler, SIGCHLD); uv_signal_start(&proc->loop->children_watcher, chld_handler, SIGCHLD);
ptyproc->winsize = (struct winsize){ ptyproc->height, ptyproc->width, 0, 0 }; ptyproc->winsize = (struct winsize){ ptyproc->height, ptyproc->width, 0, 0 };
@ -224,29 +224,29 @@ error:
return status; return status;
} }
const char *pty_process_tty_name(PtyProcess *ptyproc) const char *pty_proc_tty_name(PtyProc *ptyproc)
{ {
return ptsname(ptyproc->tty_fd); return ptsname(ptyproc->tty_fd);
} }
void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height) void pty_proc_resize(PtyProc *ptyproc, uint16_t width, uint16_t height)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
ptyproc->winsize = (struct winsize){ height, width, 0, 0 }; ptyproc->winsize = (struct winsize){ height, width, 0, 0 };
ioctl(ptyproc->tty_fd, TIOCSWINSZ, &ptyproc->winsize); ioctl(ptyproc->tty_fd, TIOCSWINSZ, &ptyproc->winsize);
} }
void pty_process_close(PtyProcess *ptyproc) void pty_proc_close(PtyProc *ptyproc)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
pty_process_close_master(ptyproc); pty_proc_close_master(ptyproc);
Process *proc = (Process *)ptyproc; Proc *proc = (Proc *)ptyproc;
if (proc->internal_close_cb) { if (proc->internal_close_cb) {
proc->internal_close_cb(proc); proc->internal_close_cb(proc);
} }
} }
void pty_process_close_master(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL void pty_proc_close_master(PtyProc *ptyproc) FUNC_ATTR_NONNULL_ALL
{ {
if (ptyproc->tty_fd >= 0) { if (ptyproc->tty_fd >= 0) {
close(ptyproc->tty_fd); close(ptyproc->tty_fd);
@ -254,12 +254,12 @@ void pty_process_close_master(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL
} }
} }
void pty_process_teardown(Loop *loop) void pty_proc_teardown(Loop *loop)
{ {
uv_signal_stop(&loop->children_watcher); uv_signal_stop(&loop->children_watcher);
} }
static void init_child(PtyProcess *ptyproc) static void init_child(PtyProc *ptyproc)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
#if defined(HAVE__NSGETENVIRON) #if defined(HAVE__NSGETENVIRON)
@ -277,13 +277,13 @@ static void init_child(PtyProcess *ptyproc)
signal(SIGTERM, SIG_DFL); signal(SIGTERM, SIG_DFL);
signal(SIGALRM, SIG_DFL); signal(SIGALRM, SIG_DFL);
Process *proc = (Process *)ptyproc; Proc *proc = (Proc *)ptyproc;
if (proc->cwd && os_chdir(proc->cwd) != 0) { if (proc->cwd && os_chdir(proc->cwd) != 0) {
ELOG("chdir(%s) failed: %s", proc->cwd, strerror(errno)); ELOG("chdir(%s) failed: %s", proc->cwd, strerror(errno));
return; return;
} }
const char *prog = process_get_exepath(proc); const char *prog = proc_get_exepath(proc);
assert(proc->env); assert(proc->env);
environ = tv_dict_to_env(proc->env); environ = tv_dict_to_env(proc->env);
@ -388,7 +388,7 @@ static void chld_handler(uv_signal_t *handle, int signum)
Loop *loop = handle->loop->data; Loop *loop = handle->loop->data;
kl_iter(WatcherPtr, loop->children, current) { kl_iter(WatcherPtr, loop->children, current) {
Process *proc = (*current)->data; Proc *proc = (*current)->data;
do { do {
pid = waitpid(proc->pid, &stat, WNOHANG); pid = waitpid(proc->pid, &stat, WNOHANG);
} while (pid < 0 && errno == EINTR); } while (pid < 0 && errno == EINTR);
@ -406,10 +406,10 @@ static void chld_handler(uv_signal_t *handle, int signum)
} }
} }
PtyProcess pty_process_init(Loop *loop, void *data) PtyProc pty_proc_init(Loop *loop, void *data)
{ {
PtyProcess rv; PtyProc rv;
rv.process = process_init(loop, kProcessTypePty, data); rv.proc = proc_init(loop, kProcTypePty, data);
rv.width = 80; rv.width = 80;
rv.height = 24; rv.height = 24;
rv.tty_fd = -1; rv.tty_fd = -1;

View File

@ -1,5 +1,5 @@
#pragma once #pragma once
// IWYU pragma: private, include "nvim/os/pty_process.h" // IWYU pragma: private, include "nvim/os/pty_proc.h"
#include <stdint.h> #include <stdint.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -7,12 +7,12 @@
#include "nvim/event/defs.h" #include "nvim/event/defs.h"
typedef struct { typedef struct {
Process process; Proc proc;
uint16_t width, height; uint16_t width, height;
struct winsize winsize; struct winsize winsize;
int tty_fd; int tty_fd;
} PtyProcess; } PtyProc;
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/pty_process_unix.h.generated.h" # include "os/pty_proc_unix.h.generated.h"
#endif #endif

View File

@ -10,20 +10,20 @@
#include "nvim/memory.h" #include "nvim/memory.h"
#include "nvim/os/os.h" #include "nvim/os/os.h"
#include "nvim/os/pty_conpty_win.h" #include "nvim/os/pty_conpty_win.h"
#include "nvim/os/pty_process_win.h" #include "nvim/os/pty_proc_win.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/pty_process_win.c.generated.h" # include "os/pty_proc_win.c.generated.h"
#endif #endif
static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused) static void CALLBACK pty_proc_finish1(void *context, BOOLEAN unused)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
PtyProcess *ptyproc = (PtyProcess *)context; PtyProc *ptyproc = (PtyProc *)context;
Process *proc = (Process *)ptyproc; Proc *proc = (Proc *)ptyproc;
os_conpty_free(ptyproc->conpty); os_conpty_free(ptyproc->conpty);
// NB: pty_process_finish1() is called on a separate thread, // NB: pty_proc_finish1() is called on a separate thread,
// but the timer only works properly if it's started by the main thread. // but the timer only works properly if it's started by the main thread.
loop_schedule_fast(proc->loop, event_create(start_wait_eof_timer, ptyproc)); loop_schedule_fast(proc->loop, event_create(start_wait_eof_timer, ptyproc));
} }
@ -31,7 +31,7 @@ static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused)
static void start_wait_eof_timer(void **argv) static void start_wait_eof_timer(void **argv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
PtyProcess *ptyproc = (PtyProcess *)argv[0]; PtyProc *ptyproc = (PtyProc *)argv[0];
if (ptyproc->finish_wait != NULL) { if (ptyproc->finish_wait != NULL) {
uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200); uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200);
@ -39,15 +39,15 @@ static void start_wait_eof_timer(void **argv)
} }
/// @returns zero on success, or negative error code. /// @returns zero on success, or negative error code.
int pty_process_spawn(PtyProcess *ptyproc) int pty_proc_spawn(PtyProc *ptyproc)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
Process *proc = (Process *)ptyproc; Proc *proc = (Proc *)ptyproc;
int status = 0; int status = 0;
conpty_t *conpty_object = NULL; conpty_t *conpty_object = NULL;
char *in_name = NULL; char *in_name = NULL;
char *out_name = NULL; char *out_name = NULL;
HANDLE process_handle = NULL; HANDLE proc_handle = NULL;
uv_connect_t *in_req = NULL; uv_connect_t *in_req = NULL;
uv_connect_t *out_req = NULL; uv_connect_t *out_req = NULL;
wchar_t *cmd_line = NULL; wchar_t *cmd_line = NULL;
@ -69,7 +69,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
uv_pipe_connect(in_req, uv_pipe_connect(in_req,
&proc->in.uv.pipe, &proc->in.uv.pipe,
in_name, in_name,
pty_process_connect_cb); pty_proc_connect_cb);
} }
if (!proc->out.s.closed) { if (!proc->out.s.closed) {
@ -77,7 +77,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
uv_pipe_connect(out_req, uv_pipe_connect(out_req,
&proc->out.s.uv.pipe, &proc->out.s.uv.pipe,
out_name, out_name,
pty_process_connect_cb); pty_proc_connect_cb);
} }
if (proc->cwd != NULL) { if (proc->cwd != NULL) {
@ -105,7 +105,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
} }
if (!os_conpty_spawn(conpty_object, if (!os_conpty_spawn(conpty_object,
&process_handle, &proc_handle,
NULL, NULL,
cmd_line, cmd_line,
cwd, cwd,
@ -114,42 +114,42 @@ int pty_process_spawn(PtyProcess *ptyproc)
status = (int)GetLastError(); status = (int)GetLastError();
goto cleanup; goto cleanup;
} }
proc->pid = (int)GetProcessId(process_handle); proc->pid = (int)GetProcessId(proc_handle);
uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer); uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer);
ptyproc->wait_eof_timer.data = (void *)ptyproc; ptyproc->wait_eof_timer.data = (void *)ptyproc;
if (!RegisterWaitForSingleObject(&ptyproc->finish_wait, if (!RegisterWaitForSingleObject(&ptyproc->finish_wait,
process_handle, proc_handle,
pty_process_finish1, pty_proc_finish1,
ptyproc, ptyproc,
INFINITE, INFINITE,
WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) { WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) {
abort(); abort();
} }
// Wait until pty_process_connect_cb is called. // Wait until pty_proc_connect_cb is called.
while ((in_req != NULL && in_req->handle != NULL) while ((in_req != NULL && in_req->handle != NULL)
|| (out_req != NULL && out_req->handle != NULL)) { || (out_req != NULL && out_req->handle != NULL)) {
uv_run(&proc->loop->uv, UV_RUN_ONCE); uv_run(&proc->loop->uv, UV_RUN_ONCE);
} }
ptyproc->conpty = conpty_object; ptyproc->conpty = conpty_object;
ptyproc->process_handle = process_handle; ptyproc->proc_handle = proc_handle;
conpty_object = NULL; conpty_object = NULL;
process_handle = NULL; proc_handle = NULL;
cleanup: cleanup:
if (status) { if (status) {
// In the case of an error of MultiByteToWideChar or CreateProcessW. // In the case of an error of MultiByteToWideChar or CreateProcessW.
ELOG("pty_process_spawn(%s): %s: error code: %d", ELOG("pty_proc_spawn(%s): %s: error code: %d",
proc->argv[0], emsg, status); proc->argv[0], emsg, status);
status = os_translate_sys_error(status); status = os_translate_sys_error(status);
} }
os_conpty_free(conpty_object); os_conpty_free(conpty_object);
xfree(in_name); xfree(in_name);
xfree(out_name); xfree(out_name);
if (process_handle != NULL) { if (proc_handle != NULL) {
CloseHandle(process_handle); CloseHandle(proc_handle);
} }
xfree(in_req); xfree(in_req);
xfree(out_req); xfree(out_req);
@ -159,32 +159,32 @@ cleanup:
return status; return status;
} }
const char *pty_process_tty_name(PtyProcess *ptyproc) const char *pty_proc_tty_name(PtyProc *ptyproc)
{ {
return "?"; return "?";
} }
void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height) void pty_proc_resize(PtyProc *ptyproc, uint16_t width, uint16_t height)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
os_conpty_set_size(ptyproc->conpty, width, height); os_conpty_set_size(ptyproc->conpty, width, height);
} }
void pty_process_close(PtyProcess *ptyproc) void pty_proc_close(PtyProc *ptyproc)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
Process *proc = (Process *)ptyproc; Proc *proc = (Proc *)ptyproc;
pty_process_close_master(ptyproc); pty_proc_close_master(ptyproc);
if (ptyproc->finish_wait != NULL) { if (ptyproc->finish_wait != NULL) {
UnregisterWaitEx(ptyproc->finish_wait, NULL); UnregisterWaitEx(ptyproc->finish_wait, NULL);
ptyproc->finish_wait = NULL; ptyproc->finish_wait = NULL;
uv_close((uv_handle_t *)&ptyproc->wait_eof_timer, NULL); uv_close((uv_handle_t *)&ptyproc->wait_eof_timer, NULL);
} }
if (ptyproc->process_handle != NULL) { if (ptyproc->proc_handle != NULL) {
CloseHandle(ptyproc->process_handle); CloseHandle(ptyproc->proc_handle);
ptyproc->process_handle = NULL; ptyproc->proc_handle = NULL;
} }
if (proc->internal_close_cb) { if (proc->internal_close_cb) {
@ -192,17 +192,17 @@ void pty_process_close(PtyProcess *ptyproc)
} }
} }
void pty_process_close_master(PtyProcess *ptyproc) void pty_proc_close_master(PtyProc *ptyproc)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
} }
void pty_process_teardown(Loop *loop) void pty_proc_teardown(Loop *loop)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
} }
static void pty_process_connect_cb(uv_connect_t *req, int status) static void pty_proc_connect_cb(uv_connect_t *req, int status)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
assert(status == 0); assert(status == 0);
@ -212,23 +212,23 @@ static void pty_process_connect_cb(uv_connect_t *req, int status)
static void wait_eof_timer_cb(uv_timer_t *wait_eof_timer) static void wait_eof_timer_cb(uv_timer_t *wait_eof_timer)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
PtyProcess *ptyproc = wait_eof_timer->data; PtyProc *ptyproc = wait_eof_timer->data;
Process *proc = (Process *)ptyproc; Proc *proc = (Proc *)ptyproc;
assert(ptyproc->finish_wait != NULL); assert(ptyproc->finish_wait != NULL);
if (proc->out.s.closed || proc->out.did_eof || !uv_is_readable(proc->out.s.uvstream)) { if (proc->out.s.closed || proc->out.did_eof || !uv_is_readable(proc->out.s.uvstream)) {
uv_timer_stop(&ptyproc->wait_eof_timer); uv_timer_stop(&ptyproc->wait_eof_timer);
pty_process_finish2(ptyproc); pty_proc_finish2(ptyproc);
} }
} }
static void pty_process_finish2(PtyProcess *ptyproc) static void pty_proc_finish2(PtyProc *ptyproc)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
Process *proc = (Process *)ptyproc; Proc *proc = (Proc *)ptyproc;
DWORD exit_code = 0; DWORD exit_code = 0;
GetExitCodeProcess(ptyproc->process_handle, &exit_code); GetExitCodeProcess(ptyproc->proc_handle, &exit_code);
proc->status = proc->exit_signal ? 128 + proc->exit_signal : (int)exit_code; proc->status = proc->exit_signal ? 128 + proc->exit_signal : (int)exit_code;
proc->internal_exit_cb(proc); proc->internal_exit_cb(proc);
@ -427,14 +427,14 @@ cleanup:
return rc; return rc;
} }
PtyProcess pty_process_init(Loop *loop, void *data) PtyProc pty_proc_init(Loop *loop, void *data)
{ {
PtyProcess rv; PtyProc rv;
rv.process = process_init(loop, kProcessTypePty, data); rv.proc = proc_init(loop, kProcTypePty, data);
rv.width = 80; rv.width = 80;
rv.height = 24; rv.height = 24;
rv.conpty = NULL; rv.conpty = NULL;
rv.finish_wait = NULL; rv.finish_wait = NULL;
rv.process_handle = NULL; rv.proc_handle = NULL;
return rv; return rv;
} }

View File

@ -1,20 +1,20 @@
#pragma once #pragma once
// IWYU pragma: private, include "nvim/os/pty_process.h" // IWYU pragma: private, include "nvim/os/pty_proc.h"
#include <uv.h> #include <uv.h>
#include "nvim/event/process.h" #include "nvim/event/proc.h"
#include "nvim/lib/queue_defs.h" #include "nvim/lib/queue_defs.h"
#include "nvim/os/pty_conpty_win.h" #include "nvim/os/pty_conpty_win.h"
typedef struct pty_process { typedef struct pty_process {
Process process; Proc proc;
uint16_t width, height; uint16_t width, height;
conpty_t *conpty; conpty_t *conpty;
HANDLE finish_wait; HANDLE finish_wait;
HANDLE process_handle; HANDLE proc_handle;
uv_timer_t wait_eof_timer; uv_timer_t wait_eof_timer;
} PtyProcess; } PtyProc;
// Structure used by build_cmd_line() // Structure used by build_cmd_line()
typedef struct arg_node { typedef struct arg_node {
@ -23,5 +23,5 @@ typedef struct arg_node {
} ArgNode; } ArgNode;
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/pty_process_win.h.generated.h" # include "os/pty_proc_win.h.generated.h"
#endif #endif

View File

@ -1,7 +0,0 @@
#pragma once
#ifdef MSWIN
# include "nvim/os/pty_process_win.h"
#else
# include "nvim/os/pty_process_unix.h"
#endif

View File

@ -14,10 +14,10 @@
#include "nvim/eval.h" #include "nvim/eval.h"
#include "nvim/eval/typval_defs.h" #include "nvim/eval/typval_defs.h"
#include "nvim/event/defs.h" #include "nvim/event/defs.h"
#include "nvim/event/libuv_process.h" #include "nvim/event/libuv_proc.h"
#include "nvim/event/loop.h" #include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h" #include "nvim/event/multiqueue.h"
#include "nvim/event/process.h" #include "nvim/event/proc.h"
#include "nvim/event/rstream.h" #include "nvim/event/rstream.h"
#include "nvim/event/stream.h" #include "nvim/event/stream.h"
#include "nvim/event/wstream.h" #include "nvim/event/wstream.h"
@ -872,12 +872,12 @@ static int do_os_system(char **argv, const char *input, size_t len, char **outpu
char prog[MAXPATHL]; char prog[MAXPATHL];
xstrlcpy(prog, argv[0], MAXPATHL); xstrlcpy(prog, argv[0], MAXPATHL);
LibuvProcess uvproc = libuv_process_init(&main_loop, &buf); LibuvProc uvproc = libuv_proc_init(&main_loop, &buf);
Process *proc = &uvproc.process; Proc *proc = &uvproc.proc;
MultiQueue *events = multiqueue_new_child(main_loop.events); MultiQueue *events = multiqueue_new_child(main_loop.events);
proc->events = events; proc->events = events;
proc->argv = argv; proc->argv = argv;
int status = process_spawn(proc, has_input, true, true); int status = proc_spawn(proc, has_input, true, true);
if (status) { if (status) {
loop_poll_events(&main_loop, 0); loop_poll_events(&main_loop, 0);
// Failed, probably 'shell' is not executable. // Failed, probably 'shell' is not executable.
@ -910,7 +910,7 @@ static int do_os_system(char **argv, const char *input, size_t len, char **outpu
if (!wstream_write(&proc->in, input_buffer)) { if (!wstream_write(&proc->in, input_buffer)) {
// couldn't write, stop the process and tell the user about it // couldn't write, stop the process and tell the user about it
process_stop(proc); proc_stop(proc);
return -1; return -1;
} }
// close the input stream after everything is written // close the input stream after everything is written
@ -927,7 +927,7 @@ static int do_os_system(char **argv, const char *input, size_t len, char **outpu
msg_no_more = true; msg_no_more = true;
lines_left = -1; lines_left = -1;
} }
int exitcode = process_wait(proc, -1, NULL); int exitcode = proc_wait(proc, -1, NULL);
if (!got_int && out_data_decide_throttle(0)) { if (!got_int && out_data_decide_throttle(0)) {
// Last chunk of output was skipped; display it now. // Last chunk of output was skipped; display it now.
out_data_ring(NULL, SIZE_MAX); out_data_ring(NULL, SIZE_MAX);
@ -1292,7 +1292,7 @@ static void shell_write_cb(Stream *stream, void *data, int status)
msg_schedule_semsg(_("E5677: Error writing input to shell-command: %s"), msg_schedule_semsg(_("E5677: Error writing input to shell-command: %s"),
uv_err_name(status)); uv_err_name(status));
} }
stream_close(stream, NULL, NULL, false); stream_may_close(stream, false);
} }
/// Applies 'shellxescape' (p_sxe) and 'shellxquote' (p_sxq) to a command. /// Applies 'shellxescape' (p_sxe) and 'shellxquote' (p_sxq) to a command.

View File

@ -950,8 +950,8 @@ void time_msg(const char *mesg, const proftime_T *start)
/// Initializes the `time_fd` stream for the --startuptime report. /// Initializes the `time_fd` stream for the --startuptime report.
/// ///
/// @param fname startuptime report file path /// @param fname startuptime report file path
/// @param process_name name of the current Nvim process to write in the report. /// @param proc_name name of the current Nvim process to write in the report.
void time_init(const char *fname, const char *process_name) void time_init(const char *fname, const char *proc_name)
{ {
const size_t bufsize = 8192; // Big enough for the entire --startuptime report. const size_t bufsize = 8192; // Big enough for the entire --startuptime report.
time_fd = fopen(fname, "a"); time_fd = fopen(fname, "a");
@ -972,7 +972,7 @@ void time_init(const char *fname, const char *process_name)
semsg("time_init: setvbuf failed: %d %s", r, uv_err_name(r)); semsg("time_init: setvbuf failed: %d %s", r, uv_err_name(r));
return; return;
} }
fprintf(time_fd, "--- Startup times for process: %s ---\n", process_name); fprintf(time_fd, "--- Startup times for process: %s ---\n", proc_name);
} }
/// Flushes the startuptimes to disk for the current process /// Flushes the startuptimes to disk for the current process

View File

@ -6875,7 +6875,8 @@ bool set_ref_in_quickfix(int copyID)
// In a location list window and none of the other windows is // In a location list window and none of the other windows is
// referring to this location list. Mark the location list // referring to this location list. Mark the location list
// context as still in use. // context as still in use.
if (mark_quickfix_ctx(win->w_llist_ref, copyID)) { if (mark_quickfix_ctx(win->w_llist_ref, copyID)
|| mark_quickfix_user_data(win->w_llist_ref, copyID)) {
return true; return true;
} }
} }

View File

@ -22,6 +22,7 @@
#include "nvim/memory_defs.h" #include "nvim/memory_defs.h"
#include "nvim/msgpack_rpc/channel.h" #include "nvim/msgpack_rpc/channel.h"
#include "nvim/msgpack_rpc/channel_defs.h" #include "nvim/msgpack_rpc/channel_defs.h"
#include "nvim/os/os.h"
#include "nvim/os/os_defs.h" #include "nvim/os/os_defs.h"
#include "nvim/tui/tui.h" #include "nvim/tui/tui.h"
#include "nvim/tui/tui_defs.h" #include "nvim/tui/tui_defs.h"
@ -126,6 +127,11 @@ void ui_client_run(bool remote_ui)
ui_client_attach(width, height, term, rgb); ui_client_attach(width, height, term, rgb);
// TODO(justinmk): this is for log_spec. Can remove this after nvim_log #7062 is merged.
if (os_env_exists("__NVIM_TEST_LOG")) {
ELOG("test log message");
}
// os_exit() will be invoked when the client channel detaches // os_exit() will be invoked when the client channel detaches
while (true) { while (true) {
LOOP_PROCESS_EVENTS(&main_loop, resize_events, -1); LOOP_PROCESS_EVENTS(&main_loop, resize_events, -1);

View File

@ -14,7 +14,7 @@ EXTERN size_t grid_line_buf_size INIT( = 0);
EXTERN schar_T *grid_line_buf_char INIT( = NULL); EXTERN schar_T *grid_line_buf_char INIT( = NULL);
EXTERN sattr_T *grid_line_buf_attr INIT( = NULL); EXTERN sattr_T *grid_line_buf_attr INIT( = NULL);
// ID of the ui client channel. If zero, the client is not running. // Client-side UI channel. Zero during early startup or if not a (--remote-ui) UI client.
EXTERN uint64_t ui_client_channel_id INIT( = 0); EXTERN uint64_t ui_client_channel_id INIT( = 0);
// exit status from embedded nvim process // exit status from embedded nvim process

17
src/versiondef.h.in Normal file
View File

@ -0,0 +1,17 @@
#ifndef AUTO_VERSIONDEF_H
#define AUTO_VERSIONDEF_H
#define NVIM_VERSION_MAJOR @NVIM_VERSION_MAJOR@
#define NVIM_VERSION_MINOR @NVIM_VERSION_MINOR@
#define NVIM_VERSION_PATCH @NVIM_VERSION_PATCH@
#define NVIM_VERSION_PRERELEASE "@NVIM_VERSION_PRERELEASE@"
#cmakedefine NVIM_VERSION_MEDIUM "@NVIM_VERSION_MEDIUM@"
#ifndef NVIM_VERSION_MEDIUM
# include "auto/versiondef_git.h"
#endif
#define NVIM_VERSION_CFLAGS "${VERSION_STRING}"
#define NVIM_VERSION_BUILD_TYPE "${CONFIG}"
#endif // AUTO_VERSIONDEF_H

View File

@ -103,7 +103,7 @@ Debugging tests
DBG 2022-06-15T18:37:45.227 T57.58016.0/c UI: stop DBG 2022-06-15T18:37:45.227 T57.58016.0/c UI: stop
INF 2022-06-15T18:37:45.227 T57.58016.0/c os_exit:595: Nvim exit: 0 INF 2022-06-15T18:37:45.227 T57.58016.0/c os_exit:595: Nvim exit: 0
DBG 2022-06-15T18:37:45.229 T57.58016.0 read_cb:118: closing Stream (0x7fd5d700ea18): EOF (end of file) DBG 2022-06-15T18:37:45.229 T57.58016.0 read_cb:118: closing Stream (0x7fd5d700ea18): EOF (end of file)
INF 2022-06-15T18:37:45.229 T57.58016.0 on_process_exit:400: exited: pid=58017 status=0 stoptime=0 INF 2022-06-15T18:37:45.229 T57.58016.0 on_proc_exit:400: exited: pid=58017 status=0 stoptime=0
``` ```
- You can set `$GDB` to [run functional tests under gdbserver](https://github.com/neovim/neovim/pull/1527): - You can set `$GDB` to [run functional tests under gdbserver](https://github.com/neovim/neovim/pull/1527):

View File

@ -114,6 +114,7 @@ function Session:request(method, ...)
return true, result return true, result
end end
--- Runs the event loop.
function Session:run(request_cb, notification_cb, setup_cb, timeout) function Session:run(request_cb, notification_cb, setup_cb, timeout)
local function on_request(method, args, response) local function on_request(method, args, response)
coroutine_exec(request_cb, method, args, function(status, result, flag) coroutine_exec(request_cb, method, args, function(status, result, flag)

View File

@ -1,6 +1,6 @@
local t = require('test.testutil') local t = require('test.testutil')
local n = require('test.functional.testnvim')() local n = require('test.functional.testnvim')()
local tt = require('test.functional.terminal.testutil') local tt = require('test.functional.testterm')
local clear = n.clear local clear = n.clear
local feed_command = n.feed_command local feed_command = n.feed_command

View File

@ -1,6 +1,6 @@
local t = require('test.testutil') local t = require('test.testutil')
local n = require('test.functional.testnvim')() local n = require('test.functional.testnvim')()
local tt = require('test.functional.terminal.testutil') local tt = require('test.functional.testterm')
local uv = vim.uv local uv = vim.uv
local clear, command, testprg = n.clear, n.command, n.testprg local clear, command, testprg = n.clear, n.command, n.testprg
@ -199,7 +199,7 @@ end)
describe('autocmd TextChangedT', function() describe('autocmd TextChangedT', function()
clear() clear()
local screen = tt.screen_setup() local screen = tt.setup_screen()
it('works', function() it('works', function()
command('autocmd TextChangedT * ++once let g:called = 1') command('autocmd TextChangedT * ++once let g:called = 1')

View File

@ -1,7 +1,7 @@
local t = require('test.testutil') local t = require('test.testutil')
local n = require('test.functional.testnvim')() local n = require('test.functional.testnvim')()
local Screen = require('test.functional.ui.screen') local Screen = require('test.functional.ui.screen')
local tt = require('test.functional.terminal.testutil') local tt = require('test.functional.testterm')
local clear = n.clear local clear = n.clear
local eq = t.eq local eq = t.eq

Some files were not shown because too many files have changed in this diff Show More