Multi-file search in vim - macos

I am comfortable with vim for normal editing.
I still need to use BBEdit for a few things. Mainly multi-file search. I provide it a folder listing of XCode project and what I want to search for and it produces a listing of files that I can do down through and do whatever.
http://www.mactech.com/articles/mactech/Vol.21/21.02/BBEditDoesntSuck/figure3.jpg
Can I somehow do this in vim? I am using the new maximum-awesome version released by Square: https://github.com/square/maximum-awesome

Given that maximum-awesome includes the ack plugin and the silver searcher package, :Ack string is the easiest way to do this. It also includes unimpaired plugin, so you can navigate the results (in clist) using [q and ]q. :help unimpaired, :help ack.

Don't use that silly distribution, it may feel like a convenient shortcut at first but it will slow you down. Configuring Vim and installing plugins yourself according to your needs is a large part of the learning experience. Skip that part and you'll be hooked to plugins and to someone else's tastes without getting the chance to actually learn to use Vim.
Case in point:
Vim does exactly what you want without plugins.
:vim foo **/*.m | cw
searches for foo in every *.m file under the working directory and opens the quickfix window if matches are found.
See :help file-searching and :h :vim grep.
You have installed a distribution that comes with 35 plugins without even reviewing them and deciding if they are worth installing or not or even actually read up on what they do. One of those plugins, Ack.vim, is there specifically to provide a streamlined (and fast) project-wide search experience. You should read its documentation, :help ack.
And, maybe, try the standard method before you get too used to Ack.vim.

You can use vimg for multi file search.
vimg /search string/ **
** makes it recursive for all file types
**/**.java if you want to search recursively for all java files
* if you want to search current working directory only
copen to open search results
cnext to see next match
cprev to see prev match
cclose to close search results

Related

How do I effectively identify an unknown file format

I want to write a program that parses yum config files. These files look like this:
[google-chrome]
name=google-chrome - 64-bit
baseurl=http://dl.google.com/linux/chrome/rpm/stable/x86_64
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
This format looks like it is very easy to parse, but I do not want to reinvent the wheel. If there is an existing library that can generically parse this format, I want to use it.
But how to find a library for something you can not name?
The file extension is no help here. The term ".repo" does not yield any general results besieds yum itself.
So, please teach me how to fish:
How do I effectively find the name of a file format that is unknown to me?
Identifying an unknown file format can be a pain.
But you have some options. I will start with a very obvious one.
Ask
Showing other people the format is maybe the best way to find out its name.
Someone will likely recognize it. And if no one does, chances are good that
you have a proprietary file format in front of you.
In case of your yum repository file, I would say it is a plain old INI file.
But let's do some more research on this.
Reverse Engineering
Reverse Engineering maybe your best bet if nobody recognizes your format.
Take the reference implementation and find out what they are using to parse the format.
Luckily, yum is open source. So it is easy to look up.
Let's see, what the yum authors use to parse their repo file:
try:
ini = INIConfig(open(repo.repofile))
except:
return None
https://github.com/rpm-software-management/yum/blob/master/yum/config.py#L1304
Now the import of this function can be found here:
from iniparse import INIConfig
https://github.com/rpm-software-management/yum/blob/master/yum/config.py#L32
This leads us to a library called iniparse (https://pypi.org/project/iniparse/).
So yum uses an INI parser for its config files.
I will show you how to quickly navigate to those kind of code passages
since navigating in somewhat large projects can be intimidating.
I use a tool called ripgrep (https://github.com/BurntSushi/ripgrep).
My initial anchors are usually well known filepaths. In case of yum, I took /etc/yum.repos.d for my initial search:
# assuming you are in the root directory of yum's source code
rg /etc/yum.repos.d yum
yum/config.py
769: reposdir = ListOption(['/etc/yum/repos.d', '/etc/yum.repos.d'])
yum/__init__.py
556: # (typically /etc/yum/repos.d)
This narrows it down to two files. If you go on further with terms like read or parse,
you will quickly find the results you want.
What if you do not have the reference source?
Well, sometimes, you have no access to the source code of a reference implementation. E.g: The reference implementation is closed source.
Try to break the format. Insert some garbage and observe the log files afterwards. If you are lucky, you may find
a helpful error message which might give you hints about the format.
If you feel very brave, you can try to use an actual decompiler as well. This may or may not be illegal and may or may not be a waste of time.
I personally would only do this as a last resort.

A new language, how to auto-complete in windows vim?

I'm using Gvim in windows.
Normally, when we type some character then press Ctrl-n, vim will show some tag, but those tags just includes words which have been pre-typed in the current file.
Now, I need it working in a new language, and show the tag which has been defined in other files.
So, I create a new \\.ctags for this new language, and generate tags file by exuberant-ctags.
I can choose a function in current file, then press Ctrl-] to jump to the function definition, but this function was define in the other files. It is working very well.
I don't know how to make it show the tags which are generated by ctags when I type some character.
Please help me. Thanks very much.
My English is poor, I hope you can understand what I said.
CTRL-N is just the default completion (which completes from a variety of sources, including the open buffers and also the tags database). There are many more specialized completions (all starting with CTRL-X), among them tags completion, triggered via CTRL-X CTRL-], see :help i_CTRL-X_CTRL-]. If you've correctly configured the 'tags' option (so your tags database is found) and tags jumps do work, just start using that.
Some languages / filetypes also define a language-specific completion (for language keywords etc.), usually via the 'omnifunc' option and triggered by CTRL-X CTRL-O. You could write such yourself, too.

