1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-11-03 19:37:16 -05:00

Added input editing and buffer

Left and right arrows for inline editing.
Up arrow to go through history
This commit is contained in:
James Booth 2012-02-26 23:33:14 +00:00
parent 0a45044f1b
commit cc4c7f3e19
10 changed files with 151 additions and 14 deletions

View File

@ -3,7 +3,7 @@ WARNS = -Werror -Wall -Wextra -Wno-unused-parameter -Wno-unused-but-set-variable
LIBS = -lxml2 -lexpat -lssl -lresolv -lncurses -L ~/lib -lstrophe
CFLAGS = -I ~/include -O3 $(WARNS) $(LIBS)
OBJS = log.o windows.o title_bar.o status_bar.o input_win.o jabber.o \
profanity.o util.o command.o main.o
profanity.o util.o command.o input_buffer.o main.o
profanity: $(OBJS)
$(CC) -o profanity $(OBJS) $(LIBS)
@ -14,9 +14,10 @@ title_bar.o: windows.h
status_bar.o: windows.h util.h
input_win.o: windows.h
jabber.o: jabber.h log.h windows.h
profanity.o: log.h windows.h jabber.h command.h
profanity.o: log.h windows.h jabber.h command.h input_buffer.h
util.o: util.h
command.o: command.h util.h
command.o: command.h util.h input_buffer.h
input_buffer.o: input_buffer.h
main.o: log.h windows.h profanity.h
.PHONY: clean

View File

@ -24,6 +24,7 @@
#include <stdlib.h>
#include <ncurses.h>
#include "command.h"
#include "input_buffer.h"
#include "jabber.h"
#include "windows.h"
#include "util.h"
@ -41,6 +42,9 @@ int process_input(char *inp)
{
int result = FALSE;
if (strlen(inp) > 0)
inpbuf_append(inp);
if (strlen(inp) == 0) {
result = TRUE;
} else if (inp[0] == '/') {

View File

@ -23,6 +23,7 @@
#ifndef COMMAND_H
#define COMMAND_H
void cmd_init(void);
int process_input(char *inp);
#endif

54
input_buffer.c Normal file
View File

@ -0,0 +1,54 @@
/*
* input_buffer.c
*
* Copyright (C) 2012 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <string.h>
#define BUFMAX 100
static char *_inp_buf[BUFMAX];
static int _buf_size;
static int _buf_prev;
void inpbuf_init(void)
{
_buf_size = 0;
_buf_prev = -1;
}
void inpbuf_append(char *inp)
{
if (_buf_size < BUFMAX) {
_inp_buf[_buf_size] = (char*) malloc(strlen(inp) * sizeof(char));
strcpy(_inp_buf[_buf_size], inp);
_buf_prev = _buf_size;
_buf_size++;
}
}
char *inp_buf_get_previous(void)
{
if (_buf_size == 0 || _buf_prev == -1)
return NULL;
return _inp_buf[_buf_prev--];
}

31
input_buffer.h Normal file
View File

@ -0,0 +1,31 @@
/*
* input_buffer.h
*
* Copyright (C) 2012 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef INPUT_BUFFER_H
#define INPUT_BUFFER_H
void inpbuf_init(void);
void inpbuf_append(char *inp);
char *inp_buf_get_previous(void);
#endif

View File

@ -23,6 +23,7 @@
#include <string.h>
#include <ncurses.h>
#include "windows.h"
#include "input_buffer.h"
static WINDOW *inp_win;
@ -41,6 +42,7 @@ void inp_clear(void)
{
wclear(inp_win);
wmove(inp_win, 0, 1);
touchwin(inp_win);
wrefresh(inp_win);
}
@ -55,12 +57,21 @@ void inp_block(void)
}
/*
* Non blocking input char handling
*
* *size - holds the current size of input
* *input - holds the current input string
* *ch - getch will put a charater here if there was any input
*
* The example below shows the values of size, input, a call to wgetyx to
* find the current cursor location, and the index if the input string.
*
* size : " 7 "
* input : " example "
* inp_x : "012345678"
* index : " 0123456 " (inp_x - 1)
*/
void inp_poll_char(int *ch, char *command, int *size)
void inp_poll_char(int *ch, char *input, int *size)
{
int inp_y = 0;
int inp_x = 0;
@ -77,9 +88,25 @@ void inp_poll_char(int *ch, char *command, int *size)
if (*ch == 127) {
if (*size > 0) {
getyx(inp_win, inp_y, inp_x);
wmove(inp_win, inp_y, inp_x-1);
wdelch(inp_win);
(*size)--;
// if at end, delete last char
if (inp_x > *size) {
wmove(inp_win, inp_y, inp_x-1);
wdelch(inp_win);
(*size)--;
// if in middle, delete and shift chars left
} else if (inp_x > 1 && inp_x <= *size) {
int i;
for (i = inp_x-1; i < *size; i++)
input[i-1] = input[i];
(*size)--;
inp_clear();
for (i = 0; i < *size; i++)
waddch(inp_win, input[i]);
wmove(inp_win, 0, inp_x -1);
}
}
// left arrow
@ -96,6 +123,18 @@ void inp_poll_char(int *ch, char *command, int *size)
wmove(inp_win, inp_y, inp_x+1);
}
// up arrow
} else if (*ch == KEY_UP) {
char *prev = inp_buf_get_previous();
if (prev) {
strcpy(input, prev);
*size = strlen(input);
inp_clear();
int i;
for (i = 0; i < *size; i++)
waddch(inp_win, input[i]);
}
// else if not error, newline or special key,
// show it and store it
} else if (*ch != ERR &&
@ -124,15 +163,15 @@ void inp_poll_char(int *ch, char *command, int *size)
int i;
for (i = *size; i > inp_x -1; i--)
command[i] = command[i-1];
command[inp_x -1] = *ch;
input[i] = input[i-1];
input[inp_x -1] = *ch;
(*size)++;
// otherwise just append
} else {
waddch(inp_win, *ch);
command[(*size)++] = *ch;
input[(*size)++] = *ch;
}
}

View File

@ -65,7 +65,7 @@ static int _jabber_message_handler(xmpp_conn_t * const conn,
static int _roster_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
void * const userdata);
void init_jabber(int disable_tls)
void jabber_init(int disable_tls)
{
jabber_conn.conn_status = JABBER_STARTED;
jabber_conn.tls_disabled = disable_tls;

View File

@ -30,7 +30,7 @@ typedef enum {
JABBER_DISCONNECTED
} jabber_status_t;
void init_jabber(int disable_tls);
void jabber_init(int disable_tls);
jabber_status_t jabber_connection_status(void);
jabber_status_t jabber_connect(char *user, char *passwd);
void jabber_disconnect(void);

View File

@ -30,15 +30,22 @@
#include "windows.h"
#include "jabber.h"
#include "command.h"
#include "input_buffer.h"
static void _profanity_event_loop(int *ch, char *cmd, int *size);
static void _process_special_keys(int *ch);
static void profanity_init(int disable_tls)
{
jabber_init(disable_tls);
inpbuf_init();
}
void profanity_main(int disable_tls)
{
int cmd_result = TRUE;
init_jabber(disable_tls);
profanity_init(disable_tls);
inp_non_block();
while(cmd_result == TRUE) {

View File

@ -78,7 +78,7 @@ void status_bar_active(int win);
void status_bar_update_time(void);
// input window actions
void inp_poll_char(int *ch, char command[], int *size);
void inp_poll_char(int *ch, char *input, int *size);
void inp_clear(void);
void inp_put_back(void);
void inp_non_block(void);