So, to better explain what I'm asking for, I am writing a zsh plugin for quickly navigating up directories and I want to offer the ability to traverse into a directory by specifying a starting directory in $PWD.
For example, if I am in a directory ~/example/first/left/second and I wanted to go to a directory ~/example/first/right, I could call $ up first/right. I managed to get the functionality working just fine, but I want to offer tab completions in the same way cd ..[/..]* does.
At the moment, here is what I have
_up() {
local -a args
args=(`echo ${PWD#/} | sed 's/\// /g'`)
_arguments ':paths:($args[#])'
}
And so I currently have tab completions working for all of the initial options available, but past that point I have no idea how to get zsh to tab complete like paths past this point.
Related
I have a simple issue with zsh. Sometimes, I am in a directory with multiples sub-directories.
So, when I do a $ ls[TAB] or $cd[TAB], I list all these sub-directories.
But how to accept one of the suggestions for sub-directories? Is there a short cut or a key to choose a directory to go deeper in this directory.
I must precise that I don't know systematically the content of these subdirectories, so I can't often choose a subdirectory in which the first letter of filename could allow me to choose automatically the sub-directory to explore.
I was looking for a solution on the web but documentation about zsh completion is pretty big.
Edit: simplest solution to accomplish the desired effect:
press [/] key to 'accept' the current suggested directory ; then press again [tab] key to show suggestions of its subdirectories
Old suggested solution:
Install https://ohmyz.sh/
Then pressing the [tab] key displays a list and the first item is highlighted.
Hit the [tab] key again to choose the desired item and hit the [enter] key to write it in the command line interface, without actually executing the command, only as if you have just typed it in.
Then you can continue hitting the [tab] key to select another subdirectory, and so on.
It also works on any autocompletable, not only dirs.
The only way I know is: double click your target + cmd c + cmd v and then press Enter.
I'm really like AUTOCD option in zsh but widget names make it less comfortable in use. The problem is when I'm e.g. in my home directory, type "down" and press Tab I would expect completion for "Downloads" but on the first place in auto-completion is "down-line-or-beginning-search". Downloads is on the second pace what cause that I have to press tab additionally twice. It makes this process not to much ergonomic.
Does anybody know how to exclude widget names from zsh auto-completion?
zstyle ':completion:*:*:-command-:*:*' ignored-patterns 'down-line-or-beginning-search'
Let's say I have a directory with the following contents:
/Project.Presentation
/Project.Presentation.API
/Project.Presentation.Web
/Project.Presentation.Infra
/Project.Presentation.Util
I want to do this -> Project.Presentation: API and let it autocomplete to Project.Presentation.API. Inside Project.Presentation to type API and <tab>.
Is it possible to let zsh use this 'forgiving' way of ?
You're overcomplicating your solution.
If you want to execute a command with a file inside these directories, or just cd in one of these directories.
Just write cd (or other command) first, then press tab that will complete Project.Presentation. then you can either write API or write A and press tab.
By the way, you can have a way to navigate through the possibilities with an extra tab key.
Read man zshoptions for to discover options available in zsh.
Wordpress allows you to extend its core using "hooks" and "filters." For example, to execute something quite early in the execution process I may write
add_action( 'init', function() { // Do something } );
Filters work similarly. The function that defines a hook is do_action, so to create the init hook a core developer wrote
do_action( 'init' );
do_action accepts several optional arguments that this hook doesn't demonstrate. The function names for filters are add_filter and apply_filter.
Say I'm browsing the source code of some plugin and it's using a hook from one of the source files and I don't know which one. What is the easiest way to locate it?
In Vim I use ctags a lot and I was hoping that it was possible to do something similar, only instead of giving the function name I could give the filter or hook name. Any ideas?
(If it can't be done from within Vim, like ctags, second best would be to run a command that will locate the script for me. This could also be acceptable if it is the best solution)
Say I'm browsing the source code of some plugin and it's using a hook
from one of the source files and I don't know which one. What is the
easiest way to locate it?
I use grep. Couldn't work without it. grep gets me just about anything I want. grep -Rni "do_action( 'init'" * should find the 'init' hook. You can use regex in the search string if you need to as well as tell it to ignore particular files and/or directories. I've tried other options but just haven't ever been sold on anything else. grep is quick and clean.
This isn't a 'Vim' answer but you did say 'or similar' :)
There is a very good hook database at http://adambrown.info/p/wp_hooks/version/3.4 too.
I've had to do this quite a lot lately so I wrote a little Vim plugin to ease the process.
Simply place the caret on name of the hook or filter, press Leader+f to find the hooked functions, or Leader+F to find the hook/filter definition.
To install:
cd ~/.vim/bundle && git clone https://github.com/borzhemsky/wp-hook-finder.git
Add the keybindings to ~/.vimrc:
nnoremap <Leader>f :FindWPHook<CR>
nnoremap <Leader>F :FindWPHookDef<CR>
Site note: Writing this taught me that, yes, people do things like using add_filter hook their functions to hooks defined with do_action, so searching for occurrences manually can be error-prone.
From the basic to the rather involved:
GREP
Already explained.
GREP FROM VIM OR VIMGREP
If you are already in Vim, you can use the :vimgrep command or its sister :grep:
:vim "do_action( 'init' )" **/*.php | copen
See :help starstar for the ** wildcard that let's you do recursive search. :vimgrep uses an internal method while :grep uses, well… grep. The latter may be faster.
CTAGS
Assuming you have ctags installed, the indexing can be done in the shell or in Vim:
$ ctags -R . <-- in the shell
:!ctags -R . <-- in Vim
and the querying is just a matter of :tag do_action. Read :help tags for an indepth explanation.
CSCOPE
Assuming you have cscope installed, you can use it right from the shell:
$ cscope -R *.php
Once the index is created you can search in cscope's interface and open the chosen files in your editor.
Assuming your Vim comes with cscope support, you have to:
create the index, :!cscope -bR *.php
locate the index, :cs add cscope.out
*f*ind the *d*efinition, :cs f d do_action
There are other specialized tools like Codesearch or GNU Global but I think that you don't really need to go further than plain grep or, at most, ctags.
I'm working on a drupal 6 site at mydomain.com/drupalsite, and the designer has put a lot of hardcoded image paths in there, for instance a custom img folder in mydomain.com/drupalsite/img. So a lot of the site uses links to /drupalsite/img/myimg1.png.
Here's the problem -- the site is eventually moving to finaldomain.com, via pointing finaldomain.com to mydomain.com/drupalsite. So now paths like /drupalsite/img/myimg1.png will resolve to finaldomain.com/drupalsite/img/myimg1.png, instead of what should be finaldomain.com/img/myimg1.png. The finaldomain.com site has to point to that subdirectory so it hits the index.php.
My first instinct is to use an .htaccess file to replace the /drupalsite with "", but I've tried about a dozen different solutions and they haven't worked. My hack of a solution was to use some ln -s links but I really don't like it :) tia
Andrew
The best method, in hindsight, is to ensure folks use Drupal functions to make all links:
l (that's the letter L)
drupal_get_path()
base_path()
The l() function takes care of base path worries, and provides a systematic way to define your URL's. Using things like theme_image() plus the l() function are a sure win. Use the second and third functions above if you have to write your own <a> tags and for use inside theme functions like theme_image().
But for your current situation:
As regards Andy's solution, it would be better if you could limit your changes to certain database fields where you know the links are located.
So write a query to select all those fields (e.g. all body fields):
$my_query = db_query("SELECT vid, body FROM {node_revisions}");
This, for example, will get you every body field in the node_revisions table, so even your old revisions would have proper links.
Then run through those results, do str_replace() on each, and then write the changes back:
while($node = db_fetch_object($my_query)) {
$new_body = str_replace('what you have', 'what you want', $node->body);
db_query("UPDATE {node_revisions} SET body = '%s' WHERE vid = %d", $new_body, $node->vid);
}
I'd obviously try it on one record first, to make sure your code behaves as intended (just add a WHERE vid = 5, for example, to narrow it down to one revision). Furthermore, I haven't taken advantage of node_load and node_save, which are better for loading and saving nodes properly, so as to provide a more general solution (for you to replace text in blocks, etc.).
For your files, I'd suggest a good ol' sed command, by running something like the following from within your "sites" folder:
find ./ -type f -exec sed -i ’s/string1/string2/’ {} \;
Nabbed that from here, so take a look on that site for more explanation. If you're going to be working with paths, you'll either need to escape the / of the paths in your version of the sed command, or use a different sed separator (i.e. you can write s#string1#string2# instead of s/string1/string2/, so you could write s#/drupalsite/img/#/img# instead of s/\/drupalsite\/img\//\/img/ :-). See also Drupal handbook page for quick sed commands: http://drupal.org/node/128513.
A bit of a mess, which is why I try to enforce using the proper functions up front. But this is difficult if you want themers to create Drupal content but you don't want to give them access to the "PHP Filter" input format, or they simply don't know PHP. Proper Drupal theming, at any point past basic HTML/CSS work, requires a knowledge of PHP and Drupal's theme-related functions.
I've done this before by taking a full database dump, opening it in a text editor, and doing a global search and replace on the paths. Then on the new host, load the modified dump file, and it will have the correct paths in.
You could try Pathologic, it should be able to correct paths like this.