内网非root用户使用emacs写代码的折腾之路

内网开发服务器,不给root权限,不给网络权限。

网络渗透进去就不讲了,情况不一样。

记录下我的内网非root安装emacs写代码的折腾之路。

遇到了好多问题,热爱才让我坚持了下来,不然在内网里用着不顺手的工具,真的是煎熬。

linux服务器环境

Linux xxxx 3.10.0-957.axs7.x86_64 #1 SMP Sun May 24 08:42:07 CST 2020 x86_64 x86_64 x86_64 GNU/Linux

RedFlag Linux China Post Edition 7 SP6

gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)

服务器内核版本蛮低的,一开始我还担心会编译有问题,结果也真的是哈。

emacs编译

如果不需要tree-sitter,直接用./confiugre 和make 出奇的顺利。

但是如果用tree-sitter就比较麻烦了,遇到了好几个问题。

tree-sitter

github获取代码拷贝进去,

make生成libtree-sitter.so.0.0

由于没有root权限,

在当前用户目录下生成了 $HOME/.local/lib和$HOME/.local/include

拷贝libtree-sitter.so.0.0到$HOME/.local/lib下并且软链接libtree-sitter.so和libtree-sitter.so.0

拷贝api.h到$HOME/.local/include/tree_sitter

emacs源码编译

./configure --with-tree-sitter

如果有别的包没有会有提醒,我这边是

./configure --with-tree-sitter --with-gif=ifavailable --with-png=ifavailable --with-gnutls=ifavailable

但是会报找不到tree-sitter

一开始以为lib没加正确,重新配置了export LD_LIBRARY_PATH=$HOME/.local/lib/

还是一样的错误。

google搜索下试了几种方式都不行,后来只能研究configure文件,发现$PKG_CONFIG这个导致了报treee-

sitter no的错误,就尝试下载pkg-config进行make和软链接到$PATH对应目录下。因为不是root的原因,我又加

了这个export PKG_CONFIG_PATH=$HOME/.local/lib/pkgconfig

pkgconfig目录下的tree-sitter.pc我是从自己docker的arch下拷贝过来的“pacman -S tree-sitter"会

在/usr/local/lib/生成pkgconfig,到此就可以了.

重新执行命令./configure --with-tree-sitter – with-gif=ifavailable --with-png=ifavailable --with-gnutls=ifavailable

lsp-bridge

因为我写代码用的lsp客户端是lsp-bridge

需要解决python的依赖包安装和lsp服务端安装的问题。

python依赖包

先从外网下载依赖包

pip3 download epc orjson sexpdata six setuptools paramiko rapidfuzz -d 保存的目录

但是发现内网pip没有,就下载pip源码,结果又少了什么包,问题是我pip都还没成功啊,

最后找到一个解决方案: python -m ensurepip --default-pip

安装好pip后,通过pip install *.whl安装,如果安装有问题,也可以一个个的安装。

lsp服务器安装

本地先安装好lsp服务器,以前端为例:

sudo npm install -g emmet-ls

sudo npm install -g vls

sudo ngp install -g typescript

再直接把node_modules里的安装好的拷贝到内网服务器。

lsp-bridge需要

tsc 软链接成 typescript-language-server

vls 软链接成 vue-language-server

其它

为了内网使用方便,又迁移了 the_silver_searcher,ripgrep和zellij

发现其中rust开发的小工具直接二进制拷贝进来挺方便的。

最后

开心,我自己的emacs终于可以在内网正常使用了。

10 个赞

我也是在内网上用,不过我是用的guix 把 emacs 和配置依赖打成压缩包,这样解压就能用

1 个赞

感谢宣传, 很高兴 lsp-bridge 可以流畅的解决你远程代码补全的需求。 :wink:

如果有空的话, 欢迎分享内容到 lsp-bridge Wiki, lsp-bridge 的Wiki是完全公开的, 任何人都可以直接编辑。

能分享下具体的步骤吗?

好的,懒猫大大的很多插件我都在用,争取以后有机会能贡献补丁。

