1#############################################################################
2##
3#W  getpackagename.g      GAP 4 package `Browse'                Thomas Breuer
4##
5#Y  Copyright (C) 2012,   Lehrstuhl D für Mathematik,  RWTH Aachen,   Germany
6##
7##  This file contains a utility for `LoadPackage' in case several package
8##  names match the first argument.
9##  The library function just replaces an exact match and otherwise prints an
10##  info message about all matches.
11##  We overwrite this function by the opportunity to choose one match.
12##
13
14DeclareUserPreference( rec(
15    name:= "SelectPackageName",
16    description:= [
17"In the case that 'LoadPackage' is called with a prefix of some \
18package names, 'true' means that the user can choose one matching entry, \
19and 'false' means that the matches are just printed" ],
20    default:= true,
21    values:= [ true, false ],
22    multi:= false,
23    ) );
24
25## reset to false for 'dumb' terminals
26if GAPInfo.SystemEnvironment.TERM = "dumb" then
27  SetUserPreference("browse", "SelectPackageName", false);
28fi;
29
30#############################################################################
31##
32#F  GetPackageNameForPrefix( <prefix> ) . . . . . . . .  show list of matches
33#F                                                   or single match directly
34##
35
36BindGlobal( "GetPackageNameForPrefix_LIB", GetPackageNameForPrefix );
37MakeReadWriteGlobal( "GetPackageNameForPrefix" );
38UnbindGlobal( "GetPackageNameForPrefix" );
39
40DeclareGlobalFunction( "GetPackageNameForPrefix" );
41InstallGlobalFunction( GetPackageNameForPrefix, function( prefix )
42    local len, lowernames, name, allnames, c;
43
44    if UserPreference( "browse", "SelectPackageName" ) = false then
45      return GetPackageNameForPrefix_LIB( prefix );
46    fi;
47
48    len:= Length( prefix );
49    lowernames:= [];
50    for name in Set( RecNames( GAPInfo.PackagesInfo ) ) do
51      if Length( prefix ) <= Length( name ) and
52         name{ [ 1 .. len ] } = prefix then
53        Add( lowernames, name );
54      fi;
55    od;
56    if IsEmpty( lowernames ) then
57      # No package name matches.
58      return prefix;
59    fi;
60    allnames:= List( lowernames,
61                     nam -> GAPInfo.PackagesInfo.( nam )[1].PackageName );
62    if Length( allnames ) = 1 then
63      # There is one exact match.
64      LogPackageLoadingMessage( PACKAGE_DEBUG, Concatenation(
65          [ "replace prefix '", prefix, "' by the unique completion '",
66            allnames[1], "'" ] ), allnames[1] );
67      return lowernames[1];
68    fi;
69
70    # Several package names match.
71    c:= NCurses.Select( rec(
72            items  := allnames,
73            none   := true,
74            border := true,
75            header := [ NCurses.attrs.BOLD,
76          "   Choose an entry, 'q' for none:" ] ) );
77    if c = false then
78      # The user did not choose an entry.
79      return prefix;
80    fi;
81
82    LogPackageLoadingMessage( PACKAGE_DEBUG, Concatenation(
83        [ "replace prefix '", prefix, "' by the user choice '",
84          allnames[c], "'" ] ), allnames[c] );
85    return lowernames[c];
86    end );
87
88
89#############################################################################
90##
91#E
92
93