alezost / guix.el

Emacs interface for GNU Guix package manager
https://emacs-guix.gitlab.io/website/
GNU General Public License v3.0
139 stars 16 forks source link

elisp: Add guix-env-var #20

Closed wigust closed 6 years ago

wigust commented 6 years ago

Hello Alex,

This patch adds a functionality to prettify files like /tmp/guix-build-hello-2.10.drv-0/environment-variables. For example, guix build --no-grafts --check -K hello will produce environment-variables which in Emacs look as:

export CPLUS_INCLUDE_PATH=\
"/gnu/store/77l8sxh9py133cy1p9kypshji4q9wv0w-bzip2-1.0.6/include\
:/gnu/store/kgaf671a9a76k0ql1pwwjxjbj80x22mj-xz-5.2.3/include\
:/gnu/store/p7vdir85501lq7qsgrx5z2yrr0py26h1-file-5.32/include\
:/gnu/store/1ymg8yf9imgw8ac4n3i611nsv1mb4643-gawk-4.1.4/include\
:/gnu/store/vj24ah9a4kqsyhim2s4n6gvc4hsxhnli-make-4.2.1/include\
:/gnu/store/j7gsbkgq72qjas7plzvak40ymf0ybamq-binutils-2.28.1/include\
:/gnu/store/cfdn69spjc44x4sd0acrwhxq6yay3rbc-gcc-5.5.0/include\
:/gnu/store/n6acaivs0jwiwpidjr551dhdni5kgpcr-glibc-2.26.105-g0890d5379c/include\
:/gnu/store/yqahwgll57j88bq275m4xvifg9x3alsb-linux-libre-headers-4.9.59/include"

export C_INCLUDE_PATH=\
"/gnu/store/77l8sxh9py133cy1p9kypshji4q9wv0w-bzip2-1.0.6/include\
:/gnu/store/kgaf671a9a76k0ql1pwwjxjbj80x22mj-xz-5.2.3/include\
:/gnu/store/p7vdir85501lq7qsgrx5z2yrr0py26h1-file-5.32/include\
:/gnu/store/1ymg8yf9imgw8ac4n3i611nsv1mb4643-gawk-4.1.4/include\
:/gnu/store/vj24ah9a4kqsyhim2s4n6gvc4hsxhnli-make-4.2.1/include\
:/gnu/store/j7gsbkgq72qjas7plzvak40ymf0ybamq-binutils-2.28.1/include\
:/gnu/store/cfdn69spjc44x4sd0acrwhxq6yay3rbc-gcc-5.5.0/include\
:/gnu/store/n6acaivs0jwiwpidjr551dhdni5kgpcr-glibc-2.26.105-g0890d5379c/include\
:/gnu/store/yqahwgll57j88bq275m4xvifg9x3alsb-linux-libre-headers-4.9.59/include"

export GUIX_LOCPATH="/gnu/store/q7jz2as54ycdvjg7zggxxjkxjrp6d5mr-glibc-utf8-locales-2.26.105-g0890d5379c/lib/locale"

export HOME="/homeless-shelter"

export LC_ALL="en_US.utf8"

export LIBRARY_PATH=\
"/gnu/store/77l8sxh9py133cy1p9kypshji4q9wv0w-bzip2-1.0.6/lib\
:/gnu/store/kgaf671a9a76k0ql1pwwjxjbj80x22mj-xz-5.2.3/lib\
:/gnu/store/p7vdir85501lq7qsgrx5z2yrr0py26h1-file-5.32/lib\
:/gnu/store/1ymg8yf9imgw8ac4n3i611nsv1mb4643-gawk-4.1.4/lib\
:/gnu/store/j7gsbkgq72qjas7plzvak40ymf0ybamq-binutils-2.28.1/lib\
:/gnu/store/n6acaivs0jwiwpidjr551dhdni5kgpcr-glibc-2.26.105-g0890d5379c/lib\
:/gnu/store/hrhxx37z97j7pniyr437illc0b5qq9pa-glibc-2.26.105-g0890d5379c-static/lib\
:/gnu/store/q7jz2as54ycdvjg7zggxxjkxjrp6d5mr-glibc-utf8-locales-2.26.105-g0890d5379c/lib"

