Vim: Indent current (blank) line and insert - vim

Say I have the current text in the buffer, where _ marks the cursor
int main(int argc, char **argv) {
printf("Hello, world!\n");
_
}
I have indentexpr on (though a solution with cindent or autoindent will probably work, too).
How do I begin inserting so my cursor is placed at the appropriate column to follow the indention rules, i.e.:
int main(int argc, char **argv) {
printf("Hello, world!\n");
_
}
Currently I find myself using ddO often (or ddo at the end of the buffer), but it seems there should be a better way. Using == or even >> or v> do not seem to work because the line is blank.

Try going back into normal mode and typing S

If I'm on a blank line, but at the wrong insertion point, I tend to use CTRL-f (while in insert mode) to indent to the correct place.
This is useful when I've hit ESC to get out of insert mode, and I've then lost the proper indentation. Hitting i followed by CTRL-f does the trick.

Related

proper way of catching control+key in ncurses

What is the proper way of catching a control+key in ncurses?
current im doing it defining control like this:
#define ctl(x) ((x) & 0x1f)
it works ok, but the problem is that i cannot catch C-j and ENTER at the same time, and this is because:
j = 106 = 1101010
0x1f = 31 = 0011111
1101010 & 0011111 = 0001010 = 10 = ENTER key..
So.. how shall I catch it?
Thanks!
--
Edit:
If i try the code below,
I am not able to catch the enter key correctly, not even in the numeric keyboard. Enter gets catched as ctrl-j.
#include <stdio.h>
#include <ncurses.h>
#define ctrl(x) ((x) & 0x1f)
int main(void) {
initscr();
int c = getch();
nonl();
switch (c) {
case KEY_ENTER:
printw("key: %c", c);
break;
case ctrl('j'):
printw("key: ctrl j");
break;
}
getch();
endwin();
return;
}
New code:
#include <stdio.h>
#include <ncurses.h>
#define ctrl(x) ((x) & 0x1f)
int main(void) {
initscr();
int l = -1;
int c = getch();
cbreak();
noecho();
nonl();
keypad(stdscr, TRUE);
switch (c) {
case KEY_ENTER:
printw("key: %c", c);
break;
case ctrl('j'):
printw("key: ctrl j");
break;
}
printw("\nnow press a key to end");
getch();
endwin();
return;
}
Try nonl:
The nl and nonl routines control whether the underlying display device
translates the return key into newline on input, and whether it translates newline into return and line-feed on output (in either case, the
call addch('\n') does the equivalent of return and line feed on the
virtual screen). Initially, these translations do occur. If you disable them using nonl, curses will be able to make better use of the
line-feed capability, resulting in faster cursor motion. Also, curses
will then be able to detect the return key.
Further reading: the Notes section of the getch manual page:
Generally, KEY_ENTER denotes the character(s) sent by the Enter key on
the numeric keypad:
the terminal description lists the most useful keys,
the Enter key on the regular keyboard is already handled by the
standard ASCII characters for carriage-return and line-feed,
depending on whether nl or nonl was called, pressing "Enter" on the
regular keyboard may return either a carriage-return or line-feed,
and finally
"Enter or send" is the standard description for this key.
That addresses the question about newline/carriage-return translation. A followup comment is a reminder to point out that the manual page gives basic advice in the Initialization section:
To get character-at-a-time input without echoing (most interactive,
screen oriented programs want this), the following sequence should be
used:
initscr(); cbreak(); noecho();
and that OP's sample program did not use cbreak (or raw). The manual page for cbreak says
Normally, the tty driver buffers typed characters until a newline or
carriage return is typed. The cbreak routine disables line buffering
and erase/kill character-processing (interrupt and flow control characters are unaffected), making characters typed by the user immediately
available to the program. The nocbreak routine returns the terminal to
normal (cooked) mode.
Initially the terminal may or may not be in cbreak mode, as the mode is
inherited; therefore, a program should call cbreak or nocbreak explicitly. Most interactive programs using curses set the cbreak mode.
Note that cbreak overrides raw. (See curs_getch(3x) for a discussion
of how these routines interact with echo and noecho.)
Also, in curs_getch you may read
If keypad is TRUE, and a function key is pressed, the token for that
function key is returned instead of the raw characters:
The predefined function keys are listed in <curses.h> as macros
with values outside the range of 8-bit characters. Their names begin with KEY_.
That is, curses will only return KEY_ENTER if the program calls keypad:
keypad(stdscr, TRUE);
For the sake of discussion, here is an example fixing some of the problems with your sample program as of May 17:
#include <stdio.h>
#include <ncurses.h>
#define ctrl(x) ((x) & 0x1f)
int
main(void)
{
int c;
initscr();
keypad(stdscr, TRUE);
cbreak();
noecho();
nonl();
c = getch();
switch (c) {
case KEY_ENTER:
printw("\nkey_enter: %d", c);
break;
case ctrl('j'):
printw("\nkey: ctrl j");
break;
default:
printw("\nkeyname: %d = %s\n", c, keyname(c));
break;
}
printw("\nnow press a key to end");
getch();
endwin();
return 0;
}
That is, you have to call keypad before getch, and the value returned for KEY_ENTER is not a character (it cannot be printed with %c).
Running on the Linux console with the usual terminal description, you will see only carriage return for the numeric keypad Enter, because that description does not use application mode. Linux console does support application mode, and a corresponding description could be written. As a quick check (there are differences...) you could set TERM=vt100 to see the KEY_ENTER.

