1
1
mirror of https://github.com/wez/wezterm.git synced 2024-09-11 22:37:11 +03:00

round out quick select mode

* Make alphabet and patterns configurable
* add docs
* Enhance scrollback search to support regex captures so that
  searching for eg: `fo(o)` will select the last `o` in `foo`.

refs: https://github.com/wez/wezterm/issues/732
This commit is contained in:
Wez Furlong 2021-04-25 16:27:39 -07:00
parent 87677a73bf
commit 8ce376753f
12 changed files with 147 additions and 14 deletions

View File

@ -140,6 +140,7 @@ TOC = [
],
),
Page("Scrollback", "scrollback.md"),
Page("Quick Select Mode", "quickselect.md"),
Page("Copy Mode", "copymode.md"),
Page("Hyperlinks", "hyperlinks.md"),
Page("Shell Integration", "shell-integration.md"),

View File

@ -843,6 +843,13 @@ pub struct Config {
pub disable_default_key_bindings: bool,
pub leader: Option<LeaderKey>,
#[serde(default)]
pub disable_default_quick_select_patterns: bool,
#[serde(default)]
pub quick_select_patterns: Vec<String>,
#[serde(default = "default_alphabet")]
pub quick_select_alphabet: String,
#[serde(default)]
pub mouse_bindings: Vec<Mouse>,
#[serde(default)]
@ -1108,6 +1115,10 @@ fn default_alternate_buffer_wheel_scroll_speed() -> u8 {
3
}
fn default_alphabet() -> String {
"asdfqwerzxcvjklmiuopghtybn".to_string()
}
fn default_word_boundary() -> String {
" \t\n{[}]()\"'`".to_string()
}

View File

@ -41,6 +41,7 @@ As features stabilize some brief notes about them will accumulate here.
* New: [format-tab-title](config/lua/window-events/format-tab-title.md) hook for customizing the text in tab titles. [#647](https://github.com/wez/wezterm/issues/647)
* New: [force_reverse_video_cursor](config/lua/config/force_reverse_video_cursor.md) setting to override the cursor color scheme settings. [#706](https://github.com/wez/wezterm/issues/706)
* Fixed: ssh config parsing now expands `~` to your home directory for appropriate options; previously only `%d` and `${HOME}` were substituted. [#729](https://github.com/wez/wezterm/issues/729)
* New: [Quick Select Mode](quickselect.md) for a tmux-fingers/tmux-thumbs style mouse-less select and copy flow [#732](https://github.com/wez/wezterm/issues/732)
### 20210405-110924-a5bb5be8

View File

@ -172,6 +172,7 @@ The default key bindings are:
| `SUPER` | `f` | `Search={CaseSensitiveString=""}` |
| `CTRL+SHIFT` | `F` | `Search={CaseSensitiveString=""}` |
| `CTRL+SHIFT` | `X` | `ActivateCopyMode` |
| `CTRL+SHIFT` | ` ` | `QuickSelect` (*since: nightly builds only*) |
| `CTRL+SHIFT+ALT` | `"` | `SplitVertical={domain="CurrentPaneDomain"}` |
| `CTRL+SHIFT+ALT` | `%` | `SplitHorizontal={domain="CurrentPaneDomain"}` |
| `CTRL+SHIFT+ALT` | `LeftArrow` | `AdjustPaneSize={"Left", 1}` |

View File

@ -0,0 +1,7 @@
# disable_default_quick_select_patterns
*Since: nightly builds only*
When set to `true`, the default set of quick select patterns
are omitted, and your [quick_select_patterns](quick_select_patterns.md)
config specifies the total set of patterns used for [quick select mode](../../../quickselect.md).

View File

@ -0,0 +1,21 @@
# quick_select_alphabet
*Since: nightly builds only*
Specify the alphabet used to produce labels for the items
matched in [quick select mode](../../../quickselect.md).
The default alphabet is `"asdfqwerzxcvjklmiuopghtybn"` which
means that the first matching item from the bottom is labelled
with an `a`, the second with `s` and so forth; these are easily
accessible characters in a `qwerty` keyboard layout.
|Keyboard Layout|Suggested Alphabet|
|---------------|------------------|
|`qwerty` |`"asdfqwerzxcvjklmiuopghtybn"` (this is the default)|
|`qwertz` |`"asdfqweryxcvjkluiopmghtzbn"`|
|`azerty` |`"qsdfazerwxcvjklmuiopghtybn"`|
|`dvorak` |`"aoeuqjkxpyhtnsgcrlmwvzfidb"`|
|`colemak` |`"arstqwfpzxcvneioluymdhgjbk"`|

View File

@ -0,0 +1,17 @@
# quick_select_patterns
*Since: nightly builds only*
Specify additional patterns to match when in [quick select mode](../../../quickselect.md).
This setting is a table listing out a set of regular expressions.
```lua
return {
quick_select_patterns = {
-- match things that look like sha1 hashes
-- (this is actually one of the default patterns)
"[0-9a-f]{7,40}",
}
}
```

View File

@ -0,0 +1,15 @@
# QuickSelect
*Since: nightly builds only*
Activates [Quick Select Mode](../../../quickselect.md).
```lua
```lua
local wezterm = require 'wezterm';
return {
keys = {
{key=" ", mods="SHIFT|CTRL", action="QuickSelect"},
}
}
```

View File

@ -3,7 +3,10 @@
*since: 20200607-144723-74889cd4*
Copy mode allows you to make selections using the keyboard; no need to reach
for your mouse or trackpad.
for your mouse or trackpad. Copy mode is similar to [quick select
mode](quickselect.md) but is geared up for describing selections based on
keyboard control, whereas quick select mode is used to quickly select and
copy commonly used patterns.
The `ActivateCopyMode` key assignment is used to enter copy mode; it is
bound to `CTRL-SHIFT-X` by default.

26
docs/quickselect.md Normal file
View File

@ -0,0 +1,26 @@
## Quick Select Mode
*Since: nightly builds only*
Quick Select mode allows you to quickly highlight text that matches
commonly copied patterns, select a match by typing a one-or-two character
prefix and copy it to the clipboard.
The `QuickSelect` key assignment is used to enter quick select mode; it is
bound to `CTRL-SHIFT-SPACE` by default.
When quick select mode is activated, the terminal is searched for items that
match the patterns defined by the
[quick_select_patterns](config/lua/config/quick_select_patterns.md)
configuration combined with a default set of patterns that match things such as
URL and path fragments, git hashes, ip addresses and numbers.
Matches are highlighted and shown with a one or two character prefix derived
from the [quick_select_alphabet](config/lua/config/quick_select_alphabet.md)
configuration.
The bottom of the screen shows your input text along with a hint as to what to
do next; typing in a highlighted prefix will cause that text to be selected and
copied to the clipboard, and quick select mode will be cancelled. Pressing
`ESCAPE` will cancel quick select mode.

View File

@ -340,15 +340,25 @@ impl Pane for LocalPane {
}
Pattern::Regex(r) => {
if let Ok(re) = regex::Regex::new(r) {
for m in re.find_iter(haystack) {
let (start_x, start_y) = haystack_idx_to_coord(m.start(), coords);
let (end_x, end_y) = haystack_idx_to_coord(m.end(), coords);
results.push(SearchResult {
start_x,
start_y,
end_x,
end_y,
});
// Allow for the regex to contain captures
for c in re.captures_iter(haystack) {
// Look for the captures in reverse order, as index==0 is
// the whole matched string. We can't just call
// `c.iter().rev()` as the capture iterator isn't double-ended.
for idx in (0..c.len()).rev() {
if let Some(m) = c.get(idx) {
let (start_x, start_y) =
haystack_idx_to_coord(m.start(), coords);
let (end_x, end_y) = haystack_idx_to_coord(m.end(), coords);
results.push(SearchResult {
start_x,
start_y,
end_x,
end_y,
});
break;
}
}
}
}
}

View File

@ -1,6 +1,7 @@
use crate::selection::{SelectionCoordinate, SelectionRange};
use crate::termwindow::TermWindow;
use config::keyassignment::{ClipboardCopyDestination, ScrollbackEraseMode};
use config::ConfigHandle;
use mux::domain::DomainId;
use mux::pane::{Pane, PaneId, Pattern, SearchResult};
use mux::renderable::*;
@ -18,7 +19,6 @@ use wezterm_term::color::ColorPalette;
use wezterm_term::{Clipboard, KeyCode, KeyModifiers, Line, MouseEvent, StableRowIndex};
use window::WindowOps;
// TODO: make this configurable
const PATTERNS: [&str; 14] = [
// markdown_url
r"\[[^]]*\]\(([^)]+)\)",
@ -49,7 +49,6 @@ const PATTERNS: [&str; 14] = [
// number
r"[0-9]{4,}",
];
const QWERTY_ALPHABET: &str = "asdfqwerzxcvjklmiuopghtybn";
/// This function computes a set of labels for a given alphabet.
/// It is derived from https://github.com/fcsonline/tmux-thumbs/blob/master/src/alphabets.rs
@ -168,6 +167,8 @@ struct QuickSelectRenderable {
/// We use this to cancel ourselves later
window: ::window::Window,
config: ConfigHandle,
}
impl QuickSelectOverlay {
@ -175,7 +176,25 @@ impl QuickSelectOverlay {
let viewport = term_window.get_viewport(pane.pane_id());
let dims = pane.get_dimensions();
let pattern = format!("({})", PATTERNS.join("|"));
let config = term_window.config.clone();
let mut pattern = "(".to_string();
if !config.disable_default_quick_select_patterns {
for p in &PATTERNS {
if pattern.len() > 1 {
pattern.push('|');
}
pattern.push_str(p);
}
}
for p in &config.quick_select_patterns {
if pattern.len() > 1 {
pattern.push('|');
}
pattern.push_str(p);
}
pattern.push(')');
let pattern = Pattern::Regex(pattern);
let window = term_window.window.clone().unwrap();
@ -193,6 +212,7 @@ impl QuickSelectOverlay {
result_pos: None,
width: dims.cols,
height: dims.viewport_rows,
config,
};
let search_row = renderer.compute_search_row();
@ -487,7 +507,7 @@ impl QuickSelectRenderable {
fn recompute_results(&mut self) {
let num_results = self.results.len();
let labels = compute_labels_for_alphabet(QWERTY_ALPHABET, num_results);
let labels = compute_labels_for_alphabet(&self.config.quick_select_alphabet, num_results);
self.by_label.clear();
for ((result_index, res), label) in self