Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/ref/files.xml
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ can be used to get information about the error.
</ManSection>

<#Include Label="UserHomeExpand">
<#Include Label="UserHomeShorten">

<#Include Label="Reread">

Expand Down
51 changes: 51 additions & 0 deletions lib/string.g
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,8 @@ InstallMethod( String,
## function returns a new string with the leading <C>'~'</C> substituted by
## the user's home directory as stored in <C>GAPInfo.UserHome</C>.
## Otherwise <A>str</A> is returned unchanged.
## <P/>
## This function is the counterpart of <Ref Func="UserHomeShorten"/>.
## </Description>
## </ManSection>
## <#/GAPDoc>
Expand All @@ -339,6 +341,55 @@ BIND_GLOBAL("UserHomeExpand", function(str)
fi;
end);

#############################################################################
##
#F UserHomeShorten( <str> ) . . . . . . . . . . shorten leading user home
##
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a side remark: UserHomeContract is a very unfortunate name... maybe
use UserHomeCompress or add a directory (UserHomeDirectoryCompress...).
I was wondering what contractual issues Gap might have with me...

My 2 cents

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well it was meant to be the "opposite of UserHomeExpand, and also was inspired by Julia's contractuser (which is slightly better due to the VERB-NOUN order).

But I tend to agree...

Copy link
Copy Markdown
Member Author

@fingolfin fingolfin Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW UserHomeCompress is likewise unfortunate ("wait, will this compress my home dir? neat! or ... dangerous???")

Maybe should just call this ContractUserHomeInPath and rename the old one to ExpandUserHomeInPath (with a old name kept around as a synonym forever)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another idea would be to call this UserHomeContracted (and either live with the asymmetry, or rename the other one to UserHomeExpanded (but again with the old name an indefinite alias) 🤷

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compress - definitely not and I fully agree with @fingolfin concerns.
Naming is difficult, but I like ExpandUserHomeInPath.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like UserHomeCompress. I would read UserHomeContract as with a verb. But why not UserHomeShorten?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UserHomeShorten would also be fine by me.

## <#GAPDoc Label="UserHomeShorten">
## <ManSection>
## <Func Name="UserHomeShorten" Arg='str'/>
## <Description>
## If the string <A>str</A> starts with the user's home directory as stored
## in <C>GAPInfo.UserHome</C> then this function returns a new string with
## that prefix replaced by a leading <C>'~'</C> character.
## Otherwise <A>str</A> is returned unchanged.
## <P/>
## This function is the counterpart of <Ref Func="UserHomeExpand"/>.
## </Description>
## </ManSection>
## <#/GAPDoc>
##
BIND_GLOBAL("UserHomeShorten", function(str)
local homeLen;

if not IsString(str) or Length(str) = 0
or not IsString(GAPInfo.UserHome) or Length(GAPInfo.UserHome) = 0 then
return str;
fi;

if not IsMatchingSublist(str, GAPInfo.UserHome) then
return str;
fi;

homeLen := Length(GAPInfo.UserHome);
if Length(str) = homeLen then
return "~";
fi;

# Check that the string starts with GAPInfo.UserHome and that this is separate
# from the rest by a `/`. Otherwise if `GAPInfo.UserHome` is for example
# `/home/john` but str is `/home/johnny` we'd end up with `~ny`).
if str[homeLen + 1] <> '/' then
return str;
fi;
Comment thread
fingolfin marked this conversation as resolved.

if Length(str) = homeLen + 1 then
return "~";
fi;

return Concatenation("~/", str{[homeLen + 2..Length(str)]});
end);


# the character set definitions might be needed when processing files, thus
# they must come earlier.
Expand Down
22 changes: 21 additions & 1 deletion tst/testinstall/strings.tst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
##
## This file tests output methods (mainly for strings)
##
#@local x, str, len
#@local hadHome, len, savedHome, str, x
gap> START_TEST("strings.tst");

# FFE
Expand Down Expand Up @@ -225,5 +225,25 @@ gap> Length(x);
gap> Print(x, "\n");
abcdef

# UserHomeShorten
gap> hadHome := IsBound(GAPInfo.UserHome);;
gap> if hadHome then savedHome := GAPInfo.UserHome; fi;;
gap> GAPInfo.UserHome := "/tmp/gap-home";;
gap> UserHomeShorten("/tmp/gap-home");
"~"
gap> UserHomeShorten("/tmp/gap-home/.gap");
"~/.gap"
gap> UserHomeShorten("/tmp/gap-homedir");
"/tmp/gap-homedir"
gap> UserHomeShorten("/tmp/gap-home-extra");
"/tmp/gap-home-extra"
gap> UserHomeShorten("~/already");
"~/already"
gap> UserHomeExpand(UserHomeShorten("/tmp/gap-home/.gap"));
"/tmp/gap-home/.gap"
gap> UserHomeShorten(1234);
1234
gap> if hadHome then GAPInfo.UserHome := savedHome; else Unbind(GAPInfo.UserHome); fi;;

#
gap> STOP_TEST("strings.tst");
Loading