pkg update and first config fix

org-brain not working, add org-roam
This commit is contained in:
2022-12-19 23:02:34 +01:00
parent 02b3e07185
commit 82f05baffe
885 changed files with 356098 additions and 36993 deletions

View File

@@ -42,6 +42,15 @@ if (USE_SYSTEM_LIBVTERM)
# add_compile_definitions(VTermStringFragmentNotExists)
add_definitions(-DVTermStringFragmentNotExists)
endif()
execute_process(COMMAND grep -c "VTermSelectionMask" "${LIBVTERM_INCLUDE_DIR}/vterm.h" OUTPUT_VARIABLE VTermSelectionMaskExists)
if (${VTermSelectionMaskExists} EQUAL "0")
# add_compile_definitions(VTermStringFragmentNotExists)
add_definitions(-DVTermSelectionMaskNotExists)
endif()
execute_process(COMMAND grep -c "sb_clear" "${LIBVTERM_INCLUDE_DIR}/vterm.h" OUTPUT_VARIABLE VTermSBClearExists)
if (${VTermSBClearExists} EQUAL "0")
add_definitions(-DVTermSBClearNotExists)
endif()
else()
message(STATUS "System libvterm not found: libvterm will be downloaded and compiled as part of the build process")
endif()
@@ -63,8 +72,8 @@ else()
endif()
ExternalProject_add(libvterm
GIT_REPOSITORY https://github.com/neovim/libvterm.git
GIT_TAG 54c03b21f763fa775a4c0643a9d8326342873179
GIT_REPOSITORY https://github.com/Sbozzolo/libvterm-mirror.git
GIT_TAG 64f1775952dbe001e989f2ab679563b54f2fca55
CONFIGURE_COMMAND ""
BUILD_COMMAND ${LIBVTERM_BUILD_COMMAND} "CFLAGS='-fPIC'"
BUILD_IN_SOURCE ON

View File

@@ -68,7 +68,7 @@ Before installing emacs-libvterm, you need to make sure you have installed
3. libtool-bin (related issues:
[#66](https://github.com/akermu/emacs-libvterm/issues/66)
[#85](https://github.com/akermu/emacs-libvterm/issues/85#issuecomment-491845136))
4. OPTIONAL: [libvterm](https://github.com/neovim/libvterm) (>= 0.1). This
4. OPTIONAL: [libvterm](https://github.com/Sbozzolo/libvterm-mirror.git) (>= 0.2). This
library can be found in the official repositories of most distributions
(e.g., Arch, Debian, Fedora, Gentoo, openSUSE, Ubuntu). Typical names are
`libvterm` (Arch, Fedora, Gentoo, openSUSE), or `libvterm-dev` (Debian,
@@ -114,7 +114,7 @@ always want to use the vendored version as opposed to the one on you system, set
Build the module with:
``` sh
```sh
cd emacs-libvterm
mkdir -p build
cd build
@@ -124,7 +124,7 @@ make
And add this to your `init.el`:
``` elisp
```elisp
(add-to-list 'load-path "path/to/emacs-libvterm")
(require 'vterm)
```
@@ -153,23 +153,28 @@ There are a few options for installing Emacs27 on Ubuntu 20.04:
In any case, if you have an older Emacs version you will need to purge it before proceeding:
#### Purge Emacs
```sh
sudo apt --purge remove emacs
sudo apt autoremove
```
#### Installing Emacs27 from Kevin Kelley PPA
```sh
sudo add-apt-repository ppa:kelleyk/emacs
sudo apt install emacs27
```
##### If you get an error about emacs27_common during the install process:
```sh
Errors were encountered while processing:
/tmp/apt-dpkg-install-RVK8CA/064-emacs27-common_27.1~1.git86d8d76aa3-kk2+20.04_all.deb
```
run
```sh
sudo apt --purge remove emacs-common
sudo apt --fix-broken install
@@ -177,12 +182,14 @@ sudo apt --fix-broken install
#### Installing Emacs27 from Snap
I hesitate to include SNAP here, because I ran into a number of GTK Theme parsing errors, and Fontconfig errors when I tested it, and reverted to installing from Kevin Kelley's PPA. YMMV
```sh
sudo snap install emacs --classic
```
#### Install CMake and Libtool
In Ubuntu 20.04 CMake (v3.16.3-1ubuntu1) and Libtool can be installed with
```sh
sudo apt install cmake
sudo apt install libtool
@@ -200,6 +207,7 @@ The binary in Ubuntu Emacs Lisp PPA is currently broken and leads to segmentatio
(see [#185](https://github.com/akermu/emacs-libvterm/issues/185#issuecomment-562237077)).
In case Emacs is already on the system, you need to purge it before proceeding
with the following commands.
```sh
sudo add-apt-repository ppa:kelleyk/emacs
sudo apt update
@@ -207,6 +215,7 @@ sudo apt-get install emacs26
```
A way to install a recent version of CMake (>= 3.11) is with linuxbrew.
```sh
brew install cmake
```
@@ -240,9 +249,10 @@ via properly escaped sequences. A function that helps in this task,
readme.
For `bash` or `zsh`, put this in your `.zshrc` or `.bashrc`
```bash
vterm_printf(){
if [ -n "$TMUX" ] && ([ "${TERM%%-*}" = "tmux" ] || [ "${TERM%%-*}" = "screen" ] ); then
```sh
vterm_printf() {
if [ -n "$TMUX" ] && ([ "${TERM%%-*}" = "tmux" ] || [ "${TERM%%-*}" = "screen" ]); then
# Tell tmux to pass the escape sequences through
printf "\ePtmux;\e\e]%s\007\e\\" "$1"
elif [ "${TERM%%-*}" = "screen" ]; then
@@ -253,10 +263,12 @@ vterm_printf(){
fi
}
```
This works also for `dash`.
For `fish` put this in your `~/.config/fish/config.fish`:
```bash
```fish
function vterm_printf;
if begin; [ -n "$TMUX" ] ; and string match -q -r "screen|tmux" "$TERM"; end
# tell tmux to pass the escape sequences through
@@ -309,23 +321,27 @@ with the `clear` function provided by the shell to clear both screen and
scrollback. In order to achieve this behavior, you need to add a new shell alias.
For `zsh`, put this in your `.zshrc`:
```zsh
```zsh
if [[ "$INSIDE_EMACS" = 'vterm' ]]; then
alias clear='vterm_printf "51;Evterm-clear-scrollback";tput clear'
fi
```
For `bash`, put this in your `.bashrc`:
```bash
if [[ "$INSIDE_EMACS" = 'vterm' ]]; then
function clear(){
function clear() {
vterm_printf "51;Evterm-clear-scrollback";
tput clear;
}
fi
```
For `fish`:
```
```fish
if [ "$INSIDE_EMACS" = 'vterm' ]
function clear
vterm_printf "51;Evterm-clear-scrollback";
@@ -333,6 +349,7 @@ if [ "$INSIDE_EMACS" = 'vterm' ]
end
end
```
These aliases take advantage of the fact that `vterm` can execute `elisp`
commands, as explained below.
@@ -420,23 +437,29 @@ to which all the vterm buffers will be named "vterm TITLE".
This requires some shell-side configuration to print the title. For example to
set the name "HOSTNAME:PWD", use can you the following:
For `zsh`
For `zsh`,
```zsh
autoload -U add-zsh-hook
add-zsh-hook -Uz chpwd (){ print -Pn "\e]2;%m:%2~\a" }
```
For `bash`,
```bash
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND; }"'echo -ne "\033]0;${HOSTNAME}:${PWD}\007"'
```
For `fish`,
```fish
function fish_title
hostname
echo ":"
pwd
prompt_pwd
end
```
See [zsh and bash](http://tldp.org/HOWTO/Xterm-Title-4.html) and [fish
documentations](https://fishshell.com/docs/current/#programmable-title).
@@ -455,11 +478,23 @@ or remove it from `vterm-mode-map`. By default, `vterm.el` binds most of the
like `<backspace>` and `<return>`. Sending a keyboard interrupt is bound to `C-c
C-c`.
In order to send a keypress that is already recognized by Emacs, such as `C-g`,
use the interactive function `vterm-send-next-key`. This can be bound to a key
in the `vterm-mode-map` like `C-q`, in which case pressing `C-q C-g` will send a
`C-g` key to the terminal, and so on for other modified keys:
```elisp
(define-key vterm-mode-map (kbd "C-q") #'vterm-send-next-key)
```
This can be useful for controlling an application running in the terminal, such
as Emacs or Nano.
## Fonts
You can change the font (the _face_) used in a vterm with the following code:
``` emacs
```elisp
(add-hook 'vterm-mode-hook
(lambda ()
(set (make-local-variable 'buffer-face-mode-face) 'fixed-pitch)
@@ -525,7 +560,7 @@ For `zsh`, put this at the end of your `.zshrc`:
```zsh
vterm_prompt_end() {
vterm_printf "51;A$(whoami)@$(hostname):$(pwd)";
vterm_printf "51;A$(whoami)@$(hostname):$(pwd)"
}
setopt PROMPT_SUBST
PROMPT=$PROMPT'%{$(vterm_prompt_end)%}'
@@ -555,14 +590,15 @@ function fish_prompt --description 'Write out the prompt; do not replace this. I
vterm_prompt_end
end
```
Here we are using the function `vterm_printf` that we have discussed above, so make
sure that this function is defined in your configuration file.
Directory tracking works on remote servers too. In case the hostname of your
remote machine does not match the actual hostname needed to connect to that
server, change `$(hostname)` with the correct one. For example, if the correct
hostname is `foo` and the username is `bar`, you should have something like
```bash
HOSTNAME=foo
USER=baz
@@ -573,11 +609,14 @@ vterm_printf "51;A$USER@$HOSTNAME:$(pwd)"
`vterm` can read and execute commands. At the moment, a command is
passed by providing a specific escape sequence. For example, to evaluate
``` elisp
```elisp
(message "Hello!")
```
use
``` sh
```sh
printf "\e]51;Emessage \"Hello\!\"\e\\"
# or
vterm_printf "51;Emessage \"Hello\!\""
@@ -590,6 +629,7 @@ and backslashes need to be escaped via backslash. A convenient shell function to
automate the substitution is
`bash` or `zsh`:
```sh
vterm_cmd() {
local vterm_elisp
@@ -601,8 +641,10 @@ vterm_cmd() {
vterm_printf "51;E$vterm_elisp"
}
```
`fish`:
```sh
```fish
function vterm_cmd --description 'Run an Emacs command among the ones been defined in vterm-eval-cmds.'
set -l vterm_elisp ()
for arg in $argv
@@ -625,6 +667,7 @@ say() {
```
Or for `fish`:
```fish
function find_file
set -q argv[1]; or set argv[1] "."
@@ -641,13 +684,14 @@ This newly defined `find_file` function can now be used inside `vterm` as
```sh
find_file name_of_file_in_local_directory
```
If you call `find_file` without specifying any file (you just execute `find_file` in your shell),
`dired` will open with the current directory.
As an example, say you like having files opened below the current window. You
could add the command to do it on the lisp side like so:
``` elisp
```elisp
(push (list "find-file-below"
(lambda (path)
(if-let* ((buf (find-file-noselect path))
@@ -688,7 +732,7 @@ in the EMACS_VTERM_PATH inside the /etc sub-directory. After a package update, t
so, a code like this in your bashrc could be enough to load always the latest version of the file
from the right location without coping any file manually.
```
```sh
if [[ "$INSIDE_EMACS" = 'vterm' ]] \
&& [[ -n ${EMACS_VTERM_PATH} ]] \
&& [[ -f ${EMACS_VTERM_PATH}/etc/emacs-vterm-bash.sh ]]; then
@@ -718,16 +762,19 @@ The version of `libvterm` installed on your system is too old. You should let
`emacs-libvterm` download `libvterm` for you. You can either uninstall your
libvterm, or instruct Emacs to ignore the system libvterm. If you are compiling
from Emacs, you can do this by setting:
```emacs-lisp
```elisp
(setq vterm-module-cmake-args "-DUSE_SYSTEM_LIBVTERM=no")
```
and compile again. If you are compiling with CMake, use the flag
`-DUSE_SYSTEM_LIBVTERM=no`.
### `<C-backspace>` doesn't kill previous word.
This can be fixed by rebinding the key to what `C-w` does:
```emacs-lisp
```elisp
(define-key vterm-mode-map (kbd "<C-backspace>")
(lambda () (interactive) (vterm-send-key (kbd "C-w"))))
```
@@ -736,7 +783,8 @@ This can be fixed by rebinding the key to what `C-w` does:
Add this piece of code to your configuration file to make `counsel` use
the correct function to yank in vterm buffers.
```emacs-lisp
```elisp
(defun vterm-counsel-yank-pop-action (orig-fun &rest args)
(if (equal major-mode 'vterm-mode)
(let ((inhibit-read-only t)
@@ -755,7 +803,8 @@ We recommend that you set up shell-side configuration for reliable directory
tracking. If you cannot do it, a possible workaround is the following.
On most GNU/Linux systems, you can read current directory from `/proc`:
```emacs-lisp
```elisp
(defun vterm-directory-sync ()
"Synchronize current working directory."
(interactive)
@@ -764,10 +813,13 @@ On most GNU/Linux systems, you can read current directory from `/proc`:
(dir (file-truename (format "/proc/%d/cwd/" pid))))
(setq default-directory dir))))
```
A possible application of this function is in combination with `find-file`:
```emacs-lisp
```elisp
(advice-add #'find-file :before #'vterm-directory-sync)
```
This method does not work on remote machines.
### How can I get the directory tracking in a more understandable way?
@@ -779,32 +831,37 @@ are using `fish`).
There is another way to achieve this behavior. Define a shell function, on a
local host you can simply use
``` sh
```sh
vterm_set_directory() {
vterm_cmd update-pwd "$PWD/"
}
```
On a remote one, use instead
``` sh
```sh
vterm_set_directory() {
vterm_cmd update-pwd "/-:""$USER""@""$HOSTNAME"":""$PWD/"
}
```
Then, for `zsh`, add this function to the `chpwd` hook:
``` sh
```zsh
autoload -U add-zsh-hook
add-zsh-hook -Uz chpwd (){ vterm_set_directory }
```
For `bash`, append it to the prompt:
``` sh
```bash
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND; }vterm_set_directory"
```
Finally, add `update-pwd` to the list of commands that Emacs
is allowed to execute from vterm:
``` emacs-lisp
```elisp
(add-to-list 'vterm-eval-cmds '("update-pwd" (lambda (path) (setq default-directory path))))
```
@@ -813,7 +870,7 @@ is allowed to execute from vterm:
`evil-collection` provides a solution for this problem. If you do not want to
use `evil-collection`, you can add the following code:
```emacs-lisp
```elisp
(defun evil-collection-vterm-escape-stay ()
"Go back to normal state but don't move
cursor backwards. Moving cursor backwards is the default vim behavior but it is
@@ -836,6 +893,12 @@ not appropriate in some cases like terminals."
Obsolete variables will be removed in version 0.1.
#### August 2022
* `vterm-send-C-[a-z]` `vterm-send-M-[a-z]` `vterm-define-key`
`vterm-send-{up/down/left/right/prior/next/meta-dot/meta-comma/ctrl-slash}`
were obsolete, please use `vterm-send` or `vterm-send-key` or
`vterm--self-insert` instead.
#### October 2020
* `vterm-disable-bold-font` was renamed to `vterm-disable-bold` to uniform it

View File

@@ -55,7 +55,7 @@ emacs_value Fvterm_invalidate;
emacs_value Feq;
emacs_value Fvterm_get_color;
emacs_value Fvterm_eval;
emacs_value Fvterm_selection;
emacs_value Fvterm_set_selection;
/* Set the function cell of the symbol named NAME to SFUN using
the 'fset' function. */
@@ -202,8 +202,8 @@ emacs_value vterm_eval(emacs_env *env, emacs_value string) {
return env->funcall(env, Fvterm_eval, 1, (emacs_value[]){string});
}
emacs_value vterm_selection(emacs_env *env, emacs_value selection_target,
emacs_value selection_data) {
return env->funcall(env, Fvterm_selection, 2,
emacs_value vterm_set_selection(emacs_env *env, emacs_value selection_target,
emacs_value selection_data) {
return env->funcall(env, Fvterm_set_selection, 2,
(emacs_value[]){selection_target, selection_data});
}

View File

@@ -58,7 +58,7 @@ extern emacs_value Fvterm_invalidate;
extern emacs_value Feq;
extern emacs_value Fvterm_get_color;
extern emacs_value Fvterm_eval;
extern emacs_value Fvterm_selection;
extern emacs_value Fvterm_set_selection;
// Utils
void bind_function(emacs_env *env, const char *name, emacs_value Sfun);
@@ -93,7 +93,7 @@ void set_directory(emacs_env *env, emacs_value string);
void vterm_invalidate(emacs_env *env);
emacs_value vterm_get_color(emacs_env *env, int index);
emacs_value vterm_eval(emacs_env *env, emacs_value string);
emacs_value vterm_selection(emacs_env *env, emacs_value selection_target,
emacs_value selection_data);
emacs_value vterm_set_selection(emacs_env *env, emacs_value selection_target,
emacs_value selection_data);
#endif /* ELISP_H */

View File

@@ -48,7 +48,7 @@ add-zsh-hook -Uz chpwd (){ print -Pn "\e]2;%m:%2~\a" }
# The escape sequence "51;A" has also the role of identifying the end of the
# prompt
vterm_prompt_end() {
vterm_printf "51;A$(whoami)@$(hostname):$(pwd)";
vterm_printf "51;A$(whoami)@$(hostname):$(pwd)"
}
setopt PROMPT_SUBST
PROMPT=$PROMPT'%{$(vterm_prompt_end)%}'

View File

@@ -30,7 +30,7 @@ end
function fish_title
hostname
echo ":"
pwd
prompt_pwd
end
# With vterm_cmd you can execute Emacs commands directly from the shell.

View File

@@ -154,6 +154,32 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data) {
return 1;
}
static int term_sb_clear(void *data) {
Term *term = (Term *)data;
if (term->sb_clear_pending) {
// Another scrollback clear is already pending, so skip this one.
return 0;
}
for (int i = 0; i < term->sb_current; i++) {
if (term->sb_buffer[i]->info != NULL) {
free_lineinfo(term->sb_buffer[i]->info);
term->sb_buffer[i]->info = NULL;
}
free(term->sb_buffer[i]);
}
free(term->sb_buffer);
term->sb_buffer = malloc(sizeof(ScrollbackLine *) * term->sb_size);
term->sb_clear_pending = true;
term->sb_current = 0;
term->sb_pending = 0;
term->sb_pending_by_height_decr = 0;
invalidate_terminal(term, -1, -1);
return 0;
}
static int row_to_linenr(Term *term, int row) {
return row != INT_MAX ? row + (int)term->sb_current + 1 : INT_MAX;
}
@@ -436,6 +462,14 @@ static int term_resize(int rows, int cols, void *user_data) {
static void refresh_scrollback(Term *term, emacs_env *env) {
int max_line_count = (int)term->sb_current + term->height;
int del_cnt = 0;
if (term->sb_clear_pending) {
del_cnt = term->linenum - term->height;
if (del_cnt > 0) {
delete_lines(env, 1, del_cnt, true);
term->linenum -= del_cnt;
}
term->sb_clear_pending = false;
}
if (term->sb_pending > 0) {
// This means that either the window height has decreased or the screen
// became full and libvterm had to push all rows up. Convert the first
@@ -608,13 +642,13 @@ static void term_redraw(Term *term, emacs_env *env) {
term->elisp_code_p_insert = &term->elisp_code_first;
if (term->selection_data) {
emacs_value selection_target = env->make_string(
env, &term->selection_target[0], strlen(&term->selection_target[0]));
emacs_value selection_mask = env->make_integer(env, term->selection_mask);
emacs_value selection_data = env->make_string(env, term->selection_data,
strlen(term->selection_data));
vterm_selection(env, selection_target, selection_data);
vterm_set_selection(env, selection_mask, selection_data);
free(term->selection_data);
term->selection_data = NULL;
term->selection_mask = 0;
}
term->is_invalidated = false;
@@ -628,6 +662,9 @@ static VTermScreenCallbacks vterm_screen_callbacks = {
.resize = term_resize,
.sb_pushline = term_sb_push,
.sb_popline = term_sb_pop,
#if !defined(VTermSBClearNotExists)
.sb_clear = term_sb_clear,
#endif
};
static bool compare_cells(VTermScreenCell *a, VTermScreenCell *b) {
@@ -846,24 +883,11 @@ static void term_flush_output(Term *term, emacs_env *env) {
}
static void term_clear_scrollback(Term *term, emacs_env *env) {
term_sb_clear(term);
vterm_screen_flush_damage(term->vts);
term_redraw(term, env);
if (term->sb_pending > 0) { // Pending rows must be processed first.
return;
}
for (int i = 0; i < term->sb_current; i++) {
if (term->sb_buffer[i]->info != NULL) {
free_lineinfo(term->sb_buffer[i]->info);
term->sb_buffer[i]->info = NULL;
}
free(term->sb_buffer[i]);
}
free(term->sb_buffer);
term->sb_buffer = malloc(sizeof(ScrollbackLine *) * term->sb_size);
delete_lines(env, 1, term->sb_current, true);
term->linenum -= term->sb_current;
term->sb_current = 0;
}
static void term_process_key(Term *term, emacs_env *env, unsigned char *key,
size_t len, VTermModifier modifier) {
if (is_key(key, len, "<clear_scrollback>")) {
@@ -1076,37 +1100,7 @@ static int handle_osc_cmd_51(Term *term, char subCmd, char *buffer) {
}
return 0;
}
static int handle_osc_cmd_52(Term *term, char *buffer) {
/* OSC 52 ; Pc ; Pd BEL */
/* Manipulate Selection Data */
/* https://invisible-island.net/xterm/ctlseqs/ctlseqs.html */
/* test by printf "\033]52;c;$(printf "%s" "blabla" | base64)\a" */
for (int i = 0; i < SELECTION_TARGET_MAX; i++) { /* reset Pc */
term->selection_target[i] = 0;
}
int selection_target_idx = 0;
size_t cmdlen = strlen(buffer);
for (int i = 0; i < cmdlen; i++) {
/* OSC 52 ; Pc ; Pd BEL */
if (buffer[i] == ';') { /* find the second ";" */
term->selection_data = malloc(cmdlen - i);
strcpy(term->selection_data, &buffer[i + 1]);
break;
}
if (selection_target_idx < SELECTION_TARGET_MAX) {
/* c , p , q , s , 0 , 1 , 2 , 3 , 4 , 5 , 6 , and 7 */
/* for clipboard, primary, secondary, select, or cut buffers 0 through 7
* respectively */
term->selection_target[selection_target_idx] = buffer[i];
selection_target_idx++;
} else { /* len of Pc should not >12 just ignore this cmd,am I wrong? */
return 0;
}
}
return 1;
}
static int handle_osc_cmd(Term *term, int cmd, char *buffer) {
if (cmd == 51) {
char subCmd = '0';
@@ -1116,11 +1110,11 @@ static int handle_osc_cmd(Term *term, int cmd, char *buffer) {
subCmd = buffer[0];
/* ++ skip the subcmd char */
return handle_osc_cmd_51(term, subCmd, ++buffer);
} else if (cmd == 52) {
return handle_osc_cmd_52(term, buffer);
}
return 0;
}
/* maybe we should drop support of libvterm < v0.2 */
/* VTermStringFragmentNotExists was introduced when libvterm is not released */
#ifdef VTermStringFragmentNotExists
static int osc_callback(const char *command, size_t cmdlen, void *user) {
Term *term = (Term *)user;
@@ -1134,10 +1128,6 @@ static int osc_callback(const char *command, size_t cmdlen, void *user) {
} else if (cmdlen > 4 && buffer[0] == '5' && buffer[1] == '1' &&
buffer[2] == ';' && buffer[3] == 'E') {
return handle_osc_cmd_51(term, 'E', &buffer[4]);
} else if (cmdlen > 4 && buffer[0] == '5' && buffer[1] == '2' &&
buffer[2] == ';') {
/* OSC 52 ; Pc ; Pd BEL */
return handle_osc_cmd_52(term, &buffer[3]);
}
return 0;
}
@@ -1159,13 +1149,6 @@ static int osc_callback(int cmd, VTermStringFragment frag, void *user) {
/* "51;A" has also the role of identifying the end of the prompt */
/* "51;E" executes elisp code */
/* The elisp code is executed in term_redraw */
/* "52;[cpqs01234567];data" Manipulate Selection Data */
/* I think libvterm has bug ,sometimes when the data is long enough ,the final
* fragment is missed */
/* printf "\033]52;c;$(printf "%s" $(ruby -e 'print "x"*999999')|base64)\a"
*/
Term *term = (Term *)user;
if (frag.initial) {
@@ -1194,6 +1177,37 @@ static VTermStateFallbacks parser_callbacks = {
.osc = &osc_callback,
.dcs = NULL,
};
#ifndef VTermSelectionMaskNotExists
static int set_selection(VTermSelectionMask mask, VTermStringFragment frag,
void *user) {
Term *term = (Term *)user;
if (frag.initial) {
term->selection_mask = mask;
if (term->selection_data) {
free(term->selection_data);
}
term->selection_data = NULL;
}
if (frag.len) {
term->selection_data =
concat(term->selection_data, frag.str, frag.len, true);
}
return 1;
}
/* OSC 52 ; Pc ; Pd BEL */
/* Manipulate Selection Data */
/* https://invisible-island.net/xterm/ctlseqs/ctlseqs.html */
/* test by printf "\033]52;c;$(printf "%s" "blabla" | base64)\a" */
/* c , p , q , s , 0 , 1 , 2 , 3 , 4 , 5 , 6 , and 7 */
/* for clipboard, primary, secondary, select, or cut buffers 0 through 7 */
/* respectively */
static VTermSelectionCallbacks selection_callbacks = {
.set = &set_selection,
.query = NULL,
};
#endif /* VTermSelectionMaskNotExists */
#endif
@@ -1217,6 +1231,11 @@ emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[],
VTermState *state = vterm_obtain_state(term->vt);
vterm_state_set_unrecognised_fallbacks(state, &parser_callbacks, term);
#ifndef VTermSelectionMaskNotExists
vterm_state_set_selection_callbacks(state, &selection_callbacks, term,
term->selection_buf, SELECTION_BUF_LEN);
#endif
vterm_state_set_bold_highbright(state, set_bold_hightbright);
vterm_screen_reset(term->vts, 1);
@@ -1226,6 +1245,7 @@ emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[],
term->sb_size = MIN(SB_MAX, sb_size);
term->sb_current = 0;
term->sb_pending = 0;
term->sb_clear_pending = false;
term->sb_pending_by_height_decr = 0;
term->sb_buffer = malloc(sizeof(ScrollbackLine *) * term->sb_size);
term->invalid_start = 0;
@@ -1262,6 +1282,7 @@ emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[],
term->elisp_code_first = NULL;
term->elisp_code_p_insert = &term->elisp_code_first;
term->selection_data = NULL;
term->selection_mask = 0;
term->cmd_buffer = NULL;
@@ -1472,8 +1493,8 @@ int emacs_module_init(struct emacs_runtime *ert) {
Fvterm_get_color =
env->make_global_ref(env, env->intern(env, "vterm--get-color"));
Fvterm_eval = env->make_global_ref(env, env->intern(env, "vterm--eval"));
Fvterm_selection =
env->make_global_ref(env, env->intern(env, "vterm--selection"));
Fvterm_set_selection =
env->make_global_ref(env, env->intern(env, "vterm--set-selection"));
// Exported functions
emacs_value fun;

View File

@@ -8,17 +8,17 @@
// https://gcc.gnu.org/wiki/Visibility
#if defined _WIN32 || defined __CYGWIN__
#ifdef __GNUC__
#define VTERM_EXPORT __attribute__ ((dllexport))
#else
#define VTERM_EXPORT __declspec(dllexport)
#endif
#ifdef __GNUC__
#define VTERM_EXPORT __attribute__((dllexport))
#else
#if __GNUC__ >= 4
#define VTERM_EXPORT __attribute__ ((visibility ("default")))
#else
#define VTERM_EXPORT
#endif
#define VTERM_EXPORT __declspec(dllexport)
#endif
#else
#if __GNUC__ >= 4
#define VTERM_EXPORT __attribute__((visibility("default")))
#else
#define VTERM_EXPORT
#endif
#endif
VTERM_EXPORT int plugin_is_GPL_compatible;
@@ -53,7 +53,7 @@ typedef struct ElispCodeListNode {
/* c , p , q , s , 0 , 1 , 2 , 3 , 4 , 5 , 6 , and 7 */
/* clipboard, primary, secondary, select, or cut buffers 0 through 7 */
#define SELECTION_TARGET_MAX 12
#define SELECTION_BUF_LEN 4096
typedef struct Cursor {
int row, col;
@@ -79,6 +79,7 @@ typedef struct Term {
// window height has increased) and must be deleted from the terminal buffer
int sb_pending;
int sb_pending_by_height_decr;
bool sb_clear_pending;
long linenum;
long linenum_added;
@@ -100,8 +101,9 @@ typedef struct Term {
/* c , p , q , s , 0 , 1 , 2 , 3 , 4 , 5 , 6 , and 7 */
/* clipboard, primary, secondary, select, or cut buffers 0 through 7 */
char selection_target[SELECTION_TARGET_MAX];
int selection_mask; /* see VTermSelectionMask in vterm.h */
char *selection_data;
char selection_buf[SELECTION_BUF_LEN];
/* the size of dirs almost = window height, value = directory of that line */
LineInfo **lines;

View File

@@ -1,6 +1,6 @@
(define-package "vterm" "20211226.817" "Fully-featured terminal emulator"
(define-package "vterm" "20221118.1354" "Fully-featured terminal emulator"
'((emacs "25.1"))
:commit "a940dd2ee8a82684860e320c0f6d5e15d31d916f" :authors
:commit "f14d113ee4618f052879509ec378feb9766b871b" :authors
'(("Lukas Fürmetz" . "fuermetz@mailbox.org"))
:maintainer
'("Lukas Fürmetz" . "fuermetz@mailbox.org")

View File

@@ -3,7 +3,7 @@
;; Copyright (C) 2017-2020 by Lukas Fürmetz & Contributors
;;
;; Author: Lukas Fürmetz <fuermetz@mailbox.org>
;; Version: 0.0.1
;; Version: 0.0.2
;; URL: https://github.com/akermu/emacs-libvterm
;; Keywords: terminals
;; Package-Requires: ((emacs "25.1"))
@@ -62,6 +62,8 @@
(error "VTerm needs module support. Please compile Emacs with
the --with-modules option!"))
(defvar vterm-copy-mode)
;;; Compilation of the module
(defcustom vterm-module-cmake-args ""
@@ -191,7 +193,7 @@ named \"*vterm*<2>\"."
:group 'vterm)
(defcustom vterm-max-scrollback 1000
"Maximum 'scrollback' value.
"Maximum \\='scrollback\\=' value.
The maximum allowed is 100000. This value can modified by
changing the SB_MAX variable in vterm-module.h and recompiling
@@ -229,7 +231,7 @@ screen in vterm buffers.
If `vterm-clear-scrollback-when-clearing' is nil, `vterm-clear'
clears only the screen, so the scrollback is accessible moving
the point up."
:type 'number
:type 'boolean
:group 'vterm)
(defcustom vterm-keymap-exceptions
@@ -297,21 +299,21 @@ information on the how to configure the shell."
(defcustom vterm-environment nil
"List of extra environment variables to the vterm shell processes only.
demo: '(\"env1=v1\" \"env2=v2\")"
demo: \\='(\"env1=v1\" \"env2=v2\")"
:type '(repeat string)
:group 'vterm)
(defcustom vterm-enable-manipulate-selection-data-by-osc52 nil
"Support OSC 52 MANIPULATE SELECTION DATA.
"Support OSC 52 MANIPULATE SELECTION DATA(libvterm 0.2 is needed).
Support copy text to emacs kill ring and system clipboard by using OSC 52.
For example: send base64 encoded 'foo' to kill ring: echo -en '\e]52;c;Zm9v\a',
Support copy text to Emacs kill ring and system clipboard by using OSC 52.
For example: send base64 encoded \\='foo\\=' to kill ring: echo -en \\='\\e]52;c;Zm9v\\a\\=',
tmux can share its copy buffer to terminals by supporting osc52(like iterm2
xterm) you can enable this feature for tmux by :
set -g set-clipboard on #osc 52 copy paste share with iterm
set -ga terminal-overrides ',xterm*:XT:Ms=\E]52;%p1%s;%p2%s\007'
set -ga terminal-overrides ',screen*:XT:Ms=\E]52;%p1%s;%p2%s\007'
set -ga terminal-overrides \\=',xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007\\='
set -ga terminal-overrides \\=',screen*:XT:Ms=\\E]52;%p1%s;%p2%s\\007\\='
The clipboard querying/clearing functionality offered by OSC 52 is not
implemented here,And for security reason, this feature is disabled
@@ -372,7 +374,7 @@ This means that vterm will render bold with the default face weight."
:group 'vterm)
(defcustom vterm-ignore-blink-cursor t
"When t,vterm will ignore request from application to turn on/off cursor blink.
"When t, vterm will ignore request from application to turn on/off cursor blink.
If nil, cursor in any window may begin to blink or not blink because
`blink-cursor-mode`is a global minor mode in Emacs,
@@ -521,16 +523,19 @@ of data. If nil, never delay. The units are seconds.")
"Define a command that sends KEY with modifiers C and M to vterm."
(declare (indent defun)
(doc-string 3))
`(defun ,(intern (format "vterm-send-%s" key))()
,(format "Sends %s to the libvterm." key)
(interactive)
(vterm-send-key ,(char-to-string (get-byte (1- (length key)) key))
,(let ((case-fold-search nil))
(or (string-match-p "[A-Z]$" key)
(string-match-p "S-" key)))
,(string-match-p "M-" key)
,(string-match-p "C-" key))))
`(progn (defun ,(intern (format "vterm-send-%s" key))()
,(format "Sends %s to the libvterm." key)
(interactive)
(vterm-send-key ,(char-to-string (get-byte (1- (length key)) key))
,(let ((case-fold-search nil))
(or (string-match-p "[A-Z]$" key)
(string-match-p "S-" key)))
,(string-match-p "M-" key)
,(string-match-p "C-" key)))
(make-obsolete ',(intern (format "vterm-send-%s" key))
"use `vterm--self-insert' or `vterm-send' or `vterm-send-key'."
"v0.1")))
(make-obsolete 'vterm-define-key "" "v0.1")
(mapc (lambda (key)
(eval `(vterm-define-key ,key)))
(cl-loop for prefix in '("M-")
@@ -558,29 +563,20 @@ Exceptions are defined by `vterm-keymap-exceptions'."
for key = (format "<f%i>" number)
unless (member key exceptions)
collect key))
(mapc (lambda (key)
(define-key map (kbd key)
(intern (format "vterm-send-%s" key))))
(cl-loop for prefix in '("M-")
append (cl-loop for char from ?A to ?Z
for key = (format "%s%c" prefix char)
unless (member key exceptions)
collect key)))
(mapc (lambda (key)
(define-key map (kbd key)
(intern (format "vterm-send-%s" key))))
(cl-loop for prefix in '("C-" "M-" "C-S-" )
append (cl-loop for char from ?a to ?z
for key = (format "%s%c" prefix char)
unless (member key exceptions)
collect key)))
(mapc (lambda (key)
(define-key map (kbd key) 'ignore))
(cl-loop for prefix in '("C-M-" "C-M-S-")
append (cl-loop for char from ?a to ?z
for key = (format "%s%c" prefix char)
unless (member key exceptions)
collect key))))
(let ((esc-map (lookup-key map "\e"))
(i 0)
key)
(unless esc-map (setq esc-map (make-keymap)))
(while (< i 128)
(setq key (make-string 1 i))
(unless (member (key-description key) exceptions)
(define-key map key 'vterm--self-insert))
;; Avoid O and [. They are used in escape sequences for various keys.
(unless (or (eq i ?O) (eq i 91))
(unless (member (key-description key "\e") exceptions)
(define-key esc-map key 'vterm--self-insert-meta)))
(setq i (1+ i)))
(define-key map "\e" esc-map)))
(defun vterm-xterm-paste (event)
"Handle xterm paste EVENT in vterm."
@@ -607,19 +603,21 @@ Exceptions are defined by `vterm-keymap-exceptions'."
(define-key map [C-backspace] #'vterm-send-meta-backspace)
(define-key map [return] #'vterm-send-return)
(define-key map (kbd "RET") #'vterm-send-return)
(define-key map [C-left] #'vterm-send-M-b)
(define-key map [M-left] #'vterm-send-M-b)
(define-key map [C-right] #'vterm-send-M-f)
(define-key map [M-right] #'vterm-send-M-f)
(define-key map [C-up] #'vterm-send-up)
(define-key map [C-down] #'vterm-send-down)
(define-key map [left] #'vterm-send-left)
(define-key map [right] #'vterm-send-right)
(define-key map [up] #'vterm-send-up)
(define-key map [down] #'vterm-send-down)
(define-key map [prior] #'vterm-send-prior)
(define-key map [C-left] #'vterm--self-insert)
(define-key map [M-left] #'vterm--self-insert)
(define-key map [C-right] #'vterm--self-insert)
(define-key map [M-right] #'vterm--self-insert)
(define-key map [C-up] #'vterm--self-insert)
(define-key map [C-down] #'vterm--self-insert)
(define-key map [M-up] #'vterm--self-insert)
(define-key map [M-down] #'vterm--self-insert)
(define-key map [left] #'vterm--self-insert)
(define-key map [right] #'vterm--self-insert)
(define-key map [up] #'vterm--self-insert)
(define-key map [down] #'vterm--self-insert)
(define-key map [prior] #'vterm--self-insert)
(define-key map [S-prior] #'scroll-down-command)
(define-key map [next] #'vterm-send-next)
(define-key map [next] #'vterm--self-insert)
(define-key map [S-next] #'scroll-up-command)
(define-key map [home] #'vterm--self-insert)
(define-key map [end] #'vterm--self-insert)
@@ -633,16 +631,16 @@ Exceptions are defined by `vterm-keymap-exceptions'."
(define-key map (kbd "C-SPC") #'vterm--self-insert)
(define-key map (kbd "S-SPC") #'vterm-send-space)
(define-key map (kbd "C-_") #'vterm--self-insert)
(define-key map (kbd "C-/") #'vterm-undo)
(define-key map (kbd "M-.") #'vterm-send-meta-dot)
(define-key map (kbd "M-,") #'vterm-send-meta-comma)
(define-key map [remap undo] #'vterm-undo)
(define-key map (kbd "M-.") #'vterm--self-insert)
(define-key map (kbd "M-,") #'vterm--self-insert)
(define-key map (kbd "C-c C-y") #'vterm--self-insert)
(define-key map (kbd "C-c C-c") #'vterm-send-C-c)
(define-key map (kbd "C-c C-c") #'vterm--self-insert)
(define-key map (kbd "C-c C-l") #'vterm-clear-scrollback)
(define-key map (kbd "C-l") #'vterm-clear)
(define-key map (kbd "C-\\") #'vterm-send-ctrl-slash)
(define-key map (kbd "C-c C-g") #'vterm-send-C-g)
(define-key map (kbd "C-c C-u") #'vterm-send-C-u)
(define-key map (kbd "C-\\") #'vterm--self-insert)
(define-key map (kbd "C-c C-g") #'vterm--self-insert)
(define-key map (kbd "C-c C-u") #'vterm--self-insert)
(define-key map [remap self-insert-command] #'vterm--self-insert)
(define-key map (kbd "C-c C-r") #'vterm-reset-cursor-point)
(define-key map (kbd "C-c C-n") #'vterm-next-prompt)
@@ -879,25 +877,20 @@ will invert `vterm-copy-exclude-prompt' for that call."
;;; Commands
(defun vterm--self-insert-meta ()
(interactive)
(when vterm--term
(dolist (key (vterm--translate-event-to-args
last-command-event :meta))
(apply #'vterm-send-key key))))
(defun vterm--self-insert ()
"Send invoking key to libvterm."
(interactive)
(when vterm--term
(let* ((modifiers (event-modifiers last-command-event))
(shift (memq 'shift modifiers))
(meta (memq 'meta modifiers))
(ctrl (memq 'control modifiers))
(raw-key (event-basic-type last-command-event))
(ev-keys))
(if input-method-function
(let ((inhibit-read-only t))
(setq ev-keys (funcall input-method-function raw-key))
(when (listp ev-keys)
(dolist (k ev-keys)
(when-let ((key (key-description (vector k))))
(vterm-send-key key shift meta ctrl)))))
(when-let ((key (key-description (vector raw-key))))
(vterm-send-key key shift meta ctrl))))))
(dolist (key (vterm--translate-event-to-args
last-command-event))
(apply #'vterm-send-key key))))
(defun vterm-send-key (key &optional shift meta ctrl accept-proc-output)
"Send KEY to libvterm with optional modifiers SHIFT, META and CTRL."
@@ -905,8 +898,6 @@ will invert `vterm-copy-exclude-prompt' for that call."
(when vterm--term
(let ((inhibit-redisplay t)
(inhibit-read-only t))
(when (and (not (symbolp last-command-event)) shift (not meta) (not ctrl))
(setq key (upcase key)))
(vterm--update vterm--term key shift meta ctrl)
(setq vterm--redraw-immididately t)
(when accept-proc-output
@@ -914,13 +905,19 @@ will invert `vterm-copy-exclude-prompt' for that call."
(defun vterm-send (key)
"Send KEY to libvterm. KEY can be anything `kbd' understands."
(let* ((event (listify-key-sequence (kbd key)))
(modifiers (event-modifiers event))
(base (event-basic-type event)))
(vterm-send-key (char-to-string base)
(memq 'shift modifiers)
(memq 'meta modifiers)
(memq 'control modifiers))))
(dolist (key (vterm--translate-event-to-args
(listify-key-sequence (kbd key))))
(apply #'vterm-send-key key)))
(defun vterm-send-next-key ()
"Read next input event and send it to the libvterm.
With this you can directly send modified keys to applications
running in the terminal (like Emacs or Nano)."
(interactive)
(dolist (key (vterm--translate-event-to-args
(read-event)))
(apply #'vterm-send-key key)))
(defun vterm-send-start ()
"Output from the system is started when the system receives START."
@@ -970,46 +967,55 @@ will invert `vterm-copy-exclude-prompt' for that call."
"Send `<up>' to the libvterm."
(interactive)
(vterm-send-key "<up>"))
(make-obsolete 'vterm-send-up 'vterm--self-insert "v0.1")
(defun vterm-send-down ()
"Send `<down>' to the libvterm."
(interactive)
(vterm-send-key "<down>"))
(make-obsolete 'vterm-send-down 'vterm--self-insert "v0.1")
(defun vterm-send-left ()
"Send `<left>' to the libvterm."
(interactive)
(vterm-send-key "<left>"))
(make-obsolete 'vterm-send-left 'vterm--self-insert "v0.1")
(defun vterm-send-right ()
"Send `<right>' to the libvterm."
(interactive)
(vterm-send-key "<right>"))
(make-obsolete 'vterm-send-right 'vterm--self-insert "v0.1")
(defun vterm-send-prior ()
"Send `<prior>' to the libvterm."
(interactive)
(vterm-send-key "<prior>"))
(make-obsolete 'vterm-send-prior 'vterm--self-insert "v0.1")
(defun vterm-send-next ()
"Send `<next>' to the libvterm."
(interactive)
(vterm-send-key "<next>"))
(make-obsolete 'vterm-send-next 'vterm--self-insert "v0.1")
(defun vterm-send-meta-dot ()
"Send `M-.' to the libvterm."
(interactive)
(vterm-send-key "." nil t))
(make-obsolete 'vterm-send-meta-dot 'vterm--self-insert "v0.1")
(defun vterm-send-meta-comma ()
"Send `M-,' to the libvterm."
(interactive)
(vterm-send-key "," nil t))
(make-obsolete 'vterm-send-meta-comma 'vterm--self-insert "v0.1")
(defun vterm-send-ctrl-slash ()
"Send `C-\' to the libvterm."
(interactive)
(vterm-send-key "\\" nil nil t))
(make-obsolete 'vterm-send-ctrl-slash 'vterm--self-insert "v0.1")
(defun vterm-send-escape ()
"Send `<escape>' to the libvterm."
@@ -1034,7 +1040,7 @@ prefix argument ARG or with \\[universal-argument]."
(and vterm-clear-scrollback-when-clearing (not arg))
(and arg (not vterm-clear-scrollback-when-clearing)))
(vterm-clear-scrollback))
(vterm-send-C-l))
(vterm-send-key "l" nil nil :ctrl))
(defun vterm-undo ()
"Send `C-_' to the libvterm."
@@ -1103,44 +1109,86 @@ Provide similar behavior as `insert' for vterm."
(defun vterm-delete-region (start end)
"Delete the text between START and END for vterm. "
(when vterm--term
(if (vterm-goto-char start)
(cl-loop repeat (- end start) do
(vterm-send-key "<delete>" nil nil nil t))
(let ((inhibit-read-only nil))
(vterm--delete-region start end)))))
(save-excursion
(when (get-text-property start 'vterm-line-wrap)
;; skip over the fake newline when start there.
(setq start (1+ start))))
;; count of chars after fake newline removed
(let ((count (length (filter-buffer-substring start end))))
(if (vterm-goto-char start)
(cl-loop repeat count do
(vterm-send-key "<delete>" nil nil nil t))
(let ((inhibit-read-only nil))
(vterm--delete-region start end))))))
(defun vterm-goto-char (pos)
"Set point to POSITION for vterm.
The return value is `t' when point moved successfully.
It will reset to original position if it can't move there."
The return value is `t' when point moved successfully."
(when (and vterm--term
(vterm-cursor-in-command-buffer-p)
(vterm-cursor-in-command-buffer-p pos))
(let ((moved t)
(origin-point (point))
pt cursor-pos succ)
(vterm-reset-cursor-point)
(setq cursor-pos (point))
(setq pt cursor-pos)
(while (and (> pos pt) moved)
(vterm-send-key "<right>" nil nil nil t)
(setq moved (not (= pt (point))))
(setq pt (point)))
(setq pt (point))
(setq moved t)
(while (and (< pos pt) moved)
(vterm-send-key "<left>" nil nil nil t)
(setq moved (not (= pt (point))))
(setq pt (point)))
(setq succ (= pos (point)))
(unless succ
(vterm-goto-char cursor-pos)
(goto-char origin-point))
succ)))
(vterm-reset-cursor-point)
(let ((diff (- pos (point))))
(cond
((zerop diff) t) ;do not need move
((< diff 0) ;backward
(while (and
(vterm--backward-char)
(> (point) pos)))
(<= (point) pos))
(t
(while (and (vterm--forward-char)
(< (point) pos)))
(>= (point) pos))))))
;;; Internal
(defun vterm--forward-char ()
"Move point 1 character forward ().
the return value is `t' when cursor moved."
(vterm-reset-cursor-point)
(let ((pt (point)))
(vterm-send-key "<right>" nil nil nil t)
(cond
((= (point) (1+ pt)) t)
((and (> (point) pt)
;; move over the fake newline
(get-text-property (1- (point)) 'vterm-line-wrap))
t)
((and (= (point) (+ 4 pt))
(looking-back (regexp-quote "^[[C") nil)) ;escape code for <right>
(dotimes (_ 3) (vterm-send-key "<backspace>" nil nil nil t)) ;;delete "^[[C"
nil)
((> (point) (1+ pt)) ;auto suggest
(vterm-send-key "_" nil nil t t) ;undo C-_
nil)
(t nil))))
(defun vterm--backward-char ()
"Move point N characters backward.
Return count of moved characeters."
(vterm-reset-cursor-point)
(let ((pt (point)))
(vterm-send-key "<left>" nil nil nil t)
(cond
((= (point) (1- pt)) t)
((and (= (point) (- pt 2))
;; backward cross fake newline
(string-equal (buffer-substring-no-properties
(1+ (point)) (+ 2 (point)))
"\n"))
t)
((and (= (point) (+ 4 pt))
(looking-back (regexp-quote "^[[D") nil)) ;escape code for <left>
(dotimes (_ 3) (vterm-send-key "<backspace>" nil nil nil t)) ;;delete "^[[D"
nil)
(t nil))))
(defun vterm--delete-region(start end)
"A wrapper for `delete-region'."
(funcall vterm--delete-region-function start end))
@@ -1153,6 +1201,33 @@ It will reset to original position if it can't move there."
"A wrapper for `delete-char'."
(funcall vterm--delete-char-function n killflag))
(defun vterm--translate-event-to-args (event &optional meta)
"Translate EVENT as list of args for `vterm-send-key'.
When some input method is enabled, one key may generate
several characters, so the result of this function is a list,
looks like: ((\"m\" :shift ))"
(let* ((modifiers (event-modifiers event))
(shift (memq 'shift modifiers))
(meta (or meta (memq 'meta modifiers)))
(ctrl (memq 'control modifiers))
(raw-key (event-basic-type event))
(ev-keys) keys)
(if input-method-function
(let ((inhibit-read-only t))
(setq ev-keys (funcall input-method-function raw-key))
(when (listp ev-keys)
(dolist (k ev-keys)
(when-let ((key (key-description (vector k))))
(when (and (not (symbolp event)) shift (not meta) (not ctrl))
(setq key (upcase key)))
(setq keys (append keys (list (list key shift meta ctrl))))))))
(when-let ((key (key-description (vector raw-key))))
(when (and (not (symbolp event)) shift (not meta) (not ctrl))
(setq key (upcase key)))
(setq keys (list (list key shift meta ctrl)))))
keys))
(defun vterm--invalidate ()
"The terminal buffer is invalidated, the buffer needs redrawing."
(if (and (not vterm--redraw-immididately)
@@ -1189,31 +1264,25 @@ Argument BUFFER the terminal buffer."
(when (cl-member (selected-window) windows :test #'eq)
(set-window-hscroll (selected-window) 0))))))))
(defun vterm--selection (targets data)
;; see VTermSelectionMask in vterm.el
;; VTERM_SELECTION_CLIPBOARD = (1<<0),
;; VTERM_SELECTION_PRIMARY = (1<<1),
(defconst vterm--selection-clipboard 1) ;(1<<0)
(defconst vterm--selection-primary 2) ;(1<<1)
(defun vterm--set-selection (mask data)
"OSC 52 Manipulate Selection Data.
Search Manipulate Selection Data in
https://invisible-island.net/xterm/ctlseqs/ctlseqs.html ."
(when vterm-enable-manipulate-selection-data-by-osc52
(unless (or (string-equal data "?")
(string-empty-p data))
(let* ((inhibit-eol-conversion t)
(decoded-data (decode-coding-string
(base64-decode-string data) locale-coding-system))
(select-enable-clipboard select-enable-clipboard)
(select-enable-primary select-enable-primary))
;; https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
;; c , p , q , s , 0 , 1 , 2 , 3 , 4 , 5 , 6 , and 7
;; clipboard, primary, secondary, select, or cut buffers 0 through 7
(unless (string-empty-p targets)
(setq select-enable-clipboard nil)
(setq select-enable-primary nil))
(when (cl-find ?c targets)
(setq select-enable-clipboard t))
(when (cl-find ?p targets)
(setq select-enable-primary t))
(kill-new decoded-data)
(message "kill-ring is updated by vterm OSC 52(Manipulate Selection Data)")))))
(let ((select-enable-clipboard select-enable-clipboard)
(select-enable-primary select-enable-primary))
(setq select-enable-clipboard
(logand mask vterm--selection-clipboard))
(setq select-enable-primary
(logand mask vterm--selection-primary))
(kill-new data)
(message "kill-ring is updated by vterm OSC 52(Manipulate Selection Data)"))
))
;;; Entry Points
@@ -1292,7 +1361,7 @@ value of `vterm-buffer-name'."
"\\(?:[\r\n\000\007\t\b\016\017]\\|"
;; a C1 escape coded character (see [ECMA-48] section 5.3 "Elements
;; of the C1 set"),
"\e\\(?:[DM78c]\\|"
"\e\\(?:[DM78c=]\\|"
;; another Emacs specific control sequence for term.el,
"AnSiT[^\n]+\n\\|"
;; another Emacs specific control sequence for vterm.el
@@ -1436,7 +1505,7 @@ If option DELETE-WHOLE-LINE is non-nil, then this command kills
the whole line including its terminating newline"
(save-excursion
(when (vterm--goto-line line-num)
(vterm--delete-region (point) (point-at-eol count))
(vterm--delete-region (point) (line-end-position count))
(when (and delete-whole-line
(looking-at "\n"))
(vterm--delete-char 1)))))
@@ -1525,7 +1594,8 @@ the called functions."
(f (assoc command vterm-eval-cmds)))
(if f
(apply (cadr f) args)
(message "Failed to find command: %s" command))))
(message "Failed to find command: %s. To execute a command,
add it to the `vterm-eval-cmd' list" command))))
;; TODO: Improve doc string, it should not point to the readme but it should
;; be self-contained.
@@ -1555,7 +1625,7 @@ in README."
(promp-pt (vterm--get-prompt-point)))
(when promp-pt (goto-char promp-pt))
(cl-loop repeat (or n 1) do
(setq pt (next-single-property-change (point-at-bol 2) 'vterm-prompt))
(setq pt (next-single-property-change (line-beginning-position 2) 'vterm-prompt))
(when pt (goto-char pt))))
(term-next-prompt n)))
@@ -1622,12 +1692,9 @@ More information see `vterm--prompt-tracking-enabled-p' and
"Check whether cursor in command buffer area."
(save-excursion
(vterm-reset-cursor-point)
(let ((promp-pt (vterm--get-prompt-point))
eol)
(let ((promp-pt (vterm--get-prompt-point)))
(when promp-pt
(goto-char promp-pt)
(setq eol (vterm--get-end-of-line))
(<= promp-pt (or pt (vterm--get-cursor-point)) eol)))))
(<= promp-pt (or pt (vterm--get-cursor-point)))))))
(defun vterm-beginning-of-line ()
"Move point to the beginning of the line.
@@ -1662,7 +1729,7 @@ Effectively toggle between the two positions."
(defun vterm--remove-fake-newlines ()
"Filter out injected newlines were injected when rendering the terminal.
These newlines were tagged with 'vterm-line-wrap property so we
These newlines were tagged with \\='vterm-line-wrap property so we
can find them and remove them."
(goto-char (point-min))
(let (fake-newline)