Worth switching to zsh for casual use? [closed] - bash

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
The default shell in Mac OS X is bash, which I'm generally happy to be using. I just take it for granted. It would be really nice if it auto-completed more stuff, though, and I've heard good things about zsh in this regard. But I don't really have the inclination to spend hours fiddling with settings to improve my command line usage by a tiny amount, since my life on the command line isn't that bad.
(As I understand it, bash can also be configured to auto-complete more cleverly. It's the configuring I'm not all that keen on.)
Will switching to zsh, even in a small number cases, make my life easier? Or is it only a better shell if you put in the time to learn why it's better? (Examples would be nice, too :) )
#Rodney Amato
&
#Vulcan Eager
give two good reasons to respectively stick to bash and switch to zsh. Looks like I'll have to investigate both! Oh well :)
Is there anyone with an opinion from both sides of the argument?

Personally, I love zsh.
Generally, you probably won't notice the difference between it and bash, until you want to quickly do things like recursive globbing:
**/*.c for example.
Or use suffix aliases to associate specific progs with different suffixes, so that you can "execute" them directly. The below alias lets you "run" a C source file at the prompt by simply typing ./my_program.c – which will work exactly as if you typed vim ./my_program.c. (Sort of the equivalent to double clicking on the icon of a file.)
alias -s c=vim
Or print the names of files modified today:
print *(e:age today now:)
You can probably do all of these things in bash, but my experience with zsh is that if there's something I want to do, I can probably find it in zsh-lovers.
I also find the book 'From Bash to Z-Shell' really useful.
Playing with the mind bogglingly large number of options is good fun too!

For casual use you are probably better off sticking with bash and just installing bash completion.
Installing it is pretty easy, grab the bash-completion-20060301.tar.gz from http://www.caliban.org/bash/index.shtml#completion and extract it with
tar -xzvf bash-completion-20060301.tar.gz
then copy the bash_completion/bash_completion file to /etc with
sudo cp bash_completion/bash_completion /etc
which will prompt you for your password. You probably will want to make a /etc/bash_completion.d directory for any additional completion scripts (for instance I have the git completion script in there).
Once this is done the last step is to make sure the .bash_profile file in your home directory has
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
in it to load the completion file when you login.
To test it just open a new terminal, and try completing on cvs and it should show you the cvs options in the list of completions.

Switch to zsh. You will have access to:
zmv: You can do: zmv '(*).mp3' '$1.wma' for thousands of files.
zcalc: Extremely comfortable calculator, better than bc.
zparseopts: One-liner for parsing arbitrary complex options given to your script.
autopushd: You can always do popd after cd to change back to your previous directory.
Floating point support. It is needed from time to time.
Hashes support. Sometimes they are just a key feature.

If all you want to use ZSH for is better completion, the configuration is pretty easy. Place this in your ~/.zshrc:
autoload -U zutil # [1]
autoload -U compinit # [2]
autoload -U complist # [3]
compinit
However, it's worth checking out all the other great features of the ZSH. The above example will give you a pretty plain prompt with good completion. If you don't want to fiddle with configurations, but want to see what ZSH can do for you, Google for "zshrc" and you will get some ready to use configurations to get started.
[1]: http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fzutil-Module
[2]: http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Initialization
[3]: http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fcomplist-Module

zsh has a console gui configuration thing. You can set it up pretty quickly and easily without having to fiddle with configuration files. I don't think you will need much time to set it up, probably 10 seconds with just using defaults, so go ahead and try it out.

Staale is talking about a wizard like program (CUI) which autoruns the first time you run zsh. Just answer some questions, view/change the defaults and its configured for you.
IBM developerWorks has great resources on zsh.
I have not used very advanced features and so far I have not come across serious differences which should hamper someone coming from bash.
Some examples:
!?pattern<Tab> will autocomplete to
the last command in history matching
pattern. Very useful.
You can configure a prompt on the
RHS. One use is to keep a fixed
width prompt on the left hand side
so all commands line up nicely while
displaying the pwd (or anything of
variable width) as the right hand
side prompt.
You can redirect input from multiple files (yet to try this): cat < file1 < file2 < file3

Related

How can I make my terminal text rainbow colored upon every boot up? (with lolcat)

I've been wondering how I could do some of these cool customization options for the terminal on a Mac and I came across lolcat.
However, I can't seem to find an answer as to how to add this into my bashrc (FYI: I'm using zsh now just in case that makes a difference as to which file to add my customizations in) I have tried what many others have suggested, which was just typing zsh | lolcat into the terminal to get rainbow output in the current session, but I was wondering how I can have this every time I start a terminal session.
Also, I'm not sure if this is a bug or if there's something wrong with my terminal settings, but when I use a command with lolcat, I get an output like this:
karenlee#Karens-MBP ~ % Documents
Downloads
Library
Movies
Music
Pictures
Postman
Public
38;5;48m
karenlee#Karens-MBP ~ % 38;5;48m
The colors look right, but as you can see, when I type the ls command on the command line, it disappears and the output also gets messy. It also seems like there's extra lines of 38;5;48m which are appearing. And it also seemed like many of the gems that are installed with lolcat have deprecated; is there another alternative to lolcat that plays nicely with macOS Catalina?
I made a shell extension for the world's fastest website generator that I make called Nift. It has an easter egg where you can turn on lolcat output for most things with lolcat.on (after starting the shell with eg. nift sh). You will even get rainbow output when pressing tab to get possible completion options, I doubt you get that with any other suggested solutions.
The shell extension is for f++ which is the in-built scripting language, which has these functions and these types available. But anything it doesn't recognise is run as a system call using the (probably primary/default) shell on your machine (hence calling it a shell extension in REPL shell mode).
Nift will look for a version of lolcat installed on your machine and otherwise use an in-built version of it which should be the world's fastest (it's near identical to my c++ implementation lolcat-cc which is the world's fastest). I highly recommend installing lolcat-cc (or another version of lolcat) on top of Nift though as otherwise you are frequently running the ~5mb Nift binary for basically all system calls, instead of a <1mb binary for lolcat.
f++ is somewhat of an interesting scripting language as well. Take this script for example which creates and deletes 100k empty text files. On my machine this runs in ~3.5 seconds whereas this Bash script doing essentially the same thing takes more like 3 minutes!! Some of the cool things you might already notice from that f++ script is you can expand variables inside strings, you can define variables with types, you can expand variables in to multiple parameters with function calls, you can have LOTS more than 10k input parameters for function calls (should be able to have millions!).
You can find some more information about the Nift REPLs (including shortcuts for different platforms) here.
If you need to define shell variables (not through f++ but the underlying shell) then you will need to do blocks of code using the sys/system function. You can also do blocks of code for Lua(JIT) and ExprTk similarly as they are both embedded in to Nift. You can use both Lua and ExprTk with accessing/modifying f++ variables as well..
So to get this shell (extension). Install Nift through a package manager or clone, make and install off GitHub. Enter nift sh in to your terminal to start the Nift f++ shell extension, then enter lolcat.on to turn on rainbow output.

Refreshing Bash prompt after invocation of a readline bound command

My shell is GNU Bash 4.3.11, and I currently have M-h bound to cd .. by calling the builtin
bind -x '"\eh": "cd .."'
This gives me a nifty way to navigate up the directory tree, as I can repeatedly hit M-h instead of the incredibly time-consuming cd ... It has the downside, however, either of not resetting my $PS1 or of not redrawing my prompt, so I lose the context of my current working directory until I enter a new command.
One alternative I'm aware of is to put a macro like
"\eh": "\C-a\C-kcd ..\C-m"
in my .inputrc directly. This, however, has the downside of not only losing the context of any existing command I'm typing in (which I think can probably be worked around) but also of printing out cd .. (which I don't think can be).
My desired behavior is to be able to be in a directory ~/one/two with prompt ~/one/two$; hit M-h; and then be in ~/one and have the prompt be ~/one$, ideally keeping any command I had initially. How can I achieve this?
Figured this out.
# maintain state
bind -x '"\200": TEMP_LINE=$READLINE_LINE; TEMP_POINT=$READLINE_POINT'
bind -x '"\201": READLINE_LINE=$TEMP_LINE; READLINE_POINT=$TEMP_POINT; unset TEMP_POINT; unset TEMP_LINE'
# "cd .." use case.
bind -x '"\206": "cd .."'
bind '"\eh":"\200\C-a\C-k\206\C-m\201"'
I'm quite late to that party - and came here looking for that answer also. First of all: As you were the only one providing information on this: thanks for not letting it come to this: https://xkcd.com/979/ ;) instead you pointed me to the on corner in that fractal that seems to hold a solution.
This approach, in my opinion backed up by hours of trying, is the only one where you can a) replace content on the line, and b) execute bash code. Let me offer up some more suggestions to a specific problem:
If you are trying to have it both ways: insert something on the command line, or executing code, things can get very tricky. for both, there exist bindings, and I let the reader figure out things with help bind. But in the case you e.g. have FZF produce some directory as output, and you'd either cd to it, or have it pasted into your command -- depending on the keystroke done in FZF -- things will get near impossible. you'll face either the not-updated-promt problem, or not be able to execute the cd command in the top shell (where it has effect).
Your solution would be a multiplexing -x binding, inspecting the output for "macros" (get extracted and eval'd) or the default pass-through (manipulating READLINE_LINE/POINT).
Because the solution has some enormity, and the audience may be limited (closed answer...), I'll leave it at a haphazard gist where I pasted my code which works now. To make up for the brevity and uncommented-ness, I welcome any questions in comment or elsewhere. Hope someone may be pointed in the right direction.
- The code related to this question starts in function bindInsertEvalWithMacrosVi
- It is designed for Vi keybindings but the same principles apply for normal readline mode
- It depends on some \C-x\C-... combinations to do redrawing in places that are not related to this post.
https://gist.github.com/simlei/032470cfcd23641987f97a96749128d7

ksh - Display Current Mode

Is there any way to have ksh display the current typing mode at the bottom of the window like vim; like "Insert", "Command", "Visual", etc? Unfortunately, I am having a lot of trouble remembering which mode I'm in and find the shell unintuitive (at least until I get used to all the commands). I consistantly hit the wrong key in command mode and have difficulty figuring out how to get back to proper typing (sometimes it lets me type but not delete part of the line and I don't know why).
I am required to use ksh for work and am heavily restricted in what I can download and install, but I need to figure this out. Hopefully there is something I can do with a profile or script along these lines to help ease the transistion. Also, this is HP-Unix, in case that affects anything.
This set -o alone command will show if emacs is defined to on
$ set -o|grep emacs
emacs on

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.

How many ways can I get Bash alias completion on a partial substring?

Question: I have a question that is apparently not answered by this already-asked Bash completion question on Stack Overflow. The question is, how to get Bash alias completion (for any alias) on a partial substring.
Example:
For example, assume I have the following aliases:
open.alicehome="cd /usr/home/alice"
open.bakerhome="cd /usr/home/baker"
open.charliehome="cd /usr/home/charlie"
gohomenow="shutdown -now"
I would like to lazily just type "baker{{TAB}}" to invoke the second alias.
I would like to lazily just type "home{{TAB}}" to get a list of all of the above aliases that I can then choose from with the keyboard (optimal) or choose by typing an unambiguous substring that distinguishes among the three options (less than optimal).
.. OR ..
I would like to lazily just type "home" and then repeatedly press {{TAB}} until the specific alias I want shows up, then press {{ENTER}} to execute it.
Feel free to be creative:
If you have a way to do this, even if it requires resorting to extreme guru hackery, please feel free to share it and feel free to explain your guru hackery to the level of a five-year-old who will have to try to implement your idea for himself.
Links to existing web-pages or RTFMs are welcome.
If you really want to change bash's tab behavior,
# ~/.inputrc
# The default binding for [Tab] is ``complete'', which is what we're used to.
# ``menu-complete'' gives you irssi-like behavior: cycle through completions.
"\t": menu-complete
This is documented in The GNU Readline Library # Letting Readline Type For You.
You can generate the matches for a specified substring with compgen -c -X'!*substring*'
To include this in bash autocompletion you can create a .bash_completion file in your home directory containing something like this:
_comp() {
local cur
cur=${COMP_WORDS[$COMP_CWORD]}
COMPREPLY=( $( compgen -c -X '!*'$cur'*' ) )
}
complete -F _comp $nospace eval
This match function will run when you press <TAB> on the arguments to the eval command. I haven't found a way to include a new matching function for the first command search in bash, I've only found documentation on how to add custom completions for a specific command, like eval above.
But I'm a bit skeptical to how useful this is... There is no easy way to select which match you want from the list.
Probably you can achieve what you want with custom bash_completion settings, but I'm not going to do the job for you, ok? :-)
If you don't know what I'm talking about, see here and here for details. By the way, I would find very annoying this
I would like to lazily just type
"home" and then repeatedly press
{{TAB}} until the specific alias I
want shows up, then press {{ENTER}} to
execute it.
which I think is the M$ style of "completion" (are you coming for DOS/windows environment?)

Resources