mirror of
https://github.com/tstack/lnav.git
synced 2024-09-11 13:05:51 +03:00
parent
80ef38227b
commit
6a90dd9bc2
3
NEWS
3
NEWS
@ -6,6 +6,9 @@ lnav v0.7.2:
|
||||
and write-csv-to commands will also write their output to the terminal
|
||||
when passed '-' as the file name. This mode can be useful for copying
|
||||
plain text lines to the clipboard.
|
||||
* (OS X) Text search strings are copied to the system's "find" clipboard.
|
||||
Also, when starting a new search, the current value in the "find"
|
||||
clipboard can be tab-completed.
|
||||
|
||||
lnav v0.7.1:
|
||||
Features:
|
||||
|
@ -36,6 +36,7 @@ set(diag_STAT_SRCS
|
||||
sqlite-extension-func.c
|
||||
statusview_curses.cc
|
||||
string-extension-functions.cc
|
||||
sysclip.cc
|
||||
pcrepp.cc
|
||||
piper_proc.cc
|
||||
sql_util.cc
|
||||
@ -87,6 +88,7 @@ set(diag_STAT_SRCS
|
||||
sequence_sink.hh
|
||||
status_controllers.hh
|
||||
strong_int.hh
|
||||
sysclip.hh
|
||||
term_extra.hh
|
||||
termios_guard.hh
|
||||
textfile_sub_source.hh
|
||||
|
@ -124,6 +124,7 @@ noinst_HEADERS = \
|
||||
statusview_curses.hh \
|
||||
strnatcmp.h \
|
||||
strong_int.hh \
|
||||
sysclip.hh \
|
||||
termios_guard.hh \
|
||||
term_extra.hh \
|
||||
textfile_sub_source.hh \
|
||||
@ -192,6 +193,7 @@ libdiag_a_SOURCES = \
|
||||
sql_util.cc \
|
||||
state-extension-functions.cc \
|
||||
strnatcmp.c \
|
||||
sysclip.cc \
|
||||
textview_curses.cc \
|
||||
time_fmts.cc \
|
||||
view_curses.cc \
|
||||
|
@ -130,14 +130,15 @@ am_libdiag_a_OBJECTS = ansi_scrubber.$(OBJEXT) bookmarks.$(OBJEXT) \
|
||||
string-extension-functions.$(OBJEXT) pcrepp.$(OBJEXT) \
|
||||
piper_proc.$(OBJEXT) sql_util.$(OBJEXT) \
|
||||
state-extension-functions.$(OBJEXT) strnatcmp.$(OBJEXT) \
|
||||
textview_curses.$(OBJEXT) time_fmts.$(OBJEXT) \
|
||||
view_curses.$(OBJEXT) vt52_curses.$(OBJEXT) \
|
||||
log_vtab_impl.$(OBJEXT) xterm_mouse.$(OBJEXT) yajlpp.$(OBJEXT) \
|
||||
yajl/yajl.$(OBJEXT) yajl/yajl_alloc.$(OBJEXT) \
|
||||
yajl/yajl_buf.$(OBJEXT) yajl/yajl_encode.$(OBJEXT) \
|
||||
yajl/yajl_gen.$(OBJEXT) yajl/yajl_lex.$(OBJEXT) \
|
||||
yajl/yajl_parser.$(OBJEXT) yajl/yajl_tree.$(OBJEXT) \
|
||||
yajl/yajl_version.$(OBJEXT) spookyhash/SpookyV2.$(OBJEXT)
|
||||
sysclip.$(OBJEXT) textview_curses.$(OBJEXT) \
|
||||
time_fmts.$(OBJEXT) view_curses.$(OBJEXT) \
|
||||
vt52_curses.$(OBJEXT) log_vtab_impl.$(OBJEXT) \
|
||||
xterm_mouse.$(OBJEXT) yajlpp.$(OBJEXT) yajl/yajl.$(OBJEXT) \
|
||||
yajl/yajl_alloc.$(OBJEXT) yajl/yajl_buf.$(OBJEXT) \
|
||||
yajl/yajl_encode.$(OBJEXT) yajl/yajl_gen.$(OBJEXT) \
|
||||
yajl/yajl_lex.$(OBJEXT) yajl/yajl_parser.$(OBJEXT) \
|
||||
yajl/yajl_tree.$(OBJEXT) yajl/yajl_version.$(OBJEXT) \
|
||||
spookyhash/SpookyV2.$(OBJEXT)
|
||||
libdiag_a_OBJECTS = $(am_libdiag_a_OBJECTS)
|
||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
|
||||
@ -456,6 +457,7 @@ noinst_HEADERS = \
|
||||
statusview_curses.hh \
|
||||
strnatcmp.h \
|
||||
strong_int.hh \
|
||||
sysclip.hh \
|
||||
termios_guard.hh \
|
||||
term_extra.hh \
|
||||
textfile_sub_source.hh \
|
||||
@ -524,6 +526,7 @@ libdiag_a_SOURCES = \
|
||||
sql_util.cc \
|
||||
state-extension-functions.cc \
|
||||
strnatcmp.c \
|
||||
sysclip.cc \
|
||||
textview_curses.cc \
|
||||
time_fmts.cc \
|
||||
view_curses.cc \
|
||||
@ -783,6 +786,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/statusview_curses.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string-extension-functions.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strnatcmp.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sysclip.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_override.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/textview_curses.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time_fmts.Po@am__quote@
|
||||
|
@ -221,6 +221,7 @@ throw (error)
|
||||
|
||||
/* Still need more space, try a realloc. */
|
||||
old = this->lb_buffer.release();
|
||||
this->lb_share_manager.invalidate_refs();
|
||||
tmp = (char *)realloc(old, new_max);
|
||||
if (tmp != NULL) {
|
||||
this->lb_buffer = tmp;
|
||||
@ -250,7 +251,6 @@ throw (error)
|
||||
* The request is outside the cached range, need to reload the
|
||||
* whole thing.
|
||||
*/
|
||||
this->lb_share_manager.invalidate_refs();
|
||||
prefill = 0;
|
||||
this->lb_buffer_size = 0;
|
||||
if ((this->lb_file_size != (size_t)-1) &&
|
||||
@ -284,6 +284,8 @@ throw (error)
|
||||
* Need more space, move any existing data to the front of the
|
||||
* buffer.
|
||||
*/
|
||||
this->lb_share_manager.invalidate_refs();
|
||||
|
||||
this->lb_buffer_size -= prefill;
|
||||
this->lb_file_offset += prefill;
|
||||
memmove(&this->lb_buffer[0],
|
||||
@ -295,8 +297,6 @@ throw (error)
|
||||
this->resize_buffer(this->lb_buffer_max +
|
||||
DEFAULT_LINE_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
this->lb_share_manager.invalidate_refs();
|
||||
}
|
||||
}
|
||||
|
||||
|
62
src/lnav.cc
62
src/lnav.cc
@ -110,6 +110,7 @@
|
||||
#include "lnav_config.hh"
|
||||
#include "sql_util.hh"
|
||||
#include "sqlite-extension-func.h"
|
||||
#include "sysclip.hh"
|
||||
#include "term_extra.hh"
|
||||
#include "log_data_helper.hh"
|
||||
#include "readline_highlighters.hh"
|
||||
@ -531,8 +532,28 @@ static void add_view_text_possibilities(
|
||||
readline_curses *rlc = lnav_data.ld_rl_view;
|
||||
|
||||
rlc->clear_possibilities(context, type);
|
||||
|
||||
{
|
||||
auto_mem<FILE> pfile(pclose);
|
||||
|
||||
pfile = open_clipboard(CT_FIND, CO_READ);
|
||||
if (pfile.in() != NULL) {
|
||||
char buffer[64];
|
||||
|
||||
if (fgets(buffer, sizeof(buffer), pfile) != NULL) {
|
||||
char *nl;
|
||||
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
if ((nl = strchr(buffer, '\n')) != NULL) {
|
||||
*nl = '\0';
|
||||
}
|
||||
rlc->add_possibility(context, type, std::string(buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (vis_line_t curr_line = tc->get_top();
|
||||
curr_line < tc->get_bottom();
|
||||
curr_line <= tc->get_bottom();
|
||||
++curr_line) {
|
||||
string line;
|
||||
|
||||
@ -1215,22 +1236,6 @@ static bool moveto_cluster(vis_line_t(bookmark_vector<vis_line_t>::*f) (
|
||||
return false;
|
||||
}
|
||||
|
||||
static void check_for_clipboard(FILE **pfile, const char *execstr)
|
||||
{
|
||||
if (execstr == NULL || pfile == NULL || *pfile != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*pfile = popen(execstr, "w")) != NULL && pclose(*pfile) == 0) {
|
||||
*pfile = popen(execstr, "w");
|
||||
}
|
||||
else {
|
||||
*pfile = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX For one, this code is kinda crappy. For two, we should probably link
|
||||
* directly with X so we don't need to have xclip installed and it'll work if
|
||||
* we're ssh'd into a box.
|
||||
@ -1242,17 +1247,13 @@ static void copy_to_xclip(void)
|
||||
bookmark_vector<vis_line_t> &bv =
|
||||
tc->get_bookmarks()[&textview_curses::BM_USER];
|
||||
bookmark_vector<vis_line_t>::iterator iter;
|
||||
FILE * pfile = NULL;
|
||||
auto_mem<FILE> pfile(pclose);
|
||||
int line_count = 0;
|
||||
string line;
|
||||
|
||||
/* XXX : Check if this is linux or MAC. Probably not the best solution but */
|
||||
/* better than traversing the PATH to stat for the binaries or trying to */
|
||||
/* forkexec. */
|
||||
check_for_clipboard(&pfile, "xclip -i > /dev/null 2>&1");
|
||||
check_for_clipboard(&pfile, "pbcopy > /dev/null 2>&1");
|
||||
pfile = open_clipboard(CT_GENERAL);
|
||||
|
||||
if (!pfile) {
|
||||
if (!pfile.in()) {
|
||||
flash();
|
||||
lnav_data.ld_rl_view->set_value(
|
||||
"error: Unable to copy to clipboard. "
|
||||
@ -1266,9 +1267,6 @@ static void copy_to_xclip(void)
|
||||
line_count += 1;
|
||||
}
|
||||
|
||||
pclose(pfile);
|
||||
pfile = NULL;
|
||||
|
||||
char buffer[128];
|
||||
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
@ -2779,6 +2777,12 @@ static void rl_callback(void *dummy, readline_curses *rc)
|
||||
case LNM_CAPTURE:
|
||||
rl_search_internal(dummy, rc, true);
|
||||
if (rc->get_value().size() > 0) {
|
||||
auto_mem<FILE> pfile(pclose);
|
||||
|
||||
pfile = open_clipboard(CT_FIND);
|
||||
if (pfile.in() != NULL) {
|
||||
fprintf(pfile, "%s", rc->get_value().c_str());
|
||||
}
|
||||
lnav_data.ld_view_stack.top()->set_follow_search(false);
|
||||
rc->set_value("search: " + rc->get_value());
|
||||
rc->set_alt_value(HELP_MSG_2(
|
||||
@ -2864,7 +2868,7 @@ static void rl_display_next(void *dummy, readline_curses *rc)
|
||||
static void usage(void)
|
||||
{
|
||||
const char *usage_msg =
|
||||
"usage: %s [-hVsar] [logfile1 logfile2 ...]\n"
|
||||
"usage: %s [options] [logfile1 logfile2 ...]\n"
|
||||
"\n"
|
||||
"A curses-based log file viewer that indexes log messages by type\n"
|
||||
"and time to make it easier to navigate through files quickly.\n"
|
||||
@ -2901,7 +2905,7 @@ static void usage(void)
|
||||
"\n"
|
||||
"Examples:\n"
|
||||
" To load and follow the syslog file:\n"
|
||||
" $ lnav -s\n"
|
||||
" $ lnav\n"
|
||||
"\n"
|
||||
" To load all of the files in /var/log:\n"
|
||||
" $ lnav /var/log\n"
|
||||
|
80
src/sysclip.cc
Normal file
80
src/sysclip.cc
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Timothy Stack
|
||||
*
|
||||
* 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 the name of Timothy Stack 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 REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 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 NOT 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.
|
||||
*
|
||||
* @file sysclip.cc
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lnav_log.hh"
|
||||
#include "sysclip.hh"
|
||||
|
||||
struct clip_command {
|
||||
const char *cc_cmd[2];
|
||||
};
|
||||
|
||||
static clip_command *get_commands()
|
||||
{
|
||||
static clip_command OSX_CMDS[] = {
|
||||
{ { "pbcopy > /dev/null 2>&1",
|
||||
"pbpaste -Prefer txt 2>/dev/null", } },
|
||||
{ { "pbcopy -pboard find > /dev/null 2>&1",
|
||||
"pbpaste -pboard find -Prefer txt 2>/dev/null" } },
|
||||
};
|
||||
static clip_command X_CMDS[] = {
|
||||
{ { "xclip -i > /dev/null 2>&1",
|
||||
"xclip -o < /dev/null 2>/dev/null" } },
|
||||
{ { NULL, NULL } },
|
||||
};
|
||||
if (system("which pbcopy > /dev/null 2>&1") == 0) {
|
||||
return OSX_CMDS;
|
||||
}
|
||||
if (system("which xclip > /dev/null 2>&1") == 0) {
|
||||
return X_CMDS;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX For one, this code is kinda crappy. For two, we should probably link
|
||||
* directly with X so we don't need to have xclip installed and it'll work if
|
||||
* we're ssh'd into a box.
|
||||
*/
|
||||
FILE *open_clipboard(clip_type_t type, clip_op_t op)
|
||||
{
|
||||
const char *mode = op == CO_WRITE ? "w" : "r";
|
||||
clip_command *cc = get_commands();
|
||||
FILE *pfile = NULL;
|
||||
|
||||
if (cc != NULL) {
|
||||
pfile = popen(cc[type].cc_cmd[op], mode);
|
||||
}
|
||||
|
||||
return pfile;
|
||||
}
|
47
src/sysclip.hh
Normal file
47
src/sysclip.hh
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Timothy Stack
|
||||
*
|
||||
* 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 the name of Timothy Stack 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 REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 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 NOT 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.
|
||||
*
|
||||
* @file sysclip.hh
|
||||
*/
|
||||
|
||||
#ifndef __sysclip_hh
|
||||
#define __sysclip_hh
|
||||
|
||||
enum clip_type_t {
|
||||
CT_GENERAL,
|
||||
CT_FIND,
|
||||
};
|
||||
|
||||
enum clip_op_t {
|
||||
CO_WRITE,
|
||||
CO_READ,
|
||||
};
|
||||
|
||||
FILE *open_clipboard(clip_type_t type, clip_op_t op = CO_WRITE);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user