aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2014-03-15 14:00:18 -0700
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2014-03-15 14:00:18 -0700
commit2442ae60dba9e7120170fba7c0cb307a3609b375 (patch)
tree458f547d15fa25b80d60f1a19e9b76d802701e77
parent6c096191ba0b13c3396c4b130daf64f5a9f75267 (diff)
Remove old fish_pager source and implementation
-rw-r--r--Makefile.in25
-rw-r--r--complete.h7
-rw-r--r--fish.xcodeproj/project.pbxproj137
-rw-r--r--fish_pager.cpp1427
-rw-r--r--reader.cpp138
5 files changed, 2 insertions, 1732 deletions
diff --git a/Makefile.in b/Makefile.in
index ccd90833..8d18ce1d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -57,7 +57,6 @@ CXXFLAGS = @CXXFLAGS@ $(MACROS) $(EXTRA_CXXFLAGS)
LDFLAGS = @LDFLAGS@
LDFLAGS_FISH = ${LDFLAGS} @LIBS_FISH@ @LDFLAGS_FISH@
LDFLAGS_FISH_INDENT = ${LDFLAGS} @LIBS_FISH_INDENT@
-LDFLAGS_FISH_PAGER = ${LDFLAGS} @LIBS_FISH_PAGER@
LDFLAGS_FISHD = ${LDFLAGS} @LIBS_FISHD@
LDFLAGS_MIMEDB = ${LDFLAGS} @LIBS_MIMEDB@
@@ -107,15 +106,6 @@ BUILTIN_FILES := builtin_set.cpp builtin_commandline.cpp \
#
-# All objects that the system needs to build fish_pager
-#
-
-FISH_PAGER_OBJS := fish_pager.o output.o wutil.o \
- input_common.o env_universal.o env_universal_common.o common.o \
- print_help.o iothread.o color.o
-
-
-#
# All objects that the system needs to build fish_tests
#
@@ -192,7 +182,7 @@ FUNCTIONS_DIR_FILES := $(wildcard share/functions/*.fish)
# Programs to install
#
-PROGRAMS := fish mimedb fish_pager fishd fish_indent
+PROGRAMS := fish mimedb fishd fish_indent
#
# Manual pages to install
@@ -239,7 +229,7 @@ FISH-BUILD-VERSION-FILE: FORCE
-include FISH-BUILD-VERSION-FILE
CPPFLAGS += -DFISH_BUILD_VERSION=\"$(FISH_BUILD_VERSION)\"
.PHONY: FORCE
-env.o fish.o fish_indent.o fish_pager.o fishd.o mimedb.o: FISH-BUILD-VERSION-FILE
+env.o fish.o fish_indent.o fishd.o mimedb.o: FISH-BUILD-VERSION-FILE
#
@@ -700,14 +690,6 @@ fish: $(FISH_OBJS) fish.o
#
-# Build the fish_pager program.
-#
-
-fish_pager: $(FISH_PAGER_OBJS)
- $(CXX) $(CXXFLAGS) $(FISH_PAGER_OBJS) $(LDFLAGS_FISH_PAGER) -o $@
-
-
-#
# Build the fishd program.
#
@@ -863,9 +845,6 @@ fish.o: expand.h intern.h exec.h output.h screen.h history.h path.h input.h
fish.o: input_common.h
fish_indent.o: config.h fallback.h signal.h util.h common.h wutil.h
fish_indent.o: tokenizer.h print_help.h parser_keywords.h
-fish_pager.o: config.h signal.h fallback.h util.h wutil.h common.h complete.h
-fish_pager.o: output.h screen.h highlight.h env.h color.h input_common.h
-fish_pager.o: env_universal.h env_universal_common.h print_help.h
fish_tests.o: config.h signal.h fallback.h util.h common.h proc.h io.h
fish_tests.o: parse_tree.h tokenizer.h parse_constants.h reader.h complete.h
fish_tests.o: highlight.h env.h color.h builtin.h function.h event.h
diff --git a/complete.h b/complete.h
index be10d17b..10f351fe 100644
--- a/complete.h
+++ b/complete.h
@@ -56,13 +56,6 @@
#define COMPLETE_SEP_STR L"\004"
/**
- * Separator between completion items in fish_pager. This is used for
- * completion grouping, e.g. when putting completions with the same
- * descriptions on the same line.
- */
-#define COMPLETE_ITEM_SEP L'\uf500'
-
-/**
* Character that separates the completion and description on
* programmable completions
*/
diff --git a/fish.xcodeproj/project.pbxproj b/fish.xcodeproj/project.pbxproj
index d2e9d2bc..deb3a107 100644
--- a/fish.xcodeproj/project.pbxproj
+++ b/fish.xcodeproj/project.pbxproj
@@ -18,7 +18,6 @@
dependencies = (
D07D265715E33B86009E43F6 /* PBXTargetDependency */,
D07D265915E33B86009E43F6 /* PBXTargetDependency */,
- D07D265B15E33B86009E43F6 /* PBXTargetDependency */,
D07D265D15E33B86009E43F6 /* PBXTargetDependency */,
D0A56500168D257900AF6161 /* PBXTargetDependency */,
);
@@ -49,7 +48,6 @@
dependencies = (
D0F01A1315AA36280034B3B1 /* PBXTargetDependency */,
D0F01A1515AA362E0034B3B1 /* PBXTargetDependency */,
- D0F01A1915AA36310034B3B1 /* PBXTargetDependency */,
D0F01A1715AA36300034B3B1 /* PBXTargetDependency */,
D0A564EF168D09C000AF6161 /* PBXTargetDependency */,
);
@@ -172,24 +170,11 @@
D0D02ADB159864C2008E62BD /* tokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855D13B3ACEE0099B651 /* tokenizer.cpp */; };
D0D02ADC159864D5008E62BD /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D02A8C15983CFA008E62BD /* libncurses.dylib */; };
D0D02ADD159864D7008E62BD /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D02A8A15983CDF008E62BD /* libiconv.dylib */; };
- D0D02AEA15986549008E62BD /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D02A8C15983CFA008E62BD /* libncurses.dylib */; };
- D0D02AEB1598654C008E62BD /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D02A8A15983CDF008E62BD /* libiconv.dylib */; };
- D0D1CD6C15B7451900F03988 /* fish_pager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854013B3ACEE0099B651 /* fish_pager.cpp */; };
- D0D1CD6D15B7452100F03988 /* output.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855113B3ACEE0099B651 /* output.cpp */; };
- D0D1CD6E15B7452600F03988 /* wutil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0856113B3ACEE0099B651 /* wutil.cpp */; };
- D0D1CD6F15B7452D00F03988 /* input_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854913B3ACEE0099B651 /* input_common.cpp */; };
- D0D1CD7015B7453300F03988 /* env_universal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853913B3ACEE0099B651 /* env_universal.cpp */; };
- D0D1CD7115B7453700F03988 /* env_universal_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853813B3ACEE0099B651 /* env_universal_common.cpp */; };
- D0D1CD7215B7454A00F03988 /* print_help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855613B3ACEE0099B651 /* print_help.cpp */; };
- D0D1CD7315B7455200F03988 /* color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0B6B0FE14E88BA400AD6C10 /* color.cpp */; };
- D0D1CD7415B7456000F03988 /* iothread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854D13B3ACEE0099B651 /* iothread.cpp */; };
- D0D1CD7515B7458B00F03988 /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853613B3ACEE0099B651 /* common.cpp */; };
D0D2694915983772005D9B9C /* function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854413B3ACEE0099B651 /* function.cpp */; };
D0D2694A15983779005D9B9C /* builtin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853513B3ACEE0099B651 /* builtin.cpp */; };
D0F019F115A977140034B3B1 /* fish in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0D2693C159835CA005D9B9C /* fish */; };
D0F019F215A977270034B3B1 /* fishd in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0D02ABC15985EF9008E62BD /* fishd */; };
D0F019F315A977290034B3B1 /* fish_indent in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0D02AD01598642A008E62BD /* fish_indent */; };
- D0F019F415A9772C0034B3B1 /* fish_pager in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0D02AE415986537008E62BD /* fish_pager */; };
D0F019F815A977AB0034B3B1 /* config.fish in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0CBD580159EE48F0024809C /* config.fish */; };
D0F019FD15A977CA0034B3B1 /* config.fish in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0C4FD9415A7D7EE00212EF1 /* config.fish */; };
D0F01A0315A978910034B3B1 /* osx_fish_launcher.m in Sources */ = {isa = PBXBuildFile; fileRef = D0D02AFA159871B2008E62BD /* osx_fish_launcher.m */; };
@@ -219,13 +204,6 @@
remoteGlobalIDString = D0D02ABB15985EF9008E62BD;
remoteInfo = fishd;
};
- D07D265C15E33B86009E43F6 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = D0A084F213B3AC130099B651 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = D0D02AE315986537008E62BD;
- remoteInfo = fish_pager;
- };
D07D265E15E33B86009E43F6 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D0A084F213B3AC130099B651 /* Project object */;
@@ -268,13 +246,6 @@
remoteGlobalIDString = D0D02ACF1598642A008E62BD;
remoteInfo = fish_indent;
};
- D0F01A1815AA36310034B3B1 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = D0A084F213B3AC130099B651 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = D0D02AE315986537008E62BD;
- remoteInfo = fish_pager;
- };
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -355,7 +326,6 @@
D0F019F115A977140034B3B1 /* fish in CopyFiles */,
D0F019F215A977270034B3B1 /* fishd in CopyFiles */,
D0F019F315A977290034B3B1 /* fish_indent in CopyFiles */,
- D0F019F415A9772C0034B3B1 /* fish_pager in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -458,7 +428,6 @@
D0A0853D13B3ACEE0099B651 /* expand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = expand.cpp; sourceTree = "<group>"; };
D0A0853E13B3ACEE0099B651 /* fallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fallback.cpp; sourceTree = "<group>"; };
D0A0853F13B3ACEE0099B651 /* fish_indent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fish_indent.cpp; sourceTree = "<group>"; };
- D0A0854013B3ACEE0099B651 /* fish_pager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fish_pager.cpp; sourceTree = "<group>"; };
D0A0854113B3ACEE0099B651 /* fish_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fish_tests.cpp; sourceTree = "<group>"; };
D0A0854213B3ACEE0099B651 /* fish.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fish.cpp; sourceTree = "<group>"; };
D0A0854313B3ACEE0099B651 /* fishd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fishd.cpp; sourceTree = "<group>"; };
@@ -516,7 +485,6 @@
D0D02AA915985C0C008E62BD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = osx/Info.plist; sourceTree = "<group>"; };
D0D02ABC15985EF9008E62BD /* fishd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fishd; sourceTree = BUILT_PRODUCTS_DIR; };
D0D02AD01598642A008E62BD /* fish_indent */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fish_indent; sourceTree = BUILT_PRODUCTS_DIR; };
- D0D02AE415986537008E62BD /* fish_pager */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fish_pager; sourceTree = BUILT_PRODUCTS_DIR; };
D0D02AFA159871B2008E62BD /* osx_fish_launcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = osx_fish_launcher.m; path = osx/osx_fish_launcher.m; sourceTree = "<group>"; };
D0D2693C159835CA005D9B9C /* fish */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fish; sourceTree = BUILT_PRODUCTS_DIR; };
D0D9B2B318555D92001AE279 /* parse_constants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = parse_constants.h; sourceTree = "<group>"; };
@@ -554,15 +522,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- D0D02AE115986537008E62BD /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- D0D02AEA15986549008E62BD /* libncurses.dylib in Frameworks */,
- D0D02AEB1598654C008E62BD /* libiconv.dylib in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
D0D26939159835CA005D9B9C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -676,7 +635,6 @@
D0A0850E13B3ACEE0099B651 /* function.h */,
D0A0854413B3ACEE0099B651 /* function.cpp */,
D0A0853F13B3ACEE0099B651 /* fish_indent.cpp */,
- D0A0854013B3ACEE0099B651 /* fish_pager.cpp */,
D0A0854113B3ACEE0099B651 /* fish_tests.cpp */,
D0A0854213B3ACEE0099B651 /* fish.cpp */,
D0A0854313B3ACEE0099B651 /* fishd.cpp */,
@@ -789,7 +747,6 @@
D0D02A9A15985A75008E62BD /* fish.app */,
D0D02ABC15985EF9008E62BD /* fishd */,
D0D02AD01598642A008E62BD /* fish_indent */,
- D0D02AE415986537008E62BD /* fish_pager */,
D08A328D17B4455100F3A533 /* fish_tests */,
);
name = Products;
@@ -890,22 +847,6 @@
productReference = D0D02AD01598642A008E62BD /* fish_indent */;
productType = "com.apple.product-type.tool";
};
- D0D02AE315986537008E62BD /* fish_pager */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = D0D02AE715986537008E62BD /* Build configuration list for PBXNativeTarget "fish_pager" */;
- buildPhases = (
- D0D02AE015986537008E62BD /* Sources */,
- D0D02AE115986537008E62BD /* Frameworks */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = fish_pager;
- productName = fish_pager;
- productReference = D0D02AE415986537008E62BD /* fish_pager */;
- productType = "com.apple.product-type.tool";
- };
D0D2693B159835CA005D9B9C /* fish_shell */ = {
isa = PBXNativeTarget;
buildConfigurationList = D0D26943159835CA005D9B9C /* Build configuration list for PBXNativeTarget "fish_shell" */;
@@ -948,7 +889,6 @@
D0D2693B159835CA005D9B9C /* fish_shell */,
D0D02ABB15985EF9008E62BD /* fishd */,
D0D02ACF1598642A008E62BD /* fish_indent */,
- D0D02AE315986537008E62BD /* fish_pager */,
D08A328C17B4455100F3A533 /* fish_tests */,
D0A564E6168CFDD800AF6161 /* man_pages */,
D0A084F713B3AC130099B651 /* Makefile */,
@@ -1201,23 +1141,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- D0D02AE015986537008E62BD /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- D0D1CD6C15B7451900F03988 /* fish_pager.cpp in Sources */,
- D0D1CD6D15B7452100F03988 /* output.cpp in Sources */,
- D0D1CD6E15B7452600F03988 /* wutil.cpp in Sources */,
- D0D1CD6F15B7452D00F03988 /* input_common.cpp in Sources */,
- D0D1CD7015B7453300F03988 /* env_universal.cpp in Sources */,
- D0D1CD7115B7453700F03988 /* env_universal_common.cpp in Sources */,
- D0D1CD7315B7455200F03988 /* color.cpp in Sources */,
- D0D1CD7515B7458B00F03988 /* common.cpp in Sources */,
- D0D1CD7215B7454A00F03988 /* print_help.cpp in Sources */,
- D0D1CD7415B7456000F03988 /* iothread.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
D0D26938159835CA005D9B9C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -1292,11 +1215,6 @@
target = D0D02ABB15985EF9008E62BD /* fishd */;
targetProxy = D07D265A15E33B86009E43F6 /* PBXContainerItemProxy */;
};
- D07D265B15E33B86009E43F6 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = D0D02AE315986537008E62BD /* fish_pager */;
- targetProxy = D07D265C15E33B86009E43F6 /* PBXContainerItemProxy */;
- };
D07D265D15E33B86009E43F6 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D0D02ACF1598642A008E62BD /* fish_indent */;
@@ -1327,11 +1245,6 @@
target = D0D02ACF1598642A008E62BD /* fish_indent */;
targetProxy = D0F01A1615AA36300034B3B1 /* PBXContainerItemProxy */;
};
- D0F01A1915AA36310034B3B1 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = D0D02AE315986537008E62BD /* fish_pager */;
- targetProxy = D0F01A1815AA36310034B3B1 /* PBXContainerItemProxy */;
- };
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
@@ -1435,18 +1348,6 @@
};
name = "Release_C++11";
};
- D007FDE117136EAA00A52BE6 /* Release_C++11 */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- COPY_PHASE_STRIP = YES;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- GCC_ENABLE_OBJC_EXCEPTIONS = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- PRODUCT_NAME = "$(TARGET_NAME)";
- };
- name = "Release_C++11";
- };
D007FDE217136EAA00A52BE6 /* Release_C++11 */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -1743,34 +1644,6 @@
};
name = Release;
};
- D0D02AE815986537008E62BD /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- COPY_PHASE_STRIP = NO;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_OBJC_EXCEPTIONS = YES;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- PRODUCT_NAME = "$(TARGET_NAME)";
- };
- name = Debug;
- };
- D0D02AE915986537008E62BD /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- COPY_PHASE_STRIP = YES;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- GCC_ENABLE_OBJC_EXCEPTIONS = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- PRODUCT_NAME = "$(TARGET_NAME)";
- };
- name = Release;
- };
D0D26944159835CA005D9B9C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -1898,16 +1771,6 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- D0D02AE715986537008E62BD /* Build configuration list for PBXNativeTarget "fish_pager" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- D0D02AE815986537008E62BD /* Debug */,
- D0D02AE915986537008E62BD /* Release */,
- D007FDE117136EAA00A52BE6 /* Release_C++11 */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
D0D26943159835CA005D9B9C /* Build configuration list for PBXNativeTarget "fish_shell" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/fish_pager.cpp b/fish_pager.cpp
deleted file mode 100644
index f640e995..00000000
--- a/fish_pager.cpp
+++ /dev/null
@@ -1,1427 +0,0 @@
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <wchar.h>
-#include <unistd.h>
-#include <termios.h>
-#include <string.h>
-#include <map>
-#include <algorithm>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <dirent.h>
-#include <fcntl.h>
-
-#include <locale.h>
-
-#if HAVE_NCURSES_H
-#include <ncurses.h>
-#else
-#include <curses.h>
-#endif
-
-#if HAVE_TERM_H
-#include <term.h>
-#elif HAVE_NCURSES_TERM_H
-#include <ncurses/term.h>
-#endif
-
-#include <signal.h>
-
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-
-#include <errno.h>
-#include <vector>
-
-#include "fallback.h"
-#include "util.h"
-
-#include "wutil.h"
-#include "common.h"
-#include "complete.h"
-#include "output.h"
-#include "input_common.h"
-#include "env_universal.h"
-#include "print_help.h"
-
-enum
-{
- LINE_UP = R_NULL+1,
- LINE_DOWN,
- PAGE_UP,
- PAGE_DOWN
-}
-;
-
-
-enum
-{
- HIGHLIGHT_PAGER_PREFIX,
- HIGHLIGHT_PAGER_COMPLETION,
- HIGHLIGHT_PAGER_DESCRIPTION,
- HIGHLIGHT_PAGER_PROGRESS,
- HIGHLIGHT_PAGER_SECONDARY
-}
-;
-
-enum
-{
- /*
- Returnd by the pager if no more displaying is needed
- */
- PAGER_DONE,
- /*
- Returned by the pager if the completions would not fit in the specified number of columns
- */
- PAGER_RETRY,
- /*
- Returned by the pager if the terminal changes size
- */
- PAGER_RESIZE
-}
-;
-
-/**
- The minimum width (in characters) the terminal may have for fish_pager to not refuse showing the completions
-*/
-#define PAGER_MIN_WIDTH 16
-
-/**
- The maximum number of columns of completion to attempt to fit onto the screen
-*/
-#define PAGER_MAX_COLS 6
-
-/**
- The string describing the single-character options accepted by fish_pager
-*/
-#define GETOPT_STRING "c:hr:qvp:"
-
-/**
- Error to use when given an invalid file descriptor for reading completions or writing output
-*/
-#define ERR_NOT_FD _( L"%ls: Argument '%s' is not a valid file descriptor\n" )
-
-/**
- This struct should be continually updated by signals as the term
- resizes, and as such always contain the correct current size.
-*/
-static struct winsize termsize;
-
-/**
- The termios modes the terminal had when the program started. These
- should be restored on exit
-*/
-static struct termios saved_modes;
-
-/**
- This flag is set to 1 of we have sent the enter_ca_mode terminfo
- sequence to save the previous terminal contents.
-*/
-static int is_ca_mode = 0;
-
-/**
- This buffer is used to buffer the output of the pager to improve
- screen redraw performance bu cutting down the number of write()
- calls to only one.
-*/
-static std::vector<char> pager_buffer;
-
-/**
- The environment variables used to specify the color of different
- tokens.
-*/
-static const wchar_t *hightlight_var[] =
-{
- L"fish_pager_color_prefix",
- L"fish_pager_color_completion",
- L"fish_pager_color_description",
- L"fish_pager_color_progress",
- L"fish_pager_color_secondary"
-}
-;
-
-/**
- This string contains the text that should be sent back to the calling program
-*/
-static wcstring out_buff;
-/**
- This is the file to which the output text should be sent. It is really a pipe.
-*/
-static FILE *out_file;
-
-/**
- Data structure describing one or a group of related completions
-*/
-struct comp_t
-{
- /**
- The list of all completin strings this entry applies to
- */
- wcstring_list_t comp;
- /**
- The description
- */
- wcstring desc;
- /**
- On-screen width of the completion string
- */
- int comp_width;
- /**
- On-screen width of the description information
- */
- int desc_width;
- /**
- Preffered total width
- */
- int pref_width;
- /**
- Minimum acceptable width
- */
- int min_width;
-};
-
-/**
- This function translates from a highlight code to a specific color
- by check invironement variables
-*/
-static rgb_color_t get_color(int highlight)
-{
- const wchar_t *val;
-
- if (highlight < 0)
- return rgb_color_t::normal();
- if (highlight >= (5))
- return rgb_color_t::normal();
-
- val = wgetenv(hightlight_var[highlight]);
-
- if (!val)
- {
- val = env_universal_get(hightlight_var[highlight]);
- }
-
- if (!val)
- {
- return rgb_color_t::normal();
- }
-
- return parse_color(val, false);
-}
-
-/**
- This function calculates the minimum width for each completion
- entry in the specified array_list. This width depends on the
- terminal size, so this function should be called when the terminal
- changes size.
-*/
-static void recalc_width(std::vector<comp_t *> &lst, const wchar_t *prefix)
-{
- for (size_t i=0; i<lst.size(); i++)
- {
- comp_t *c = lst.at(i);
-
- c->min_width = mini(c->desc_width, maxi(0,termsize.ws_col/3 - 2)) +
- mini(c->desc_width, maxi(0,termsize.ws_col/5 - 4)) +4;
- }
-
-}
-
-/**
- Test if the specified character sequence has been entered on the
- keyboard
-*/
-static int try_sequence(const char *seq)
-{
- int j, k;
- wint_t c=0;
-
- for (j=0;
- seq[j] != '\0' && seq[j] == (c=input_common_readch(j>0));
- j++)
- ;
-
- if (seq[j] == '\0')
- {
- return 1;
- }
- else
- {
- input_common_unreadch(c);
- for (k=j-1; k>=0; k--)
- input_common_unreadch(seq[k]);
- }
- return 0;
-}
-
-/**
- Read a character from keyboard
-*/
-static wint_t readch()
-{
- struct mapping
- {
- const char *seq;
- wint_t bnd;
- }
- ;
-
- struct mapping m[]=
- {
- {
- "\x1b[A", LINE_UP
- }
- ,
- {
- key_up, LINE_UP
- }
- ,
- {
- "\x1b[B", LINE_DOWN
- }
- ,
- {
- key_down, LINE_DOWN
- }
- ,
- {
- key_ppage, PAGE_UP
- }
- ,
- {
- key_npage, PAGE_DOWN
- }
- ,
- {
- " ", PAGE_DOWN
- }
- ,
- {
- "\t", PAGE_DOWN
- }
- ,
- {
- 0, 0
- }
-
- }
- ;
- int i;
-
- for (i=0; m[i].bnd; i++)
- {
- if (!m[i].seq)
- {
- continue;
- }
-
- if (try_sequence(m[i].seq))
- return m[i].bnd;
- }
- return input_common_readch(0);
-}
-
-/**
- Write specified character to the output buffer \c pager_buffer
-*/
-static int pager_buffered_writer(char c)
-{
- pager_buffer.push_back(c);
- return 0;
-}
-
-/**
- Flush \c pager_buffer to stdout
-*/
-static void pager_flush()
-{
- if (! pager_buffer.empty())
- {
- write_loop(1, & pager_buffer.at(0), pager_buffer.size() * sizeof(char));
- pager_buffer.clear();
- }
-}
-
-/**
- Print the specified string, but use at most the specified amount of
- space. If the whole string can't be fitted, ellipsize it.
-
- \param str the string to print
- \param max the maximum space that may be used for printing
- \param has_more if this flag is true, this is not the entire string, and the string should be ellisiszed even if the string fits but takes up the whole space.
-*/
-static int print_max(const wchar_t *str, int max, int has_more)
-{
- int i;
- int written = 0;
- for (i=0; str[i]; i++)
- {
-
- if (written + wcwidth(str[i]) > max)
- break;
- if ((written + wcwidth(str[i]) == max) && (has_more || str[i+1]))
- {
- writech(ellipsis_char);
- written += wcwidth(ellipsis_char);
- break;
- }
-
- writech(str[i]);
- written+= wcwidth(str[i]);
- }
- return written;
-}
-
-/**
- Print the specified item using at the specified amount of space
-*/
-static void completion_print_item(const wchar_t *prefix, comp_t *c, int width, bool secondary)
-{
- int comp_width=0, desc_width=0;
- int written=0;
-
- if (c->pref_width <= width)
- {
- /*
- The entry fits, we give it as much space as it wants
- */
- comp_width = c->comp_width;
- desc_width = c->desc_width;
- }
- else
- {
- /*
- The completion and description won't fit on the
- allocated space. Give a maximum of 2/3 of the
- space to the completion, and whatever is left to
- the description.
- */
- int desc_all = c->desc_width?c->desc_width+4:0;
-
- comp_width = maxi(mini(c->comp_width,
- 2*(width-4)/3),
- width - desc_all);
- if (c->desc_width)
- desc_width = width-comp_width-4;
- else
- c->desc_width=0;
-
- }
-
- rgb_color_t bg = secondary ? get_color(HIGHLIGHT_PAGER_SECONDARY) : rgb_color_t::normal();
- for (size_t i=0; i<c->comp.size(); i++)
- {
- const wcstring &comp = c->comp.at(i);
- if (i != 0)
- written += print_max(L" ", comp_width - written, 2);
- set_color(get_color(HIGHLIGHT_PAGER_PREFIX), bg);
- written += print_max(prefix, comp_width - written, comp.empty()?0:1);
- set_color(get_color(HIGHLIGHT_PAGER_COMPLETION), bg);
- written += print_max(comp.c_str(), comp_width - written, i!=(c->comp.size()-1));
- }
-
-
- if (desc_width)
- {
- while (written < (width-desc_width-2))
- {
- written++;
- writech(L' ');
- }
- set_color(get_color(HIGHLIGHT_PAGER_DESCRIPTION), bg);
- written += print_max(L"(", 1, 0);
- written += print_max(c->desc.c_str(), desc_width, 0);
- written += print_max(L")", 1, 0);
- }
- else
- {
- while (written < width)
- {
- written++;
- writech(L' ');
- }
- }
- if (secondary)
- set_color(rgb_color_t::normal(), rgb_color_t::normal());
-}
-
-/**
- Print the specified part of the completion list, using the
- specified column offsets and quoting style.
-
- \param l The list of completions to print
- \param cols number of columns to print in
- \param width An array specifying the width of each column
- \param row_start The first row to print
- \param row_stop the row after the last row to print
- \param prefix The string to print before each completion
- \param is_quoted Whether to print the completions are in a quoted environment
-*/
-
-static void completion_print(int cols,
- int *width,
- int row_start,
- int row_stop,
- const wchar_t *prefix,
- int is_quoted,
- const std::vector<comp_t *> &lst)
-{
-
- size_t rows = (lst.size()-1)/cols+1;
- size_t i, j;
-
- for (i = row_start; i<row_stop; i++)
- {
- for (j = 0; j < cols; j++)
- {
- comp_t *el;
-
- int is_last = (j==(cols-1));
-
- if (lst.size() <= j*rows + i)
- continue;
-
- el = lst.at(j*rows + i);
-
- completion_print_item(prefix, el, width[j] - (is_last?0:2), i%2);
-
- if (!is_last)
- writestr(L" ");
- }
- writech(L'\n');
- }
-}
-
-
-/**
- Try to print the list of completions l with the prefix prefix using
- cols as the number of columns. Return 1 if the completion list was
- printed, 0 if the terminal is to narrow for the specified number of
- columns. Always succeeds if cols is 1.
-
- If all the elements do not fit on the screen at once, make the list
- scrollable using the up, down and space keys to move. The list will
- exit when any other key is pressed.
-
- \param cols the number of columns to try to fit onto the screen
- \param prefix the character string to prefix each completion with
- \param is_quoted whether the completions should be quoted
- \param l the list of completions
-
- \return one of PAGER_RETRY, PAGER_DONE and PAGER_RESIZE
-*/
-
-static int completion_try_print(int cols,
- const wchar_t *prefix,
- int is_quoted,
- std::vector<comp_t *> &lst)
-{
- /*
- The calculated preferred width of each column
- */
- int pref_width[PAGER_MAX_COLS];
- /*
- The calculated minimum width of each column
- */
- int min_width[PAGER_MAX_COLS];
- /*
- If the list can be printed with this width, width will contain the width of each column
- */
- int *width=pref_width;
- /*
- Set to one if the list should be printed at this width
- */
- int print=0;
-
- long i, j;
-
- int rows = (int)((lst.size()-1)/cols+1);
-
- int pref_tot_width=0;
- int min_tot_width = 0;
- int res=PAGER_RETRY;
- /*
- Skip completions on tiny terminals
- */
-
- if (termsize.ws_col < PAGER_MIN_WIDTH)
- return PAGER_DONE;
-
- memset(pref_width, 0, sizeof(pref_width));
- memset(min_width, 0, sizeof(min_width));
-
- /* Calculate how wide the list would be */
- for (j = 0; j < cols; j++)
- {
- for (i = 0; i<rows; i++)
- {
- int pref,min;
- comp_t *c;
- if (lst.size() <= j*rows + i)
- continue;
-
- c = lst.at(j*rows + i);
- pref = c->pref_width;
- min = c->min_width;
-
- if (j != cols-1)
- {
- pref += 2;
- min += 2;
- }
- min_width[j] = maxi(min_width[j],
- min);
- pref_width[j] = maxi(pref_width[j],
- pref);
- }
- min_tot_width += min_width[j];
- pref_tot_width += pref_width[j];
- }
- /*
- Force fit if one column
- */
- if (cols == 1)
- {
- if (pref_tot_width > termsize.ws_col)
- {
- pref_width[0] = termsize.ws_col;
- }
- width = pref_width;
- print=1;
- }
- else if (pref_tot_width <= termsize.ws_col)
- {
- /* Terminal is wide enough. Print the list! */
- width = pref_width;
- print=1;
- }
- else
- {
- long next_rows = (lst.size()-1)/(cols-1)+1;
- /* fwprintf( stderr,
- L"cols %d, min_tot %d, term %d, rows=%d, nextrows %d, termrows %d, diff %d\n",
- cols,
- min_tot_width, termsize.ws_col,
- rows, next_rows, termsize.ws_row,
- pref_tot_width-termsize.ws_col );
- */
- if (min_tot_width < termsize.ws_col &&
- (((rows < termsize.ws_row) && (next_rows >= termsize.ws_row)) ||
- (pref_tot_width-termsize.ws_col< 4 && cols < 3)))
- {
- /*
- Terminal almost wide enough, or squeezing makes the
- whole list fit on-screen.
-
- This part of the code is really important. People hate
- having to scroll through the completion list. In cases
- where there are a huge number of completions, it can't
- be helped, but it is not uncommon for the completions to
- _almost_ fit on one screen. In those cases, it is almost
- always desirable to 'squeeze' the completions into a
- single page.
-
- If we are using N columns and can get everything to
- fit using squeezing, but everything would also fit
- using N-1 columns, don't try.
- */
-
- int tot_width = min_tot_width;
- width = min_width;
-
- while (tot_width < termsize.ws_col)
- {
- for (i=0; (i<cols) && (tot_width < termsize.ws_col); i++)
- {
- if (width[i] < pref_width[i])
- {
- width[i]++;
- tot_width++;
- }
- }
- }
- print=1;
- }
- }
-
- if (print)
- {
- res=PAGER_DONE;
- if (rows < termsize.ws_row)
- {
- /* List fits on screen. Print it and leave */
- if (is_ca_mode)
- {
- is_ca_mode = 0;
- writembs(exit_ca_mode);
- }
-
- completion_print(cols, width, 0, rows, prefix, is_quoted, lst);
- pager_flush();
- }
- else
- {
- int npos, pos = 0;
- int do_loop = 1;
-
- /*
- Enter ca_mode, which means that the terminal
- content will be restored to the current
- state on exit.
- */
- if (enter_ca_mode && exit_ca_mode)
- {
- is_ca_mode=1;
- writembs(enter_ca_mode);
- }
-
-
- completion_print(cols,
- width,
- 0,
- termsize.ws_row-1,
- prefix,
- is_quoted,
- lst);
- /*
- List does not fit on screen. Print one screenfull and
- leave a scrollable interface
- */
- while (do_loop)
- {
- set_color(rgb_color_t::black(), get_color(HIGHLIGHT_PAGER_PROGRESS));
- wcstring msg = format_string(_(L" %d to %d of %d"), pos, pos+termsize.ws_row-1, rows);
- msg.append(L" \r");
-
- writestr(msg.c_str());
- set_color(rgb_color_t::normal(), rgb_color_t::normal());
- pager_flush();
- int c = readch();
-
- switch (c)
- {
- case LINE_UP:
- {
- if (pos > 0)
- {
- pos--;
- writembs(tparm(cursor_address, 0, 0));
- writembs(scroll_reverse);
- completion_print(cols,
- width,
- pos,
- pos+1,
- prefix,
- is_quoted,
- lst);
- writembs(tparm(cursor_address,
- termsize.ws_row-1, 0));
- writembs(clr_eol);
-
- }
-
- break;
- }
-
- case LINE_DOWN:
- {
- if (pos <= (rows - termsize.ws_row))
- {
- pos++;
- completion_print(cols,
- width,
- pos+termsize.ws_row-2,
- pos+termsize.ws_row-1,
- prefix,
- is_quoted,
- lst);
- }
- break;
- }
-
- case PAGE_DOWN:
- {
-
- npos = mini((int)(rows - termsize.ws_row+1), (int)(pos + termsize.ws_row-1));
- if (npos != pos)
- {
- pos = npos;
- completion_print(cols,
- width,
- pos,
- pos+termsize.ws_row-1,
- prefix,
- is_quoted,
- lst);
- }
- else
- {
- if (flash_screen)
- writembs(flash_screen);
- }
-
- break;
- }
-
- case PAGE_UP:
- {
- npos = maxi(0,
- pos - termsize.ws_row+1);
-
- if (npos != pos)
- {
- pos = npos;
- completion_print(cols,
- width,
- pos,
- pos+termsize.ws_row-1,
- prefix,
- is_quoted,
- lst);
- }
- else
- {
- if (flash_screen)
- writembs(flash_screen);
- }
- break;
- }
-
- case R_NULL:
- {
- do_loop=0;
- res=PAGER_RESIZE;
- break;
-
- }
-
- default:
- {
- out_buff.push_back(c);
- do_loop = 0;
- break;
- }
- }
- }
- writembs(clr_eol);
- }
- }
- return res;
-}
-
-/**
- Substitute any series of whitespace with a single space character
- inside completion descriptions. Remove all whitespace from
- beginning/end of completion descriptions.
-*/
-static void mangle_descriptions(wcstring_list_t &lst)
-{
- int skip;
- for (size_t i=0; i<lst.size(); i++)
- {
- wcstring &next = lst.at(i);
- size_t in, out;
- skip=1;
-
- size_t next_idx = 0;
- while (next_idx < next.size() && next[next_idx] != COMPLETE_SEP)
- next_idx++;
-
- if (next_idx == next.size())
- continue;
-
- in=out=next_idx + 1;
-
- while (in < next.size())
- {
- if (next[in] == L' ' || next[in]==L'\t' || next[in]<32)
- {
- if (!skip)
- next[out++]=L' ';
- skip=1;
- }
- else
- {
- next[out++] = next[in];
- skip=0;
- }
- in++;
- }
- next.resize(out);
- }
-}
-
-/**
- Merge multiple completions with the same description to the same line
-*/
-static void join_completions(wcstring_list_t *lst)
-{
- std::map<wcstring, long> desc_table;
-
- for (size_t i=0; i<lst->size(); i++)
- {
- const wchar_t *item = lst->at(i).c_str();
- const wchar_t *desc = wcschr(item, COMPLETE_SEP);
- long prev_idx;
-
- if (!desc)
- continue;
- desc++;
- prev_idx = desc_table[desc] - 1;
- if (prev_idx == -1)
- {
- desc_table[desc] = (long)(i+1);
- }
- else
- {
- const wchar_t *old = lst->at(prev_idx).c_str();
- const wchar_t *old_end = wcschr(old, COMPLETE_SEP);
-
- if (old_end)
- {
-
- wcstring foo;
- foo.append(old, old_end - old);
- foo.push_back(COMPLETE_ITEM_SEP);
- foo.append(item);
-
- lst->at(prev_idx) = foo;
- lst->at(i).clear();
- }
-
- }
-
- }
-
- /* Remove empty strings */
- lst->erase(remove(lst->begin(), lst->end(), wcstring()), lst->end());
-}
-
-/**
- Replace completion strings with a comp_t structure
-*/
-static std::vector<comp_t *> mangle_completions(wcstring_list_t &lst, const wchar_t *prefix)
-{
- std::vector<comp_t *> result;
- for (size_t i=0; i<lst.size(); i++)
- {
- wcstring &next = lst.at(i);
- size_t start, end;
-
- comp_t zerod = {};
- comp_t *comp = new comp_t(zerod);
-
- for (start=end=0; 1; end++)
- {
- wchar_t c = next.c_str()[end];
-
- if ((c == COMPLETE_ITEM_SEP) || (c==COMPLETE_SEP) || !c)
- {
- wcstring start2 = wcstring(next, start, end - start);
- wcstring str = escape_string(start2, ESCAPE_ALL | ESCAPE_NO_QUOTED);
- comp->comp_width += my_wcswidth(str.c_str());
- comp->comp.push_back(str);
- start = end+1;
- }
-
- if (c == COMPLETE_SEP)
- {
- comp->desc = next.c_str() + start;
- break;
- }
-
- if (!c)
- break;
-
- }
-
- comp->comp_width += (int)(my_wcswidth(prefix)*comp->comp.size() + 2*(comp->comp.size()-1));
- comp->desc_width = comp->desc.empty()?0:my_wcswidth(comp->desc.c_str());
-
- comp->pref_width = comp->comp_width + comp->desc_width + (comp->desc_width?4:0);
-
- result.push_back(comp);
- }
-
- recalc_width(result, prefix);
- return result;
-}
-
-
-
-/**
- Respond to a winch signal by checking the terminal size
-*/
-static void handle_winch(int sig)
-{
- if (ioctl(1,TIOCGWINSZ,&termsize)!=0)
- {
- return;
- }
-}
-
-/**
- The callback function that the keyboard reading function calls when
- an interrupt occurs. This makes sure that R_NULL is returned at
- once when an interrupt has occured.
-*/
-static int interrupt_handler()
-{
- return R_NULL;
-}
-
-/**
- Initialize various subsystems. This also closes stdin and replaces
- it with a copy of stderr, so the reading of completion strings must
- be done before init is called.
-*/
-static void init(int mangle_descriptors, int out)
-{
- struct sigaction act;
-
- static struct termios pager_modes;
- char *term;
-
- if (mangle_descriptors)
- {
-
- /*
- Make fd 1 output to screen, and use some other fd for writing
- the resulting output back to the caller
- */
- int in;
- out = dup(1);
- close(1);
- close(0);
-
- /* OK to not use CLO_EXEC here because fish_pager is single threaded */
- if ((in = open(ttyname(2), O_RDWR)) != -1)
- {
- if (dup2(2, 1) == -1)
- {
- debug(0, _(L"Could not set up output file descriptors for pager"));
- exit(1);
- }
-
- if (dup2(in, 0) == -1)
- {
- debug(0, _(L"Could not set up input file descriptors for pager"));
- exit(1);
- }
- }
- else
- {
- debug(0, _(L"Could not open tty for pager"));
- exit(1);
- }
- }
-
- if (!(out_file = fdopen(out, "w")))
- {
- debug(0, _(L"Could not initialize result pipe"));
- exit(1);
- }
-
-
- env_universal_init(0, 0, 0, 0);
- input_common_init(&interrupt_handler);
- output_set_writer(&pager_buffered_writer);
-
- sigemptyset(& act.sa_mask);
- act.sa_flags=0;
- act.sa_handler=SIG_DFL;
- act.sa_flags = 0;
- act.sa_handler= &handle_winch;
- if (sigaction(SIGWINCH, &act, 0))
- {
- wperror(L"sigaction");
- exit(1);
- }
-
- handle_winch(0); /* Set handler for window change events */
-
- tcgetattr(0,&pager_modes); /* get the current terminal modes */
- memcpy(&saved_modes,
- &pager_modes,
- sizeof(saved_modes)); /* save a copy so we can reset the terminal later */
-
- pager_modes.c_lflag &= ~ICANON; /* turn off canonical mode */
- pager_modes.c_lflag &= ~ECHO; /* turn off echo mode */
- pager_modes.c_cc[VMIN]=1;
- pager_modes.c_cc[VTIME]=0;
-
- /*
-
- */
- if (tcsetattr(0,TCSANOW,&pager_modes)) /* set the new modes */
- {
- wperror(L"tcsetattr");
- exit(1);
- }
-
- int errret;
- if (setupterm(0, STDOUT_FILENO, &errret) == ERR)
- {
- debug(0, _(L"Could not set up terminal"));
- exit(1);
- }
-
- term = getenv("TERM");
- if (term)
- {
- wcstring wterm = str2wcstring(term);
- output_set_term(wterm);
- }
-
- /* Infer term256 support */
- char *fish_term256 = getenv("fish_term256");
- bool support_term256;
- if (fish_term256)
- {
- support_term256 = from_string<bool>(fish_term256);
- }
- else
- {
- support_term256 = term && strstr(term, "256color");
- }
- output_set_supports_term256(support_term256);
-}
-
-/**
- Free memory used by various subsystems.
-*/
-static void destroy()
-{
- env_universal_destroy();
- input_common_destroy();
- wutil_destroy();
- if (fish_del_curterm(cur_term) == ERR)
- {
- debug(0, _(L"Error while closing terminfo"));
- }
-
- fclose(out_file);
-}
-
-/**
- Read lines of input from the specified file, unescape them and
- insert them into the specified list.
-*/
-static void read_array(FILE* file, wcstring_list_t &comp)
-{
- std::vector<char> buffer;
- int c;
-
- while (!feof(file))
- {
- buffer.clear();
-
- while (1)
- {
- c = getc(file);
- if (c == EOF)
- {
- break;
- }
-
- if (c == '\n')
- {
- break;
- }
-
- buffer.push_back(static_cast<char>(c));
- }
-
- if (! buffer.empty())
- {
- buffer.push_back(0);
- wcstring wcs = str2wcstring(&buffer.at(0));
- if (unescape_string_in_place(&wcs, false))
- {
- comp.push_back(wcs);
- }
- }
- }
-
-}
-
-static int get_fd(const char *str)
-{
- char *end;
- long fd;
-
- errno = 0;
- fd = strtol(str, &end, 10);
- if (fd < 0 || *end || errno)
- {
- debug(0, ERR_NOT_FD, program_name, optarg);
- exit(1);
- }
- return (int)fd;
-}
-
-
-int main(int argc, char **argv)
-{
- int i;
- int is_quoted=0;
- wcstring_list_t comp;
- wcstring prefix;
-
- int mangle_descriptors = 0;
- int result_fd = -1;
- set_main_thread();
- setup_fork_guards();
-
- /*
- This initialization is made early, so that the other init code
- can use global_context for memory managment
- */
- program_name = L"fish_pager";
-
-
- wsetlocale(LC_ALL, L"");
-
- /*
- The call signature for fish_pager is a mess. Because we want
- to be able to upgrade fish without breaking running
- instances, we need to support all previous
- modes. Unfortunatly, the two previous ones are a mess. The
- third one is designed to be extensible, so hopefully it will
- be the last.
- */
-
- if (argc > 1 && argv[1][0] == '-')
- {
- /*
- Third mode
- */
-
- int completion_fd = -1;
- FILE *completion_file;
-
- while (1)
- {
- static struct option
- long_options[] =
- {
- {
- "result-fd", required_argument, 0, 'r'
- }
- ,
- {
- "completion-fd", required_argument, 0, 'c'
- }
- ,
- {
- "prefix", required_argument, 0, 'p'
- }
- ,
- {
- "is-quoted", no_argument, 0, 'q'
- }
- ,
- {
- "help", no_argument, 0, 'h'
- }
- ,
- {
- "version", no_argument, 0, 'v'
- }
- ,
- {
- 0, 0, 0, 0
- }
- }
- ;
-
- int opt_index = 0;
-
- int opt = getopt_long(argc,
- argv,
- GETOPT_STRING,
- long_options,
- &opt_index);
-
- if (opt == -1)
- break;
-
- switch (opt)
- {
- case 0:
- {
- break;
- }
-
- case 'r':
- {
- result_fd = get_fd(optarg);
- break;
- }
-
- case 'c':
- {
- completion_fd = get_fd(optarg);
- break;
- }
-
- case 'p':
- {
- prefix = str2wcstring(optarg);
- break;
- }
-
- case 'h':
- {
- print_help(argv[0], 1);
- exit(0);
- }
-
- case 'v':
- {
- debug(0, L"%ls, version %s\n", program_name, FISH_BUILD_VERSION);
- exit(0);
- }
-
- case 'q':
- {
- is_quoted = 1;
- }
-
- }
- }
-
- if (completion_fd == -1 || result_fd == -1)
- {
- debug(0, _(L"Unspecified file descriptors"));
- exit(1);
- }
-
-
- if ((completion_file = fdopen(completion_fd, "r")))
- {
- read_array(completion_file, comp);
- fclose(completion_file);
- }
- else
- {
- debug(0, _(L"Could not read completions"));
- wperror(L"fdopen");
- exit(1);
- }
-
- }
- else
- {
- /*
- Second or first mode. These suck, but we need to support
- them for backwards compatibility. At least for some
- time.
-
- Third mode was implemented in January 2007, and previous
- modes should be considered deprecated from that point
- forward. A reasonable time frame for removal of the code
- below has yet to be determined.
- */
-
- if (argc < 3)
- {
- print_help(argv[0], 1);
- exit(0);
- }
- else
- {
- mangle_descriptors = 1;
-
- prefix = str2wcstring(argv[2]);
- is_quoted = strcmp("1", argv[1])==0;
-
- if (argc > 3)
- {
- /*
- First mode
- */
- for (i=3; i<argc; i++)
- {
- wcstring wcs = str2wcstring(argv[i]);
- comp.push_back(wcs);
- }
- }
- else
- {
- /*
- Second mode
- */
- read_array(stdin, comp);
- }
- }
-
- }
-
-// debug( 3, L"prefix is '%ls'", prefix );
-
- if (comp.empty())
- {
- exit_without_destructors(EXIT_FAILURE);
- }
-
- init(mangle_descriptors, result_fd);
-
- mangle_descriptions(comp);
-
- if (prefix == L"-")
- join_completions(&comp);
-
- std::vector<comp_t *> completions = mangle_completions(comp, prefix.c_str());
-
- /**
- Try to print the completions. Start by trying to print the
- list in PAGER_MAX_COLS columns, if the completions won't
- fit, reduce the number of columns by one. Printing a single
- column never fails.
- */
- for (i = PAGER_MAX_COLS; i>0; i--)
- {
- switch (completion_try_print(i, prefix.c_str(), is_quoted, completions))
- {
-
- case PAGER_RETRY:
- break;
-
- case PAGER_DONE:
- i=0;
- break;
-
- case PAGER_RESIZE:
- /*
- This means we got a resize event, so we start
- over from the beginning. Since it the screen got
- bigger, we might be able to fit all completions
- on-screen.
- */
- i=PAGER_MAX_COLS+1;
- break;
-
- }
- }
-
- fwprintf(out_file, L"%ls", out_buff.c_str());
- if (is_ca_mode)
- {
- writembs(exit_ca_mode);
- pager_flush();
- }
- destroy();
-
-}
-
diff --git a/reader.cpp b/reader.cpp
index 3899e4d4..6a81f380 100644
--- a/reader.cpp
+++ b/reader.cpp
@@ -1347,144 +1347,6 @@ static void completion_insert(const wchar_t *val, complete_flags_t flags)
data->suppress_autosuggestion = true;
}
-/* Return an escaped path to fish_pager */
-static wcstring escaped_fish_pager_path(void)
-{
- wcstring result;
- const env_var_t bin_dir = env_get_string(L"__fish_bin_dir");
- if (bin_dir.missing_or_empty())
- {
- /* This isn't good, hope our normal command stuff can find it */
- result = L"fish_pager";
- }
- else
- {
- result = escape_string(bin_dir + L"/fish_pager", ESCAPE_ALL);
- }
- return result;
-}
-
-/**
- Run the fish_pager command to display the completion list. If the
- fish_pager outputs any text, it is inserted into the input
- backbuffer.
-
- \param prefix the string to display before every completion.
- \param is_quoted should be set if the argument is quoted. This will change the display style.
- \param comp the list of completions to display
-*/
-static void run_pager(const wcstring &prefix, int is_quoted, const std::vector<completion_t> &comp)
-{
- wcstring msg;
- wcstring prefix_esc;
- char *foo;
-
- shared_ptr<io_buffer_t> in_buff(io_buffer_t::create(true, 3));
- shared_ptr<io_buffer_t> out_buff(io_buffer_t::create(false, 4));
-
- // The above may fail e.g. if we have too many open fds
- if (in_buff.get() == NULL || out_buff.get() == NULL)
- return;
-
- wchar_t *escaped_separator;
-
- if (prefix.empty())
- {
- prefix_esc = L"\"\"";
- }
- else
- {
- prefix_esc = escape_string(prefix, 1);
- }
-
-
- const wcstring pager_path = escaped_fish_pager_path();
- const wcstring cmd = format_string(L"%ls -c 3 -r 4 %ls -p %ls",
- // L"valgrind --track-fds=yes --log-file=pager.txt --leak-check=full ./%ls %d %ls",
- pager_path.c_str(),
- is_quoted?L"-q":L"",
- prefix_esc.c_str());
-
- escaped_separator = escape(COMPLETE_SEP_STR, 1);
-
- editable_line_t *el = &data->command_line;
-
- for (size_t i=0; i< comp.size(); i++)
- {
- long base_len=-1;
- const completion_t &cmpl = comp.at(i);
-
- wcstring completion_text;
- wcstring description_text;
-
- // Note that an empty completion is perfectly sensible here, e.g. tab-completing 'foo' with a file called 'foo' and another called 'foobar'
- if ((cmpl.flags & COMPLETE_REPLACES_TOKEN) && match_type_shares_prefix(cmpl.match.type))
- {
- // Compute base_len if we have not yet
- if (base_len == -1)
- {
- const wchar_t *begin, *buff = el->text.c_str();
-
- parse_util_token_extent(buff, el->position, &begin, 0, 0, 0);
- base_len = el->position - (begin-buff);
- }
-
- completion_text = escape_string(cmpl.completion.c_str() + base_len, ESCAPE_ALL | ESCAPE_NO_QUOTED);
- }
- else
- {
- completion_text = escape_string(cmpl.completion, ESCAPE_ALL | ESCAPE_NO_QUOTED);
- }
-
-
- if (! cmpl.description.empty())
- {
- description_text = escape_string(cmpl.description, true);
- }
-
- /* It's possible (even common) to have an empty completion with no description. An example would be completing 'foo' with extant files 'foo' and 'foobar'. But fish_pager ignores blank lines. So if our completion text is empty, always include a description, even if it's empty.
- */
- msg.reserve(msg.size() + completion_text.size() + description_text.size() + 2);
- msg.append(completion_text);
- if (! description_text.empty() || completion_text.empty())
- {
- msg.append(escaped_separator);
- msg.append(description_text);
- }
- msg.push_back(L'\n');
- }
-
- free(escaped_separator);
-
- foo = wcs2str(msg.c_str());
- in_buff->out_buffer_append(foo, strlen(foo));
- free(foo);
-
- term_donate();
- parser_t &parser = parser_t::principal_parser();
- io_chain_t io_chain;
- io_chain.push_back(out_buff);
- io_chain.push_back(in_buff);
- parser.eval(cmd, io_chain, TOP);
- term_steal();
-
- out_buff->read();
-
- const char zero = 0;
- out_buff->out_buffer_append(&zero, 1);
-
- const char *out_data = out_buff->out_buffer_ptr();
- if (out_data)
- {
- const wcstring str = str2wcstring(out_data);
- size_t idx = str.size();
- while (idx--)
- {
- input_unreadch(str.at(idx));
- }
- }
-}
-
struct autosuggestion_context_t
{
wcstring search_string;