mirror of https://github.com/helix-editor/helix
Merge 893f4c8ece
into 205e7ece70
commit
8ef154f4b3
|
@ -89,3 +89,6 @@
|
|||
| `:read`, `:r` | Load a file into buffer |
|
||||
| `:echo` | Prints the given arguments to the statusline. |
|
||||
| `:noop` | Does nothing. |
|
||||
| `:align-text-left`, `:atl` | Align text to the left |
|
||||
| `:align-text-center`, `:atc` | Center-align text, optionally pass a number overriding the current document's text width |
|
||||
| `:align-text-right`, `:atr` | Align text to the right, optionally pass a number overriding the current document's text width |
|
||||
|
|
|
@ -204,6 +204,84 @@ fn buffer_gather_paths_impl(editor: &mut Editor, args: Args) -> Vec<DocumentId>
|
|||
document_ids
|
||||
}
|
||||
|
||||
fn align_text_impl(
|
||||
cx: &mut compositor::Context,
|
||||
args: Args,
|
||||
event: PromptEvent,
|
||||
format: fn(usize, &str) -> String,
|
||||
) -> anyhow::Result<()> {
|
||||
if event != PromptEvent::Validate {
|
||||
return Ok(());
|
||||
}
|
||||
let editor_text_width = cx.editor.config().text_width;
|
||||
let (view, doc) = current!(cx.editor);
|
||||
let text = doc.text().slice(..);
|
||||
|
||||
let custom_text_width = args.first().map(|arg| {
|
||||
arg.parse::<usize>()
|
||||
.map_err(|_| anyhow!("Could not parse argument as a number: {arg}"))
|
||||
});
|
||||
|
||||
let text_width = custom_text_width.unwrap_or(Ok(doc
|
||||
.language_config()
|
||||
.and_then(|c| c.text_width)
|
||||
.unwrap_or(editor_text_width)))?;
|
||||
|
||||
let lines = get_lines(doc, view.id);
|
||||
let mut changes = Vec::with_capacity(lines.len());
|
||||
|
||||
for line_idx in lines {
|
||||
let line = doc.text().line(line_idx);
|
||||
let old_line = line.to_string();
|
||||
|
||||
let aligned_line = format(text_width, old_line.trim());
|
||||
let aligned_line = aligned_line.trim_end();
|
||||
let tendril = Tendril::from(aligned_line);
|
||||
|
||||
changes.push((
|
||||
text.line_to_char(line_idx),
|
||||
text.line_to_char(line_idx + 1) - doc.line_ending.len_chars(),
|
||||
Some(tendril),
|
||||
))
|
||||
}
|
||||
|
||||
let transaction = Transaction::change(doc.text(), changes.into_iter());
|
||||
|
||||
doc.apply(&transaction, view.id);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn align_text_left(
|
||||
cx: &mut compositor::Context,
|
||||
args: Args,
|
||||
event: PromptEvent,
|
||||
) -> anyhow::Result<()> {
|
||||
align_text_impl(cx, args, event, |text_width, text| {
|
||||
format!("{:<text_width$}", text)
|
||||
})
|
||||
}
|
||||
|
||||
fn align_text_center(
|
||||
cx: &mut compositor::Context,
|
||||
args: Args,
|
||||
event: PromptEvent,
|
||||
) -> anyhow::Result<()> {
|
||||
align_text_impl(cx, args, event, |text_width, text| {
|
||||
format!("{:^text_width$}", text)
|
||||
})
|
||||
}
|
||||
|
||||
fn align_text_right(
|
||||
cx: &mut compositor::Context,
|
||||
args: Args,
|
||||
event: PromptEvent,
|
||||
) -> anyhow::Result<()> {
|
||||
align_text_impl(cx, args, event, |text_width, text| {
|
||||
format!("{:>text_width$}", text)
|
||||
})
|
||||
}
|
||||
|
||||
fn buffer_close(
|
||||
cx: &mut compositor::Context,
|
||||
args: Args,
|
||||
|
@ -3567,6 +3645,39 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
|
|||
..Signature::DEFAULT
|
||||
},
|
||||
},
|
||||
TypableCommand {
|
||||
name: "align-text-left",
|
||||
aliases: &["atl"],
|
||||
doc: "Align text to the left",
|
||||
fun: align_text_left,
|
||||
completer: CommandCompleter::none(),
|
||||
signature: Signature {
|
||||
positionals: (0, Some(0)),
|
||||
..Signature::DEFAULT
|
||||
},
|
||||
},
|
||||
TypableCommand {
|
||||
name: "align-text-center",
|
||||
aliases: &["atc"],
|
||||
doc: "Center-align text, optionally pass a number overriding the current document's text width",
|
||||
fun: align_text_center,
|
||||
completer: CommandCompleter::none(),
|
||||
signature: Signature {
|
||||
positionals: (0, Some(1)),
|
||||
..Signature::DEFAULT
|
||||
},
|
||||
},
|
||||
TypableCommand {
|
||||
name: "align-text-right",
|
||||
aliases: &["atr"],
|
||||
doc: "Align text to the right, optionally pass a number overriding the current document's text width",
|
||||
fun: align_text_right,
|
||||
completer: CommandCompleter::none(),
|
||||
signature: Signature {
|
||||
positionals: (0, Some(1)),
|
||||
..Signature::DEFAULT
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> =
|
||||
|
|
|
@ -2,6 +2,7 @@ use helix_term::application::Application;
|
|||
|
||||
use super::*;
|
||||
|
||||
mod align_text;
|
||||
mod insert;
|
||||
mod movement;
|
||||
mod write;
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
use super::*;
|
||||
|
||||
const IN: &str = indoc! {"
|
||||
#[pub fn docgen() -> Result<(), DynError> {
|
||||
use crate::docgen::*;
|
||||
write(TYPABLE_COMMANDS_MD_OUTPUT, &typable_commands()?);
|
||||
write(STATIC_COMMANDS_MD_OUTPUT, &static_commands()?);
|
||||
write(LANG_SUPPORT_MD_OUTPUT, &lang_features()?);
|
||||
Ok(())
|
||||
}\n|]#"};
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn left() -> anyhow::Result<()> {
|
||||
test((
|
||||
IN,
|
||||
":align-text-left<ret>",
|
||||
indoc! {"\
|
||||
#[pub fn docgen() -> Result<(), DynError> {
|
||||
use crate::docgen::*;
|
||||
write(TYPABLE_COMMANDS_MD_OUTPUT, &typable_commands()?);
|
||||
write(STATIC_COMMANDS_MD_OUTPUT, &static_commands()?);
|
||||
write(LANG_SUPPORT_MD_OUTPUT, &lang_features()?);
|
||||
Ok(())
|
||||
}\n|]#"},
|
||||
))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn center() -> anyhow::Result<()> {
|
||||
test((
|
||||
IN,
|
||||
":align-text-center<ret>",
|
||||
indoc! {"\
|
||||
#[ pub fn docgen() -> Result<(), DynError> {
|
||||
use crate::docgen::*;
|
||||
write(TYPABLE_COMMANDS_MD_OUTPUT, &typable_commands()?);
|
||||
write(STATIC_COMMANDS_MD_OUTPUT, &static_commands()?);
|
||||
write(LANG_SUPPORT_MD_OUTPUT, &lang_features()?);
|
||||
Ok(())
|
||||
}\n|]#"},
|
||||
))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn right() -> anyhow::Result<()> {
|
||||
test((
|
||||
IN,
|
||||
":align-text-right<ret>",
|
||||
indoc! {"\
|
||||
#[ pub fn docgen() -> Result<(), DynError> {
|
||||
use crate::docgen::*;
|
||||
write(TYPABLE_COMMANDS_MD_OUTPUT, &typable_commands()?);
|
||||
write(STATIC_COMMANDS_MD_OUTPUT, &static_commands()?);
|
||||
write(LANG_SUPPORT_MD_OUTPUT, &lang_features()?);
|
||||
Ok(())
|
||||
}\n|]#"},
|
||||
))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue