1

Ex. suppose some directories are named

absorbing
appreciate
arrive
connect
depend
drop
few
fold
littlel
popcorn
shrill
sticky

In Windows, if I put _ before the directories, it would be at the top, like this.

_connect
_few
_little
_shrill
absorbing
appreciate
arrive
depend
drop
fold
popcorn
sticky

However, the same directories look the following when sorted alphabetically in Nemo 4.0.6 (to be specific, Linux Mint 19.1, Cinnamon 4.0.10)

absorbing
appreciate
arrive
_connect
depend
drop
_few
fold
_little
popcorn
_shrill
sticky

So, the sort algorithm, in Nemo is completely ignoring _ at the beginning of directory name.

I want the sorting to work like in the first listing, is there any way to do that?

Ahmad Ismail
  • 2,478
  • 1
  • 22
  • 47
  • 1
    What tool are you using (`ls`, a file-manager, …)? – ctrl-alt-delor Apr 04 '19 at 15:33
  • 3
    This is about sorting in Nemo, right? – terdon Apr 04 '19 at 15:49
  • (no time to write this up, leaving as pointer for someone) — `ls` will do this too, it's the default sorting in at least en_US.UTF-8. LC_COLLATE=C will not. – derobert Apr 04 '19 at 15:54
  • 1
    Linking in: https://unix.stackexchange.com/questions/39827/how-do-i-make-ls-sort-underscore-characters-first – Jeff Schaller Apr 04 '19 at 15:55
  • This may be a locale issue, and similar to the issue here: [Is it possible to make thunar sort by ASCII order?](//unix.stackexchange.com/q/10581) – Kusalananda Apr 04 '19 at 16:13
  • 1
    That's consistent with the [ISO14651 standard](https://standards.iso.org/iso-iec/14651/ed-4/ISO14651_2016_TABLE1_en.txt) (see line ` IGNORE;IGNORE;IGNORE; % LOW LINE` meaning `_` is to be ignored for sorting). – Stéphane Chazelas Apr 04 '19 at 16:15
  • This seems like a locale issue, the kernel doesn't sort the file names for you. It's probably configurable in other OS's too, and comparing to them doesn't really help you in finding a way to change the behaviour. – ilkkachu Apr 04 '19 at 16:20
  • 1
    If your goal is to sort the directories alphabetically before the files, there's no need to go primitive with underscores. Take a look at the `View` section of Nemo's `Preferences`. There you should find a `Sort folders before files` option to check that should do the trick. – David Yockey Aug 08 '19 at 00:03

1 Answers1

3

I tested this solution on Linux Mint 19.3.

First go ahead and read nemo file sort order differs from /bin/ls to have a little background.

We have two steps:

  1. Modify Nemo so that it sorts according to our locale.
  2. Edit /usr/share/i18n/locales/iso14651_t1_common for the locale to sort according to our linking.

Modify Nemo

The main guide in on github.

git clone https://github.com/linuxmint/nemo

Now we have to edit nemo/libnemo-private/nemo-file.c

Remove -

/* Files that start with these characters sort after files that don't. */
#define SORT_LAST_CHAR1 '.'
#define SORT_LAST_CHAR2 '#'

Replace -

static int
compare_by_display_name (NemoFile *file_1, NemoFile *file_2)
{
    const char *name_1, *name_2;
    const char *key_1, *key_2;
    gboolean sort_last_1, sort_last_2;
    int compare=0;

    name_1 = nemo_file_peek_display_name (file_1);
    name_2 = nemo_file_peek_display_name (file_2);

    sort_last_1 = name_1 && (name_1[0] == SORT_LAST_CHAR1 || name_1[0] == SORT_LAST_CHAR2);
    sort_last_2 = name_2 && (name_2[0] == SORT_LAST_CHAR1 || name_2[0] == SORT_LAST_CHAR2);

    if (sort_last_1 && !sort_last_2) {
        compare = +1;
    } else if (!sort_last_1 && sort_last_2) {
        compare = -1;
    } else if (name_1 == NULL || name_2 == NULL) {
        if (name_1 && !name_2)
            compare = +1;
        else if (!name_1 && name_2)
            compare = -1;
    } else {
        key_1 = nemo_file_peek_display_name_collation_key (file_1);
        key_2 = nemo_file_peek_display_name_collation_key (file_2);
        compare = g_strcmp0 (key_1, key_2);
    }

    return compare;
}

With -

static int
compare_by_display_name (NemoFile *file_1, NemoFile *file_2)
{
    const char *key_1, *key_2;
    int compare=0;

    key_1 = nemo_file_peek_display_name_collation_key (file_1);
    key_2 = nemo_file_peek_display_name_collation_key (file_2);
    compare = strcmp (key_1, key_2);

    return compare;
}

And Replace -

file->details->display_name_collation_key = g_utf8_collate_key_for_filename (display_name, -1);

with -

file->details->display_name_collation_key = g_utf8_collate_key (display_name, -1);

Now turn on source code repositories in Software Sources.

Then Inside nemo directory give the following commands -

sudo apt-get build-dep nemo 
dpkg-buildpackage 
cd .. && sudo dpkg -i *.deb

Then ctrlaltbackspace to restart Xorg.

enter image description here

Modify iso14651_t1_common

Open /usr/share/i18n/locales/iso14651_t1_common as admin.

Replace -

<U005F> IGNORE;IGNORE;IGNORE;<U005F> # 33 _ 

With

<U005F> <RES-2>;IGNORE;IGNORE;<U005F> # 33 _

Run sudo locale-gen

Acknowledgements

  1. Michael Webster, taught me to build nemo from source.

  2. bjd-pfq found out the issue with g_utf8_collate_key_for_filename

  3. Steven Xu Directed my towards patching Nemo.

  4. The two posts that helped me understand /usr/share/i18n/locales/iso14651_t1_common was by beandip. The answers are, How can I make “ls” show dotfiles first while staying case-insensitive? & Specify the sort order with LC_COLLATE so lowercase is before uppercase

P.S.

Previous version of this answer can be found on revisions

Ahmad Ismail
  • 2,478
  • 1
  • 22
  • 47