Emacs Patches

2024-09-08
4 min read

Some emacs features need to be implement with patches. let’s make a patch and apply it.

Why?

Some emacs features need to be implement with patches,because some of the features do not accept by the git repositorys author,we could use patches to modified the source code and then compile it.
The principle of patch is apply git diff after git clone so that the source code modified is out of the main branch.

How?

Make patches of emacs you need clone emacs-mirror and then modify your custom code and commit your code.Noties we can not push the commit to the git repository lack of the authority.
Use `git format-patch -1` make a new patches of last commit.

Make a emacs patch

Cursor animation is a awesome feature.you could find the patches code in the neo-emacs here.It works well on emacs30 but failed on emacs31.So let’s make a new patch for emacs31.

  1. Use `git clone git@github.com:emacs-mirror/emacs.git`.

  2. Compare with https://github.com/sincebyte/neo-emacs/blob/master/patches/cursor-animation.patch and apply the changes.We found there have 2 file changes src/nsterm.h src/nsterm.m,Notice use one commit else it will generate 2 patches.

  3. After modified the source code use `git format-patch -1` to generate a new patch.
    For some reason this step might repeat many times so git rebase interactive could help. Use git rebase interactive could make many different neighbor commit squash into one.Use `git rebase -i HEAD~2` for squash the last 2 commits,It will launch vim help your selection interactively.As you see commits order by commit time ascedly.

     1      pick 79127d8 fix:
     2      pick 3a183a9 fix:
     3  
     4      # Rebase 358208d..79127d8 onto 358208d (1 command)
     5      #
     6      # Commands:
     7      # p, pick <commit> = use commit
     8      # r, reword <commit> = use commit, but edit the commit message
     9      # e, edit <commit> = use commit, but stop for amending
    10      # s, squash <commit> = use commit, but meld into previous commit
    11      # f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
    12      #                    commit's log message, unless -C is used, in which case
    13      #                    keep only this commit's message; -c is same as -C but
    

    Just change the bottom commit’s commands to squash,below we have the example.Use :wq to confirm your rebase,then git will launch another vim for a new commit.After that you could see we have successfully squash 2 commit into one.

    1      pick 79127d8 fix:
    2      squash 3a183a9 fix:
    3  
    4      :wq
    
  4. Now It’s time to make a patch file. It’s simple just use `git format-patch -1` and then there will generate a patch file on the git root dir.We could have a look about it.

     1     From 79127d822df37df8c8ce1fa3415a649a931e3862 Mon Sep 17 00:00:00 2001
     2     From: "liu.zijie" <at18708169062@gmail.com>
     3     Date: Sat, 7 Sep 2024 18:45:28 +0800
     4     Subject: [PATCH] fix:
     5  
     6     fix: animation cursor
     7  
     8     feat: 1
     9  
    10     fix: return
    11  
    12     fix: return 2
    13     ---
    14     src/nsterm.h |  1 +
    15     src/nsterm.m | 65 +++++++++++++++++++++++++---------------------------
    16     2 files changed, 32 insertions(+), 34 deletions(-)
    17  
    18     diff --git a/src/nsterm.h b/src/nsterm.h
    19     index 6c67653..480f9fe 100644
    20     --- a/src/nsterm.h
    21     +++ b/src/nsterm.h
    22     @@ -485,6 +485,7 @@ enum ns_return_frame_mode
    23     struct frame *emacsframe;
    24     int scrollbarsNeedingUpdate;
    25     NSRect ns_userRect;
    26     +  CALayer *cursor_layer;
    27     }
    28  
    29     /* AppKit-side interface */
    30     diff --git a/src/nsterm.m b/src/nsterm.m
    31     index 8c40573..b43abec 100644
    32     --- a/src/nsterm.m
    33     +++ b/src/nsterm.m
    

Config patch for emacs-plus

It depends on your compile method,I recommend use emacs-plus to install emacs.Emacs-plus will compile locally prevent some of platform compatibility issues.Before install will need know how to apply patch for emacs plus.Different version of emacs have different formula file.For emacs31 it’s /opt/homebrew/Library/Taps/d12frosted/homebrew-emacs-plus/Formula/emacs-plus@31.rb.Find the chunk of patches here define patches.Only ns-alpha-background and cursor animation was defined by me,the rest of them was defined by emacs-plus offically.
Every patch need config a sha value which you could obtain it by sha256 command.

 1  #
 2  # Patches
 3  #
 4  
 5  opoo "The option --with-no-frame-refocus is not required anymore in emacs-plus@31." if build.with? "no-frame-refocus"
 6  local_patch "fix-window-role", sha: "1f8423ea7e6e66c9ac6dd8e37b119972daa1264de00172a24a79a710efcb8130"
 7  local_patch "system-appearance", sha: "9eb3ce80640025bff96ebaeb5893430116368d6349f4eb0cb4ef8b3d58477db6"
 8  local_patch "poll", sha: "59e876f82e6fd8e4583bc2456339eda4f989c86b1e16a02b0726702e95f60825" if build.with? "poll"
 9  local_patch "round-undecorated-frame", sha: "7451f80f559840e54e6a052e55d1100778abc55f98f1d0c038a24e25773f2874"
10  local_patch "ns-alpha-background", sha: "6c174aff2602b64255ce8952f91302ede51e213be090f1b39e06913bbe0b086b"
11  local_patch "cursor-animation", sha: "27cfa478208d93590804e3e98a97f18c5983a3e7c5619dff5d8eeac00719a813"

Locate patch

The question is where did emacs-plus find the patch files?In fact this is predefined.The location was opt/homebrew/Library/Taps/d12frosted/homebrew-emacs-plus/patches.Different version of emacs have different patch dir.For emacs 31 we need locate to a sub-dir named emacs-31.

Apply patch

Now it’s time to apply the patch.

brew reinstall emacs-plus@31 --with-modern-papirus-icon --with-imagemagick --with-native-comp

When emacs compile and install verify them,maybe some bugs remain,else just enjoy them.