jovanbulck / jsh

A basic UNIX shell implementation in C
GNU General Public License v3.0
30 stars 10 forks source link

Enhanced code completion #16

Open GijsTimmers opened 9 years ago

GijsTimmers commented 9 years ago

Current situation:

$ ls
Downloads/
Desktop/
$ cd do            ## Press [Tab]: nothing happens
$ cd Do            ## Press [Tab]: code completion to cd Downloads/
$ cd Downloads/

Request: complete code disregarding case. For instance:

$ ls
Downloads/
Desktop/
$ cd do            ## Press [Tab]: code completion to cd Downloads/:
$ cd Downloads/
jovanbulck commented 9 years ago

This wont be easy to code, but it would indeed be awesome :-)

Some pointers:

jovanbulck commented 9 years ago

I looked a bit further in case-insensitive completion:

=> FIX: including "set completion-ignore-case on" in ~/.inputrc configures readline. This works in jsh as well :-) (you might have to do ctrl-x ctrl-r after creating the inputrc file)

jovanbulck commented 9 years ago

I changed the subject to better reflect the current issue:

GijsTimmers commented 9 years ago

OK, thanks for the info. This will work in the meantime, although I'd prefer an entry in ~/.jshrc, or a default setting.

Some other examples of smart completions:

$ ls
  Track_17.mp3 Track_18.mp3
$ rm 17<TAB>
$ rm Track_17.mp3        ## detect filenames after writing just a part of them

$ ls
  Spain.map Italy.map France.map
$ rm Farnce.map<TAB>
$ rm France.map          ## detect filenames even if not writing them correctly
jovanbulck commented 9 years ago

From the gnu readline manual (http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC32):

Function: int rl_parse_and_bind (char line) Parse line as if it had been read from the inputrc file and perform any key bindings and variable assignments found (see section 1.3 Readline Init File). Function: int rl_read_init_file (const char filename) Read keybindings and variable assignments from filename (see section 1.3 Readline Init File).

This means one call "set completion-ignore-case on" from within the jsh code :-)

jovanbulck commented 9 years ago

Using the rl_parse_and_bind (char *line) function we can now enable case insentive autocompletion from within the jsh code. Even better: we can execute any readline settings that go in the initrc file, eliminating the need to use the inputrc file in jsh :-)

I issued a bug report since passing a static compile-time string to this function causes a segmentation fault. As explained in the mailing list, this can be avoided by copying it first to malloced memory.

I think the best thing to do, would be something like:

  1. configure readline as we please in the jsh code at startup time, using rl_parse_and_bind()
  2. check for the existence of the ~/.inputrc file; if found, execute it using rl_read_init_file() allowing the user to explicitly override any default rl options we choose

(Note we could also design our own jsh syntax, put it in the jshrc file and map it onto the according readline syntax. This would be pretty useless and less flexible/customizable however, I think.)

GijsTimmers commented 9 years ago

So how can I use this for the time being?

jovanbulck commented 9 years ago

@GijsTimmers You have to hack into the source code of jsh.c. Do something as in this commit:

/*************** at the start of the file **************/
#define RL_CASE_INSENSITIVE     "set completion-ignore-case on"

/************** in things_todo_at_start() function ******************/
//TODO readline configuration
// copy constants to normal mem; see https://lists.gnu.org/archive/html/bug-readline/201410/msg00004.html
char *s;
// macro def; ignore the do-while hack (see eg http://stackoverflow.com/questions/1067226/c-multi-line-macro-do-while0-vs-scope-block)
#define RL_PARSE(str) \
   do { \
         s = malloc(strlen(str)+1); \
         strcpy(s,str); \
         printdebug("passing '%s' to rl_parse_and_bind", s); \
         rl_parse_and_bind(s); \
         free(s); \
         s = NULL; \
    } while(0)

RL_PARSE(RL_CASE_INSENSITIVE);
RL_PARSE("any other string you want to experiment with; see http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC9");

Happy hacking ;-)

jovanbulck commented 9 years ago

See issue #51 for further discussion