Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | package Psh::Builtins::Theme; |
2 | ||
3 | require Psh::OS; | |
4 | require Psh::Util; | |
5 | require Psh::Parser; | |
6 | ||
7 | =item * C<theme list> | |
8 | ||
9 | Displays a list of available themes. | |
10 | ||
11 | =item * C<theme NAME> | |
12 | ||
13 | Activates the theme. | |
14 | ||
15 | If your themes look strange try C<option encoding=iso8859-1> - this | |
16 | will switch to an alternative usage of graphical characters. | |
17 | ||
18 | =cut | |
19 | ||
20 | sub _parse_error { | |
21 | my $file= shift; | |
22 | my $line= shift; | |
23 | Psh::Util::print_error("Error parsing themefile $file.\n"); | |
24 | Psh::Util::print_error("Do not understand: $line\n") if $line; | |
25 | return (0,undef); | |
26 | } | |
27 | ||
28 | sub _set_theme { | |
29 | my $file= shift; | |
30 | my @lines; | |
31 | if ($file=~/\.bt$/) { | |
32 | eval { | |
33 | require Archive::Tar; | |
34 | }; | |
35 | if ($@) { | |
36 | Psh::Util::print_error("Please install Archive::Tar to handle .bt files!\n"); | |
37 | return (0,undef); | |
38 | } | |
39 | my $tar= Archive::Tar->new(); | |
40 | $tar->read($file,1); | |
41 | @lines= split /\n/, $tar->get_content('theme'); | |
42 | } else { | |
43 | open(THEME,"< $file"); | |
44 | @lines= <THEME>; | |
45 | close(THEME); | |
46 | } | |
47 | if (!@lines) { | |
48 | Psh::Util::print_error("Could not find theme '$file'.\n"); | |
49 | return (0,undef); | |
50 | } | |
51 | if ($lines[0]=~/^\#\!.*psh/) { # psh-script | |
52 | Psh::process_variable(join("\n",@lines)); | |
53 | return (1,undef); | |
54 | } else { # try to parse it as a simple bashish theme | |
55 | my @ps; | |
56 | my $title='\w'; | |
57 | my $bashish_compat=0; | |
58 | foreach my $line (@lines) { | |
59 | next if substr($line,0,1) eq '#'; | |
60 | if ($line=~/^\s*needmod\s+themecompat\s*$/) { | |
61 | $bashish_compat=1; | |
62 | } elsif ($line=~/^\s*PS(\d)\s*\=\s*(.*)$/) { | |
63 | my ($num,$text)= ($1,$2); | |
64 | if ($num>0 and $num<5) { | |
65 | $ps[$num]= Psh::Parser::unquote($text); | |
66 | } else { | |
67 | return _parse_error($file); | |
68 | } | |
69 | } elsif ($line=~/^\s*PROMPT\s*\=\s*(.*)$/) { | |
70 | $ps[1]= Psh::Parser::unquote($1); | |
71 | } elsif ($line=~/^\s*TITLE\s*\=\s*(.*)$/) { | |
72 | $title= Psh::Parser::unquote($1); | |
73 | } elsif ($line=~/^\s*X\w+\=/ or | |
74 | $line=~/^\s*needmod\s+/ or | |
75 | $line=~/^\s*THEME_.*\=/ or | |
76 | $line=~/^\s*SUPERPROMPT/ or | |
77 | $line=~/^\s*CURCOLOR/ or | |
78 | $line=~/^\s*$/) { | |
79 | # ignore | |
80 | } else { | |
81 | return _parse_error($file,$line); | |
82 | } | |
83 | } | |
84 | if ($bashish_compat) { | |
85 | for (my $i=1; $i<=4; $i++) { | |
86 | next unless defined $ps[$i]; | |
87 | $ps[$i]=~s/\$n/\\n/g; $ps[$i]=~s/\$t/\\t/g; | |
88 | $ps[$i]=~s/\$w/\\w/g; $ps[$i]=~s/\$W/\\W/g; | |
89 | $ps[$i]=~s/\$u/\\u/g; $ps[$i]=~s/\$c/\\!/g; | |
90 | $ps[$i]=~s/\$b/\\\$/g; $ps[$i]=~s/\$s/\\s/g; | |
91 | $ps[$i]=~s/\$h/\\h/g; $ps[$i]=~s/\$i/\\#/g; | |
92 | $ps[$i]=~s/\$d/\\d/g; $ps[$i]=~s/\$x/%/g; | |
93 | $ps[$i]=~s/\$e/\!/g; $ps[$i]=~s/\$m/\$/g; | |
94 | $ps[$i]=~s/\$z/\\\$/g; | |
95 | } | |
96 | } | |
97 | Psh::Options::set_option('window_title',$title) if defined $title; | |
98 | for (my $i=1; $i<=4; $i++) { | |
99 | next unless defined $ps[$i]; | |
100 | Psh::Options::set_option("ps$i",$ps[$i]); | |
101 | } | |
102 | Psh::Options::del_option('ps3') unless defined $ps[3]; | |
103 | Psh::Options::del_option('ps4') unless defined $ps[4]; | |
104 | Psh::Options::del_option('promp_command'); | |
105 | return (1,undef); | |
106 | } | |
107 | } | |
108 | ||
109 | sub bi_theme { | |
110 | my $line= shift; | |
111 | my @dirs= (Psh::OS::catdir(Psh::OS::rootdir(),'usr','share', | |
112 | 'psh','themes'), | |
113 | Psh::OS::catdir(Psh::OS::rootdir(),'usr','local','share', | |
114 | 'psh','themes'), | |
115 | Psh::OS::catdir(Psh::OS::get_home_dir(),'.psh','share','themes'), | |
116 | Psh::OS::catdir(Psh::OS::rootdir(),'psh','themes')); | |
117 | if ($line eq 'list') { | |
118 | my @result=(); | |
119 | foreach my $dir (@dirs) { | |
120 | next unless -r $dir; | |
121 | my @tmp= Psh::OS::glob('*',$dir,1); | |
122 | foreach my $file (@tmp) { | |
123 | my $full= Psh::OS::catfile($dir,$file); | |
124 | next if !-r $full or -d _; | |
125 | next if $file =~ /\~$/; | |
126 | $file=~ s/\.bt$//; | |
127 | push @result, $file; | |
128 | } | |
129 | } | |
130 | @result= sort @result; | |
131 | Psh::Util::print_list(@result); | |
132 | return (1,undef); | |
133 | } else { | |
134 | if ($line) { | |
135 | if ($line=~/$Psh::OS::FILE_SEPARATOR/) { # abs path specified | |
136 | my $tmp= Psh::Util::abs_path($line); | |
137 | return _set_theme($tmp) if $tmp; | |
138 | } else { | |
139 | foreach my $dir (@dirs) { | |
140 | next unless -r $dir; | |
141 | my $file= Psh::OS::catfile($dir,$line); | |
142 | if (-r "$file.bt") { | |
143 | return _set_theme("$file.bt"); | |
144 | } elsif (-r $file) { | |
145 | return _set_theme($file); | |
146 | } | |
147 | } | |
148 | } | |
149 | Psh::Util::print_error("Could not find theme '$line'.\n"); | |
150 | } | |
151 | } | |
152 | return (0,undef); | |
153 | } | |
154 | ||
155 | { | |
156 | ||
157 | sub get_color { | |
158 | my $name= shift; | |
159 | return $color_table{$name}; | |
160 | } | |
161 | } | |
162 | ||
163 | 1; |