2017-10-12 17 views

Odpowiedz

1

to pytanie odpowiedział w niedawnym I pity the foo() blogu ...

Czy odwrotnej wyszukiwania w historii poleceń być używany wewnątrz REPL węzła?

Obecnie wydaje się, że nie jest to możliwe. Replikacja REPL węzła pozwala na utrwalenie historii w pliku, a następnie załadowanie go, ale nie pozwala na przeszukiwanie w odwrotnym kierunku.

Wygląda więc na to, że wyszukiwanie wstecznej historii nie jest obsługiwane przez REPL.

Można jednak zainstalować narzędzie rlwrap i uruchomić je na REPL-ie węzła, aby zapewnić podobną funkcjonalność. Witryna REPL documentation zawiera podstawowe instrukcje, które pomogą Ci rozpocząć pracę. Byłem trochę ciekawy, co dzieje się za kulisami, więc nieco więcej Googlingów pojawiło się w tej sekcji z Learning Node: Moving to the Server Side, która idzie bardziej szczegółowo na temat kompromisów związanych z używaniem rlwrap. Na przykład ...

Pomocne jako rlwrap jest to, że wciąż kończymy z undefined za każdym razem, gdy wpisujemy wyrażenie, które nie zwraca wartości. Możemy jednak dostosować to i inne funkcje, po prostu tworząc własny niestandardowy REPL, omówiony poniżej.

1

Widzę, że nagroda wkrótce się kończy ... czy mogę ją mieć? A co, gdybym ci powiedział:

Przejdź do sekcji Kod, jeśli znasz historię wyszukiwania i chciałbyś jej użyć jako alternatywy.

Czy znasz historię wyszukiwania firmy zsh? Jest to prawie jak wyszukiwanie wsteczne, z wyjątkiem faktu, że możesz rozpocząć wyszukiwanie po wpisaniu czegoś w wierszu poleceń i naciśnięciu klawisza strzałki up. Uważam, że jest to szybsza alternatywa niż wyszukiwanie wsteczne i częściej go wykorzystuję. Minusem (co moim zdaniem jest niewielkie) jest to, że nie możesz zaktualizować swojego zapytania oryginalnego po wyszukaniu, chyba że wrócisz do niego przez "powrót w dół".Na przykład:

historia (top-down)

foo 
bar 
foo-ish 
fubar 
... 

na swoim wierszu:

> fo 

prasowej up

> foo 

prasowej up

> foo-ish 

naciśnij down

> foo 

naciśnij down

> fo 

UWAGA: Jak najszybciej zmienić wynik wyszukiwania i naciśnij up znowu zmieniony tekst staje się nowy zapytania.

Kodeks

const PROMPT = '> '; 

// history search 
let input = ''; 
let searchInput = input; 
let searchResults = []; 
let searchResultIndex = 0; 
process.stdin.on('keypress', (_, key) => { 
    // update 'input' on changes, excluding history 
    if (input !== server.line && !['up', 'down'].includes(key.name)) { 
    input = server.line; 
    } 
    // search is initiated if a user presses the 'up' key after having inputted 
    if (input !== '' && (
    key.name === 'up' || 
    (key.name === 'down' && searchResultIndex > 0) 
)) { 
    // reset on fresh search or if user changed input during search 
    if (searchInput !== input) { 
     searchResultIndex = 0; 
     // first search result is always user's input 
     searchResults = [input, ...server.history.filter(item => item.includes(input))]; 
     searchInput = input; 
    } 
    const increment = key.name === 'up' ? 1 : -1; 
    searchResultIndex = Math.min(searchResultIndex + increment, searchResults.length - 1); 
    server.historyIndex = -1; 
    server.line = ''; 
    process.stdout.clearLine(); 
    process.stdout.cursorTo(0); 
    const result = searchResults[searchResultIndex]; 
    process.stdout.write(PROMPT + result); 
    server.cursor = result.length; 
    server.line = result; 
    } 
}); 

BONUS - Aby wdrożyć trwałe historia:

const HISTSIZE = 100; 

const server = repl.start({ 
    prompt: PROMPT, 
    historySize: HISTSIZE, 
    removeHistoryDuplicates: true, 
}); 

// load history or create file 
historyFile = path.join(path.dirname(require.main.filename), 
'.repl_history'); 
try { 
    fs.statSync(historyFile); 
    fs.readFileSync(historyFile, 'utf8') 
    .split('\n') 
    .filter(line => line.trim()) 
    .map(line => server.history.push(line)); 
} 
catch (e) { 
    console.log(e); 
    fs.closeSync(fs.openSync(historyFile, 'w')); 
} 

server.on('exit',() => { 
    // save history 
    fs.writeFileSync(historyFile, server.history.slice(0, HISTSIZE).join('\n')); 
    console.log('Thank you. Come again.'); 
    process.exit(); 
});