;;; term-compat.el ---  -*- lexical-binding: t -*-

;; Copyright (C) 2024 Benson Chu

;; Author: Benson Chu <bensonchu457@gmail.com>
;; Created: [2024-05-30 16:59]

;; This file is not part of GNU Emacs

;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;;; Code:

(require 'term/xterm)

(let ((ascii-start ? )
      (M-start ?\M-\s)
      (C-M-start ?\C-\M-\s)
      (M-S-start ?\M-\S-\s))
  (dotimes (n (1+ (- ?~ ? )))
    ))

(let ((ascii-start 97)
      (M-start ?\M-a)
      (C-M-start ?\C-\M-a)
      (M-S-start ?\M-\S-a))
  (dotimes (n 26)
    (define-key xterm-function-map
                (format "\e[27;5;%d~" (+ ascii-start n))
                (vector (1+ n)))
    (define-key xterm-function-map
                (format "\e[27;3;%d~" (+ ascii-start n))
                (vector (+ n M-start)))
    (define-key xterm-function-map
                (format "\e[27;4;%d~" (+ ascii-start n))
                (vector (+ n M-S-start)))
    (define-key xterm-function-map
                (format "\e[27;7;%d~" (+ ascii-start n))
                (vector (+ n C-M-start)))))

(define-key xterm-function-map
            "\e[27;4;13~"
            [M-S-return])

(define-key xterm-function-map
            "\e[27;5;8~"
            [C-backspace])

(define-key xterm-function-map
            "\e[27;2;127~"
            [S-backspace])

(define-key xterm-function-map
            "\e[27;5;32~"
            [?\C-\s] ;; Or (kbd "C-SPC") ;; Or [?\C- ]
            )

(define-key xterm-function-map
            "\e[27;2;32~"
            [?\S-\s])

(defun tmux-wrap-escape-sequence (sequence)
  (concat "\ePtmux;"
          (-->
           sequence
           (replace-regexp-in-string "\e" "\e\e" it))
          "\e\\"))

(defun tmux-p ()
  (not (string-empty-p (getenv "TMUX")))
  nil)

;; (xterm--init-modify-other-keys)
(defun my/xterm--init-modify-other-keys ()
  "Terminal initialization for xterm's modifyOtherKeys support."
  (let ((set-modify-other-keys
         (if (not (tmux-p))
             "\e[>4;2m"
           (tmux-wrap-escape-sequence "\e[>4;2m")))
        (unset-modify-other-keys
         (if (not (tmux-p))
             "\e[>4m"
           (tmux-wrap-escape-sequence "\e[>4m"))))
    (send-string-to-terminal set-modify-other-keys)
    (push unset-modify-other-keys (terminal-parameter nil 'tty-mode-reset-strings))
    (push set-modify-other-keys (terminal-parameter nil 'tty-mode-set-strings))))

(advice-add #'xterm--init-modify-other-keys
            :override
            #'my/xterm--init-modify-other-keys)

(setq xterm-extra-capabilities
      '(modifyOtherKeys))

(add-hook 'emacs-startup-hook
          (lambda ()
            (xterm-mouse-mode 1)
            (terminal-init-xterm)))

(defun my/org--mks-read-key-use-read-key (orig &rest args)
  (cl-letf (((symbol-function 'read-char-exclusive)
             (lambda (&optional prompt inherit-input-method seconds)
               (read-key prompt nil))))
    (apply orig args)))

(advice-add #'org--mks-read-key
            :around
            #'my/org--mks-read-key-use-read-key)

;; (global-set-key (kbd "M-[ emacs-C-SPC") #'set-mark-command)
;; (global-set-key (kbd "M-[ emacs-M-SPC") #'cycle-spacing)
;; (global-set-key (kbd "M-[ emacs-C-/") #'undo)
(global-set-key (kbd "M-[ emacs-C-<backspace>") #'backward-kill-word)

(with-eval-after-load 'org
  ;; (define-key org-mode-map (kbd "C-c M-[ emacs-C-,") #'org-insert-structure-template)
  ;; (define-key org-mode-map (kbd "M-[ emacs-C-<return>") #'org-insert-heading-respect-content)
  (define-key org-mode-map (kbd "M-[ emacs-M-S-<return>") #'org-insert-todo-heading)
  ;; (define-key org-mode-map (kbd "M-[ emacs-C-S-<return>") #'org-insert-todo-heading-respect-content)
  )

(with-eval-after-load 'vterm
  (define-key vterm-mode-map (kbd "M-[ emacs-C-<backspace>")
              #'(lambda () (interactive) (vterm-send-key "w" nil nil t))))

(provide 'term-compat)
;;; term-compat.el ends here
