/* Add a character to a command line */ int addChar(wchar_t ** CommandLine, int key, unsigned int *cursorLocation) { unsigned int indexToMoveChar = 0; unsigned int sizeOfCmd = 0; sizeOfCmd = wcslen(*CommandLine); if (L' ' <= key || key == L'\n') { if (key == L'\n') { *cursorLocation = sizeOfCmd; } setStringCapacities("im"); /* * If the size of the string size is a multiple of 1024, * it means the string has reached its max. */ if (sizeOfCmd && !((sizeOfCmd + 1) % 1024)) { *CommandLine = realloc(*CommandLine, sizeof(wchar_t) * (sizeOfCmd + 1 + 1024)); } indexToMoveChar = sizeOfCmd; /* move each character to the next place */ while (indexToMoveChar > *cursorLocation) { (*CommandLine)[indexToMoveChar] = (*CommandLine)[indexToMoveChar - 1]; indexToMoveChar--; } /* Add the new character to the command line. */ (*CommandLine)[*cursorLocation] = (wchar_t) key; if (isatty(fileno(stdin))) { /* We are not in a pipe */ printf("%lc", (*CommandLine)[*cursorLocation]); } sizeOfCmd++; (*CommandLine)[sizeOfCmd] = L'\0'; (*cursorLocation)++; setStringCapacities("ei"); /* To prevent a lost cursor (if cursor reach the last column of the term) */ if ((*CommandLine)[*cursorLocation] && (*CommandLine)[*cursorLocation] != L'\n') { /* Write the next character in the string then move the cursor left */ printf("%lc\b", (*CommandLine)[*cursorLocation]); } else { /* If there is none, write a space then move the cursor left */ printf(" \b"); } } return 0; }
/* Move cursor to the right */ int gotoRight(wchar_t * CommandLine, unsigned int *cursorLocation) { int nbrCol; int sizeOfWChar = 0; int widthOfStringInTerm = 0; nbrCol = tgetnum("co"); /* if the cursor is not at the end of the command line */ if (*cursorLocation != wcslen(CommandLine)) { /* In case the wide char occupy more than one column */ if (CommandLine[*cursorLocation] == L'\n') { sizeOfWChar = 1; } else { sizeOfWChar = wcwidth(CommandLine[*cursorLocation]); } widthOfStringInTerm = sizeOfOneLineInTerm(CommandLine, *cursorLocation + 1); /* While we are not at the beginning of the character... */ while (sizeOfWChar) { if ((widthOfStringInTerm && !(widthOfStringInTerm % nbrCol) && sizeOfWChar <= 1) // if last column of the terminal is reached... || CommandLine[*cursorLocation] == L'\n') // ... or if the cursor will go to the next line. { /* move the cursor down. */ setStringCapacities("do"); } else { /* else, move it to the right */ setStringCapacities("nd"); } sizeOfWChar--; } (*cursorLocation)++; } /* else, if the cursor is next to the last column of the window, move it down a line */ else if (widthOfStringInTerm && !(widthOfStringInTerm % nbrCol)) { setStringCapacities("do"); } return *cursorLocation; }
/* Delete all characters from cursor to the end. */ int deleteFromCursToEndLine(wchar_t * CommandLine, unsigned int *cursorLocation) { /* set the end of the command line at the current cursor location */ CommandLine[*cursorLocation] = '\0'; /* * Clear screen from cursor to the end of the screen * Don't use "ce" because of multiline. */ setStringCapacities("cd"); return 0; }
/* Delete a character in the command line */ int rmChar(wchar_t * CommandLine, int key, unsigned int *cursorLocation) { unsigned int indexToMoveChar; unsigned int sizeOfCmd = 0; sizeOfCmd = wcslen(CommandLine); /* * Case Backspace is pressed -> cursor must not be at the beginning of the command line * Case Delete is pressed -> cursor must not be at the end of line */ if ((*cursorLocation && key == SCI_BACKSPACE) || ((sizeOfCmd != *cursorLocation) && key == SCI_DELETE)) { if (key == SCI_BACKSPACE) { gotoLeft(CommandLine, cursorLocation); } indexToMoveChar = *cursorLocation; /* Save cursor position where it must be placed */ setStringCapacities("sc"); while (indexToMoveChar < sizeOfCmd) { /* move each character to the previous place and print it */ CommandLine[indexToMoveChar] = CommandLine[indexToMoveChar + 1]; indexToMoveChar++; } CommandLine[indexToMoveChar] = L'\0'; /* Delete sreen from cursor to the end */ setStringCapacities("cd"); /* write the new string */ printf("%ls", &CommandLine[*cursorLocation]); /* Put cursor to the previously saved position */ setStringCapacities("rc"); } return 0; }
/* Move cursor to the left */ int gotoLeft(wchar_t * CommandLine, unsigned int *cursorLocation) { int nbrCol; int sizeOfWChar = 0; int widthOfStringInTerm = 0; int i = 0; if (CommandLine != NULL) { i = *cursorLocation; } if (i) { /* In case the wide char occupy more than one column */ if (CommandLine[*cursorLocation - 1] == L'\n') { /* Because L'\n' return -1 */ sizeOfWChar = 1; } else { sizeOfWChar = wcwidth(CommandLine[*cursorLocation - 1]); } /* Get the number of move too reach the end of the line (not the end of the command) */ if (CommandLine[*cursorLocation - 1] == L'\n') { /* Manage two consecutive L'\n' */ if ((*cursorLocation >= 2 && CommandLine[*cursorLocation - 2] == L'\n')) { setStringCapacities("up"); i--; if (CommandLine != NULL) { *cursorLocation = i; } return i; } /* If the cursor will move to a previous line separated by L'\n' */ if (*cursorLocation > 1) { nbrCol = (sizeOfOneLineInTerm(CommandLine, *cursorLocation - 2) + 1) % tgetnum("co"); } else { nbrCol = printPrompt(NOWRITE_PROMPT); } } else { /* If the cursor move up because of the terminal size */ nbrCol = tgetnum("co"); } widthOfStringInTerm = sizeOfOneLineInTerm(CommandLine, i); while (sizeOfWChar) /* While we are not at the beginning of the character... */ { if ((nbrCol && !(widthOfStringInTerm % nbrCol) && sizeOfWChar <= 1) // if last column of the terminal is reached... || CommandLine[*cursorLocation - 1] == L'\n') // ... or if the cursor will go to the previous line. { setStringCapacities("up"); while (nbrCol) { setStringCapacities("nd"); --nbrCol; } } else { putchar('\b'); } sizeOfWChar--; } i--; } if (CommandLine != NULL) { *cursorLocation = i; } return i; }