aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Wilm <jwilm@users.noreply.github.com>2017-01-06 21:51:24 -0800
committerGitHub <noreply@github.com>2017-01-06 21:51:24 -0800
commit852c2d8f15bfc11f0222fa08626c38724accd35a (patch)
tree0880b8e38d76ae4ba0fb1772fbd11cae53168729
parent62739bd226974358a811b4680b4b74c268418f5b (diff)
parent4e1f4c8cd7180606156b71ad0222f60e4559f2b3 (diff)
downloadalacritty-852c2d8f15bfc11f0222fa08626c38724accd35a.tar.gz
alacritty-852c2d8f15bfc11f0222fa08626c38724accd35a.zip
Merge pull request #131 from Manishearth/stable
Make it compile on stable Rust (almost)
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml2
-rw-r--r--src/ansi.rs6
-rw-r--r--src/config.rs3
-rw-r--r--src/event.rs4
-rw-r--r--src/grid.rs13
-rw-r--r--src/index.rs182
-rw-r--r--src/input.rs9
-rw-r--r--src/lib.rs11
-rw-r--r--src/main.rs2
-rw-r--r--src/renderer/mod.rs4
-rw-r--r--src/selection.rs11
-rw-r--r--src/term/cell.rs2
-rw-r--r--src/term/mod.rs42
-rw-r--r--src/util.rs10
-rw-r--r--src/window.rs18
16 files changed, 225 insertions, 95 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b96204f3..a741a18f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -10,6 +10,7 @@ dependencies = [
"font 0.1.0",
"gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin 0.6.1 (git+https://github.com/jwilm/glutin?rev=af7fe340bd4a2af53ea521defcb4f377cdc588cf)",
+ "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 2.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/Cargo.toml b/Cargo.toml
index 3ab73116..67614ddb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,6 +17,7 @@ notify = "2.6"
bitflags = "*"
font = { path = "./font" }
errno = "0.1.6"
+lazy_static = "0.2.2"
parking_lot = { version = "0.3.1", features = ["nightly"] }
serde = "0.8"
serde_yaml = "0.5"
@@ -34,6 +35,7 @@ default = ["err-println"]
# Enabling this feature makes shaders automatically reload when changed
live-shader-reload = []
err-println = []
+nightly = []
[build-dependencies]
gl_generator = "0.5"
diff --git a/src/ansi.rs b/src/ansi.rs
index e5c129e3..f24708bd 100644
--- a/src/ansi.rs
+++ b/src/ansi.rs
@@ -18,7 +18,7 @@ use std::io;
use vte;
-use index::{Column, Line};
+use index::{Column, Line, Contains};
use ::Rgb;
@@ -743,8 +743,8 @@ fn parse_color(attrs: &[i64], i: &mut usize) -> Option<Color> {
*i += 4;
- let range = 0...255;
- if !range.contains(r) || !range.contains(g) || !range.contains(b) {
+ let range = 0..256;
+ if !range.contains_(r) || !range.contains_(g) || !range.contains_(b) {
err_println!("Invalid RGB color spec: ({}, {}, {})", r, g, b);
return None;
}
diff --git a/src/config.rs b/src/config.rs
index 36f0c363..f36859c7 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -713,7 +713,8 @@ fn rgb_from_hex<D>(deserializer: &mut D) -> ::std::result::Result<Rgb, D::Error>
deserializer.deserialize_str(RgbVisitor)
}
-impl Rgb {
+impl FromStr for Rgb {
+ type Err = ();
fn from_str(s: &str) -> ::std::result::Result<Rgb, ()> {
let mut chars = s.chars();
let mut rgb = Rgb::default();
diff --git a/src/event.rs b/src/event.rs
index 66abbaa2..bdfe2708 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -153,12 +153,10 @@ impl<N: Notify> Processor<N> {
processor.ctx.terminal.dirty = true;
}
},
- glutin::Event::Focused(true) => {
- processor.ctx.terminal.dirty = true;
- },
glutin::Event::MouseWheel(scroll_delta, touch_phase) => {
processor.on_mouse_wheel(scroll_delta, touch_phase);
},
+ glutin::Event::Focused(true) |
glutin::Event::Refresh |
glutin::Event::Awakened => {
processor.ctx.terminal.dirty = true;
diff --git a/src/grid.rs b/src/grid.rs
index 77fe92b9..5c3da769 100644
--- a/src/grid.rs
+++ b/src/grid.rs
@@ -24,10 +24,9 @@ use std::borrow::ToOwned;
use std::cmp::Ordering;
use std::iter::IntoIterator;
use std::ops::{Deref, DerefMut, Range, RangeTo, RangeFrom, RangeFull, Index, IndexMut};
-use std::ops::RangeInclusive;
use std::slice::{self, Iter, IterMut};
-use index::{self, Point};
+use index::{self, Point, IndexRange, RangeInclusive};
/// Convert a type to a linear index range.
pub trait ToRange {
@@ -53,7 +52,7 @@ pub struct Grid<T> {
impl<T: Clone> Grid<T> {
pub fn new(lines: index::Line, cols: index::Column, template: &T) -> Grid<T> {
let mut raw = Vec::with_capacity(*lines);
- for _ in index::Line(0)..lines {
+ for _ in IndexRange(index::Line(0)..lines) {
raw.push(Row::new(cols, template));
}
@@ -84,7 +83,7 @@ impl<T: Clone> Grid<T> {
}
fn grow_lines(&mut self, lines: index::Line, template: &T) {
- for _ in self.num_lines()..lines {
+ for _ in IndexRange(self.num_lines()..lines) {
self.raw.push(Row::new(self.cols, template));
}
@@ -124,7 +123,7 @@ impl<T> Grid<T> {
#[inline]
pub fn scroll_down(&mut self, region: Range<index::Line>, positions: index::Line) {
- for line in region.rev() {
+ for line in IndexRange(region).rev() {
let src = line;
let dst = line - positions;
self.swap_lines(src, dst);
@@ -133,7 +132,7 @@ impl<T> Grid<T> {
#[inline]
pub fn scroll_up(&mut self, region: Range<index::Line>, positions: index::Line) {
- for line in region {
+ for line in IndexRange(region) {
let src = line;
let dst = line + positions;
self.swap_lines(src, dst);
@@ -151,7 +150,7 @@ impl<T> Grid<T> {
/// better error messages by doing the bounds checking ourselves.
#[inline]
pub fn swap_lines(&mut self, src: index::Line, dst: index::Line) {
- use std::intrinsics::unlikely;
+ use util::unlikely;
unsafe {
// check that src/dst are in bounds. Since index::Line newtypes usize,
diff --git a/src/index.rs b/src/index.rs
index c80589da..25d5eaff 100644
--- a/src/index.rs
+++ b/src/index.rs
@@ -17,9 +17,7 @@
/// Indexing types and implementations for Grid and Line
use std::cmp::{Ord, Ordering};
use std::fmt;
-use std::iter::Step;
-use std::mem;
-use std::ops::{self, Deref, Add};
+use std::ops::{self, Deref, Add, Range};
/// The side of a cell
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
@@ -46,7 +44,7 @@ impl Ord for Point {
use std::cmp::Ordering::*;
match (self.line.cmp(&other.line), self.col.cmp(&other.col)) {
(Equal, Equal) => Equal,
- (Equal, ord) => ord,
+ (Equal, ord) |
(ord, Equal) => ord,
(Less, _) => Less,
(Greater, _) => Greater,
@@ -200,6 +198,128 @@ macro_rules! sub {
}
}
+/// This exists because we can't implement Iterator on Range
+/// and the existing impl needs the unstable Step trait
+/// This should be removed and replaced with a Step impl
+/// in the ops macro when `step_by` is stabilized
+pub struct IndexRange<T>(pub Range<T>);
+
+impl<T> From<Range<T>> for IndexRange<T> {
+ fn from(from: Range<T>) -> Self {
+ IndexRange(from)
+ }
+}
+
+pub enum RangeInclusive<Idx> {
+ Empty {
+ at: Idx,
+ },
+ NonEmpty {
+ start: Idx,
+ end: Idx,
+ },
+}
+
+impl<Idx> RangeInclusive<Idx> {
+ pub fn new(from: Idx, to: Idx) -> Self {
+ RangeInclusive::NonEmpty {
+ start: from,
+ end: to
+ }
+ }
+}
+
+macro_rules! inclusive {
+ ($ty:ty, $steps_add_one:expr) => {
+ // impl copied from stdlib, can be removed when inclusive_range is stabilized
+ impl Iterator for RangeInclusive<$ty> {
+ type Item = $ty;
+
+ #[inline]
+ fn next(&mut self) -> Option<$ty> {
+ use index::RangeInclusive::*;
+
+ // this function has a sort of odd structure due to borrowck issues
+ // we may need to replace self.range, so borrows of start and end need to end early
+
+ let at_end;
+ match *self {
+ Empty { .. } => return None, // empty iterators yield no values
+
+ NonEmpty { ref mut start, ref mut end } => {
+
+ // march start towards (maybe past!) end and yield the old value
+ if start <= end {
+ let old = *start;
+ *start = old + 1;
+ return Some(old);
+ }
+ at_end = *end;
+ }
+ };
+
+ // got this far; the range is empty, replace it
+ *self = Empty { at: at_end };
+ None
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ use index::RangeInclusive::*;
+
+ match *self {
+ Empty { .. } => (0, Some(0)),
+
+ NonEmpty { ref start, ref end } => {
+ let added = $steps_add_one(start, end);
+ match added {
+ Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
+ None => (0, None)
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+fn steps_add_one_u8(start: &u8, end: &u8) -> Option<usize> {
+ if *start < *end {
+ Some((*end - *start) as usize)
+ } else {
+ None
+ }
+}
+inclusive!(u8, steps_add_one_u8);
+
+#[test]
+fn test_range() {
+ assert_eq!(RangeInclusive::new(1,10).collect::<Vec<_>>(),
+ vec![1,2,3,4,5,6,7,8,9,10]);
+}
+
+// can be removed if range_contains is stabilized
+pub trait Contains {
+ type Content;
+ fn contains_(&self, item: Self::Content) -> bool;
+}
+
+impl<T: PartialOrd<T>> Contains for Range<T> {
+ type Content = T;
+ fn contains_(&self, item: Self::Content) -> bool {
+ (self.start <= item) && (item < self.end)
+ }
+}
+
+impl<T: PartialOrd<T>> Contains for RangeInclusive<T> {
+ type Content = T;
+ fn contains_(&self, item: Self::Content) -> bool {
+ if let RangeInclusive::NonEmpty{ref start, ref end} = *self {
+ (*start <= item) && (item <= *end)
+ } else { false }
+ }
+}
+
macro_rules! ops {
($ty:ty, $construct:expr) => {
add!($ty, $construct);
@@ -207,12 +327,7 @@ macro_rules! ops {
deref!($ty, usize);
forward_ref_binop!(impl Add, add for $ty, $ty);
- impl Step for $ty {
- #[inline]
- fn step(&self, by: &$ty) -> Option<$ty> {
- Some(*self + *by)
- }
-
+ impl $ty {
#[inline]
#[allow(trivial_numeric_casts)]
fn steps_between(start: &$ty, end: &$ty, by: &$ty) -> Option<usize> {
@@ -233,36 +348,45 @@ macro_rules! ops {
#[inline]
fn steps_between_by_one(start: &$ty, end: &$ty) -> Option<usize> {
- Step::steps_between(start, end, &$construct(1))
- }
-
- #[inline]
- #[allow(unused_comparisons)]
- fn is_negative(&self) -> bool {
- self.0 < 0
+ Self::steps_between(start, end, &$construct(1))
}
+ }
+ impl Iterator for IndexRange<$ty> {
+ type Item = $ty;
#[inline]
- fn replace_one(&mut self) -> Self {
- mem::replace(self, $construct(0))
+ fn next(&mut self) -> Option<$ty> {
+ if self.0.start < self.0.end {
+ let old = self.0.start;
+ self.0.start = old + 1;
+ Some(old)
+ } else {
+ None
+ }
}
-
#[inline]
- fn replace_zero(&mut self) -> Self {
- mem::replace(self, $construct(1))
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ match Self::Item::steps_between_by_one(&self.0.start, &self.0.end) {
+ Some(hint) => (hint, Some(hint)),
+ None => (0, None)
+ }
}
+ }
- #[inline]
- fn add_one(&self) -> Self {
- *self + 1
- }
+ inclusive!($ty, <$ty>::steps_between_by_one);
+ impl DoubleEndedIterator for IndexRange<$ty> {
#[inline]
- fn sub_one(&self) -> Self {
- *self - 1
+ fn next_back(&mut self) -> Option<$ty> {
+ if self.0.start < self.0.end {
+ let new = self.0.end - 1;
+ self.0.end = new;
+ Some(new)
+ } else {
+ None
+ }
}
}
-
impl ops::AddAssign<$ty> for $ty {
#[inline]
fn add_assign(&mut self, rhs: $ty) {
diff --git a/src/input.rs b/src/input.rs
index f2bd461b..8823b89e 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -209,11 +209,10 @@ impl<'a, N: Notify + 'a> Processor<'a, N> {
line: point.line,
col: point.col
}, self.ctx.mouse.cell_side);
- } else if self.ctx.terminal.mode().contains(mode::MOUSE_MOTION) {
- // Only report motion when changing cells
- if prev_line != self.ctx.mouse.line || prev_col != self.ctx.mouse.column {
- self.mouse_report(0 + 32);
- }
+ } else if self.ctx.terminal.mode().contains(mode::MOUSE_MOTION)
+ // Only report motion when changing cells
+ && (prev_line != self.ctx.mouse.line || prev_col != self.ctx.mouse.column) {
+ self.mouse_report(32);
}
}
}
diff --git a/src/lib.rs b/src/lib.rs
index d29204d2..295a674c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,19 +13,14 @@
// limitations under the License.
//
//! Alacritty - The GPU Enhanced Terminal
-#![feature(range_contains)]
-#![feature(inclusive_range_syntax)]
-#![feature(inclusive_range)]
-#![feature(drop_types_in_const)]
-#![feature(step_trait)]
-#![feature(plugin)]
+#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", deny(clippy))]
#![cfg_attr(feature = "clippy", deny(enum_glob_use))]
#![cfg_attr(feature = "clippy", deny(if_not_else))]
#![cfg_attr(feature = "clippy", deny(wrong_pub_self_convention))]
#![cfg_attr(test, feature(test))]
-#![feature(core_intrinsics)]
+#![cfg_attr(feature = "nightly", feature(core_intrinsics))]
#![feature(proc_macro)]
@@ -37,6 +32,8 @@ extern crate copypasta;
extern crate errno;
extern crate font;
extern crate glutin;
+#[macro_use]
+extern crate lazy_static;
extern crate libc;
extern crate mio;
extern crate notify;
diff --git a/src/main.rs b/src/main.rs
index d53daf0f..f6ccc966 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,8 +13,8 @@
// limitations under the License.
//
//! Alacritty - The GPU Enhanced Terminal
-#![feature(plugin)]
#![cfg_attr(feature = "clippy", plugin(clippy))]
+#![cfg_attr(feature = "clippy", feature(plugin))]
#[macro_use]
extern crate alacritty;
diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs
index 10d3d838..a70b1ca3 100644
--- a/src/renderer/mod.rs
+++ b/src/renderer/mod.rs
@@ -24,7 +24,7 @@ use font::{self, Rasterizer, Rasterize, RasterizedGlyph, FontDesc, GlyphKey, Fon
use gl::types::*;
use gl;
use notify::{Watcher as WatcherApi, RecommendedWatcher as Watcher, op};
-use index::{Line, Column};
+use index::{Line, Column, RangeInclusive};
use window::{Size, Pixels};
@@ -225,7 +225,7 @@ impl GlyphCache {
macro_rules! load_glyphs_for_font {
($font:expr) => {
- for i in 32u8...128u8 {
+ for i in RangeInclusive::new(32u8, 128u8) {
cache.load_and_cache_glyph(GlyphKey {
font_key: $font,
c: i as char,
diff --git a/src/selection.rs b/src/selection.rs
index ebc84bee..3e5b799c 100644
--- a/src/selection.rs
+++ b/src/selection.rs
@@ -19,9 +19,8 @@
//! when text is added/removed/scrolled on the screen. The selection should
//! also be cleared if the user clicks off of the selection.
use std::mem;
-use std::ops::RangeInclusive;
-use index::{Point, Column, Side, Linear, Line};
+use index::{Point, Column, RangeInclusive, Side, Linear, Line};
use grid::ToRange;
/// The area selected
@@ -107,14 +106,14 @@ impl Selection {
// Single-cell selections are a special case
if start == end {
- if start_side != end_side {
+ if start_side == end_side {
+ return None;
+ } else {
return Some(Span {
ty: SpanType::Inclusive,
front: *front,
tail: *tail
});
- } else {
- return None;
}
}
@@ -248,7 +247,7 @@ impl ToRange for Span {
SpanType::ExcludeTail => (start, Span::exclude_end(end))
};
- start...end
+ RangeInclusive::new(start, end)
}
}
diff --git a/src/term/cell.rs b/src/term/cell.rs
index 499f99b8..021ce280 100644
--- a/src/term/cell.rs
+++ b/src/term/cell.rs
@@ -96,7 +96,7 @@ impl Cell {
#[inline]
pub fn reset(&mut self, template: &Cell) {
// memcpy template to self
- *self = template.clone();
+ *self = *template;
}
#[inline]
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 690c2f10..45dd8a45 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -13,14 +13,14 @@
// limitations under the License.
//
//! Exports the `Term` type which is a high-level API for the Grid
-use std::ops::{Deref, Range, RangeInclusive};
+use std::ops::{Deref, Range};
use std::ptr;
use std::cmp;
use std::io;
use ansi::{self, Color, NamedColor, Attr, Handler};
use grid::{Grid, ClearRegion, ToRange};
-use index::{self, Point, Column, Line, Linear};
+use index::{self, Point, Column, Line, Linear, IndexRange, Contains, RangeInclusive};
use selection::{Span, Selection};
pub mod cell;
@@ -129,7 +129,7 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
self.column += 1;
let selected = self.selection.as_ref()
- .map(|range| range.contains(index))
+ .map(|range| range.contains_(index))
.unwrap_or(false);
// Skip empty cells
@@ -286,7 +286,7 @@ impl Term {
let grid = Grid::new(num_lines, num_cols, &template);
- let mut tabs = (Column(0)..grid.num_cols())
+ let mut tabs = IndexRange::from(Column(0)..grid.num_cols())
.map(|i| (*i as usize) % TAB_SPACES == 0)
.collect::<Vec<bool>>();
@@ -306,7 +306,7 @@ impl Term {
mode: Default::default(),
scroll_region: scroll_region,
size_info: size,
- template_cell: template.clone(),
+ template_cell: template,
empty_cell: template,
}
}
@@ -424,7 +424,7 @@ impl Term {
// Starting line
res.append(&self.grid, start.line, start.col..);
- let middle_range = (start.line + 1)..(end.line);
+ let middle_range = IndexRange::from((start.line + 1)..(end.line));
for line in middle_range {
res.append(&self.grid, line, ..);
}
@@ -498,7 +498,7 @@ impl Term {
println!("num_cols, num_lines = {}, {}", num_cols, num_lines);
// Resize grids to new size
- let template = self.template_cell.clone();
+ let template = self.template_cell;
self.grid.resize(num_lines, num_cols, &template);
self.alt_grid.resize(num_lines, num_cols, &template);
@@ -507,14 +507,14 @@ impl Term {
self.cursor.col = limit(self.cursor.col, Column(0), num_cols);
// Recreate tabs list
- self.tabs = (Column(0)..self.grid.num_cols())
+ self.tabs = IndexRange::from(Column(0)..self.grid.num_cols())
.map(|i| (*i as usize) % TAB_SPACES == 0)
.collect::<Vec<bool>>();
self.tabs[0] = false;
// Make sure bottom of terminal is clear
- let template = self.empty_cell.clone();
+ let template = self.empty_cell;
self.grid.clear_region((self.cursor.line).., |c| c.reset(&template));
self.alt_grid.clear_region((self.cursor.line).., |c| c.reset(&template));
@@ -538,7 +538,7 @@ impl Term {
::std::mem::swap(&mut self.cursor, &mut self.alt_cursor);
if self.alt {
- let template = self.empty_cell.clone();
+ let template = self.empty_cell;
self.grid.clear(|c| c.reset(&template));
}
}
@@ -551,7 +551,7 @@ impl Term {
debug_println!("scroll_down: {}", lines);
// Copy of cell template; can't have it borrowed when calling clear/scroll
- let template = self.empty_cell.clone();
+ let template = self.empty_cell;
// Clear `lines` lines at bottom of area
{
@@ -576,7 +576,7 @@ impl Term {
debug_println!("scroll_up: {}", lines);
// Copy of cell template; can't have it borrowed when calling clear/scroll
- let template = self.empty_cell.clone();
+ let template = self.empty_cell;
// Clear `lines` lines starting from origin to origin + lines
{
@@ -630,13 +630,13 @@ impl ansi::Handler for Term {
}
unsafe {
- if ::std::intrinsics::unlikely(self.cursor.line == self.grid.num_lines()) {
+ if ::util::unlikely(self.cursor.line == self.grid.num_lines()) {
panic!("cursor fell off grid");
}
}
let cell = &mut self.grid[&self.cursor];
- *cell = self.template_cell.clone();
+ *cell = self.template_cell;
cell.c = c;
self.cursor.col += 1;
}
@@ -682,7 +682,7 @@ impl ansi::Handler for Term {
// Cells were just moved out towards the end of the line; fill in
// between source and dest with blanks.
- let template = self.empty_cell.clone();
+ let template = self.empty_cell;
for c in &mut line[source..destination] {
c.reset(&template);
}
@@ -812,7 +812,7 @@ impl ansi::Handler for Term {
#[inline]
fn insert_blank_lines(&mut self, lines: Line) {
debug_println!("insert_blank_lines: {}", lines);
- if self.scroll_region.contains(self.cursor.line) {
+ if self.scroll_region.contains_(self.cursor.line) {
let origin = self.cursor.line;
self.scroll_down_relative(origin, lines);
}
@@ -821,7 +821,7 @@ impl ansi::Handler for Term {
#[inline]
fn delete_lines(&mut self, lines: Line) {
debug_println!("delete_lines: {}", lines);
- if self.scroll_region.contains(self.cursor.line) {
+ if self.scroll_region.contains_(self.cursor.line) {
let origin = self.cursor.line;
self.scroll_up_relative(origin, lines);
}
@@ -834,7 +834,7 @@ impl ansi::Handler for Term {
let end = start + count;
let row = &mut self.grid[self.cursor.line];
- let template = self.empty_cell.clone();
+ let template = self.empty_cell;
for c in &mut row[start..end] {
c.reset(&template);
}
@@ -861,7 +861,7 @@ impl ansi::Handler for Term {
// Clear last `count` cells in line. If deleting 1 char, need to delete
// 1 cell.
- let template = self.empty_cell.clone();
+ let template = self.empty_cell;
let end = self.size_info.cols() - count;
for c in &mut line[end..] {
c.reset(&template);
@@ -891,7 +891,7 @@ impl ansi::Handler for Term {
#[inline]
fn clear_line(&mut self, mode: ansi::LineClearMode) {
debug_println!("clear_line: {:?}", mode);
- let template = self.empty_cell.clone();
+ let template = self.empty_cell;
match mode {
ansi::LineClearMode::Right => {
let row = &mut self.grid[self.cursor.line];
@@ -917,7 +917,7 @@ impl ansi::Handler for Term {
#[inline]
fn clear_screen(&mut self, mode: ansi::ClearMode) {
debug_println!("clear_screen: {:?}", mode);
- let template = self.empty_cell.clone();
+ let template = self.empty_cell;
match mode {
ansi::ClearMode::Below => {
for row in &mut self.grid[self.cursor.line..] {
diff --git a/src/util.rs b/src/util.rs
index 44f7b3de..ccb22cc9 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -13,6 +13,16 @@
// limitations under the License.
use std::cmp;
+#[cfg(not(feature = "nightly"))]
+#[inline(always)]
+#[cfg_attr(feature = "clippy", allow(inline_always))]
+pub unsafe fn unlikely(x: bool) -> bool {
+ x
+}
+
+#[cfg(feature = "nightly")]
+pub use ::std::intrinsics::unlikely;
+
/// Threading utilities
pub mod thread {
/// Like `thread::spawn`, but with a `name` argument
diff --git a/src/window.rs b/src/window.rs
index b56b28a0..40729e99 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -14,6 +14,7 @@
use std::convert::From;
use std::fmt::{self, Display};
use std::ops::Deref;
+use std::sync::Mutex;
use gl;
use glutin;
@@ -26,13 +27,13 @@ use glutin;
///
/// This will fail horribly if more than one window is created. Don't do that :)
fn window_resize_handler(width: u32, height: u32) {
- unsafe {
- RESIZE_CALLBACK.as_ref().map(|func| func(width, height));
- }
+ RESIZE_CALLBACK.lock().unwrap().as_ref().map(|func| (*func)(width, height));
}
-/// The resize callback invoked by `window_resize_handler`
-static mut RESIZE_CALLBACK: Option<Box<Fn(u32, u32)>> = None;
+lazy_static! {
+ /// The resize callback invoked by `window_resize_handler`
+ static ref RESIZE_CALLBACK: Mutex<Option<Box<Fn(u32, u32) + 'static + Send>>> = Mutex::new(None);
+}
/// Window errors
#[derive(Debug)]
@@ -238,10 +239,9 @@ impl Window {
///
/// This method takes self mutably to ensure there's no race condition
/// setting the callback.
- pub fn set_resize_callback<F: Fn(u32, u32) + 'static>(&mut self, func: F) {
- unsafe {
- RESIZE_CALLBACK = Some(Box::new(func));
- }
+ pub fn set_resize_callback<F: Fn(u32, u32) + 'static + Send>(&mut self, func: F) {
+ let mut guard = RESIZE_CALLBACK.lock().unwrap();
+ *guard = Some(Box::new(func));
}
pub fn inner_size_pixels(&self) -> Option<Size<Pixels<u32>>> {