From 958a4326a2615c0a486a6ef450729625a97b9118 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Wed, 3 Oct 2018 03:15:01 +0200 Subject: [PATCH] Change default URL launchers The default configuration has been altered to use `xdg-open` to launch URLs on linux and `open` to do so on macOS. This should allow clicking on links by default on most systems. Some changes which were made to the reverse grid iterator have also been reverted. Alacritty also doesn't crash anymore when the program specified as `url_launcher` isn't installed on the system. Instead it will print a warning to the log. --- alacritty.yml | 5 +---- alacritty_macos.yml | 5 +---- src/event.rs | 30 ++++++++++++++++++------------ src/grid/mod.rs | 9 +++++++-- src/grid/tests.rs | 8 ++++---- src/input.rs | 10 +++++----- src/term/mod.rs | 4 ++-- 7 files changed, 38 insertions(+), 33 deletions(-) diff --git a/alacritty.yml b/alacritty.yml index a0765b12..5a841263 100644 --- a/alacritty.yml +++ b/alacritty.yml @@ -263,10 +263,7 @@ mouse: # # This program is executed when clicking on a text which is recognized as a URL. # The URL is always added to the command as the last parameter. - #url_launcher: - # program: /usr/bin/firefox - # args: - # - --new-tab + url_launcher: xdg-open selection: semantic_escape_chars: ",│`|:\"' ()[]{}<>" diff --git a/alacritty_macos.yml b/alacritty_macos.yml index cf102764..c8ca3a0f 100644 --- a/alacritty_macos.yml +++ b/alacritty_macos.yml @@ -261,10 +261,7 @@ mouse: # # This program is executed when clicking on a text which is recognized as a URL. # The URL is always added to the command as the last parameter. - #url_launcher: - # program: /usr/bin/firefox - # args: - # - --new-tab + url_launcher: open selection: semantic_escape_chars: ",│`|:\"' ()[]{}<>" diff --git a/src/event.rs b/src/event.rs index 9d29f2ed..890ca3a7 100644 --- a/src/event.rs +++ b/src/event.rs @@ -13,7 +13,7 @@ use copypasta::{Clipboard, Load, Store, Buffer as ClipboardBuffer}; use url::Url; use ansi::{Handler, ClearMode}; -use grid::Scroll; +use grid::{Scroll, BidirectionalIterator}; use config::{self, Config}; use cli::Options; use display::OnResize; @@ -21,11 +21,13 @@ use index::{Line, Column, Side, Point}; use input::{self, MouseBinding, KeyBinding}; use selection::Selection; use sync::FairMutex; -use term::{Term, SizeInfo, TermMode, Cell}; +use term::{Term, SizeInfo, TermMode}; use util::limit; use util::fmt::Red; use window::Window; +const URL_SEPARATOR_CHARS: [char; 3] = [' ', '"', '\'']; + /// Byte sequences are sent to a `Notify` in response to some events pub trait Notify { /// Notify that an escape sequence should be written to the pty @@ -116,18 +118,22 @@ impl<'a, N: Notify + 'a> input::ActionContext for ActionContext<'a, N> { // Create forwards and backwards iterators let iterf = grid.iter_from(point); point.col += 1; - let iterb = grid.iter_from(point); - - // Put all characters until separators into a String - let url_char = |cell: &&Cell| { - cell.c != ' ' && cell.c != '\'' && cell.c != '"' - }; + let mut iterb = grid.iter_from(point); + // Put all characters until separators into a string let mut buf = String::new(); - - iterb.rev().take_while(url_char).for_each(|cell| buf.push(cell.c)); - buf = buf.chars().rev().collect(); - iterf.take_while(url_char).for_each(|cell| buf.push(cell.c)); + while let Some(cell) = iterb.prev() { + if URL_SEPARATOR_CHARS.contains(&cell.c) { + break; + } + buf.insert(0, cell.c); + } + for cell in iterf { + if URL_SEPARATOR_CHARS.contains(&cell.c) { + break; + } + buf.push(cell.c); + } // Check if string is valid url match Url::parse(&buf) { diff --git a/src/grid/mod.rs b/src/grid/mod.rs index 3d39f0ac..9e15bd02 100644 --- a/src/grid/mod.rs +++ b/src/grid/mod.rs @@ -31,6 +31,11 @@ use self::storage::Storage; const MIN_INIT_SIZE: usize = 1_000; +/// Bidirection iterator +pub trait BidirectionalIterator: Iterator { + fn prev(&mut self) -> Option; +} + /// An item in the grid along with its Line and Column. pub struct Indexed { pub inner: T, @@ -469,8 +474,8 @@ impl<'a, T> Iterator for GridIterator<'a, T> { } } -impl<'a, T> DoubleEndedIterator for GridIterator<'a, T> { - fn next_back(&mut self) -> Option { +impl<'a, T> BidirectionalIterator for GridIterator<'a, T> { + fn prev(&mut self) -> Option { let num_cols = self.grid.num_cols(); match self.cur { diff --git a/src/grid/tests.rs b/src/grid/tests.rs index 78728464..e136e3b3 100644 --- a/src/grid/tests.rs +++ b/src/grid/tests.rs @@ -14,7 +14,7 @@ //! Tests for the Gird -use super::{Grid}; +use super::{Grid, BidirectionalIterator}; use index::{Point, Line, Column}; // Scroll up moves lines upwards @@ -112,7 +112,7 @@ fn test_iter() { col: Column(0), }); - assert_eq!(None, iter.next_back()); + assert_eq!(None, iter.prev()); assert_eq!(Some(&1), iter.next()); assert_eq!(Column(1), iter.cur.col); assert_eq!(4, iter.cur.line); @@ -126,7 +126,7 @@ fn test_iter() { assert_eq!(Column(0), iter.cur.col); assert_eq!(3, iter.cur.line); - assert_eq!(Some(&4), iter.next_back()); + assert_eq!(Some(&4), iter.prev()); assert_eq!(Column(4), iter.cur.col); assert_eq!(4, iter.cur.line); @@ -137,5 +137,5 @@ fn test_iter() { col: Column(4), }); assert_eq!(None, final_iter.next()); - assert_eq!(Some(&23), final_iter.next_back()); + assert_eq!(Some(&23), final_iter.prev()); } diff --git a/src/input.rs b/src/input.rs index 4fabad73..56ae36eb 100644 --- a/src/input.rs +++ b/src/input.rs @@ -494,11 +494,11 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> { if let Some(text) = self.ctx.url(Point::new(point.line.0, point.col)) { let mut args = launcher.args().to_vec(); args.push(text); - debug!("Launching: {} {:?}", launcher.program(), args); - Command::new(launcher.program()) - .args(&args) - .spawn() - .expect("url launcher error"); + match Command::new(launcher.program()).args(&args).spawn() { + Ok(_) => debug!("Launching: {} {:?}", launcher.program(), args), + Err(_) => warn!("Unable to launch: {} {:?}", launcher.program(), args), + } + } } } diff --git a/src/term/mod.rs b/src/term/mod.rs index ce1d3a5b..9be8b96b 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -23,7 +23,7 @@ use unicode_width::UnicodeWidthChar; use font::{self, Size}; use ansi::{self, Color, NamedColor, Attr, Handler, CharsetIndex, StandardCharset, CursorStyle}; -use grid::{Grid, Indexed, IndexRegion, DisplayIter, Scroll, ViewportPosition}; +use grid::{BidirectionalIterator, Grid, Indexed, IndexRegion, DisplayIter, Scroll, ViewportPosition}; use index::{self, Point, Column, Line, IndexRange, Contains, RangeInclusive, Linear}; use selection::{self, Selection, Locations}; use config::{Config, VisualBellAnimation}; @@ -44,7 +44,7 @@ impl selection::SemanticSearch for Term { let mut iter = self.grid.iter_from(point); let last_col = self.grid.num_cols() - Column(1); - while let Some(cell) = iter.next_back() { + while let Some(cell) = iter.prev() { if self.semantic_escape_chars.contains(cell.c) { break; }