What can I do in VIM that I can't already do in Visual Studio? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I heard it takes 30 days minimum to get comfortable with vi. I'm on day 2 hehe. Right now, I seem to be merely memorizing different shortcuts for things I already did in Visual Studio (incremental search, prev/next word, etc.).
So far the most powerful aspect seems to be the numeric keys combined with commands (5 * next line), and the idea of normal/insert modes.
There are a few things I miss from Visual Studio. Ctrl-Click'ing the mouse for quick copy and pasting is probably the biggest.
So that I don't get discouraged, can you guys walk me through some things in vi that you do regularly that can't be done in Visual Studio? It'll help me focus on what to learn and help me develop better habits.
I'll just leave a link to this SO answer here.
VI means never ever having to take you fingers off the keyboard.
Note that I don't use Visual Studio, and know little about the available features in it. The following are examples of what I find useful in Vim, not a list of missing features in Visual Studio.
Macros
It's easy to create macros for complex (but repetitive) operations. To illustrate with a simple example, let's say we start with:
Line1
Line2
Line3
Line4
Line5
Now we want to envelop each line in a print(""); statement.
Place the cursor on the first line, and enter:
qx to start recording a macro to the register x
Shift+I print(" Esc to insert text at the beginning of the line
Shift+A "); Esc to append text at the end of the line
j to go down one line
q to stop recording the macro
4#x to execute the macro in register x 4 times
See :help complex-repeat for more info on Vim macros.
Text objects
Note that this is one of the improvements Vim has over the traditional Vi. If it doesn't work, you're probably running in Vi compatibility mode; use :set nocompatible to enable the full functionality of Vim.
Text objects allow you to easily select regions of text. Let's say we start with the following text, and place the cursor on some text:
<b><i>some text</i></b>
Now we want to delete everything between <i> and </i>. This can be done by simply typing the command dit (d'elete i'nner t'ag)! Or if we want to include the tags themselves in our selection, use dat (d'elete a t'ag). To delete everything inside the <b> tags, use d2it (d'elete two i'nner t'ags).
You can similarly use daw (delete a word), dap (delete a paragraph), di" (delete inside double-quotes), etc; see :help text-objects for the complete list.
Another useful example of text objects:
v2ap"+y
v toggles visual mode. This makes it easier to see what you're selecting, and lets you adjust your selection with a series of multiple motions before you execute a command.
2ap selects this paragraph and the next one
"+ selects the system clipboard as register for the next operation
y yanks the selection to the given register
In other words, that command would copy two paragraphs from your text to the system clipboard (e.g. for pasting them here at StackOverflow).
Global editing
The global command is used to apply an Ex command to all lines matching a given regular expression. Examples:
:global/test/print or :g/test/p would print all lines containing the phrase test
:global/test/delete or :g/test/d would delete said lines
:global/test/substitute/^/#/ or :g/test/s/^/#/ would search for lines containing the phrase test, and comment them out by substituting the regexp anchor ^ (beginning-of-line) with the symbol #.
You can also do some cool stuff by passing the search motions /pattern or ?pattern as ranges:
:?test?move . searches backwards for a line containing test, and moves it to your current position in the file
:/test/copy . searches forwards for a line containing test, and copies it to the current position in the file
Good luck and have fun learning Vim!
Edit a file on a Solaris machine that only allows SSH access.
This article is what got me started on Vim, and I never looked back:
http://www.viemu.com/a-why-vi-vim.html
It has some great examples on Vim's power.
Use screen to keep a session running on a remote machine accessed over ssh
Visual Studio's regular expressions are a little bit Mickey Mouse. Vim has the full POSIX regular expression language at your fingertips.
As far as I can tell (in Visual C# express 2010) ctrl-click just selects whatever word you click on. To do the same in VIM, you can combine the yank command with a movement command.
So you press "y" for yank (copy) then "e" or "w" to copy to the end of the word.
There is many differences.
Block (and column) wise copy, paste, edit
the dot command! (after duck tape the second most powerful tool on the planet, seriously)
I suggest you watch some screencasts at http://vimcasts.org/ to get a feeling of the power of vim.
e.g.:
http://vimcasts.org/episodes/creating-the-vimcasts-logo-as-ascii-art/
http://vimcasts.org/episodes/selecting-columns-with-visual-block-mode/
You could always use the Vim emulator/add-on for Visual Studio and get some of the power of vim mixed with the features of VS. If you're already using Visual Studio, I assume you're using a .NET language, which without VS, would be much more painful to use.
Vim Essentials is a nice set of slides.
Personally, I got used to vi a long time ago, when we didn't have the luxury of a mouse in student's Unix terminals. Since then, I used vi/vim for everything safe for writing emails.
To this day, I probably use only 1/20 of the commands, but never felt the need to write code with another text editor, and reaching for a mouse in an IDE feels very clumsy to me.
Using high level and expressive languages, that do not require an IDE (mainly python, sql, javascript) really helps. I suppose it wouldn't be as easy with Java or C++.
Not having to move and point with the mouse when coding (safe for using the browser) also helps preventing Carpal tunnel syndrome.
BTW, I suppose Vim integrates better with Unix than with Windows... and who said 30 minutes was a little optimistic :)
Edit documents over SSH. Vim's really nice for that.
Edit: looks like a lot of people have already said that :)
teco is your answer. You only need a PDP-10 and an ASR-33 and you're on your way!

