3

I have a file called foo.txt. I want to associate my own program with the mime-type .txt so that my program opens a terminal and shows the contents of foo.txt as standard output. I would prefer Ruby, but BASH scripting will also be OK.

An working example: I can open an HTML file with firefox. I want to open txt files with my own executable the same way.

I can't figure out how can I actually get it working?

Example 2: I can open a .txt file with Geany/Mousepad/Atom/Code etc. Let's suppose I have made a tool just like mousepad. How should my program handle the .txt mimetype?

So far I have made a small GUI program with Ruby and made it executable and tried to open foo.txt with my program (I used the Nemo file manager). I have captured arguments, and stdins in my Ruby program so it will show the Argument and STDINs if any. But my program doesn't even show up the window if I open a .txt file with it!

How am I supposed to achieve the result?

11
  • To be clear, you have right clicked on the file and selected Open With > Other Application and selected your custom application and that does not work? What happens specifically? When you use your custom application can you open files with it?
    – kemotep
    Mar 6, 2019 at 22:02
  • Yes. I am using a simple Ruby GUI program (with Ruby2D) The custom command is a GUI application that shows the arguments given, the base name of the script. It runs normally from the terminal, but doesn't open when I 'open as' with that. Also, I have proper permissions, and I am using a single user.
    – 15 Volts
    Mar 7, 2019 at 8:20
  • What operating system are you using? You may need to change the values or import them from ~/.local/share/applications/mimeapps.list to have Nemo recognize the change.
    – kemotep
    Mar 7, 2019 at 18:23
  • 1
    Your Ruby GUI program is able to open up files, its Nemo not opening said files using your choice of filetype association? Is that the issue? Or is the issue that your Ruby program does not open up files? If the latter is the issue this question would be better served on Stack Overflow.
    – kemotep
    Mar 8, 2019 at 1:03
  • 1
    If "Opens a terminal and shows the contents of foo.txt as standard output" are all done inside your program, and your program support command line parameters like program filename, then you can simply create a desktop file for your program, and set mime association through your DE settings. Mar 8, 2019 at 16:26

2 Answers 2

5

Introduction

When a file is opened with an application, the file is just passed to the application as an argument.

So when you open firefox-nightly located in /bin/ with p.html located in /home/user/, it's basically similar to run /bin/firefox-nightly /home/user/p.html.

Creating an Executable

As mentioned in the question:

So far I have made a small GUI program with Ruby and made it executable and tried to open foo.txt with my program (I used the Nemo file manager).

Let us create a Ruby program as asked by the OP that will copy the contents of a file passed as an argument to /tmp/tempfile-#{n}. Note that any programming language will work if it can accept command line arguments.

#!/usr/bin/env ruby

# Errors
ERR_NO_FILE = 2

FILE = $*[0]

begin
    tempfile, counter = File.join(%W(/ tmp tempfile)), 0
    tempfile.replace(File.join(%W(/ tmp tempfile-#{counter += 1}))) while File.exist?(tempfile)
    IO.write(tempfile, IO.read(FILE))
rescue Errno::ENOENT
    exit!(ERR_NO_FILE)
rescue Interrupt, SystemExit, SignalException
    exit!(0)
rescue Exception
    abort($!.backtrace.join(?\n))
end if FILE

And let's call our program copycat.rb, and move it to /tmp/ directory.

We can surely run the program on a terminal like this:

/tmp/copycat.rb /tmp/AFile

A this will copy all the contents of /tmp/AFile to /tmp/tempfile-#{n} Where #{n} is the count in case any duplicate tempfile exists.

Creating an Application Entry

Now to open this with our program from the file manager, we need to create an Application entry. To do that, we have 2 options. The first options is:

Create a file called copycat.desktop in $HOME/.local/share/applications, with the following content:

[Desktop Entry]
Version=1.0
Type=Application
Name=CopyCat
Comment=Copy the contents of a file to /tmp/tempfile#{n}
Exec=/tmp/copycat.rb %u
Icon=edit-copy
Path=
Terminal=false
StartupNotify=false
Actions=
Categories=Copy;Utility

Don't forget to add the %u option to the line starts with Exec.

Testing

Well, to test, let's create a simple file called with the content 'hello world' or anything you want. Open your file manager, and click your secondary mouse button on the file, and select "Open With" or similar option. Because it's GUI related, I will add some sample pictures.

  1. Nautilus, "Open With Other Application":

    Nautilus, "Open With Other Application"

  2. Nautilus, "View All Applications":

    Nautilus, "View All Applications"

  3. "CopyCat":

    "CopyCat"

  4. When done, you can see the tempfile-#{n} created in /tmp/

    enter image description here

The file manager I used here is Nautilus, but this should work with other file managers as well, just the text might differ.

The second option is to make the application available for all users. To do that, you have to move the file from $HOME/.local/share/applications/copycat.desktop to /usr/share/applications and change the ownership to root.

This is how the open with a custom executable works in Linux. A similar GUI app can be created and opened in the same way.

1
case $1 in
 *txt)  applic=less ;;
 *html) applic=vim  ;;
esac

xterm -e $applic $1 &

Minimalistic, but tested.

This script you can call from a first xterm. Dont look at the case-esac, but note xterm with -e and ampersand.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .