Skip to content

Commit e887912

Browse files
committed
Merge branch 'master' into multiple-language-servers
2 parents f2ee673 + 682bcc3 commit e887912

40 files changed

+1071
-138
lines changed

base16_theme.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
"comment" = { fg = "gray" }
1111
"ui.statusline" = { fg = "black", bg = "white" }
1212
"ui.statusline.inactive" = { fg = "gray", bg = "white" }
13-
"ui.help" = { modifiers = ["reversed"] }
1413
"ui.cursor" = { fg = "white", modifiers = ["reversed"] }
1514
"variable" = "red"
1615
"constant.numeric" = "yellow"

book/src/generated/lang-support.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
| heex || | | |
3939
| html || | | `vscode-html-language-server` |
4040
| iex || | | |
41-
| java || | | |
41+
| java || | | `jdtls` |
4242
| javascript || || `typescript-language-server` |
4343
| json || || `vscode-json-language-server` |
4444
| jsx || || `typescript-language-server` |
@@ -76,8 +76,10 @@
7676
| ruby |||| `solargraph` |
7777
| rust |||| `rust-analyzer` |
7878
| scala || || `metals` |
79+
| scheme || | | |
7980
| solidity || | | `solc` |
8081
| sql || | | |
82+
| sshclientconfig || | | |
8183
| svelte || || `svelteserver` |
8284
| swift || | | `sourcekit-lsp` |
8385
| tablegen |||| |

book/src/keymap.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
| `%` | Select entire file | `select_all` |
108108
| `x` | Select current line, if already selected, extend to next line | `extend_line` |
109109
| `X` | Extend selection to line bounds (line-wise selection) | `extend_to_line_bounds` |
110+
| `Alt-x` | Shrink selection to line bounds (line-wise selection) | `shrink_to_line_bounds` |
110111
| `J` | Join lines inside selection | `join_selections` |
111112
| `K` | Keep selections matching the regex | `keep_selections` |
112113
| `Alt-K` | Remove selections matching the regex | `remove_selections` |
@@ -367,6 +368,7 @@ Keys to use within prompt, Remapping currently not supported.
367368
| `Ctrl-s` | Insert a word under doc cursor, may be changed to Ctrl-r Ctrl-w later |
368369
| `Ctrl-p`, `Up` | Select previous history |
369370
| `Ctrl-n`, `Down` | Select next history |
371+
| `Ctrl-r` | Insert the content of the register selected by following input char |
370372
| `Tab` | Select next completion item |
371373
| `BackTab` | Select previous completion item |
372374
| `Enter` | Open selected |

book/src/themes.md

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -205,35 +205,40 @@ These scopes are used for theming the editor interface.
205205
- `hover` - for hover popup ui
206206

207207

