Vim:Use path relative to current file

From FVue
Jump to: navigation, search

Problem

Sometimes you're editing a file deeply nested in a directory hierarchy, and you want to edit a file in an adjacent directory, relative to the current directory. E.g. you're editing:

/usr/local/var/chi/proj/foo/back/app/views/bar/index.html.erb

and you want to edit:

/usr/local/var/chi/proj/foo/back/app/views/cee/index.html.erb

Environment

  • vim-8.2

Solution

See: https://superuser.com/questions/252893/vim-use-the-path-of-the-current-file

In vim, % is the actual file, %:h is the directory of the actual file, and %:p is the full path of the actual file.

So to edit the new file (if current file path is full enough), type:

:e %:h/../cee/index.html.arb

Or when current file path isn't full enough:

:e %:p:h/../cee/index.html.erb

:help filename-modifiers

                                                         filename-modifiers
:_%: ::8 ::p ::. ::~ ::h ::t ::r ::e ::s ::gs ::S
     %:8 %:p %:. %:~ %:h %:t %:r %:e %:s %:gs %:S
The file name modifiers can be used after "%", "#", "#n", "<cfile>", "<sfile>",
"<afile>" or "<abuf>".  They are also used with the fnamemodify() function.

These modifiers can be given, in this order:
        :p      Make file name a full path.  Must be the first modifier.  Also
                changes "~/" (and "~user/" for Unix and VMS) to the path for
                the home directory.  If the name is a directory a path
                separator is added at the end.  For a file name that does not
                exist and does not have an absolute path the result is
                unpredictable.  On MS-Windows an 8.3 filename is expanded to
                the long name.
        :8      Converts the path to 8.3 short format (currently only on
                MS-Windows).  Will act on as much of a path that is an
                existing path.
        :~      Reduce file name to be relative to the home directory, if
                possible.  File name is unmodified if it is not below the home
                directory.
        :.      Reduce file name to be relative to current directory, if
                possible.  File name is unmodified if it is not below the
                current directory.
                For maximum shortness, use ":~:.".
        :h      Head of the file name (the last component and any separators
                removed).  Cannot be used with :e, :r or :t.
                Can be repeated to remove several components at the end.
                When the file name ends in a path separator, only the path
                separator is removed.  Thus ":p:h" on a directory name results
                on the directory name itself (without trailing slash).
                When the file name is an absolute path (starts with "/" for
                Unix; "x:\" for Win32; "drive:" for Amiga), that part is not
                removed.  When there is no head (path is relative to current
                directory) the result is empty.
        :t      Tail of the file name (last component of the name).  Must
                precede any :r or :e.
        :r      Root of the file name (the last extension removed).  When
                there is only an extension (file name that starts with '.',
                e.g., ".vimrc"), it is not removed.  Can be repeated to remove
                several extensions (last one first).
        :e      Extension of the file name.  Only makes sense when used alone.
                When there is no extension the result is empty.
                When there is only an extension (file name that starts with
                '.'), the result is empty.  Can be repeated to include more
                extensions.  If there are not enough extensions (but at least
                one) as much as possible are included.
        :s?pat?sub?
                Substitute the first occurrence of "pat" with "sub".  This
                works like the :s command.  "pat" is a regular expression.
                Any character can be used for '?', but it must not occur in
                "pat" or "sub".
                After this, the previous modifiers can be used again.  For
                example ":p", to make a full path after the substitution.
        :gs?pat?sub?
                Substitute all occurrences of "pat" with "sub".  Otherwise
                this works like ":s".
        :S      Escape special characters for use with a shell command (see
                shellescape()). Must be the last one. Examples:
                    :!dir <cfile>:S
                    :call system('chmod +w -- ' . expand('%:S'))

There's a similarity with bash history expansion modifiers:

$ man bash
HISTORY EXPANSION
   Modifiers
       After the optional word designator, there may appear a sequence of one or  more
       of the following modifiers, each preceded by a `:'.  These modify, or edit, the
       word or words selected from the history event.

       h      Remove a trailing filename component, leaving only the head.
       t      Remove all leading filename components, leaving the tail.
       r      Remove a trailing suffix of the form .xxx, leaving the basename.
       e      Remove all but the trailing suffix.
       p      Print the new command but do not execute it.
       q      Quote the substituted words, escaping further substitutions.
       x      Quote the substituted words as with q, but break into  words  at  blanks
              and  newlines.   The  q and x modifiers are mutually exclusive; the last
              one supplied is used.
       s/old/new/
              Substitute new for the first occurrence of old in the event  line.   Any
              character  may be used as the delimiter in place of /.  The final delim?
              iter is optional if it is the last character of the event line.  The de?
              limiter  may be quoted in old and new with a single backslash.  If & ap?
              pears in new, it is replaced by old.  A single backslash will quote  the
              &.   If  old  is  null, it is set to the last old substituted, or, if no
              previous  history  substitutions  took  place,  the  last  string  in  a
              !?string[?]  search.  If new is null, each matching old is deleted.
       &      Repeat the previous substitution.
       g      Cause changes to be applied over the entire event line.  This is used in
              conjunction with `:s' (e.g., `:gs/old/new/')  or  `:&'.   If  used  with
              `:s',  any  delimiter can be used in place of /, and the final delimiter
              is optional if it is the last character of the event line.  An a may  be
              used as a synonym for g.
       G      Apply  the  following `s' or `&' modifier once to each word in the event
              line.

Comments

blog comments powered by Disqus