Great tools to find and replace in files? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 1 year ago.
Improve this question
I'm switching from a Windows PHP-specific editor to VIM, on the philosophy of "use one editor for everything and learn it really well."
However, one feature I liked in my PHP editor was its "find and replace" capability. I could approach things two ways:
Just find. Search all files in a project for a string, see all the occurrences listed, and click to dive into that file at that line.
Blindly replace all occurrences of "foo" with "bar".
And of course I could use the GUI to say what types of files, whether to look in subfolders, whether it was case sensitive, etc.
I'm trying to approximate this ability now, and trying to piece it together with bash is pretty tedious. Doable, but tedious.
Does anybody know any great tools for things like this, for Linux and/or Windows? (I would really prefer a GUI if possible.) Or failing that, a bash script that does the job well? (If it would list file names and line numbers and show code snippets, that would be great.)
Try sed. For example:
sed -i -e 's/foo/bar/g' myfile.txt
Vim has multi-file search built in using the command :vimgrep (or :grep to use an external grep program - this is the only option prior to Vim 7).
:vimgrep will search through files for a regex and load a list of matches into a buffer - you can then either navigate the list of results visually in the buffer or with the :cnext and :cprev commands. It also supports searching through directory trees with the ** wildcard. e.g.
:vimgrep "^Foo.*Bar" **/*.txt
to search for lines starting with Foo and containing Bar in any .txt file under the current directory.
:vimgrep uses the 'quickfix' buffer to store its results. There is also :lvimgrep which uses a local buffer that is specific to the window you are using.
Vim does not support multi-file replace out of the box, but there are plugins that will do that too on vim.org.
I don't get why you can't do this with VIM.
Just Find
/Foo
Highlights all instances of Foo in the file and you can do what you want.
Blindly Replace
:% s/Foo/Bar/g
Obviously this is just the tip of the iceberg. You have lots of flexibility of the scope of your search and full regex support for your term. It might not work exactly like your former editor, but I think your original 'use one editor' idea is a valid one.
Notepad++ allows me to search and replace in an entire folder (and subfolders), with regex support.
You can use perl in command prompt to replace text in files.
perl -p -i".backup" -e "s/foo/bar/g" test.txt
Since you are looking for a GUI tool, I generally use the following 2 tools. Both of them have great functionality including wildcat matching, regex, filetype filter etc. Both of them displays good useful information about the hit in files like filename/lines.
Visual Studio: fast yet powerful. I uses it if the file number is huge (say, tens of thousands...)
pspad: lightweight. And a good feature about find/replace for pspad is that it will organize hits in different files in a tree hierarchy, which is very clear.
There are a number of tools that you can use to make things easier. Firstly, to search all the files in the project from vim you can use :grep like so:
:grep 'Function1' myproject/
This essentially runs a grep and lets you quickly jump from/to locations where it has been found.
Ctags is a tool that finds declarations in your code and then allows vim to jump to these declarations. To do this, run ctags and then place your cursor over a function call and then use Ctrl-]. Here is a link with some more ctags information:
http://www.davedevelopment.co.uk/2006/03/13/vim-ctags-and-php-5/
I don't know if it is an option for you, but if you load all your files into vim with
vim *.php
than you can
:set hidden
:argdo %s/foo/bar/g => will execute the substitue command in all opened buffers
:wall => will write all opened buffers
Or instead of loading all your files into vim try :help vimgrep and a cominbation of :help argdo and :help argadd
For Windows, I think that grepWin is hard to beat -- a GUI to a powerful and flexible grep tool for Windows. It searches, and replaces, knows about regular expressions, that sort of stuff.
look into sed ... powerful command line tool that should accomplish most of what you're looking for ... its supports regex, so your find/replace is quite easy.
(man sed)
Notepad++ has support for syntax highlighting in many languages and supports find and replace across all open files with regex and basic \n \r \t support.
The command grep -rn "search terms" * will search for the specified terms in all files (including those in sub-directories) and will return matching lines including file name and line number. Armed with this info, it is easy to jump to a particular file/line in VIM.
As was mentioned before, sed is extremely powerful for doing find-and-replace.
You can run both of these tools from inside VIM as well.
Some developers I currently work with swear by Textpad. It has a UI and also supports using regex's -- everything you're looking for and more.
A very useful search tool is ack. (Ubuntu refers to it as "ack-grep" in the repositories and man pages.)
The short version of what it does is a combination of find and grep that's more powerful and intelligent than that pair.

General Purpose Filter As You Type (aka typeahead, Incremental find, autocomplete) is it out there?

Background
Lately I've become a fanatic that everything I type while working on a computer should be compatible with "DRY". If there's anything I have to type more than once in any context, I want some kind of user-aware auto-complete option to do some of the work for me -- always -- no exceptions.
Having to work under Windows, I've looked at GUI solutions to make this insane goal a reality.
The (almost) optimal solution
If you have a moment, open up Firefox 3.0 and type a few keystrokes into the address bar. You will notice that it performs a kind of Incremental Autocomplete based on space-separated sub-strings of whatever you type. Another place in Firefox that does something similar is the about:config URL.
This is sub-optimal, because I don't want this in Firefox only. I want to use this everywhere.
The Question
Does anyone out there know of a widget or app that does nothing but insanely good incremental auto-complete that can be used as a general purpose "run everywhere" tool? Something that allows the user to: 1) maintain one or more "completion candidate files"; 2) pick one of those files as the source for Firefox 3.0 style completion; 3) return the result (or blank if the user canceled), and do those three things only?
Details
Here's how it should work:
STEP1: user saves or more csv file(s) (or other easy-edit format) somewhere in his hard-drive
STEP2: user creates a Windows Script Host script or a batch file (or whatever) instantiates the FilterAsYouType GUI
STEP3: user runs the script file, and the script file instantiates the GUI, telling it which CSV file to use as the source of all potential completions
STEP4: the user either chooses one of the completions, supplies his own text that is not in the list, or cancels out without supplying anything
STEP5: when the user is done the script saves the result to a variable and does something with it
Here is some pseudo-code for the script:
include "GenericTypeaheadWidget";
var gengui = new GenericTypaheadWidget('c:\docs\favorite_foods.csv');
var fave_food = gengui.get_user_input();
if(fave_food != ''){
alert('you chose '+fave_food+'!');
}
The rationale
The goal is to just have a way to always be able to do auto-completions from a list of arbitrary items, even if the list is a couple thousand items, and not have to rely on it being built into some IDE or standalone application that only accepts certain kinds of input or has an overly-complicated API relative to the simplicity of this task.
CSV (or text or sqlite database) would provide a way for me to self-generate "candidate lists" or "history logs" and then just use those logs as the source of the possible completions.
The disclaimer
I've tried several GUI "launcher" programs, command-line engines like power-shell and scripting shells, the regular plain old command-line history with varying degrees of satisfaction. The problem with these is they all do extra superfluous stuff like searching directories or built-in commands. I just want nothing but whatever is in the CSV file I happen to be pointing at.
I'm wondering if there is any simple tool that does nothing but what I'm describing above.
UPDATE: It looks like this question is very closely related to Graphical Command Shell, which captures the essential idea presented here.
You should really try Launchy - it's exactly what you're looking for, a "run anything" with intelligent autocompletion. It completely changes the way you interact with a Windows PC.
And it has open source-code, so you can borrow its autocompletion code if you want to roll your own interface.

Resources