xaizek / hstr (License: Apachev2) (since 2018-12-07)
Bash and Zsh shell history suggest box - easily view, navigate, search and manage your command history.
Commit e969b56700a0eb93fbd0f2770b386abd66033e60

Moved ot curses based keyboard handling and fixed #36.
Author: Martin Dvorak
Author date (UTC): 2014-01-18 20:45
Committer name: Martin Dvorak
Committer date (UTC): 2014-01-18 20:45
Parent(s): 995ad9481fac2e0366b2d40df5b45464b2712177
Signing key:
Tree: 7075550185b760c17cbdab9bdbe36216708671a2
File Lines added Lines deleted
man/hh.1 9 3
src/hstr.c 141 159
src/hstr_history.c 5 0
src/hstr_utils.c 1 1
src/include/hstr_history.h 1 0
tests/src/test_curses_keyb.c 54 0
tests/src/test_keyb.c 12 5
tests/test_curses.sh 1 0
File man/hh.1 changed (mode: 100644) (index 7f77357..abe2862)
... ... hh allows removal of commands from history - for instance with a typo or with a
17 17 Show configuration to be added to .bashrc Show configuration to be added to .bashrc
18 18 .SH COMMANDS .SH COMMANDS
19 19 .TP .TP
20 \fBpattern\fR\eC\-u
20 \fBpattern\fR
21 21 Type to filter shell history. Type to filter shell history.
22 22 .TP .TP
23 \fBCtrl\-i\fR
23 \fBCtrl\-u\fR
24 24 Toggle case sensitive search. Toggle case sensitive search.
25 25 .TP .TP
26 26 \fBCtrl\-h\fR \fBCtrl\-h\fR
 
... ... Toggle history as provided by shell vs. ranked history ordered by the number of
29 29 \fBUP\fR arrow, \fBDOWN\fR arrow \fBUP\fR arrow, \fBDOWN\fR arrow
30 30 Navigate in the history list. Navigate in the history list.
31 31 .TP .TP
32 \fBTAB\fR
33 Choose currently selected item for completion and let user to edit it on the command prompt.
34 .TP
32 35 \fBENTER\fR \fBENTER\fR
33 Choose currently selected item for completion.
36 Choose currently selected item for completion and execute it.
34 37 .TP .TP
35 38 \fBCtrl\-r\fR \fBCtrl\-r\fR
36 39 Remove currently selected item from the shell history. Remove currently selected item from the shell history.
37 40 .TP .TP
38 41 \fBCtrl\-x\fR \fBCtrl\-x\fR
39 42 Write changes to shell history and exit. Write changes to shell history and exit.
43 .TP
44 \fBCtrl\-g\fR
45 Exit with empty prompt.
40 46 .SH INSTALLATION .SH INSTALLATION
41 47 Add the following lines to ~/.bashrc: Add the following lines to ~/.bashrc:
42 48 .nf .nf
File src/hstr.c changed (mode: 100644) (index b6fcb75..1e9a1e9)
34 34 #define Y_OFFSET_HISTORY 3 #define Y_OFFSET_HISTORY 3
35 35 #define Y_OFFSET_ITEMS 4 #define Y_OFFSET_ITEMS 4
36 36
37 #define K_ESC 91
38 #define K_ALT 27
39
40 37 #define K_CTRL_A 1 #define K_CTRL_A 1
41 38 #define K_CTRL_E 5 #define K_CTRL_E 5
39 #define K_CTRL_G 7
42 40 #define K_CTRL_H 8 #define K_CTRL_H 8
43 #define K_CTRL_I 9
44 41 #define K_CTRL_R 18 #define K_CTRL_R 18
42 #define K_CTRL_T 20
43 #define K_CTRL_U 21
45 44 #define K_CTRL_X 24 #define K_CTRL_X 24
45 #define K_CTRL_Z 26
46 46
47 #define K_ARROW_LEFT 68
48 #define K_ARROW_RIGHT 67
49 #define K_ARROW_UP 65
50 #define K_ARROW_DOWN 66
47 #define K_TAB 9
51 48
52 49 #define K_ENTER 10 #define K_ENTER 10
53 #define K_BACKSPACE 127
50 #define K_ALT 27
54 51
55 52 #define DEBUG_KEYS #define DEBUG_KEYS
56 53 #ifdef DEBUG_KEYS #ifdef DEBUG_KEYS
57 #define LOGKEYS(Y,KEY, BRANCH) mvprintw(Y, 0, "%s Key number: '%3d' / Char: '%c'", BRANCH, KEY, KEY)
54 #define LOGKEYS(Y,KEY) mvprintw(Y, 0, "Key: '%3d' / Char: '%c'", KEY, KEY); clrtoeol()
58 55 #else #else
59 #define LOGKEYS(Y,KEY, BRANCH)
56 #define LOGKEYS(Y,KEY)
60 57 #endif #endif
61 58
62 59 #ifdef DEBUG_CURPOS #ifdef DEBUG_CURPOS
 
