Is the error 1:1 no such buffer message an invalid issue?

…and it still worked properly.

And if you add another forward slash to HOME=$HOME// kak -n everything is working properly?

In other words, is only one of the two, but not both, so something gottta give

If it’s working let me know, so I will throw away this computer and the system behind it.

shell ignores additional slashes

mkdir -p a/b/c; cd a/////b/////////c////////////////

works in dash. I think Kakoune should handle this the same way

the problem with Kak is that it doesn’t even know what directory is on

What is ~ by the way? I don’t want to sound senile like a cranky old man, but what is ~ really?

So if any testing is goiing to be done, I’d like to know what is the rationale behind it?

for example,

what is before $ when calling the terminal ? If is ~ is wrong

If it’s the username is correct

End of the story, as simple as that

~ is tilde but what is it exactly? It doesn’t mean nothing! whereas a username for the system does

guys sorry about the last rant.

I don’t care if it’s a bug or only my bug.

The inconsistency is there as soon as a desktop.file comes into play.
Because it doesn’t really matter whether I’d have, as I did without even being fully aware of it - it was a file I have had for a while and didn’t pay attention to it - the export HOME=/home/c/ on bashrc

if I were to have on bashrc

export HOME=/home/c

or you might as well change the c to your own username in this case.

Notice that there’s no forward slash appended to the username.

then it would be reasonable by using the same example as @Screwtapello kindly provided, to say

  ~$ HOME=$HOME/ kak -n

What follows a directory after all but a path separating it from its contents?

Or don’t include the above export HOME=/home/username on bashrc and invoke on the terminal instead

 printenv $HOME

It should be the same as if you were to have it set on bashrc

Also, as I said before, I can’t confirm whether it is a bug or just my bug.

If it is a bug indeed, I don’t want be taken as the individual reporting it.

My intention with anything that I’ve written or have said on this thread or any other, has been solely as an end-user experience with the editor.

there’s nothing on my bash config file
if I were to

 $ echo $HOME
 $ /home/c

Then and based on the example

 HOME=$HOME kak -n

everything’s good.

But it’s a subtle-deceving-error, because as soon as you say escape it with

  HOME=$HOME\/ kak -n

the error comes back… because of path expansion.

What it should have been, but it’s not is

  HOME=$HOME\// kak -n

And if that’s not true, I’ll wipe my system. No good.

The kernel ignores additional slashes, so that applications can form a path with first + '/' + second without having to care whether first ends with a slash or not.

Unfortunately, this means that every other path operation gets more complex. If an application wants to compare two paths, it has to normalise them to remove the redundant slashes before comparing; /home//foo/bar and /home/foo//bar are the same path even though strcmp says they’re different.

Given the symptom that kicked off this thread was something along the lines of “doing a thing works fine to begin with, then breaks after cd”, it sounds like somebody missed a normalisation somewhere, although whether it’s in Kakoune or a shell or a GUI tool or something I have no idea.

The dash(1) manpage says:

A word beginning with an unquoted tilde character (~) is subjected to tilde expansion. All the characters up to a slash (/) or the end of the word are treated as a username and are replaced with the user’s home directory. If the username is missing (as in ~/foobar), the tilde is replaced with the value of the HOME variable (the current user’s home directory).

So ~/ is basically identical to $HOME/ as far as the shell is concerned. Kakoune does the same thing except that it only supports ~ and ~/, not ~user or $HOME.

Because ~/ generally expands to $HOME/, some tools (like Kakoune, or bash when $PS1 contains \w or \W) abbreviate $HOME/ to ~/ when it appears in a path.

I can’t help but notice that the .desktop file you quote says something like:

Exec=uxterm kak
Terminal=false

…manually running Kakoune inside a terminal, rather than:

Exec=kak
Terminal=true

…so Kakoune runs inside the system default terminal, whatever it is. That might have something to do with it.

Alternatively, it might be to do with how you log in. If you login to Linux on the console or via ssh, those systems will launch your preferred shell (probably bash) as an “interactive login shell”, so the process looks like this:

  • bash reads the “login config” file .bash_profile
  • bash reads the “interactive config” file .bashrc
  • bash prints a prompt and waits for you to type a command

That is, the contents of both .bash_profile and .bashrc are relevant.

If you login to Linux through a graphical login screen like gdm3 (the GNOME Display Manager) then launch a terminal, the process looks like this:

  • gdm3 launches /bin/sh as a non-interactive login shell to start the desktop environment
  • /bin/sh reads the “login config” file .profile
  • /bin/sh starts the desktop environment
  • the desktop environment starts your terminal
  • your terminal starts your preferred shell (probably bash) interatively
  • bash reads the “interactive config” file .bashrc
  • bash prints a prompt and waits for you to type a command

