1

I have used gedit with Ubuntu a lot and now transitioning on Macos. I noticed that some of the plugins in the Macos version are missing. For instance, there is no (AFAIK) an out-of-the-box option to comment/uncomment code. However, there is the possibility to define an external tool to basically have whatever you want.

I want to just comment the text selection in R/python style (prepending a # before each line of the input). I went to Tools -> Manage External Tools and defined a "Comment Code" tool in this way:

#!/bin/bash
awk '{print "#" $0}'

and set Input as "Current Selection" and output as "Replace Current Selection".

It works if you select a text; however if you don't select anything, it stalls forever, since (for what I understood) awk is waiting for an input.

How can I avoid this problem? Of course I don't need a awk (or whatever) solution, whatever works is fine. I'm not much expert of bash tools like awk or sed, so very likely I'm missing something very simple.

3
  • There isn't any elegant way in Bash to check whether a script is receiving anything on standard input. You could simply add a timeout but how exactly to do that is somewhat platform-dependent. See e.g. stackoverflow.com/questions/526782/… Commented Mar 11, 2021 at 10:40
  • Thank you for your comment. Ideally, the script shouldn't wait anything if called when there is not a selection. I don't know how gedit passes the input selection to the script and couldn't find a solution to just do nothing when there is no a selection. Commented Mar 11, 2021 at 10:56
  • I would assume that it passes the region as standard input. There is no simple way for a Bash script to determine that standard input is empty (it will always be when you start, and then you wait) but perhaps there could be a way on the gedit side to control this. Commented Mar 11, 2021 at 11:03

1 Answer 1

3

See https://www.gnu.org/software/gawk/manual/html_node/Read-Timeout.html for how to implement a read timeout with GNU awk.

With input from stdin (enter 7 then Enter/Return then Control-D):

$ gawk 'BEGIN{PROCINFO["-", "READ_TIMEOUT"]=5000} {print "#" $0}'
7
#7

or with input from a pipe:

$ seq 2 | gawk 'BEGIN{PROCINFO["-", "READ_TIMEOUT"]=5000} {print "#" $0}'
#1
#2

or from a file:

$ seq 2 > file
$ gawk 'BEGIN{PROCINFO["-", "READ_TIMEOUT"]=5000} {print "#" $0}' file
#1
#2

but if you don't provide any input and wait 5 seconds:

$ gawk 'BEGIN{PROCINFO["-", "READ_TIMEOUT"]=5000} {print "#" $0}'
gawk: cmd. line:1: fatal: error reading input file `-': Connection timed out
$

You can always redirect stderr the usual way if you don't want to see the timeout message:

$ gawk 'BEGIN{PROCINFO["-", "READ_TIMEOUT"]=5000} {print "#" $0}' 2>/dev/null
$

but of course that would mask ALL error messages so you might want to do this instead to just mask that one message:

{ gawk 'BEGIN{PROCINFO["-", "READ_TIMEOUT"]=5000} {print "#" $0}' 2>&1 >&3 |
    grep -v 'fatal: error reading input file'; } 3>&1

e.g.:

$ { gawk 'BEGIN{print "other error" >"/dev/stderr";
        PROCINFO["-", "READ_TIMEOUT"]=5000} {print "#" $0}' 2>&1 >&3 |
    grep -v 'fatal: error reading input file'; } 3>&1
other error
$

Obviously change the 5000 to however many milliseconds you want the script to wait for input.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your reply. It looks like that, on macos, gawk is not defined, so I couldn't check your answer. Maybe my question was misleading, but I don't necessary need awk to have read timeout; I'm trying to find a way to prepend the # character to each line of a selection, when there is a selection, and do nothing otherwise.
You can install gawk on macos (I have). Understood on your needs, just showing you one way to, I think, get the functionality you want working. There may of course be other ways with other tools, etc.
Thank you. I will install gawk and test your solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.