208-
| Key | Notes |
209-
| --- | --- |
210-
| `ui.background` | |
211-
| `ui.cursor` | |
212-
| `ui.cursor.insert` | |
213-
| `ui.cursor.select` | |
214-
| `ui.cursor.match` | Matching bracket etc. |
215-
| `ui.cursor.primary` | Cursor with primary selection |
216-
| `ui.linenr` | Line numbers |
217-
| `ui.linenr.selected` | Line number for the line the cursor is on |
218-
| `ui.statusline` | Statusline |
219-
| `ui.statusline.inactive` | Statusline (unfocused document) |
220-
| `ui.popup` | Documentation popups (e.g space-k) |
221-
| `ui.popup.info` | Prompt for multiple key options |
222-
| `ui.window` | Border lines separating splits |
223-
| `ui.help` | Description box for commands |
224-
| `ui.text` | Command prompts, popup text, etc. |
225-
| `ui.text.focus` | |
226-
| `ui.text.info` | The key: command text in `ui.popup.info` boxes |
227-
| `ui.virtual.ruler` | Ruler columns (see the [`editor.rulers` config][rulers-config])|
228-
| `ui.virtual.whitespace` | Visible white-space characters |
229-
| `ui.menu` | Code and command completion menus |
230-
| `ui.menu.selected` | Selected autocomplete item |
231-
| `ui.selection` | For selections in the editing area |
232-
| `ui.selection.primary` | |
233-
| `warning` | Diagnostics warning (gutter) |
234-
| `error` | Diagnostics error (gutter) |
235-
| `info` | Diagnostics info (gutter) |
236-
| `hint` | Diagnostics hint (gutter) |
237-
| `diagnostic` | For text in editing area |
208+
| Key | Notes |
209+
| --- | --- |
210+
| `ui.background` | |
211+
| `ui.background.separator` | Picker separator below input line |
212+
| `ui.cursor` | |
213+
| `ui.cursor.insert` | |
214+
| `ui.cursor.select` | |
215+
| `ui.cursor.match` | Matching bracket etc. |
216+
| `ui.cursor.primary` | Cursor with primary selection |
217+
| `ui.linenr` | Line numbers |
218+
| `ui.linenr.selected` | Line number for the line the cursor is on |
219+
| `ui.statusline` | Statusline |
220+
| `ui.statusline.inactive` | Statusline (unfocused document) |
221+
| `ui.popup` | Documentation popups (e.g space-k) |
222+
| `ui.popup.info` | Prompt for multiple key options |
223+
| `ui.window` | Border lines separating splits |
224+
| `ui.help` | Description box for commands |
225+
| `ui.text` | Command prompts, popup text, etc. |
226+
| `ui.text.focus` | |
227+
| `ui.text.info` | The key: command text in `ui.popup.info` boxes |
228+
| `ui.virtual.ruler` | Ruler columns (see the [`editor.rulers` config][rulers-config])|
229+
| `ui.virtual.whitespace` | Visible white-space characters |
230+
| `ui.menu` | Code and command completion menus |
231+
| `ui.menu.selected` | Selected autocomplete item |
232+
| `ui.selection` | For selections in the editing area |
233+
| `ui.selection.primary` | |
234+
| `warning` | Diagnostics warning (gutter) |
235+
| `error` | Diagnostics error (gutter) |
236+
| `info` | Diagnostics info (gutter) |
237+
| `hint` | Diagnostics hint (gutter) |
238+
| `diagnostic` | Diagnostics fallback style (editing area) |
239+
| `diagnostic.hint` | Diagnostics hint (editing area) |
240+
| `diagnostic.info` | Diagnostics info (editing area) |
241+
| `diagnostic.warning` | Diagnostics warning (editing area) |
242+
| `diagnostic.error` | Diagnostics error (editing area) |
238243

239244
[rulers-config]: ./configuration.md#editor-section

helix-core/src/syntax.rs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ pub struct TextObjectQuery {
235235
pub query: Query,
236236
}
237237

