Sublime Forum

Bash case indentation

#1

With the bash shell script syntax, case switches don’t indent properly, ex:

typing

case $1 in
a)
echo hello
;;
b)
echo
goodbye
;;
*)
echo what?
;;
esac

should display:

case $1 in
	a)
		echo hello
		;;
	b)
		echo goodbye
		;;
	*)
		echo what?
		;;
esac

but instead displays:

case $1 in
	a)
echo hello
;;
b)
echo
goodbye
;;
*)
echo what?
;;
esac

Sorry if there’s a better place to post this, but it’s been bugging me all day! Especially since I tend to rely on “reindent lines” to fix any indentation blunders that may have popped up, but that just sends all of the case clauses flush to the left.

0 Likes

Bash indent to sensitive, and lacking
#2

hey zopiac,

did you ever figure this one out? i am wondering about exactly the same thing.

0 Likes

#3

I’m sorry for another “me too” post, but the ugly is killing my eyes!

I tried to take a look at it and ended up in

Packages/ShellScript/Shell-Unix-Generic.tmLanguage

But I found it a bit overwhelming to understand the finer point of syntax definitions in sublime text just to fix this.

I guess this is just a call for help from someone with a more appropriate skill set than I have.

0 Likes

#4

Just saying, still a issue. Would be nice if fixed.

0 Likes

#5

this is currently not possible with the way the indentation system in ST works - esac would need to de-indent 2 levels, but ST only supports changing one indentation level per line.

the closest you could approximate would be:

case $1 in
a)
	echo hello
	;;
b)
	echo goodbye
	;;
*)
	echo what?
	;;
esac

or

case $1 in
	a)
		echo hello
		;;
	b)
		echo goodbye
		;;
	*)
		echo what?
		;;
        esac
0 Likes

#6

The first approxomation would work very well for me. :slight_smile:

0 Likes

#7

then you can create a new tmPreferences file with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
    <key>name</key>
    <string>Miscellaneous</string>
    <key>scope</key>
    <string>meta.scope.case-clause-body.shell</string>
    <key>settings</key>
    <dict>
        <key>decreaseIndentPattern</key>
        <string>^\s*[^)]+\)$</string>
        <key>increaseIndentPattern</key>
        <string>^\s*[^)]+\)$</string>
        <key>indentNextLinePattern</key>
        <string></string>
    </dict>
</dict>
</plist>

and you’ll probably want to remove case from the increaseIndentPattern in Packages/ShellScript/Miscellaneous.tmPreferences

0 Likes

#8

I’ve been exploiting a bug/feature and using the comment behavior to manually set indention levels such as in this formatted example. It also works for single line if statements.

An excerpt from some utility script I’m working on:

while getopts "hr:v:p:umosd" intputOptions; do
  case "${inputOptions}" in
    h) usage ;;                ##
    ##
    r) connection=${OPTARG} ;; ##
    v) volumeName=${OPTARG} ;; ##
    p) mountPoint=${OPTARG} ;; ##
    ##
    u) unmountMode=1 ;;        ##
    m) mount_mode=1 ;;         ##
    o) openInSublime=1 ;;      ##
    s) shellOpen=1 ;;          ##
    d) DEBUG_MODE=1;;          ##
    ##
    *) usage ;;                ##
    ##
  esac
done
shift $((OPTIND-1))

remoteSansColon=`echo ${connection} | perl -pe "s/://gi"`
perlRemoteHost=`echo ${connection} | perl -pe "s/:.*//gi"`
perlRemotePath=`echo ${connection} | perl -pe "s/.*://gi"`

if [[ $connection == $remoteSansColon ]]; then echo "Incorrect remote format"; usage;fi ##
if [[ -z "${connection}" ]]; then echo "No connection specified"; usage; fi             ##
if [[ -z "${perlRemoteHost}" ]]; then echo "No remote Host specified"; usage; fi        ##
if [[ -z "${perlRemotePath}" ]]; then echo "No remote Path specified"; usage; fi        ##
##

if [[ -z $volumeName ]]; then
  volumeName=`echo $connection | cut -d "@" -f 2 | tr ":/." "_--"`
fi
0 Likes