Readline interface: Difference between revisions
m
→{{header|Wren}}: Changed to Wren S/H
m (→{{header|Wren}}: Changed to Wren S/H) |
|||
(12 intermediate revisions by 7 users not shown) | |||
Line 1:
{{draft task|
A readline interface is a line editing facility that provides auto completion facilities and the ability to recall previously typed lines. Build a simple application that accepts at least two commands and uses a readline style interface.
Line 16:
__TOC__
=={{header|11l}}==
{{trans|D}}
<syntaxhighlight lang="11l">[String] histArr
F hello()
print(‘Hello World!’)
:histArr [+]= ‘hello’
F hist()
I :histArr.empty
print(‘No history’)
E
L(cmd) :histArr
print(‘ - ’cmd)
:histArr [+]= ‘hist’
F help()
print(‘Available commands:’)
print(‘ hello’)
print(‘ hist’)
print(‘ exit’)
print(‘ help’)
:histArr [+]= ‘help’
[String = (() -> N)] aa
aa[‘help’] = help
aa[‘hist’] = hist
aa[‘hello’] = hello
print(‘Enter a command, type help for a listing.’)
L
V line = input(‘>’)
I line == ‘exit’
L.break
aa.get(line, help)()</syntaxhighlight>
=={{header|C}}==
A program that does absolutely nothing. Type 'help' for help.
<
#include <readline/history.h>
#include <string.h>
Line 43 ⟶ 81:
puts("Yes...?");
}
}</
=={{header
{{trans|D}}
<
using System.Collections.Generic;
using System.Runtime.CompilerServices;
Line 108 ⟶ 146:
}
}
}</
=={{header|C++}}==
{{trans|D}}
<syntaxhighlight lang="cpp">#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> hist;
std::ostream& operator<<(std::ostream& os, const std::string& str) {
return os << str.c_str();
}
void appendHistory(const std::string& name) {
hist.push_back(name);
}
void hello() {
std::cout << "Hello World!\n";
appendHistory(__func__);
}
void history() {
if (hist.size() == 0) {
std::cout << "No history\n";
} else {
for (auto& str : hist) {
std::cout << " - " << str << '\n';
}
}
appendHistory(__func__);
}
void help() {
std::cout << "Available commands:\n";
std::cout << " hello\n";
std::cout << " hist\n";
std::cout << " exit\n";
std::cout << " help\n";
appendHistory(__func__);
}
int main() {
bool done = false;
std::string cmd;
do {
std::cout << "Enter a command, type help for a listing.\n";
std::cin >> cmd;
for (size_t i = 0; i < cmd.size(); ++i) {
cmd[i] = toupper(cmd[i]);
}
if (strcmp(cmd.c_str(), "HELLO") == 0) {
hello();
} else if (strcmp(cmd.c_str(), "HIST") == 0) {
history();
} else if (strcmp(cmd.c_str(), "EXIT") == 0) {
done = true;
} else {
help();
}
} while (!done);
return 0;
}</syntaxhighlight>
=={{header|D}}==
<
import std.stdio;
Line 163 ⟶ 267:
write(">");
}
}</
{{out}}
<pre>Enter a command, type help for a listing.
Line 181 ⟶ 285:
- readline_interface.hello
>exit</pre>
=={{header|Go}}==
{{trans|D}}
<syntaxhighlight lang="go">package main
import (
"bufio"
"fmt"
"log"
"os"
"strings"
)
type vf = func()
var history []string
func hello() {
fmt.Println("Hello World!")
history = append(history, "hello")
}
func hist() {
if len(history) == 0 {
fmt.Println("No history")
} else {
for _, cmd := range history {
fmt.Println(" -", cmd)
}
}
history = append(history, "hist")
}
func help() {
fmt.Println("Available commands:")
fmt.Println(" hello")
fmt.Println(" hist")
fmt.Println(" exit")
fmt.Println(" help")
history = append(history, "help")
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
vfs := map[string]vf{"help": help, "hist": hist, "hello": hello}
fmt.Println("Enter a command, type help for a listing.")
for {
fmt.Print(">")
scanner.Scan()
if scerr := scanner.Err(); scerr != nil {
log.Fatal(scerr)
}
line := strings.TrimSpace(scanner.Text())
if line == "exit" {
return
}
cmd, ok := vfs[line]
if !ok {
fmt.Println("Unknown command, try again")
} else {
cmd()
}
}
}</syntaxhighlight>
{{out}}
Sample session:
<pre>
Enter a command, type help for a listing.
>hit
Unknown command, try again
>hist
No history
>help
Available commands:
hello
hist
exit
help
>hello
Hello World!
>hist
- hist
- help
- hello
>exit
</pre>
=={{header|Java}}==
{{trans|C#}}
<
import java.io.IOException;
import java.io.InputStreamReader;
Line 242 ⟶ 433:
}
}
}</
=={{header|Julia}}==
Line 249 ⟶ 440:
Simple program that does nothing (copy of [[#C | C]]).
<
print(prompt)
r = readline(STDIN)
Line 264 ⟶ 455:
end
input("This is a common prompt> ")</
=={{header|Kotlin}}==
<
var range = intArrayOf() // empty initially
Line 416 ⟶ 607:
println()
}
}</
{{out}}
Line 493 ⟶ 684:
quit
</pre>
=={{header|Nim}}==
{{trans|Go}}
Nim provides a module <code>rdstdin</code> to read form standard input file. This modules provides navigation in history of previous commands using the up and down keys.
<syntaxhighlight lang="nim">import rdstdin, strutils, tables
var history: seq[string]
proc hello =
echo "Hello World!"
history.add "hello"
proc hist =
if history.len == 0:
echo "no history"
else:
for cmd in history:
echo " -", cmd
history.add "hist"
proc help =
echo "Available commands:"
echo " hello"
echo " hist"
echo " exit"
echo " help"
history.add "help"
const Vfs = {"help": help, "hist": hist, "hello": hello}.toTable
echo "Enter a command, type help for a listing."
while true:
let line = try:
readLineFromStdin(">").strip()
except IOError:
echo "EOF encountered. Bye."
break
if line == "exit": break
if line notin Vfs:
echo "Unknown command, try again."
else:
Vfs[line]()</syntaxhighlight>
{{out}}
Sample session.
<pre>Enter a command, type help for a listing.
>help
Available commands:
hello
hist
exit
help
>hello
Hello World!
>hist
-help
-hello
>quit
Unknown command, try again.
>exit</pre>
=={{header|PARI/GP}}==
Line 498 ⟶ 750:
gp uses readline, but it can also be used directly in PARI:
<
#include <pari/pari.h>
#include <readline/readline.h>
Line 542 ⟶ 794:
}
return 0;
}</
<small>Code thanks to [http://pari.math.u-bordeaux.fr/archives/pari-dev-1002/msg00023.html Bill Allombert]</small>
=={{header|Perl
A Perl shell with command history, line-editing and variable-name completion. Simplified from the example supplied with the CPAN module <code>Term::Readline::Gnu</code>.
<syntaxhighlight lang="perl">use strict;
use warnings;
use Term::ReadLine;
use POSIX;
my $term = Term::ReadLine->new( 'simple Perl shell' );
my $attribs = $term->Attribs;
$attribs->{completion_append_character} = ' ';
$attribs->{attempted_completion_function} = \&attempt_perl_completion;
$attribs->{completion_display_matches_hook} = \&perl_symbol_display_match_list;
while (defined(my $command = &reader)) {
my @result = eval ("package main; $command");
print "$_\n" for @result;
}
sub reader {
my $command = $term->readline('> ');
$term->addhistory($command) if $command;
$command;
}
sub perl_symbol_display_match_list {
my($matches, $num_matches, $max_length) = @_;
map { $_ =~ s/^((\$#|[\@\$%&])?).*::(.+)/$3/; }(@{$matches});
$term->display_match_list($matches);
$term->forced_update_display;
}
sub attempt_perl_completion {
my ($text, $line, $start, $end) = @_;
$term->completion_matches($text, \&perl_symbol_completion_function);
}
use vars qw($i @matches $prefix);
sub perl_symbol_completion_function {
my($text, $state) = @_;
my %type = ('$' => 'SCALAR', '*' => 'SCALAR', '@' => 'ARRAY', '$#' => 'ARRAY', '%' => 'HASH', '&' => 'CODE');
if ($state) {
$i++;
} else {
my ($pre, $pkg, $sym);
$i = 0;
no strict qw(refs);
($prefix, $pre, $pkg) = ($text =~ m/^((\$#|[\@\$%&])?(.*::)?)/);
@matches = grep /::$/, $pkg ? keys %$pkg : keys %::;
$pkg = '::' unless $pkg;
@matches = (@matches, grep (/^\w+$/ && ($sym = $pkg . $_, defined *$sym{$type{$pre}}), keys %$pkg));
}
my $entry;
for (; $i <= $#matches; $i++) {
$entry = $prefix . $matches[$i];
return $entry if ($entry =~ /^\Q$text/);
}
undef;
}</syntaxhighlight>
=={{header|Phix}}==
Line 603 ⟶ 908:
watch.pike is the solution from [[Simple database#Pike]]. this solution demonstrates how to retrofit an application with a readline interface by inheriting the original and overriding specific functions.
<
inherit "watch.pike";
Line 668 ⟶ 973:
}
}
}</
Sample session:
Line 692 ⟶ 997:
> save
> quit
=={{header|Python}}==
Python readline interface is enabled by default in the interpreter REPL, and can be enabled in user code simply by importing the readline module
<syntaxhighlight lang="python">#!/usr/bin/env python3
#
# A simple readline demo that does nothing.
# Interactive line editing and history active
#
import readline
while True:
try:
print(input('> '))
except:
break
</syntaxhighlight>
=={{header|Racket}}==
Racket's has a readline interface which is not used by default due to its license. This includes the usual readline-style editing, and tab-completion for Racket bindings. It is possible to use it as a library, or as a REPL convenience (both uses described [http://docs.racket-lang.org/readline/ in the documentation]) -- but it is better to use [http://docs.racket-lang.org/xrepl/ xrepl] which provides an enhanced command-line REPL and includes the readline interaction.
=={{header|Raku}}==
(formerly Perl 6)
Raku has a built in REPL that can be initiated by running the Raku executable without any parameters. It is fairly basic on its own but here are bindings available in the Raku ecosystem for [https://tiswww.case.edu/php/chet/readline/rltop.html GNU Readline] and/or [https://github.com/antirez/linenoise Linenoise] either of which will automatically provide command history, tab completion and more advance command line editing capability if installed. They are not included in the Raku distribution directly. There are incompatible licensing requirements and providing hooks for third party tools allows for more customization options.
Linenoise is generally the preferred option unless you really want the emacs compatible command line editing key bindings. Readline is arguably more powerful but is somewhat fiddly to set up.
If you are not inclined to install Readline ''or'' Linenoise, the REPL also works fairly well with 3rd party tools like rlwrap.
=={{header|REXX}}==
Line 701 ⟶ 1,033:
<br>The HELP (or '''?'''), REDO, error checking, and abbreviations took up most of the program.
<br>"User" commands (subroutines) are identified with a leading period ('''.''') to make it easier to understand what's what.
<
trace off /*suppress echoing of non-zero retCodes*/
signal on syntax; signal on noValue /*handle REXX program errors. */
Line 829 ⟶ 1,161:
end /*select*/
return ccc
</syntaxhighlight>
This REXX program makes use of '''LINESIZE''' REXX program (or BIF) which is used to determine the screen width (or linesize) of the terminal (console).
<br>The '''LINESIZE.REX''' REXX program is included here ──► [[LINESIZE.REX]].<br>
Line 986 ⟶ 1,318:
<br>A history of the commands is navigated by the up- and down-keys. All commands are just echoed, except "quit" which exits.
<br>It uses the Ruby 2.3 method Hash#to_proc.
<
require "abbrev"
Line 995 ⟶ 1,327:
exit if buf.strip == "quit"
p buf
end</
=={{header|Sidef}}==
<
var term = %O<Term::ReadLine>.new('Example')
Line 1,013 ⟶ 1,345:
say "You inserted <<#{cmd}>>"
}</
=={{header|Wren}}==
{{trans|Go}}
<syntaxhighlight lang="wren">import "io" for Stdin, Stdout
class ReadLine {
static start {
__hist = []
System.print("Enter a command, type help for a listing.")
while (true) {
System.write(">")
Stdout.flush()
var cmd = Stdin.readLine().trim()
if (cmd == "exit") {
return
} else if (cmd == "hello") {
hello_
} else if (cmd == "hist") {
hist_
} else if (cmd == "help") {
help_
} else {
System.print("Unknown command, try again")
}
}
}
static hello_ {
System.print("Hello World!")
__hist.add("hello")
}
static hist_ {
if (__hist.count == 0) {
System.print("No history")
} else {
for (cmd in __hist) System.print(" - %(cmd)")
}
__hist.add("hist")
}
static help_ {
System.print("Available commands:")
System.print(" hello")
System.print(" hist")
System.print(" exit")
System.print(" help")
__hist.add("help")
}
}
ReadLine.start</syntaxhighlight>
{{out}}
Sample session (as Go):
<pre>
Enter a command, type help for a listing.
>hit
Unknown command, try again
>hist
No history
>help
Available commands:
hello
hist
exit
help
>hello
Hello World!
>hist
- hist
- help
- hello
>exit
</pre>
|