66 63 #endif #endif
67 64
68 65 static const char *INSTALL_STRING= static const char *INSTALL_STRING=
69 "\n# Add this configuration to ~/.bashrc to let HH load and flush up to date history"
66 "\n# Add this configuration to ~/.bashrc to let HH load and flush up to date history"
70 67 "\nshopt -s histappend" "\nshopt -s histappend"
71 68 "\nexport PROMPT_COMMAND=\"history -a; history -n; ${PROMPT_COMMAND}\"" "\nexport PROMPT_COMMAND=\"history -a; history -n; ${PROMPT_COMMAND}\""
72 69 "\nbind '\"\\C-r\": \"\\C-ahh \\C-j\"'" "\nbind '\"\\C-r\": \"\\C-ahh \\C-j\"'"
 
... ... void print_cmd_deleted_label(char *cmd, int occurences)
116 113 // make this status row // make this status row
117 114 void print_history_label(HistoryItems *history) void print_history_label(HistoryItems *history)
118 115 { {
119 sprintf(screenLine, "- HISTORY - case:%s (C-i) - order:%s (C-h) - %d/%d ",
116 sprintf(screenLine, "- HISTORY - case:%s (C-u) - order:%s (C-h) - %d/%d ",
120 117 (caseSensitive?"sensitive":"insensitive"), (caseSensitive?"sensitive":"insensitive"),
121 118 (defaultOrder?"history":"ranking"), (defaultOrder?"history":"ranking"),
122 119 history->count, history->count,
 
... ... void signal_callback_handler_ctrl_c(int signum)
331 328 } }
332 329 } }
333 330
331 char *prepare_result(int selectionCursorPosition, bool executeResult)
332 {
333 cmdline[0]=0;
334 strcpy(cmdline,selection[selectionCursorPosition]);
335 if(executeResult) strcat(cmdline,"\n");
336 alloc_selection(0);
337 return cmdline;
338 }
339
334 340 char *selection_loop(HistoryItems *history) char *selection_loop(HistoryItems *history)
335 341 { {
336 342 signal(SIGINT, signal_callback_handler_ctrl_c); signal(SIGINT, signal_callback_handler_ctrl_c);
337 343
338 344 initscr(); initscr();
345 keypad(stdscr, TRUE);
346 noecho();
339 347 color_start(); color_start();
340 348 color_init_pair(1, COLOR_WHITE, COLOR_BLACK); color_init_pair(1, COLOR_WHITE, COLOR_BLACK);
341 349 color_attr_on(COLOR_PAIR(1)); color_attr_on(COLOR_PAIR(1));
 
... ... char *selection_loop(HistoryItems *history)
343 351 print_history_label(history); print_history_label(history);
344 352 print_help_label(); print_help_label();
345 353 print_selection(get_max_history_items(stdscr), NULL, history); print_selection(get_max_history_items(stdscr), NULL, history);
346 int basex = print_prompt(stdscr);
347 int x = basex;
348 int width=getmaxx(stdscr);
354
349 355 color_attr_off(COLOR_PAIR(1)); color_attr_off(COLOR_PAIR(1));
350 356
357 bool done=FALSE, skip=TRUE, executeResult=FALSE;
358 int basex=print_prompt(stdscr);
359 int x=basex, y=1, c, cursorX=0, cursorY=0, maxHistoryItems, deleteOccurences;
360 int width=getmaxx(stdscr);
351 361 int selectionCursorPosition=SELECTION_CURSOR_IN_PROMPT; int selectionCursorPosition=SELECTION_CURSOR_IN_PROMPT;
352 362 int previousSelectionCursorPosition=SELECTION_CURSOR_IN_PROMPT; int previousSelectionCursorPosition=SELECTION_CURSOR_IN_PROMPT;
353
354 int y = 1, c, maxHistoryItems, cursorX=0, cursorY=0, deleteOccurences;
355 bool done = FALSE, skip=TRUE;
363 char *result="", *msg, *delete;
356 364 char prefix[SELECTION_PREFIX_MAX_LNG]; char prefix[SELECTION_PREFIX_MAX_LNG];
357 365 prefix[0]=0; prefix[0]=0;
358 366 strcpy(prefix, cmdline); strcpy(prefix, cmdline);
359 char *result="", *msg, *delete;
360 367 while (!done) { while (!done) {
361 368 maxHistoryItems=get_max_history_items(stdscr); maxHistoryItems=get_max_history_items(stdscr);
362 369
363 noecho();
364 370 if(!skip) { if(!skip) {
365 371 c = wgetch(stdscr); c = wgetch(stdscr);
366 372 } else { } else {
367 373 skip=FALSE; skip=FALSE;
368 }
369 //echo();
370
371 if(c==K_ALT) {
372 374 continue; continue;
373 375 } }
374 376
375 if(CTRL_CHAR(c)) {
376 switch (c) {
377 case K_CTRL_R:
378 if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) {
379 delete=selection[selectionCursorPosition];
380 msg=malloc(strlen(delete)+1);
381 strcpy(msg,delete);
382 selection_remove(delete, history);
383 deleteOccurences=history_mgmt_remove(delete);
384 result = print_selection(maxHistoryItems, prefix, history);
385 print_cmd_deleted_label(msg, deleteOccurences);
386 move(y, basex+strlen(prefix));
387 }
388 print_history_label(history);
389 break;
390 case K_CTRL_I:
391 caseSensitive=!caseSensitive;
392 result = print_selection(maxHistoryItems, prefix, history);
393 print_history_label(history);
394 break;
395 case K_CTRL_H:
396 defaultOrder=!defaultOrder;
377 switch (c) {
378 case K_CTRL_R:
379 if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) {
380 delete=selection[selectionCursorPosition];
381 msg=malloc(strlen(delete)+1);
382 strcpy(msg,delete);
383 selection_remove(delete, history);
384 deleteOccurences=history_mgmt_remove(delete);
397 385 result = print_selection(maxHistoryItems, prefix, history); result = print_selection(maxHistoryItems, prefix, history);
398 print_history_label(history);
399 break;
400 case K_CTRL_X:
401 result = NULL;
402 done = TRUE;
403 break;
404 case KEY_ENTER:
405 case K_ENTER:
406 if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) {
407 result=selection[selectionCursorPosition];
408 alloc_selection(0);
386 print_cmd_deleted_label(msg, deleteOccurences);
387 move(y, basex+strlen(prefix));
388 }
389 print_history_label(history);
390 break;
391 case K_CTRL_U:
392 caseSensitive=!caseSensitive;
393 result = print_selection(maxHistoryItems, prefix, history);
394 print_history_label(history);
395 break;
396 case K_CTRL_H:
397 defaultOrder=!defaultOrder;
398 result = print_selection(maxHistoryItems, prefix, history);
399 print_history_label(history);
400 break;
401 case K_CTRL_X:
402 result = NULL;
403 done = TRUE;
404 break;
405 case KEY_RESIZE:
406 print_history_label(history);
407 move(y, basex+strlen(prefix));
408 break;
409 case KEY_BACKSPACE:
410 if(strlen(prefix)>0) {
411 prefix[strlen(prefix)-1]=0;
412 x--;
413 wattron(stdscr,A_BOLD);
414 mvprintw(y, basex, "%s", prefix);
415 wattroff(stdscr,A_BOLD);
416 clrtoeol();
417 }
418
419 if(strlen(prefix)>0) {
420 make_selection(prefix, history, maxHistoryItems);
421 } else {
422 make_selection(NULL, history, maxHistoryItems);
423 }
424 result = print_selection(maxHistoryItems, prefix, history);
425
426 move(y, basex+strlen(prefix));
427 break;
428 case KEY_UP:
429 previousSelectionCursorPosition=selectionCursorPosition;
430 if(selectionCursorPosition>0) {
431 selectionCursorPosition--;
432 } else {
433 selectionCursorPosition=selectionSize-1;
434 }
435 highlight_selection(selectionCursorPosition, previousSelectionCursorPosition, prefix);
436 move(y, basex+strlen(prefix));
437 break;
438 case KEY_DOWN:
439 if(selectionCursorPosition==SELECTION_CURSOR_IN_PROMPT) {
440 selectionCursorPosition=previousSelectionCursorPosition=0;
441 } else {
442 previousSelectionCursorPosition=selectionCursorPosition;
443 if((selectionCursorPosition+1)<selectionSize) {
444 selectionCursorPosition++;
445 } else {
446 selectionCursorPosition=0;
409 447 } }
410 done = TRUE;
411 break;
412 default:
413 LOGKEYS(Y_OFFSET_HELP, c, "CTRL");
414 // skip
415 break;
416 448 } }
417 } else {
418 switch (c) {
419 case KEY_RESIZE:
420 print_history_label(history);
421 move(y, basex+strlen(prefix));
422 break;
423 case KEY_BACKSPACE:
424 case K_BACKSPACE:
425 if(strlen(prefix)>0) {
426 prefix[strlen(prefix)-1]=0;
427 x--;
449 highlight_selection(selectionCursorPosition, previousSelectionCursorPosition, prefix);
450 move(y, basex+strlen(prefix));
451 break;
452 case K_ENTER:
453 case KEY_ENTER:
454 executeResult=TRUE;
455 case K_TAB:
456 case KEY_LEFT:
457 case KEY_RIGHT:
458 if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) {
459 result=prepare_result(selectionCursorPosition, executeResult);
460 }
461 done = TRUE;
462 break;
463 case K_CTRL_G:
464 result="";
465 history_clear_dirty();
466 done=TRUE;
467 break;
468 default:
469 LOGKEYS(Y_OFFSET_HELP, c);
470 LOGCURSOR(Y_OFFSET_HELP);
471
472 if(c>K_CTRL_Z) {
473 selectionCursorPosition=SELECTION_CURSOR_IN_PROMPT;
474
475 if(strlen(prefix)<(width-basex-1)) {
476 strcat(prefix, (char*)(&c));
428 477 wattron(stdscr,A_BOLD); wattron(stdscr,A_BOLD);
429 478 mvprintw(y, basex, "%s", prefix); mvprintw(y, basex, "%s", prefix);
479 cursorX=getcurx(stdscr);
480 cursorY=getcury(stdscr);
430 481 wattroff(stdscr,A_BOLD); wattroff(stdscr,A_BOLD);
431 482 clrtoeol(); clrtoeol();
432 483 } }
433 484
434 if(strlen(prefix)>0) {
435 make_selection(prefix, history, maxHistoryItems);
436 } else {
437 make_selection(NULL, history, maxHistoryItems);
438 }
439 485 result = print_selection(maxHistoryItems, prefix, history); result = print_selection(maxHistoryItems, prefix, history);
440
441 move(y, basex+strlen(prefix));
442 break;
443 case KEY_UP:
444 case K_ARROW_UP:
445 previousSelectionCursorPosition=selectionCursorPosition;
446 if(selectionCursorPosition>0) {
447 selectionCursorPosition--;
448 } else {
449 selectionCursorPosition=selectionSize-1;
450 }
451 highlight_selection(selectionCursorPosition, previousSelectionCursorPosition, prefix);
452 move(y, basex+strlen(prefix));
453 break;
454 case KEY_DOWN:
455 case K_ARROW_DOWN:
456 if(selectionCursorPosition==SELECTION_CURSOR_IN_PROMPT) {
457 selectionCursorPosition=previousSelectionCursorPosition=0;
458 } else {
459 previousSelectionCursorPosition=selectionCursorPosition;
460 if((selectionCursorPosition+1)<selectionSize) {
461 selectionCursorPosition++;
462 } else {
463 selectionCursorPosition=0;
464 }
465 }
466 highlight_selection(selectionCursorPosition, previousSelectionCursorPosition, prefix);
467 move(y, basex+strlen(prefix));
468 break;
469 case K_ESC:
470 case K_ARROW_LEFT:
471 case K_ARROW_RIGHT:
472 break;
473 default:
474 LOGKEYS(Y_OFFSET_HELP, c, "ASCII");
475 LOGCURSOR(Y_OFFSET_HELP);
476
477 if(c!=27) { // TODO remove
478 selectionCursorPosition=SELECTION_CURSOR_IN_PROMPT;
479
480 if(strlen(prefix)<(width-basex-1)) {
481 strcat(prefix, (char*)(&c));
482 wattron(stdscr,A_BOLD);
483 mvprintw(y, basex, "%s", prefix);
484 cursorX=getcurx(stdscr);
485 cursorY=getcury(stdscr);
486 wattroff(stdscr,A_BOLD);
487 clrtoeol();
488 }
489
490 result = print_selection(maxHistoryItems, prefix, history);
491 move(cursorY, cursorX);
492 refresh();
493 }
494 break;
486 move(cursorY, cursorX);
487 refresh();
495 488 } }
489 break;
496 490 } }
497 491 } }
498 492 endwin(); endwin();
 
