1use project::ContextProviderWithTasks;
2use task::{TaskTemplate, TaskTemplates, VariableName};
3
4pub(super) fn bash_task_context() -> ContextProviderWithTasks {
5 ContextProviderWithTasks::new(TaskTemplates(vec![
6 TaskTemplate {
7 label: "execute selection".to_owned(),
8 command: VariableName::SelectedText.template_value(),
9 ..TaskTemplate::default()
10 },
11 TaskTemplate {
12 label: format!("run '{}'", VariableName::File.template_value()),
13 command: VariableName::File.template_value(),
14 ..TaskTemplate::default()
15 },
16 ]))
17}
18
19#[cfg(test)]
20mod tests {
21 use gpui::{AppContext as _, BorrowAppContext, Context, TestAppContext};
22 use language::{AutoindentMode, Buffer};
23 use settings::SettingsStore;
24 use std::num::NonZeroU32;
25 use unindent::Unindent;
26 use util::test::marked_text_offsets;
27
28 #[gpui::test]
29 async fn test_bash_autoindent(cx: &mut TestAppContext) {
30 cx.executor().set_block_on_ticks(usize::MAX..=usize::MAX);
31 let language = crate::language("bash", tree_sitter_bash::LANGUAGE.into());
32 cx.update(|cx| {
33 let test_settings = SettingsStore::test(cx);
34 cx.set_global(test_settings);
35 cx.update_global::<SettingsStore, _>(|store, cx| {
36 store.update_user_settings(cx, |s| {
37 s.project.all_languages.defaults.tab_size = NonZeroU32::new(2)
38 });
39 });
40 });
41
42 cx.new(|cx| {
43 let mut buffer = Buffer::local("", cx).with_language(language, cx);
44
45 let expect_indents_to =
46 |buffer: &mut Buffer, cx: &mut Context<Buffer>, input: &str, expected: &str| {
47 buffer.edit( [(0..buffer.len(), input)], Some(AutoindentMode::EachLine), cx, );
48 assert_eq!(buffer.text(), expected);
49 };
50
51 // Do not indent after shebang
52 expect_indents_to(
53 &mut buffer,
54 cx,
55 "#!/usr/bin/env bash\n#",
56 "#!/usr/bin/env bash\n#",
57 );
58
59 // indent function correctly
60 expect_indents_to(
61 &mut buffer,
62 cx,
63 "function name() {\necho \"Hello, World!\"\n}",
64 "function name() {\n echo \"Hello, World!\"\n}",
65 );
66
67 // indent if-else correctly
68 expect_indents_to(
69 &mut buffer,
70 cx,
71 "if true;then\nfoo\nelse\nbar\nfi",
72 "if true;then\n foo\nelse\n bar\nfi",
73 );
74
75 // indent if-elif-else correctly
76 expect_indents_to(
77 &mut buffer,
78 cx,
79 "if true;then\nfoo\nelif true;then\nbar\nelse\nbar\nfi",
80 "if true;then\n foo\nelif true;then\n bar\nelse\n bar\nfi",
81 );
82
83 // indent case-when-else correctly
84 expect_indents_to(
85 &mut buffer,
86 cx,
87 "case $1 in\nfoo) echo \"Hello, World!\";;\n*) echo \"Unknown argument\";;\nesac",
88 "case $1 in\n foo) echo \"Hello, World!\";;\n *) echo \"Unknown argument\";;\nesac",
89 );
90
91 // indent for-loop correctly
92 expect_indents_to(
93 &mut buffer,
94 cx,
95 "for i in {1..10};do\nfoo\ndone",
96 "for i in {1..10};do\n foo\ndone",
97 );
98
99 // indent while-loop correctly
100 expect_indents_to(
101 &mut buffer,
102 cx,
103 "while true; do\nfoo\ndone",
104 "while true; do\n foo\ndone",
105 );
106
107 // indent array correctly
108 expect_indents_to(
109 &mut buffer,
110 cx,
111 "array=(\n1\n2\n3\n)",
112 "array=(\n 1\n 2\n 3\n)",
113 );
114
115 // indents non-"function" function correctly
116 expect_indents_to(
117 &mut buffer,
118 cx,
119 "foo() {\necho \"Hello, World!\"\n}",
120 "foo() {\n echo \"Hello, World!\"\n}",
121 );
122
123 let (input, offsets) = marked_text_offsets(
124 &r#"
125 if foo; then
126 1ˇ
127 else
128 3
129 fi
130 "#
131 .unindent(),
132 );
133
134 buffer.edit([(0..buffer.len(), input)], None, cx);
135 buffer.edit(
136 [(offsets[0]..offsets[0], "\n")],
137 Some(AutoindentMode::EachLine),
138 cx,
139 );
140 buffer.edit(
141 [(offsets[0] + 3..offsets[0] + 3, "elif")],
142 Some(AutoindentMode::EachLine),
143 cx,
144 );
145 let expected = r#"
146 if foo; then
147 1
148 elif
149 else
150 3
151 fi
152 "#
153 .unindent();
154
155 pretty_assertions::assert_eq!(buffer.text(), expected);
156
157 buffer
158 });
159 }
160}