Subject: Re: bug#44272: guix edit doesn't work when $EDITOR is set to VSCode

From: Simon Tournier <[email-masked]>
Date: Thu, 02 Nov 2023 10:32:27 +0100

Hi,

PS: I write it here for later discovery.  The bug remains closed. :-)  I
will open another thread for discussing it.

On Wed, 28 Oct 2020 at 15:52, zimoun <[email-masked]> wrote:

> Instead ’kate’ use ’--line/-l’ and not ’+N’.  You could wrap, something
> along these lines:
>
> #!/bin/sh
>
> kate -l $(echo "$*" | tr "+" " ")
>
> then:
>
>   export EDITOR=/path/to/kate-wrapper.sh
>   guix edit emacs

VSCode does not respect the usual convention, too!  For instance,

    $ code +9 path/to/file

open files named “+9” and “path/to/file”.  Instead, VSCode expects:

    $ code --goto path/to/file:9

Therefore, it makes annoying to use VSCode with “guix edit”.  Here a
tiny wrapper to still be able to compose the both.  Well,

    $ EDITOR=vscode-wrapper guix edit hello

opens at the correct location.

Cheers,
simon

--8<---------------cut here---------------start------------->8---
#!/usr/bin/env -S guix repl -q --
;; -*- mode: scheme -*-
!#
;;; Copyright © 2023 Simon Tournier <[email-masked]>

;;;
;;; VSCode does not respect the convention:
;;;
;;;     $EDITOR +line file
;;;
;;; and instead relies on:
;;;
;;;     code --goto file:line
;;;
;;;
;;; This wrapper is a workaround.  It is Scheme but it could be whatever else
;;; as Bash, Python, etc.  It uses "guix repl" although no Guix library is
;;; required.  Because we assume the invokation,
;;;
;;;     EDITOR=vscode-wrapper guix edit foo bar
;;;
;;; relying on "guix repl" allows to easily get Guile.
;;;

(use-modules (ice-9 match)
             ((ice-9 string-fun) #:select (string-replace-substring)))

(define %vscode--goto "code --goto ")

(define +line-files
  (match (command-line)
    ((wrapper rest ...)
     (if (eqv? 0 (modulo (length rest) 2))
         rest
         (begin
           (write "Error with 'guix edit'")
           (exit 1))))))

(define files
  (let loop ((files:lines '())
             (lst +line-files))
    (if (null? lst)
        (reverse files:lines)
        (match lst
          ((n file rest ...)
           (loop
            (cons (string-append
                   file ":" (string-replace-substring n "+" ""))
                  files:lines)
            rest))))))

(catch 'system-error
  (lambda ()
    (for-each (lambda (file)
                (system (string-append
                         %vscode--goto file)))
              files))
  (lambda _
    (write "failed to launch!")))
--8<---------------cut here---------------end--------------->8---