0

I want to be able to search files that only reside in the directory of the file that I opened inside vim.

The documentary of Ack says:

:Ack[!] [options] {pattern n} [{directory}]                               *:Ack*

Search recursively in {directory} (which defaults to the current
directory) for the {pattern}.  Behaves just like the |:grep| command, but
will open the |Quickfix| window for you. If [!] is not given the first
occurrence is jumped to.

On VimFandom I found that I could get the current directory of the file with echo expand('%:p:h') but how could I get this to evaluate in the Ack command?

I'd need something like this:

:Ack searchpattern expand('%:p:h')

Flov
  • 1,527
  • 16
  • 25

4 Answers4

2

The expression register, "=, will let you evaluate an expression and put/paste the output. Using <c-r> on the command-line will insert content from a register.

:Ack pat <c-r>=expand('%:p:h')<cr>

For more help see:

:h "=
:h i_CTRL-R

Using :grep instead of :Ack

You can set 'grepprg' to use the silver searcher or other grep-like tool, e.g. ripgrep.

set grepprg=ag\ --vimgrep\ $*
set grepformat=%f:%l:%c:%m

:grep understands % and :h as parameters. This means you can do:

:grep pat %:h

For more help see:

:h 'grepprg'
:h :grep
Peter Rincker
  • 43,539
  • 9
  • 74
  • 101
1

If directory has no further children (otherwise is recursive search):

nnoremap <leader>f <Esc>:cd %:p:h<CR><Esc>:Ag<CR>

Where,

  • :cd %:p:h changes directory to the location of current file
  • :Ag<CR> directly goes to the interactive search window if you have fzf-vim

By "interactive search" I mean customizing your search pattern dynamically (try wildcard, test if adding more keywords, ...)

On the other hand, if you don't need the interactive search, you are sure what you look for, then:

nnoremap <leader>f <Esc>:cd %:p:h<CR><Esc>:Ag<Space>
Xopi García
  • 359
  • 1
  • 2
  • 9
0

Use :exe[cute]:

:exe 'Ack searchpattern ' . expand('%:p:h')

. (dot) means string concatenation.

phd
  • 82,685
  • 13
  • 120
  • 165
  • Thanks @phd in my setup it's working without the dot. Now I just need to find a way how to make it work with a single command so I can start to type in the searchpattern. I mapped the command to map `a :exe 'Ack searchpattern' expand('%:p:h')` but I'd still need to scroll back to go back with the cursors to searchpattern. Any ideas how to make this work so the cursor is positioned at the right spot? – Flov Jan 17 '20 at 11:31
0

I have a little mapping for cases like this: %% inserts the directory of the current file.

cnoremap <expr> %% filename#command_dir('%%')

And the function definition:

function filename#command_dir(keymap) abort
  if getcmdtype() isnot# ':'
    return a:keymap
  endif
  let l:dir = expand('%:h')
  return empty(l:dir) ? '.' : (dir.'/')
endfunction
D. Ben Knoble
  • 4,273
  • 1
  • 20
  • 38
  • I would like to use this but since I'm terribly unfamiliar with vimscripts I'm having trouble testing this out. Just pasting this into my vimrc file gives me `Function name does not match script file name` – Flov Jan 18 '20 at 13:05
  • 1
    @Flov it’s following an autoload function convention, so you put the function in `~/.vim/autoload/filename.vim`. The help for autoloading is pretty good, but ofc you dont know to look there if you dont know thats what it is! Thanks for following up – D. Ben Knoble Jan 18 '20 at 13:10