1use std::path::{Path, PathBuf};
2
3use nvim_types::{
4 self as nvim,
5 conversion::{FromObject, ToObject},
6 Array,
7 Dictionary,
8 Integer,
9 Object,
10};
11
12use crate::choose;
13use crate::ffi::global::*;
14use crate::iterator::SuperIterator;
15use crate::opts::*;
16use crate::types::*;
17use crate::StringOrFunction;
18use crate::LUA_INTERNAL_CALL;
19use crate::{Buffer, TabPage, Window};
20use crate::{Error, Result};
21
22pub fn chan_send(channel_id: u32, data: &str) -> Result<()> {
26 let mut err = nvim::Error::new();
27 let data = nvim::String::from(data);
28 unsafe { nvim_chan_send(channel_id.into(), data.non_owning(), &mut err) };
29 choose!(err, ())
30}
31
32pub fn create_buf(is_listed: bool, is_scratch: bool) -> Result<Buffer> {
36 let mut err = nvim::Error::new();
37 let handle = unsafe { nvim_create_buf(is_listed, is_scratch, &mut err) };
38 choose!(err, Ok(handle.into()))
39}
40
41pub fn create_user_command<Cmd>(
45 name: &str,
46 command: Cmd,
47 opts: &CreateCommandOpts,
48) -> Result<()>
49where
50 Cmd: StringOrFunction<CommandArgs, ()>,
51{
52 let name = nvim::String::from(name);
53 let command = command.to_object();
54 let opts = KeyDict_user_command::from(opts);
55 let mut err = nvim::Error::new();
56 unsafe {
57 nvim_create_user_command(
58 name.non_owning(),
59 command.non_owning(),
60 &opts,
61 &mut err,
62 )
63 };
64 choose!(err, ())
65}
66
67pub fn del_current_line() -> Result<()> {
71 let mut err = nvim::Error::new();
72 unsafe { nvim_del_current_line(&mut err) };
73 choose!(err, ())
74}
75
76pub fn del_keymap(mode: Mode, lhs: &str) -> Result<()> {
81 let mode = nvim::String::from(mode);
82 let lhs = nvim::String::from(lhs);
83 let mut err = nvim::Error::new();
84 unsafe {
85 nvim_del_keymap(
86 LUA_INTERNAL_CALL,
87 mode.non_owning(),
88 lhs.non_owning(),
89 &mut err,
90 )
91 };
92 choose!(err, ())
93}
94
95pub fn del_mark(name: char) -> Result<()> {
101 let name = nvim::String::from(name);
102 let mut err = nvim::Error::new();
103 let was_deleted = unsafe { nvim_del_mark(name.non_owning(), &mut err) };
104 choose!(
105 err,
106 match was_deleted {
107 true => Ok(()),
108 _ => Err(Error::custom("Couldn't delete mark")),
109 }
110 )
111}
112
113pub fn del_user_command(name: &str) -> Result<()> {
118 let name = nvim::String::from(name);
119 let mut err = nvim::Error::new();
120 unsafe { nvim_del_user_command(name.non_owning(), &mut err) };
121 choose!(err, ())
122}
123
124pub fn del_var(name: &str) -> Result<()> {
128 let name = nvim::String::from(name);
129 let mut err = nvim::Error::new();
130 unsafe { nvim_del_var(name.non_owning(), &mut err) };
131 choose!(err, ())
132}
133
134pub fn echo<'hl, Text, Chunks>(chunks: Chunks, history: bool) -> Result<()>
138where
139 Chunks: IntoIterator<Item = (Text, Option<&'hl str>)>,
140 Text: Into<nvim::String>,
141{
142 let chunks = chunks
143 .into_iter()
144 .map(|(text, hlgroup)| {
145 Array::from_iter([
146 Object::from(text.into()),
147 Object::from(hlgroup.map(|hl| hl.to_owned())),
148 ])
149 })
150 .collect::<Array>();
151
152 let mut err = nvim::Error::new();
153 let opts = Dictionary::new();
154 unsafe {
155 nvim_echo(chunks.non_owning(), history, opts.non_owning(), &mut err)
156 };
157 choose!(err, ())
158}
159
160pub fn err_write(str: &str) {
166 unsafe { nvim_err_write(nvim::String::from(str).non_owning()) }
167}
168
169pub fn err_writeln(str: &str) {
174 unsafe { nvim_err_writeln(nvim::String::from(str).non_owning()) }
175}
176
177pub fn eval_statusline(
181 str: &str,
182 opts: &EvalStatuslineOpts,
183) -> Result<StatuslineInfos> {
184 let str = nvim::String::from(str);
185 let opts = KeyDict_eval_statusline::from(opts);
186 let mut err = nvim::Error::new();
187 let dict =
188 unsafe { nvim_eval_statusline(str.non_owning(), &opts, &mut err) };
189 choose!(err, Ok(StatuslineInfos::from_object(dict.into())?))
190}
191
192pub fn feedkeys(keys: &str, mode: Mode, escape_ks: bool) {
194 let keys = nvim::String::from(keys);
195 let mode = nvim::String::from(mode);
196 unsafe { nvim_feedkeys(keys.non_owning(), mode.non_owning(), escape_ks) }
197}
198
199pub fn get_all_options_info() -> Result<impl SuperIterator<OptionInfos>> {
203 let mut err = nvim::Error::new();
204 let infos = unsafe { nvim_get_all_options_info(&mut err) };
205 choose!(
206 err,
207 Ok({
208 infos
209 .into_iter()
210 .map(|(_, optinf)| OptionInfos::from_object(optinf).unwrap())
211 })
212 )
213}
214
215pub fn get_chan_info(channel_id: u32) -> Result<ChannelInfos> {
219 let mut err = nvim::Error::new();
220 let infos = unsafe { nvim_get_chan_info(channel_id.into(), &mut err) };
221 choose!(err, Ok(ChannelInfos::from_object(infos.into())?))
222}
223
224pub fn get_color_by_name(name: &str) -> Result<u32> {
229 let name = nvim::String::from(name);
230 let color = unsafe { nvim_get_color_by_name(name.non_owning()) };
231 (color != -1).then(|| color.try_into().unwrap()).ok_or_else(|| {
232 Error::custom(format!("{name} is not a valid color name"))
233 })
234}
235
236pub fn get_color_map() -> impl SuperIterator<(String, u32)> {
241 unsafe { nvim_get_color_map() }.into_iter().map(|(k, v)| {
242 (String::try_from(k).unwrap(), u32::from_object(v).unwrap())
243 })
244}
245
246pub fn get_commands(
251 opts: &GetCommandsOpts,
252) -> Result<impl SuperIterator<CommandInfos>> {
253 let opts = KeyDict_get_commands::from(opts);
254 let mut err = nvim::Error::new();
255 let cmds = unsafe { nvim_get_commands(&opts, &mut err) };
256 choose!(
257 err,
258 Ok({
259 cmds.into_iter()
260 .map(|(_, cmd)| CommandInfos::from_object(cmd).unwrap())
261 })
262 )
263}
264
265pub fn get_context(opts: &GetContextOpts) -> Result<EditorContext> {
269 let opts = KeyDict_context::from(opts);
270 let mut err = nvim::Error::new();
271 let ctx = unsafe { nvim_get_context(&opts, &mut err) };
272 choose!(err, Ok(EditorContext::from_object(ctx.into())?))
273}
274
275pub fn get_current_buf() -> Buffer {
279 unsafe { nvim_get_current_buf() }.into()
280}
281
282pub fn get_current_line() -> Result<String> {
286 let mut err = nvim::Error::new();
287 let str = unsafe { nvim_get_current_line(&mut err) };
288 choose!(err, str.try_into().map_err(From::from))
289}
290
291pub fn get_current_tabpage() -> TabPage {
295 unsafe { nvim_get_current_tabpage() }.into()
296}
297
298pub fn get_current_win() -> Window {
302 unsafe { nvim_get_current_win() }.into()
303}
304
305pub fn get_hl_by_id(hl_id: u32, rgb: bool) -> Result<HighlightInfos> {
309 let mut err = nvim::Error::new();
310 let hl = unsafe { nvim_get_hl_by_id(hl_id.into(), rgb, &mut err) };
311 choose!(err, Ok(HighlightInfos::from_object(hl.into())?))
312}
313
314pub fn get_hl_by_name(name: &str, rgb: bool) -> Result<HighlightInfos> {
318 let name = nvim::String::from(name);
319 let mut err = nvim::Error::new();
320 let hl = unsafe { nvim_get_hl_by_name(name.non_owning(), rgb, &mut err) };
321 choose!(err, Ok(HighlightInfos::from_object(hl.into())?))
322}
323
324pub fn get_hl_id_by_name(name: &str) -> Result<u32> {
328 let name = nvim::String::from(name);
329 let id = unsafe { nvim_get_hl_id_by_name(name.non_owning()) };
330 id.try_into().map_err(Into::into)
331}
332
333pub fn get_keymap(mode: Mode) -> impl SuperIterator<KeymapInfos> {
337 let mode = nvim::String::from(mode);
338 unsafe { nvim_get_keymap(LUA_INTERNAL_CALL, mode.non_owning()) }
339 .into_iter()
340 .map(|obj| KeymapInfos::from_object(obj).unwrap())
341}
342
343pub fn get_mark(
348 name: char,
349 opts: &GetMarkOpts,
350) -> Result<(usize, usize, Buffer, String)> {
351 let name = nvim::String::from(name);
352 let opts = Dictionary::from(opts);
353 let mut err = nvim::Error::new();
354 let mark = unsafe {
355 nvim_get_mark(name.non_owning(), opts.non_owning(), &mut err)
356 };
357 choose!(err, {
358 let mut iter = mark.into_iter();
359 let row = usize::from_object(iter.next().expect("row is present"))?;
360 let col = usize::from_object(iter.next().expect("col is present"))?;
361 let buffer =
362 Buffer::from_object(iter.next().expect("buffer is present"))?;
363 let buffername =
364 String::from_object(iter.next().expect("buffername is present"))?;
365 Ok((row, col, buffer, buffername))
366 })
367}
368
369pub fn get_mode() -> Result<GotMode> {
374 Ok(GotMode::from_object(unsafe { nvim_get_mode() }.into())?)
375}
376
377pub fn get_option<Opt>(name: &str) -> Result<Opt>
381where
382 Opt: FromObject,
383{
384 let name = nvim::String::from(name);
385 let mut err = nvim::Error::new();
386 let obj = unsafe { nvim_get_option(name.non_owning(), &mut err) };
387 choose!(err, Ok(Opt::from_object(obj)?))
388}
389
390pub fn get_option_info(name: &str) -> Result<OptionInfos> {
394 let name = nvim::String::from(name);
395 let mut err = nvim::Error::new();
396 let obj = unsafe { nvim_get_option_info(name.non_owning(), &mut err) };
397 choose!(err, Ok(OptionInfos::from_object(obj.into())?))
398}
399
400pub fn get_option_value<Opt>(name: &str, opts: &OptionValueOpts) -> Result<Opt>
408where
409 Opt: FromObject,
410{
411 let name = nvim::String::from(name);
412 let opts = KeyDict_option::from(opts);
413 let mut err = nvim::Error::new();
414 let obj =
415 unsafe { nvim_get_option_value(name.non_owning(), &opts, &mut err) };
416 choose!(err, Ok(Opt::from_object(obj)?))
417}
418
419pub fn get_proc(pid: u32) -> Result<ProcInfos> {
423 let mut err = nvim::Error::new();
424 let obj = unsafe { nvim_get_proc(pid.into(), &mut err) };
425 choose!(err, Ok(ProcInfos::from_object(obj)?))
426}
427
428pub fn get_proc_children(pid: u32) -> Result<impl SuperIterator<u32>> {
432 let mut err = nvim::Error::new();
433 let procs = unsafe { nvim_get_proc_children(pid.into(), &mut err) };
434 choose!(
435 err,
436 Ok(procs.into_iter().map(|obj| u32::from_object(obj).unwrap()))
437 )
438}
439
440pub fn get_runtime_file(
444 name: impl AsRef<Path>,
445 get_all: bool,
446) -> Result<impl SuperIterator<PathBuf>> {
447 let name = nvim::String::from(name.as_ref().to_owned());
448 let mut err = nvim::Error::new();
449 let files =
450 unsafe { nvim_get_runtime_file(name.non_owning(), get_all, &mut err) };
451 choose!(
452 err,
453 Ok({
454 files.into_iter().map(|obj| {
455 PathBuf::from(nvim::String::from_object(obj).unwrap())
456 })
457 })
458 )
459}
460
461pub fn get_var<Var>(name: &str) -> Result<Var>
465where
466 Var: FromObject,
467{
468 let mut err = nvim::Error::new();
469 let name = nvim::String::from(name);
470 let obj = unsafe { nvim_get_var(name.non_owning(), &mut err) };
471 choose!(err, Ok(Var::from_object(obj)?))
472}
473
474pub fn get_vvar<Var>(name: &str) -> Result<Var>
478where
479 Var: FromObject,
480{
481 let name = nvim::String::from(name);
482 let mut err = nvim::Error::new();
483 let obj = unsafe { nvim_get_vvar(name.non_owning(), &mut err) };
484 choose!(err, Ok(Var::from_object(obj)?))
485}
486
487pub fn input<Input>(keys: Input) -> Result<usize>
494where
495 Input: Into<nvim::String>,
496{
497 unsafe { nvim_input(keys.into().non_owning()) }
498 .try_into()
499 .map_err(From::from)
500}
501
502pub fn input_mouse(
506 button: MouseButton,
507 action: MouseAction,
508 modifier: &str,
509 grid: u32,
510 row: usize,
511 col: usize,
512) -> Result<()> {
513 let button = nvim::String::from(button);
514 let action = nvim::String::from(action);
515 let modifier = nvim::String::from(modifier);
516 let mut err = nvim::Error::new();
517 unsafe {
518 nvim_input_mouse(
519 button.non_owning(),
520 action.non_owning(),
521 modifier.non_owning(),
522 grid.into(),
523 row.try_into()?,
524 col.try_into()?,
525 &mut err,
526 )
527 };
528 choose!(err, ())
529}
530
531pub fn list_bufs() -> impl SuperIterator<Buffer> {
537 unsafe { nvim_list_bufs() }
538 .into_iter()
539 .map(|obj| Buffer::from_object(obj).unwrap())
540}
541
542pub fn list_chans() -> impl SuperIterator<ChannelInfos> {
546 unsafe { nvim_list_chans() }
547 .into_iter()
548 .map(|obj| ChannelInfos::from_object(obj).unwrap())
549}
550
551pub fn list_runtime_paths() -> Result<impl SuperIterator<PathBuf>> {
555 let mut err = nvim::Error::new();
556 let paths = unsafe { nvim_list_runtime_paths(&mut err) };
557 choose!(
558 err,
559 Ok({
560 paths.into_iter().map(|obj| {
561 PathBuf::from(nvim::String::from_object(obj).unwrap())
562 })
563 })
564 )
565}
566
567pub fn list_tabpages() -> impl SuperIterator<TabPage> {
571 unsafe { nvim_list_tabpages() }
572 .into_iter()
573 .map(|obj| TabPage::from_object(obj).unwrap())
574}
575
576pub fn list_uis() -> impl SuperIterator<UiInfos> {
580 unsafe { nvim_list_uis() }
581 .into_iter()
582 .map(|obj| UiInfos::from_object(obj).unwrap())
583}
584
585pub fn list_wins() -> impl SuperIterator<Window> {
589 unsafe { nvim_list_wins() }
590 .into_iter()
591 .map(|obj| Window::from_object(obj).unwrap())
592}
593
594pub fn load_context(ctx: EditorContext) {
598 let ctx = Dictionary::from(ctx);
599 let _ = unsafe { nvim_load_context(ctx.non_owning()) };
600}
601
602pub fn notify(
604 msg: &str,
605 log_level: LogLevel,
606 opts: &NotifyOpts,
607) -> Result<()> {
608 let msg = nvim::String::from(msg);
609 let opts = Dictionary::from(opts);
610 let mut err = nvim::Error::new();
611 let _ = unsafe {
612 nvim_notify(
613 msg.non_owning(),
614 log_level as Integer,
615 opts.non_owning(),
616 &mut err,
617 )
618 };
619 choose!(err, ())
620}
621
622pub fn open_term(buffer: &Buffer, opts: &OpenTermOpts) -> Result<u32> {
628 let opts = Dictionary::from(opts);
629 let mut err = nvim::Error::new();
630 let channel_id =
631 unsafe { nvim_open_term(buffer.0, opts.non_owning(), &mut err) };
632 choose!(
633 err,
634 match channel_id {
635 0 => Err(Error::custom("Couldn't create terminal instance")),
636 other => Ok(other.try_into().expect("always positive")),
637 }
638 )
639}
640
641pub fn out_write<Msg>(str: Msg)
646where
647 Msg: Into<nvim::String>,
648{
649 unsafe { nvim_out_write(str.into().non_owning()) }
650}
651
652pub fn paste<Data>(data: Data, crlf: bool, phase: PastePhase) -> Result<bool>
657where
658 Data: Into<nvim::String>,
659{
660 let mut err = nvim::Error::new();
661 let go_on = unsafe {
662 nvim_paste(data.into().non_owning(), crlf, phase as Integer, &mut err)
663 };
664 choose!(err, Ok(go_on))
665}
666
667pub fn put<Line, Lines>(
671 lines: Lines,
672 reg_type: RegisterType,
673 after: bool,
674 follow: bool,
675) -> Result<()>
676where
677 Lines: Iterator<Item = Line>,
678 Line: Into<nvim::String>,
679{
680 let lines = lines.into_iter().map(Into::into).collect::<Array>();
681 let reg_type = nvim::String::from(reg_type);
682 let mut err = nvim::Error::new();
683 unsafe {
684 nvim_put(
685 lines.non_owning(),
686 reg_type.non_owning(),
687 after,
688 follow,
689 &mut err,
690 )
691 };
692 choose!(err, ())
693}
694
695pub fn replace_termcodes<Input>(
700 str: Input,
701 from_part: bool,
702 do_lt: bool,
703 special: bool,
704) -> nvim::String
705where
706 Input: Into<nvim::String>,
707{
708 let str = str.into();
709 unsafe {
710 nvim_replace_termcodes(str.non_owning(), from_part, do_lt, special)
711 }
712}
713
714pub fn select_popupmenu_item(
718 item: usize,
719 insert: bool,
720 finish: bool,
721 opts: &SelectPopupMenuItemOpts,
722) -> Result<()> {
723 let opts = Dictionary::from(opts);
724 let mut err = nvim::Error::new();
725 unsafe {
726 nvim_select_popupmenu_item(
727 item.try_into()?,
728 insert,
729 finish,
730 opts.non_owning(),
731 &mut err,
732 )
733 };
734 choose!(err, ())
735}
736
737pub fn set_current_buf(buf: &Buffer) -> Result<()> {
741 let mut err = nvim::Error::new();
742 unsafe { nvim_set_current_buf(buf.0, &mut err) };
743 choose!(err, ())
744}
745
746pub fn set_current_dir<Dir>(dir: Dir) -> Result<()>
750where
751 Dir: AsRef<Path>,
752{
753 let dir = nvim::String::from(dir.as_ref().to_owned());
754 let mut err = nvim::Error::new();
755 unsafe { nvim_set_current_dir(dir.non_owning(), &mut err) };
756 choose!(err, ())
757}
758
759pub fn set_current_line<Line>(line: Line) -> Result<()>
763where
764 Line: Into<nvim::String>,
765{
766 let mut err = nvim::Error::new();
767 unsafe { nvim_set_current_line(line.into().non_owning(), &mut err) };
768 choose!(err, ())
769}
770
771pub fn set_current_tabpage(tabpage: &TabPage) -> Result<()> {
775 let mut err = nvim::Error::new();
776 unsafe { nvim_set_current_tabpage(tabpage.0, &mut err) };
777 choose!(err, ())
778}
779
780pub fn set_current_win(win: &Window) -> Result<()> {
784 let mut err = nvim::Error::new();
785 unsafe { nvim_set_current_win(win.0, &mut err) };
786 choose!(err, ())
787}
788
789pub fn set_hl(ns_id: u32, name: &str, opts: &SetHighlightOpts) -> Result<()> {
793 let name = nvim::String::from(name);
794 let opts = KeyDict_highlight::from(opts);
795 let mut err = nvim::Error::new();
796 unsafe {
797 nvim_set_hl(ns_id as Integer, name.non_owning(), &opts, &mut err)
798 };
799 choose!(err, ())
800}
801
802pub fn set_keymap(
807 mode: Mode,
808 lhs: &str,
809 rhs: &str,
810 opts: &SetKeymapOpts,
811) -> Result<()> {
812 let mode = nvim::String::from(mode);
813 let lhs = nvim::String::from(lhs);
814 let rhs = nvim::String::from(rhs);
815 let opts = KeyDict_keymap::from(opts);
816 let mut err = nvim::Error::new();
817 unsafe {
818 nvim_set_keymap(
819 LUA_INTERNAL_CALL,
820 mode.non_owning(),
821 lhs.non_owning(),
822 rhs.non_owning(),
823 &opts,
824 &mut err,
825 )
826 };
827 choose!(err, ())
828}
829
830pub fn set_option<Opt>(name: &str, value: Opt) -> Result<()>
834where
835 Opt: ToObject,
836{
837 let name = nvim::String::from(name);
838 let mut err = nvim::Error::new();
839 unsafe {
840 nvim_set_option(
841 LUA_INTERNAL_CALL,
842 name.non_owning(),
843 value.to_object()?.non_owning(),
844 &mut err,
845 )
846 };
847 choose!(err, ())
848}
849
850pub fn set_option_value<Opt>(
857 name: &str,
858 value: Opt,
859 opts: &OptionValueOpts,
860) -> Result<()>
861where
862 Opt: ToObject,
863{
864 let name = nvim::String::from(name);
865 let opts = KeyDict_option::from(opts);
866 let mut err = nvim::Error::new();
867 unsafe {
868 nvim_set_option_value(
869 name.non_owning(),
870 value.to_object()?.non_owning(),
871 &opts,
872 &mut err,
873 )
874 };
875 choose!(err, ())
876}
877
878pub fn set_var<Var>(name: &str, value: Var) -> Result<()>
882where
883 Var: ToObject,
884{
885 let name = nvim::String::from(name);
886 let value = value.to_object()?;
887 let mut err = nvim::Error::new();
888 unsafe { nvim_set_var(name.non_owning(), value.non_owning(), &mut err) };
889 choose!(err, ())
890}
891
892pub fn set_vvar<Var>(name: &str, value: Var) -> Result<()>
896where
897 Var: ToObject,
898{
899 let name = nvim::String::from(name);
900 let value = value.to_object()?;
901 let mut err = nvim::Error::new();
902 unsafe { nvim_set_vvar(name.non_owning(), value.non_owning(), &mut err) };
903 choose!(err, ())
904}
905
906pub fn strwidth(text: &str) -> Result<usize> {
911 let text = nvim::String::from(text);
912 let mut err = nvim::Error::new();
913 let width = unsafe { nvim_strwidth(text.non_owning(), &mut err) };
914 choose!(err, Ok(width.try_into().expect("always positive")))
915}