parent
8072801bf0
commit
422cd6b459
43
doc.go
43
doc.go
@ -79,7 +79,7 @@ The following options can be used to customize the behavior of lf:
|
|||||||
wrapscan boolean (default on)
|
wrapscan boolean (default on)
|
||||||
scrolloff integer (default 0)
|
scrolloff integer (default 0)
|
||||||
tabstop integer (default 8)
|
tabstop integer (default 8)
|
||||||
filesep string (default ":")
|
filesep string (default "\n")
|
||||||
ifs string (default "") (not exported if empty)
|
ifs string (default "") (not exported if empty)
|
||||||
previewer string (default "") (not filtered if empty)
|
previewer string (default "") (not filtered if empty)
|
||||||
shell string (default "/bin/sh")
|
shell string (default "/bin/sh")
|
||||||
@ -91,7 +91,7 @@ The following options can be used to customize the behavior of lf:
|
|||||||
The following variables are exported for shell commands:
|
The following variables are exported for shell commands:
|
||||||
|
|
||||||
$f current file
|
$f current file
|
||||||
$fs marked file(s) separated with ':'
|
$fs marked file(s) separated with 'filesep'
|
||||||
$fx current file or marked file(s) if any
|
$fx current file or marked file(s) if any
|
||||||
$id id number of the client
|
$id id number of the client
|
||||||
|
|
||||||
@ -221,10 +221,10 @@ A first attempt to write such a command may look like this:
|
|||||||
|
|
||||||
cmd trash ${{
|
cmd trash ${{
|
||||||
mkdir -p ~/.trash
|
mkdir -p ~/.trash
|
||||||
if [ -z $fs ]; then
|
if [ -z "$fs" ]; then
|
||||||
mv --backup=numbered "$f" $HOME/.trash
|
mv --backup=numbered "$f" ~/.trash
|
||||||
else
|
else
|
||||||
IFS=':'; mv --backup=numbered $fs $HOME/.trash
|
IFS="`printf '\n\t'`"; mv --backup=numbered $fs ~/.trash
|
||||||
fi
|
fi
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ variable is provided. We can use this variable to get rid of the conditional:
|
|||||||
|
|
||||||
cmd trash ${{
|
cmd trash ${{
|
||||||
mkdir -p ~/.trash
|
mkdir -p ~/.trash
|
||||||
IFS=':'; mv --backup=numbered $fx $HOME/.trash
|
IFS="`printf '\n\t'`"; mv --backup=numbered $fx ~/.trash
|
||||||
}}
|
}}
|
||||||
|
|
||||||
The trash directory is checked each time the command is executed. We can move
|
The trash directory is checked each time the command is executed. We can move
|
||||||
@ -242,19 +242,20 @@ it outside of the command so it would only run once at startup:
|
|||||||
|
|
||||||
${{ mkdir -p ~/.trash }}
|
${{ mkdir -p ~/.trash }}
|
||||||
|
|
||||||
cmd trash ${{ IFS=':'; mv --backup=numbered $fx $HOME/.trash }}
|
cmd trash ${{ IFS="`printf '\n\t'`"; mv --backup=numbered $fx ~/.trash }}
|
||||||
|
|
||||||
Since these are one liners, we can drop "{{" and "}}":
|
Since these are one liners, we can drop "{{" and "}}":
|
||||||
|
|
||||||
$mkdir -p ~/.trash
|
$mkdir -p ~/.trash
|
||||||
|
|
||||||
cmd trash $IFS=':'; mv --backup=numbered $fx $HOME/.trash
|
cmd trash $IFS="`printf '\n\t'`"; mv --backup=numbered $fx ~/.trash
|
||||||
|
|
||||||
Finally note that we set "IFS" variable accordingly in the command. Instead we
|
Finally note that we set "IFS" variable manually in these commands. Instead we
|
||||||
could use the "ifs" option to set it for all commands (e.g. "set ifs ':'").
|
could use the "ifs" option to set it for all shell commands (i.e. 'set ifs
|
||||||
This can be especially useful for interactive use (e.g. "rm $fs" would simply
|
"\n"'). This can be especially useful for interactive use (e.g. "$rm $f" or
|
||||||
work). This option is not set by default as things may behave unexpectedly at
|
"$rm $fs" would simply work). This option is not set by default as it can
|
||||||
other places.
|
behave unexpectedly for new users. However, use of this option is highly
|
||||||
|
recommended and it is assumed in the rest of the documentation.
|
||||||
|
|
||||||
Remote Commands
|
Remote Commands
|
||||||
|
|
||||||
@ -363,22 +364,18 @@ called by "open" when the current file is not a directory. Normally a user maps
|
|||||||
the "open" command to a key (default "l") and customize "open-file" command as
|
the "open" command to a key (default "l") and customize "open-file" command as
|
||||||
desired. You can define it just as you would define any other command:
|
desired. You can define it just as you would define any other command:
|
||||||
|
|
||||||
cmd open-file $IFS=':'; vim $fx
|
cmd open-file $vim $fx
|
||||||
|
|
||||||
It is possible to use different command types:
|
It is possible to use different command types:
|
||||||
|
|
||||||
cmd open-file &xdg-open "$f"
|
cmd open-file &xdg-open $f
|
||||||
|
|
||||||
You may want to use either file extensions or mime types from "file" command:
|
You may want to use either file extensions or mime types from "file" command:
|
||||||
|
|
||||||
cmd open-file ${{
|
cmd open-file ${{
|
||||||
case $(file --mime-type "$f" -b) in
|
case $(file --mime-type $f -b) in
|
||||||
text/*)
|
text/*) vim $fx;;
|
||||||
IFS=':'; vim $fx;;
|
*) for f in $fx; do xdg-open $f > /dev/null 2> /dev/null & done;;
|
||||||
*)
|
|
||||||
IFS=':'; for f in $fx; do
|
|
||||||
xdg-open "$f" > /dev/null 2> /dev/null &
|
|
||||||
done;;
|
|
||||||
esac
|
esac
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@ -403,7 +400,7 @@ this file. Output of the execution is printed in the preview pane. You may want
|
|||||||
to use the same script in your pager mapping as well if any:
|
to use the same script in your pager mapping as well if any:
|
||||||
|
|
||||||
set previewer ~/.config/lf/pv.sh
|
set previewer ~/.config/lf/pv.sh
|
||||||
map i $~/.config/lf/pv.sh "$f" | less -R
|
map i $~/.config/lf/pv.sh $f | less -R
|
||||||
|
|
||||||
Since this script is called for each file selection change it needs to be as
|
Since this script is called for each file selection change it needs to be as
|
||||||
efficient as possible and this responsibility is left to the user. You may use
|
efficient as possible and this responsibility is left to the user. You may use
|
||||||
|
43
docstring.go
43
docstring.go
@ -83,7 +83,7 @@ The following options can be used to customize the behavior of lf:
|
|||||||
wrapscan boolean (default on)
|
wrapscan boolean (default on)
|
||||||
scrolloff integer (default 0)
|
scrolloff integer (default 0)
|
||||||
tabstop integer (default 8)
|
tabstop integer (default 8)
|
||||||
filesep string (default ":")
|
filesep string (default "\n")
|
||||||
ifs string (default "") (not exported if empty)
|
ifs string (default "") (not exported if empty)
|
||||||
previewer string (default "") (not filtered if empty)
|
previewer string (default "") (not filtered if empty)
|
||||||
shell string (default "/bin/sh")
|
shell string (default "/bin/sh")
|
||||||
@ -95,7 +95,7 @@ The following options can be used to customize the behavior of lf:
|
|||||||
The following variables are exported for shell commands:
|
The following variables are exported for shell commands:
|
||||||
|
|
||||||
$f current file
|
$f current file
|
||||||
$fs marked file(s) separated with ':'
|
$fs marked file(s) separated with 'filesep'
|
||||||
$fx current file or marked file(s) if any
|
$fx current file or marked file(s) if any
|
||||||
$id id number of the client
|
$id id number of the client
|
||||||
|
|
||||||
@ -231,10 +231,10 @@ A first attempt to write such a command may look like this:
|
|||||||
|
|
||||||
cmd trash ${{
|
cmd trash ${{
|
||||||
mkdir -p ~/.trash
|
mkdir -p ~/.trash
|
||||||
if [ -z $fs ]; then
|
if [ -z "$fs" ]; then
|
||||||
mv --backup=numbered "$f" $HOME/.trash
|
mv --backup=numbered "$f" ~/.trash
|
||||||
else
|
else
|
||||||
IFS=':'; mv --backup=numbered $fs $HOME/.trash
|
IFS="'printf '\n\t''"; mv --backup=numbered $fs ~/.trash
|
||||||
fi
|
fi
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@ -245,7 +245,7 @@ conditional:
|
|||||||
|
|
||||||
cmd trash ${{
|
cmd trash ${{
|
||||||
mkdir -p ~/.trash
|
mkdir -p ~/.trash
|
||||||
IFS=':'; mv --backup=numbered $fx $HOME/.trash
|
IFS="'printf '\n\t''"; mv --backup=numbered $fx ~/.trash
|
||||||
}}
|
}}
|
||||||
|
|
||||||
The trash directory is checked each time the command is executed. We can
|
The trash directory is checked each time the command is executed. We can
|
||||||
@ -253,19 +253,20 @@ move it outside of the command so it would only run once at startup:
|
|||||||
|
|
||||||
${{ mkdir -p ~/.trash }}
|
${{ mkdir -p ~/.trash }}
|
||||||
|
|
||||||
cmd trash ${{ IFS=':'; mv --backup=numbered $fx $HOME/.trash }}
|
cmd trash ${{ IFS="'printf '\n\t''"; mv --backup=numbered $fx ~/.trash }}
|
||||||
|
|
||||||
Since these are one liners, we can drop "{{" and "}}":
|
Since these are one liners, we can drop "{{" and "}}":
|
||||||
|
|
||||||
$mkdir -p ~/.trash
|
$mkdir -p ~/.trash
|
||||||
|
|
||||||
cmd trash $IFS=':'; mv --backup=numbered $fx $HOME/.trash
|
cmd trash $IFS="'printf '\n\t''"; mv --backup=numbered $fx ~/.trash
|
||||||
|
|
||||||
Finally note that we set "IFS" variable accordingly in the command. Instead
|
Finally note that we set "IFS" variable manually in these commands. Instead
|
||||||
we could use the "ifs" option to set it for all commands (e.g. "set ifs
|
we could use the "ifs" option to set it for all shell commands (i.e. 'set
|
||||||
':'"). This can be especially useful for interactive use (e.g. "rm $fs"
|
ifs "\n"'). This can be especially useful for interactive use (e.g. "$rm $f"
|
||||||
would simply work). This option is not set by default as things may behave
|
or "$rm $fs" would simply work). This option is not set by default as it can
|
||||||
unexpectedly at other places.
|
behave unexpectedly for new users. However, use of this option is highly
|
||||||
|
recommended and it is assumed in the rest of the documentation.
|
||||||
|
|
||||||
|
|
||||||
Remote Commands
|
Remote Commands
|
||||||
@ -379,23 +380,19 @@ maps the "open" command to a key (default "l") and customize "open-file"
|
|||||||
command as desired. You can define it just as you would define any other
|
command as desired. You can define it just as you would define any other
|
||||||
command:
|
command:
|
||||||
|
|
||||||
cmd open-file $IFS=':'; vim $fx
|
cmd open-file $vim $fx
|
||||||
|
|
||||||
It is possible to use different command types:
|
It is possible to use different command types:
|
||||||
|
|
||||||
cmd open-file &xdg-open "$f"
|
cmd open-file &xdg-open $f
|
||||||
|
|
||||||
You may want to use either file extensions or mime types from "file"
|
You may want to use either file extensions or mime types from "file"
|
||||||
command:
|
command:
|
||||||
|
|
||||||
cmd open-file ${{
|
cmd open-file ${{
|
||||||
case $(file --mime-type "$f" -b) in
|
case $(file --mime-type $f -b) in
|
||||||
text/*)
|
text/*) vim $fx;;
|
||||||
IFS=':'; vim $fx;;
|
*) for f in $fx; do xdg-open $f > /dev/null 2> /dev/null & done;;
|
||||||
*)
|
|
||||||
IFS=':'; for f in $fx; do
|
|
||||||
xdg-open "$f" > /dev/null 2> /dev/null &
|
|
||||||
done;;
|
|
||||||
esac
|
esac
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@ -422,7 +419,7 @@ pane. You may want to use the same script in your pager mapping as well if
|
|||||||
any:
|
any:
|
||||||
|
|
||||||
set previewer ~/.config/lf/pv.sh
|
set previewer ~/.config/lf/pv.sh
|
||||||
map i $~/.config/lf/pv.sh "$f" | less -R
|
map i $~/.config/lf/pv.sh $f | less -R
|
||||||
|
|
||||||
Since this script is called for each file selection change it needs to be as
|
Since this script is called for each file selection change it needs to be as
|
||||||
efficient as possible and this responsibility is left to the user. You may
|
efficient as possible and this responsibility is left to the user. You may
|
||||||
|
@ -8,10 +8,12 @@
|
|||||||
# interpreter for shell commands (needs to be POSIX compatible)
|
# interpreter for shell commands (needs to be POSIX compatible)
|
||||||
#set shell /bin/sh
|
#set shell /bin/sh
|
||||||
|
|
||||||
# set internal field seperator (IFS) to ':'
|
# set internal field separator (IFS) to "\n" for shell commands
|
||||||
# This is especially useful for interactive use to automatically split file
|
# This is useful to automatically split file names in $fs and $fx properly
|
||||||
# names in $fs and $fx. Things may behave unexpectedly so use with caution.
|
# since default file separator used in these variables (i.e. `filesep` option)
|
||||||
#set ifs ':'
|
# is newline. You need to consider the values of these options and create your
|
||||||
|
# commands accordingly.
|
||||||
|
set ifs "\n"
|
||||||
|
|
||||||
# leave some space at the top and the bottom of the screen
|
# leave some space at the top and the bottom of the screen
|
||||||
set scrolloff 10
|
set scrolloff 10
|
||||||
@ -39,20 +41,20 @@ map gr cd /
|
|||||||
map <enter> read-shell
|
map <enter> read-shell
|
||||||
|
|
||||||
# mappings for pager and editor (change as you like)
|
# mappings for pager and editor (change as you like)
|
||||||
map i $less "$f"
|
map i $less $f
|
||||||
map e $vim "$f"
|
map e $vim $f
|
||||||
|
|
||||||
# mapping to spawn a shell in working directory
|
# mapping to spawn a shell in working directory
|
||||||
# (see also etc/lf.sh as an alternative workflow)
|
# (see also etc/lf.sh as an alternative workflow)
|
||||||
map w $$SHELL
|
map w $$SHELL
|
||||||
|
|
||||||
# execute current file (must be executable)
|
# execute current file (must be executable)
|
||||||
map x $"$f"
|
map x $$f
|
||||||
map X !"$f"
|
map X !$f
|
||||||
|
|
||||||
# dedicated keys for file opener actions
|
# dedicated keys for file opener actions
|
||||||
map o &mimeopen "$f"
|
map o &mimeopen $f
|
||||||
map O $mimeopen --ask "$f"
|
map O $mimeopen --ask $f
|
||||||
|
|
||||||
# show documentation (overrides search-back)
|
# show documentation (overrides search-back)
|
||||||
map ? $lf -doc | less
|
map ? $lf -doc | less
|
||||||
@ -62,18 +64,18 @@ map ? $lf -doc | less
|
|||||||
# want to use either file extensions and/or mime types here. Below uses an
|
# want to use either file extensions and/or mime types here. Below uses an
|
||||||
# editor for text files and a file opener for the rest.
|
# editor for text files and a file opener for the rest.
|
||||||
cmd open-file ${{
|
cmd open-file ${{
|
||||||
case $(file --mime-type "$f" -b) in
|
case $(file --mime-type $f -b) in
|
||||||
text/*) IFS=':'; vim $fx;;
|
text/*) vim $fx;;
|
||||||
*) IFS=':'; for f in $fx; do xdg-open "$f" > /dev/null 2> /dev/null & done;;
|
*) for f in $fx; do xdg-open $f > /dev/null 2> /dev/null & done;;
|
||||||
esac
|
esac
|
||||||
}}
|
}}
|
||||||
|
|
||||||
# rename current file without overwrite
|
# rename current file without overwrite
|
||||||
cmd rename ${{
|
cmd rename ${{
|
||||||
if [ -e "$1" ]; then
|
if [ -e $1 ]; then
|
||||||
lf -remote "send $id echo file exists"
|
lf -remote "send $id echo file exists"
|
||||||
else
|
else
|
||||||
mv "$f" "$1"
|
mv $f $1
|
||||||
fi
|
fi
|
||||||
}}
|
}}
|
||||||
map r push :rename<space>
|
map r push :rename<space>
|
||||||
@ -86,26 +88,26 @@ $mkdir -p $HOME/.trash
|
|||||||
|
|
||||||
# move current file or selected files to trash folder
|
# move current file or selected files to trash folder
|
||||||
# (see 'man mv' or 'mv --help' for backup options)
|
# (see 'man mv' or 'mv --help' for backup options)
|
||||||
cmd trash $IFS=':'; mv --backup=numbered $fx $HOME/.trash
|
cmd trash $mv --backup=numbered $fx $HOME/.trash
|
||||||
|
|
||||||
# remove current file or selected files (prompting)
|
# remove current file or selected files (prompting)
|
||||||
#cmd remove ${{
|
#cmd remove ${{
|
||||||
# echo "$fx" | tr ':' '\n'
|
# printf "$fx\n"
|
||||||
# echo -n 'remove?[y/n]'
|
# printf "remove?[y/n]"
|
||||||
# read ans
|
# read ans
|
||||||
# [ $ans = 'y' ] && (IFS=':'; rm -rf $fx)
|
# [ $ans = "y" ] && rm -rf $fx
|
||||||
#}}
|
#}}
|
||||||
|
|
||||||
# extract the current file with the right command
|
# extract the current file with the right command
|
||||||
# (xkcd link: https://xkcd.com/1168/)
|
# (xkcd link: https://xkcd.com/1168/)
|
||||||
cmd extract ${{
|
cmd extract ${{
|
||||||
case "$f" in
|
case $f in
|
||||||
*.tar.bz|*.tar.bz2|*.tbz|*.tbz2) tar xjvf "$f";;
|
*.tar.bz|*.tar.bz2|*.tbz|*.tbz2) tar xjvf $f;;
|
||||||
*.tar.gz|*.tgz) tar xzvf "$f";;
|
*.tar.gz|*.tgz) tar xzvf $f;;
|
||||||
*.tar.xz|*.txz) tar xJvf "$f";;
|
*.tar.xz|*.txz) tar xJvf $f;;
|
||||||
*.zip) unzip "$f";;
|
*.zip) unzip $f;;
|
||||||
*.rar) unrar x "$f";;
|
*.rar) unrar x $f;;
|
||||||
*.7z) 7z x "$f";;
|
*.7z) 7z x $f;;
|
||||||
esac
|
esac
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@ -113,10 +115,10 @@ cmd extract ${{
|
|||||||
# This command takes the output name without '.tar.gz' suffix as an argument
|
# This command takes the output name without '.tar.gz' suffix as an argument
|
||||||
# (e.g. "compress foo" creates "foo.tar.gz").
|
# (e.g. "compress foo" creates "foo.tar.gz").
|
||||||
cmd compress ${{
|
cmd compress ${{
|
||||||
mkdir "$1"
|
mkdir $1
|
||||||
IFS=':'; cp $fs "$1"
|
cp $fs $1
|
||||||
tar czvf "$1.tar.gz" "$1"
|
tar czvf $1.tar.gz $1
|
||||||
rm -rf "$1"
|
rm -rf $1
|
||||||
}}
|
}}
|
||||||
|
|
||||||
# dynamically set the number of columns on startup based on terminal width
|
# dynamically set the number of columns on startup based on terminal width
|
||||||
|
42
eval_test.go
42
eval_test.go
@ -264,9 +264,9 @@ var gEvalTests = []struct {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"cmd usage $du -h \"$1\" | less",
|
"cmd usage $du -h $1 | less",
|
||||||
[]string{"cmd", "usage", "$", `du -h "$1" | less`, "\n"},
|
[]string{"cmd", "usage", "$", "du -h $1 | less", "\n"},
|
||||||
[]expr{&cmdExpr{"usage", &execExpr{"$", `du -h "$1" | less`}}},
|
[]expr{&cmdExpr{"usage", &execExpr{"$", "du -h $1 | less"}}},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -320,42 +320,42 @@ var gEvalTests = []struct {
|
|||||||
{
|
{
|
||||||
`map c ${{
|
`map c ${{
|
||||||
mkdir foo
|
mkdir foo
|
||||||
IFS=':'; cp ${fs} foo
|
cp $fs foo
|
||||||
tar -czvf "foo.tar.gz" foo
|
tar -czvf foo.tar.gz foo
|
||||||
rm -rf foo
|
rm -rf foo
|
||||||
}}`,
|
}}`,
|
||||||
[]string{"map", "c", "$", "{{", `
|
[]string{"map", "c", "$", "{{", `
|
||||||
mkdir foo
|
mkdir foo
|
||||||
IFS=':'; cp ${fs} foo
|
cp $fs foo
|
||||||
tar -czvf "foo.tar.gz" foo
|
tar -czvf foo.tar.gz foo
|
||||||
rm -rf foo
|
rm -rf foo
|
||||||
`, "}}", "\n"},
|
`, "}}", "\n"},
|
||||||
[]expr{&mapExpr{"c", &execExpr{"$", `
|
[]expr{&mapExpr{"c", &execExpr{"$", `
|
||||||
mkdir foo
|
mkdir foo
|
||||||
IFS=':'; cp ${fs} foo
|
cp $fs foo
|
||||||
tar -czvf "foo.tar.gz" foo
|
tar -czvf foo.tar.gz foo
|
||||||
rm -rf foo
|
rm -rf foo
|
||||||
`}}},
|
`}}},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
`cmd compress ${{
|
`cmd compress ${{
|
||||||
mkdir "$1"
|
mkdir $1
|
||||||
IFS=':'; cp ${fs} "$1"
|
cp $fs $1
|
||||||
tar -czvf "$1.tar.gz" "$1"
|
tar -czvf $1.tar.gz $1
|
||||||
rm -rf "$1"
|
rm -rf $1
|
||||||
}}`,
|
}}`,
|
||||||
[]string{"cmd", "compress", "$", "{{", `
|
[]string{"cmd", "compress", "$", "{{", `
|
||||||
mkdir "$1"
|
mkdir $1
|
||||||
IFS=':'; cp ${fs} "$1"
|
cp $fs $1
|
||||||
tar -czvf "$1.tar.gz" "$1"
|
tar -czvf $1.tar.gz $1
|
||||||
rm -rf "$1"
|
rm -rf $1
|
||||||
`, "}}", "\n"},
|
`, "}}", "\n"},
|
||||||
[]expr{&cmdExpr{"compress", &execExpr{"$", `
|
[]expr{&cmdExpr{"compress", &execExpr{"$", `
|
||||||
mkdir "$1"
|
mkdir $1
|
||||||
IFS=':'; cp ${fs} "$1"
|
cp $fs $1
|
||||||
tar -czvf "$1.tar.gz" "$1"
|
tar -czvf $1.tar.gz $1
|
||||||
rm -rf "$1"
|
rm -rf $1
|
||||||
`}}},
|
`}}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
2
opts.go
2
opts.go
@ -39,7 +39,7 @@ func init() {
|
|||||||
gOpts.wrapscan = true
|
gOpts.wrapscan = true
|
||||||
gOpts.scrolloff = 0
|
gOpts.scrolloff = 0
|
||||||
gOpts.tabstop = 8
|
gOpts.tabstop = 8
|
||||||
gOpts.filesep = ":"
|
gOpts.filesep = "\n"
|
||||||
gOpts.shell = gDefaultShell
|
gOpts.shell = gDefaultShell
|
||||||
gOpts.sortby = "natural"
|
gOpts.sortby = "natural"
|
||||||
gOpts.timefmt = time.ANSIC
|
gOpts.timefmt = time.ANSIC
|
||||||
|
Loading…
Reference in New Issue
Block a user