Merge branch 'master' into imcontext

This commit is contained in:
daa84 2017-07-11 12:33:55 +03:00
commit 0987518b58
14 changed files with 879 additions and 360 deletions

230
Cargo.lock generated
View File

@ -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)" = "<none>"
"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)" = "<none>"
"checksum cairo-sys-rs 0.3.4 (git+https://github.com/gtk-rs/cairo)" = "<none>"
"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)" = "<none>"
"checksum gdk-pixbuf 0.1.3 (git+https://github.com/gtk-rs/gdk-pixbuf)" = "<none>"
"checksum gdk-pixbuf-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "<none>"
@ -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)" = "<none>"
"checksum gtk-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "<none>"
"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)" = "<none>"
"checksum pango-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "<none>"
"checksum pangocairo 0.1.3 (git+https://github.com/RazrFalcon/pangocairo-rs)" = "<none>"
@ -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"

View File

@ -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/

View File

@ -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"

View File

@ -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<UiMutex<State>>) -> 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);
}
}

52
src/error.rs Normal file
View File

@ -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!("<big>Can't start nvim instance:</big>\n\
<i>{}</i>\n\
<span foreground=\"red\"><i>{}</i></span>\n\n\
<big>Possible error reasons:</big>\n\
&#9679; Not supported nvim version (minimum supported version is <b>{}</b>)\n\
&#9679; Error in configuration file (init.vim or ginit.vim)\n\
&#9679; Wrong nvim binary path \
(right path can be passed with <i>--nvim-bin-path=path_here</i>)",
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) -> &gtk::Box {
&self.base
}
}

View File

@ -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: &gtk::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: &gtk::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<I>(args: I) -> Option<String>

52
src/mode.rs Normal file
View File

@ -0,0 +1,52 @@
use nvim;
#[derive(PartialEq)]
pub enum NvimMode {
Normal,
Insert,
Other,
}
pub struct Mode {
mode: NvimMode,
idx: usize,
info: Option<Vec<nvim::ModeInfo>>,
}
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<nvim::ModeInfo>) {
self.info = if cursor_style_enabled {
Some(info)
} else {
None
};
}
}

View File