1 个赞

主要的步骤在这个帖子里

我也是内网非root用户,但我面临的麻烦跟题主的有所不同。姑且写在这里以供有相似需求的人参考吧。我的工作较接近高性能计算。我个人习惯用Emacs,偏偏用的一个集群上没有装Emacs。我这边是十几个人共用一个帐号,这是因为那个集群并不是什么正规的超算中心的集群,仅仅只是熟人用手头的资源搭的一个平台,把几台计算机分成了一个登录节点和多个计算节点。我没有集群的root用户,集群也连不上因特网。我想起来之前用过的一个超算中心,里面的module中有Emacs的几个版本,我便想依葫芦画瓢。

编译Emacs的时候没费什么周折,因为我正常用这个集群的时候都是命令行操作,自然在编译Emacs的时候选择了“–with-x=no”,而且我用的Emacs的版本较老。由于是共用的帐号,所以我常用的目录是/ihome/LEADER/USER这样的格式,而实际上的HOME环境变量指向的是/ihome/LEADER。我把Emacs装到了/ihome/LEADER/USER/software/emacs-24.3目录。接下来就是配置文件了。我习惯用坛友“redguardtoo”的配置文件,但我需要考虑的一个问题就是配置文件放在哪个目录,如果按照默认的话,应该是/ihome/LEADER/.emacs.d,但鉴于共用者中有一部分人主业不是高性能计算,如果我把配置文件放在/ihome/LEADER/.emacs.d的话,恐怕会带来不必要的纠纷。我想的解决方案是借鉴这一段代码 init file - Running spacemacs alongside regular emacs: how to keep a separate .emacs.d - Emacs Stack Exchange

运行

nano /ihome/LEADER/.emacs

用nano文本编辑器修改默认的配置文件。

(let* ((user-init-dir-default
    (file-name-as-directory (concat "~" init-file-user "/.emacs.d")))
       (user-init-dir
    (file-name-as-directory (or (getenv "EMACS_USER_DIRECTORY")
                    user-init-dir-default)))
       (user-init-file-1
    (expand-file-name "init" user-init-dir)))
  (setq user-emacs-directory user-init-dir)
  (setq user-init-file t)
  (load user-init-file-1 t t)
  (when (eq user-init-file t)
    (setq user-emacs-directory user-init-dir-default)
    (load (expand-file-name "init" user-init-dir-default) t t)))

