1

I know it is possible to launch the default editor from a shell script. For example, assuming the $EDITOR environment variable is set:

$EDITOR ~/newfile.txt

Is it possible to open a new file with pre-populated text? One way I can think of is to create the file before opening it:

echo "Header" > ~/newfile.txt
$EDITOR ~/newfile.txt

But it would be slightly nicer if the file which the text editor opens is pre-populated, but also capable of being thrown away. Is this possible?

5
  • 1
    The way you suggested is the way it should be done. I.e., put some prepopulated content in a file, in some way, shape or form then open it with $EDITOR filename command. Do you need something different ? If you are inquiring if the OS or the editor of your choice supports such an arrangement, without requiring creating the file somehow, it all depends the editor of your choice and capabilities of that editor. It is not something that OS could provide for you. – MelBurslan Feb 22 '16 at 22:04
  • I just want to put the editor in the state it would be in if you typed a few lines after opening it. If at that point you quit the editor, It should throw the file away. That's the behaviour of every editor I have used, so I thought this might be possible somehow. – SauceCode Feb 22 '16 at 22:13
  • If it's doable, it's not doable in a generic way such that you can use $EDITOR. – Andy Dalton Feb 22 '16 at 22:20
  • I had imagined something like what git does when you commit, though I guess that uses some trickery with git hooks below the hood to move the file from <repo>/.git/COMMIT_EDITMSG to a useful location after you save it. – SauceCode Feb 22 '16 at 22:23
  • The behavior of ANY editor, depends on the editor's capabilities. And in most part, every editor, who opens a document upon invocation, do not throw the document away. If you made a change it asks you if you want to save it. If you haven't made any change, no-harm, no-fault it keeps the file as it for the next invocation. Your expectancies are not based on an EDITOR's capability, it is the way you configure it to act the way you want it to. – MelBurslan Feb 22 '16 at 22:32
3

If you want to pre-populate content in the editor, write this initial content to the file, just like you thought.

There is no way to “put the editor in the state it would be in if you typed a few lines after opening it” that works across diverse editors. In many editors, this means that the file will be unsaved, but there's no uniform way to achieve that state, and there are editors that don't have this concept at all (e.g. Scratch).

You can however detect whether the file was saved at all from the editor. Abandon the operation if the file wasn't saved. To detect whether the file was saved, check its modification time before and after.

file=$(mktemp)
cat <<EOF >"$file"
Hello
world
EOF
old_metadata=$(ls -li "$file")
"${VISUAL:-"${EDITOR:-vi}"}" "$file"
new_metadata=$(ls -li "$file")
if [ "$new_metadata" = "$old_metadata" ]; then
  … # unchanged file, abandon operation
else
  … # modified file, carry on
fi

Beware that if the file was modified but the size and inode didn't change and the modification took less than 1 second, this script will think that the file hasn't been modified. This won't happen if a human is editing, but it could easily happen if $EDITOR is a script that submits a modified file automatically. It's difficult to do better in a portable way. With GNU coreutils, passing the --full-time option to ls solves this problem if the filesystem supports subsecond timestamps with sufficient precision.

Alternatively, check whether the file has been modified. The portable way of doing this is to keep a copy of the initial content and call cmp. If commands like sha256sum or sha are available, you can use these and compare the hashes before and after. You may still want to consider the file to have been edited if its timestamp has changed — maybe the user did want to submit the default input.

This technique is what several version control systems use when they launch an editor to edit a commit message. If the user doesn't save the file, the commit is aborted.

If you also want to place the cursor at the end of the input, there's no universal way to do that. With many editors, you can write

"$EDITOR" +"$line" "$file"

and the editor will open with the cursor on the specified line. This is supported by many editors including vi (all variants), emacs, joe and gedit, but not by kwrite.

1
  • I've often wondered how version control systems handle this. Very nice to know! – SauceCode Feb 23 '16 at 1:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.