bash.rs

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