That is, the contents of .profile and .bashrc are relevant, and .bash_profile is irrelevant.

If you don’t start a terminal with a shell, but instead start a terminal running a program directly (like your .desktop entry that runs uxterm kak), then “your preferred shell” is not involved, so bashrc is never read, and only .profile is relevant.

If you login to Linux through a graphical login screen like lightdm then launch a terminal, the process looks like this:

  • lightdm launches /bin/sh as a non-interactive, non-login shell to start the desktop environment
  • /bin/sh starts the desktop environment
  • the desktop starts your terminal
  • your terminal starts your preferred shell (probably bash) interactively
  • bash reads the “interactive config” file .bashrc
  • bash prints a prompt and waits for you to type a command

That is, the contents of .bashrc is relevant, and .profile and .bash_profile are irrelevant.

Again, if you don’t start a terminal with a shell, but instead start a terminal running a program directly, then your “preferred shell” is not involved, so none of .bashrc, .profile, or .bash_profile are relevant.

Long story short: if you can at all avoid it, don’t configure interactive applications by setting environment variables, because it’s a nightmare trying to ensure that they’re set at the right times and in the right places.

2 Likes

@Screwtapello

give me a a few minutes to read your post. . As always, your input is appreciated.

@Screwtapello One if not the most thorough technical explanation I’ve seen that exclusively pertains to this issue . Great explanation.

Given the symptom that kicked off this thread was something along the lines of "doing a thing works fine to begin with, then breaks after cd ", it sounds like somebody missed a normalisation somewhere , although whether it’s in Kakoune or a shell or a GUI tool or something I have no idea.

I agree. I’ve never said otherwise.

So ~/ is basically identical to $HOME/ as far as the shell is concerned. Kakoune does the same thing except that it only supports ~ and ~/ , not ~user or $HOME .

Can this be tackled?

This is perhaps the most important part of this post alone.

I personally don’t like this issue to start with. An overhaul that It’s like @andreyorst 's absolute path quote.

If you login to Linux through a graphical login screen like gdm3 (the GNOME Display Manager) then launch a terminal, the process looks like this:
That is, the contents of .profile and .bashrc are relevant, and .bash_profile is irrelevant.

Almost, but .profile if memory helps me here overtakes. But of course, I’m not implying that .bashrc is irrelevant. Used it at one point.

If you login to Linux through a graphical login screen like lightdm then launch a terminal, the process looks like this:

good to know for posterity. Used it for a while but no longer.

But I quite don’t understand after your explanation, whatever the display manager is in use with the issue at hand.

Take that out of the assumption, because the issue with 1:1 no such buffer comes back whether there’s one or not.

Because ~/ generally expands to $HOME/ , some tools (like Kakoune, or bash when $PS1 contains \w or \W ) abbreviate $HOME/ to ~/ when it appears in a path.

As I said if

 echo $HOME
 /home/c/

then

 HOME=$HOME\/ kak works

if

 echo $HOME
 /home/c

then

 HOME=$HOME\/ kak errors 1:1 no such buffer

This is a weird one, but I think I got it clearly caught on asciinema, can you confirm this is what you are talking about @nonumeros?

https://asciinema.org/a/1chvG1TaWd2tdCD8OIdnAeBs5

What makes it interesting is three different behaviors happen.

/home/rmelton gives you a buffer named ~/Documents/atest.txt which you can switch to without issue.

/home/rmelton/ gives you a buffer named ~Documents/atest.txt which gives the error

/home/rmelton// gives you a buffer named /home/rmelton/Documents/atest.txt which you can switch to without issue.

I can make sense of the first two cases, but why does it get expanded out in the 3rd?

I did a toy patch to fix this, it removes any slashes at the end of $HOME during the compact_path and handles multiple slashes in the way @andreyorst said it should (won’t strip just one at the end, but as many as are there).

diff --git i/src/file.cc w/src/file.cc
index 52a0f288..0be76e58 100644
--- i/src/file.cc
+++ w/src/file.cc
@@ -86,7 +86,7 @@ String real_path(StringView filename)
                 return res;

             StringView dir = res;
-            if (dir.substr(dir.length()-1_byte, 1_byte) == "/")
+            while (dir.substr(dir.length()-1_byte, 1_byte) == "/")
                 dir = dir.substr(0_byte, dir.length()-1_byte);
             return format("{}/{}", dir, non_existing);
         }
@@ -115,9 +115,13 @@ String compact_path(StringView filename)
     if (prefix_match(real_filename, real_cwd))
         return real_filename.substr(real_cwd.length()).str();

