2

A good and well-established guideline for commenting a shell function is to put it before the function's header. I am trying to follow these guidelines as much as I can, but this convention makes it hard to read the function's comments. For instance, I don't have access to the comments of my function

#######################################
# init the current directory with the required files to work with latex in Vscode's extension LaTeX workshop
# Arguments:
# $1 -> Main .tex file. Optional. Default to "main.tex"
#######################################
initlatex () {
    curl https://gist.githubusercontent.com/tapyu/886dc95fc19c4250fb38581ccc58bed8/raw/0eeaa62d401659fe1c57602ec8f17608775d5338/_default_preamble.tex > default_preamble.tex
    grep -q "\\input{default_preamble.tex}" ${1:-main.tex} || sed -i '2i\\\input{default_preamble.tex}\n' ${1:-main.tex}
    curl https://gist.githubusercontent.com/tapyu/886dc95fc19c4250fb38581ccc58bed8/raw/Makefile > Makefile
    [[ ! -d .vscode ]] && mkdir --parents --verbose .vscode
    curl https://gist.githubusercontent.com/tapyu/886dc95fc19c4250fb38581ccc58bed8/raw/0eeaa62d401659fe1c57602ec8f17608775d5338/_vscode_makefile.json > .vscode/settings.json
}

directly on terminal by using the which command:

❯ which initlatex
initlatex () {
    curl https://gist.githubusercontent.com/tapyu/886dc95fc19c4250fb38581ccc58bed8/raw/0eeaa62d401659fe1c57602ec8f17608775d5338/_default_preamble.tex > default_preamble.tex
    grep -q "\\input{default_preamble.tex}" ${1:-main.tex} || sed -i '2i\\\input{default_preamble.tex}\n' ${1:-main.tex}
    curl https://gist.githubusercontent.com/tapyu/886dc95fc19c4250fb38581ccc58bed8/raw/Makefile > Makefile
    [[ ! -d .vscode ]] && mkdir --parents --verbose --parents --verbose .vscode
    curl https://gist.githubusercontent.com/tapyu/886dc95fc19c4250fb38581ccc58bed8/raw/0eeaa62d401659fe1c57602ec8f17608775d5338/_vscode_makefile.json > .vscode/settings.json
}

Is there another command to print out the function's comments without breaking this best practice?

Rubem Pacelli
  • 215
  • 1
  • 9

4 Answers4

6

One approach is to take the approach used by LISP programmers, and then taken up by languages such as Python, and instead of using comment syntax, use a documentation string (docstring). This will be seen when you use which/whence/type. In LISP a string evaluates to itself, and is then ignored. For shell you need to assign it, e.g. to _doc.

gmt(){
   _doc="Show date in gmt"
   date -u "$@"
}

A second approach is to note that a function takes arguments. You can establish a convention that if you invoke the function with a first argument of --help it will give you help. ksh93 has an extended getopts parser which can make generating these easy, e.g. this env command.

icarus
  • 17,420
  • 1
  • 37
  • 54
  • 3
    A heredoc with `: <<-EOF` will also be useful for multiline doc strings – muru Jun 27 '23 at 01:38
  • I am not a LISP programmer, so maybe I didn't get it, but your first approach just redirect the `date --help` output to `gmt --help`. That is not effective, at all. I am not trying to redirect `--help` of other commands. Plus, `which gmt` does not provide any comment. – Rubem Pacelli Jun 27 '23 at 05:50
  • Concerning your second approach, I didn't get it how to proceed. You are not referring to a shell function, but to a `ksh` command. – Rubem Pacelli Jun 27 '23 at 05:50
  • 1
    @RubemPacelli He's referring to using the `getopts` command in the function definition, rather than using `which` to show the documentation. The problem with `which` is that it also shows the entire function definition, not just the doc. – Barmar Jun 27 '23 at 14:57
  • 2
    The "first approach" is you still use "which initlatex" or "which gmt", but now you get to see the assignment to _doc, where you can put whatever information you want, such as the meaning of the arguments. The "second approach" is to note that "initlatex" is a function, and as such can be programmed to respond to arguments. The suggestion is that if the argument is `--help` then you print out some helpful information and then return. The pointer to the env **function** in the ksh93 source was an example. You add a call to getopts to initlatex and then use `initlatex --help` to get help. – icarus Jun 27 '23 at 15:45
1

I would put the documentation into a variable that is related to the function name by a rigid coding convention. Such as, oh, the name being exactly the same, since variables and functions are in different namespaces:

initlatex='
#######################################
# init the current directory with the required
# files to work with latex in Vscode'\''s extension LaTeX workshop
# Arguments:
# $1 -> Main .tex file. Optional. Default to "main.tex"
#######################################
'
initlatex () {
    curl ...
}

Now if we know the name of a function, we can get its documentation:

$ echo "$initlatex"

#######################################
# init the current directory with the required
# files to work with latex in Vscode's extension LaTeX workshop
# Arguments:
# $1 -> Main .tex file. Optional. Default to "main.tex"
#######################################

Kaz
  • 7,676
  • 1
  • 25
  • 46
0

I code the same way with a detailed comment above the function but I add a one liner within the function itself:

function dewpoint() { # Calculate dewpoint(C) based on Temperature(C) and Humidity(%)

then I have a small script llfunctions that displays a one line info

dewpoint() Calculate dewpoint(C) based on Temperature(C) and Humidity(%)

llfunctions

#!/usr/bin/env bash
source ~/bin/functions-prt

list=(~/bin/functions-*)
[[ $1 ]] && list=("$@")

for fn in "${list[@]}"; do
    name=$(basename "$fn")
    prt-underline "$name"
    prt ""
    awk '/^function/ { printf "%25s", $2; $1=$2=$3=$4=""; $0=$0; print $0 }' "$fn"
    prt ""
done
rr0ss0rr
  • 332
  • 2
  • 6
0

which myfunction (in zsh which you seem to be using) shows you a shell-syntax rendering of a precompiled form of the code of the function.

You won't find any comment in there as those are not part of the compiled code (in any language, not just shells). The code you see may be different from the code which the function was defined from, you'll notice aliases have been expanded, the indentation will be different, line continuation removed, short forms changed to long forms, etc.

Here it seems you want to see the actual source as written by the author. Like you'd want to see the file.java source for a java function in a file.class file and not the decompiled version of your file.class.

In zsh, for those functions that have been defined in files, you can view the corresponding file with:

view $functions_source[myfunction]

(or your favourite viewer/editor) assuming that file is still there. You'll also benefit from syntax highlighting and other goodies of your viewer/editor.

type myfunction also tells you where the function definition was read from:

$ type ls _ls
ls is a shell function from /home/chazelas/.zshrc
_ls is a shell function from /usr/share/zsh/functions/Completion/Unix/_ls
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501