How to set carriage return location or equivalent?

I am looking for a way to set where the carriage return, returns to or an equivalent way to do so.
For example I have a line like this:
^ denotes cursor location
myshell>cat file.txt
^
After carriage return it should look like this.
myshell>cat file.txt
^
You're probably after what's collectively called ANSI escape sequences. Its hard to search for if you really have no idea what you're after.
This tiny example saves/restores cursor position:
#include <stdio.h>
int main(int argc, char**argv)
{
char cmd_buf[100];
cmd_buf[0]=0;
while(strncmp(cmd_buf, "quit", 4))
{
printf("mypromt>\033[s <-Cursor should go there\033[u");
fflush(stdout);
fgets(cmd_buf, sizeof(cmd_buf), stdin);
printf("\nYou entered: %s\n", cmd_buf);
}
}
Note that in terminator, gnome-terminal and xterm on Ubuntu, this "magically" supports CTRL+U as-is, but not CTRL+A or CTRL+E.
There are many, many more sequences available. The wikipedia page is probably the simplest reference to get you started.
Update: Also, unless you're doing this as a learning exercise (which I get the impression Benjamin is), to build an interactive shell, you should probably use one of the two well established libraries for shell-style line editing, namely:
readline (GPLv3, but far more popular)
editline (BSD licensed, closest "second place")
They are the libraries that provide the emacs-style (typical default) and vi-style keybindings and history features we all know and love from bash, python, lua, perl, node, etc, etc.
For positioning on the screen, termios is of limited use (the ioctl's dealing with screensize are not in POSIX), and unless you want to assume a lot about the terminal characteristics, control characters and escape sequences have their limitations.
You can do what's asked in curses using the filter function to tell the library you want to use just the current line of the display. As written, the question is puzzling since it does not mention any output other than the current line. But for example (this is exactly what was asked):
#include <curses.h>
int
main(void)
{
int ch, y, x;
filter();
initscr();
cbreak();
addstr("myshell>");
getyx(stdscr, y, x);
while ((ch = getch()) != ERR) {
if (ch == '\n')
move(y, x);
}
endwin();
return 0;
}
However, a usable program would do more than that. There's an example of the filter() function in ncurses-examples, which you may find useful for reading. A screenshot:

How can I line up/indent function arguments up to (

I want to do this in VIM:
// before
int DoStuffToSometing(int stuff,
char action,
int something);
// after
int DoStuffToSometing(int stuff,
char action,
int someting);
=% while being on the matching parenthesis, doesn't work.
How to line up things as shown above?
Use :set cinoptions+=(0 then do the select the content and press =.

Surrounding multiple selected lines with #ifdef

I'm trying to write a macro that will allow me to surround currently highlighted lines of text with an #ifdef. Ideally with the cursor placed after the #ifdef to be ready to enter the macro name. I'm able to record to create a macro, but I'm only able to do it for one line of code.
Before:
bool first_selected_line = false;
int second_selected_line = 0;
After:
#ifdef // if possible, cursor placed here in insert mode
bool first_selected_line = false;
int second_selected_line = 0;
#else
bool first_selected_line = false;
int second_selected_line = 0;
#endif
Any ideas?
You could do something along the lines of:
qjc#ifdef<esc>magpO#else<esc>gpO#endif<esc>`aq
Basically:
Start recording qj
Delete what you selected and go into insertmode c
Type your construct, pasting your code back as necessary
You put a mark (ma) just after typing #ifdef and jump back to it at the end
Repeat the macro with #j
Hope this example helps!
I would probably use snipmate or some other plugin to accomplish this task. There are couple ways to go about it manually though. Here's my solution for a macro:
Visually select the text then...
qqc#ifdef
<C-r><C-o>"
#else
<C-r><C-o>"
#endif<esc>'[A<C-o>q
You also don't have to visually select the text at all if you don't want to. Use the same macro but start with qqcj instead.

Entering text in snippet fields uses wrong character when using langmap

I am using a custom keymap using langmap option in vimrc.
I am trying to use snipmate but I am running into trouble. When I type a word and hit tab it allows me to edit the parameter. The problem is that the first character is the remapped one, while I want it to be the actual key.
For instance, I'll type this:
for
and hit tab to expand the snippet:
for (i = 0; i < COUNT; ++i)
The i is highlighted which means I can edit it. I type "aaa":
for (baa = 0; i < COUNT; ++i)
It comes out baa even though I typed aaa. This is because I remapped a and b.
How can I fix this?
Here is my keymapping:
set langmap=nj,N},ek,E{,il,IL,{^,}$,lb,LB,uw,UW,ye,YE,jg,JG,\\;z,f\\.,F\\,,zu,ZU,.?,\\,/,/v,? V,ta,TA,si,SI,ro,RO,ac,AC,wr,WR,xx,XX,dd,DD,bs,BS,gf,GF,pt,PT,kn,KN,cy,CY,vp,VP,o\\;
It won't make much sense to others, and I haven't finalized how I want it to look.
From your :set langmap I understand that you mapped a to c so, by typing aaa, did you expect to obtain ccc?
From what I understand (:help langmap), your custom substitutions are not available in INSERT mode for actually inserting stuff and I don't see a mention of the SELECT mode you are in when overwriting SnipMate's placeholders.
If I do this
:set langmap+=ac,bs
and I type aaa in SELECT mode, I obtain caa.
That's because langmap applies to the first a (:help Select-mode) and, therefore inserts c. But, after this first character I am in INSERT mode for all subsequent characters. Since langmap doesn't apply in INSERT mode, aa is inserted as is.
What is not clear to me is why you obtain baa instead of caa. Your langmap seems to be pretty clear about your intention: you want a to insert c and b to insert s. Typing a shouldn't insert b.
I smell a risk of mistyping in your .vimrc. Try this: reset your set langmap and start adding your mappings one by one.
May I ask you what is the purpose of such a massive remapping?
C program which outputs mappings similar behavior to langmap but not for select:
/* input:
lhs rhs optional-descripton
lhs rhs ...
*/
#include <stdlib.h>
#include <stdio.h>
int main() {
FILE *fi = fopen("in.txt", "r");
FILE *fo = fopen("out.txt", "w");
char lc[8], rc[8];
while (fscanf(fi, "\n%s %s", lc, rc) != EOF) {
fprintf(fo, "nnoremap %s %s\n", lc, rc);
fprintf(fo, "xnoremap %s %s\n", lc, rc);
fprintf(fo, "onoremap %s %s\n", lc, rc);
while (fgetc(fi) != '\n');
}
fclose(fo);
fclose(fi);
}
It doesn't work identically to langmap and so it might break other bindings.
This has now been fixed in vim 7.4.1150. See
https://github.com/vim/vim/issues/572
for details.

Resources