Implement Rich text on Windows
This commit is contained in:
		
							parent
							
								
									50f1fe9f19
								
							
						
					
					
						commit
						185d06e8e9
					
				
							
								
								
									
										209
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										209
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -380,10 +380,12 @@ dependencies = [
 | 
			
		|||
 "dialoguer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "html2text 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "log-panics 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "markdown 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "named_pipe 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
| 
						 | 
				
			
			@ -505,6 +507,15 @@ name = "fuchsia-zircon-sys"
 | 
			
		|||
version = "0.3.3"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "futf"
 | 
			
		||||
version = "0.1.4"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "new_debug_unreachable 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "futures"
 | 
			
		||||
version = "0.1.29"
 | 
			
		||||
| 
						 | 
				
			
			@ -546,6 +557,29 @@ dependencies = [
 | 
			
		|||
 "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "html2text"
 | 
			
		||||
version = "0.2.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "html5ever 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "markup5ever_rcdom 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "html5ever"
 | 
			
		||||
version = "0.25.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "markup5ever 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "http"
 | 
			
		||||
version = "0.1.18"
 | 
			
		||||
| 
						 | 
				
			
			@ -725,6 +759,48 @@ dependencies = [
 | 
			
		|||
 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "mac"
 | 
			
		||||
version = "0.1.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "markdown"
 | 
			
		||||
version = "0.3.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "pipeline 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "markup5ever"
 | 
			
		||||
version = "0.10.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "phf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "phf_codegen 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "string_cache 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "string_cache_codegen 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "tendril 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "markup5ever_rcdom"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "html5ever 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "markup5ever 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "tendril 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "xml5ever 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "matches"
 | 
			
		||||
version = "0.1.8"
 | 
			
		||||
| 
						 | 
				
			
			@ -839,6 +915,11 @@ dependencies = [
 | 
			
		|||
 "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "new_debug_unreachable"
 | 
			
		||||
version = "1.0.4"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "nodrop"
 | 
			
		||||
version = "0.1.13"
 | 
			
		||||
| 
						 | 
				
			
			@ -955,6 +1036,45 @@ name = "percent-encoding"
 | 
			
		|||
version = "2.1.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "phf"
 | 
			
		||||
version = "0.8.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "phf_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "phf_codegen"
 | 
			
		||||
version = "0.8.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "phf_generator 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "phf_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "phf_generator"
 | 
			
		||||
version = "0.8.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "phf_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "phf_shared"
 | 
			
		||||
version = "0.8.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "siphasher 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "pipeline"
 | 
			
		||||
version = "0.5.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "pkg-config"
 | 
			
		||||
version = "0.3.16"
 | 
			
		||||
| 
						 | 
				
			
			@ -970,6 +1090,11 @@ name = "ppv-lite86"
 | 
			
		|||
version = "0.2.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "precomputed-hash"
 | 
			
		||||
version = "0.1.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "proc-macro2"
 | 
			
		||||
version = "0.4.30"
 | 
			
		||||
| 
						 | 
				
			
			@ -1042,6 +1167,7 @@ dependencies = [
 | 
			
		|||
 "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
| 
						 | 
				
			
			@ -1139,6 +1265,14 @@ dependencies = [
 | 
			
		|||
 "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "rand_pcg"
 | 
			
		||||
version = "0.2.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "rand_xorshift"
 | 
			
		||||
version = "0.1.1"
 | 
			
		||||
| 
						 | 
				
			
			@ -1393,6 +1527,11 @@ dependencies = [
 | 
			
		|||
 "term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "siphasher"
 | 
			
		||||
version = "0.3.3"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "slab"
 | 
			
		||||
version = "0.4.2"
 | 
			
		||||
| 
						 | 
				
			
			@ -1416,6 +1555,29 @@ dependencies = [
 | 
			
		|||
 "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "string_cache"
 | 
			
		||||
version = "0.8.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "new_debug_unreachable 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "phf_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "string_cache_codegen"
 | 
			
		||||
version = "0.5.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "phf_generator 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "phf_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "strsim"
 | 
			
		||||
version = "0.8.0"
 | 
			
		||||
| 
						 | 
				
			
			@ -1465,6 +1627,16 @@ dependencies = [
 | 
			
		|||
 "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "tendril"
 | 
			
		||||
version = "0.4.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "utf-8 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "term"
 | 
			
		||||
version = "0.6.1"
 | 
			
		||||
| 
						 | 
				
			
			@ -1703,6 +1875,11 @@ dependencies = [
 | 
			
		|||
 "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "utf-8"
 | 
			
		||||
version = "0.7.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "uuid"
 | 
			
		||||
version = "0.7.4"
 | 
			
		||||
| 
						 | 
				
			
			@ -1810,6 +1987,17 @@ dependencies = [
 | 
			
		|||
 "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "xml5ever"
 | 
			
		||||
version = "0.16.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "markup5ever 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "yaml-rust"
 | 
			
		||||
version = "0.4.3"
 | 
			
		||||
| 
						 | 
				
			
			@ -1888,10 +2076,13 @@ dependencies = [
 | 
			
		|||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
 | 
			
		||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
 | 
			
		||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 | 
			
		||||
"checksum futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b"
 | 
			
		||||
"checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
 | 
			
		||||
"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
 | 
			
		||||
"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571"
 | 
			
		||||
"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
 | 
			
		||||
"checksum html2text 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a26379dcb715e237b96102a12b505c553e2bffa74bae2e54658748d298660ef1"
 | 
			
		||||
"checksum html5ever 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b"
 | 
			
		||||
"checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4"
 | 
			
		||||
"checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
 | 
			
		||||
"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
 | 
			
		||||
| 
						 | 
				
			
			@ -1912,6 +2103,10 @@ dependencies = [
 | 
			
		|||
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
 | 
			
		||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
 | 
			
		||||
"checksum log-panics 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ae0136257df209261daa18d6c16394757c63e032e27aafd8b07788b051082bef"
 | 
			
		||||
"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
 | 
			
		||||
"checksum markdown 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef3aab6a1d529b112695f72beec5ee80e729cb45af58663ec902c8fac764ecdd"
 | 
			
		||||
"checksum markup5ever 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aae38d669396ca9b707bfc3db254bc382ddb94f57cc5c235f34623a669a01dab"
 | 
			
		||||
"checksum markup5ever_rcdom 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f015da43bcd8d4f144559a3423f4591d69b8ce0652c905374da7205df336ae2b"
 | 
			
		||||
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
 | 
			
		||||
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
 | 
			
		||||
"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
 | 
			
		||||
| 
						 | 
				
			
			@ -1924,6 +2119,7 @@ dependencies = [
 | 
			
		|||
"checksum named_pipe 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad9c443cce91fc3e12f017290db75dde490d685cdaaf508d7159d7cf41f0eb2b"
 | 
			
		||||
"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"
 | 
			
		||||
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
 | 
			
		||||
"checksum new_debug_unreachable 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
 | 
			
		||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
 | 
			
		||||
"checksum notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd"
 | 
			
		||||
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
 | 
			
		||||
| 
						 | 
				
			
			@ -1937,9 +2133,15 @@ dependencies = [
 | 
			
		|||
"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
 | 
			
		||||
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
 | 
			
		||||
"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
 | 
			
		||||
"checksum phf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
 | 
			
		||||
"checksum phf_codegen 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815"
 | 
			
		||||
"checksum phf_generator 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
 | 
			
		||||
"checksum phf_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
 | 
			
		||||
"checksum pipeline 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d15b6607fa632996eb8a17c9041cb6071cb75ac057abd45dece578723ea8c7c0"
 | 
			
		||||
"checksum pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "72d5370d90f49f70bd033c3d75e87fc529fbfff9d6f7cccef07d6170079d91ea"
 | 
			
		||||
"checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd"
 | 
			
		||||
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
 | 
			
		||||
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 | 
			
		||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
 | 
			
		||||
"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95"
 | 
			
		||||
"checksum publicsuffix 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9bf259a81de2b2eb9850ec990ec78e6a25319715584fd7652b9b26f96fcb1510"
 | 
			
		||||
| 
						 | 
				
			
			@ -1958,6 +2160,7 @@ dependencies = [
 | 
			
		|||
"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
 | 
			
		||||
"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
 | 
			
		||||
"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
 | 
			
		||||
"checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
 | 
			
		||||
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
 | 
			
		||||
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
 | 
			
		||||
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
 | 
			
		||||
| 
						 | 
				
			
			@ -1986,15 +2189,19 @@ dependencies = [
 | 
			
		|||
"checksum signal-hook 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff2db2112d6c761e12522c65f7768548bd6e8cd23d2a9dae162520626629bd6"
 | 
			
		||||
"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41"
 | 
			
		||||
"checksum simplelog 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe8c881061cce7ee205784634eda7a61922925e7cc2833188467d3a560e027"
 | 
			
		||||
"checksum siphasher 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
 | 
			
		||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
 | 
			
		||||
"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
 | 
			
		||||
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
 | 
			
		||||
"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
 | 
			
		||||
"checksum string_cache 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2940c75beb4e3bf3a494cef919a747a2cb81e52571e212bfbd185074add7208a"
 | 
			
		||||
"checksum string_cache_codegen 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97"
 | 
			
		||||
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
 | 
			
		||||
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
 | 
			
		||||
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
 | 
			
		||||
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
 | 
			
		||||
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
 | 
			
		||||
"checksum tendril 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "707feda9f2582d5d680d733e38755547a3e8fb471e7ba11452ecfd9ce93a5d3b"
 | 
			
		||||
"checksum term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5"
 | 
			
		||||
"checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625"
 | 
			
		||||
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
 | 
			
		||||
| 
						 | 
				
			
			@ -2020,6 +2227,7 @@ dependencies = [
 | 
			
		|||
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
 | 
			
		||||
"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
 | 
			
		||||
"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61"
 | 
			
		||||
"checksum utf-8 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
 | 
			
		||||
"checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
 | 
			
		||||
"checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95"
 | 
			
		||||
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
 | 
			
		||||
| 
						 | 
				
			
			@ -2036,5 +2244,6 @@ dependencies = [
 | 
			
		|||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 | 
			
		||||
"checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
 | 
			
		||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
 | 
			
		||||
"checksum xml5ever 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b1b52e6e8614d4a58b8e70cf51ec0cc21b256ad8206708bcff8139b5bbd6a59"
 | 
			
		||||
"checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d"
 | 
			
		||||
"checksum zip 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3c21bb410afa2bd823a047f5bda3adb62f51074ac7e06263b2c97ecdd47e9fc6"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,8 @@ dialoguer = "0.4.0"
 | 
			
		|||
rand = "0.7.2"
 | 
			
		||||
zip = "0.5.3"
 | 
			
		||||
notify = "4.0.13"
 | 
			
		||||
markdown = "0.3.0"
 | 
			
		||||
html2text = "0.2.1"
 | 
			
		||||
 | 
			
		||||
[target.'cfg(unix)'.dependencies]
 | 
			
		||||
libc = "0.2.62"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -898,3 +898,37 @@ int32_t set_clipboard_image(wchar_t *path) {
 | 
			
		|||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Inspired by https://docs.microsoft.com/en-za/troubleshoot/cpp/add-html-code-clipboard
 | 
			
		||||
int32_t set_clipboard_html(char * html, wchar_t * text_fallback) {
 | 
			
		||||
    // Get clipboard id for HTML format
 | 
			
		||||
    static int cfid = 0;
 | 
			
		||||
    if(!cfid) {
 | 
			
		||||
        cfid = RegisterClipboardFormat(L"HTML Format");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int32_t result = 0;
 | 
			
		||||
    const size_t html_len = strlen(html) + 1;
 | 
			
		||||
    HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, html_len * sizeof(char));
 | 
			
		||||
    memcpy(GlobalLock(hMem), html, html_len * sizeof(char));
 | 
			
		||||
    GlobalUnlock(hMem);
 | 
			
		||||
 | 
			
		||||
    const size_t fallback_len = wcslen(text_fallback) + 1;
 | 
			
		||||
    HGLOBAL hMemFallback =  GlobalAlloc(GMEM_MOVEABLE, fallback_len * sizeof(wchar_t));
 | 
			
		||||
    memcpy(GlobalLock(hMemFallback), text_fallback, fallback_len * sizeof(wchar_t));
 | 
			
		||||
    GlobalUnlock(hMemFallback);
 | 
			
		||||
 | 
			
		||||
    if (!OpenClipboard(NULL)) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    EmptyClipboard();
 | 
			
		||||
    if (!SetClipboardData(cfid, hMem)) {
 | 
			
		||||
        result = -2;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (!SetClipboardData(CF_UNICODETEXT, hMemFallback)) {
 | 
			
		||||
        result = -3;
 | 
			
		||||
    }
 | 
			
		||||
    CloseClipboard();
 | 
			
		||||
    GlobalFree(hMem);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -179,6 +179,13 @@ extern "C" int32_t set_clipboard(wchar_t * text);
 | 
			
		|||
 */
 | 
			
		||||
extern "C" int32_t set_clipboard_image(wchar_t * path);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Set clipboard HTML. Notice how in this case, text is not a wide char but instead
 | 
			
		||||
 * uses the UTF8 encoding.
 | 
			
		||||
 * Also set the text fallback, in case some applications don't support HTML clipboard.
 | 
			
		||||
 */
 | 
			
		||||
extern "C" int32_t set_clipboard_html(char * html, wchar_t * text_fallback);
 | 
			
		||||
 | 
			
		||||
// PROCESSES
 | 
			
		||||
 | 
			
		||||
extern "C" int32_t start_process(wchar_t * cmd);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@
 | 
			
		|||
 * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
use std::os::raw::c_void;
 | 
			
		||||
use std::os::raw::{c_char, c_void};
 | 
			
		||||
 | 
			
		||||
#[repr(C)]
 | 
			
		||||
pub struct WindowsMenuItem {
 | 
			
		||||
| 
						 | 
				
			
			@ -55,6 +55,7 @@ extern "C" {
 | 
			
		|||
    pub fn get_clipboard(buffer: *mut u16, size: i32) -> i32;
 | 
			
		||||
    pub fn set_clipboard(payload: *const u16) -> i32;
 | 
			
		||||
    pub fn set_clipboard_image(path: *const u16) -> i32;
 | 
			
		||||
    pub fn set_clipboard_html(html: *const c_char, text_fallback: *const u16) -> i32;
 | 
			
		||||
 | 
			
		||||
    // KEYBOARD
 | 
			
		||||
    pub fn register_keypress_callback(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,7 @@ pub trait ClipboardManager {
 | 
			
		|||
    fn get_clipboard(&self) -> Option<String>;
 | 
			
		||||
    fn set_clipboard(&self, payload: &str);
 | 
			
		||||
    fn set_clipboard_image(&self, image_path: &Path);
 | 
			
		||||
    fn set_clipboard_html(&self, html: &str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LINUX IMPLEMENTATION
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,8 +17,10 @@
 | 
			
		|||
 * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
use crate::bridge::windows::{get_clipboard, set_clipboard, set_clipboard_image};
 | 
			
		||||
use std::path::Path;
 | 
			
		||||
use crate::bridge::windows::{
 | 
			
		||||
    get_clipboard, set_clipboard, set_clipboard_html, set_clipboard_image,
 | 
			
		||||
};
 | 
			
		||||
use std::{ffi::CString, path::Path};
 | 
			
		||||
use widestring::U16CString;
 | 
			
		||||
 | 
			
		||||
pub struct WindowsClipboardManager {}
 | 
			
		||||
| 
						 | 
				
			
			@ -60,4 +62,58 @@ impl super::ClipboardManager for WindowsClipboardManager {
 | 
			
		|||
            set_clipboard_image(payload_c.as_ptr());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn set_clipboard_html(&self, html: &str) {
 | 
			
		||||
        // In order to set the HTML clipboard, we have to create a prefix with a specific format
 | 
			
		||||
        // For more information, look here:
 | 
			
		||||
        // https://docs.microsoft.com/en-us/windows/win32/dataxchg/html-clipboard-format
 | 
			
		||||
        // https://docs.microsoft.com/en-za/troubleshoot/cpp/add-html-code-clipboard
 | 
			
		||||
        let mut tokens = Vec::new();
 | 
			
		||||
        tokens.push("Version:0.9");
 | 
			
		||||
        tokens.push("StartHTML:<<STR*#>");
 | 
			
		||||
        tokens.push("EndHTML:<<END*#>");
 | 
			
		||||
        tokens.push("StartFragment:<<SFG#*>");
 | 
			
		||||
        tokens.push("EndFragment:<<EFG#*>");
 | 
			
		||||
        tokens.push("<html>");
 | 
			
		||||
        tokens.push("<body>");
 | 
			
		||||
        let content = format!("<!--StartFragment-->{}<!--EndFragment-->", html);
 | 
			
		||||
        tokens.push(&content);
 | 
			
		||||
        tokens.push("</body>");
 | 
			
		||||
        tokens.push("</html>");
 | 
			
		||||
 | 
			
		||||
        let mut render = tokens.join("\r\n");
 | 
			
		||||
 | 
			
		||||
        // Now replace the placeholders with the actual positions
 | 
			
		||||
        render = render.replace(
 | 
			
		||||
            "<<STR*#>",
 | 
			
		||||
            &format!("{:0>8}", render.find("<html>").unwrap_or_default()),
 | 
			
		||||
        );
 | 
			
		||||
        render = render.replace("<<END*#>", &format!("{:0>8}", render.len()));
 | 
			
		||||
        render = render.replace(
 | 
			
		||||
            "<<SFG#*>",
 | 
			
		||||
            &format!(
 | 
			
		||||
                "{:0>8}",
 | 
			
		||||
                render.find("<!--StartFragment-->").unwrap_or_default()
 | 
			
		||||
                    + "<!--StartFragment-->".len()
 | 
			
		||||
            ),
 | 
			
		||||
        );
 | 
			
		||||
        render = render.replace(
 | 
			
		||||
            "<<EFG#*>",
 | 
			
		||||
            &format!(
 | 
			
		||||
                "{:0>8}",
 | 
			
		||||
                render.find("<!--EndFragment-->").unwrap_or_default()
 | 
			
		||||
            ),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // Render the text fallback for those applications that don't support HTML clipboard
 | 
			
		||||
        let decorator = html2text::render::text_renderer::TrivialDecorator::new();
 | 
			
		||||
        let text_fallback =
 | 
			
		||||
            html2text::from_read_with_decorator(html.as_bytes(), 1000000, decorator);
 | 
			
		||||
        unsafe {
 | 
			
		||||
            let payload_c =
 | 
			
		||||
                CString::new(render).expect("unable to create CString for html content");
 | 
			
		||||
            let payload_fallback_c = U16CString::from_str(text_fallback).unwrap();
 | 
			
		||||
            set_clipboard_html(payload_c.as_ptr(), payload_fallback_c.as_ptr());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -154,8 +154,14 @@ impl<
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn inject_text(&self, config: &Configs, target_string: &str, force_clipboard: bool) {
 | 
			
		||||
        let backend = if force_clipboard {
 | 
			
		||||
    fn inject_text(
 | 
			
		||||
        &self,
 | 
			
		||||
        config: &Configs,
 | 
			
		||||
        target_string: &str,
 | 
			
		||||
        force_clipboard: bool,
 | 
			
		||||
        is_html: bool,
 | 
			
		||||
    ) {
 | 
			
		||||
        let backend = if force_clipboard || is_html {
 | 
			
		||||
            &BackendType::Clipboard
 | 
			
		||||
        } else if config.backend == BackendType::Auto {
 | 
			
		||||
            if cfg!(target_os = "linux") {
 | 
			
		||||
| 
						 | 
				
			
			@ -188,7 +194,12 @@ impl<
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
            BackendType::Clipboard => {
 | 
			
		||||
                self.clipboard_manager.set_clipboard(&target_string);
 | 
			
		||||
                if !is_html {
 | 
			
		||||
                    self.clipboard_manager.set_clipboard(&target_string);
 | 
			
		||||
                } else {
 | 
			
		||||
                    self.clipboard_manager.set_clipboard_html(&target_string);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                self.keyboard_manager.trigger_paste(&config);
 | 
			
		||||
            }
 | 
			
		||||
            _ => {
 | 
			
		||||
| 
						 | 
				
			
			@ -270,10 +281,10 @@ impl<
 | 
			
		|||
                // clipboard content to restore it later.
 | 
			
		||||
                previous_clipboard_content = self.return_content_if_preserve_clipboard_is_enabled();
 | 
			
		||||
 | 
			
		||||
                self.inject_text(&config, &target_string, m.force_clipboard);
 | 
			
		||||
                self.inject_text(&config, &target_string, m.force_clipboard, m.is_html);
 | 
			
		||||
 | 
			
		||||
                // Disallow undo backspace if cursor positioning is used
 | 
			
		||||
                if cursor_rewind.is_none() {
 | 
			
		||||
                // Disallow undo backspace if cursor positioning is used or text is HTML
 | 
			
		||||
                if cursor_rewind.is_none() && !m.is_html {
 | 
			
		||||
                    expansion_data = Some((
 | 
			
		||||
                        m.triggers[trigger_offset].clone(),
 | 
			
		||||
                        target_string.chars().count() as i32,
 | 
			
		||||
| 
						 | 
				
			
			@ -350,7 +361,7 @@ impl<
 | 
			
		|||
            self.keyboard_manager
 | 
			
		||||
                .delete_string(&config, *injected_text_len - 1);
 | 
			
		||||
            // Restore previous text
 | 
			
		||||
            self.inject_text(&config, trigger_string, false);
 | 
			
		||||
            self.inject_text(&config, trigger_string, false, false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										19
									
								
								src/guard.rs
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/guard.rs
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,22 @@
 | 
			
		|||
/*
 | 
			
		||||
 * This file is part of espanso.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2020 Federico Terzi
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
use crate::config::Configs;
 | 
			
		||||
use log::debug;
 | 
			
		||||
use std::sync::atomic::Ordering::Release;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,9 +22,9 @@ use crate::event::{KeyEvent, KeyModifier};
 | 
			
		|||
use regex::{Captures, Regex};
 | 
			
		||||
use serde::{Deserialize, Deserializer, Serialize};
 | 
			
		||||
use serde_yaml::{Mapping, Value};
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
use std::fs;
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
use std::{borrow::Cow, collections::HashMap};
 | 
			
		||||
 | 
			
		||||
pub(crate) mod scrolling;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -36,6 +36,7 @@ pub struct Match {
 | 
			
		|||
    pub passive_only: bool,
 | 
			
		||||
    pub propagate_case: bool,
 | 
			
		||||
    pub force_clipboard: bool,
 | 
			
		||||
    pub is_html: bool,
 | 
			
		||||
 | 
			
		||||
    // Automatically calculated from the triggers, used by the matcher to check for correspondences.
 | 
			
		||||
    #[serde(skip_serializing)]
 | 
			
		||||
| 
						 | 
				
			
			@ -132,15 +133,36 @@ impl<'a> From<&'a AutoMatch> for Match {
 | 
			
		|||
            })
 | 
			
		||||
            .collect();
 | 
			
		||||
 | 
			
		||||
        let content = if let Some(replace) = &other.replace {
 | 
			
		||||
            // Text match
 | 
			
		||||
            let new_replace = replace.clone();
 | 
			
		||||
        let (text_content, is_html) = if let Some(replace) = &other.replace {
 | 
			
		||||
            (Some(Cow::from(replace)), false)
 | 
			
		||||
        } else if let Some(markdown_str) = &other.markdown {
 | 
			
		||||
            // Render the markdown into HTML
 | 
			
		||||
            let mut html = markdown::to_html(markdown_str);
 | 
			
		||||
            html = html.trim().to_owned();
 | 
			
		||||
 | 
			
		||||
            if !other.paragraph {
 | 
			
		||||
                // Remove the surrounding paragraph
 | 
			
		||||
                if html.starts_with("<p>") {
 | 
			
		||||
                    html = html.trim_start_matches("<p>").to_owned();
 | 
			
		||||
                }
 | 
			
		||||
                if html.ends_with("</p>") {
 | 
			
		||||
                    html = html.trim_end_matches("</p>").to_owned();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            (Some(Cow::from(html)), true)
 | 
			
		||||
        } else if let Some(html) = &other.html {
 | 
			
		||||
            (Some(Cow::from(html)), true)
 | 
			
		||||
        } else {
 | 
			
		||||
            (None, false)
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let content = if let Some(content) = text_content {
 | 
			
		||||
            // Check if the match contains variables
 | 
			
		||||
            let has_vars = VAR_REGEX.is_match(replace);
 | 
			
		||||
            let has_vars = VAR_REGEX.is_match(&content);
 | 
			
		||||
 | 
			
		||||
            let content = TextContent {
 | 
			
		||||
                replace: new_replace,
 | 
			
		||||
                replace: content.to_string(),
 | 
			
		||||
                vars: other.vars.clone(),
 | 
			
		||||
                _has_vars: has_vars,
 | 
			
		||||
            };
 | 
			
		||||
| 
						 | 
				
			
			@ -208,7 +230,7 @@ impl<'a> From<&'a AutoMatch> for Match {
 | 
			
		|||
 | 
			
		||||
            MatchContentType::Image(content)
 | 
			
		||||
        } else {
 | 
			
		||||
            eprintln!("ERROR: no action specified for match {}, please specify either 'replace', 'image_path' or 'form'", other.trigger);
 | 
			
		||||
            eprintln!("ERROR: no action specified for match {}, please specify either 'replace', 'markdown', 'html', image_path' or 'form'", other.trigger);
 | 
			
		||||
            std::process::exit(2);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -220,6 +242,7 @@ impl<'a> From<&'a AutoMatch> for Match {
 | 
			
		|||
            _trigger_sequences: trigger_sequences,
 | 
			
		||||
            propagate_case: other.propagate_case,
 | 
			
		||||
            force_clipboard: other.force_clipboard,
 | 
			
		||||
            is_html,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -259,6 +282,15 @@ struct AutoMatch {
 | 
			
		|||
 | 
			
		||||
    #[serde(default = "default_force_clipboard")]
 | 
			
		||||
    pub force_clipboard: bool,
 | 
			
		||||
 | 
			
		||||
    #[serde(default = "default_markdown")]
 | 
			
		||||
    pub markdown: Option<String>,
 | 
			
		||||
 | 
			
		||||
    #[serde(default = "default_paragraph")]
 | 
			
		||||
    pub paragraph: bool,
 | 
			
		||||
 | 
			
		||||
    #[serde(default = "default_html")]
 | 
			
		||||
    pub html: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn default_trigger() -> String {
 | 
			
		||||
| 
						 | 
				
			
			@ -294,6 +326,15 @@ fn default_propagate_case() -> bool {
 | 
			
		|||
fn default_force_clipboard() -> bool {
 | 
			
		||||
    false
 | 
			
		||||
}
 | 
			
		||||
fn default_markdown() -> Option<String> {
 | 
			
		||||
    None
 | 
			
		||||
}
 | 
			
		||||
fn default_paragraph() -> bool {
 | 
			
		||||
    true
 | 
			
		||||
}
 | 
			
		||||
fn default_html() -> Option<String> {
 | 
			
		||||
    None
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
 | 
			
		||||
pub struct MatchVariable {
 | 
			
		||||
| 
						 | 
				
			
			@ -663,4 +704,95 @@ mod tests {
 | 
			
		|||
            _ => panic!("wrong content"),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_match_markdown_loaded_correctly() {
 | 
			
		||||
        let match_str = r###"
 | 
			
		||||
        trigger: ":test"
 | 
			
		||||
        markdown: "This *text* is **very bold**"
 | 
			
		||||
        "###;
 | 
			
		||||
 | 
			
		||||
        let _match: Match = serde_yaml::from_str(match_str).unwrap();
 | 
			
		||||
 | 
			
		||||
        match _match.content {
 | 
			
		||||
            MatchContentType::Text(content) => {
 | 
			
		||||
                assert_eq!(
 | 
			
		||||
                    content.replace,
 | 
			
		||||
                    "This <em>text</em> is <strong>very bold</strong>"
 | 
			
		||||
                );
 | 
			
		||||
                assert_eq!(_match.is_html, true);
 | 
			
		||||
            }
 | 
			
		||||
            _ => {
 | 
			
		||||
                assert!(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_match_markdown_keep_vars() {
 | 
			
		||||
        let match_str = r###"
 | 
			
		||||
        trigger: ":test"
 | 
			
		||||
        markdown: "This *text* is {{variable}} **very bold**"
 | 
			
		||||
        "###;
 | 
			
		||||
 | 
			
		||||
        let _match: Match = serde_yaml::from_str(match_str).unwrap();
 | 
			
		||||
 | 
			
		||||
        match _match.content {
 | 
			
		||||
            MatchContentType::Text(content) => {
 | 
			
		||||
                assert_eq!(
 | 
			
		||||
                    content.replace,
 | 
			
		||||
                    "This <em>text</em> is {{variable}} <strong>very bold</strong>"
 | 
			
		||||
                );
 | 
			
		||||
                assert_eq!(_match.is_html, true);
 | 
			
		||||
                assert_eq!(content._has_vars, true);
 | 
			
		||||
            }
 | 
			
		||||
            _ => {
 | 
			
		||||
                assert!(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_match_html_loaded_correctly() {
 | 
			
		||||
        let match_str = r###"
 | 
			
		||||
        trigger: ":test"
 | 
			
		||||
        html: "This <i>text<i> is <b>very bold</b>"
 | 
			
		||||
        "###;
 | 
			
		||||
 | 
			
		||||
        let _match: Match = serde_yaml::from_str(match_str).unwrap();
 | 
			
		||||
 | 
			
		||||
        match _match.content {
 | 
			
		||||
            MatchContentType::Text(content) => {
 | 
			
		||||
                assert_eq!(content.replace, "This <i>text<i> is <b>very bold</b>");
 | 
			
		||||
                assert_eq!(_match.is_html, true);
 | 
			
		||||
            }
 | 
			
		||||
            _ => {
 | 
			
		||||
                assert!(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_match_html_keep_vars() {
 | 
			
		||||
        let match_str = r###"
 | 
			
		||||
        trigger: ":test"
 | 
			
		||||
        html: "This <i>text<i> is {{var}} <b>very bold</b>"
 | 
			
		||||
        "###;
 | 
			
		||||
 | 
			
		||||
        let _match: Match = serde_yaml::from_str(match_str).unwrap();
 | 
			
		||||
 | 
			
		||||
        match _match.content {
 | 
			
		||||
            MatchContentType::Text(content) => {
 | 
			
		||||
                assert_eq!(
 | 
			
		||||
                    content.replace,
 | 
			
		||||
                    "This <i>text<i> is {{var}} <b>very bold</b>"
 | 
			
		||||
                );
 | 
			
		||||
                assert_eq!(_match.is_html, true);
 | 
			
		||||
                assert_eq!(content._has_vars, true);
 | 
			
		||||
            }
 | 
			
		||||
            _ => {
 | 
			
		||||
                assert!(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,22 @@
 | 
			
		|||
/*
 | 
			
		||||
 * This file is part of espanso.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2020 Federico Terzi
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
use log::debug;
 | 
			
		||||
use std::error::Error;
 | 
			
		||||
use std::io::{copy, Cursor};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,22 @@
 | 
			
		|||
/*
 | 
			
		||||
 * This file is part of espanso.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2020 Federico Terzi
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
use log::info;
 | 
			
		||||
use std::os::unix::fs::symlink;
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,22 @@
 | 
			
		|||
/*
 | 
			
		||||
 * This file is part of espanso.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2020 Federico Terzi
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
use crate::config::Configs;
 | 
			
		||||
use log::{error, info};
 | 
			
		||||
use std::io::{Error, Write};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user