Is there a way to search LLDB commands similar to the readline library's history-search-backward in bash and GDB?
I want to be able to type some characters, and use up arrow to cycle through all commands that start with those characters.
lldb uses editline rather than readline. Editline has a backward search in command history feature (em-inc-search-prev) that's bound to ^R by default (though you can change this in your .editrc) It works like emac's ^S, you type characters to refine the search, and ^R to go to the previous match. To reverse direction and start searching forward you would use em-inc-search-next, but we haven't bound that to anything.
I was working on my own bash prompt when hit strange behaviour (both iTerm and Terminal.app on macos). I managed to boil it down to the minimum working example:
~/.bash_profile:
WHITE="\[\033[1;37m\]"
COLOR_NONE="\[\033[0m\]"
# This always wraps correctly
PS1="\u:\w"
# This (added coloring) wraps incorrectly when using small window.
# PS1="${WHITE}\u:\w${COLOR_NONE}"
Now create a long directory name say
mkdir ~/very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name
and cd to it. Problem is: with the first version of the PS1 it wraps perfectly, while adding just one color breaks wrapping for small windows. Can anybody clarify of give a workaround? Adding \n to the end is an option, but looks ugly for short prompts.
Thanks!
Sources I have already seen:
BashFAQ/053 about colors
SO question about \[ and \]
Issue with \x01 and \x02
UPD:
bash version version 3.2.57(1)-release (x86_64-apple-darwin17)
Bash has always had trouble handling long prompts with invisible characters, so the usual practice is to avoid them. For example, you could automatically trim the length of the prompt by omitting the beginning of the path if it is too long, or you could automatically output a trailing newline if the path is very long. (In such cases, you might want to use $COLUMNS, which will normally tell you the width of the window.)
In patch 19 to bash v4.4 (which I realise is not really relevant to your environment since you seem to still be using the antique version of bash provided by a default OS X install), a long-standing bug was corrected, which had the effect of triggering a segfault in certain very rare cases of multiline prompts with both invisible and multibyte characters. The behaviour definitely changed between v4.4.18 and v4.4.19, but even with that patch very long prompts cause problems when the prompt extends to a third line.
There is a comment in lib/readline/display.c which indicates that the readline library assumes that prompts will not exceed two lines. I suggest that you use that as a limit.
In vim, to find a character you can use 'f' to find the next matching character in the line that your cursor is on, and 'F' to find the previous matching character in the line that your cursor is on.
Is there a way to move around like that on the bash command line?
I know that you can set bash to be in vim mode, by saying set -o vim, and this works great for my local machine, but I administer a lot of machines where I can't change that setting.
Ignoring for a moment the security issues associated with everybody in your office sharing the same user, you could add a key binding to the readline command character-search:
# ~/.inputrc
C-]: character-search
To use the search, type Ctrl-] followed by the character you want to search for. You can bind the command to any key sequence, not just Ctrl-], but for obvious reasons you probably don't want to emulate vi mode by binding it to the letter f.
This would be less invasive than turning on vi mode so most users would probably not even notice the change. However, somebody could easily stumble upon your key sequence by accident and become very confused. You would also have to use three keystrokes instead of the two you're accustomed to with vi.
Open up irb and
type gets. It should work fine.
Then try system("choice /c YN") It should work as expected.
Now try gets again, it behaves oddly.
Can someone tell me why this is?
EDIT: For some clarification on the "odd" behavior, it allows me to type for gets, but doesn't show me the characters and I have to press the enter key twice.
Terminal input-output handling is dark and mysterious art. Anyone trying to make colorized output of bash work in windows PowerShell via ssh knows that. (And various shortcutting habits like Ctrl+Backspace only make things worse.)
One of the possible reasons for your problem is special characters handling. Every terminal out there can type characters in number of different modes, and it parses its own output in search for certain character sequences in order to toggle states.
F.e. here one can find ANSI escape code sequences, one of possible supported standards among different kind of terminals.
See there Esc[5;45m? That will make all the following output to blink on magenta background. And there is significantly more stuff like that out there.
So, the answer to your question taken literally is — your choice command messes something with output modes using special escape sequences, and ruby's gets breaks in that quirk special mode of terminal operation.
But more useful will be the link to HighLine gem documentation. Why one might want to implement platform-specific and obtrusive behavior when it is possible to implement the same with about 12 LOC? All the respect for the Gist goes to botimer, I've only stumbled into his code using search.
target: dependencies
command1
command2
On my system (Mac OS X), make seems to require that that Makefiles have a tab character preceding the the content of each command line, or it throws a syntax error.
This is an annoyance when creating or editing Makefiles because I have my editor set up to be all-spaces-all-the-time.
Can you make valid Makefiles without tab characters?
This is a syntax oddity/requirement of make, it has nothing to do with Mac OS X. Unfortunately, there's nothing you can do about it if you are going to use make.
Edit: GNU Make now supports a custom recipe prefix. See this answer.
You are not the first one to dislike this aspect of make. To quote Unix Haters' Handbook:
The problem with Dennis’s Makefile is that when he added the comment line, he inadvertently inserted a space before the tab character at the beginning of line 2. The tab character is a very important part of the syntax of Makefiles. All command lines (the lines beginning with cc in our example) must start with tabs. After he made his change, line 2 didn’t, hence the error.
“So what?” you ask, “What’s wrong with that?”
There is nothing wrong with it, by itself. It’s just that when you consider how other programming tools work in Unix, using tabs as part of the syntax is like one of those pungee stick traps in The Green Berets: the poor kid from Kansas is walking point in front of John Wayne and doesn’t see the trip wire. After all, there are no trip wires to watch out for in Kansas corn fields. WHAM!
In the time since this question was originally asked, a version of GNU Make has been released that allows you to use something other than Tab as the prefix character. From the mailing list announcement:
New special variable: .RECIPEPREFIX allows you to reset the recipe
introduction character from the default (TAB) to something else. The
first character of this variable value is the new recipe introduction
character. If the variable is set to the empty string, TAB is used again.
It can be set and reset at will; recipes will use the value active when
they were first parsed. To detect this feature check the value of $(.RECIPEPREFIX).
This feature was added in GNU Make 3.82, released in July 2010 (six months after this question's original ask date). Since it has in turn been three years and change since that, it's likely that other Make flavors have followed GNU Make.
There is a convoluted way of have a valid makefile without tabs.
If you change your makefile to read:
target: dependencies; command1; command2
If will work. If you want it on more than one line, then you can do:
target: dependencies; \
command1; \
command2
Messy, but it works.
If you have a vimrc in your profile you can add this line to prevent vim from changing to spaces:
autocmd FileType make setlocal noexpandtab
I too was struggling with this, and this fixed it for me. Spread the good word!
This does it for me if you would like to use spaces
.RECIPEPREFIX +=
Example
If you are using EditorConfig, you can add the following lines to your .editorconfig file to force your IDE to use tab for indentation instead of spaces in Makefile:
[Makefile]
indent_style = tab
In vim's insert mode, one can use Ctrl-v <TAB> to insert a literal tab, even if you have set the tab key to insert spaces. This doesn't answer your question, of course, but might be an alternative to the methods available to avoid needing literal tabs.
Until GNU Make 4.2
Steven Penny's answer works.
.RECIPEPREFIX +=
The reason why this works is described in my comment.
Since GNU Make 4.3 (released on 19 Jan 2020)
Behavior of += operator has been changed in a backward-incompatible way. If the left operand has an empty value, a space is no longer added.
You can instead use
.RECIPEPREFIX := $(.RECIPEPREFIX)<space>
, where <space> is a single space. Although $(.RECIPEPREFIX) is expanded as an empty value, this is needed not to let GNU Make ignore <space>. Note this code works even on GNU Make older than version 4.3.
in ubuntu: vi Makefiles
replace space by tab (or anything else you want):
:%s/<space chars>/^I/g
For ex replace 8 spaces by tab:
:%s/ /^I/g
Be attention: ^I insert with tab key, not ^ and I characters :D
Not portably. Certain flavours of make absolutely require tab characters. Yet another reason for preferring tabs over spaces :-)