... ... char *selection_loop(HistoryItems *history)
500 494 return result; return result;
501 495 } }
502 496
503 void install_write()
504 {
505 char *home = getenv(ENV_VAR_HOME);
506 sprintf(screenLine, "%s/%s", home, FILE_BASHRC);
507 FILE *file = fopen(screenLine,"a");
508 fseek(file,0, SEEK_END);
509 fprintf(file,"%s",INSTALL_STRING);
510 fprintf(file,"%s","\n\n");
511 fclose(file);
512 }
513
514 497 void install_show() void install_show()
515 498 { {
516 499 printf("# %s\n%s", BUILD_STRING, INSTALL_STRING); printf("# %s\n%s", BUILD_STRING, INSTALL_STRING);
517 500 } }
518 501
519 void hstr()
520 {
521 HistoryItems *history=get_prioritized_history();
522 if(history) {
523 history_mgmt_open();
524 char *command = selection_loop(history);
525 hstr_on_exit(command);
526 } else {
527 printf("Empty shell history - nothing to suggest...\n");
528 }
529 }
530
531 502 void assemble_cmdline(int argc, char *argv[]) { void assemble_cmdline(int argc, char *argv[]) {
532 503 int i; int i;
533 504 cmdline[0]=0; cmdline[0]=0;
534 505 for(i=1; i<argc; i++) { for(i=1; i<argc; i++) {
535 506 if((strlen(cmdline)+strlen(argv[i])*2)>CMDLINE_LNG) break; if((strlen(cmdline)+strlen(argv[i])*2)>CMDLINE_LNG) break;
536 printf("%d %s\n", i, argv[i]);
537 507 if(strstr(argv[i], " ")) { if(strstr(argv[i], " ")) {
538 508 strcat(cmdline, "\""); strcat(cmdline, "\"");
539 509 } }
 
... ... void assemble_cmdline(int argc, char *argv[]) {
547 517 } }
548 518 } }
549 519
520 void hstr()
521 {
522 HistoryItems *history=get_prioritized_history();
523 if(history) {
524 history_mgmt_open();
525 char *command = selection_loop(history);
526 hstr_on_exit(command);
527 } else {
528 printf("Empty shell history - nothing to suggest...\n");
529 }
530 }
531
550 532 int main(int argc, char *argv[]) int main(int argc, char *argv[])
551 533 { {
552 534 if(argc>0) { if(argc>0) {
File src/hstr_history.c changed (mode: 100644) (index 7e3edb8..1ba72e7)
... ... void history_mgmt_open()
154 154 dirty=false; dirty=false;
155 155 } }
156 156
157 void history_clear_dirty()
158 {
159 dirty=false;
160 }
161
157 162 int history_mgmt_remove(char *cmd) int history_mgmt_remove(char *cmd)
158 163 { {
159 164 int offset=history_search_pos(cmd, 0, 0), occurences=0; int offset=history_search_pos(cmd, 0, 0), occurences=0;
File src/hstr_utils.c changed (mode: 100644) (index d855e8e..e59f078)
... ... void tiocsti()
24 24
25 25 void fill_terminal_input(char *cmd, bool padding) void fill_terminal_input(char *cmd, bool padding)
26 26 { {
27 if(cmd) {
27 if(cmd && strlen(cmd)>0) {
28 28 size_t size = strlen(cmd); size_t size = strlen(cmd);
29 29 unsigned i; unsigned i;
30 30 char *c; char *c;
File src/include/hstr_history.h changed (mode: 100644) (index 0f13947..229473b)
... ... HistoryItems *prioritize_history(HistoryItems *historyFileItems);
43 43 void free_prioritized_history(); void free_prioritized_history();
44 44
45 45 void history_mgmt_open(); void history_mgmt_open();
46 void history_clear_dirty();
46 47 int history_mgmt_remove(char *cmd); int history_mgmt_remove(char *cmd);
47 48 void history_mgmt_close(); void history_mgmt_close();
48 49
File tests/src/test_curses_keyb.c added (mode: 100644) (index 0000000..873ba19)
1 /*
2 ============================================================================
3 Name : test_curses_keyb.c
4 Author : martin.dvorak@midforger.com
5 Copyright : Apache 2.0
6 Description : A test
7 ============================================================================
8 */
9
10 #include <curses.h>
11 #include <stdlib.h>
12
13 int main(int argc, char *argv[])
14 {
15 initscr();
16 noecho();
17 keypad(stdscr, TRUE);
18
19 int c;
20 while(TRUE) {
21 c = getch();
22
23 mvprintw(1, 0, "Key number: '%3d' / Char: '%c'", c, c);
24
25 switch(c) {
26 // ctrl-r, ctrl-h, ctrl-i
27 case KEY_BACKSPACE:
28 case KEY_LEFT:
29 case KEY_RIGHT:
30 case KEY_UP:
31 case KEY_DOWN:
32 mvprintw(5, 0, "CATCHED! %3d",c);
33 break;
34
35 case KEY_STAB:
36 case KEY_BTAB:
37 case KEY_CTAB:
38 mvprintw(5, 0, "TAB! %3d",c);
39 break;
40
41 case KEY_RESIZE:
42 mvprintw(5, 0, "RESIZE! %3d",c);
43 break;
44
45 case KEY_ENTER:
46 endwin();
47 exit(0);
48 default:
49 break;
50 }
51 }
52
53 endwin();
54 }
File tests/src/test_keyb.c changed (mode: 100644) (index 6594896..1d5dc96)
11 11 #include <readline/readline.h> #include <readline/readline.h>
12 12 #include <readline/chardefs.h> #include <readline/chardefs.h>
13 13
14 int main(int argc, char *argv[])
14 void echo_printable_characters()
15 15 { {
16 16 int c; int c;
17 for(c=0; c<255; c++) {
18 printf("Key number: '%3d' / Char: '%c' Meta: \n", c, c, c&meta_character_bit);
19 }
20 }
17 21
18 // for(c=0; c<255; c++) {
19 // printf("Key number: '%3d' / Char: '%c' Meta: \n", c, c, c&meta_character_bit);
20 // }
21
22 void echo_keyb_characters() {
23 int c;
22 24 while(1) { while(1) {
23 25 c = getc(stdin); c = getc(stdin);
24 26 printf("Key number: '%3d' / Char: '%c' Meta: %d Ctrl: %d Ctrl mask: %d\n", c, c, META_CHAR(c), CTRL_CHAR(c), c&control_character_mask); printf("Key number: '%3d' / Char: '%c' Meta: %d Ctrl: %d Ctrl mask: %d\n", c, c, META_CHAR(c), CTRL_CHAR(c), c&control_character_mask);
25 27 } }
26 28 } }
29
30 int main(int argc, char *argv[])
31 {
32
33 }
File tests/test_curses.sh added (mode: 100755) (index 0000000..c783782)
1 gcc ./src/test_curses_keyb.c -lcurses -o _curses
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/hstr

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/hstr

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master