export NIX_BUILD_CORES="3"

export NIX_BUILD_TOP="/tmp/guix-build-hello-2.10.drv-0"

export NIX_STORE="/gnu/store"

export OLDPWD

export PATH=\
"/gnu/store/k9slb2ysqp2n82pl6knb2isapav81dvx-tar-1.29/bin\
:/gnu/store/4r1g01m0isdfd4ahd8qigfp04276biv3-gzip-1.8/bin\
:/gnu/store/77l8sxh9py133cy1p9kypshji4q9wv0w-bzip2-1.0.6/bin\
:/gnu/store/kgaf671a9a76k0ql1pwwjxjbj80x22mj-xz-5.2.3/bin\
:/gnu/store/p7vdir85501lq7qsgrx5z2yrr0py26h1-file-5.32/bin\
:/gnu/store/rp61rxvajx4w1k0ci2nqi10y8xgds53b-diffutils-3.6/bin\
:/gnu/store/5gq1gn722zpz1crsnfmxij21zdxqj37x-patch-2.7.5/bin\
:/gnu/store/z24b9d81w7bfcyk3j73xixygwx2ymlhv-sed-4.4/bin\
:/gnu/store/0qxdnkyh0cqwflxhqa4v4vsjwff08j9p-findutils-4.6.0/bin\
:/gnu/store/1ymg8yf9imgw8ac4n3i611nsv1mb4643-gawk-4.1.4/bin\
:/gnu/store/5jhfm3r3h7cjl8qqc86rx70nw7bzizpf-grep-3.1/bin\
:/gnu/store/6i33ik7haav0hd5a797l3llkq04ghx6g-coreutils-8.28/bin\
:/gnu/store/vj24ah9a4kqsyhim2s4n6gvc4hsxhnli-make-4.2.1/bin\
:/gnu/store/icz3hd36aqpjz5slyp4hhr8wsfbgiml1-bash-minimal-4.4.12/bin\
:/gnu/store/37h89zknsp0p6nsszc1n4lyxc9s393ak-ld-wrapper-0/bin\
:/gnu/store/j7gsbkgq72qjas7plzvak40ymf0ybamq-binutils-2.28.1/bin\
:/gnu/store/cfdn69spjc44x4sd0acrwhxq6yay3rbc-gcc-5.5.0/bin\
:/gnu/store/n6acaivs0jwiwpidjr551dhdni5kgpcr-glibc-2.26.105-g0890d5379c/bin\
:/gnu/store/n6acaivs0jwiwpidjr551dhdni5kgpcr-glibc-2.26.105-g0890d5379c/sbin"

export PWD="/tmp/guix-build-hello-2.10.drv-0/hello-2.10"

export SHLVL="1"

export SOURCE_DATE_EPOCH="1"

export TEMP="/tmp/guix-build-hello-2.10.drv-0"

export TEMPDIR="/tmp/guix-build-hello-2.10.drv-0"

export TMP="/tmp/guix-build-hello-2.10.drv-0"

export TMPDIR="/tmp/guix-build-hello-2.10.drv-0"

export out="/gnu/store/x9m1q4l4d768lhli6wyrkm16q220ly7q-hello-2.10"
alezost commented 6 years ago

Hello, Oleg!

I have not looked at the code closely yet, but I have several comments. At first, thank you! I often wanted to have a possibility to "indent" all these guix paths that I saw here and there.

Thank you!

alezost commented 6 years ago

What I don't like, is when I switch to another mode (like M-x sh-mode), all this indentation stays the same.

