Browse Source

Add fixnl() to fix common newline-related annoyances

Alois Mahdal 8 years ago
parent
commit
e72883698d
1 changed files with 42 additions and 0 deletions
  1. 42
    0
      dotfiles/bash/main.bashrc

+ 42
- 0
dotfiles/bash/main.bashrc View File

@@ -102,6 +102,48 @@ vims() {
102 102
       | tac
103 103
 }
104 104
 
105
+fixnl() {
106
+    #
107
+    # Fix newlines in stdin and pass to stdout
108
+    #
109
+    # Note: We need to read whole stdin; this cannot work
110
+    # for infinite stream.
111
+    #
112
+    # Fix annoying cases:
113
+    #
114
+    #  *  If multi-line text is missing newline at the
115
+    #     end---add the missing newline.
116
+    #
117
+    #  *  If -c is passed, and single-line text does have
118
+    #     a newline at the end, remove it.
119
+    #
120
+    # This will not touch properly terminated multi-line texts,
121
+    # or zero-line texts (ie. oly chars with no newline at all).
122
+    #
123
+    local arg=$1        # argument passed
124
+    local cache         # cache to keep stream in
125
+    local nlcount       # count of newlines in the stream
126
+    local lastchr       # hex dump (2-digit, lowercase) of last char
127
+    local single=keep   # single-line streams:
128
+                        #   keep: do nothing
129
+                        #   chop: drop last char if it's a LF
130
+    case $arg in
131
+        -c|--chop-single) single=chop ;;
132
+    esac
133
+    cache="$(mktemp -t fixnl.XXXXXXXX)"
134
+    cat >"$cache"
135
+    nlcount=$(<"$cache" wc -l)
136
+    lastchr=$(<"$cache" tail -c1 | hexdump -e '"%02x"')
137
+    case $nlcount:$lastchr:$single in
138
+        0:??:*)     cat "$cache"        ;;  # 'abc'       => keep as is
139
+        1:0a:chop)  head -c -1 "$cache" ;;  # 'abc\n'     => -c passed: chop!
140
+        1:0a:keep)  cat "$cache"        ;;  # 'abc\n'     => keep as is
141
+        *:0a:*)     cat "$cache"        ;;  # 'a\nb\nc\n' => keep as is
142
+        *:??:*)     cat "$cache";  echo ;;  # 'a\nb\nc'   => add the missing NL
143
+    esac
144
+    rm "$cache"
145
+}
146
+
105 147
 xod() {
106 148
     #
107 149
     # Like mktemp but get the content from clipboard