注:此后台启动非emacs daemon模式
有没有好用的alias
,平时我都是在终端输入emacs打开emacs gui,但通常这时终端也会被占用,除非我加上 &
而像gvim,或者vscode调用时不用加 & 也不会占用终端的
而像alias emacs='emacs &'
这样的,又不能直接使用emacs filename
或者emacs -nw
注:此后台启动非emacs daemon模式
有没有好用的alias
,平时我都是在终端输入emacs打开emacs gui,但通常这时终端也会被占用,除非我加上 &
而像gvim,或者vscode调用时不用加 & 也不会占用终端的
而像alias emacs='emacs &'
这样的,又不能直接使用emacs filename
或者emacs -nw
可能我没有完全理解你的需求,emacsclient
不行么?
emacsclient的话其实就是emacs daemon了,我并不想直接手动调用emacs --daemon
,而是我手动调用emacs gui时,根据我对server
的配置来启动daemon,但调用emacs gui会同时占用我的终端
可以写一个函数
ec() { emacs "$1" & ; }
Ctrl-Z 放到后台不行嘛
如果只是gui,我之前实现一个类似的
nohup emacs "$@" &> /dev/null & disown
但对于emacs -nw
来说是无效的
双击图标应该就是后台启动吧
emacs直接卡死
emacsclient -c -n
可以考虑用终端复用器
Mac 中 Bash 下这么可以(关掉终端 Emacs 也不会关掉)
bash-3.2$ emacs -Q & disown $!
Zsh 下这么也可以
zsh$ emacs -Q & disown
参考:
可能超出了题主的要求。。。
我把下面的内容保存成了一个名为 run-emacs 的脚本:
#!/bin/bash
EMACS=/usr/local/bin/emacs
EMACSCLIENT=/usr/local/bin/emacsclient
export PATH="/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
export LC_CTYPE=zh_CN.UTF-8
export LC_ALL=
ARCH=`uname`
if [ ! -f $EMACS ]; then
echo "Can't find proper executable emacs..."
exit 1
fi
_is_emacs_daemon_started () {
netstat -nl 2> /dev/null | awk '{print $NF}' | grep -q "emacs.*server"
}
_is_emacs_window_exist () {
_is_emacs_daemon_started && $EMACSCLIENT -e '(<= 2 (length (visible-frame-list)))' | grep -q -x t
}
_raise_emacs() {
if [ $ARCH = 'Linux' ]; then
which wmctrl > /dev/null 2>&1 && wmctrl -xa "emacs.Emacs"
elif [ $ARCH = 'Darwin' ]; then
osascript -e 'tell application "Emacs" to activate'
else
echo "Unsupported platform"
fi
}
start_emacs ()
{
$EMACS --daemon
return $?
}
main () {
_is_emacs_daemon_started
if [ $? -ne 0 ] ; then
start_emacs
if [ $? -eq 0 ]; then
echo ' [sucess]'
else
echo ' [faild]'
return 1
fi
fi
while [ 1 ]; do
_is_emacs_daemon_started
if [ $? -ne 0 ]; then
echo "Waiting emacs to be started..."
sleep 1
else
break
fi
done
# Simply return if --daemon is set. This is only used by systemd.
if [ "$1" = "--daemon" ]; then
return 0
fi
# Get arguments passed to emacsclient.
local args=""
while getopts tnc var; do
case $var in
t)
args="-t";;
n)
args="-n";;
c)
args="-c";;
*)
printf "Usage: %s [-t/-n] [-c] file:line" $0
;;
esac
done
shift $(($OPTIND - 1))
if [ -z "$args" ]; then
if [ "$ARCH" = 'Linux' ]; then
if [ -z $DISPLAY ]; then
# Always opens new frame if working in command-line mode (without X).
args="-t $args"
else
# Don't wait if working under X.
args="-n $args"
fi
elif [ "$ARCH" = 'Darwin' ]; then
args="-n"
fi
fi
_is_emacs_window_exist || args="$args -c"
$EMACSCLIENT $args -u "$@"
if [ $? -eq 0 ]; then
_raise_emacs
fi
}
main "$@"
然后在 .bashrc 中添加:
function emacs_edit ()
{
local fn=
local ln=
local args=
while [ $# -ne 0 ] ; do
if [[ "$1" =~ "-" ]]; then
if [ -z "$args" ]; then
args="$1"
else
args="$args $1"
fi
else
fn=`expr "$1" : '\([^:]*\):.*' '|' $1`
ln=`expr "$1" : '[^:]*:\(.*\)'` # line_info
break
fi
shift 1
done
if [ -z $ln ]; then
run-emacs $args $fn
else
run-emacs $args "+$ln" $fn
fi
}
alias ee=emacs_edit
alias eet="emacs_edit -t"
alias edit=emacs_eidt
然后, shell 中输入 ee filename
, 如果有已经启动的 emacs daemon ,则直接使用 emacsclient 打开文件,并聚焦到 Emacs 窗口。如果没有 daemon,则打开一个 emacs daemon,然后再调用 emacsclient. 两种情况下都不会占用终端。
eet
和 ee
类似,但会在终端中使用 tty 方式 打开文件。
直接双击图标开一个GUI Emacs,里面启动server-mode,在终端直接用emacsclient开文件。
非常感谢你的回复,我试一下
根据大家的回复,下午研究了一下,找到了比较适合我自己的方式,多谢各位的帮助
EMACS=/usr/bin/emacs
GUI=0
ARGS="$@"
ARRAY=("-nw" "--no-window-system" "--batch" "--help")
for arg in $ARGS; do
for keyword in "${ARRAY[@]}";do
if [ $keyword = $arg ];then
GUI=1
break
fi
done
if [ $GUI -eq 1 ]; then
break
fi
done
if [ $GUI -eq 1 ]; then
$EMACS $ARGS
else
$EMACS $ARGS &> /dev/null &
# nohup $EMACS $ARGS &> /dev/null & disown
fi
@lululau @seagle0128 我使用i3wm,没有图标可点击,还是习惯于直接终端输入
@cireu 终端复用器的话有些复杂了
@xuchunyang emacs直接加&
对于需要打开文件或者需要某些参数的操作不太适用
i3有C-d (dmenu)可用啊
你的问题是两个吧?
而且这两个问题不相干,你要用 Shell Function 或者单独的脚本来处理第一个问题,至于第二问题,&
配合上 disown
可以解决,在我这里测试的话。
我经常在终端cd到某个目录,然后用emacs打开文件,mod+d不使用这种场景
确实是这样,但emacs是相同的二进制,传递不同的参数打开gui,或者no-window-system,如果只是对于打开gui直接加&
是对的,对于no-window-system加&
就不适用了,因为no-window-system本来就一定要占用终端的