Skip to main content
4 of 4
added 2 characters in body
Kusalananda
  • 355.8k
  • 42
  • 735
  • 1.1k

A cursory glance at the various Vim help files does not reveal whether this is possible without resorting to using a Vim script. If you use :e filename in Vim and filename does not exist, the editor will open a new buffer of that name and will save the buffer to that name when you use :w. This is usually what you would want to do.

To require that a filename exists when starting Vim, you can overload the vim command with a shell function:

vim () {
    if [ -e "$1" ] || [ -z "$1" ]; then
        command vim ${1:+"$1"}
    else
        printf 'No such file or directory: %s\n' "$1" >&2
        return 1
    fi
}

This would allow you to

  1. only edit an existing file, and
  2. start Vim with no file on the command line (this would enable you to create a new file with :e filename in Vim).

The two tests, [ -e "$1" ] and [ -z "$1" ], detects whether the first argument to the function exists as a filename, or whether it's empty.

The parameter expansion ${1:+"$1"} will expand to the given filename, quoted, or to nothing if there was no filename given.

command vim ensures that we don't call our function recursively.


To also handle possible options that a user may pass to Vim, one would have to parse the command line arguments and remove the arguments that are filename operands that corresponds to non-existing names:

vim () {
    dashdash=false

    for arg do
        use_arg=false

        case $arg in
            --)
                dashdash=true
                use_arg=true
                ;;
            -*)
                if "$dashdash"; then
                    [ -e "$arg" ] && use_arg=true
                else
                    use_arg=true
                fi
                ;;
            *)
                [ -e "$arg" ] && use_arg=true
        esac

        if "$use_arg"; then
            set -- "$@" "$arg"
        else
            printf 'No such file or directory (skipping): %s\n' "$arg" >&2
        fi

        shift
    done

    unset arg dashdash use_arg

    command vim "$@"
}

The only tricky bit here is that an -- argument on the command line signals the end of options. This means that every argument after -- needs to be tested as a filename, whereas while we haven't seen a -- we can skip the -e test on anything that starts with a dash.

This function would open the editor with a blank buffer if no existing filenames were given.

Kusalananda
  • 355.8k
  • 42
  • 735
  • 1.1k