#[derive(Debug, Clone, Default)]
pub struct MatcherInfo {
pub bufnr: i32,
pub buffer_name: Option<Vec<u8>>,
pub buffer_options: std::collections::HashMap<String, String>,
}
pub fn buffer_name(matcher_info: &MatcherInfo) -> Option<Vec<u8>> {
matcher_info.buffer_name.clone()
}
pub fn vim_getbufoption(matcher_info: &MatcherInfo, option: &str) -> String {
matcher_info
.buffer_options
.get(option)
.cloned()
.unwrap_or_default()
}
#[derive(Debug, Clone)]
pub struct VimTabpage {
pub number: i32,
pub window: VimWindow,
}
#[derive(Debug, Clone)]
pub struct VimWindow {
pub number: i32,
pub window_id: i32,
pub buffer: VimBuffer,
}
#[derive(Debug, Clone)]
pub struct VimBuffer {
pub number: i32,
pub name: Option<Vec<u8>>,
pub modified: bool,
pub listed: bool,
}
pub fn list_tabpages() -> Vec<VimTabpage> {
Vec::new()
}
pub fn current_tabpage() -> VimTabpage {
VimTabpage {
number: 1,
window: VimWindow {
number: 1,
window_id: -1,
buffer: VimBuffer {
number: 1,
name: None,
modified: false,
listed: true,
},
},
}
}
pub fn bufvar_exists(_matcher_info: Option<&MatcherInfo>, _var: &str) -> bool {
false
}
pub fn vim_func_exists(_name: &str) -> bool {
false
}
pub fn vim_global_exists(_name: &str) -> bool {
false
}
pub fn vim_command_exists(_name: &str) -> bool {
false
}
pub fn vim_get_autoload_func(_f: &str, _rettype: Option<&str>) -> Option<()> {
None
}
pub fn create_ruby_dpowerline() {}
pub fn get_vim_encoding() -> &'static str {
"utf-8"
}
pub fn python_to_vim(value: &serde_json::Value) -> Vec<u8> {
match value {
serde_json::Value::String(s) => {
let mut out = Vec::new();
out.push(b'\'');
for c in s.chars() {
if c == '\'' {
out.extend_from_slice(b"''");
} else {
let mut buf = [0u8; 4];
out.extend_from_slice(c.encode_utf8(&mut buf).as_bytes());
}
}
out.push(b'\'');
out
}
serde_json::Value::Array(arr) => {
let mut out = Vec::new();
out.push(b'[');
for (i, item) in arr.iter().enumerate() {
if i > 0 {
out.push(b',');
}
out.extend_from_slice(&python_to_vim(item));
}
out.push(b']');
out
}
serde_json::Value::Number(n) => n.to_string().into_bytes(),
serde_json::Value::Bool(b) => {
if *b {
b"1".to_vec()
} else {
b"0".to_vec()
}
}
serde_json::Value::Null => b"v:null".to_vec(),
serde_json::Value::Object(_) => {
b"''".to_vec()
}
}
}
pub fn str_to_bytes(s: &str) -> Vec<u8> {
s.as_bytes().to_vec()
}
pub fn vim_environ_value_escape(value: &str) -> String {
value
.replace('"', "\\\"")
.replace('\\', "\\\\")
.replace('\n', "\\n")
.replace('\0', "")
}
pub fn vim_environ_set_command(key: &str, value: &str) -> String {
format!("let ${}=\"{}\"", key, vim_environ_value_escape(value))
}
pub fn vim_environ_get_expr(key: &str) -> String {
format!("${}", key)
}
pub fn powerline_vim_strtrans_error(bytes: &[u8]) -> (String, usize) {
let mut out = String::with_capacity(bytes.len() * 5);
for b in bytes {
out.push_str(&format!("<<{:02X}>>", b));
}
(out, bytes.len())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn buffer_name_returns_set_value() {
let info = MatcherInfo {
bufnr: 1,
buffer_name: Some(b"/tmp/test.txt".to_vec()),
..Default::default()
};
assert_eq!(buffer_name(&info), Some(b"/tmp/test.txt".to_vec()));
}
#[test]
fn vim_getbufoption_returns_value_if_set() {
let mut opts = std::collections::HashMap::new();
opts.insert("filetype".into(), "rust".into());
let info = MatcherInfo {
buffer_options: opts,
..Default::default()
};
assert_eq!(vim_getbufoption(&info, "filetype"), "rust");
assert_eq!(vim_getbufoption(&info, "missing"), "");
}
#[test]
fn list_tabpages_empty_when_no_vim() {
assert!(list_tabpages().is_empty());
}
#[test]
fn get_vim_encoding_returns_utf8_fallback() {
assert_eq!(get_vim_encoding(), "utf-8");
}
#[test]
fn python_to_vim_unicode_quotes_and_escapes() {
let r = python_to_vim(&serde_json::json!("it's"));
assert_eq!(r, b"'it''s'".to_vec());
}
#[test]
fn python_to_vim_plain_string() {
let r = python_to_vim(&serde_json::json!("hello"));
assert_eq!(r, b"'hello'".to_vec());
}
#[test]
fn python_to_vim_int_emits_ascii_digits() {
let r = python_to_vim(&serde_json::json!(42));
assert_eq!(r, b"42".to_vec());
}
#[test]
fn python_to_vim_float_emits_ascii_digits() {
let r = python_to_vim(&serde_json::json!(3.5));
assert_eq!(r, b"3.5".to_vec());
}
#[test]
fn python_to_vim_list_emits_bracketed_csv() {
let r = python_to_vim(&serde_json::json!(["a", 1, "b"]));
assert_eq!(r, b"['a',1,'b']".to_vec());
}
#[test]
fn python_to_vim_empty_list() {
let r = python_to_vim(&serde_json::json!([]));
assert_eq!(r, b"[]".to_vec());
}
#[test]
fn python_to_vim_bool_emits_0_or_1() {
let r = python_to_vim(&serde_json::json!(true));
assert_eq!(r, b"1".to_vec());
let r = python_to_vim(&serde_json::json!(false));
assert_eq!(r, b"0".to_vec());
}
#[test]
fn str_to_bytes_returns_utf8_bytes() {
assert_eq!(str_to_bytes("hello"), b"hello".to_vec());
assert_eq!(str_to_bytes("héllo"), "héllo".as_bytes().to_vec());
}
#[test]
fn vim_environ_value_escape_quotes_double_quote() {
assert_eq!(vim_environ_value_escape("a\"b"), "a\\\\\"b");
}
#[test]
fn vim_environ_value_escape_escapes_backslash() {
assert_eq!(vim_environ_value_escape("a\\b"), "a\\\\b");
}
#[test]
fn vim_environ_value_escape_newline_becomes_backslash_n() {
assert_eq!(vim_environ_value_escape("a\nb"), "a\\nb");
}
#[test]
fn vim_environ_value_escape_strips_null_byte() {
assert_eq!(vim_environ_value_escape("a\0b"), "ab");
}
#[test]
fn vim_environ_set_command_builds_let_form() {
let cmd = vim_environ_set_command("FOO", "bar");
assert_eq!(cmd, "let $FOO=\"bar\"");
}
#[test]
fn vim_environ_set_command_escapes_value() {
let cmd = vim_environ_set_command("X", "a\"b");
assert_eq!(cmd, "let $X=\"a\\\\\"b\"");
}
#[test]
fn vim_environ_get_expr_builds_dollar_key() {
assert_eq!(vim_environ_get_expr("PATH"), "$PATH");
}
#[test]
fn powerline_vim_strtrans_error_emits_hex_per_byte() {
let (s, end) = powerline_vim_strtrans_error(&[0xff, 0xfe]);
assert_eq!(s, "<<FF>><<FE>>");
assert_eq!(end, 2);
}
#[test]
fn powerline_vim_strtrans_error_empty_input() {
let (s, end) = powerline_vim_strtrans_error(&[]);
assert_eq!(s, "");
assert_eq!(end, 0);
}
}