-    const StringView home = homedir();
+    StringView home = homedir();
+
     if (not home.empty())
     {
+        while (home.substr(home.length()-1_byte, 1_byte) == "/")
+            home = home.substr(0_byte, home.length()-1_byte);
+
         ByteCount home_len = home.length();
         if (real_filename.substr(0, home_len) == home)
             return "~" + real_filename.substr(home_len);
@@ -405,7 +409,7 @@ String find_file(StringView filename, StringView buf_dir, ConstArrayView<String>
     {
         if (stat(filename.zstr(), &buf) == 0 and S_ISREG(buf.st_mode))
             return filename.str();
-         return "";
+        return "";
     }
     if (filename.substr(0_byte, 2_byte) == "~/")
     {
1 Like

And that lead me to seeing the hardcoded 1024 and the use of PATH_MAX, which tickled my brain because I remembered having to use a custom one because it is really busted, and refound http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html

This has been a fun rabbithole of a thread.

EDIT: More -> https://serverfault.com/questions/9546/filename-length-limits-on-linux

https://asciinema.org/a/1chvG1TaWd2tdCD8OIdnAeBs5

Robert thank you!

melton-file-list-for-error|590x354,75% .

Very nice of you. I do appreciate it.

melton-second-file-from-list-error

How the hillbillies would say, ‘I reckon you only need to escape once son’

you were running the test with say /home/melton/. And that slash itself would corroborate it if you would have echoed $HOME

Think about it for a second, it’s not quantum mechanics Schrödinger’s cat

edit

At no point the reference should be taken as an insult or disrespect. It would have taken me months if that to put the code that @robertmeta provided.

 diff --git i/src/file.cc w/src/file.cc
 index 52a0f288..0be76e58 100644
 --- i/src/file.cc
 +++ w/src/file.cc
 @@ -86,7 +86,7 @@ String real_path(StringView filename)
                  return res;
 
              StringView dir = res;
 -            if (dir.substr(dir.length()-1_byte, 1_byte) == "/")
 +            while (dir.substr(dir.length()-1_byte, 1_byte) == "/")
                  dir = dir.substr(0_byte, dir.length()-1_byte);
              return format("{}/{}", dir, non_existing);
          }
 @@ -115,9 +115,13 @@ String compact_path(StringView filename)
      if (prefix_match(real_filename, real_cwd))
          return real_filename.substr(real_cwd.length()).str();
 
 -    const StringView home = homedir();
 +    StringView home = homedir();
 +
      if (not home.empty())
      {
 +        while (home.substr(home.length()-1_byte, 1_byte) == "/")
 +            home = home.substr(0_byte, home.length()-1_byte);
 +
          ByteCount home_len = home.length();
          if (real_filename.substr(0, home_len) == home)
              return "~" + real_filename.substr(home_len);
 @@ -405,7 +409,7 @@ String find_file(StringView filename, StringView buf_dir, ConstArrayView<String>
      {
          if (stat(filename.zstr(), &buf) == 0 and S_ISREG(buf.st_mode))
              return filename.str();
 -         return "";
 +        return "";
      }
      if (filename.substr(0_byte, 2_byte) == "~/")
      {

Outstanding!

Something that I couldn’t put together.

/home/rmelton// gives you a buffer named /home/rmelton/Documents/atest.txt which you can switch to without issue.

Overanalyzing is the Achilles’ heel of very clever people. It’s an expected domain.

in my case and from the terminal

 c$ export HOME=/home/c/
 c$ echo $HOME
 c$ /home/c/   <-- notice the appended slash, the user and the home directory
 c$ HOME=$HOME // kak -n  

One ends up on the filesystem for the home director, no escaping whatsoever is needed because is already escaped by corroborating it with echo $HOME that by then should return the slash / with that very same slash appended to the home directory c, so c/

if on the other hand

  c$ export HOME=/home/c

Notice now the subtle change to

  ~$ <-- this needs to be escaped accordingly.

because if you were to say

 ~ $ and keep an eye on the ~ that needs to be escaped
 ~ $ echo $HOME  this confirms it  with the following
 ~ $ /home/c   where is my slash?

I’m going to escape it accordingly

  ~ $ HOME=$HOME\/ kak -n
  ~ $ 1:1 error no such buffer

This has been a fun rabbithole of a thread.

Indeed. Unfortunately the only lesson I learned from it and this is a jab as in Kakoune! to @Screwtapello , is: don’t assume, because you know what they say about assuming, you’re going to make an ass out of you and out of me for assuming

@mawww by reading some of your past comments - mostly from the repo site - I know you’re not very keen on adding some features to something the editor provides.

This patch path by @robertmeta takes care of the issue from this thread.

Can it be included upstream?

I tested it with some of the features I need it for, namely for hugo and some git commands, and it seems to be working…

I am putting together a more complete path handling fix for upstream.

Perfect, thank you to everyone involved in tracking that bug down.

:+1: way to go! thank you all.