rwxrob / dot

Migrating to z Bonzai stateful command tree monolith
https://github.com/rwxrob/z
Apache License 2.0
242 stars 38 forks source link

snip tool wont autoplace a snippet if nothing is on the line #41

Closed qwertimer closed 3 years ago

qwertimer commented 3 years ago

The snip tool works as expected for everything except if i have an empty line and wish to place a snippet on this line. The snippet fails to place anything down. Not sure whether you wish to support this. I thought i figured out how to fix it but it breaks the multiline parsing. If we add -ge 0 rather than > 0 we can place a snippet on an empty line.

rossim2i2 commented 3 years ago

The problem is with they way we are checking the number of arguments. After our shift, $# will always be zero. We need to change the qualifier for the if statement on line 12.

I started working on this earlier this morning, but had to stop to log onto work. I'll keep playing with it as I have free time.

For now I changed line 12 from > to = so the script will import the text in the snippet file. However, the email example Rob reviewed yesterday won't work.

rossim2i2 commented 3 years ago

"After our shift, $# will always be zero"

This is actually only true if we don't pass anything else in the command. For example, snip nameemail and snip foo will both have $# equal to zero. If we passed additional arguments, i.e. snip nameemail Mike Mike@mike.com, then our $# > 0 would be TRUE.

However, when we use VI Magic and pass data into the script, the shell still only recognizes snip nameemail. Our update will need to get the data passed to the script (maybe by using STDIN) and apply logic there.

Sorry for the additional details, but I wanted to spell this out in case it helps anyone else who is following along.

rossim2i2 commented 3 years ago

I think this works. I'll need to play around on how to do a PR (if needed). Let me know what you think.

#!/usr/bin/bash

[[ -z $SNIPPETS ]] && echo "SNIPPETS directory undefined" && exit 1

snip() {
  local name="$1"
  shift
  local path="$SNIPPETS/$name"
  if [[ -r $path ]]; then

    local buf="$(<$path)"
    local in="$(</dev/stdin)"

    if [[ $# = 0 && -z $in ]]; then
      echo "$buf"
      return
    fi

    if [[ $# > 0 ]]; then
      local -i n=1
      for arg in $@; do
        buf=${buf//\{$n\}/$arg}
        ((n++))
      done
      echo "$buf"
    else
      while IFS=$'\n' read -r argline; do
        if [[ -n $argline ]]; then
          IFS=" " snip $name $argline
        fi
      done
    fi

  fi
}

snip "$@"
rossim2i2 commented 3 years ago

I found a bug when there is no STDIN. Fixed code is below:

#!/usr/bin/bash

[[ -z $SNIPPETS ]] && echo "SNIPPETS directory undefined" && exit 1

snip() {
  local name="$1"
  shift
  local path="$SNIPPETS/$name"

  if [[ -r $path ]]; then

    local buf="$(<$path)"
    if [[ -s /dev/stdin ]]; then
      local in="$(</dev/stdin)"
    else
      local in=""
    fi

    if [[ $# = 0 && -z $in ]]; then
      echo "$buf"
      return
    fi

    if [[ $# > 0 ]]; then
      local -i n=1
      for arg in $@; do
        buf=${buf//\{$n\}/$arg}
        ((n++))
      done
      echo "$buf"
    else
      while IFS=$'\n' read -r argline; do
        if [[ -n $argline ]]; then
          IFS=" " snip $name $argline
        fi
      done
    fi

  fi
}

snip "$@"
qwertimer commented 3 years ago

Looks like it works. I was able to add a snippet into an empty buffer in vim. It also outputs to the terminal if i run the snip tool in the terminal.