.
This commit is contained in:
parent
ac8b1ba6dc
commit
046e3a75f7
6
Makefile
6
Makefile
@ -1,12 +1,14 @@
|
|||||||
DEBUG:=1
|
DEBUG:=1
|
||||||
GCC:=0
|
GCC:=0
|
||||||
|
|
||||||
|
LIBS:=ncurses readline history
|
||||||
|
|
||||||
CC:=gcc
|
CC:=gcc
|
||||||
CFLAGS:=-Wall -Wextra -Wpedantic
|
CFLAGS:=-Wall -Wextra -Wpedantic
|
||||||
CFLAGS +=$(if $(DEBUG),-O0 -ggdb,-O3 -flto=auto -fomit-frame-pointer)
|
CFLAGS +=$(if $(DEBUG),-O0 -ggdb,-O3 -flto=auto -fomit-frame-pointer)
|
||||||
CFLAGS +=$(if $(SAN),-fsanitize=${SAN})
|
CFLAGS +=$(if $(SAN),-fsanitize=${SAN})
|
||||||
CPPFLAGS:=-I config/ -I ${CHDRD} ${shell pkg-config --cflags ncurses readline}
|
CPPFLAGS:=-I config/ -I ${CHDRD} ${shell pkg-config --cflags ${LIBS}}
|
||||||
LDLIBS=${shell pkg-config --libs ncurses readline}
|
LDLIBS=${shell pkg-config --libs ${LIBS}}
|
||||||
LEX:=flex
|
LEX:=flex
|
||||||
|
|
||||||
LEXD:=src/
|
LEXD:=src/
|
||||||
|
63
README.md
63
README.md
@ -26,7 +26,7 @@ Csope is alive and well.
|
|||||||
|
|
||||||
# Interface
|
# Interface
|
||||||
<-- Tab -->
|
<-- Tab -->
|
||||||
+------------Message-------------+ +--------------------------------+
|
+--Version-----------------Case--+ +--------------------------------+
|
||||||
A |+--------------+---------------+| |+------------------------------+|
|
A |+--------------+---------------+| |+------------------------------+|
|
||||||
| || Input Window | Result window || || ||
|
| || Input Window | Result window || || ||
|
||||||
| |+--------------+ || ? || ||
|
| |+--------------+ || ? || ||
|
||||||
@ -36,7 +36,7 @@ Csope is alive and well.
|
|||||||
| || | || || ||
|
| || | || || ||
|
||||||
| || | || || ||
|
| || | || || ||
|
||||||
V |+--------------+---------------+| |+------------------------------+|
|
V |+--------------+---------------+| |+------------------------------+|
|
||||||
+-----------Tool Tips------------+ +--------------------------------+
|
+---------------------Tool Tips--+ +--------------------------------+
|
||||||
|
|
||||||
# Usacases
|
# Usacases
|
||||||
Csope shines at exploring stranger and obsecure code bases due to its TUI.
|
Csope shines at exploring stranger and obsecure code bases due to its TUI.
|
||||||
@ -49,21 +49,29 @@ fixing it would have been a lost cause, if not for Cscope itself. Well, Csope no
|
|||||||
|
|
||||||
# Improvements/Changes
|
# Improvements/Changes
|
||||||
## User side
|
## User side
|
||||||
+ renamed the program, because "cscope" is annoying to type
|
+ Renamed the program, because "cscope" is annoying to type
|
||||||
+ improved gui
|
+ Improved tui
|
||||||
+ GNU Readline integration (ie. VI/EMACS mode, command history) /*pending*/
|
+ GNU Readline/History integration
|
||||||
## To the code
|
## To the code
|
||||||
+ nuked autoconf, replaced with single Makefile
|
+ Nuked autoconf, replaced with single Makefile
|
||||||
+ reorganized main()
|
+ Reorganized the control flow
|
||||||
+ encapsulated changes to the TUI into display.c
|
+ Encapsulated changes to the TUI into display.c
|
||||||
+ encapsulated searching into find.c
|
+ Encapsulated searching into find.c
|
||||||
+ removed "scanner.l" which seems to be an anchient version (and redundant copy) of "fscanner.l" forgotten by all
|
+ Removed "scanner.l" which seems to be an anchient version (and redundant copy) of "fscanner.l" forgotten by all
|
||||||
+ removed macro hell put in place to allow compiling on a dead badger
|
+ Removed macro hell put in place to allow compiling on a dead badger
|
||||||
+ replaced repeated inline #ifdef KEY_\*-s with guaranteed definitions
|
+ Use stdbool instead of YES/NO macros
|
||||||
+ removed random commets giving tips for and refering to specific issues
|
+ Saved kilobytes by stripping trailing whitespace
|
||||||
+ use stdbool instead of YES/NO macros
|
+ ...and much more
|
||||||
+ saved kilobytes by stripping trailing whitespace
|
|
||||||
+ FILE\* refsfound used to be rewind()-ed everytime the reads were not sequencial
|
# Installation
|
||||||
|
You will have to compile from source.
|
||||||
|
After you made sure you have the following (dev) libraries installed:
|
||||||
|
ncurses
|
||||||
|
GNU Readline
|
||||||
|
GNU History (should come with Readline)
|
||||||
|
Just run:
|
||||||
|
make
|
||||||
|
This will yield the executable "scope", which you are free to do whatever with.
|
||||||
|
|
||||||
# Control flow
|
# Control flow
|
||||||
...
|
...
|
||||||
@ -86,26 +94,25 @@ fixing it would have been a lost cause, if not for Cscope itself. Well, Csope no
|
|||||||
| int window_change | Bit mask type of the CH_\* macros. Keeps track of the windows to be refresed on the next run of display(). Could be better utalized.
|
| int window_change | Bit mask type of the CH_\* macros. Keeps track of the windows to be refresed on the next run of display(). Could be better utalized.
|
||||||
|
|
||||||
# TODO /*move soon*/
|
# TODO /*move soon*/
|
||||||
+ sort out constants.h
|
+ sort out constants.h
|
||||||
+ scrollbar() uses magic int literals?
|
+ scrollbar() uses magic int literals?
|
||||||
+ Ordering function declarations in global.h by alpha order is not smart
|
+ lineflagafterfile is stupid
|
||||||
+ lineflagafterfile is stupid
|
+ library.h...; "private library", in a program using 90 globals; ffs
|
||||||
+ library.h...; "private library", in a program using 90 globals; ffs
|
+ sort out the global hell
|
||||||
+ sort out the global hell
|
+ was there really ever a scrollbar?
|
||||||
+ was there really ever a scrollbar?
|
+ handle resizing
|
||||||
+ handle resizing
|
+ a search struct could be great for caching and could ease the global situation
|
||||||
+ a search struct could be great for caching and could easy the global situation
|
|
||||||
## Original
|
## Original
|
||||||
+ Same capabilities as interactive in non interactive (one shot) mode
|
+ Same capabilities as interactive in non interactive (one shot) mode
|
||||||
+ Provide some how-do-I-use-this-thing doc.
|
+ Provide some how-do-I-use-this-thing doc.
|
||||||
|
|
||||||
|
|
||||||
# BUGS
|
# BUGS
|
||||||
+ Changing text double frees:
|
+ Changing text double frees:
|
||||||
free(): double free detected in tcache 2
|
free(): double free detected in tcache 2
|
||||||
Aborted
|
Aborted
|
||||||
+ Changing text can crash without replacing text and leaving the console ncursed
|
+ Changing text can crash without replacing text and leaving the console ncursed
|
||||||
+ After an attempted change malloc *can* cry and crash
|
+ After an attempted change malloc *can* cry and crash
|
||||||
|
|
||||||
# Future features / contributor wishlist
|
# Future features / contributor wishlist
|
||||||
+ providing support for other languages by integrating new lexers (e.g. ctag's)
|
+ providing support for other languages by integrating new lexers (e.g. ctag's)
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
# define COLOR_HELP_BG -1
|
# define COLOR_HELP_BG -1
|
||||||
# define COLOR_TOOLTIP_FG COLOR_WHITE
|
# define COLOR_TOOLTIP_FG COLOR_WHITE
|
||||||
# define COLOR_TOOLTIP_BG COLOR_GREEN
|
# define COLOR_TOOLTIP_BG COLOR_GREEN
|
||||||
|
# define COLOR_CASE_FG COLOR_GREEN
|
||||||
|
# define COLOR_CASE_BG -1
|
||||||
# define COLOR_MESSAGE_FG COLOR_WHITE
|
# define COLOR_MESSAGE_FG COLOR_WHITE
|
||||||
# define COLOR_MESSAGE_BG COLOR_BLACK
|
# define COLOR_MESSAGE_BG COLOR_BLACK
|
||||||
# define COLOR_PATTERN_FG COLOR_WHITE
|
# define COLOR_PATTERN_FG COLOR_WHITE
|
||||||
@ -78,6 +80,7 @@ enum color_pairs{
|
|||||||
COLOR_PAIR_FIELD_SELECTED,
|
COLOR_PAIR_FIELD_SELECTED,
|
||||||
COLOR_PAIR_HELP,
|
COLOR_PAIR_HELP,
|
||||||
COLOR_PAIR_TOOLTIP,
|
COLOR_PAIR_TOOLTIP,
|
||||||
|
COLOR_PAIR_CASE,
|
||||||
COLOR_PAIR_PATTERN,
|
COLOR_PAIR_PATTERN,
|
||||||
COLOR_PAIR_MESSAGE,
|
COLOR_PAIR_MESSAGE,
|
||||||
COLOR_PAIR_TABLE_HEADER,
|
COLOR_PAIR_TABLE_HEADER,
|
||||||
|
@ -94,6 +94,7 @@ WINDOW *wresult;
|
|||||||
WINDOW *whelp;
|
WINDOW *whelp;
|
||||||
/* Non-Selectable windows */
|
/* Non-Selectable windows */
|
||||||
WINDOW *wtooltip;
|
WINDOW *wtooltip;
|
||||||
|
WINDOW *wcase;
|
||||||
/* Selected window pointer */
|
/* Selected window pointer */
|
||||||
WINDOW **current_window;
|
WINDOW **current_window;
|
||||||
static WINDOW **last_window;
|
static WINDOW **last_window;
|
||||||
@ -113,6 +114,7 @@ static inline void display_cursor(void);
|
|||||||
static inline void display_help(void);
|
static inline void display_help(void);
|
||||||
static inline void display_frame(const bool border_only);
|
static inline void display_frame(const bool border_only);
|
||||||
static inline void display_mode(void);
|
static inline void display_mode(void);
|
||||||
|
static inline void display_case(void);
|
||||||
static inline void display_command_field(void);
|
static inline void display_command_field(void);
|
||||||
static inline void display_results(void);
|
static inline void display_results(void);
|
||||||
static inline void display_tooltip(void);
|
static inline void display_tooltip(void);
|
||||||
@ -161,6 +163,7 @@ void dispinit(void) {
|
|||||||
easy_init_pair(FIELD_SELECTED);
|
easy_init_pair(FIELD_SELECTED);
|
||||||
easy_init_pair(HELP);
|
easy_init_pair(HELP);
|
||||||
easy_init_pair(TOOLTIP);
|
easy_init_pair(TOOLTIP);
|
||||||
|
easy_init_pair(CASE);
|
||||||
easy_init_pair(MESSAGE);
|
easy_init_pair(MESSAGE);
|
||||||
easy_init_pair(PATTERN);
|
easy_init_pair(PATTERN);
|
||||||
easy_init_pair(TABLE_HEADER);
|
easy_init_pair(TABLE_HEADER);
|
||||||
@ -189,6 +192,7 @@ void dispinit(void) {
|
|||||||
mdisprefs = result_window_height - (WRESULT_TABLE_BODY_START + 1);
|
mdisprefs = result_window_height - (WRESULT_TABLE_BODY_START + 1);
|
||||||
tooltip_width =
|
tooltip_width =
|
||||||
MAX(MAX(strlen(tooltip_winput), strlen(tooltip_wmode)), strlen(tooltip_wresult));
|
MAX(MAX(strlen(tooltip_winput), strlen(tooltip_wmode)), strlen(tooltip_wresult));
|
||||||
|
static int case_width = sizeof("Case: XXX")-1;
|
||||||
|
|
||||||
if(mdisprefs <= 0) {
|
if(mdisprefs <= 0) {
|
||||||
postfatal(PROGRAM_NAME ": screen too small\n");
|
postfatal(PROGRAM_NAME ": screen too small\n");
|
||||||
@ -208,6 +212,7 @@ void dispinit(void) {
|
|||||||
wresult = newwin(result_window_height, second_col_width, 1, first_col_width + 1 + 1);
|
wresult = newwin(result_window_height, second_col_width, 1, first_col_width + 1 + 1);
|
||||||
whelp = newwin(LINES - 2, COLS - 2, 1, 1);
|
whelp = newwin(LINES - 2, COLS - 2, 1, 1);
|
||||||
wtooltip = newwin(1, tooltip_width, LINES - 1, COLS - (tooltip_width + 4));
|
wtooltip = newwin(1, tooltip_width, LINES - 1, COLS - (tooltip_width + 4));
|
||||||
|
wcase = newwin(1, case_width, 0, COLS - case_width - 4);
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
current_window = &winput;
|
current_window = &winput;
|
||||||
@ -261,6 +266,13 @@ static inline void display_help() {
|
|||||||
do_press_any_key = true;
|
do_press_any_key = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void display_case(){
|
||||||
|
wmove(wcase, 0, 0);
|
||||||
|
wattron(wcase, COLOR_PAIR(COLOR_PAIR_CASE));
|
||||||
|
waddstr(wcase, (caseless ? "Case: OFF" : "Case: ON"));
|
||||||
|
wattroff(wcase, COLOR_PAIR(COLOR_PAIR_CASE));
|
||||||
|
}
|
||||||
|
|
||||||
static inline void display_frame(const bool border_only) {
|
static inline void display_frame(const bool border_only) {
|
||||||
wattron(stdscr, COLOR_PAIR(COLOR_PAIR_FRAME));
|
wattron(stdscr, COLOR_PAIR(COLOR_PAIR_FRAME));
|
||||||
|
|
||||||
@ -273,12 +285,6 @@ static inline void display_frame(const bool border_only) {
|
|||||||
#else
|
#else
|
||||||
wprintw(stdscr, PROGRAM_NAME " version %d%s", FILEVERSION, FIXVERSION);
|
wprintw(stdscr, PROGRAM_NAME " version %d%s", FILEVERSION, FIXVERSION);
|
||||||
#endif
|
#endif
|
||||||
wmove(stdscr, 0, COLS - (int)sizeof("Case: XXX") - 4);
|
|
||||||
if(caseless) {
|
|
||||||
waddstr(stdscr, "Case: ON");
|
|
||||||
} else {
|
|
||||||
waddstr(stdscr, "Case: OFF");
|
|
||||||
}
|
|
||||||
/* --- */
|
/* --- */
|
||||||
if(!border_only) {
|
if(!border_only) {
|
||||||
/* Vertical line */
|
/* Vertical line */
|
||||||
@ -805,6 +811,7 @@ void display(void) {
|
|||||||
lstwin = *current_window;
|
lstwin = *current_window;
|
||||||
display_tooltip();
|
display_tooltip();
|
||||||
}
|
}
|
||||||
|
if(window_change & CH_CASE) { display_case(); }
|
||||||
if(window_change & CH_INPUT) { display_command_field(); }
|
if(window_change & CH_INPUT) { display_command_field(); }
|
||||||
if(window_change & CH_RESULT) { display_results(); }
|
if(window_change & CH_RESULT) { display_results(); }
|
||||||
if(window_change & CH_MODE) { display_mode(); }
|
if(window_change & CH_MODE) { display_mode(); }
|
||||||
@ -814,6 +821,7 @@ void display(void) {
|
|||||||
wrefresh(wmode);
|
wrefresh(wmode);
|
||||||
wrefresh(wresult);
|
wrefresh(wresult);
|
||||||
wrefresh(wtooltip);
|
wrefresh(wtooltip);
|
||||||
|
wrefresh(wcase);
|
||||||
}
|
}
|
||||||
|
|
||||||
window_change = CH_NONE;
|
window_change = CH_NONE;
|
||||||
|
10
src/global.h
10
src/global.h
@ -80,8 +80,9 @@ enum {
|
|||||||
CH_RESULT = 0x0001 << 0,
|
CH_RESULT = 0x0001 << 0,
|
||||||
CH_INPUT = 0x0001 << 1,
|
CH_INPUT = 0x0001 << 1,
|
||||||
CH_MODE = 0x0001 << 2,
|
CH_MODE = 0x0001 << 2,
|
||||||
CH_HELP = 0x0001 << 3, /* do NOT add to CH_ALL */
|
CH_CASE = 0x0001 << 3,
|
||||||
CH_ALL = CH_RESULT | CH_INPUT | CH_MODE
|
CH_HELP = 0x0001 << 4, /* do NOT add to CH_ALL */
|
||||||
|
CH_ALL = CH_RESULT | CH_INPUT | CH_MODE | CH_CASE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -252,7 +253,6 @@ void PCS_reset(void);
|
|||||||
|
|
||||||
void rlinit(void);
|
void rlinit(void);
|
||||||
|
|
||||||
void addcmd(int f, char *s);
|
|
||||||
void addsrcfile(char *path);
|
void addsrcfile(char *path);
|
||||||
void askforchar(void);
|
void askforchar(void);
|
||||||
void askforreturn(void);
|
void askforreturn(void);
|
||||||
@ -295,7 +295,6 @@ void posterr(char *msg, ...);
|
|||||||
void postfatal(const char *msg, ...);
|
void postfatal(const char *msg, ...);
|
||||||
void putposting(char *term, int type);
|
void putposting(char *term, int type);
|
||||||
void fetch_string_from_dbase(char *, size_t);
|
void fetch_string_from_dbase(char *, size_t);
|
||||||
void resetcmd(void);
|
|
||||||
void shellpath(char *out, int limit, char *in);
|
void shellpath(char *out, int limit, char *in);
|
||||||
void sourcedir(char *dirlist);
|
void sourcedir(char *dirlist);
|
||||||
void myungetch(int c);
|
void myungetch(int c);
|
||||||
@ -309,9 +308,6 @@ bool writerefsfound(void);
|
|||||||
|
|
||||||
int findinit(const char *pattern_);
|
int findinit(const char *pattern_);
|
||||||
MOUSE *getmouseaction(char leading_char);
|
MOUSE *getmouseaction(char leading_char);
|
||||||
struct cmd *currentcmd(void);
|
|
||||||
struct cmd *prevcmd(void);
|
|
||||||
struct cmd *nextcmd(void);
|
|
||||||
|
|
||||||
int egrep(char *file, FILE *output, char *format);
|
int egrep(char *file, FILE *output, char *format);
|
||||||
int hash(char *ss);
|
int hash(char *ss);
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
/*===========================================================================
|
|
||||||
Copyright (c) 1998-2000, The Santa Cruz Operation
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
*Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
*Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
*Neither name of The Santa Cruz Operation nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this software
|
|
||||||
without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
|
|
||||||
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT falseT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
|
||||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT falseT LIMITED TO, PROCUREMENT OF
|
|
||||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
INTERRUPTION)
|
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
DAMAGE.
|
|
||||||
=========================================================================*/
|
|
||||||
|
|
||||||
/* cscope - interactive C symbol or text cross-reference
|
|
||||||
*
|
|
||||||
* command history
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "global.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static struct cmd *tail, *current;
|
|
||||||
|
|
||||||
/* add a cmd to the history list */
|
|
||||||
void addcmd(int f, char *s) /* field number and command text */
|
|
||||||
{
|
|
||||||
struct cmd *h;
|
|
||||||
|
|
||||||
h = malloc(sizeof(struct cmd));
|
|
||||||
if(tail) {
|
|
||||||
tail->next = h;
|
|
||||||
h->next = 0;
|
|
||||||
h->prev = tail;
|
|
||||||
tail = h;
|
|
||||||
} else {
|
|
||||||
tail = h;
|
|
||||||
h->next = h->prev = 0;
|
|
||||||
}
|
|
||||||
h->field = f;
|
|
||||||
h->text = strdup(s);
|
|
||||||
current = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return previous history item */
|
|
||||||
struct cmd *prevcmd(void) {
|
|
||||||
if(current) {
|
|
||||||
if(current->prev) /* stay on first item */
|
|
||||||
return current = current->prev;
|
|
||||||
else
|
|
||||||
return current;
|
|
||||||
} else if(tail)
|
|
||||||
return current = tail;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return next history item */
|
|
||||||
struct cmd *nextcmd(void) {
|
|
||||||
if(current) {
|
|
||||||
if(current->next) /* stay on first item */
|
|
||||||
return current = current->next;
|
|
||||||
else
|
|
||||||
return current;
|
|
||||||
} else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reset current to tail */
|
|
||||||
void resetcmd(void) {
|
|
||||||
current = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cmd *currentcmd(void) {
|
|
||||||
return current;
|
|
||||||
}
|
|
13
src/input.c
13
src/input.c
@ -160,17 +160,14 @@ static int wmode_input(const int c) {
|
|||||||
case KEY_DOWN:
|
case KEY_DOWN:
|
||||||
case KEY_RIGHT:
|
case KEY_RIGHT:
|
||||||
field = (field + 1) % FIELDS;
|
field = (field + 1) % FIELDS;
|
||||||
resetcmd();
|
|
||||||
break;
|
break;
|
||||||
case ctrl('P'): /* go to previous input field */
|
case ctrl('P'): /* go to previous input field */
|
||||||
case KEY_UP:
|
case KEY_UP:
|
||||||
case KEY_LEFT:
|
case KEY_LEFT:
|
||||||
field = (field + (FIELDS - 1)) % FIELDS;
|
field = (field + (FIELDS - 1)) % FIELDS;
|
||||||
resetcmd();
|
|
||||||
break;
|
break;
|
||||||
case KEY_HOME: /* go to first input field */
|
case KEY_HOME: /* go to first input field */
|
||||||
field = 0;
|
field = 0;
|
||||||
resetcmd();
|
|
||||||
break;
|
break;
|
||||||
case KEY_LL: /* go to last input field */
|
case KEY_LL: /* go to last input field */
|
||||||
curdispline = disprefs;
|
curdispline = disprefs;
|
||||||
@ -206,7 +203,6 @@ static int wresult_input(const int c) {
|
|||||||
break;
|
break;
|
||||||
case KEY_LL:
|
case KEY_LL:
|
||||||
field = FIELDS - 1;
|
field = FIELDS - 1;
|
||||||
resetcmd();
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(c > mdisprefs) { goto noredisp; }
|
if(c > mdisprefs) { goto noredisp; }
|
||||||
@ -230,12 +226,10 @@ static int global_input(const int c) {
|
|||||||
break;
|
break;
|
||||||
case ctrl('K'):
|
case ctrl('K'):
|
||||||
field = (field + (FIELDS - 1)) % FIELDS;
|
field = (field + (FIELDS - 1)) % FIELDS;
|
||||||
resetcmd();
|
|
||||||
window_change |= CH_MODE;
|
window_change |= CH_MODE;
|
||||||
break;
|
break;
|
||||||
case ctrl('J'):
|
case ctrl('J'):
|
||||||
field = (field + 1) % FIELDS;
|
field = (field + 1) % FIELDS;
|
||||||
resetcmd();
|
|
||||||
window_change |= CH_MODE;
|
window_change |= CH_MODE;
|
||||||
break;
|
break;
|
||||||
case ctrl('H'): /* display previous page */
|
case ctrl('H'): /* display previous page */
|
||||||
@ -361,6 +355,13 @@ static int global_input(const int c) {
|
|||||||
case ctrl('E'): /* edit all lines */
|
case ctrl('E'): /* edit all lines */
|
||||||
editall();
|
editall();
|
||||||
break;
|
break;
|
||||||
|
case ctrl('S'): // toggle caseless
|
||||||
|
caseless = !caseless;
|
||||||
|
egrepcaseless(caseless);
|
||||||
|
window_change |= CH_CASE;
|
||||||
|
break;
|
||||||
|
case EOF:
|
||||||
|
myexit(0);
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef KEYS_H
|
#ifndef KEYS_H
|
||||||
#define KEYS_H
|
#define KEYS_H
|
||||||
|
|
||||||
|
#include <ncurses.h>
|
||||||
|
|
||||||
/* Key macros */
|
/* Key macros */
|
||||||
/* These macros are not guaranteed to be defined,
|
/* These macros are not guaranteed to be defined,
|
||||||
* however we wish to test for these anyways while
|
* however we wish to test for these anyways while
|
||||||
|
@ -420,7 +420,6 @@ int process_mouse() {
|
|||||||
field = p->y1 - FLDLINE;
|
field = p->y1 - FLDLINE;
|
||||||
/* force it into range */
|
/* force it into range */
|
||||||
if(field >= FIELDS) { field = FIELDS - 1; }
|
if(field >= FIELDS) { field = FIELDS - 1; }
|
||||||
resetcmd();
|
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
119
src/readline.c
119
src/readline.c
@ -1,18 +1,65 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
|
#include <readline/history.h>
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
|
|
||||||
static int input_available = 0;
|
static int input_available = 0;
|
||||||
static char input_char;
|
static int input_char;
|
||||||
char input_line[PATLEN + 1];
|
char input_line[PATLEN + 1];
|
||||||
|
/* used for saving a line not [Enter]-ed yet,
|
||||||
|
* so its not lost if the user scrolls the history
|
||||||
|
*/
|
||||||
|
static struct PARTIAL_LINE {
|
||||||
|
bool is_active;
|
||||||
|
char* line;
|
||||||
|
int pos;
|
||||||
|
} partial_line = {
|
||||||
|
.line = NULL,
|
||||||
|
.is_active = true
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static inline void previous_history_proxy(void);
|
||||||
|
static inline void next_history_proxy(void);
|
||||||
|
static inline int rebuild_reference(void);
|
||||||
|
|
||||||
|
|
||||||
bool interpret(int c) {
|
bool interpret(int c) {
|
||||||
|
/* A switch is faster then binding Readline to a billion functions
|
||||||
|
* and since KEY_* values can't be bound anyways (values too large
|
||||||
|
* (because while the first argument of rl_bind_key() is an int,
|
||||||
|
* only unsigned chars are valid)), handling everything here
|
||||||
|
* creates consistency too.
|
||||||
|
*/
|
||||||
|
switch(c){
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
rl_rubout(1, 0);
|
||||||
|
break;
|
||||||
|
case KEY_UP:
|
||||||
|
previous_history_proxy();
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
next_history_proxy();
|
||||||
|
break;
|
||||||
|
case ctrl('R'):
|
||||||
|
rebuild_reference();
|
||||||
|
break;
|
||||||
|
case ESC:
|
||||||
|
case ctrl('X'):
|
||||||
|
process_mouse();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
input_char = c;
|
input_char = c;
|
||||||
input_available = 1;
|
input_available = 1;
|
||||||
rl_callback_read_char();
|
rl_callback_read_char();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//XXX:
|
||||||
|
// rl_bind_key(ctrl('\\'), /**/); /* bypass bindings */
|
||||||
|
|
||||||
|
window_change |= CH_INPUT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,7 +67,7 @@ static int getc_function(FILE *ignore) {
|
|||||||
UNUSED(ignore);
|
UNUSED(ignore);
|
||||||
|
|
||||||
input_available = 0;
|
input_available = 0;
|
||||||
return (int)input_char;
|
return input_char;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int input_available_hook() {
|
static int input_available_hook() {
|
||||||
@ -34,6 +81,8 @@ static void redisplay_function() {
|
|||||||
static void callback_handler(char *line) {
|
static void callback_handler(char *line) {
|
||||||
if(!line) { return; }
|
if(!line) { return; }
|
||||||
|
|
||||||
|
add_history(line);
|
||||||
|
|
||||||
switch(input_mode) {
|
switch(input_mode) {
|
||||||
case INPUT_NORMAL:
|
case INPUT_NORMAL:
|
||||||
strncpy(input_line, line, PATLEN);
|
strncpy(input_line, line, PATLEN);
|
||||||
@ -62,24 +111,7 @@ static void callback_handler(char *line) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ctrl_z() {
|
static inline int rebuild_reference() {
|
||||||
kill(0, SIGTSTP);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int toggle_caseless() {
|
|
||||||
if(caseless == false) {
|
|
||||||
caseless = true;
|
|
||||||
postmsg2("Caseless mode is now ON");
|
|
||||||
} else {
|
|
||||||
caseless = false;
|
|
||||||
postmsg2("Caseless mode is now OFF");
|
|
||||||
}
|
|
||||||
egrepcaseless(caseless); /* turn on/off -i flag */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rebuild_reference() {
|
|
||||||
if(isuptodate == true) {
|
if(isuptodate == true) {
|
||||||
postmsg("The -d option prevents rebuilding the symbol database");
|
postmsg("The -d option prevents rebuilding the symbol database");
|
||||||
return (false);
|
return (false);
|
||||||
@ -99,7 +131,41 @@ static int rebuild_reference() {
|
|||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void previous_history_proxy(){
|
||||||
|
HIST_ENTRY* i = previous_history();
|
||||||
|
if(i){
|
||||||
|
if(partial_line.is_active){
|
||||||
|
free(partial_line.line);
|
||||||
|
partial_line = (struct PARTIAL_LINE){
|
||||||
|
.line = rl_line_buffer,
|
||||||
|
.pos = rl_point,
|
||||||
|
.is_active = false
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
free(rl_line_buffer);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
rl_line_buffer = strdup(i->line);
|
||||||
|
rl_point = strlen(rl_line_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void next_history_proxy(){
|
||||||
|
HIST_ENTRY* i = next_history();
|
||||||
|
if(i){
|
||||||
|
free(rl_line_buffer);
|
||||||
|
rl_line_buffer = strdup(i->line);
|
||||||
|
rl_point = strlen(rl_line_buffer);
|
||||||
|
}else if(!partial_line.is_active){
|
||||||
|
rl_line_buffer = strdup(partial_line.line);
|
||||||
|
rl_point = partial_line.pos;
|
||||||
|
partial_line.is_active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void rlinit() {
|
void rlinit() {
|
||||||
|
using_history();
|
||||||
|
|
||||||
rl_catch_signals = 0;
|
rl_catch_signals = 0;
|
||||||
rl_catch_sigwinch = 0;
|
rl_catch_sigwinch = 0;
|
||||||
rl_prep_term_function = NULL;
|
rl_prep_term_function = NULL;
|
||||||
@ -110,17 +176,4 @@ void rlinit() {
|
|||||||
rl_input_available_hook = input_available_hook;
|
rl_input_available_hook = input_available_hook;
|
||||||
rl_redisplay_function = redisplay_function;
|
rl_redisplay_function = redisplay_function;
|
||||||
rl_callback_handler_install("", callback_handler);
|
rl_callback_handler_install("", callback_handler);
|
||||||
|
|
||||||
rl_bind_key(7,
|
|
||||||
rl_rubout); // XXX: 7 is backspace for some reason (on my system anyways?)
|
|
||||||
rl_bind_key(KEY_BACKSPACE, rl_rubout);
|
|
||||||
|
|
||||||
rl_bind_key(EOF, myexit);
|
|
||||||
rl_bind_key(ctrl('Z'), ctrl_z);
|
|
||||||
rl_bind_key(ctrl('Z'), toggle_caseless);
|
|
||||||
rl_bind_key(ctrl('R'), rebuild_reference);
|
|
||||||
rl_bind_key(ESC, process_mouse); /* possible unixpc mouse selection */
|
|
||||||
rl_bind_key(ctrl('X'), process_mouse); /* mouse selection */
|
|
||||||
|
|
||||||
// rl_bind_key(ctrl('\\'), /**/); /* bypass bindings */
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user