238+
#[derive(Debug)]
238239
pub enum CapturedNode<'a> {
239240
Single(Node<'a>),
240241
/// Guaranteed to be not empty
@@ -269,12 +270,12 @@ impl TextObjectQuery {
269270
/// and support for this is partial and could use improvement.
270271
///
271272
/// ```query
272-
/// ;; supported:
273273
/// (comment)+ @capture
274274
///
275-
/// ;; unsupported:
275+
/// ; OR
276276
/// (
277-
/// (comment)+
277+
/// (comment)*
278+
/// .
278279
/// (function)
279280
/// ) @capture
280281
/// ```
@@ -300,28 +301,29 @@ impl TextObjectQuery {
300301
let capture_idx = capture_names
301302
.iter()
302303
.find_map(|cap| self.query.capture_index_for_name(cap))?;
303-
let captures = cursor.matches(&self.query, node, RopeProvider(slice));
304-
305-
let nodes = captures.flat_map(move |mat| {
306-
let captures = mat.captures.iter().filter(move |c| c.index == capture_idx);
307-
let nodes = captures.map(|c| c.node);
308-
let pattern_idx = mat.pattern_index;
309-
let quantifier = self.query.capture_quantifiers(pattern_idx)[capture_idx as usize];
310-
311-
let iter: Box<dyn Iterator<Item = CapturedNode>> = match quantifier {
312-
CaptureQuantifier::OneOrMore | CaptureQuantifier::ZeroOrMore => {
313-
let nodes: Vec<Node> = nodes.collect();
314-
if nodes.is_empty() {
315-
Box::new(std::iter::empty())
316-
} else {
317-
Box::new(std::iter::once(CapturedNode::Grouped(nodes)))
318-
}
304+
305+
let nodes = cursor
306+
.captures(&self.query, node, RopeProvider(slice))
307+
.filter_map(move |(mat, _)| {
308+
let nodes: Vec<_> = mat
309+
.captures
310+
.iter()
311+
.filter_map(|x| {
312+
if x.index == capture_idx {
313+
Some(x.node)
314+
} else {
315+
None
316+
}
317+
})
318+
.collect();
319+
320+
if nodes.len() > 1 {
321+
Some(CapturedNode::Grouped(nodes))
322+
} else {
323+
nodes.into_iter().map(CapturedNode::Single).next()
319324
}
320-
_ => Box::new(nodes.map(CapturedNode::Single)),
321-
};
325+
});
322326

323-
iter
324-
});
325327
Some(nodes)
326328
}
327329
}
@@ -1123,8 +1125,8 @@ pub(crate) fn generate_edits(
11231125
use std::sync::atomic::{AtomicUsize, Ordering};
11241126
use std::{iter, mem, ops, str, usize};
11251127
use tree_sitter::{
1126-
CaptureQuantifier, Language as Grammar, Node, Parser, Point, Query, QueryCaptures, QueryCursor,
1127-
QueryError, QueryMatch, Range, TextProvider, Tree,
1128+
Language as Grammar, Node, Parser, Point, Query, QueryCaptures, QueryCursor, QueryError,
1129+
QueryMatch, Range, TextProvider, Tree,
11281130
};
11291131

11301132
const CANCELLATION_CHECK_INTERVAL: usize = 100;

helix-term/src/commands.rs

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ impl MappableCommand {
247247
extend_line, "Select current line, if already selected, extend to next line",
248248
extend_line_above, "Select current line, if already selected, extend to previous line",
249249
extend_to_line_bounds, "Extend selection to line bounds (line-wise selection)",
250+
shrink_to_line_bounds, "Shrink selection to line bounds (line-wise selection)",
250251
delete_selection, "Delete selection",
251252
delete_selection_noyank, "Delete selection, without yanking",
252253
change_selection, "Change selection (delete and enter insert mode)",
@@ -360,6 +361,11 @@ impl MappableCommand {
360361
jump_view_left, "Jump to the split to the left",
361362
jump_view_up, "Jump to the split above",
362363
jump_view_down, "Jump to the split below",
364+
swap_view_right, "Swap with the split to the right",
365+
swap_view_left, "Swap with the split to the left",
366+
swap_view_up, "Swap with the split above",
367+
swap_view_down, "Swap with the split below",
368+
transpose_view, "Transpose splits",
363369
rotate_view, "Goto next window",
364370
hsplit, "Horizontal bottom split",
365371
hsplit_new, "Horizontal bottom split scratch buffer",
@@ -1224,11 +1230,11 @@ fn replace(cx: &mut Context) {
12241230
// need to wait for next key
12251231
cx.on_next_key(move |cx, event| {
12261232
let (view, doc) = current!(cx.editor);
1227-
let ch = match event {
1233+
let ch: Option<&str> = match event {
12281234
KeyEvent {
12291235
code: KeyCode::Char(ch),
12301236
..
1231-
} => Some(&ch.encode_utf8(&mut buf[..])[..]),
1237+
} => Some(ch.encode_utf8(&mut buf[..])),
12321238
KeyEvent {
12331239
code: KeyCode::Enter,
12341240
..
@@ -1937,6 +1943,47 @@ fn extend_to_line_bounds(cx: &mut Context) {
19371943
);
19381944
}
19391945

1946+
fn shrink_to_line_bounds(cx: &mut Context) {
1947+
let (view, doc) = current!(cx.editor);
1948+
1949+
doc.set_selection(
1950+
view.id,
1951+
doc.selection(view.id).clone().transform(|range| {
1952+
let text = doc.text();
1953+
1954+
let (start_line, end_line) = range.line_range(text.slice(..));
1955+
1956+
// Do nothing if the selection is within one line to prevent
1957+
// conditional logic for the behavior of this command
1958+
if start_line == end_line {
1959+
return range;
1960+
}
1961+
1962+
let mut start = text.line_to_char(start_line);
1963+
1964+
// line_to_char gives us the start position of the line, so
1965+
// we need to get the start position of the next line. In
1966+
// the editor, this will correspond to the cursor being on
1967+
// the EOL whitespace charactor, which is what we want.
1968+
let mut end = text.line_to_char((end_line + 1).min(text.len_lines()));
1969+
1970+
if start != range.from() {
1971+
start = text.line_to_char((start_line + 1).min(text.len_lines()));
1972+
}
1973+
1974+
if end != range.to() {
1975+
end = text.line_to_char(end_line);
1976+
}
1977+
1978+
if range.anchor <= range.head {
1979+
Range::new(start, end)
1980+
} else {
1981+
Range::new(end, start)
1982+
}
1983+
}),
1984+
);
1985+
}
1986+
19401987
enum Operation {
19411988
Delete,
19421989
Change,
@@ -3860,6 +3907,26 @@ fn jump_view_down(cx: &mut Context) {
38603907
cx.editor.focus_down()
38613908
}
38623909

3910+
fn swap_view_right(cx: &mut Context) {
3911+
cx.editor.swap_right()
3912+
}
3913+
3914+
fn swap_view_left(cx: &mut Context) {
3915+
cx.editor.swap_left()
3916+
}
3917+
3918+
fn swap_view_up(cx: &mut Context) {
3919+
cx.editor.swap_up()
3920+
}
3921+
3922+
fn swap_view_down(cx: &mut Context) {
3923+
cx.editor.swap_down()
3924+
}
3925+
3926+
fn transpose_view(cx: &mut Context) {
3927+
cx.editor.transpose_view()
3928+
}
3929+
38633930
// split helper, clear it later
38643931
fn split(cx: &mut Context, action: Action) {
38653932
let (view, doc) = current!(cx.editor);

helix-term/src/commands/typed.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,8 +781,11 @@ fn reload(
781781
_args: &[Cow<str>],
782782
_event: PromptEvent,
783783
) -> anyhow::Result<()> {
784+
let scrolloff = cx.editor.config().scrolloff;
784785
let (view, doc) = current!(cx.editor);
785-
doc.reload(view.id)
786+
doc.reload(view.id).map(|_| {
787+
view.ensure_cursor_in_view(doc, scrolloff);
788+
})
786789
}
787790

788791
fn tree_sitter_scopes(

helix-term/src/keymap/default.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub fn default() -> HashMap<Mode, Keymap> {
8787
"%" => select_all,
8888
"x" => extend_line,
8989
"X" => extend_to_line_bounds,
90-
// crop_to_whole_line
90+
"A-x" => shrink_to_line_bounds,
9191

9292
"m" => { "Match"
9393
"m" => match_brackets,
@@ -171,6 +171,7 @@ pub fn default() -> HashMap<Mode, Keymap> {
171171
"C-w" | "w" => rotate_view,
172172
"C-s" | "s" => hsplit,
173173
"C-v" | "v" => vsplit,
174+
"C-t" | "t" => transpose_view,
174175
"f" => goto_file_hsplit,
175176
"F" => goto_file_vsplit,
176177
"C-q" | "q" => wclose,
@@ -179,6 +180,10 @@ pub fn default() -> HashMap<Mode, Keymap> {
179180
"C-j" | "j" | "down" => jump_view_down,
180181
"C-k" | "k" | "up" => jump_view_up,
181182
"C-l" | "l" | "right" => jump_view_right,
183+
"L" => swap_view_right,
184+
"K" => swap_view_up,
185+
"H" => swap_view_left,
186+
"J" => swap_view_down,
182187
"n" => { "New split scratch buffer"
183188
"C-s" | "s" => hsplit_new,
184189
"C-v" | "v" => vsplit_new,
@@ -226,6 +231,7 @@ pub fn default() -> HashMap<Mode, Keymap> {
226231
"C-w" | "w" => rotate_view,
227232
"C-s" | "s" => hsplit,
228233
"C-v" | "v" => vsplit,
234+
"C-t" | "t" => transpose_view,
229235
"f" => goto_file_hsplit,
230236
"F" => goto_file_vsplit,
231237
"C-q" | "q" => wclose,
@@ -234,6 +240,10 @@ pub fn default() -> HashMap<Mode, Keymap> {
234240
"C-j" | "j" | "down" => jump_view_down,
235241
"C-k" | "k" | "up" => jump_view_up,
236242
"C-l" | "l" | "right" => jump_view_right,
243+
"H" => swap_view_left,
244+
"J" => swap_view_down,
245+
"K" => swap_view_up,
246+
"L" => swap_view_right,
237247
"n" => { "New split scratch buffer"
238248
"C-s" | "s" => hsplit_new,
239249
"C-v" | "v" => vsplit_new,

0 commit comments

Comments
 (0)