(provide '.emacs)

最后按一下Ctrl+O,再按回车键就保存了,然后按一下Ctrl+X就退出nano文本编辑器了。

我把原始网页中代码里跟“with-eval-after-load”有关的一段代码删除了,因为我用不到Emacs daemon,而且跟“with-eval-after-load”有关的这段代码在我编译的Emacs上会导致报错。接下来是“redguardtoo”的配置文件。我用的是Emacs 24.3,所以从 https://github.com/redguardtoo/emacs.d/archive/2.6.zip 下载了emacs.d-2.6.zip,从 https://github.com/redguardtoo/myelpa/archive/2.6.zip 下载了myelpa-2.6.zip。 我把emacs.d-2.6.zip解压到了/ihome/LEADER/USER/emacs-configurations/24.3-init目录,把myelpa-2.6.zip解压到了/ihome/LEADER/USER/emacs-configurations/24.3-projs/myelpa目录。在/ihome/LEADER/USER/emacs-configurations/24.3-init目录下进行递归式的字符串替换,把除了README.org之外的文件中的“~/.emacs.d”替换成了“/ihome/LEADER/USER/emacs-configurations/24.3-init”,然后就是要用本地缓存的elpa了,运行

nano /ihome/LEADER/USER/emacs-configurations/24.3-init/lisp/init-elpa.el

;; (setq package-archives '(("myelpa" . "~/projs/myelpa")))

这一行改成如下内容:

(setq package-archives '(("myelpa" . "/ihome/LEADER/USER/emacs-configurations/24.3-projs/myelpa")))

然后就是第一次运行

EMACS_USER_DIRECTORY=/ihome/LEADER/USER/emacs-configurations/24.3-init /ihome/LEADER/USER/software/emacs-24.3/bin/emacs

等上一会儿就行了。

接下来就是写modulefile了。我把自己的所有modulefile放在一个目录里,就是/ihome/LEADER/USER/modulefiles,这样的话,我如果要调用自己写的modulefile的话,就是运行

module use --append /ihome/LEADER/USER/modulefiles

我在/ihome/LEADER/USER/modulefiles目录下创建了两个新目录:emacs与binchen。我在/ihome/LEADER/USER/modulefiles/emacs里面放了一个名为24.3的文件,其内容如下:

#%Module1.0#####################################################################
##
## modules emacs/24.3
##
## /ihome/LEADER/USER/modulefiles/emacs/24.3. Sample emacs module.
##
proc ModulesHelp { } {
        global version topdir

        puts stderr "emacs/$version - sets the environment for Emacs $version"
        puts stderr "\nThe software has been installed to the following directory $topdir"
        puts stderr "\nThis package does not have GUI support.\n"
}

module-whatis   "GNU Emacs"
module-whatis   "Website: https://www.gnu.org/software/emacs/"
module-whatis   "Version: 24.3"
module-whatis   "Compiler: gcc-4.8.5"

# for Tcl script use only
set     version         24.3
set     topdir          /ihome/LEADER/USER/software/emacs-24.3

conflict emacs

prepend-path    PATH                ${topdir}/bin

prepend-path    INFOPATH            ${topdir}/share/info

prepend-path    MANPATH             ${topdir}/share/man

我在/ihome/LEADER/USER/modulefiles/binchen里面放了一个名为24.3的文件,其内容如下:

#%Module1.0#####################################################################
##
## modules binchen/24.3
##
## /ihome/LEADER/USER/modulefiles/binchen/24.3. Sample binchen module.
##
proc ModulesHelp { } {
        global version topdir elpadir

        puts stderr "binchen/$version - sets the emacs setup mainly written by Bin Chen for Emacs $version"
        puts stderr "\nThe software has been installed to the following directory $topdir"
        puts stderr "\nThe local repository has been installed to the following directory $elpadir\n"
}

module-whatis   "Emacs configuration files from Bin Chen (redguardtoo)"
module-whatis   "Website: https://github.com/redguardtoo/emacs.d"
module-whatis   "Source: https://github.com/redguardtoo/emacs.d/archive/2.6.zip"
module-whatis   "Repository: https://github.com/redguardtoo/myelpa/archive/2.6.zip"
module-whatis   "This configuration is accustomed to Emacs 24.3."

# for Tcl script use only
set     version         24.3
set     topdir          /ihome/LEADER/USER/emacs-configurations/24.3-init
set     elpadir         /ihome/LEADER/USER/emacs-configurations/24.3-projs/myelpa

conflict binchen
module load emacs/${version}

unsetenv        EMACS_USER_DIRECTORY
setenv          EMACS_USER_DIRECTORY    $topdir

接下来试试看我的modulefile有没有问题

module use --append ~/USER/modulefiles
module help emacs/24.3
module what-is emacs/24.3
module help binchen/24.3
module what-is binchen/24.3

我自己需要运行Emacs的时候,就是

module use --append ~/USER/modulefiles
module load binchen/24.3
emacs

如果是其他人想要运行一个空白配置的Emacs的话,那就是运行

module use --append ~/USER/modulefiles
module load emacs/24.3
emacs

由于集群上使用的Environment Modules( https://modules.sourceforge.net/ )的版本实在太老,我连pushenv这个语法都用不了,所以我写在上面的modulefile有点臃肿。如果有人想尝试这类东西的话,我个人建议在行得通的情况下优先考虑Lmod( Lmod ),我个人认为Lmod的modulefile写起来比Environment Modules要简单。

比较不幸的是我写完了modulefile的时候才从论坛 【分享】emacs多个配置共存的思路 里看到了 GitHub - plexus/chemacs2: Emacs version switcher, improved

1 个赞