HACKING BASHISH
---------------

1. What's the fuzz?
2. Syntax
 .1 language compliance
 .2 coding style
   .1 headers
   .2 indentation
   .3 trap
   .4 test
3. Bashish architechture
 .2 Performance
 .3 Porting to a new shell
 .4 Distribution tools
4. Things to help with
 .1 Terminal.app in MacOS X
 .2 Optimizing gnome-terminal
 .3 konsole

1. What's the fuzz?
-------------------
This document should hopefully give some info about where I'm (currently)
heading with bashish.
My thoughts on how it is supposed to be written and what it should provide.

I might not be doing everything right, and some things I might have overlooked
or could have done better.
I'm always interested to hear what people thinks about Bashish, whether its
on a technical level or from a user standpoint, English grammar corrections
and spelling is also appreciated :)

/Thomas

2. Syntax
---------
2.1 Language Compliance
-----------------------
All code should use a syntax which is parseable without errors on 'pdksh',
'bash', 'ksh93' and 'zsh' version 4 in ksh-emulation mode.

Exceptions are made for code under the following subdirectories:
* $HOME/.bashish/bt/ each 'prompt.*' should conform in syntax to the shell
  intended to parse it. The 'theme' files should have the ksh-compatible
  syntax as specified above.
* $BASHISHDIR/main/prompt/sh should be parseable on the heirloom bourne shell
  http://heirloom.sourceforge.net/sh.html
* $BASHISHDIR/main/prompt/csh should be parseable on the c-shell (csh)
  http://www.openbsd.org/cgi-bin/cvsweb/src/bin/csh/
  http://packages.debian.org/stable/shells/csh
* $BASHISHDIR/main/prompt/fish should be parseable on the Friendly
  Interactive SHell version 1.20.0: http://roo.no-ip.org/fish/
* $BASHISHDIR/main/prompt/rc should be parseable on the Plan/9 shell:
  http://www.star.le.ac.uk/~tjg/rc/
* $BASHISHDIR/main/prompt/osh should be parseable on the Old Thompson shell:
  http://jneitzel.sdf1.org/osh/command_files/
* $BASHISHDIR/main/prompt/lsh should be parseable on the Lossy Shell:
  http://packages.debian.org/stable/shells/lsh
* $BASHISHDIR/main/prompt/esh should be parseable on the Easy Shell, esh:
  http://web.archive.org/web/20100207011433/http://slon.ttk.ru/esh/

2.2 coding style
----------------

2.2.1 Headers
-------------
Where possible, each file should have the following header:
--begin header--
#!/bin/bash
##################################################################################
## Bashish, a console theme engine
## Copyright (C) 2010 Thomas Eriksson
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License
## as published by the Free Software Foundation; either version 2
## of the License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## 
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
##################################################################################
##
## this file provides feature X
## feature X works by Y and Z being foobar-ized.
##
###############################################################################
--end header--

If you add code, add a copyright line with a line of your own.

Some shells do not parse '#' as a comment, if possible in these shells, the
comment should be left intact but each line preceeded with the comment
character of the shell. eg. see $BASHISHDIR/main/prompt/lsh/init which uses
'REM' for future compatibility with CMD.EXE or COMMAND.COM

The '#!/bin/bash' (aka shebang) serves three purposes:
* comply with the debian policy about ksh compatible code
* enable syntax highlightning in various editors

most commands in Bashish are not executed by the system on their own,
instead they are mostly sourced.

The commands 'bashish' and 'bashishtheme' have a shebang header pointing to
the specified interpreter, this is autogenerated by the 'genheader' script
and autoconf.

Indentation
-----------
one tab space is used for indentation.
Comments generally have tho sharp characters: '##', commented code have one:
'#'.

## as of Bashish 2.0.5 the syntax foo() is depriciated, instead write as
## following with local being used to declare local variabels
function foo
{
	local var1=foo var2=bar
	cmd
}
## I use the test builtin by an old habit trying bashish to be bourne
## compatible...
if test bar = foo
then
	cmd
else
	foo
fi

## short if ;)
test foo = bar && { cmd1; cmd2;cmd3;cmd4; }

case foo in
	bar) cmd1;;
	baz|foo) cmd2;;
esac

for i in a b c
do
	echo $i
done

while true
do
	true
done

trap
----
signals are trapped with 
% trap 'cmd' SIG

signals are untrapped with
% trap - SIG

replace 'SIG' with three-letter signal of choice, replace 'cmd' with command
to execute, or '' to ignore the signal.

test
----
one can safely assume that syntax used by test should be GNU test
compatible as test is a builtin on several shells.

a common gotcha is the string testing syntax:

% test $STRING && cmd

if string starts with -, test will most likely fail. Also enclose the string
with (double) quotation marks, elsewise test will fail if the string is
unset or includes spaces.
Use the following syntax:
% test "x$STRING" != x && cmd

Binary false in conjugation with comparing strings are not recommended:
% test foo =  bar || asdf
% test foo != bar || asdf

instead switch the logical operator:
% test foo != bar && asdf
% test foo = bar  && asdf

closing of filedescriptors
--------------------------
Closing a file descriptor is problematic on some NetBSD utilities, thus
filedescriptors should NOT be closed but instead redirected to /dev/null

How not to write:
command 2>&-
command 1>&-

Instead write:
command 2>/dev/null
command 1>&-