@ -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<String>)>)
-> RepaintMode;
fn mode_info_set(&mut self,
cursor_style_enabled: bool,
mode_info: Vec<ModeInfo>)
-> 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::<Result<Vec<_>, _>>())
);
($arg:expr, $err:expr, |$item:ident| {$exp:expr}) => (
$arg.as_array()
.ok_or($err)
.and_then(|items| items.iter().map(|$item| {
$exp
}).collect::<Result<Vec<_>, _>>())
);
}
#[derive(Debug, Clone)]
pub enum CursorShape {
Block,
Horizontal,
Vertical,
Unknown,
}
impl CursorShape {
fn new(shape_code: &Value) -> Result<CursorShape, String> {
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<CursorShape>,
cell_percentage: Option<u64>,
}
impl ModeInfo {
pub fn new(mode_info_arr: &Vec<(Value, Value)>) -> Result<Self, String> {
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<error::Error>,
cmd: String,
}
impl NvimInitError {
pub fn new<E>(cmd: &Command, error: E) -> NvimInitError
where E: Into<Box<error::Error>>
{
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<UiMutex<shell::State>>,
nvim_bin_path: Option<&String>)
-> Result<Neovim> {
nvim_bin_path: Option<&String>,
cols: u64,
rows: u64)
-> result::Result<Neovim, NvimInitError> {
let mut cmd = if let Some(path) = nvim_bin_path {
Command::new(path)
} else {
@ -106,10 +242,7 @@ pub fn initialize(shell: Arc<UiMutex<shell::State>>,
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<UiMutex<shell::State>>,
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<Vec<_>, &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::*;

View File

@ -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<Rc<RefCell<Neovim>>>,
nvim: Option<Rc<RefCell<nvim::NeovimClient>>>,
renderer: gtk::CellRendererText,
tree: gtk::TreeView,
scroll: gtk::ScrolledWindow,

View File

@ -1,8 +1,6 @@
use std::rc::{Rc, Weak};
use std::cell::RefCell;
use gio::SettingsExt;
#[cfg(unix)]
use nvim::RepaintMode;

View File

@ -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<Attrs>,
pub mode: NvimMode,
mouse_enabled: bool,
nvim: Option<Rc<RefCell<Neovim>>>,
nvim: Rc<RefCell<NeovimClient>>,
font_desc: FontDescription,
cursor: Option<Cursor>,
popup_menu: RefCell<PopupMenu>,
settings: Rc<RefCell<Settings>>,
pub mode: mode::Mode,
stack: gtk::Stack,
drawing_area: gtk::DrawingArea,
tabs: Tabline,
im_context: gtk::IMMulticontext,
error_area: error::ErrorArea,
line_height: Option<f64>,
char_width: Option<f64>,
request_resize: bool,
resize_timer: Option<glib::SourceId>,
parent: sync::Weak<UiMutex<ui::Components>>,
options: ShellOptions,
detach_cb: Option<Box<RefCell<FnMut() + Send + 'static>>>,
}
impl State {
pub fn new(settings: Rc<RefCell<Settings>>, parent: &Arc<UiMutex<ui::Components>>) -> State {
pub fn new(settings: Rc<RefCell<Settings>>, 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<Neovim> {
self.nvim.as_ref().unwrap().borrow_mut()
RefMut::map(self.nvim.borrow_mut(), |n| n.nvim_mut())
}
pub fn nvim_clone(&self) -> Rc<RefCell<Neovim>> {
self.nvim.as_ref().unwrap().clone()
pub fn nvim_clone(&self) -> Rc<RefCell<NeovimClient>> {
self.nvim.clone()
}
pub fn set_detach_cb<F>(&mut self, cb: Option<F>)
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<String>,
open_path: Option<String>,
}
impl ShellOptions {
pub fn new(nvim_bin_path: Option<String>, open_path: Option<String>) -> Self {
ShellOptions {
nvim_bin_path,
open_path,
}
}
}
pub struct Shell {
pub state: Arc<UiMutex<State>>,
ui_state: Rc<RefCell<UiState>>,
@ -210,9 +279,9 @@ pub struct Shell {
}
impl Shell {
pub fn new(settings: Rc<RefCell<Settings>>, parent: &Arc<UiMutex<ui::Components>>) -> Shell {
pub fn new(settings: Rc<RefCell<Settings>>, 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 {
"<Esc>\"*pa"
@ -406,6 +470,13 @@ impl Shell {
let mut nvim = &mut *state.nvim();
nvim.command(":wa").report_err(nvim);
}
pub fn set_detach_cb<F>(&self, cb: Option<F>)
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<UiMutex<State>>, 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<UiMutex<State>>, 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<UiMutex<State>>) {
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<UiMutex<State>>, ev: &EventConfigure) -> bool {
let (width, height) = ev.get_size();
fn gtk_configure_event(state: &Arc<UiMutex<State>>, _: &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<String>)>)
-> 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<nvim::ModeInfo>)
-> RepaintMode {
self.mode.set_info(cursor_style_enabled, mode_info);
RepaintMode::Nothing
}
}
impl GuiApi for State {

View File

@ -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<Tabpage>,
selected: Option<Tabpage>,
nvim: Option<Rc<RefCell<Neovim>>>,
nvim: Option<Rc<RefCell<nvim::NeovimClient>>>,
}
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<RefCell<Neovim>>,
nvim: &Rc<RefCell<nvim::NeovimClient>>,
selected: &Tabpage,
tabs: &Vec<(Tabpage, Option<&str>)>) {
tabs: &Vec<(Tabpage, Option<String>)>) {
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<RefCell<Neovim>>,
nvim: &Rc<RefCell<nvim::NeovimClient>>,
selected: &Tabpage,
tabs: &Vec<(Tabpage, Option<&str>)>) {
tabs: &Vec<(Tabpage, Option<String>)>) {
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));

View File

@ -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: &gtk::Application,
nvim_bin_path: Option<&String>,
open_path: Option<&str>) {
pub fn init(&mut self, app: &gtk::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: &gtk::Application) {
@ -181,6 +167,10 @@ fn on_help_about(comps: &Components) {
}
fn gtk_delete(comps: &UiMutex<Components>, shell: &RefCell<Shell>) -> 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();

20
src/value.rs Normal file
View File

@ -0,0 +1,20 @@
use std::collections::HashMap;
use neovim_lib::Value;
pub trait ValueMapExt {
fn to_attrs_map(&self) -> Result<HashMap<&str, Value>, String>;
}
impl ValueMapExt for Vec<(Value, Value)> {
fn to_attrs_map(&self) -> Result<HashMap<&str, Value>, 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::<Result<HashMap<&str, Value>, String>>()
}
}