set.rs 3.51 KB
Newer Older
1
use liner::KeyBindings;
2
use shell::{flags::*, Shell};
3
use small;
4
use std::iter;
Michael Aaron Murphy's avatar
Michael Aaron Murphy committed
5
use types;
Michael Aaron Murphy's avatar
Michael Aaron Murphy committed
6
7
8
9
10
11
12
13

enum PositionalArgs {
    UnsetIfNone,
    RetainIfNone,
}

use self::PositionalArgs::*;

14
pub(crate) fn set(args: &[small::String], shell: &mut Shell) -> i32 {
Michael Aaron Murphy's avatar
Michael Aaron Murphy committed
15
16
17
18
19
    let mut args_iter = args.iter();
    let mut positionals = None;

    while let Some(arg) = args_iter.next() {
        if arg.starts_with("--") {
20
21
            if arg.len() == 2 {
                positionals = Some(UnsetIfNone);
22
                break;
23
            }
24
            return 0;
Michael Aaron Murphy's avatar
Michael Aaron Murphy committed
25
        } else if arg.starts_with('-') {
26
27
            if arg.len() == 1 {
                positionals = Some(RetainIfNone);
28
                break;
29
            }
Michael Aaron Murphy's avatar
Michael Aaron Murphy committed
30
31
32
            for flag in arg.bytes().skip(1) {
                match flag {
                    b'e' => shell.flags |= ERR_EXIT,
33
                    b'o' => match args_iter.next().map(|s| s as &str) {
AdminXVII's avatar
AdminXVII committed
34
35
36
37
38
39
40
41
42
43
                        Some("vi") => {
                            if let Some(context) = shell.context.as_mut() {
                                context.key_bindings = KeyBindings::Vi;
                            }
                        }
                        Some("emacs") => {
                            if let Some(context) = shell.context.as_mut() {
                                context.key_bindings = KeyBindings::Emacs;
                            }
                        }
44
                        Some("huponexit") => shell.flags |= HUPONEXIT,
45
                        Some(_) => {
46
                            eprintln!("ion: set: invalid option");
47
                            return 0;
48
49
                        }
                        None => {
50
                            eprintln!("ion: set: no option given");
51
                            return 0;
52
53
                        }
                    },
54
55
                    b'x' => shell.flags |= PRINT_COMMS,
                    _ => return 0,
Michael Aaron Murphy's avatar
Michael Aaron Murphy committed
56
57
58
59
60
61
                }
            }
        } else if arg.starts_with('+') {
            for flag in arg.bytes().skip(1) {
                match flag {
                    b'e' => shell.flags &= 255 ^ ERR_EXIT,
Michael Aaron Murphy's avatar
Michael Aaron Murphy committed
62
                    b'x' => shell.flags &= 255 ^ PRINT_COMMS,
63
64
                    b'o' => match args_iter.next().map(|s| s as &str) {
                        Some("huponexit") => shell.flags &= 255 ^ HUPONEXIT,
65
66
67
68
69
70
71
72
                        Some(_) => {
                            eprintln!("ion: set: invalid option");
                            return 0;
                        }
                        None => {
                            eprintln!("ion: set: no option given");
                            return 0;
                        }
Thomas Kinnen's avatar
Thomas Kinnen committed
73
                    },
74
                    _ => return 0,
Michael Aaron Murphy's avatar
Michael Aaron Murphy committed
75
76
77
78
79
80
81
82
                }
            }
        }
    }

    match positionals {
        None => (),
        Some(kind) => {
83
            let command = shell.variables.get::<types::Array>("args").unwrap()[0].clone();
84
85
86
            // This used to take a `&[String]` but cloned them all, so although
            // this is non-ideal and could probably be better done with `Rc`, it
            // hasn't got any slower.
Michael Aaron Murphy's avatar
Michael Aaron Murphy committed
87
            let arguments: types::Array = iter::once(command).chain(args_iter.cloned()).collect();
Michael Aaron Murphy's avatar
Michael Aaron Murphy committed
88
            match kind {
Michael Aaron Murphy's avatar
Michael Aaron Murphy committed
89
90
91
                UnsetIfNone => {
                    shell.variables.set("args", arguments);
                }
AdminXVII's avatar
AdminXVII committed
92
93
94
95
96
                RetainIfNone => {
                    if arguments.len() != 1 {
                        shell.variables.set("args", arguments);
                    }
                }
Michael Aaron Murphy's avatar
Michael Aaron Murphy committed
97
98
99
100
101
102
            }
        }
    }

    0
}