Skip to content

Commit

Permalink
gh-9 sys, api: Add ability to set autocmds
Browse files Browse the repository at this point in the history
  • Loading branch information
turboladen committed Jan 27, 2022
1 parent d74e1ae commit a5ea504
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 5 deletions.
26 changes: 25 additions & 1 deletion neovim_sys/src/autocmd.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Functions and supporting types from `nvim/autocmd.{c,h}`.
//!
use crate::types::CharU;
use std::os::raw::c_int;
use std::os::raw::{c_char, c_int};

extern "C" {
/// Does an `augroup` with name `name` exist?
Expand All @@ -11,4 +11,28 @@ extern "C" {
/// Defines an `augroup`; `:augroup {name}` or `:augroup! {name}`.
///
pub fn do_augroup(name: *const CharU, del_group: c_int);

/// Defines an `autocmd`.
///
/// - `:h autocmd-define`:
/// - `:autocmd [group] <event> <pattern> [++once] [++nested] <cmd>`
/// - `:h autocmd-remove`:
/// - `:autocmd! [group] <event> <pattern>`
/// - `:autocmd! [group] * <pattern>`
/// - `:autocmd! [group] <event>`
/// - `:autocmd! [group]`
/// - `:h autocmd-list`:
/// - `:autocmd [group] <event> <pattern>`
/// - `:autocmd [group] * <pattern>`
/// - `:autocmd [group] <event>`
/// - `:autocmd [group]`
pub fn do_autocmd(arg_in: *const CharU, force_it: c_int);

/// #Group#Event#pat
/// #Group#Event
/// #Group
/// #Event#pat
/// #Event
///
pub fn au_exists(arg: *const c_char) -> bool;
}
30 changes: 29 additions & 1 deletion nvim_api/src/autocmd.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::ffi::{CString, NulError};

use neovim_sys::api::nvim::NvimString;

pub fn augroup(name: &str) -> Result<(), NulError> {
let cstring = CString::new(name)?;
let api_name = cstring.into_bytes_with_nul();
Expand All @@ -18,11 +20,37 @@ pub fn remove_augroup(name: &str) -> Result<(), NulError> {
Ok(())
}

pub fn augroup_defined(name: &str) -> Result<bool, NulError> {
pub fn augroup_exists(name: &str) -> Result<bool, NulError> {
let cstring = CString::new(name)?;
let api_name = cstring.into_bytes_with_nul();

let result = unsafe { neovim_sys::autocmd::au_has_group(api_name.as_ptr()) };

Ok(result)
}

pub fn autocmd(name: &str) -> Result<(), NulError> {
let cstring = CString::new(name)?;
let api_name = cstring.into_bytes_with_nul();

unsafe { neovim_sys::autocmd::do_autocmd(api_name.as_ptr(), 0) };

Ok(())
}

pub fn force_autocmd(name: &str) -> Result<(), NulError> {
let cstring = CString::new(name)?;
let api_name = cstring.into_bytes_with_nul();

unsafe { neovim_sys::autocmd::do_autocmd(api_name.as_ptr(), 1) };

Ok(())
}

pub fn autocmd_exists(name: &str) -> Result<bool, NulError> {
let cstring = NvimString::new(name)?;

let result = unsafe { neovim_sys::autocmd::au_exists(cstring.as_ptr()) };

Ok(result)
}
107 changes: 104 additions & 3 deletions nvim_api/src/lua_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,110 @@ fn test_set_buf_noremap() {
fn test_augroup() {
crate::autocmd::augroup("Overkill").unwrap();
crate::autocmd::augroup("END").unwrap();
assert!(crate::autocmd::augroup_defined("Overkill").unwrap());
assert!(!crate::autocmd::augroup_defined("blarghOverkill").unwrap());
assert!(crate::autocmd::augroup_exists("Overkill").unwrap());
assert!(!crate::autocmd::augroup_exists("blarghOverkill").unwrap());

crate::autocmd::remove_augroup("Overkill").unwrap();
assert!(!crate::autocmd::augroup_defined("Overkill").unwrap());
assert!(!crate::autocmd::augroup_exists("Overkill").unwrap());
}

#[nvim_test]
fn test_autocmd() {
// Undefined event or group shouldn't exist
{
assert!(!crate::autocmd::autocmd_exists("NotAnEventOrGroup").unwrap());
}

// Ungrouped, built-in events...
{
crate::autocmd::autocmd("FileChangedShell *.meow,*.bobo echo hi").unwrap();
assert!(crate::autocmd::autocmd_exists("FileChangedShell").unwrap());
assert!(crate::autocmd::autocmd_exists("FileChangedShell *.meow").unwrap());
assert!(crate::autocmd::autocmd_exists("FileChangedShell *.bobo").unwrap());
assert!(crate::autocmd::autocmd_exists("FileChangedShell *.meow,*.bobo").unwrap());
}

// Ungrouped, user-defined events...
{
crate::autocmd::autocmd("User OverkillThing echo hi").unwrap();

// Any ungrouped User event will return true
assert!(crate::autocmd::autocmd_exists("User OverkillThing").unwrap());

// ...but one with a group will fail
assert!(!crate::autocmd::autocmd_exists("SomeGroup User NotOverkillThing").unwrap());
}

// Grouped, built-in events
{
crate::autocmd::augroup("OverkillBuiltIn").unwrap();
crate::autocmd::autocmd("FileChangedShell *.meow,*.bobo echo hi").unwrap();
crate::autocmd::augroup("END").unwrap();

assert!(crate::autocmd::autocmd_exists("OverkillBuiltIn#FileChangedShell#*.meow").unwrap());
assert!(crate::autocmd::autocmd_exists("OverkillBuiltIn#FileChangedShell").unwrap());
assert!(crate::autocmd::autocmd_exists("OverkillBuiltIn").unwrap());
assert!(crate::autocmd::autocmd_exists("FileChangedShell#*.bobo").unwrap());
assert!(crate::autocmd::autocmd_exists("FileChangedShell").unwrap());

assert!(!crate::autocmd::autocmd_exists("OverkillBuiltIn#FileChangedShell#*.txt").unwrap());
assert!(!crate::autocmd::autocmd_exists("FileChangedShell#*.txt").unwrap());
}

// Grouped, user-defined events
{
crate::autocmd::augroup("OverkillUserDef").unwrap();
crate::autocmd::autocmd("User OverkillThing echo hi").unwrap();
crate::autocmd::augroup("END").unwrap();

assert!(crate::autocmd::autocmd_exists("OverkillUserDef#User OverkillThing").unwrap());
assert!(crate::autocmd::autocmd_exists("OverkillUserDef").unwrap());
assert!(crate::autocmd::autocmd_exists("User OverkillThing").unwrap());
}
}

#[nvim_test]
fn test_force_autocmd() {
// Ungrouped, built-in events...
{
crate::autocmd::autocmd("UILeave *.meow echo hi").unwrap();
crate::autocmd::force_autocmd("UILeave *.meow echo bye").unwrap();

assert!(crate::autocmd::autocmd_exists("UILeave").unwrap());
assert!(crate::autocmd::autocmd_exists("UILeave *.meow").unwrap());
}

// Ungrouped, user-defined events...
{
crate::autocmd::autocmd("User OverkillThing echo hi").unwrap();
crate::autocmd::force_autocmd("User OverkillThing echo bye").unwrap();

assert!(crate::autocmd::autocmd_exists("User OverkillThing").unwrap());
}

// Grouped, built-in events
{
crate::autocmd::augroup("OverkillBuiltIn").unwrap();
crate::autocmd::autocmd("UILeave *.meow echo hi").unwrap();
crate::autocmd::augroup("END").unwrap();

crate::autocmd::augroup("OverkillBuiltIn").unwrap();
crate::autocmd::autocmd("UILeave *.meow echo bye").unwrap();
crate::autocmd::augroup("END").unwrap();

assert!(crate::autocmd::autocmd_exists("OverkillBuiltIn#UILeave#*.meow").unwrap());
}

// Grouped, user-defined events
{
crate::autocmd::augroup("OverkillUserDef").unwrap();
crate::autocmd::autocmd("User OverkillThing echo hi").unwrap();
crate::autocmd::augroup("END").unwrap();

crate::autocmd::augroup("OverkillUserDef").unwrap();
crate::autocmd::force_autocmd("User OverkillThing echo bye").unwrap();
crate::autocmd::augroup("END").unwrap();

assert!(crate::autocmd::autocmd_exists("OverkillUserDef#User OverkillThing").unwrap());
}
}
14 changes: 14 additions & 0 deletions tests/plenary/nvim_api_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ ffi.cdef [[
bool test_set_buf_noremap();

bool test_augroup();
bool test_autocmd();
bool test_force_autocmd();
]]

local suffix = ffi.os == "OSX" and ".dylib" or ".so"
Expand Down Expand Up @@ -98,5 +100,17 @@ describe(
assert.True(lib.test_augroup())
end
)
it(
"tests autocmd::autocmd()",
function()
assert.True(lib.test_autocmd())
end
)
it(
"tests autocmd::force_autocmd()",
function()
assert.True(lib.test_force_autocmd())
end
)
end
)

0 comments on commit a5ea504

Please sign in to comment.