I have suddenly recalled that there is guix-scheme-mode that does a similar thing (for such files as /var/guix/profiles/system/boot). I also didn't like this behaviour at that time, that's why I added a message "This buffer has been indented byguix-scheme-mode'."`

Now I see, that it is problematic to restore the original indentation, so I think it's not worth borthering. But adding a similar message (so that a user can see that something happened with the "real" contents of the buffer) would be good. And maybe even adding a variable (like guix-env-var-enable-formatting) that will control whether a buffer will be indented by default or not.

wigust commented 6 years ago

Hello Alex,

Apologies for a long reply.

I applied all your suggestions and pushed a commit. Please, take a look on it.

Thanks, Oleg.

wigust commented 6 years ago

A patch to simplify guix-env-var-prettify-variable procedure:

diff --git a/elisp/guix-env-var.el b/elisp/guix-env-var.el
index 4a83373..ef4ed72 100644
--- a/elisp/guix-env-var.el
+++ b/elisp/guix-env-var.el
@@ -84,12 +84,11 @@ indented (while the original buffer file may not be indented).")
       (when (search-forward "=" nil t)
         (insert "\\")
         (newline)
-        (while (search-forward ":" nil t)
-          (when (char-equal ?/ (following-char))
-            (backward-char)
-            (insert "\\")
-            (newline)
-            (forward-char))))
+        (while (search-forward ":/" nil t)
+          (backward-char 2)
+          (insert "\\")
+          (newline)
+          (forward-char)))
       (end-of-line)
       (widen))))
wigust commented 6 years ago

My main question is: I don't understand why you use guix-env-var-derived-sh-modes, guix-env-var-mode-eq and guix-env-var-mode-p.

Let's take a piece of /etc/profile as an example:

# Crucial variables that could be missing in the profiles' 'etc/profile'
# because they would require combining both profiles.
# FIXME: See <http://bugs.gnu.org/20255>.
export MANPATH=$HOME/.guix-profile/share/man:/run/current-system/profile/share/man
export INFOPATH=$HOME/.guix-profile/share/info:/run/current-system/profile/share/info
export XDG_DATA_DIRS=$HOME/.guix-profile/share:/run/current-system/profile/share
export XDG_CONFIG_DIRS=$HOME/.guix-profile/etc/xdg:/run/current-system/profile/etc/xdg

Evaluation of (search-forward-regexp guix-env-var-regexp nil t) procedure in a fundamental-mode will move a cursor from a beginning of a buffer to (a pipe symbol):

export MANPATH=|$HOME/.guix-profile/share/man:/run/current-system/profile/share/man

but in sh-mode the cursor will be one character behind:

export MANPATH|=$HOME/.guix-profile/share/man:/run/current-system/profile/share/man

Are they really needed?

I wrote a first implementation without sh-mode derivation and found this issue after making guix-env-var-mode derived from sh-mode. guix-env-var-prettify-buffer will fail in case when you use call it directly without guix-env-var-mode.

Why do you autoload guix-env-var-prettify-variable and guix-env-var-prettify-buffer? Also why guix-env-var-prettify-variable is interactive? Is it intended for users?

Yes, both procedures are indented for users and autoloaded to make them available after starting Emacs. I'm sorry about forgetting to make guix-env-var-prettify-buffer interactive.

I applied all your suggestions and pushed a new commit.

alezost commented 6 years ago

Evaluation of (search-forward-regexp guix-env-var-regexp nil t) procedure in a fundamental-mode will move a cursor from a beginning of a buffer to (a pipe symbol): [...] but in sh-mode the cursor will be one character behind:

Ah, that's because modes define symbol syntax differently (and I think fundamental-mode does not define it at all). What about fixing regexp instead? (I really think that this "mode-checking" workaround is the wrong way). For example, like this:

(defvar guix-env-var-regexp
  (rx "export" (one-or-more space)
      letter (zero-or-more (or alphanumeric "_")))
  "Regexp matching shell variables in Guix environment-variables file.")

BTW I think (char space) is not correct as potentially there may be several spaces after export, so I changed it to (one-or-more space). WDYT?

wigust commented 6 years ago

Apologies for the last push, I was hurry and didn't check it properly. Don't look on this, because it's broken.

wigust commented 6 years ago

Actually it was OK, except I forgot to remove functions related to major mode.

I've applied all your suggestions. Thank you.

Also I found a bug with guix-env-var-prettify-buffer procedure didn't prettify from a start of a buffer but from a current cursor position. Fixed in the last pushed commit.

alezost commented 6 years ago

Great, I made some minor changes and applied as commit 87a8c12210e8c3b853f95900eae72fb13411a130, thank you!

Oh, also I plan to make a release soon (hopefully soon enough :-)), is there anything you are willing to add/modify before the release?

wigust commented 6 years ago

[…]

is there anything you are willing to add/modify before the release?

I have some useful things in my .emacs which users could find useful.

backward-paragraph and forward-paragraph in shell

First of all for guix package --search=git inside M-x shell

Snippet, which make a use of backward-paragraph and forward-paragraph procedures easier.

(add-hook 'shell-mode-hook
          (lambda ()
            (progn (setq paragraph-separate "[  ]*$")
                   (setq paragraph-start "\\|[     ]*$"))))

For example, without the snippet the cursor after invoking backward-paragraph two times, will be at the following line:

+ <http://dblp.uni-trier.de/search/>)

in:

guix package --search=git

[…]

+ <http://dblp.uni-trier.de/search/>)
+ 
+ * To check whether an article is freely available online, use ‘x’ in the list of
+ results.  For example ‘M-x crossref-lookup RET Emacs stallman RET’ followed by ‘x
+ Dissemin RET’ will help you find open access copies of Stallman's paper on EMACS
+ (spoiler: http://hdl.handle.net/1721.1/5736).
+ 
+ See http://github.com/cpitclaudel/biblio.el for more information, including
+ documentation on extending this framework.
relevance: 2

[more packages …]

name: audacity
[more audacity fields…]
description: Audacity is a multi-track audio editor designed for recording, playing
+ and editing digital audio.  It features digital effects and spectrum analysis
+ tools.
relevance: 2

name: alsa-modular-synth
version: 2.1.2
outputs: out
systems: x86_64-linux i686-linux armhf-linux aarch64-linux
dependencies: alsa-lib-1.1.5 clalsadrv-2.0.0 fftw-3.3.5 jack-0.125.0 ladspa-1.13
+ liblo-0.29 pkg-config-0.29.2 qtbase-5.9.4 qttools-5.9.4
location: gnu/packages/audio.scm:97:2
homepage: http://alsamodular.sourceforge.net/
license: GPL 2
synopsis: Realtime modular synthesizer and effect processor  
description: AlsaModularSynth is a digital implementation of a classical analog
+ modular synthesizer system.  It uses virtual control voltages to control the
+ parameters of the modules.  The control voltages which control the frequency e.g.
+ of the VCO (Voltage Controlled Oscillator) and VCF (Voltage Controlled Filter)
+ modules follow the convention of 1V / Octave.
relevance: 2

natsu@magnolia ~$ 

but with a snippet the cursor will jump between empty lines (one line above name:).

more ffap

I have an advised find-file-at-point procedure, which allows to call ffap on:

Misc

Procedure which opens a selected email in Gnus *Summary* buffer in an Emacs debbugs.

Procedure to copy a HTML URL to current selected node in Info.

Procedure to show a commit hash at point in Magit in Guix repository.

alezost commented 6 years ago

Snippet, which make a use of backward-paragraph and forward-paragraph procedures easier.

(add-hook 'shell-mode-hook
          (lambda ()
            (progn (setq paragraph-separate "[    ]*$")
                   (setq paragraph-start "\\|[   ]*$"))))

Hm, I think this is more a general thing than a guix-specific setting.

I have an advised find-file-at-point procedure, which allows to call ffap on:

  • /gnu/store/…-package-version to invoke find /gnu/store/…-package-version in shell.
  • /gnu/store/…-package-version.tar.gz to invoke tar xf /gnu/store/…-package-version.tar.gz in shell.

To be honest, I think these are personal settings, that people do in their emacs config files.

  • DOCUMENTATION.info or DOCUMENTATION.info.gz to invoke (info DOCUMENTATION).

  • Same for man pages. [...] Misc

  • Procedure which opens a selected email in Gnus Summary buffer in an Emacs debbugs.

  • Procedure to copy a HTML URL to current selected node in Info.

  • Procedure to show a commit hash at point in Magit in Guix repository.

These are also general things, not specific to guix. BTW, regarding info: if you use (require 'dired-x), you can press I in a dired buffer to invoke info on the current file.

Sorry, if I wasn't polite, I really think these settings are just some personal preferences and customizations. My .emacs is full of similar hacky things, but I doubt they should be put in a package form. So I think they probably shouldn't go to Emacs-Guix, but it's worth mentioning on a guix mailing list if you want to share your knowledge.

Anyway, thanks!

wigust commented 6 years ago

Thank you for pointing onto dired-x package! I'll close the pull request.