Commit e5384110 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Fixing d8's broken readline history.

Review URL: http://codereview.chromium.org/7885026

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9282 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 96de832c
// Copyright 2008 the V8 project authors. All rights reserved. // Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -72,6 +72,7 @@ bool ReadLineEditor::Open() { ...@@ -72,6 +72,7 @@ bool ReadLineEditor::Open() {
rl_completer_word_break_characters = kWordBreakCharacters; rl_completer_word_break_characters = kWordBreakCharacters;
rl_bind_key('\t', rl_complete); rl_bind_key('\t', rl_complete);
using_history(); using_history();
stifle_history(Shell::kMaxHistoryEntries);
return read_history(Shell::kHistoryFileName) == 0; return read_history(Shell::kHistoryFileName) == 0;
} }
...@@ -88,6 +89,18 @@ i::SmartArrayPointer<char> ReadLineEditor::Prompt(const char* prompt) { ...@@ -88,6 +89,18 @@ i::SmartArrayPointer<char> ReadLineEditor::Prompt(const char* prompt) {
void ReadLineEditor::AddHistory(const char* str) { void ReadLineEditor::AddHistory(const char* str) {
// Do not record empty input.
if (strlen(str) == 0) return;
// Remove duplicate history entry.
history_set_pos(history_length-1);
if (current_history()) {
do {
if (strcmp(current_history()->line, str) == 0) {
remove_history(where_history());
break;
}
} while (previous_history());
}
add_history(str); add_history(str);
} }
......
...@@ -70,6 +70,7 @@ namespace v8 { ...@@ -70,6 +70,7 @@ namespace v8 {
#ifndef V8_SHARED #ifndef V8_SHARED
LineEditor *LineEditor::first_ = NULL; LineEditor *LineEditor::first_ = NULL;
const char* Shell::kHistoryFileName = ".d8_history"; const char* Shell::kHistoryFileName = ".d8_history";
const int Shell::kMaxHistoryEntries = 1000;
LineEditor::LineEditor(Type type, const char* name) LineEditor::LineEditor(Type type, const char* name)
...@@ -117,6 +118,7 @@ CounterCollection Shell::local_counters_; ...@@ -117,6 +118,7 @@ CounterCollection Shell::local_counters_;
CounterCollection* Shell::counters_ = &local_counters_; CounterCollection* Shell::counters_ = &local_counters_;
i::Mutex* Shell::context_mutex_(i::OS::CreateMutex()); i::Mutex* Shell::context_mutex_(i::OS::CreateMutex());
Persistent<Context> Shell::utility_context_; Persistent<Context> Shell::utility_context_;
LineEditor* Shell::console = NULL;
#endif // V8_SHARED #endif // V8_SHARED
Persistent<Context> Shell::evaluation_context_; Persistent<Context> Shell::evaluation_context_;
...@@ -791,6 +793,7 @@ void Shell::Exit(int exit_code) { ...@@ -791,6 +793,7 @@ void Shell::Exit(int exit_code) {
#ifndef V8_SHARED #ifndef V8_SHARED
void Shell::OnExit() { void Shell::OnExit() {
if (console != NULL) console->Close();
if (i::FLAG_dump_counters) { if (i::FLAG_dump_counters) {
printf("+----------------------------------------+-------------+\n"); printf("+----------------------------------------+-------------+\n");
printf("| Name | Value |\n"); printf("| Name | Value |\n");
...@@ -895,20 +898,19 @@ void Shell::RunShell() { ...@@ -895,20 +898,19 @@ void Shell::RunShell() {
HandleScope outer_scope; HandleScope outer_scope;
Handle<String> name = String::New("(d8)"); Handle<String> name = String::New("(d8)");
#ifndef V8_SHARED #ifndef V8_SHARED
LineEditor* editor = LineEditor::Get(); console = LineEditor::Get();
printf("V8 version %s [console: %s]\n", V8::GetVersion(), editor->name()); printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name());
if (i::FLAG_debugger) { if (i::FLAG_debugger) {
printf("JavaScript debugger enabled\n"); printf("JavaScript debugger enabled\n");
} }
editor->Open(); console->Open();
while (true) { while (true) {
i::SmartArrayPointer<char> input = editor->Prompt(Shell::kPrompt); i::SmartArrayPointer<char> input = console->Prompt(Shell::kPrompt);
if (input.is_empty()) break; if (input.is_empty()) break;
editor->AddHistory(*input); console->AddHistory(*input);
HandleScope inner_scope; HandleScope inner_scope;
ExecuteString(String::New(*input), name, true, true); ExecuteString(String::New(*input), name, true, true);
} }
editor->Close();
#else #else
printf("V8 version %s [D8 light using shared library]\n", V8::GetVersion()); printf("V8 version %s [D8 light using shared library]\n", V8::GetVersion());
static const int kBufferSize = 256; static const int kBufferSize = 256;
......
...@@ -116,6 +116,29 @@ class CounterMap { ...@@ -116,6 +116,29 @@ class CounterMap {
#endif // V8_SHARED #endif // V8_SHARED
#ifndef V8_SHARED
class LineEditor {
public:
enum Type { DUMB = 0, READLINE = 1 };
LineEditor(Type type, const char* name);
virtual ~LineEditor() { }
virtual i::SmartArrayPointer<char> Prompt(const char* prompt) = 0;
virtual bool Open() { return true; }
virtual bool Close() { return true; }
virtual void AddHistory(const char* str) { }
const char* name() { return name_; }
static LineEditor* Get();
private:
Type type_;
const char* name_;
LineEditor* next_;
static LineEditor* first_;
};
#endif // V8_SHARED
class SourceGroup { class SourceGroup {
public: public:
SourceGroup() : SourceGroup() :
...@@ -313,6 +336,8 @@ class Shell : public i::AllStatic { ...@@ -313,6 +336,8 @@ class Shell : public i::AllStatic {
static void AddOSMethods(Handle<ObjectTemplate> os_template); static void AddOSMethods(Handle<ObjectTemplate> os_template);
#ifndef V8_SHARED #ifndef V8_SHARED
static const char* kHistoryFileName; static const char* kHistoryFileName;
static const int kMaxHistoryEntries;
static LineEditor* console;
#endif // V8_SHARED #endif // V8_SHARED
static const char* kPrompt; static const char* kPrompt;
static ShellOptions options; static ShellOptions options;
...@@ -343,29 +368,6 @@ class Shell : public i::AllStatic { ...@@ -343,29 +368,6 @@ class Shell : public i::AllStatic {
}; };
#ifndef V8_SHARED
class LineEditor {
public:
enum Type { DUMB = 0, READLINE = 1 };
LineEditor(Type type, const char* name);
virtual ~LineEditor() { }
virtual i::SmartArrayPointer<char> Prompt(const char* prompt) = 0;
virtual bool Open() { return true; }
virtual bool Close() { return true; }
virtual void AddHistory(const char* str) { }
const char* name() { return name_; }
static LineEditor* Get();
private:
Type type_;
const char* name_;
LineEditor* next_;
static LineEditor* first_;
};
#endif // V8_SHARED
} // namespace v8 } // namespace v8
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment