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, language_settings::AllLanguageSettings};
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 language::init(cx);
36 cx.update_global::<SettingsStore, _>(|store, cx| {
37 store.update_user_settings::<AllLanguageSettings>(cx, |s| {
38 s.defaults.tab_size = NonZeroU32::new(2)
39 });
40 });
41 });
42
43 cx.new(|cx| {
44 let mut buffer = Buffer::local("", cx).with_language(language, cx);
45
46 let expect_indents_to =
47 |buffer: &mut Buffer, cx: &mut Context<Buffer>, input: &str, expected: &str| {
48 buffer.edit( [(0..buffer.len(), input)], Some(AutoindentMode::EachLine), cx, );
49 assert_eq!(buffer.text(), expected);
50 };
51
52 // Do not indent after shebang
53 expect_indents_to(
54 &mut buffer,
55 cx,
56 "#!/usr/bin/env bash\n#",
57 "#!/usr/bin/env bash\n#",
58 );
59
60 // indent function correctly
61 expect_indents_to(
62 &mut buffer,
63 cx,
64 "function name() {\necho \"Hello, World!\"\n}",
65 "function name() {\n echo \"Hello, World!\"\n}",
66 );
67
68 // indent if-else correctly
69 expect_indents_to(
70 &mut buffer,
71 cx,
72 "if true;then\nfoo\nelse\nbar\nfi",
73 "if true;then\n foo\nelse\n bar\nfi",
74 );
75
76 // indent if-elif-else correctly
77 expect_indents_to(
78 &mut buffer,
79 cx,
80 "if true;then\nfoo\nelif true;then\nbar\nelse\nbar\nfi",
81 "if true;then\n foo\nelif true;then\n bar\nelse\n bar\nfi",
82 );
83
84 // indent case-when-else correctly
85 expect_indents_to(
86 &mut buffer,
87 cx,
88 "case $1 in\nfoo) echo \"Hello, World!\";;\n*) echo \"Unknown argument\";;\nesac",
89 "case $1 in\n foo) echo \"Hello, World!\";;\n *) echo \"Unknown argument\";;\nesac",
90 );
91
92 // indent for-loop correctly
93 expect_indents_to(
94 &mut buffer,
95 cx,
96 "for i in {1..10};do\nfoo\ndone",
97 "for i in {1..10};do\n foo\ndone",
98 );
99
100 // indent while-loop correctly
101 expect_indents_to(
102 &mut buffer,
103 cx,
104 "while true; do\nfoo\ndone",
105 "while true; do\n foo\ndone",
106 );
107
108 // indent array correctly
109 expect_indents_to(
110 &mut buffer,
111 cx,
112 "array=(\n1\n2\n3\n)",
113 "array=(\n 1\n 2\n 3\n)",
114 );
115
116 // indents non-"function" function correctly
117 expect_indents_to(
118 &mut buffer,
119 cx,
120 "foo() {\necho \"Hello, World!\"\n}",
121 "foo() {\n echo \"Hello, World!\"\n}",
122 );
123
124 let (input, offsets) = marked_text_offsets(
125 &r#"
126 if foo; then
127 1ˇ
128 else
129 3
130 fi
131 "#
132 .unindent(),
133 );
134
135 buffer.edit([(0..buffer.len(), input)], None, cx);
136 buffer.edit(
137 [(offsets[0]..offsets[0], "\n")],
138 Some(AutoindentMode::EachLine),
139 cx,
140 );
141 buffer.edit(
142 [(offsets[0] + 3..offsets[0] + 3, "elif")],
143 Some(AutoindentMode::EachLine),
144 cx,
145 );
146 let expected = r#"
147 if foo; then
148 1
149 elif
150 else
151 3
152 fi
153 "#
154 .unindent();
155
156 pretty_assertions::assert_eq!(buffer.text(), expected);
157
158 buffer
159 });
160 }
161}