aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <chrisduerr@users.noreply.github.com>2018-11-17 14:39:13 +0000
committerGitHub <noreply@github.com>2018-11-17 14:39:13 +0000
commit6265ef91d5496461fcd1025b21323982f3e47085 (patch)
treed8ab17aac3c2833d5bb231a5346504c227a242f1
parentea637cde1c82ad971078671aff087236f3fb0fbd (diff)
downloadalacritty-6265ef91d5496461fcd1025b21323982f3e47085.tar.gz
alacritty-6265ef91d5496461fcd1025b21323982f3e47085.zip
Display errors and warnings
To make sure that all error and information reporting to the user is unified, all instances of `print!`, `eprint!`, `println!` and `eprintln!` have been removed and replaced by logging. When `RUST_LOG` is not specified, the default Alacritty logger now also prints to both the stderr and a log file. The log file is only created when a message is written to it and its name is printed to stdout the first time it is used. Whenever a warning or an error has been written to the log file/stderr, a message is now displayed in Alacritty which points to the log file where the full error is documented. The message is cleared whenever the screen is cleared using either the `clear` command or the `Ctrl+L` key binding. To make sure that log files created by root don't prevent normal users from interacting with them, the Alacritty log file is `/tmp/Alacritty-$PID.log`. Since it's still possible that the log file can't be created, the UI error/warning message now informs the user if the message was only written to stderr. The reason why it couldn't be created is then printed to stderr. To make sure the deletion of the log file at runtime doesn't create any issues, the file is re-created if a write is attempted without the file being present. To help with debugging Alacritty issues, a timestamp and the error level are printed in all log messages. All log messages now follow this format: [YYYY-MM-DD HH:MM] [LEVEL] Message Since it's not unusual to spawn a lot of different terminal emulators without restarting, Alacritty can create a ton of different log files. To combat this problem, logfiles are removed by default after Alacritty has been closed. If the user wants to persist the log of a single session, the `--persistent_logging` option can be used. For persisting all log files, the `persistent_logging` option can be set in the configuration file
-rw-r--r--CHANGELOG.md4
-rw-r--r--Cargo.lock89
-rw-r--r--Cargo.toml3
-rw-r--r--alacritty-completions.bash2
-rw-r--r--alacritty-completions.fish3
-rw-r--r--alacritty-completions.zsh1
-rw-r--r--alacritty.man3
-rw-r--r--alacritty.yml3
-rw-r--r--alacritty_macos.yml3
-rw-r--r--alacritty_windows.yml3
-rw-r--r--build.rs8
-rw-r--r--src/ansi.rs6
-rw-r--r--src/cli.rs13
-rw-r--r--src/config.rs87
-rw-r--r--src/display.rs45
-rw-r--r--src/event.rs2
-rw-r--r--src/grid/tests.rs12
-rw-r--r--src/input.rs4
-rw-r--r--src/lib.rs1
-rw-r--r--src/logging.rs203
-rw-r--r--src/macros.rs28
-rw-r--r--src/main.rs35
-rw-r--r--src/renderer/mod.rs14
-rw-r--r--src/term/mod.rs14
24 files changed, 415 insertions, 171 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1c8cbbc8..5d3f2a8c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,6 +31,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- New `mouse.url.modifiers` option to specify keyboard modifiers for opening URLs on click
- Binaries for macOS, Windows and Debian-based systems are now published with GitHub releases
- The keys F16-F24 have been added as options for key bindings
+- Display notice about errors and warnings inside Alacritty
+- Log all messages to both stderr and a log file in the system's temporary directory
+- New configuration option `persistent_logging` and CLI flag `--persistent-logging`,
+ for keeping the log file after closing Alacritty
### Changed
diff --git a/Cargo.lock b/Cargo.lock
index b35f20ff..948fc8d5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -53,9 +53,10 @@ dependencies = [
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_yaml 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "static_assertions 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "static_assertions 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"terminfo 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"vte 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -73,7 +74,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"line_drawing 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rusttype 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rusttype 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -285,7 +286,7 @@ name = "cgl"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gleam 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gleam 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -616,7 +617,7 @@ dependencies = [
[[package]]
name = "encoding_rs"
-version = "0.8.10"
+version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -675,7 +676,7 @@ dependencies = [
[[package]]
name = "euclid"
-version = "0.19.2"
+version = "0.19.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -704,9 +705,9 @@ name = "failure_derive"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -742,7 +743,7 @@ dependencies = [
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 13.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.19.3 (registry+https://github.com/rust-lang/crates.io-index)",
"font-loader 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype-rs 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -880,7 +881,7 @@ dependencies = [
[[package]]
name = "gleam"
-version = "0.6.6"
+version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gl_generator 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1425,9 +1426,9 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1576,7 +1577,7 @@ dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1648,7 +1649,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
-version = "0.4.23"
+version = "0.4.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1669,7 +1670,7 @@ name = "quote"
version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1781,7 +1782,7 @@ name = "regex-syntax"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1789,7 +1790,7 @@ name = "regex-syntax"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1814,7 +1815,7 @@ version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "encoding_rs 0.8.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "encoding_rs 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1857,7 +1858,7 @@ dependencies = [
[[package]]
name = "rusttype"
-version = "0.7.2"
+version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"approx 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1951,9 +1952,9 @@ name = "serde_derive"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2040,7 +2041,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "smallvec"
-version = "0.6.5"
+version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2081,7 +2082,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "static_assertions"
-version = "0.3.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -2099,10 +2100,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
-version = "0.15.20"
+version = "0.15.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2112,9 +2113,9 @@ name = "synstructure"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2128,6 +2129,19 @@ dependencies = [
]
[[package]]
+name = "tempfile"
+version = "3.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "termcolor"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2390,7 +2404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ucd-util"
-version = "0.1.2"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -2824,13 +2838,13 @@ dependencies = [
"checksum dunce 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e86b07356baf1cc7058c95807ffba0bebe0c8cadd0df4c40b292c86194eabb37"
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
"checksum embed-resource 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "59edbe56442f96505f79c9116006f2e26c7f5655cccdc2c1546b2528c63bd612"
-"checksum encoding_rs 0.8.10 (registry+https://github.com/rust-lang/crates.io-index)" = "065f4d0c826fdaef059ac45487169d918558e3cf86c9d89f6e81cf52369126e5"
+"checksum encoding_rs 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5169856daf01399422d2cbaacdce579cd4f546c7a8481d3a4e926b313293ec56"
"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"
"checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e"
"checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e"
"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
-"checksum euclid 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4019b11e3498dd84d8893848c3d70e40c6dc71bb277ae5252cc16af006d06872"
+"checksum euclid 0.19.3 (registry+https://github.com/rust-lang/crates.io-index)" = "600657e7e5c03bfbccdc68721bc3b5abcb761553973387124eae9c9e4f02c210"
"checksum expat-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa"
"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
@@ -2852,7 +2866,7 @@ dependencies = [
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
"checksum gif 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4bca55ac1f213920ce3527ccd62386f1f15fa3f1714aeee1cf93f2c416903f"
"checksum gl_generator 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0ffaf173cf76c73a73e080366bf556b4776ece104b06961766ff11449f38604"
-"checksum gleam 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5d2f879e1548675cf46169cd7e770f6a6916f6263052fe4e6afc3b41bb7f63c"
+"checksum gleam 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bef810e31d619f5b77a7daea76a26ee50e63036637048a9f2128a33d5474141a"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum glutin 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "535c6eda58adbb227604b2db10a022ffd6339d7ea3e970f338e7d98aeb24fcc3"
"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83"
@@ -2937,7 +2951,7 @@ dependencies = [
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
"checksum png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f54b9600d584d3b8a739e1662a595fab051329eff43f20e7d8cc22872962145b"
"checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd"
-"checksum proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)" = "88dae56b29da695d783ea7fc5a90de281f79eb38407e77f6d674dd8befc4ac47"
+"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
@@ -2960,7 +2974,7 @@ dependencies = [
"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum rusttype 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "11ff03da02f6d340bbee5ec55eed03ff9abd6ea013b93bc7c35973cc28f65999"
-"checksum rusttype 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b8eb11f5b0a98c8eca2fb1483f42646d8c340e83e46ab416f8a063a0fd0eeb20"
+"checksum rusttype 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "436c67ae0d0d24f14e1177c3ed96780ee16db82b405f0fba1bb80b46c9a30625"
"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
@@ -2983,16 +2997,17 @@ dependencies = [
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"
-"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
+"checksum smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "622df2d454c29a4d89b30dc3b27b42d7d90d6b9e587dbf8f67652eb7514da484"
"checksum smithay-client-toolkit 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ef227bd9251cf8f8e54f8dd9a4b164307e515f5312cd632ebc87b56f723893a2"
"checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
-"checksum static_assertions 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab836ee18887baf9c5312314b25a4219a37c04a59ae1b5cbc199cea093e7e433"
+"checksum static_assertions 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "389ce475f424f267dbed6479cbd8f126c5e1afb053b0acdaa019c74305fc65d1"
"checksum stb_truetype 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "48fa7d3136d8645909de1f7c7eb5416cc43057a75ace08fc39ae736bc9da8af1"
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
-"checksum syn 0.15.20 (registry+https://github.com/rust-lang/crates.io-index)" = "8886c8d2774e853fcd7d9d2131f6e40ba46c9c0e358e4d57178452abd6859bb0"
+"checksum syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)" = "816b7af21405b011a23554ea2dc3f6576dc86ca557047c34098c1d741f10f823"
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
+"checksum tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "55c1195ef8513f3273d55ff59fe5da6940287a0d7a98331254397f464833675b"
"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
"checksum terminfo 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8e51065bafd2abe106b6036483b69d1741f4a1ec56ce8a2378de341637de689e"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
@@ -3016,7 +3031,7 @@ dependencies = [
"checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c"
"checksum tokio-uds 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df195376b43508f01570bacc73e13a1de0854dc59e79d1ec09913e8db6dd2a70"
"checksum try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2aa4715743892880f70885373966c83d73ef1b0838a664ef0c76fffd35e7c2"
-"checksum ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0f8bfa9ff0cadcd210129ad9d2c5f145c13e9ced3d3e5d948a6213487d52444"
+"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
"checksum unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3218ea14b4edcaccfa0df0a64a3792a2c32cc706f1b336e48867f9d3147f90"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
diff --git a/Cargo.toml b/Cargo.toml
index 07b34941..53d9c95c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -49,6 +49,7 @@ image = "0.20.1"
static_assertions = "0.3.0"
terminfo = "0.6.1"
url = "1.7.1"
+time = "0.1.40"
[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os="dragonfly", target_os="openbsd"))'.dependencies]
x11-dl = "2"
@@ -75,8 +76,8 @@ gl_generator = "0.10.0"
[target.'cfg(windows)'.build-dependencies]
embed-resource = "1.1.4"
+tempfile = "3.0.4"
reqwest = "0.8"
-tempdir = "0.3"
zip = "0.4"
[profile.release]
diff --git a/alacritty-completions.bash b/alacritty-completions.bash
index f8ffc107..48c683e8 100644
--- a/alacritty-completions.bash
+++ b/alacritty-completions.bash
@@ -11,7 +11,7 @@ _alacritty()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
prevprev="${COMP_WORDS[COMP_CWORD-2]}"
- opts="-h --help -V --version --live-config-reload --no-live-config-reload --print-events -q -qq -v -vv -vvv --ref-test -e --command --config-file -d --dimensions -t --title --working-directory"
+ opts="-h --help -V --version --live-config-reload --no-live-config-reload --persistent-logging --print-events -q -qq -v -vv -vvv --ref-test -e --command --config-file -d --dimensions -t --title --working-directory"
# If `--command` or `-e` is used, stop completing
for i in "${!COMP_WORDS[@]}"; do
diff --git a/alacritty-completions.fish b/alacritty-completions.fish
index 516c8ea9..6ffaef4b 100644
--- a/alacritty-completions.fish
+++ b/alacritty-completions.fish
@@ -16,6 +16,9 @@ complete -c alacritty \
-l "no-live-config-reload" \
-d "Disable automatic config reloading"
complete -c alacritty \
+ -l "persistent-logging" \
+ -d "Keep the log file after quitting Alacritty"
+complete -c alacritty \
-f \
-l "config-file" \
-d "Specify an alternative config file"
diff --git a/alacritty-completions.zsh b/alacritty-completions.zsh
index d2cc0eea..be7123a1 100644
--- a/alacritty-completions.zsh
+++ b/alacritty-completions.zsh
@@ -9,6 +9,7 @@ _alacritty() {
"(-V --version)"{-V,--version}"[Prints version information]" \
"(--no-live-config-reload)--live-config-reload[Enable automatic config reloading]" \
"(--live-config-reload)--no-live-config-reload[Disable automatic config reloading]" \
+ "(--persistent-logging)--persistent-logging[Keep the log file after quitting Alacritty]" \
"--print-events[Print all events to stdout]" \
{-q,-qq}"[Reduces the level of verbosity (min is -qq)]" \
{-v,-vv,-vvv}"[Increases the level of verbosity (max is -vvv)]" \
diff --git a/alacritty.man b/alacritty.man
index ba01b459..e0a1b519 100644
--- a/alacritty.man
+++ b/alacritty.man
@@ -19,6 +19,9 @@ Enable automatic config reloading
.TP
\fB\-\-no\-live\-config\-reload\fR
Disable automatic config reloading
+.TP
+\fB\-\-persistent\-logging\fR
+Keep the log file after quitting Alacritty
.HP
\fB\-\-print\-events\fR
.TP
diff --git a/alacritty.yml b/alacritty.yml
index f66269a1..83ec652f 100644
--- a/alacritty.yml
+++ b/alacritty.yml
@@ -130,6 +130,9 @@ font:
# Display the time it takes to redraw each frame.
render_timer: false
+# Keep the log file after quitting Alacritty.
+persistent_logging: false
+
# If `true`, bold text is drawn using the bright color variants.
draw_bold_text_with_bright_colors: true
diff --git a/alacritty_macos.yml b/alacritty_macos.yml
index 59f2ccb0..e4ead06d 100644
--- a/alacritty_macos.yml
+++ b/alacritty_macos.yml
@@ -125,6 +125,9 @@ font:
# Display the time it takes to redraw each frame.
render_timer: false
+# Keep the log file after quitting Alacritty.
+persistent_logging: false
+
# If `true`, bold text is drawn using the bright color variants.
draw_bold_text_with_bright_colors: true
diff --git a/alacritty_windows.yml b/alacritty_windows.yml
index debf06ff..af429152 100644
--- a/alacritty_windows.yml
+++ b/alacritty_windows.yml
@@ -108,6 +108,9 @@ font:
# Display the time it takes to redraw each frame.
render_timer: false
+# Keep the log file after quitting Alacritty.
+persistent_logging: false
+
# Colors (Tomorrow Night Bright)
colors:
# Default colors
diff --git a/build.rs b/build.rs
index fd9aee37..22799c95 100644
--- a/build.rs
+++ b/build.rs
@@ -14,15 +14,12 @@
#[cfg(windows)]
extern crate embed_resource;
#[cfg(windows)]
-extern crate tempdir;
+extern crate tempfile;
#[cfg(windows)]
extern crate reqwest;
#[cfg(windows)]
extern crate zip;
-#[cfg(windows)]
-use tempdir::TempDir;
-
extern crate gl_generator;
use gl_generator::{Api, Fallbacks, GlobalGenerator, Profile, Registry};
@@ -66,8 +63,7 @@ fn main() {
#[cfg(windows)]
fn aquire_winpty_agent(out_path: &Path) {
- let tmp_dir = TempDir::new("alacritty_build").unwrap();
-
+ let tmp_dir = tempfile::Builder::new().prefix("alacritty_build").tempdir().unwrap();
let mut response = reqwest::get(WINPTY_PACKAGE_URL).unwrap();
let mut file = OpenOptions::new()
diff --git a/src/ansi.rs b/src/ansi.rs
index f1ca759a..2171f868 100644
--- a/src/ansi.rs
+++ b/src/ansi.rs
@@ -60,7 +60,7 @@ fn parse_rgb_color(color: &[u8]) -> Option<Rgb> {
let r = parse_hex!();
let val = next!();
- if val != Some('/') { println!("val={:?}", val); return None; }
+ if val != Some('/') { return None; }
let g = parse_hex!();
if next!() != Some('/') { return None; }
let b = parse_hex!();
@@ -901,7 +901,7 @@ impl<'a, H, W> vte::Perform for Performer<'a, H, W>
macro_rules! unhandled {
() => {{
- warn!("[Unhandled CSI] action={:?}, args={:?}, intermediates={:?}",
+ debug!("[Unhandled CSI] action={:?}, args={:?}, intermediates={:?}",
action, args, intermediates);
return;
}}
@@ -1137,7 +1137,7 @@ impl<'a, H, W> vte::Perform for Performer<'a, H, W>
) {
macro_rules! unhandled {
() => {{
- warn!("[unhandled] esc_dispatch params={:?}, ints={:?}, byte={:?} ({:02x})",
+ debug!("[unhandled] esc_dispatch params={:?}, ints={:?}, byte={:?} ({:02x})",
params, intermediates, byte as char, byte);
return;
}}
diff --git a/src/cli.rs b/src/cli.rs
index 0a36179a..99728780 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -31,6 +31,7 @@ pub struct Options {
pub command: Option<Shell<'static>>,
pub working_dir: Option<PathBuf>,
pub config: Option<PathBuf>,
+ pub persistent_logging: bool,
}
impl Default for Options {
@@ -46,6 +47,7 @@ impl Default for Options {
command: None,
working_dir: None,
config: None,
+ persistent_logging: false,
}
}
}
@@ -71,6 +73,9 @@ impl Options {
.conflicts_with("live-config-reload"))
.arg(Arg::with_name("print-events")
.long("print-events"))
+ .arg(Arg::with_name("persistent-logging")
+ .long("persistent-logging")
+ .help("Keep the log file after quitting Alacritty"))
.arg(Arg::with_name("dimensions")
.long("dimensions")
.short("d")
@@ -129,6 +134,10 @@ impl Options {
options.live_config_reload = Some(false);
}
+ if matches.is_present("persistent-logging") {
+ options.persistent_logging = true;
+ }
+
if let Some(mut dimensions) = matches.values_of("dimensions") {
let width = dimensions.next().map(|w| w.parse().map(Column));
let height = dimensions.next().map(|h| h.parse().map(Line));
@@ -147,8 +156,8 @@ impl Options {
}
match matches.occurrences_of("v") {
- 0 => {},
- 1 => options.log_level = log::LevelFilter::Info,
+ 0 if !options.print_events => {},
+ 0 | 1 => options.log_level = log::LevelFilter::Info,
2 => options.log_level = log::LevelFilter::Debug,
3 | _ => options.log_level = log::LevelFilter::Trace
}
diff --git a/src/config.rs b/src/config.rs
index ee30c085..ae1ec897 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -73,7 +73,7 @@ fn deserialize_duration_ms<'a, D>(deserializer: D) -> ::std::result::Result<Dura
match u64::deserialize(deserializer) {
Ok(threshold_ms) => Ok(Duration::from_millis(threshold_ms)),
Err(err) => {
- eprintln!("problem with config: {}; Using default value", err);
+ error!("problem with config: {}; Using default value", err);
Ok(default_threshold_ms())
},
}
@@ -172,7 +172,7 @@ fn deserialize_visual_bell_duration<'a, D>(deserializer: D) -> ::std::result::Re
match u16::deserialize(deserializer) {
Ok(duration) => Ok(duration),
Err(err) => {
- eprintln!("problem with config: {}; Using default value", err);
+ error!("problem with config: {}; Using default value", err);
Ok(default_visual_bell_duration())
},
}
@@ -310,19 +310,19 @@ impl<'de> Deserialize<'de> for Decorations {
"none" => Ok(Decorations::None),
"full" => Ok(Decorations::Full),
"true" => {
- eprintln!("deprecated decorations boolean value, \
+ error!("deprecated decorations boolean value, \
use one of transparent|buttonless|none|full instead; \
Falling back to \"full\"");
Ok(Decorations::Full)
},
"false" => {
- eprintln!("deprecated decorations boolean value, \
+ error!("deprecated decorations boolean value, \
use one of transparent|buttonless|none|full instead; \
Falling back to \"none\"");
Ok(Decorations::None)
},
_ => {
- eprintln!("invalid decorations value: {}; Using default value", value);
+ error!("invalid decorations value: {}; Using default value", value);
Ok(Decorations::Full)
}
}
@@ -336,23 +336,23 @@ impl<'de> Deserialize<'de> for Decorations {
"none" => Ok(Decorations::None),
"full" => Ok(Decorations::Full),
"true" => {
- eprintln!("deprecated decorations boolean value, \
+ error!("deprecated decorations boolean value, \
use one of none|full instead; \
Falling back to \"full\"");
Ok(Decorations::Full)
},
"false" => {
- eprintln!("deprecated decorations boolean value, \
+ error!("deprecated decorations boolean value, \
use one of none|full instead; \
Falling back to \"none\"");
Ok(Decorations::None)
},
"transparent" | "buttonless" => {
- eprintln!("macos-only decorations value: {}; Using default value", value);
+ error!("macos-only decorations value: {}; Using default value", value);
Ok(Decorations::Full)
},
_ => {
- eprintln!("invalid decorations value: {}; Using default value", value);
+ error!("invalid decorations value: {}; Using default value", value);
Ok(Decorations::Full)
}
}
@@ -392,7 +392,7 @@ fn deserialize_padding<'a, D>(deserializer: D) -> ::std::result::Result<Delta<u8
match Delta::deserialize(deserializer) {
Ok(delta) => Ok(delta),
Err(err) => {
- eprintln!("problem with config: {}; Using default value", err);
+ error!("problem with config: {}; Using default value", err);
Ok(default_padding())
},
}
@@ -503,6 +503,10 @@ pub struct Config {
#[serde(default, deserialize_with="failure_default")]
cursor: Cursor,
+ /// Keep the log file after quitting
+ #[serde(default, deserialize_with="failure_default")]
+ persistent_logging: bool,
+
// TODO: DEPRECATED
#[serde(default, deserialize_with = "failure_default")]
custom_cursor_colors: Option<bool>,
@@ -528,7 +532,7 @@ fn failure_default_vec<'a, D, T>(deserializer: D) -> ::std::result::Result<Vec<T
let vec = match Vec::<serde_yaml::Value>::deserialize(deserializer) {
Ok(vec) => vec,
Err(err) => {
- eprintln!("problem with config: {}; Using empty vector", err);
+ error!("problem with config: {}; Using empty vector", err);
return Ok(Vec::new());
},
};
@@ -539,7 +543,7 @@ fn failure_default_vec<'a, D, T>(deserializer: D) -> ::std::result::Result<Vec<T
match T::deserialize(value) {
Ok(binding) => bindings.push(binding),
Err(err) => {
- eprintln!("problem with config: {}; Skipping value", err);
+ error!("problem with config: {}; Skipping value", err);
},
}
}
@@ -557,7 +561,7 @@ fn deserialize_tabspaces<'a, D>(deserializer: D) -> ::std::result::Result<usize,
match usize::deserialize(deserializer) {
Ok(value) => Ok(value),
Err(err) => {
- eprintln!("problem with config: {}; Using `8`", err);
+ error!("problem with config: {}; Using `8`", err);
Ok(default_tabspaces())
},
}
@@ -569,7 +573,7 @@ fn default_true_bool<'a, D>(deserializer: D) -> ::std::result::Result<bool, D::E
match bool::deserialize(deserializer) {
Ok(value) => Ok(value),
Err(err) => {
- eprintln!("problem with config: {}; Using `true`", err);
+ error!("problem with config: {}; Using `true`", err);
Ok(true)
},
}
@@ -583,7 +587,7 @@ fn failure_default<'a, D, T>(deserializer: D)
match T::deserialize(deserializer) {
Ok(value) => Ok(value),
Err(err) => {
- eprintln!("problem with config: {}; Using default value", err);
+ error!("problem with config: {}; Using default value", err);
Ok(T::default())
},
}
@@ -645,7 +649,7 @@ fn deserialize_scrolling_history<'a, D>(deserializer: D) -> ::std::result::Resul
match u32::deserialize(deserializer) {
Ok(lines) => {
if lines > MAX_SCROLLBACK_LINES {
- eprintln!(
+ error!(
"problem with config: scrollback size is {}, but expected a maximum of {}; \
Using {1} instead",
lines, MAX_SCROLLBACK_LINES,
@@ -656,7 +660,7 @@ fn deserialize_scrolling_history<'a, D>(deserializer: D) -> ::std::result::Resul
}
},
Err(err) => {
- eprintln!("problem with config: {}; Using default value", err);
+ error!("problem with config: {}; Using default value", err);
Ok(default_scrolling_history())
},
}
@@ -668,7 +672,7 @@ fn deserialize_scrolling_multiplier<'a, D>(deserializer: D) -> ::std::result::Re
match u8::deserialize(deserializer) {
Ok(lines) => Ok(lines),
Err(err) => {
- eprintln!("problem with config: {}; Using default value", err);
+ error!("problem with config: {}; Using default value", err);
Ok(default_scrolling_multiplier())
},
}
@@ -710,7 +714,7 @@ impl<'a> de::Deserialize<'a> for ModsWrapper {
"Shift" => res.shift = true,
"Alt" | "Option" => res.alt = true,
"Control" => res.ctrl = true,
- _ => eprintln!("unknown modifier {:?}", modifier),
+ _ => error!("unknown modifier {:?}", modifier),
}
}
@@ -831,7 +835,7 @@ impl<'a> de::Deserialize<'a> for ModeWrapper {
"~AppCursor" => res.not_mode |= mode::TermMode::APP_CURSOR,
"AppKeypad" => res.mode |= mode::TermMode::APP_KEYPAD,
"~AppKeypad" => res.not_mode |= mode::TermMode::APP_KEYPAD,
- _ => eprintln!("unknown mode {:?}", modifier),
+ _ => error!("unknown mode {:?}", modifier),
}
}
@@ -1193,7 +1197,7 @@ fn deserialize_color_index<'a, D>(deserializer: D) -> ::std::result::Result<u8,
match u8::deserialize(deserializer) {
Ok(index) => {
if index < 16 {
- eprintln!(
+ error!(
"problem with config: indexed_color's index is '{}', \
but a value bigger than 15 was expected; \
Ignoring setting",
@@ -1207,7 +1211,7 @@ fn deserialize_color_index<'a, D>(deserializer: D) -> ::std::result::Result<u8,
}
},
Err(err) => {
- eprintln!("problem with config: {}; Ignoring setting", err);
+ error!("problem with config: {}; Ignoring setting", err);
// Return value out of range to ignore this color
Ok(0)
@@ -1262,7 +1266,7 @@ fn deserialize_optional_color<'a, D>(deserializer: D) -> ::std::result::Result<O
},
Ok(None) => Ok(None),
Err(err) => {
- eprintln!("problem with config: {}; Using standard foreground color", err);
+ error!("problem with config: {}; Using standard foreground color", err);
Ok(None)
},
}
@@ -1361,7 +1365,7 @@ fn rgb_from_hex<'a, D>(deserializer: D) -> ::std::result::Result<Rgb, D::Error>
match rgb {
Ok(rgb) => Ok(rgb),
Err(err) => {
- eprintln!("problem with config: {}; Using color #ff00ff", err);
+ error!("problem with config: {}; Using color #ff00ff", err);
Ok(Rgb { r: 255, g: 0, b: 255 })
},
}
@@ -1671,6 +1675,12 @@ impl Config {
self.scrolling.history = history;
}
+ /// Keep the log file after quitting Alacritty
+ #[inline]
+ pub fn persistent_logging(&self) -> bool {
+ self.persistent_logging
+ }
+
pub fn load_from<P: Into<PathBuf>>(path: P) -> Result<Config> {
let path = path.into();
let raw = Config::read_file(path.as_path())?;
@@ -1701,24 +1711,22 @@ impl Config {
}
fn print_deprecation_warnings(&mut self) {
- use ::util::fmt;
if self.dimensions.is_some() {
- eprintln!("{}", fmt::Yellow("Config `dimensions` is deprecated. \
- Please use `window.dimensions` instead."));
+ warn!("{}", "Config `dimensions` is deprecated. \
+ Please use `window.dimensions` instead.");
}
if self.padding.is_some() {
- eprintln!("{}", fmt::Yellow("Config `padding` is deprecated. \
- Please use `window.padding` instead."));
+ warn!("{}", "Config `padding` is deprecated. Please use `window.padding` instead.");
}
if self.mouse.faux_scrollback_lines.is_some() {
- println!("{}", fmt::Yellow("Config `mouse.faux_scrollback_lines` is deprecated. \
- Please use `mouse.faux_scrolling_lines` instead."));
+ warn!("{}", "Config `mouse.faux_scrollback_lines` is deprecated. \
+ Please use `mouse.faux_scrolling_lines` instead.");
}
if let Some(custom_cursor_colors) = self.custom_cursor_colors {
- eprintln!("{}", fmt::Yellow("Config `custom_cursor_colors` is deprecated."));
+ warn!("{}", "Config `custom_cursor_colors` is deprecated.");
if !custom_cursor_colors {
self.colors.cursor.cursor = None;
@@ -1727,18 +1735,17 @@ impl Config {
}
if self.cursor_style.is_some() {
- eprintln!("{}", fmt::Yellow("Config `cursor_style` is deprecated. \
- Please use `cursor.style` instead."));
+ warn!("{}", "Config `cursor_style` is deprecated. Please use `cursor.style` instead.");
}
if self.hide_cursor_when_typing.is_some() {
- eprintln!("{}", fmt::Yellow("Config `hide_cursor_when_typing` is deprecated. \
- Please use `mouse.hide_when_typing` instead."));
+ warn!("{}", "Config `hide_cursor_when_typing` is deprecated. \
+ Please use `mouse.hide_when_typing` instead.");
}
if self.unfocused_hollow_cursor.is_some() {
- eprintln!("{}", fmt::Yellow("Config `unfocused_hollow_cursor` is deprecated. \
- Please use `cursor.unfocused_hollow` instead."));
+ warn!("{}", "Config `unfocused_hollow_cursor` is deprecated. \
+ Please use `cursor.unfocused_hollow` instead.");
}
}
}
@@ -1839,7 +1846,7 @@ impl DeserializeSize for Size {
match size {
Ok(size) => Ok(size),
Err(err) => {
- eprintln!("problem with config: {}; Using size 12", err);
+ error!("problem with config: {}; Using size 12", err);
Ok(Size::new(12.))
},
}
@@ -2062,7 +2069,7 @@ impl Monitor {
let _ = config_tx.send(config);
handler.on_config_reload();
},
- Err(err) => eprintln!("Ignoring invalid config: {}", err),
+ Err(err) => error!("Ignoring invalid config: {}", err),
}
}
}
diff --git a/src/display.rs b/src/display.rs
index 1a145185..12842649 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -28,6 +28,7 @@ use renderer::{self, GlyphCache, QuadRenderer};
use term::{Term, SizeInfo, RenderableCell};
use sync::FairMutex;
use window::{self, Window};
+use logging::LoggerProxy;
use Rgb;
#[derive(Debug)]
@@ -99,6 +100,7 @@ pub struct Display {
meter: Meter,
font_size: font::Size,
size_info: SizeInfo,
+ logger_proxy: LoggerProxy,
}
/// Can wakeup the render loop from other threads
@@ -129,7 +131,11 @@ impl Display {
&self.size_info
}
- pub fn new(config: &Config, options: &cli::Options) -> Result<Display, Error> {
+ pub fn new(
+ config: &Config,
+ options: &cli::Options,
+ logger_proxy: LoggerProxy
+ ) -> Result<Display, Error> {
// Extract some properties from config
let render_timer = config.render_timer();
@@ -218,6 +224,7 @@ impl Display {
meter: Meter::new(),
font_size: font::Size::new(0.),
size_info,
+ logger_proxy,
})
}
@@ -420,10 +427,38 @@ impl Display {
g: 0x4e,
b: 0x53,
};
- self.renderer
- .with_api(config, &size_info, visual_bell_intensity, |mut api| {
- api.render_string(&timing[..], glyph_cache, color);
- });
+ self.renderer.with_api(config, &size_info, visual_bell_intensity, |mut api| {
+ api.render_string(&timing[..], size_info.lines() - 2, glyph_cache, color);
+ });
+ }
+
+ // Display errors and warnings
+ if self.logger_proxy.errors() {
+ let msg = match self.logger_proxy.log_path() {
+ Some(path) => format!(" ERROR! See log at {} ", path),
+ None => " ERROR! See log in stderr ".into(),
+ };
+ let color = Rgb {
+ r: 0xff,
+ g: 0x00,
+ b: 0x00,
+ };
+ self.renderer.with_api(config, &size_info, visual_bell_intensity, |mut api| {
+ api.render_string(&msg, size_info.lines() - 1, glyph_cache, color);
+ });
+ } else if self.logger_proxy.warnings() {
+ let msg = match self.logger_proxy.log_path() {
+ Some(path) => format!(" WARNING! See log at {} ", path),
+ None => " WARNING! See log in stderr ".into(),
+ };
+ let color = Rgb {
+ r: 0xff,
+ g: 0xff,
+ b: 0x00,
+ };
+ self.renderer.with_api(config, &size_info, visual_bell_intensity, |mut api| {
+ api.render_string(&msg, size_info.lines() - 1, glyph_cache, color);
+ });
}
}
diff --git a/src/event.rs b/src/event.rs
index 7a1faa70..ece8ec6f 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -488,7 +488,7 @@ impl<N: Notify> Processor<N> {
let hide_mouse = &mut self.hide_mouse;
let mut process = |event| {
if print_events {
- println!("glutin event: {:?}", event);
+ info!("glutin event: {:?}", event);
}
Processor::handle_event(
&mut processor,
diff --git a/src/grid/tests.rs b/src/grid/tests.rs
index e136e3b3..9cb30a7f 100644
--- a/src/grid/tests.rs
+++ b/src/grid/tests.rs
@@ -20,19 +20,13 @@ use index::{Point, Line, Column};
// Scroll up moves lines upwards
#[test]
fn scroll_up() {
- println!();
-
let mut grid = Grid::new(Line(10), Column(1), 0, 0);
for i in 0..10 {
grid[Line(i)][Column(0)] = i;
}
- println!("grid: {:?}", grid);
-
grid.scroll_up(&(Line(0)..Line(10)), Line(2), &0);
- println!("grid: {:?}", grid);
-
assert_eq!(grid[Line(0)][Column(0)], 2);
assert_eq!(grid[Line(0)].occ, 1);
assert_eq!(grid[Line(1)][Column(0)], 3);
@@ -58,19 +52,13 @@ fn scroll_up() {
// Scroll down moves lines downwards
#[test]
fn scroll_down() {
- println!();
-
let mut grid = Grid::new(Line(10), Column(1), 0, 0);
for i in 0..10 {
grid[Line(i)][Column(0)] = i;
}
- println!("grid: {:?}", grid);
-
grid.scroll_down(&(Line(0)..Line(10)), Line(2), &0);
- println!("grid: {:?}", grid);
-
assert_eq!(grid[Line(0)][Column(0)], 0); // was 8
assert_eq!(grid[Line(0)].occ, 0);
assert_eq!(grid[Line(1)][Column(0)], 0); // was 9
diff --git a/src/input.rs b/src/input.rs
index 600a1abe..d2f8f6b5 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -218,7 +218,7 @@ impl Action {
.and_then(|clipboard| clipboard.load_primary() )
.map(|contents| { self.paste(ctx, &contents) })
.unwrap_or_else(|err| {
- eprintln!("Error loading data from clipboard. {}", Red(err));
+ error!("Error loading data from clipboard. {}", Red(err));
});
},
Action::PasteSelection => {
@@ -228,7 +228,7 @@ impl Action {
.and_then(|clipboard| clipboard.load_selection() )
.map(|contents| { self.paste(ctx, &contents) })
.unwrap_or_else(|err| {
- warn!("Error loading data from clipboard. {}", Red(err));
+ error!("Error loading data from clipboard. {}", Red(err));
});
}
},
diff --git a/src/lib.rs b/src/lib.rs
index 1d393d1a..7ba3538b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -64,6 +64,7 @@ extern crate xdg;
extern crate base64;
extern crate terminfo;
extern crate url;
+extern crate time;
#[macro_use]
pub mod macros;
diff --git a/src/logging.rs b/src/logging.rs
index 10929980..5ad1dcd5 100644
--- a/src/logging.rs
+++ b/src/logging.rs
@@ -17,37 +17,134 @@
//! The main executable is supposed to call `initialize()` exactly once during
//! startup. All logging messages are written to stdout, given that their
//! log-level is sufficient for the level configured in `cli::Options`.
-use log;
-use std::sync;
-use std::io;
use cli;
+use log::{self, Level};
+use time;
-pub struct Logger<T> {
+use std::env;
+use std::fs::{self, File, OpenOptions};
+use std::io::{self, LineWriter, Stdout, Write};
+use std::path::PathBuf;
+use std::process;
+use std::sync::atomic::{AtomicBool, Ordering};
+use std::sync::{Arc, Mutex};
+
+pub fn initialize(options: &cli::Options) -> Result<LoggerProxy, log::SetLoggerError> {
+ // Use env_logger if RUST_LOG environment variable is defined. Otherwise,
+ // use the alacritty-only logger.
+ if ::std::env::var("RUST_LOG").is_ok() {
+ ::env_logger::try_init()?;
+ Ok(LoggerProxy::default())
+ } else {
+ let logger = Logger::new(options.log_level);
+ let proxy = logger.proxy();
+
+ log::set_boxed_logger(Box::new(logger))?;
+
+ Ok(proxy)
+ }
+}
+
+/// Proxy object for bidirectional communicating with the global logger.
+#[derive(Clone, Default)]
+pub struct LoggerProxy {
+ errors: Arc<AtomicBool>,
+ warnings: Arc<AtomicBool>,
+ logfile_proxy: OnDemandLogFileProxy,
+}
+
+impl LoggerProxy {
+ /// Check for new logged errors.
+ pub fn errors(&self) -> bool {
+ self.errors.load(Ordering::Relaxed)
+ }
+
+ /// Check for new logged warnings.
+ pub fn warnings(&self) -> bool {
+ self.warnings.load(Ordering::Relaxed)
+ }
+
+ /// Get the path of the log file if it has been created.
+ pub fn log_path(&self) -> Option<&str> {
+ if self.logfile_proxy.created.load(Ordering::Relaxed) {
+ Some(&self.logfile_proxy.path)
+ } else {
+ None
+ }
+ }
+
+ /// Clear log warnings/errors from the Alacritty UI.
+ pub fn clear(&mut self) {
+ self.errors.store(false, Ordering::Relaxed);
+ self.warnings.store(false, Ordering::Relaxed);
+ }
+
+ pub fn delete_log(&mut self) {
+ self.logfile_proxy.delete_log();
+ }
+}
+
+struct Logger {
level: log::LevelFilter,
- output: sync::Mutex<T>
+ logfile: Mutex<OnDemandLogFile>,
+ stdout: Mutex<LineWriter<Stdout>>,
+ errors: Arc<AtomicBool>,
+ warnings: Arc<AtomicBool>,
}
-impl<T: Send + io::Write> Logger<T> {
+impl Logger {
// False positive, see: https://github.com/rust-lang-nursery/rust-clippy/issues/734
#[cfg_attr(feature = "cargo-clippy", allow(new_ret_no_self))]
- pub fn new(output: T, level: log::LevelFilter) -> Logger<io::LineWriter<T>> {
+ fn new(level: log::LevelFilter) -> Self {
log::set_max_level(level);
+
+ let logfile = Mutex::new(OnDemandLogFile::new());
+ let stdout = Mutex::new(LineWriter::new(io::stdout()));
+
Logger {
level,
- output: sync::Mutex::new(io::LineWriter::new(output))
+ logfile,
+ stdout,
+ errors: Arc::new(AtomicBool::new(false)),
+ warnings: Arc::new(AtomicBool::new(false)),
+ }
+ }
+
+ fn proxy(&self) -> LoggerProxy {
+ LoggerProxy {
+ errors: self.errors.clone(),
+ warnings: self.warnings.clone(),
+ logfile_proxy: self.logfile.lock().expect("").proxy(),
}
}
}
-impl<T: Send + io::Write> log::Log for Logger<T> {
+impl log::Log for Logger {
fn enabled(&self, metadata: &log::Metadata) -> bool {
metadata.level() <= self.level
}
fn log(&self, record: &log::Record) {
if self.enabled(record.metadata()) && record.target().starts_with("alacritty") {
- if let Ok(ref mut writer) = self.output.lock() {
- let _ = writer.write_all(format!("{}\n", record.args()).as_ref());
+ let msg = format!(
+ "[{}] [{}] {}\n",
+ time::now().strftime("%F %R").unwrap(),
+ record.level(),
+ record.args()
+ );
+
+ if let Ok(ref mut logfile) = self.logfile.lock() {
+ let _ = logfile.write_all(msg.as_ref());
+ }
+
+ if let Ok(ref mut stdout) = self.stdout.lock() {
+ let _ = stdout.write_all(msg.as_ref());
+ }
+
+ match record.level() {
+ Level::Error => self.errors.store(true, Ordering::Relaxed),
+ Level::Warn => self.warnings.store(true, Ordering::Relaxed),
+ _ => (),
}
}
}
@@ -55,12 +152,82 @@ impl<T: Send + io::Write> log::Log for Logger<T> {
fn flush(&self) {}
}
-pub fn initialize(options: &cli::Options) -> Result<(), log::SetLoggerError> {
- // Use env_logger if RUST_LOG environment variable is defined. Otherwise,
- // use the alacritty-only logger.
- if ::std::env::var("RUST_LOG").is_ok() {
- ::env_logger::try_init()
- } else {
- log::set_boxed_logger(Box::new(Logger::new(io::stdout(), options.log_level)))
+#[derive(Clone, Default)]
+struct OnDemandLogFileProxy {
+ created: Arc<AtomicBool>,
+ path: String,
+}
+
+impl OnDemandLogFileProxy {
+ fn delete_log(&mut self) {
+ if self.created.load(Ordering::Relaxed) && fs::remove_file(&self.path).is_ok() {
+ let _ = writeln!(io::stdout(), "Deleted log file at {:?}", self.path);
+ self.created.store(false, Ordering::Relaxed);
+ }
+ }
+}
+
+struct OnDemandLogFile {
+ file: Option<LineWriter<File>>,
+ created: Arc<AtomicBool>,
+ path: PathBuf,
+}
+
+impl OnDemandLogFile {
+ fn new() -> Self {
+ let mut path = env::temp_dir();
+ path.push(format!("Alacritty-{}.log", process::id()));
+
+ OnDemandLogFile {
+ path,
+ file: None,
+ created: Arc::new(AtomicBool::new(false)),
+ }
+ }
+
+ fn file(&mut self) -> Result<&mut LineWriter<File>, io::Error> {
+ // Allow to recreate the file if it has been deleted at runtime
+ if self.file.is_some() && !self.path.as_path().exists() {
+ self.file = None;
+ }
+
+ // Create the file if it doesn't exist yet
+ if self.file.is_none() {
+ let file = OpenOptions::new()
+ .append(true)
+ .create(true)
+ .open(&self.path);
+
+ match file {
+ Ok(file) => {
+ self.file = Some(io::LineWriter::new(file));
+ self.created.store(true, Ordering::Relaxed);
+ let _ = writeln!(io::stdout(), "Created log file at {:?}", self.path);
+ }
+ Err(e) => {
+ let _ = writeln!(io::stdout(), "Unable to create log file: {}", e);
+ return Err(e);
+ }
+ }
+ }
+
+ Ok(self.file.as_mut().unwrap())
+ }
+
+ fn proxy(&self) -> OnDemandLogFileProxy {
+ OnDemandLogFileProxy {
+ created: self.created.clone(),
+ path: self.path.to_string_lossy().to_string(),
+ }
+ }
+}
+
+impl Write for OnDemandLogFile {
+ fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
+ self.file()?.write(buf)
+ }
+
+ fn flush(&mut self) -> Result<(), io::Error> {
+ self.file()?.flush()
}
}
diff --git a/src/macros.rs b/src/macros.rs
index 464110e6..519f8b6a 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -15,33 +15,7 @@
#[macro_export]
macro_rules! die {
($($arg:tt)*) => {{
- eprintln!($($arg)*);
+ error!($($arg)*);
::std::process::exit(1);
}}
}
-
-#[macro_export]
-macro_rules! maybe {
- ($option:expr) => {
- match $option {
- Some(value) => value,
- None => return None,
- }
- }
-}
-
-#[macro_export]
-macro_rules! print {
- ($($arg:tt)*) => {{
- use std::io::Write;
- let _ = write!(::std::io::stdout(), $($arg)*);
- }};
-}
-
-#[macro_export]
-macro_rules! eprint {
- ($($arg:tt)*) => {{
- use std::io::Write;
- let _ = write!(::std::io::stderr(), $($arg)*);
- }};
-}
diff --git a/src/main.rs b/src/main.rs
index 11adb396..a44c8eb3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -52,7 +52,7 @@ use alacritty::event;
use alacritty::event_loop::{self, EventLoop, Msg};
#[cfg(target_os = "macos")]
use alacritty::locale;
-use alacritty::logging;
+use alacritty::logging::{self, LoggerProxy};
use alacritty::sync::FairMutex;
use alacritty::term::Term;
use alacritty::tty::{self, process_should_exit};
@@ -65,8 +65,13 @@ fn main() {
#[cfg(windows)]
unsafe { AttachConsole(ATTACH_PARENT_PROCESS); }
- // Load command line options and config
+ // Load command line options
let options = cli::Options::load();
+
+ // Initialize the logger as soon as possible as to capture output from other subsystems
+ let logger_proxy = logging::initialize(&options).expect("Unable to initialize logger");
+
+ // Load configuration file
let config = load_config(&options).update_dynamic_title(&options);
// Switch to home directory
@@ -77,11 +82,9 @@ fn main() {
locale::set_locale_environment();
// Run alacritty
- if let Err(err) = run(config, &options) {
+ if let Err(err) = run(config, &options, logger_proxy) {
die!("Alacritty encountered an unrecoverable error:\n\n\t{}\n", Red(err));
}
-
- info!("Goodbye.");
}
/// Load configuration
@@ -98,7 +101,7 @@ fn load_config(options: &cli::Options) -> Config {
});
Config::load_from(&*config_path).unwrap_or_else(|err| {
- eprintln!("Error: {}; Loading default config", err);
+ error!("Error: {}; Loading default config", err);
Config::default()
})
}
@@ -107,10 +110,11 @@ fn load_config(options: &cli::Options) -> Config {
///
/// Creates a window, the terminal state, pty, I/O event loop, input processor,
/// config change monitor, and runs the main display loop.
-fn run(mut config: Config, options: &cli::Options) -> Result<(), Box<Error>> {
- // Initialize the logger first as to capture output from other subsystems
- logging::initialize(options)?;
-
+fn run(
+ mut config: Config,
+ options: &cli::Options,
+ mut logger_proxy: LoggerProxy,
+) -> Result<(), Box<Error>> {
info!("Welcome to Alacritty.");
if let Some(config_path) = config.path() {
info!("Configuration loaded from {}", config_path.display());
@@ -122,7 +126,7 @@ fn run(mut config: Config, options: &cli::Options) -> Result<(), Box<Error>> {
// Create a display.
//
// The display manages a window and can draw the terminal
- let mut display = Display::new(&config, options)?;
+ let mut display = Display::new(&config, options, logger_proxy.clone())?;
info!(
"PTY Dimensions: {:?} x {:?}",
@@ -135,7 +139,8 @@ fn run(mut config: Config, options: &cli::Options) -> Result<(), Box<Error>> {
// This object contains all of the state about what's being displayed. It's
// wrapped in a clonable mutex since both the I/O loop and display need to
// access it.
- let terminal = Term::new(&config, display.size().to_owned());
+ let mut terminal = Term::new(&config, display.size().to_owned());
+ terminal.set_logger_proxy(logger_proxy.clone());
let terminal = Arc::new(FairMutex::new(terminal));
// Find the window ID for setting $WINDOWID
@@ -258,5 +263,11 @@ fn run(mut config: Config, options: &cli::Options) -> Result<(), Box<Error>> {
#[cfg(windows)]
unsafe { FreeConsole(); }
+ info!("Goodbye.");
+
+ if !options.persistent_logging && !config.persistent_logging() {
+ logger_proxy.delete_log();
+ }
+
Ok(())
}
diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs
index 1a193caf..ef5a1e76 100644
--- a/src/renderer/mod.rs
+++ b/src/renderer/mod.rs
@@ -817,10 +817,16 @@ impl<'a> RenderApi<'a> {
self.batch.clear();
}
- /// Render a string in a predefined location. Used for printing render time for profiling and
- /// optimization.
- pub fn render_string(&mut self, string: &str, glyph_cache: &mut GlyphCache, color: Rgb) {
- let line = Line(23);
+
+ /// Render a string in a variable location. Used for printing the render timer, warnings and
+ /// errors.
+ pub fn render_string(
+ &mut self,
+ string: &str,
+ line: Line,
+ glyph_cache: &mut GlyphCache,
+ color: Rgb
+ ) {
let col = Column(0);
let cells = string
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 39213ee2..0f228f86 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -31,6 +31,7 @@ use config::{Config, VisualBellAnimation};
use {MouseCursor, Rgb};
use copypasta::{Clipboard, Load, Store};
use input::FONT_SIZE_STEP;
+use logging::LoggerProxy;
pub mod cell;
pub mod color;
@@ -810,6 +811,9 @@ pub struct Term {
/// Automatically scroll to bottom when new lines are added
auto_scroll: bool,
+
+ /// Proxy object for clearing displayed errors and warnings
+ logger_proxy: Option<LoggerProxy>,
}
/// Terminal size info
@@ -936,9 +940,14 @@ impl Term {
dynamic_title: config.dynamic_title(),
tabspaces,
auto_scroll: config.scrolling().auto_scroll,
+ logger_proxy: None,
}
}
+ pub fn set_logger_proxy(&mut self, logger_proxy: LoggerProxy) {
+ self.logger_proxy = Some(logger_proxy);
+ }
+
pub fn change_font_size(&mut self, delta: f32) {
// Saturating addition with minimum font size FONT_SIZE_STEP
let new_size = self.font_size + Size::new(delta);
@@ -1822,6 +1831,11 @@ impl ansi::Handler for Term {
}
},
ansi::ClearMode::All => {
+ // Clear displayed errors and warnings
+ if let Some(ref mut logger_proxy) = self.logger_proxy {
+ logger_proxy.clear();
+ }
+
self.grid.region_mut(..).each(|c| c.reset(&template));
},
ansi::ClearMode::Above => {