mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
Merge branch 'master' into releases/1.4
This commit is contained in:
commit
a3db31d5cb
15 changed files with 242 additions and 86 deletions
48
CHANGELOG.md
48
CHANGELOG.md
|
|
@ -1,5 +1,6 @@
|
|||
# Changelog
|
||||
|
||||
* [Unreleased](#unreleased)
|
||||
* [1.4.2](#1.4.2)
|
||||
* [1.4.1](#1-4-1)
|
||||
* [1.4.0](#1-4-0)
|
||||
|
|
@ -9,6 +10,53 @@
|
|||
* [1.2.1](#1-2-1)
|
||||
* [1.2.0](#1-2-0)
|
||||
|
||||
## Unreleased
|
||||
### Added
|
||||
|
||||
* Section to [README.md](README.md) describing how to programmatically
|
||||
identify foot.
|
||||
* [LICENSE](LICENSE), [README.md](README.md) and
|
||||
[CHANGELOG.md](CHANGELOG.md) are now installed to
|
||||
`${datadir}/doc/foot`.
|
||||
* Support for escaping quotes in **pipe-visible** and
|
||||
**pipe-scrollback** commands.
|
||||
|
||||
|
||||
### Changed
|
||||
|
||||
* Primary DA to no longer indicate support for _Selective Erase_,
|
||||
_Technical Characters_ and _Terminal State Interrogation_.
|
||||
* Secondary DA to report foot as a VT220 instead of a VT420.
|
||||
* Secondary DA to report foot's version number in parameter 2, the
|
||||
_Firmware Version_. The string is made up of foot's major, minor and
|
||||
patch version numbers, always using two digits for each version
|
||||
number and without any other separating characters. Thus, _1.4.2_
|
||||
would be reported as `010402` (i.e. the full response would be
|
||||
`\E[>1;010402;0c`).
|
||||
* Scrollback search to only move the viewport if the match lies
|
||||
outside it.
|
||||
* Scrollback search to focus match, that requires a viewport change,
|
||||
roughly in the center of the screen.
|
||||
* Extending a selection with the right mouse button now works while
|
||||
dragging the mouse.
|
||||
|
||||
|
||||
### Deprecated
|
||||
### Removed
|
||||
### Fixed
|
||||
|
||||
* Crash in scrollback search.
|
||||
* Crash when a **pipe-visible** or **pipe-scrollback** command
|
||||
contained an unclosed quote
|
||||
(https://codeberg.org/dnkl/foot/issues/49).
|
||||
|
||||
|
||||
### Security
|
||||
### Contributors
|
||||
|
||||
* [birger](https://codeberg.org/birger)
|
||||
* [cherti](https://codeberg.org/cherti)
|
||||
|
||||
|
||||
## 1.4.2
|
||||
|
||||
|
|
|
|||
2
LICENSE
2
LICENSE
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 Daniel Eklöf
|
||||
Copyright (c) 2019 Daniel Eklöf
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
1
PKGBUILD
1
PKGBUILD
|
|
@ -42,6 +42,7 @@ check() {
|
|||
|
||||
package_foot-git() {
|
||||
pkgdesc="A wayland native terminal emulator"
|
||||
changelog=CHANGELOG.md
|
||||
optdepends=('foot-terminfo: terminfo for foot')
|
||||
conflicts=('foot')
|
||||
provides=('foot')
|
||||
|
|
|
|||
48
README.md
48
README.md
|
|
@ -5,6 +5,7 @@ The fast, lightweight and minimalistic Wayland terminal emulator.
|
|||
## Index
|
||||
|
||||
1. [Features](#features)
|
||||
1. [Configuration](#configuration)
|
||||
1. [Troubleshooting](#troubleshooting)
|
||||
1. [Why the name 'foot'?](#why-the-name-foot)
|
||||
1. [Fonts](#fonts)
|
||||
|
|
@ -18,6 +19,7 @@ The fast, lightweight and minimalistic Wayland terminal emulator.
|
|||
1. [Backspace](#backspace)
|
||||
1. [DPI and font size](#dpi-and-font-size)
|
||||
1. [Supported OSCs](#supported-oscs)
|
||||
1. [Programmatically checking if running in foot](#programmatically-checking-if-running-in-foot)
|
||||
1. [Requirements](#requirements)
|
||||
1. [Running](#running)
|
||||
1. [Building](#building)
|
||||
|
|
@ -33,7 +35,6 @@ The fast, lightweight and minimalistic Wayland terminal emulator.
|
|||
1. [Bugs](#bugs)
|
||||
1. [Mastodon](#mastodon)
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
* Fast (see [benchmarks](doc/benchmark.md))
|
||||
|
|
@ -52,6 +53,14 @@ The fast, lightweight and minimalistic Wayland terminal emulator.
|
|||
|
||||

|
||||
|
||||
## Configuration
|
||||
|
||||
**foot** can be configured by creating a file `$XDG_CONFIG_HOME/footrc` (defaulting to `~/.config/footrc`).
|
||||
A template for that can usually be found in `/usr/share/foot/footrc` or
|
||||
[here](https://codeberg.org/dnkl/foot/src/branch/master/footrc).
|
||||
|
||||
Further information can be found in foot's manpage `foot(5)`.
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
|
@ -222,14 +231,14 @@ want to launch a new terminal.
|
|||
By default, foot prefixes _Meta characters_ with ESC. This corresponds
|
||||
to XTerm's `metaSendsEscape` option set to `true`.
|
||||
|
||||
This can be disabled programatically with `\E[?1036l` (and enabled
|
||||
This can be disabled programmatically with `\E[?1036l` (and enabled
|
||||
again with `\E[?1036h`).
|
||||
|
||||
When disabled, foot will instead set the 8:th bit of meta character
|
||||
and then UTF-8 encode it. This corresponds to XTerm's `eightBitMeta`
|
||||
option set to `true`.
|
||||
|
||||
This can also be disabled programatically with `rmm` (_reset meta
|
||||
This can also be disabled programmatically with `rmm` (_reset meta
|
||||
mode_, `\E[?1034l`), and enabled again with `smm` (_set meta mode_,
|
||||
`\E[?1034h`).
|
||||
|
||||
|
|
@ -301,6 +310,39 @@ with the terminal emulator itself. Foot implements the following OSCs:
|
|||
* `OSC 555` - flash screen (**foot specific**)
|
||||
|
||||
|
||||
## Programmatically checking if running in foot
|
||||
|
||||
Foot does **not** set any environment variables that can be used to
|
||||
identify foot (reading `TERM` is not reliable since the user may have
|
||||
chosen to use a different terminfo).
|
||||
|
||||
You can instead use the escape sequences to read the _Secondary_ and
|
||||
_Tertiary Device Attributes_ (secondary/tertiary DA, for short).
|
||||
|
||||
The tertiary DA response is always `\EP!|464f4f54\E\\`. The `\EP!|` is
|
||||
the standard tertiary DA response prefix, `DCS ! |`. The trailing
|
||||
`\E\\` is of course the standard string terminator, `ST`.
|
||||
|
||||
In the response above, the interresting part is `464f4f54`; this is
|
||||
the string _FOOT_ in hex.
|
||||
|
||||
The secondary DA response is `\E[>1;XXYYZZ;0c`, where XXYYZZ is foot's
|
||||
major, minor and patch version numbers, in decimal, using two digits
|
||||
for each number. For example, foot-1.4.2 would respond with
|
||||
`\E[>1;010402;0c`.
|
||||
|
||||
**Note**: not all terminal emulators implement tertiary DA. Most
|
||||
implement secondary DA, but not all. All _should_ however implement
|
||||
_Primary DA_.
|
||||
|
||||
Thus, a safe way to query the terminal is to request the tertiary,
|
||||
secondary and primary DA all at once, in that order. All terminals
|
||||
should ignore escape sequences they do not recognize. You will have to
|
||||
parse the response (which in foot will consist of all three DA
|
||||
responses, all at once) to determine which requests the terminal
|
||||
emulator actually responded to.
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
### Running
|
||||
|
|
|
|||
29
csi.c
29
csi.c
|
|
@ -13,10 +13,11 @@
|
|||
#define LOG_ENABLE_DBG 0
|
||||
#include "log.h"
|
||||
#include "grid.h"
|
||||
#include "vt.h"
|
||||
#include "selection.h"
|
||||
#include "sixel.h"
|
||||
#include "util.h"
|
||||
#include "version.h"
|
||||
#include "vt.h"
|
||||
|
||||
#define UNHANDLED() LOG_DBG("unhandled: %s", csi_as_string(term, final, -1))
|
||||
#define UNHANDLED_SGR(idx) LOG_DBG("unhandled: %s", csi_as_string(term, 'm', idx))
|
||||
|
|
@ -373,8 +374,17 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
* - 22 ANSI color, e.g., VT525.
|
||||
* - 28 Rectangular editing.
|
||||
* - 29 ANSI text locator (i.e., DEC Locator mode).
|
||||
*
|
||||
* Note: we report ourselves as a VT220, mainly to be able
|
||||
* to pass parameters, to indiciate we support sixel, and
|
||||
* ANSI colors.
|
||||
*
|
||||
* The VT level must be synchronized with the secondary DA
|
||||
* response.
|
||||
*
|
||||
* Note: tertiary DA responds with "FOOT".
|
||||
*/
|
||||
const char *reply = "\033[?62;4;6;15;17;22c";
|
||||
const char *reply = "\033[?62;4;22c";
|
||||
term_to_slave(term, reply, strlen(reply));
|
||||
break;
|
||||
}
|
||||
|
|
@ -1405,9 +1415,22 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
* xterm uses its version number. We use an xterm
|
||||
* version number too, since e.g. Emacs uses this to
|
||||
* determine level of support.
|
||||
*
|
||||
* We report ourselves as a VT220. This must be
|
||||
* synchronized with the primary DA respons.
|
||||
*
|
||||
* Note: tertiary DA replies with "FOOT".
|
||||
*/
|
||||
|
||||
term_to_slave(term, "\033[>41;347;0c", 12);
|
||||
static_assert(FOOT_MAJOR < 100, "Major version must not exceed 99");
|
||||
static_assert(FOOT_MINOR < 100, "Minor version must not exceed 99");
|
||||
static_assert(FOOT_PATCH < 100, "Patch version must not exceed 99");
|
||||
|
||||
char reply[64];
|
||||
snprintf(reply, sizeof(reply), "\033[>1;%02u%02u%02u;0c",
|
||||
FOOT_MAJOR, FOOT_MINOR, FOOT_PATCH);
|
||||
|
||||
term_to_slave(term, reply, strlen(reply));
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ terminal. This is done **20** times for each test. Then it calculates
|
|||
the _mean_ and _standard deviation_ for each test.
|
||||
|
||||
|
||||
## 2020-06-05
|
||||
## 2020-07-25
|
||||
|
||||
### System
|
||||
|
||||
|
|
@ -40,17 +40,17 @@ Scrollback: 10000 lines
|
|||
|
||||
### Results
|
||||
|
||||
| Benchmark | Foot (GCC+PGO) 1.3.0.r59 | Alacritty 0.4.3 | URxvt 9.22 | XTerm 356 |
|
||||
| Benchmark | Foot (GCC+PGO) 1.4.2.r14 | Alacritty 0.4.3 | URxvt 9.22 | XTerm 358 |
|
||||
|------------------------|-------------------------:|---------------------:|---------------:|---------------:|
|
||||
| alt-random | 0.450s ±0.009 | 0.905s ±0.003 | 1.151s ±0.004 | 12.906s ±0.078 |
|
||||
| alt-random-colors | 0.451s ±0.013 | 0.931s ±0.005 | 1.192s ±0.005 | 11.858s ±0.155 |
|
||||
| scrolling | 1.181s ±0.036 | 1.096s ±0.022 | 1.080s ±0.007 | 38.244s ±0.118 |
|
||||
| scrolling-filled-lines | 0.878s ±0.015 | 1.320s ±0.040 | 1.251s ±0.006 | 6.812s ±0.031 |
|
||||
| unicode-random | 0.926s ±1.179 | 0.089s ±0.001 [^1] | 24.039s ±3.559 | 26.558s ±3.841 |
|
||||
| alt-random | 0.423s ±0.014 | 0.904s ±0.006 | 1.111s ±0.003 | 12.851s ±0.087 |
|
||||
| alt-random-colors | 0.382s ±0.005 | 0.935s ±0.005 | 1.146s ±0.007 | 11.816s ±0.088 |
|
||||
| scrolling | 1.380s ±0.048 | 1.011s ±0.012 | 1.021s ±0.016 | 38.483s ±0.122 |
|
||||
| scrolling-filled-lines | 0.826s ±0.020 | 1.307s ±0.008 | 1.213s ±0.015 | 6.725s ±0.016 |
|
||||
| unicode-random | 0.243s ±0.006 | 0.091s ±0.003 [^1] | 24.507s ±3.264 | 26.127s ±3.891 |
|
||||
|
||||
|
||||
|
||||
## 2020-05-31
|
||||
## 2020-07-25
|
||||
|
||||
### System
|
||||
|
||||
|
|
@ -73,13 +73,13 @@ Scrollback=10000 lines
|
|||
### Results
|
||||
|
||||
|
||||
| Benchmark | Foot (GCC+PGO) 1.3.0.r59 | Alacritty 0.4.2 | URxvt 9.22 | St 0.8.3 | XTerm 356 |
|
||||
|------------------------|-------------------------:|---------------------:|---------------:|--------------:|---------------:|
|
||||
| alt-random | 0.791s ±0.080 | 1.558s ±0.038 | 1.746s ±0.065 | 2.628s ±0.085 | 1.706s ±0.064 |
|
||||
| alt-random-colors | 0.830s ±0.076 | 1.587s ±0.041 | 2.049s ±0.118 | 3.033s ±0.129 | 2.109s ±0.131 |
|
||||
| scrolling | 1.603s ±0.070 | 1.464s ±0.098 | 1.439s ±0.035 | 3.760s ±0.113 | 1.459s ±0.036 |
|
||||
| scrolling-filled-lines | 1.888s ±0.021 | 2.334s ±0.078 | 2.145s ±0.074 | 3.372s ±0.078 | 2.144s ±0.091 |
|
||||
| unicode-random | 1.545s ±0.229 | 0.164s ±0.012 [^1] | 11.180s ±0.342 | crashed | 11.389s ±0.269 |
|
||||
| Benchmark | Foot (GCC+PGO) 1.4.2.r9 | Alacritty 0.4.3 | URxvt 9.22 | St 0.8.4 | XTerm 358 |
|
||||
|------------------------|------------------------:|---------------------:|---------------:|--------------:|----------------:|
|
||||
| alt-random | 0.784s ±0.074 | 1.568s ±0.094 | 1.600s ±0.052 | 1.917s ±0.054 | 34.487s ±0.118 |
|
||||
| alt-random-colors | 0.823s ±0.067 | 1.627s ±0.107 | 1.932s ±0.073 | 2.111s ±0.163 | 30.676s ±0.127 |
|
||||
| scrolling | 1.612s ±0.092 | 1.492s ±0.051 | 1.504s ±0.033 | 3.767s ±0.140 | 125.202s ±0.383 |
|
||||
| scrolling-filled-lines | 1.874s ±0.039 | 2.423s ±0.083 | 1.994s ±0.037 | 2.751s ±0.076 | 19.608s ±0.056 |
|
||||
| unicode-random | 0.458s ±0.026 | 0.159s ±0.007 [^1] | 12.416s ±0.223 | crashed | 16.336s ±0.410 |
|
||||
|
||||
[^1]: [Alacritty and "unicode-random"](#alacritty-and-unicode-random)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ arguments, to execute (instead of the default shell).
|
|||
# OPTIONS
|
||||
|
||||
*-c*,*--config*=_PATH_
|
||||
Path to configuration file. Default: *XDG_RUNTIME_DIR/footrc*.
|
||||
Path to configuration file. Default: *XDG_CONFIG_HOME/footrc*.
|
||||
|
||||
*-f*,*--font*=_FONT_
|
||||
Comma separated list of fonts to use, in fontconfig format (see
|
||||
|
|
@ -214,14 +214,14 @@ _Examples_:
|
|||
By default, foot prefixes meta characters with *ESC*. This corresponds
|
||||
to XTerm's *metaSendsEscape* option set to *true*.
|
||||
|
||||
This can be disabled programatically with *\E[?1036l* (and enabled
|
||||
This can be disabled programmatically with *\E[?1036l* (and enabled
|
||||
again with *\E[?1036h*).
|
||||
|
||||
When disabled, foot will instead set the 8:th bit of meta character
|
||||
and then UTF-8 encode it. This corresponds to XTerm's *eightBitMeta*
|
||||
option set to *true*.
|
||||
|
||||
This can also be disabled programatically with *rmm* (Reset Meta Mode,
|
||||
This can also be disabled programmatically with *rmm* (Reset Meta Mode,
|
||||
*\E[?1034l*), and enabled again with *smm* (Set Meta Mode,
|
||||
*\E[?1034h*).
|
||||
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ This section lets you override the default key bindings.
|
|||
The general format is _action=combo1...comboN_. That is, each action
|
||||
may have one or more key combinations, space separated. Each
|
||||
combination is on the form _mod1+mod2+key_. The names of the modifiers
|
||||
and the key *must* be a valid XKB key name.
|
||||
and the key *must* be valid XKB key names.
|
||||
|
||||
Note that if *Shift* is one of the modifiers, the _key_ *must* be in
|
||||
upper case. For example, *Control+Shift+v* will never trigger -
|
||||
|
|
@ -335,7 +335,7 @@ any of these options.
|
|||
Now, that was a lof of text. But what is it foot actually does?
|
||||
|
||||
When receiving client data, it schedules a timer, the
|
||||
*delayed-render-lower*. If we do not recieve any more client data
|
||||
*delayed-render-lower*. If we do not receive any more client data
|
||||
before the timer has run out, we render the frame. If however, we
|
||||
do receive more data, the timer is re-scheduled. That is, each
|
||||
time we receive client data, frame rendering is delayed another
|
||||
|
|
|
|||
32
footrc
32
footrc
|
|
@ -19,22 +19,22 @@
|
|||
# alpha=1.0
|
||||
# foreground=dcdccc
|
||||
# background=111111
|
||||
# regular0=222222
|
||||
# regular1=cc9393
|
||||
# regular2=7f9f7f
|
||||
# regular3=d0bf8f
|
||||
# regular4=6ca0a3
|
||||
# regular5=dc8cc3
|
||||
# regular6=93e0e3
|
||||
# regular7=dcdccc
|
||||
# bright0=666666
|
||||
# bright1=dca3a3
|
||||
# bright2=bfebbf
|
||||
# bright3=f0dfaf
|
||||
# bright4=8cd0d3
|
||||
# bright5=fcace3
|
||||
# bright6=b3ffff
|
||||
# bright7=ffffff
|
||||
# regular0=222222 # black
|
||||
# regular1=cc9393 # red
|
||||
# regular2=7f9f7f # green
|
||||
# regular3=d0bf8f # yellow
|
||||
# regular4=6ca0a3 # blue
|
||||
# regular5=dc8cc3 # magenta
|
||||
# regular6=93e0e3 # cyan
|
||||
# regular7=dcdccc # white
|
||||
# bright0=666666 # bright black
|
||||
# bright1=dca3a3 # bright red
|
||||
# bright2=bfebbf # bright green
|
||||
# bright3=f0dfaf # bright yellow
|
||||
# bright4=8cd0d3 # bright blue
|
||||
# bright5=fcace3 # bright magenta
|
||||
# bright6=b3ffff # bright cyan
|
||||
# bright7=ffffff # bright white
|
||||
|
||||
[csd]
|
||||
# preferred=server
|
||||
|
|
|
|||
|
|
@ -22,7 +22,14 @@ else
|
|||
new_version="${default_version}"
|
||||
fi
|
||||
|
||||
new_version="#define FOOT_VERSION \"${new_version}\""
|
||||
major=$(echo "${new_version}" | sed -r 's/([0-9]+)\.([0-9]+)\.([0-9]+).*/\1/')
|
||||
minor=$(echo "${new_version}" | sed -r 's/([0-9]+)\.([0-9]+)\.([0-9]+).*/\2/')
|
||||
patch=$(echo "${new_version}" | sed -r 's/([0-9]+)\.([0-9]+)\.([0-9]+).*/\3/')
|
||||
|
||||
new_version="#define FOOT_VERSION \"${new_version}\"
|
||||
#define FOOT_MAJOR ${major}
|
||||
#define FOOT_MINOR ${minor}
|
||||
#define FOOT_PATCH ${patch}"
|
||||
|
||||
if [ -f "${out_file}" ]; then
|
||||
old_version=$(cat "${out_file}")
|
||||
|
|
|
|||
2
input.c
2
input.c
|
|
@ -1171,7 +1171,7 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
|
|||
if (col < 0 || row < 0 || col >= term->cols || row >= term->rows)
|
||||
return;
|
||||
|
||||
bool update_selection = seat->mouse.button == BTN_LEFT;
|
||||
bool update_selection = seat->mouse.button == BTN_LEFT || seat->mouse.button == BTN_RIGHT;
|
||||
bool update_selection_early = term->selection.end.row == -1;
|
||||
|
||||
if (update_selection && update_selection_early)
|
||||
|
|
|
|||
|
|
@ -148,7 +148,12 @@ custom_target(
|
|||
install: true,
|
||||
install_dir: join_paths(get_option('datadir'), 'terminfo'))
|
||||
|
||||
install_data('foot.desktop', 'foot-server.desktop', install_dir: join_paths(get_option('datadir'), 'applications'))
|
||||
install_data(
|
||||
'LICENSE', 'README.md', 'CHANGELOG.md',
|
||||
install_dir: join_paths(get_option('datadir'), 'doc', 'foot'))
|
||||
install_data(
|
||||
'foot.desktop', 'foot-server.desktop',
|
||||
install_dir: join_paths(get_option('datadir'), 'applications'))
|
||||
install_data('footrc', install_dir: join_paths(get_option('datadir'), 'foot'))
|
||||
|
||||
subdir('completions')
|
||||
|
|
|
|||
78
search.c
78
search.c
|
|
@ -104,39 +104,57 @@ search_update_selection(struct terminal *term,
|
|||
int start_row, int start_col,
|
||||
int end_row, int end_col)
|
||||
{
|
||||
int old_view = term->grid->view;
|
||||
int new_view = start_row;
|
||||
bool move_viewport = true;
|
||||
|
||||
/* Prevent scrolling in uninitialized rows */
|
||||
bool all_initialized = false;
|
||||
do {
|
||||
all_initialized = true;
|
||||
|
||||
for (int i = 0; i < term->rows; i++) {
|
||||
int row_no = (new_view + i) % term->grid->num_rows;
|
||||
if (term->grid->rows[row_no] == NULL) {
|
||||
all_initialized = false;
|
||||
new_view--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!all_initialized);
|
||||
|
||||
/* Don't scroll past scrollback history */
|
||||
int end = (term->grid->offset + term->rows - 1) % term->grid->num_rows;
|
||||
if (end >= term->grid->offset) {
|
||||
/* Not wrapped */
|
||||
if (new_view >= term->grid->offset && new_view <= end)
|
||||
new_view = term->grid->offset;
|
||||
int view_end = (term->grid->view + term->rows - 1) & (term->grid->num_rows - 1);
|
||||
if (view_end >= term->grid->view) {
|
||||
/* Viewport does *not* wrap around */
|
||||
if (start_row >= term->grid->view && end_row <= view_end)
|
||||
move_viewport = false;
|
||||
} else {
|
||||
if (new_view >= term->grid->offset || new_view <= end)
|
||||
new_view = term->grid->offset;
|
||||
/* Viewport wraps */
|
||||
if (start_row >= term->grid->view || end_row <= view_end)
|
||||
move_viewport = false;
|
||||
}
|
||||
|
||||
/* Update view */
|
||||
term->grid->view = new_view;
|
||||
if (new_view != old_view)
|
||||
term_damage_view(term);
|
||||
if (move_viewport) {
|
||||
int old_view = term->grid->view;
|
||||
int new_view = start_row - term->rows / 2;
|
||||
|
||||
while (new_view < 0)
|
||||
new_view += term->grid->num_rows;
|
||||
|
||||
/* Prevent scrolling in uninitialized rows */
|
||||
bool all_initialized = false;
|
||||
do {
|
||||
all_initialized = true;
|
||||
|
||||
for (int i = 0; i < term->rows; i++) {
|
||||
int row_no = (new_view + i) % term->grid->num_rows;
|
||||
if (term->grid->rows[row_no] == NULL) {
|
||||
all_initialized = false;
|
||||
new_view--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!all_initialized);
|
||||
|
||||
/* Don't scroll past scrollback history */
|
||||
int end = (term->grid->offset + term->rows - 1) % term->grid->num_rows;
|
||||
if (end >= term->grid->offset) {
|
||||
/* Not wrapped */
|
||||
if (new_view >= term->grid->offset && new_view <= end)
|
||||
new_view = term->grid->offset;
|
||||
} else {
|
||||
if (new_view >= term->grid->offset || new_view <= end)
|
||||
new_view = term->grid->offset;
|
||||
}
|
||||
|
||||
/* Update view */
|
||||
term->grid->view = new_view;
|
||||
if (new_view != old_view)
|
||||
term_damage_view(term);
|
||||
}
|
||||
|
||||
/* Selection endpoint is inclusive */
|
||||
if (--end_col < 0) {
|
||||
|
|
@ -184,7 +202,7 @@ search_find_next(struct terminal *term)
|
|||
|
||||
int start_row = term->search.match.row;
|
||||
int start_col = term->search.match.col;
|
||||
size_t len __attribute__((unused)) = term->search.match_len;
|
||||
size_t len = term->search.match_len;
|
||||
|
||||
assert((len == 0 && start_row == -1 && start_col == -1) ||
|
||||
(len > 0 && start_row >= 0 && start_col >= 0));
|
||||
|
|
|
|||
16
selection.c
16
selection.c
|
|
@ -372,8 +372,8 @@ selection_extend_normal(struct terminal *term, int col, int row, uint32_t serial
|
|||
|
||||
if (row < start->row || (row == start->row && col < start->col)) {
|
||||
/* Extend selection to start *before* current start */
|
||||
new_start = (struct coord){col, row};
|
||||
new_end = *end;
|
||||
new_start = *end;
|
||||
new_end = (struct coord){col, row};
|
||||
}
|
||||
|
||||
else if (row > end->row || (row == end->row && col > end->col)) {
|
||||
|
|
@ -391,8 +391,8 @@ selection_extend_normal(struct terminal *term, int col, int row, uint32_t serial
|
|||
abs(linear - (end->row * term->cols + end->col)))
|
||||
{
|
||||
/* Move start point */
|
||||
new_start = (struct coord){col, row};
|
||||
new_end = *end;
|
||||
new_start = *end;
|
||||
new_end = (struct coord){col, row};
|
||||
}
|
||||
|
||||
else {
|
||||
|
|
@ -440,13 +440,13 @@ selection_extend_block(struct terminal *term, int col, int row, uint32_t serial)
|
|||
/* Move one of the top corners */
|
||||
|
||||
if (abs(col - top_left.col) < abs(col - top_right.col)) {
|
||||
new_start = (struct coord){col, row};
|
||||
new_end = bottom_right;
|
||||
new_start = bottom_right;
|
||||
new_end = (struct coord){col, row};
|
||||
}
|
||||
|
||||
else {
|
||||
new_start = (struct coord){col, row};
|
||||
new_end = bottom_left;
|
||||
new_start = bottom_left;
|
||||
new_end = (struct coord){col, row};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
16
tokenize.c
16
tokenize.c
|
|
@ -38,14 +38,16 @@ tokenize_cmdline(char *cmdline, char ***argv)
|
|||
char delim = first_token_is_quoted ? cmdline[0] : ' ';
|
||||
|
||||
char *p = first_token_is_quoted ? &cmdline[1] : &cmdline[0];
|
||||
char *search_start = p;
|
||||
|
||||
size_t idx = 0;
|
||||
while (*p != '\0') {
|
||||
char *end = strchr(p, delim);
|
||||
char *end = strchr(search_start, delim);
|
||||
if (end == NULL) {
|
||||
if (delim != ' ') {
|
||||
LOG_ERR("unterminated %s quote\n", delim == '"' ? "double" : "single");
|
||||
LOG_ERR("unterminated %s quote", delim == '"' ? "double" : "single");
|
||||
free(*argv);
|
||||
*argv = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -57,6 +59,15 @@ tokenize_cmdline(char *cmdline, char ***argv)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (end > p && *(end - 1) == '\\') {
|
||||
/* Escaped quote, remove one level of escaping and
|
||||
* continue searching for "our" closing quote */
|
||||
memmove(end - 1, end, strlen(end));
|
||||
end[strlen(end) - 1] = '\0';
|
||||
search_start = end;
|
||||
continue;
|
||||
}
|
||||
|
||||
*end = '\0';
|
||||
|
||||
if (!push_argv(argv, &argv_size, p, &idx))
|
||||
|
|
@ -74,6 +85,7 @@ tokenize_cmdline(char *cmdline, char ***argv)
|
|||
p++;
|
||||
} else
|
||||
delim = ' ';
|
||||
search_start = p;
|
||||
}
|
||||
|
||||
if (!push_argv(argv, &argv_size, NULL, &idx))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue