diff --git a/Cargo.lock b/Cargo.lock index e50722d..8118d67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = "0.1.2" dependencies = [ "cairo-rs 0.1.3 (git+https://github.com/gtk-rs/cairo)", "cairo-sys-rs 0.3.4 (git+https://github.com/gtk-rs/cairo)", - "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "gdk 0.5.3 (git+https://github.com/gtk-rs/gdk)", "gdk-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gio 0.1.3 (git+https://github.com/gtk-rs/gio)", @@ -13,16 +13,16 @@ dependencies = [ "gtk 0.1.3 (git+https://github.com/gtk-rs/gtk)", "gtk-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "htmlescape 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "neovim-lib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "pango 0.1.3 (git+https://github.com/gtk-rs/pango)", "pango-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "pangocairo 0.1.3 (git+https://github.com/RazrFalcon/pangocairo-rs)", "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -36,25 +36,15 @@ dependencies = [ [[package]] name = "atk-sys" version = "0.3.4" -source = "git+https://github.com/gtk-rs/sys#518d3a5dad0d8af2c0ff02180e369bf4f4f16a73" +source = "git+https://github.com/gtk-rs/sys#9354d21dfdb9174bfecafbd75cf2a7c0c8ba5759" dependencies = [ - "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "bitflags" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bitflags" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "bitflags" version = "0.9.1" @@ -62,7 +52,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -73,45 +63,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cairo-rs" version = "0.1.3" -source = "git+https://github.com/gtk-rs/cairo#94beb78be68b1aca2cba0ece84b526687f6fd623" +source = "git+https://github.com/gtk-rs/cairo#ef0c3315a57b5cd7134801779c111c6b7d84a410" dependencies = [ "c_vec 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cairo-sys-rs 0.3.4 (git+https://github.com/gtk-rs/cairo)", "glib 0.1.3 (git+https://github.com/gtk-rs/glib)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cairo-sys-rs" version = "0.3.4" -source = "git+https://github.com/gtk-rs/cairo#94beb78be68b1aca2cba0ece84b526687f6fd623" +source = "git+https://github.com/gtk-rs/cairo#ef0c3315a57b5cd7134801779c111c6b7d84a410" dependencies = [ - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cfg-if" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "env_logger" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gdk" version = "0.5.3" -source = "git+https://github.com/gtk-rs/gdk#7c6ed03f875a6cedb5b77343db42eb45de481a1c" +source = "git+https://github.com/gtk-rs/gdk#6f6487a46874be4e96659f6697b480a8345d2690" dependencies = [ - "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "cairo-rs 0.1.3 (git+https://github.com/gtk-rs/cairo)", "cairo-sys-rs 0.3.4 (git+https://github.com/gtk-rs/cairo)", "gdk-pixbuf 0.1.3 (git+https://github.com/gtk-rs/gdk-pixbuf)", @@ -120,45 +110,45 @@ dependencies = [ "glib 0.1.3 (git+https://github.com/gtk-rs/glib)", "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pango 0.1.3 (git+https://github.com/gtk-rs/pango)", ] [[package]] name = "gdk-pixbuf" version = "0.1.3" -source = "git+https://github.com/gtk-rs/gdk-pixbuf#09fafcfc515b9866d4aa88b026cc2261bf322350" +source = "git+https://github.com/gtk-rs/gdk-pixbuf#1888102253747deda678d0ec99b7e4f018c8a6d0" dependencies = [ "gdk-pixbuf-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "glib 0.1.3 (git+https://github.com/gtk-rs/glib)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gdk-pixbuf-sys" version = "0.3.4" -source = "git+https://github.com/gtk-rs/sys#518d3a5dad0d8af2c0ff02180e369bf4f4f16a73" +source = "git+https://github.com/gtk-rs/sys#9354d21dfdb9174bfecafbd75cf2a7c0c8ba5759" dependencies = [ - "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "gio-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gdk-sys" version = "0.3.4" -source = "git+https://github.com/gtk-rs/sys#518d3a5dad0d8af2c0ff02180e369bf4f4f16a73" +source = "git+https://github.com/gtk-rs/sys#9354d21dfdb9174bfecafbd75cf2a7c0c8ba5759" dependencies = [ - "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "cairo-sys-rs 0.3.4 (git+https://github.com/gtk-rs/cairo)", "gdk-pixbuf-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gio-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pango-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -166,67 +156,67 @@ dependencies = [ [[package]] name = "gio" version = "0.1.3" -source = "git+https://github.com/gtk-rs/gio#52757aced2f5e7a24a66fadae1a261cf8a3dd209" +source = "git+https://github.com/gtk-rs/gio#795aafa2a0ade0bdaec86f96f1bc85b0363f6793" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "gio-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "glib 0.1.3 (git+https://github.com/gtk-rs/glib)", "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gio-sys" version = "0.3.4" -source = "git+https://github.com/gtk-rs/sys#518d3a5dad0d8af2c0ff02180e369bf4f4f16a73" +source = "git+https://github.com/gtk-rs/sys#9354d21dfdb9174bfecafbd75cf2a7c0c8ba5759" dependencies = [ - "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "glib" version = "0.1.3" -source = "git+https://github.com/gtk-rs/glib#691ad4a4b715c1747d1acf627999b755eb1745fd" +source = "git+https://github.com/gtk-rs/glib#f874842c0a660165c08c2b522551cd6673431b39" dependencies = [ - "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "glib-sys" version = "0.3.4" -source = "git+https://github.com/gtk-rs/sys#518d3a5dad0d8af2c0ff02180e369bf4f4f16a73" +source = "git+https://github.com/gtk-rs/sys#9354d21dfdb9174bfecafbd75cf2a7c0c8ba5759" dependencies = [ - "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gobject-sys" version = "0.3.4" -source = "git+https://github.com/gtk-rs/sys#518d3a5dad0d8af2c0ff02180e369bf4f4f16a73" +source = "git+https://github.com/gtk-rs/sys#9354d21dfdb9174bfecafbd75cf2a7c0c8ba5759" dependencies = [ - "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gtk" version = "0.1.3" -source = "git+https://github.com/gtk-rs/gtk#9c2c15e34beac5d2bd7e329160d4e79c0dcb7d02" +source = "git+https://github.com/gtk-rs/gtk#d2aa123e5d791affb681347e42b73cb383ab620b" dependencies = [ - "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "cairo-rs 0.1.3 (git+https://github.com/gtk-rs/cairo)", "cairo-sys-rs 0.3.4 (git+https://github.com/gtk-rs/cairo)", "gdk 0.5.3 (git+https://github.com/gtk-rs/gdk)", @@ -239,24 +229,24 @@ dependencies = [ "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gtk-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pango 0.1.3 (git+https://github.com/gtk-rs/pango)", ] [[package]] name = "gtk-sys" version = "0.3.4" -source = "git+https://github.com/gtk-rs/sys#518d3a5dad0d8af2c0ff02180e369bf4f4f16a73" +source = "git+https://github.com/gtk-rs/sys#9354d21dfdb9174bfecafbd75cf2a7c0c8ba5759" dependencies = [ "atk-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", - "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "cairo-sys-rs 0.3.4 (git+https://github.com/gtk-rs/cairo)", "gdk-pixbuf-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gdk-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gio-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pango-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -266,15 +256,6 @@ name = "htmlescape" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "lazy_static" version = "0.2.8" @@ -282,12 +263,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.20" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "log" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -295,7 +276,7 @@ name = "memchr" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -303,7 +284,7 @@ name = "neovim-lib" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "rmp 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)", "rmpv 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -311,36 +292,36 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.1.37" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pango" version = "0.1.3" -source = "git+https://github.com/gtk-rs/pango#4a974b5bda739077e4ef9fc6720b1f76dc8f3491" +source = "git+https://github.com/gtk-rs/pango#6ab128152a174a84cf32bfedffa337792d0ca9e4" dependencies = [ - "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "glib 0.1.3 (git+https://github.com/gtk-rs/glib)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pango-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", ] [[package]] name = "pango-sys" version = "0.3.4" -source = "git+https://github.com/gtk-rs/sys#518d3a5dad0d8af2c0ff02180e369bf4f4f16a73" +source = "git+https://github.com/gtk-rs/sys#9354d21dfdb9174bfecafbd75cf2a7c0c8ba5759" dependencies = [ - "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pangocairo" version = "0.1.3" -source = "git+https://github.com/RazrFalcon/pangocairo-rs#532494fde8c4296b232582e23a28498adb5486a1" +source = "git+https://github.com/RazrFalcon/pangocairo-rs#55478cb05eb716e262d3a88777995d4aa33146a0" dependencies = [ "cairo-rs 0.1.3 (git+https://github.com/gtk-rs/cairo)", "glib 0.1.3 (git+https://github.com/gtk-rs/glib)", @@ -352,11 +333,11 @@ dependencies = [ [[package]] name = "pangocairo-sys" version = "0.3.4" -source = "git+https://github.com/RazrFalcon/pangocairo-rs#532494fde8c4296b232582e23a28498adb5486a1" +source = "git+https://github.com/RazrFalcon/pangocairo-rs#55478cb05eb716e262d3a88777995d4aa33146a0" dependencies = [ "cairo-sys-rs 0.3.4 (git+https://github.com/gtk-rs/cairo)", "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "pango-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -410,24 +391,24 @@ name = "rand" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -435,8 +416,8 @@ name = "rmp" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -444,28 +425,28 @@ name = "rmpv" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "rmp 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive_internals" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -495,30 +476,21 @@ dependencies = [ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "thread-id" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "thread_local" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "thread-id 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "toml" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -531,13 +503,13 @@ name = "unix_socket" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unreachable" -version = "0.1.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -558,23 +530,16 @@ name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [metadata] "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" "checksum atk-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "" -"checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" -"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" -"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8" +"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" "checksum c_vec 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6237ac5a4b1e81c213c24c6437964c61e646df910a914b4ab1487b46df20bd13" "checksum cairo-rs 0.1.3 (git+https://github.com/gtk-rs/cairo)" = "" "checksum cairo-sys-rs 0.3.4 (git+https://github.com/gtk-rs/cairo)" = "" -"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" -"checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83" +"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" +"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum gdk 0.5.3 (git+https://github.com/gtk-rs/gdk)" = "" "checksum gdk-pixbuf 0.1.3 (git+https://github.com/gtk-rs/gdk-pixbuf)" = "" "checksum gdk-pixbuf-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "" @@ -587,13 +552,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum gtk 0.1.3 (git+https://github.com/gtk-rs/gtk)" = "" "checksum gtk-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "" "checksum htmlescape 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" -"checksum libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "684f330624d8c3784fb9558ca46c4ce488073a8d22450415c5eb4f4cfb0d11b5" -"checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad" +"checksum libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "30885bcb161cf67054244d10d4a7f4835ffd58773bc72e07d35fecf472295503" +"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" "checksum neovim-lib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cd81cd2140309fcbe61775ebe5901b0730e5fdae2558a6cd27539e6e730fa76a" -"checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" +"checksum num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "1708c0628602a98b52fad936cf3edb9a107af06e52e49fdf0707e884456a6af6" "checksum pango 0.1.3 (git+https://github.com/gtk-rs/pango)" = "" "checksum pango-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "" "checksum pangocairo 0.1.3 (git+https://github.com/RazrFalcon/pangocairo-rs)" = "" @@ -605,23 +569,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" -"checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01" -"checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457" +"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" +"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum rmp 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7ce560a5728f4eec697f07f8d7fa20608893d44b4f5b8f9f5f51a2987f3cffe2" "checksum rmpv 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "45368daa6c60116376d8813ec6a2556df640229709becb8f80df1651f882e7af" -"checksum serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c0c3d79316a6051231925504f6ef893d45088e8823c77a8331a3dcf427ee9087" -"checksum serde_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0019cd5b9f0529a1a0e145a912e9a2d60c325c58f7f260fc36c71976e9d76aee" -"checksum serde_derive_internals 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "021c338d22c7e30f957a6ab7e388cb6098499dda9fd4ba1661ee074ca7a180d1" +"checksum serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7c6b751a2e8d5df57a5ff71b5b4fc8aaee9ee28ff1341d640dd130bb5f4f7a" +"checksum serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2f6ca58905ebd3c3b285a8a6d4f3ac92b92c0d7951d5649b1bdd212549c06639" +"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum thread-id 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8df7875b676fddfadffd96deea3b1124e5ede707d4884248931077518cf1f773" -"checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7" -"checksum toml 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4cc5dbfb20a481e64b99eb7ae280859ec76730c7191570ba5edaa962394edb0a" +"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" +"checksum toml 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b0601da6c97135c8d330c7a13a013ca6cd4143221b01de2f8d4edc50a9e551c7" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" -"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/Makefile b/Makefile index e5b2b56..3ef46c8 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ run: RUST_BACKTRACE=1 cargo run install: install-resources - cargo install --root $(PREFIX) + cargo install --force --root $(PREFIX) install-resources: mkdir -p $(PREFIX)/share/nvim-gtk/ diff --git a/appveyor.yml b/appveyor.yml index d200ce1..fd62518 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,7 @@ environment: PROJECT_NAME: rustfmt matrix: - TARGET: x86_64-pc-windows-gnu - RUST_VERSION: 1.17.0 + RUST_VERSION: 1.18.0 install: # - ps: Start-FileDownload "https://static.rust-lang.org/dist/channel-rust-stable" diff --git a/src/cursor.rs b/src/cursor.rs index 96a8000..5522474 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -2,7 +2,8 @@ use cairo; use ui_model::Color; use ui::UiMutex; use shell; -use shell::NvimMode; +use mode; +use nvim; use nvim::{RepaintMode, RedrawEvents}; use std::sync::{Arc, Weak}; @@ -123,7 +124,63 @@ impl Cursor { let current_point = ctx.get_current_point(); ctx.set_source_rgba(1.0 - bg.0, 1.0 - bg.1, 1.0 - bg.2, 0.6 * state.alpha.0); - let cursor_width = if shell.mode == NvimMode::Insert { + let (y, width, height) = + cursor_rect(&shell.mode, char_width, line_height, line_y, double_width); + + ctx.rectangle(current_point.0, y, width, height); + if state.anim_phase == AnimPhase::NoFocus { + ctx.stroke(); + } else { + ctx.fill(); + } + } +} + +fn cursor_rect(mode: &mode::Mode, + char_width: f64, + line_height: f64, + line_y: f64, + double_width: bool) + -> (f64, f64, f64) { + if let Some(mode_info) = mode.mode_info() { + match mode_info.cursor_shape() { + None | + Some(&nvim::CursorShape::Unknown) | + Some(&nvim::CursorShape::Block) => { + let cursor_width = if double_width { + char_width * 2.0 + } else { + char_width + }; + (line_y, cursor_width, line_height) + } + Some(&nvim::CursorShape::Vertical) => { + let cell_percentage = mode_info.cell_percentage(); + let cursor_width = if cell_percentage > 0 { + (char_width * cell_percentage as f64) / 100.0 + } else { + char_width + }; + (line_y, cursor_width, line_height) + } + Some(&nvim::CursorShape::Horizontal) => { + let cell_percentage = mode_info.cell_percentage(); + let cursor_width = if double_width { + char_width * 2.0 + } else { + char_width + }; + + if cell_percentage > 0 { + let height = (line_height * cell_percentage as f64) / 100.0; + (line_y + line_height - height, cursor_width, height) + } else { + (line_y, cursor_width, line_height) + } + } + } + } else { + let cursor_width = if mode.is(&mode::NvimMode::Insert) { char_width / 5.0 } else { if double_width { @@ -133,15 +190,9 @@ impl Cursor { } }; - ctx.rectangle(current_point.0, line_y, cursor_width, line_height); - if state.anim_phase == AnimPhase::NoFocus { - ctx.stroke(); - } else { - ctx.fill(); - } + (line_y, cursor_width, line_height) } } - fn anim_step(state: &Arc>) -> glib::Continue { let mut mut_state = state.borrow_mut(); @@ -201,3 +252,62 @@ impl Drop for Cursor { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_cursor_rect_horizontal() { + let mut mode = mode::Mode::new(); + let mode_info = nvim::ModeInfo::new(&vec![(From::from("cursor_shape"), + From::from("horizontal")), + (From::from("cell_percentage"), From::from(25))]); + mode.update("insert", 0); + mode.set_info(true, vec![mode_info.unwrap()]); + let char_width = 50.0; + let line_height = 30.0; + let line_y = 0.0; + + let (y, width, height) = cursor_rect(&mode, char_width, line_height, line_y, false); + assert_eq!(line_y + line_height - line_height / 4.0, y); + assert_eq!(char_width, width); + assert_eq!(line_height / 4.0, height); + } + + #[test] + fn test_cursor_rect_horizontal_doublewidth() { + let mut mode = mode::Mode::new(); + let mode_info = nvim::ModeInfo::new(&vec![(From::from("cursor_shape"), + From::from("horizontal")), + (From::from("cell_percentage"), From::from(25))]); + mode.update("insert", 0); + mode.set_info(true, vec![mode_info.unwrap()]); + let char_width = 50.0; + let line_height = 30.0; + let line_y = 0.0; + + let (y, width, height) = cursor_rect(&mode, char_width, line_height, line_y, true); + assert_eq!(line_y + line_height - line_height / 4.0, y); + assert_eq!(char_width * 2.0, width); + assert_eq!(line_height / 4.0, height); + } + + #[test] + fn test_cursor_rect_vertical() { + let mut mode = mode::Mode::new(); + let mode_info = nvim::ModeInfo::new(&vec![(From::from("cursor_shape"), + From::from("vertical")), + (From::from("cell_percentage"), From::from(25))]); + mode.update("insert", 0); + mode.set_info(true, vec![mode_info.unwrap()]); + let char_width = 50.0; + let line_height = 30.0; + let line_y = 0.0; + + let (y, width, height) = cursor_rect(&mode, char_width, line_height, line_y, false); + assert_eq!(line_y, y); + assert_eq!(char_width / 4.0, width); + assert_eq!(line_height, height); + } +} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..ccda4bb --- /dev/null +++ b/src/error.rs @@ -0,0 +1,52 @@ +use std::ops::Deref; + +use htmlescape::encode_minimal; + +use gtk; +use gtk::prelude::*; + +use gtk_sys; + +use shell; + +pub struct ErrorArea { + base: gtk::Box, + label: gtk::Label, +} + +impl ErrorArea { + pub fn new() -> Self { + let base = gtk::Box::new(gtk::Orientation::Horizontal, 0); + + let label = gtk::Label::new(None); + label.set_line_wrap(true); + let error_image = gtk::Image::new_from_icon_name("dialog-error", + gtk_sys::GTK_ICON_SIZE_DIALOG as i32); + base.pack_start(&error_image, false, true, 10); + base.pack_start(&label, true, true, 1); + + ErrorArea { base, label } + } + + pub fn show_nvim_start_error(&self, err: &str, cmd: &str) { + error!("Can't start nvim: {}\nCommand line: {}", err, cmd); + self.label.set_markup(&format!("Can't start nvim instance:\n\ + {}\n\ + {}\n\n\ + Possible error reasons:\n\ + ● Not supported nvim version (minimum supported version is {})\n\ + ● Error in configuration file (init.vim or ginit.vim)\n\ + ● Wrong nvim binary path \ + (right path can be passed with --nvim-bin-path=path_here)", + encode_minimal(cmd), encode_minimal(err), shell::MINIMUM_SUPPORTED_NVIM_VERSION)); + self.base.show_all(); + } +} + +impl Deref for ErrorArea { + type Target = gtk::Box; + + fn deref(&self) -> >k::Box { + &self.base + } +} diff --git a/src/main.rs b/src/main.rs index 7d5edb1..ac76661 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,8 @@ extern crate serde_derive; extern crate serde; extern crate toml; +mod value; +mod mode; mod ui_model; #[macro_use] mod ui; @@ -31,14 +33,16 @@ mod shell_dlg; mod popup_menu; mod project; mod tabline; +mod error; use std::env; -use gtk::prelude::*; use gio::{ApplicationExt, FileExt}; use ui::Ui; +use shell::ShellOptions; + const BIN_PATH_ARG: &'static str = "--nvim-bin-path"; fn main() { @@ -65,25 +69,22 @@ fn main() { .filter(|a| !a.starts_with(BIN_PATH_ARG)) .map(String::as_str) .collect(); - app.run(argv.len() as i32, &argv); + app.run(&argv); } fn open(app: >k::Application, files: &[gio::File], _: &str) { for f in files { - let mut ui = Ui::new(); + let mut ui = Ui::new(ShellOptions::new(nvim_bin_path(std::env::args()), + f.get_path().and_then(|p| p.to_str().map(str::to_owned)))); - ui.init(app, - nvim_bin_path(std::env::args()).as_ref(), - f.get_path().as_ref().map(|p| p.to_str()).unwrap_or(None)); + ui.init(app); } } fn activate(app: >k::Application) { - let mut ui = Ui::new(); + let mut ui = Ui::new(ShellOptions::new(nvim_bin_path(std::env::args()), None)); - ui.init(app, - nvim_bin_path(std::env::args()).as_ref(), - None); + ui.init(app); } fn nvim_bin_path(args: I) -> Option diff --git a/src/mode.rs b/src/mode.rs new file mode 100644 index 0000000..e8fdc60 --- /dev/null +++ b/src/mode.rs @@ -0,0 +1,52 @@ +use nvim; + +#[derive(PartialEq)] +pub enum NvimMode { + Normal, + Insert, + Other, +} + +pub struct Mode { + mode: NvimMode, + idx: usize, + info: Option>, +} + +impl Mode { + pub fn new() -> Self { + Mode { + mode: NvimMode::Normal, + idx: 0, + info: None, + } + } + + pub fn is(&self, mode: &NvimMode) -> bool { + self.mode == *mode + } + + pub fn mode_info(&self) -> Option<&nvim::ModeInfo> { + self.info + .as_ref() + .and_then(|i| i.get(self.idx)) + } + + pub fn update(&mut self, mode: &str, idx: usize) { + match mode { + "normal" => self.mode = NvimMode::Normal, + "insert" => self.mode = NvimMode::Insert, + _ => self.mode = NvimMode::Other, + } + + self.idx = idx; + } + + pub fn set_info(&mut self, cursor_style_enabled: bool, info: Vec) { + self.info = if cursor_style_enabled { + Some(info) + } else { + None + }; + } +} diff --git a/src/nvim.rs b/src/nvim.rs index 8b6f1a9..eabcae5 100644 --- a/src/nvim.rs +++ b/src/nvim.rs @@ -1,8 +1,10 @@ -use std::io::{Result, Error, ErrorKind}; +use std::error; +use std::fmt; use std::env; use std::process::{Stdio, Command}; use std::result; use std::sync::Arc; +use std::ops::{Deref, DerefMut}; use neovim_lib::{Handler, Neovim, NeovimApi, Session, Value, UiAttachOptions, CallError, UiOption}; use neovim_lib::neovim_api::Tabpage; @@ -12,6 +14,8 @@ use ui_model::{ModelRect, ModelRectVec}; use shell; use glib; +use value::ValueMapExt; + pub trait RedrawEvents { fn on_cursor_goto(&mut self, row: u64, col: u64) -> RepaintMode; @@ -37,7 +41,7 @@ pub trait RedrawEvents { fn on_update_sp(&mut self, sp: i64) -> RepaintMode; - fn on_mode_change(&mut self, mode: &str) -> RepaintMode; + fn on_mode_change(&mut self, mode: &str, idx: u64) -> RepaintMode; fn on_mouse(&mut self, on: bool) -> RepaintMode; @@ -56,8 +60,13 @@ pub trait RedrawEvents { fn tabline_update(&mut self, selected: Tabpage, - tabs: Vec<(Tabpage, Option<&str>)>) + tabs: Vec<(Tabpage, Option)>) -> RepaintMode; + + fn mode_info_set(&mut self, + cursor_style_enabled: bool, + mode_info: Vec) + -> RepaintMode; } pub trait GuiApi { @@ -76,9 +85,136 @@ macro_rules! try_uint { ($exp:expr) => ($exp.as_u64().ok_or("Can't convert argument to u64".to_owned())?) } +macro_rules! try_bool { + ($exp:expr) => ($exp.as_bool().ok_or("Can't convert argument to bool".to_owned())?) +} + +macro_rules! map_array { + ($arg:expr, $err:expr, |$item:ident| $exp:expr) => ( + $arg.as_array() + .ok_or($err) + .and_then(|items| items.iter().map(|$item| { + $exp + }).collect::, _>>()) + ); + ($arg:expr, $err:expr, |$item:ident| {$exp:expr}) => ( + $arg.as_array() + .ok_or($err) + .and_then(|items| items.iter().map(|$item| { + $exp + }).collect::, _>>()) + ); +} + +#[derive(Debug, Clone)] +pub enum CursorShape { + Block, + Horizontal, + Vertical, + Unknown, +} + +impl CursorShape { + fn new(shape_code: &Value) -> Result { + let str_code = shape_code + .as_str() + .ok_or("Can't convert cursor shape to string".to_owned())?; + + Ok(match str_code { + "block" => CursorShape::Block, + "horizontal" => CursorShape::Horizontal, + "vertical" => CursorShape::Vertical, + _ => { + error!("Unknown cursor_shape {}", str_code); + CursorShape::Unknown + } + }) + } +} + +#[derive(Debug, Clone)] +pub struct ModeInfo { + cursor_shape: Option, + cell_percentage: Option, +} + +impl ModeInfo { + pub fn new(mode_info_arr: &Vec<(Value, Value)>) -> Result { + let mode_info_map = mode_info_arr.to_attrs_map()?; + + let cursor_shape = if let Some(shape) = mode_info_map.get("cursor_shape") { + Some(CursorShape::new(shape)?) + } else { + None + }; + + let cell_percentage = if let Some(cell_percentage) = mode_info_map.get("cell_percentage") { + cell_percentage.as_u64() + } else { + None + }; + + Ok(ModeInfo { + cursor_shape, + cell_percentage, + }) + } + + pub fn cursor_shape(&self) -> Option<&CursorShape> { + self.cursor_shape.as_ref() + } + + pub fn cell_percentage(&self) -> u64 { + self.cell_percentage.unwrap_or(0) + } +} + +#[derive(Debug)] +pub struct NvimInitError { + source: Box, + cmd: String, +} + +impl NvimInitError { + pub fn new(cmd: &Command, error: E) -> NvimInitError + where E: Into> + { + NvimInitError { + cmd: format!("{:?}", cmd), + source: error.into(), + } + } + + pub fn source(&self) -> String { + format!("{}", self.source) + } + + pub fn cmd(&self) -> &str { + &self.cmd + } +} + +impl fmt::Display for NvimInitError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.source) + } +} + +impl error::Error for NvimInitError { + fn description(&self) -> &str { + "Can't start nvim instance" + } + + fn cause(&self) -> Option<&error::Error> { + Some(&*self.source) + } +} + pub fn initialize(shell: Arc>, - nvim_bin_path: Option<&String>) - -> Result { + nvim_bin_path: Option<&String>, + cols: u64, + rows: u64) + -> result::Result { let mut cmd = if let Some(path) = nvim_bin_path { Command::new(path) } else { @@ -106,10 +242,7 @@ pub fn initialize(shell: Arc>, let session = Session::new_child_cmd(&mut cmd); let session = match session { - Err(e) => { - println!("Error execute: {:?}", cmd); - return Err(From::from(e)); - } + Err(e) => return Err(NvimInitError::new(&cmd, e)), Ok(s) => s, }; @@ -120,10 +253,10 @@ pub fn initialize(shell: Arc>, let mut opts = UiAttachOptions::new(); opts.set_popupmenu_external(false); opts.set_tabline_external(true); - nvim.ui_attach(80, 24, opts) - .map_err(|e| Error::new(ErrorKind::Other, e))?; + nvim.ui_attach(cols, rows, opts) + .map_err(|e| NvimInitError::new(&cmd, e))?; nvim.command("runtime! ginit.vim") - .map_err(|e| Error::new(ErrorKind::Other, e))?; + .map_err(|e| NvimInitError::new(&cmd, e))?; Ok(nvim) } @@ -263,23 +396,17 @@ fn call(ui: &mut shell::State, "update_bg" => ui.on_update_bg(try_int!(args[0])), "update_fg" => ui.on_update_fg(try_int!(args[0])), "update_sp" => ui.on_update_sp(try_int!(args[0])), - "mode_change" => ui.on_mode_change(try_str!(args[0])), + "mode_change" => ui.on_mode_change(try_str!(args[0]), try_uint!(args[1])), "mouse_on" => ui.on_mouse(true), "mouse_off" => ui.on_mouse(false), "busy_start" => ui.on_busy(true), "busy_stop" => ui.on_busy(false), "popupmenu_show" => { - let mut menu_items = Vec::new(); - - let items = args[0].as_array().ok_or("Error get menu list array")?; - for item in items { - let item_line: result::Result, &str> = item.as_array() - .ok_or("Error get menu item array")? - .iter() - .map(|col| col.as_str().ok_or("Error get menu column")) - .collect(); - menu_items.push(item_line?); - } + let menu_items = map_array!(args[0], "Error get menu list array", |item| { + map_array!(item, + "Error get menu item array", + |col| col.as_str().ok_or("Error get menu column")) + })?; ui.popupmenu_show(&menu_items, try_int!(args[1]), @@ -289,27 +416,34 @@ fn call(ui: &mut shell::State, "popupmenu_hide" => ui.popupmenu_hide(), "popupmenu_select" => ui.popupmenu_select(try_int!(args[0])), "tabline_update" => { - let tabs_in = args[1].as_array().ok_or("Error get tabline list")?; + let tabs_out = map_array!(args[1], "Error get tabline list".to_owned(), |tab| { + tab.as_map() + .ok_or("Error get map for tab".to_owned()) + .and_then(|tab_map| tab_map.to_attrs_map()) + .map(|tab_attrs| { + let name_attr = tab_attrs + .get("name") + .and_then(|n| n.as_str().map(|s| s.to_owned())); + let tab_attr = tab_attrs + .get("tab") + .map(|tab_id| Tabpage::new(tab_id.clone())) + .unwrap(); - let mut tabs_out = Vec::new(); - for tab in tabs_in { - let tab_attrs = tab.as_map().ok_or("Error get map for tab")?; - - let mut tab_attr = None; - let mut name_attr = None; - - for attr in tab_attrs { - let key = attr.0.as_str().ok_or("Error get key value")?; - if key == "tab" { - tab_attr = Some(Tabpage::new(attr.1.clone())); - } else if key == "name" { - name_attr = attr.1.as_str(); - } - } - tabs_out.push((tab_attr.unwrap(), name_attr)); - } + (tab_attr, name_attr) + }) + })?; ui.tabline_update(Tabpage::new(args[0].clone()), tabs_out) } + "mode_info_set" => { + let mode_info = map_array!(args[1], + "Error get array key value for mode_info".to_owned(), + |mi| { + mi.as_map() + .ok_or("Erro get map for mode_info".to_owned()) + .and_then(|mi_map| ModeInfo::new(mi_map)) + })?; + ui.mode_info_set(try_bool!(args[0]), mode_info) + } _ => { println!("Event {}({:?})", method, args); RepaintMode::Nothing @@ -370,6 +504,97 @@ impl RepaintMode { } } + +enum NeovimClientWrapper { + Uninitialized, + Initialized(Neovim), + Error, +} + +impl NeovimClientWrapper { + pub fn is_initialized(&self) -> bool { + match *self { + NeovimClientWrapper::Initialized(_) => true, + _ => false, + } + } + + pub fn is_error(&self) -> bool { + match *self { + NeovimClientWrapper::Error => true, + _ => false, + } + } + + pub fn nvim(&self) -> &Neovim { + match *self { + NeovimClientWrapper::Initialized(ref nvim) => nvim, + NeovimClientWrapper::Uninitialized => panic!("Access to uninitialized neovim client"), + NeovimClientWrapper::Error => { + panic!("Access to neovim client that is not started due to some error") + } + } + } + + pub fn nvim_mut(&mut self) -> &mut Neovim { + match *self { + NeovimClientWrapper::Initialized(ref mut nvim) => nvim, + NeovimClientWrapper::Uninitialized => panic!("Access to uninitialized neovim client"), + NeovimClientWrapper::Error => { + panic!("Access to neovim client that is not started due to some error") + } + } + } +} + +pub struct NeovimClient { + nvim: NeovimClientWrapper, +} + +impl NeovimClient { + pub fn new() -> Self { + NeovimClient { nvim: NeovimClientWrapper::Uninitialized } + } + + pub fn set_nvim(&mut self, nvim: Neovim) { + self.nvim = NeovimClientWrapper::Initialized(nvim); + } + + pub fn set_error(&mut self) { + self.nvim = NeovimClientWrapper::Error; + } + + pub fn is_initialized(&self) -> bool { + self.nvim.is_initialized() + } + + pub fn is_error(&self) -> bool { + self.nvim.is_error() + } + + pub fn nvim(&self) -> &Neovim { + self.nvim.nvim() + } + + pub fn nvim_mut(&mut self) -> &mut Neovim { + self.nvim.nvim_mut() + } +} + +impl Deref for NeovimClient { + type Target = Neovim; + + fn deref(&self) -> &Neovim { + self.nvim() + } +} + +impl DerefMut for NeovimClient { + fn deref_mut(&mut self) -> &mut Neovim { + self.nvim_mut() + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/popup_menu.rs b/src/popup_menu.rs index a8e1ce4..170fd4e 100644 --- a/src/popup_menu.rs +++ b/src/popup_menu.rs @@ -9,6 +9,7 @@ use gdk::{EventButton, EventType}; use neovim_lib::{Neovim, NeovimApi}; +use nvim; use nvim::ErrorReport; use shell; use input; @@ -16,7 +17,7 @@ use input; const MAX_VISIBLE_ROWS: i32 = 10; struct State { - nvim: Option>>, + nvim: Option>>, renderer: gtk::CellRendererText, tree: gtk::TreeView, scroll: gtk::ScrolledWindow, diff --git a/src/settings.rs b/src/settings.rs index 1e942a8..1e64cfa 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,8 +1,6 @@ use std::rc::{Rc, Weak}; use std::cell::RefCell; -use gio::SettingsExt; - #[cfg(unix)] use nvim::RepaintMode; diff --git a/src/shell.rs b/src/shell.rs index f801d63..837948e 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1,8 +1,8 @@ use std::cell::{RefMut, RefCell}; use std::rc::Rc; -use std::sync; use std::sync::Arc; use std::ops::Deref; +use std::thread; use cairo; use pangocairo::CairoContextExt; @@ -21,23 +21,29 @@ use neovim_lib::neovim_api::Tabpage; use settings::{Settings, FontSource}; use ui_model::{UiModel, Cell, Attrs, Color, ModelRect, COLOR_BLACK, COLOR_WHITE, COLOR_RED}; use nvim; -use nvim::{RedrawEvents, GuiApi, RepaintMode, ErrorReport}; +use nvim::{RedrawEvents, GuiApi, RepaintMode, ErrorReport, NeovimClient}; use input; use input::keyval_to_input_string; use cursor::Cursor; -use ui; use ui::UiMutex; use popup_menu::PopupMenu; use tabline::Tabline; +use error; +use mode; -const DEFAULT_FONT_NAME: &'static str = "DejaVu Sans Mono 12"; +const DEFAULT_FONT_NAME: &str = "DejaVu Sans Mono 12"; +pub const MINIMUM_SUPPORTED_NVIM_VERSION: &str = "0.2"; +macro_rules! idle_cb_call { + ($state:ident.$cb:ident($( $x:expr ),*)) => ( + glib::idle_add(move || { + if let Some(ref cb) = $state.borrow().$cb { + (&mut *cb.borrow_mut())($($x),*); + } -#[derive(PartialEq)] -pub enum NvimMode { - Normal, - Insert, - Other, + glib::Continue(false) + }); + ) } pub struct State { @@ -46,55 +52,66 @@ pub struct State { fg_color: Color, sp_color: Color, cur_attrs: Option, - pub mode: NvimMode, mouse_enabled: bool, - nvim: Option>>, + nvim: Rc>, font_desc: FontDescription, cursor: Option, popup_menu: RefCell, settings: Rc>, + pub mode: mode::Mode, + + stack: gtk::Stack, drawing_area: gtk::DrawingArea, tabs: Tabline, im_context: gtk::IMMulticontext, + error_area: error::ErrorArea, line_height: Option, char_width: Option, request_resize: bool, resize_timer: Option, - parent: sync::Weak>, + options: ShellOptions, + + detach_cb: Option>>, } impl State { - pub fn new(settings: Rc>, parent: &Arc>) -> State { + pub fn new(settings: Rc>, options: ShellOptions) -> State { let drawing_area = gtk::DrawingArea::new(); let popup_menu = RefCell::new(PopupMenu::new(&drawing_area)); State { - model: UiModel::new(24, 80), - nvim: None, + model: UiModel::new(1, 1), + nvim: Rc::new(RefCell::new(NeovimClient::new())), cur_attrs: None, bg_color: COLOR_BLACK, fg_color: COLOR_WHITE, sp_color: COLOR_RED, - mode: NvimMode::Normal, mouse_enabled: true, font_desc: FontDescription::from_string(DEFAULT_FONT_NAME), cursor: None, popup_menu, settings: settings, + mode: mode::Mode::new(), + + // UI + stack: gtk::Stack::new(), drawing_area, tabs: Tabline::new(), im_context: gtk::IMMulticontext::new(), + error_area: error::ErrorArea::new(), line_height: None, char_width: None, resize_timer: None, request_resize: false, - parent: Arc::downgrade(parent), + options, + + detach_cb: None, } } @@ -107,11 +124,21 @@ impl State { } pub fn nvim(&self) -> RefMut { - self.nvim.as_ref().unwrap().borrow_mut() + RefMut::map(self.nvim.borrow_mut(), |n| n.nvim_mut()) } - pub fn nvim_clone(&self) -> Rc> { - self.nvim.as_ref().unwrap().clone() + pub fn nvim_clone(&self) -> Rc> { + self.nvim.clone() + } + + pub fn set_detach_cb(&mut self, cb: Option) + where F: FnMut() + Send + 'static + { + if cb.is_some() { + self.detach_cb = Some(Box::new(RefCell::new(cb.unwrap()))); + } else { + self.detach_cb = None; + } } fn create_pango_font(&self) -> FontDescription { @@ -186,10 +213,38 @@ impl State { } fn im_commit(&self, ch: &str) { - if let Some(ref nvim) = self.nvim { - input::im_input(&mut *nvim.borrow_mut(), ch); + input::im_input(&mut self.nvim.borrow_mut(), ch); + } + + fn calc_char_bounds(&self, ctx: &cairo::Context) -> (i32, i32) { + let layout = ctx.create_pango_layout(); + + let desc = self.create_pango_font(); + layout.set_font_description(Some(&desc)); + layout.set_text("A", -1); + + layout.get_pixel_size() + } + + fn calc_line_metrics(&mut self, ctx: &cairo::Context) { + if self.line_height.is_none() { + let (width, height) = self.calc_char_bounds(ctx); + self.line_height = Some(height as f64); + self.char_width = Some(width as f64); } } + + fn calc_nvim_size(&self) -> Option<(usize, usize)> { + if let Some(line_height) = self.line_height { + if let Some(char_width) = self.char_width { + let alloc = self.drawing_area.get_allocation(); + return Some(((alloc.width as f64 / char_width).trunc() as usize, + (alloc.height as f64 / line_height).trunc() as usize)); + } + } + + None + } } pub struct UiState { @@ -202,6 +257,20 @@ impl UiState { } } +pub struct ShellOptions { + nvim_bin_path: Option, + open_path: Option, +} + +impl ShellOptions { + pub fn new(nvim_bin_path: Option, open_path: Option) -> Self { + ShellOptions { + nvim_bin_path, + open_path, + } + } +} + pub struct Shell { pub state: Arc>, ui_state: Rc>, @@ -210,9 +279,9 @@ pub struct Shell { } impl Shell { - pub fn new(settings: Rc>, parent: &Arc>) -> Shell { + pub fn new(settings: Rc>, options: ShellOptions) -> Shell { let shell = Shell { - state: Arc::new(UiMutex::new(State::new(settings, parent))), + state: Arc::new(UiMutex::new(State::new(settings, options))), ui_state: Rc::new(RefCell::new(UiState::new())), widget: gtk::Box::new(gtk::Orientation::Vertical, 0), @@ -224,17 +293,29 @@ impl Shell { shell } + pub fn is_nvim_initialized(&self) -> bool { + let state = self.state.borrow(); + let nvim = state.nvim.borrow(); + nvim.is_initialized() + } + pub fn init(&mut self) { - let state = self.state.borrow_mut(); - state.drawing_area.set_size_request(500, 300); + let mut state = self.state.borrow_mut(); state.drawing_area.set_hexpand(true); state.drawing_area.set_vexpand(true); state.drawing_area.set_can_focus(true); state.im_context.set_use_preedit(false); - self.widget.pack_start(&*state.tabs, false, true, 0); - self.widget.pack_start(&state.drawing_area, true, true, 0); + let nvim_box = gtk::Box::new(gtk::Orientation::Vertical, 0); + + nvim_box.pack_start(&*state.tabs, false, true, 0); + nvim_box.pack_start(&state.drawing_area, true, true, 0); + + state.stack.add_named(&nvim_box, "Nvim"); + state.stack.add_named(&*state.error_area, "Error"); + + self.widget.pack_start(&state.stack, true, true, 0); state .drawing_area @@ -274,12 +355,7 @@ impl Shell { let ref_state = self.state.clone(); state .drawing_area - .connect_draw(move |_, ctx| { - let mut state = ref_state.borrow_mut(); - let ref_parent = sync::Weak::upgrade(&state.parent).unwrap(); - let parent = ref_parent.borrow(); - gtk_draw(&*parent, &mut *state, ctx) - }); + .connect_draw(move |_, ctx| gtk_draw(&ref_state, ctx)); let ref_state = self.state.clone(); state @@ -294,11 +370,11 @@ impl Shell { ev.get_keyval() < gdk_sys::GDK_KEY_KP_Space as u32 && ev.get_keyval() > gdk_sys::GDK_KEY_KP_Divide as u32 && shell.im_context.filter_keypress(ev) { - println!("Filter"); + println!("Filter"); Inhibit(true) } else { - if let Some(ref nvim) = shell.nvim { - input::gtk_key_press(&mut *nvim.borrow_mut(), ev) + if shell.nvim.borrow().is_initialized() { + input::gtk_key_press(&mut shell.nvim.borrow_mut(), ev) } else { Inhibit(false) } @@ -308,9 +384,9 @@ impl Shell { state .drawing_area .connect_key_release_event(move |_, ev| { - ref_state.borrow().im_context.filter_keypress(ev); - Inhibit(false) - }); + ref_state.borrow().im_context.filter_keypress(ev); + Inhibit(false) + }); let ref_state = self.state.clone(); state @@ -342,6 +418,12 @@ impl Shell { .im_context .connect_commit(move |_, ch| ref_state.borrow().im_commit(ch)); + let ref_state = self.state.clone(); + state + .drawing_area + .connect_configure_event(move |_, ev| gtk_configure_event(&ref_state, ev)); + + state.cursor.as_mut().unwrap().start(); } #[cfg(unix)] @@ -354,24 +436,6 @@ impl Shell { self.state.borrow_mut().set_font_desc(font_name); } - pub fn add_configure_event(&mut self) { - let mut state = self.state.borrow_mut(); - - let ref_state = self.state.clone(); - state - .drawing_area - .connect_configure_event(move |_, ev| gtk_configure_event(&ref_state, ev)); - - state.cursor.as_mut().unwrap().start(); - } - - pub fn init_nvim(&mut self, nvim_bin_path: Option<&String>) { - let nvim = nvim::initialize(self.state.clone(), nvim_bin_path) - .expect("Can't start nvim instance"); - let mut state = self.state.borrow_mut(); - state.nvim = Some(Rc::new(RefCell::new(nvim))); - } - pub fn grab_focus(&self) { self.state.borrow().drawing_area.grab_focus(); } @@ -391,7 +455,7 @@ impl Shell { pub fn edit_paste(&self) { let state = self.state.borrow(); - let paste_command = if state.mode == NvimMode::Normal { + let paste_command = if state.mode.is(&mode::NvimMode::Normal) { "\"*p" } else { "\"*pa" @@ -406,6 +470,13 @@ impl Shell { let mut nvim = &mut *state.nvim(); nvim.command(":wa").report_err(nvim); } + + pub fn set_detach_cb(&self, cb: Option) + where F: FnMut() + Send + 'static + { + let mut state = self.state.borrow_mut(); + state.set_detach_cb(cb); + } } impl Deref for Shell { @@ -498,33 +569,74 @@ fn gtk_motion_notify(shell: &mut State, ui_state: &mut UiState, ev: &EventMotion Inhibit(false) } -fn gtk_draw(parent: &ui::Components, state: &mut State, ctx: &cairo::Context) -> Inhibit { +#[inline] +fn update_line_metrics(state_arc: &Arc>, ctx: &cairo::Context) { + let mut state = state_arc.borrow_mut(); + if state.line_height.is_none() { - let (width, height) = calc_char_bounds(state, ctx); - state.line_height = Some(height as f64); - state.char_width = Some(width as f64); + state.calc_line_metrics(ctx); + } +} + +fn gtk_draw(state_arc: &Arc>, ctx: &cairo::Context) -> Inhibit { + update_line_metrics(state_arc, ctx); + init_nvim(state_arc); + + let mut state = state_arc.borrow_mut(); + // in case nvim not initialized + if !state.nvim.borrow().is_error() { + draw(&*state, ctx); + request_window_resize(&mut *state); } - //TODO: to much call of this function - let (row, col) = state.model.get_cursor(); - let (x, y, width, height) = ModelRect::point(col, row) - .to_area(state.line_height.unwrap(), state.char_width.unwrap()); - state - .im_context - .set_cursor_location(&gdk::Rectangle { - x, - y, - width, - height, - }); - - draw(state, ctx); - request_window_resize(parent, state); - - Inhibit(false) } + +fn init_nvim(state_arc: &Arc>) { + let state = state_arc.borrow(); + + let mut nvim_client = state.nvim.borrow_mut(); + if !nvim_client.is_initialized() && !nvim_client.is_error() { + let (cols, rows) = state.calc_nvim_size().unwrap(); + let mut nvim = match nvim::initialize(state_arc.clone(), + state.options.nvim_bin_path.as_ref(), + cols as u64, + rows as u64) { + Ok(nvim) => nvim, + Err(err) => { + nvim_client.set_error(); + state + .error_area + .show_nvim_start_error(&err.source(), err.cmd()); + + let stack = state.stack.clone(); + gtk::idle_add(move || { + stack.set_visible_child_name("Error"); + Continue(false) + }); + + return; + } + }; + + if let Some(ref path) = state.options.open_path { + nvim.command(&format!("e {}", path)).report_err(&mut nvim); + } + + let guard = nvim.session.take_dispatch_guard(); + + let state_ref = state_arc.clone(); + thread::spawn(move || { + guard.join().expect("Can't join dispatch thread"); + + idle_cb_call!(state_ref.detach_cb()); + }); + + nvim_client.set_nvim(nvim); + } +} + #[inline] fn get_model_clip(state: &State, line_height: f64, @@ -711,17 +823,7 @@ fn update_font_description(desc: &mut FontDescription, attrs: &Attrs) { } } -fn calc_char_bounds(shell: &State, ctx: &cairo::Context) -> (i32, i32) { - let layout = ctx.create_pango_layout(); - - let desc = shell.create_pango_font(); - layout.set_font_description(Some(&desc)); - layout.set_text("A", -1); - - layout.get_pixel_size() -} - -fn request_window_resize(parent: &ui::Components, state: &mut State) { +fn request_window_resize(state: &mut State) { if !state.request_resize { return; } @@ -737,7 +839,12 @@ fn request_window_resize(parent: &ui::Components, state: &mut State) { let request_width = (state.model.columns as f64 * state.char_width.unwrap()) as i32; if width != request_width || height != request_height { - let window = parent.window(); + let window: gtk::Window = state + .drawing_area + .get_toplevel() + .unwrap() + .downcast() + .unwrap(); let (win_width, win_height) = window.get_size(); let h_border = win_width - width; let v_border = win_height - height; @@ -752,33 +859,31 @@ fn split_color(indexed_color: u64) -> Color { Color(r / 255.0, g / 255.0, b / 255.0) } -fn gtk_configure_event(state: &Arc>, ev: &EventConfigure) -> bool { - let (width, height) = ev.get_size(); - +fn gtk_configure_event(state: &Arc>, _: &EventConfigure) -> bool { let mut state_ref = state.borrow_mut(); if let Some(timer) = state_ref.resize_timer { glib::source_remove(timer); } - if let Some(line_height) = state_ref.line_height { - if let Some(char_width) = state_ref.char_width { - let state = state.clone(); - state_ref.resize_timer = Some(glib::timeout_add(250, move || { - let mut state_ref = state.borrow_mut(); + if !state_ref.nvim.borrow().is_initialized() { + return false; + } - state_ref.resize_timer = None; + if let Some((columns, rows)) = state_ref.calc_nvim_size() { + let state = state.clone(); + state_ref.resize_timer = Some(glib::timeout_add(250, move || { + let mut state_ref = state.borrow_mut(); - let rows = (height as f64 / line_height).trunc() as usize; - let columns = (width as f64 / char_width).trunc() as usize; - if state_ref.model.rows != rows || state_ref.model.columns != columns { - if let Err(err) = state_ref.nvim().ui_try_resize(columns as u64, rows as u64) { - println!("Error trying resize nvim {}", err); - } + state_ref.resize_timer = None; + + if state_ref.model.rows != rows || state_ref.model.columns != columns { + if let Err(err) = state_ref.nvim().ui_try_resize(columns as u64, rows as u64) { + println!("Error trying resize nvim {}", err); } - Continue(false) - })); - } + } + Continue(false) + })); } false } @@ -889,13 +994,8 @@ impl RedrawEvents for State { RepaintMode::Nothing } - fn on_mode_change(&mut self, mode: &str) -> RepaintMode { - match mode { - "normal" => self.mode = NvimMode::Normal, - "insert" => self.mode = NvimMode::Insert, - _ => self.mode = NvimMode::Other, - } - + fn on_mode_change(&mut self, mode: &str, idx: u64) -> RepaintMode { + self.mode.update(mode, idx as usize); RepaintMode::Area(self.model.cur_point()) } @@ -947,13 +1047,20 @@ impl RedrawEvents for State { fn tabline_update(&mut self, selected: Tabpage, - tabs: Vec<(Tabpage, Option<&str>)>) + tabs: Vec<(Tabpage, Option)>) -> RepaintMode { - self.tabs - .update_tabs(&self.nvim.as_ref().unwrap(), &selected, &tabs); + self.tabs.update_tabs(&self.nvim, &selected, &tabs); RepaintMode::Nothing } + + fn mode_info_set(&mut self, + cursor_style_enabled: bool, + mode_info: Vec) + -> RepaintMode { + self.mode.set_info(cursor_style_enabled, mode_info); + RepaintMode::Nothing + } } impl GuiApi for State { diff --git a/src/tabline.rs b/src/tabline.rs index a587a4e..cea0304 100644 --- a/src/tabline.rs +++ b/src/tabline.rs @@ -7,15 +7,16 @@ use gtk::prelude::*; use glib::signal; -use neovim_lib::{Neovim, NeovimApi}; +use neovim_lib::NeovimApi; use neovim_lib::neovim_api::Tabpage; +use nvim; use nvim::ErrorReport; struct State { data: Vec, selected: Option, - nvim: Option>>, + nvim: Option>>, } impl State { @@ -31,7 +32,7 @@ impl State { let target = &self.data[idx as usize]; if Some(target) != self.selected.as_ref() { let mut nvim = self.nvim.as_ref().unwrap().borrow_mut(); - nvim.set_current_tabpage(&target).report_err(&mut *nvim); + nvim.set_current_tabpage(&target).report_err(&mut **nvim); } } } @@ -66,9 +67,9 @@ impl Tabline { } fn update_state(&self, - nvim: &Rc>, + nvim: &Rc>, selected: &Tabpage, - tabs: &Vec<(Tabpage, Option<&str>)>) { + tabs: &Vec<(Tabpage, Option)>) { let mut state = self.state.borrow_mut(); if state.nvim.is_none() { @@ -81,9 +82,9 @@ impl Tabline { } pub fn update_tabs(&self, - nvim: &Rc>, + nvim: &Rc>, selected: &Tabpage, - tabs: &Vec<(Tabpage, Option<&str>)>) { + tabs: &Vec<(Tabpage, Option)>) { if tabs.len() <= 1 { self.tabs.hide(); return; @@ -112,7 +113,7 @@ impl Tabline { for (idx, tab) in tabs.iter().enumerate() { let tab_child = self.tabs.get_nth_page(Some(idx as u32)); self.tabs - .set_tab_label_text(&tab_child.unwrap(), &tab.1.unwrap_or("??")); + .set_tab_label_text(&tab_child.unwrap(), &tab.1.as_ref().unwrap_or(&"??".to_owned())); if *selected == tab.0 { self.tabs.set_current_page(Some(idx as u32)); diff --git a/src/ui.rs b/src/ui.rs index 300cd54..cd56965 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -10,10 +10,9 @@ use gtk::ApplicationExt; use gtk::{ApplicationWindow, HeaderBar, ToolButton, Image, AboutDialog}; use gio::prelude::*; use gio::{Menu, MenuExt, MenuItem, MenuItemExt, SimpleAction}; -use glib; use settings::Settings; -use shell::Shell; +use shell::{Shell, ShellOptions}; use shell_dlg; use project::Projects; @@ -53,10 +52,10 @@ impl Components { } impl Ui { - pub fn new() -> Ui { + pub fn new(options: ShellOptions) -> Ui { let comps = Arc::new(UiMutex::new(Components::new())); let settings = Rc::new(RefCell::new(Settings::new())); - let shell = Rc::new(RefCell::new(Shell::new(settings.clone(), &comps))); + let shell = Rc::new(RefCell::new(Shell::new(settings.clone(), options))); settings.borrow_mut().set_shell(Rc::downgrade(&shell)); let projects = Projects::new(&comps.borrow().open_btn, shell.clone()); @@ -70,10 +69,7 @@ impl Ui { } } - pub fn init(&mut self, - app: >k::Application, - nvim_bin_path: Option<&String>, - open_path: Option<&str>) { + pub fn init(&mut self, app: >k::Application) { if self.initialized { return; } @@ -91,7 +87,9 @@ impl Ui { let projects = self.projects.clone(); comps.header_bar.pack_start(&comps.open_btn); - comps.open_btn.connect_clicked(move |_| projects.borrow_mut().show()); + comps + .open_btn + .connect_clicked(move |_| projects.borrow_mut().show()); let save_image = Image::new_from_icon_name("document-save", gtk_sys::GTK_ICON_SIZE_SMALL_TOOLBAR as i32); @@ -114,40 +112,28 @@ impl Ui { let window = comps.window.as_ref().unwrap(); window.set_titlebar(Some(&comps.header_bar)); + window.set_default_size(800, 600); - let mut shell = self.shell.borrow_mut(); + let shell = self.shell.borrow(); window.add(&**shell); window.show_all(); - window.set_title("Neovim-gtk"); + window.set_title("NeoVim-gtk"); let comps_ref = self.comps.clone(); let shell_ref = self.shell.clone(); window.connect_delete_event(move |_, _| gtk_delete(&*comps_ref, &*shell_ref)); - shell.add_configure_event(); - shell.init_nvim(nvim_bin_path); shell.grab_focus(); - if open_path.is_some() { - shell.open_file(open_path.unwrap()); - } - - self.guard_dispatch_thread(&mut shell); - } - - fn guard_dispatch_thread(&self, shell: &mut Shell) { - let state = shell.state.borrow(); - let guard = state.nvim().session.take_dispatch_guard(); - - let comps = self.comps.clone(); - thread::spawn(move || { - guard.join().expect("Can't join dispatch thread"); - glib::idle_add(move || { - comps.borrow().close_window(); - glib::Continue(false) - }); - }); + let comps_ref = self.comps.clone(); + shell.set_detach_cb(Some(move || { + let comps_ref = comps_ref.clone(); + gtk::idle_add(move || { + comps_ref.borrow().close_window(); + Continue(false) + }); + })); } fn create_main_menu(&self, app: >k::Application) { @@ -181,6 +167,10 @@ fn on_help_about(comps: &Components) { } fn gtk_delete(comps: &UiMutex, shell: &RefCell) -> Inhibit { + if !shell.borrow().is_nvim_initialized() { + return Inhibit(false); + } + Inhibit(if shell_dlg::can_close_window(comps, shell) { let comps = comps.borrow(); comps.close_window(); diff --git a/src/value.rs b/src/value.rs new file mode 100644 index 0000000..f74e7a1 --- /dev/null +++ b/src/value.rs @@ -0,0 +1,20 @@ +use std::collections::HashMap; +use neovim_lib::Value; + +pub trait ValueMapExt { + fn to_attrs_map(&self) -> Result, String>; +} + +impl ValueMapExt for Vec<(Value, Value)> { + fn to_attrs_map(&self) -> Result, String> { + self.iter() + .map(|p| { + p.0 + .as_str() + .ok_or("Can't convert map key to string".to_owned()) + .map(|key| (key, p.1.clone())) + }) + .collect::, String>>() + + } +}