In pdksh one can not write &>[FD] thus FD1 and FD2 redirects must be
separated.

Wrong:
command &>/dev/null

Instead write:
command 2>/dev/null 1>/dev/null

3 Bashish Architecture
----------------------


3.2 Porting to a new shell
--------------------------
Following is pseudocode for loading Bashish, it should be fairly trivial to
implement even on very Basic shells:

Terminal themeing (no prompt changing):

if "[HOMEDIR]/.bashish/launcher" is not first element in [PATH]
then
	add "[HOMEDIR]/.bashish/launcher" to the first element in [PATH]
end if;
execute bashish;

namespace
---------
All bashish functions and non-interactive commands have the string _bashish_
in the beginning of their file name.
This gives a clear distinction between user-commands and internal commands.

theme part: $BASHISHDIR/main/terminal
-------------------------------------
The theme part handle most of the terminal interaction: colors, font,
graphics, title, icon.
It runs as a process in the background and recieves commands via a named
fifo. For each themed command there is a wrapper which instructs the themer
to re-theme the terminal.

Extensions/enhancements
-----------------------
To support new terminals, the theme part needs to modified.
The first part to look into is the "detectterm" module which contains
terminal specific code.

theme changer part: $BASHISHDIR/main/bashishtheme
-------------------------------------------------
The theme changer consists of a ncurses interface and several interacting
functions for decompressing and searching themes.

Extensions/enhancements
-----------------------
The reason for changing the theme changer part might be to enhance the
interaction with Bashish or make a simpler light version.

prompt part: $BASHISHDIR/main/prompt/
-------------------------------------
Below the $BASHISHDIR/main/prompt directory is a directory for each shell 
which contains native shell script.
The prompt part is kept as simple as possible to be portable even on the 
less powerful shells. Every subdirectory contains a similar structure -
though, this might not be practical for some shells.

Extensions/enhancements
-----------------------
If you are porting to a new shell, the first thing you need to know is if
the target shell is enough compatible with code from any of the
subdirectories? Perhaps simplifications and conditionals are sufficent to 
obtain compatibility.
If the shell differs too much from supported shells, a new subdirectory
needs to be created, copy and rewrite the code, preferably from the sh/
directory.

statelist
---------
This is a list over the numbers used in the BASHISH_STATE[] array
note that pdksh cannot handle index values larger than 1023!
note also that ksh88 (ultrix) cannot handle index values larger than 511!

expect many changes prior to 2.0 release
----------------------------------------
XTerm colors
------------
0  black  ## ignored on Linux Console, is the same as bgcolor
1  red
2  green
3  yellow
4  blue
5  magenta
6  cyan
7  white ## ignored on Linux Console, is the same as fgcolor
8  brightblack
9  brightred
10 brightgreen
11 brightyellow
12 brightblue
13 brightmagenta
14 brightcyan
15 brightwhite
0-87 XTerm 88 Colors
0-255 XTerm 256 Colors

260 screenbg
261 screenfg
262 cursorbg
263 cursorfg (Eterm)
264 mousefg ## error
265 mousebg ## error
266 underline
269 all (XTerm, rxvt)
299 all (gnome-terminal, where it takes as much time to change all as in one)

graphics
--------
300 background
301 iconpixmap
302 iconbitmap
303 logo
304 transparency
305 shade

gnome-terminal specials
-----------------------
310 imagescroll

Eterm specials
--------------
320 gamma
321 

Bashish generic
---------------
330 bashish loaded [bool]

4 Font
------
400 xfont
401 fontname
402 fontsize

5 Geometry
----------
500 size_x
501 size_y
510 pos_x
511 pos_y

Reserved (perhaps won't be assigned since ksh88 only supports 512 elements!)
----------------------------------------------------------------------------
600
700
800
900

Extended shell support
----------------------
Bashish now supports a wide range of shells, even non-sh ones.
Particulary the non-sh shells will not have as many themes as the sh ones
since they may have less functionality and it may take some effort to port
the prompts.
If you port some prompts or add your own cool ones, I'd be glad to add them
though.
The shells that have prompt changing support in Bashish are:

sh: ash, bash, bourne shell, ksh, pdksh, posh, zsh
csh: csh, tcsh
fish: fish
dos: lsh
rc: akanga, es, rc

4. ANSI Color codes
-------------------
0	Reset all attributes
1	Bright
2	Dim
4	Underscore	
5	Blink
7	Reverse
8	Hidden

	Foreground Colours
30	Black
31	Red
32	Green
33	Yellow
34	Blue
35	Magenta
36	Cyan
37	White

	Bright Foreground Colors
90	Black
91	Red
92	Green
93	Yellow
94	Blue
95	Magenta
96	Cyan
97	White

	Background Colours
40	Black
41	Red
42	Green
43	Yellow
44	Blue
45	Magenta
46	Cyan
47	White



5. Things to help with
----------------------

* I'm not an experienced C coder, and I would like to have some
  help in writing a program that links to gconf and takes a gconf key as
  argument, and keeps reading from stdin in a loop to set the value
  specified. This would greatly speed up gnome-terminal themeing.
  see dcop --pipe for example.
* Write patches.
* Cleanups, optimizations.
* AppleScript wizards are welcome to bring some love to Terminal.app :)
* Report bugs and annoyances.
* Package for your favourite distribution.
* Would it be possible to create a wrapper on VMS?
* Other comments :)
