Compare commits

...

244 commits

Author SHA1 Message Date
filippo-ferrari
26adaa667a changed st font size 2024-01-28 14:22:29 +01:00
filippo-ferrari
faee988753 changed st font size 2024-01-27 20:52:26 +01:00
Luke Smith
36d225d71d libxft note removed 2022-10-01 08:15:12 -04:00
Luke Smith
4c57f1f618 vim mouse clicking fixed, fix #344 2022-09-20 08:29:49 -04:00
Luke Smith
401b6f73f0 Merge branch 'master' of https://git.suckless.org/st 2022-09-20 08:20:42 -04:00
Luke Smith
2e9f87e5d8 libxft-git now recommended 2022-09-20 08:12:51 -04:00
Luke Smith
159f1666a8
Merge pull request #342 from AndyGozas/master
Fix buffer overflow in input handling
2022-09-20 12:11:20 +00:00
Hiltjo Posthuma
0008519903 FAQ: document the color emojis crash issue which affected some systems is fixed
It is fixed in libXft 2.3.6:

https://gitlab.freedesktop.org/xorg/lib/libxft/-/blob/libXft-2.3.5/NEWS
2022-09-16 23:07:09 +02:00
Andy Gozas
513536a47a
Fix buffer overflow in input handling
kpress function in x.c previously relied on the wrong understanding
of XmbLookupString behavior. When the composed string is longer
than the available buffer, the buffer is not initialized and the
actual length of the data available to read is returned, not
the amount of data written. When that amount is later used to
process the contents of this buffer, not only will the random
contents of the uninitialized buffer be sent directly to the
terminal and whichever application is now running in it, but
possibly also whatever is in the memory after that buffer,
leading to undefined behavior and possible random command execution.
2022-08-28 22:01:47 +00:00
Tom Schwindl
72fd32736a st: use `void' to indicate an empty parameter list 2022-08-18 17:14:10 +02:00
Luke Smith
ebf6f66fe1 remove flase upstream manual entries 2022-08-15 08:05:02 -04:00
Luke Smith
6f33b1ba55 Merge branch 'equwal-lukesmith-0.8.5' 2022-08-15 08:02:47 -04:00
Luke Smith
5858b22bef ch 2022-08-15 08:02:37 -04:00
Luke Smith
a63ef65ef1 Merge branch 'lukesmith-0.8.5' of https://github.com/equwal/st into equwal-lukesmith-0.8.5 2022-08-15 07:55:34 -04:00
Luke Smith
2e2d560516 colons in urls 2022-08-15 07:55:26 -04:00
Spenser Truex
f5b5452eac Merge latest suckless build into lukesmith-0.8.5
Includes the 0.8.5 version bump, which is great since many of the
patches have already been updated to here too.
2022-08-15 01:54:18 -03:00
Luke Smith
1455fedf56
Merge pull request #334 from kronikpillow/default-font
change default font to a installed one
2022-06-28 13:54:01 +00:00
Dejan Kutle
9371089cb6
change default font to a installed one 2022-06-24 09:57:26 +02:00
Luke Smith
713545c1fc fix #333 2022-06-20 10:57:55 -04:00
Luke Smith
3144a61c18
remove problematic and obsolete git lines 2022-04-18 19:59:59 -04:00
Luke Smith
9cabe89a11
Merge branch 'fakhriaunur-master' 2022-01-21 23:00:57 -05:00
fakhriaunur
fc6581c1b0
Update hb.c
Change the default state to disabled (uncomment the latter).
Clean the unused commented lines.
2021-09-07 18:08:10 +07:00
fakhriaunur
a3e807043e
Add stylistic sets / open type font feature
Using stylistic set hb_feature code from cog1to's patch.
Tested on Fira Code font.

Enable/disable the feature within this file, and then sudo make install as usual.
2021-09-07 13:18:11 +07:00
Luke Smith
e053bd6036
prevent losing columns on resize 2021-08-10 17:25:48 -04:00
Luke Smith
0af4782a47
Merge pull request #304 from monosans/master
Remove scroll info from README.md
2021-06-03 08:09:51 -04:00
monosans
abfbfb6b00 Remove scroll info from README.md 2021-06-03 14:46:08 +03:00
Luke Smith
ecd5e3f798
Merge pull request #296 from zMoooooritz/alpha
Add support for additional alpha when the term-window is not focused
2021-05-21 08:44:26 -04:00
Luke Smith
140f27565b
fix #301 2021-05-21 08:43:39 -04:00
Moritz Biering
bb56685063 Use the additional alpha-value as offset to support a changing alpha properly 2021-05-06 14:41:36 +02:00
Moritz Biering
69925ee23b Add support for additional alpha when the term-window is not focused 2021-05-05 21:23:37 +02:00
Luke Smith
7e6e779130
externalpipe all scrollback history 2021-04-05 17:46:09 -04:00
Luke Smith
4cd9bbae3e
scroll removed 2021-04-05 09:31:07 -04:00
Luke Smith
ed60a20a11
Merge branch 'master' of github.com:LukeSmithxyz/st 2021-04-05 09:27:08 -04:00
Luke Smith
60add40bd1
revert to older, better scrollback patch, fix #284, #289 2021-04-05 09:26:55 -04:00
Luke Smith
d2e4ab7e86
Merge pull request #282 from sahidvelji/make-uninstall
Uninstall scroll when uninstalling st
2021-03-08 10:40:22 -05:00
Sahid Velji
6aee0d97ed Uninstall scroll when uninstalling st 2021-03-08 10:31:37 -05:00
Luke Smith
67ef1c4d4e
remove final punctuation from possible urls 2021-03-03 21:39:35 -05:00
Luke Smith
ebb7b6c96a
Xdefaults example restored, close #278 2021-02-19 10:50:35 -05:00
Luke Smith
03fe8634cd
scroll update, fixes #274 2021-02-06 17:21:10 -05:00
Luke Smith
d39ded34f1
readme changes 2021-02-05 22:33:01 -05:00
Luke Smith
fa3c401390
0.8.4 update, scroll added as separate prog 2021-02-05 22:28:59 -05:00
Luke Smith
73c034ba05
close #271 2021-01-24 16:48:11 -05:00
Luke Smith
13b3c631be
funding fix for github 2020-11-30 20:26:36 -05:00
Luke Smith
1faf5cbc0b
Merge branch 'narukeh-master' 2020-11-30 15:23:39 -05:00
Luke Smith
dcaad2ceba
copy/open url use same regex. slimming. 2020-11-30 15:23:31 -05:00
Hekuran
7a7c5f8bfd fixed not being able to copy URL with a dash in it 2020-11-30 20:45:38 +01:00
Luke Smith
8ab3d03681
transparency to alt keys, added to man 2020-08-21 15:35:47 -04:00
Luke Smith
acdd54fe19
Merge branch 'master' of gitlab.com:LukeSmithxyz/st into master 2020-08-21 15:30:49 -04:00
Luke Smith
80c6f5c5f0 Merge branch 'master' into 'master'
change alpha with keyboard shortcut C-F11/C-F12

See merge request LukeSmithxyz/st!6
2020-08-21 19:05:54 +00:00
luquinha.virus
73a6020865 change alpha with keyboard shortcut C-F11/C-F12 2020-08-19 00:24:54 -03:00
Luke Smith
de6fd85eeb
Merge pull request #241 from pierg75/fix_urlhandler
Fixed a small issue with the urlhandler.
2020-08-07 07:20:03 -04:00
Pierguido Lambri
7e5b697352 Fixed a small issue with the urlhandler.
Urls lile:

https://whatever.domain/~myprecious/usefull-blog.html
https://brb.imback.maybe/isit/blah#sure

Were not propery handled (everything after either '#' or '~' were ignored).
Escaped '#' and added '~' in the regex.

Signed-off-by: Pierguido Lambri <plambri@redhat.com>
2020-08-07 09:53:57 +01:00
Luke Smith
e187610a23
Merge pull request #215 from halcyonseeker/master
Expanded url scheme support and fixed issue with tilde in url
2020-07-08 11:16:52 -04:00
Luke Smith
a96508af7c
Merge branch 'mackarelfish-master' 2020-07-08 11:16:08 -04:00
Luke Smith
cfef7fa605
Merge branch 'master' of https://github.com/mackarelfish/st into mackarelfish-master 2020-07-08 11:15:08 -04:00
Luke Smith
3f51ba298c
Merge branch 'dennisleexyz-mouse' 2020-07-08 11:13:33 -04:00
Dennis Lee
cf0807b3e9 use st-scrollback-mouse-altscreen-20190131-e23acb9 2020-06-30 18:33:15 -07:00
Luke Smith
222eac739d
Merge pull request #224 from Azumgi/glyph_truncation_fix
Glyph truncation fix
2020-06-13 07:56:08 -04:00
Dreomite
e3b821dcb3 Fix wide glyphs truncation 2020-06-13 04:15:30 +03:00
Dreomite
ca42c0cc02 Revert db6f796 (fonts overdrawing fix) 2020-06-13 02:36:43 +03:00
Luke Smith
b6a1f2d333
funding file for github sponsors 2020-06-02 15:23:00 -04:00
Luke Smith
919245dd95
dumb fix 2020-06-02 15:12:35 -04:00
Luke Smith
5478e1c89e
apparently caps 2020-06-02 15:09:30 -04:00
Luke Smith
3c1ef738a7
Merge branch 'master' of github.com:LukeSmithxyz/st 2020-06-02 15:06:12 -04:00
Luke Smith
9839f563e7
funding for github sponsors 2020-06-02 15:05:13 -04:00
mackarelfish
6bf7545fc9 Merge branch 'master' of https://github.com/lukesmithxyz/st 2020-05-31 10:23:03 +07:00
Thalia Wright
47b5bdf806 Expanded url scheme support and fixed issue with tilde in url 2020-05-26 01:58:55 -07:00
Luke Smith
22c71c355c
Merge pull request #212 from LoganDungeon/patch-1
renamed compton to picom
2020-05-17 07:57:56 -04:00
LoganDungeon
1d64231047
renamed compton to picom
Just a small change: compton recently was renamed to picom
2020-05-17 13:55:24 +02:00
Luke Smith
d2083bb47b
Merge pull request #211 from jakubrekowski/patch-1
Added info about include X11 in ubuntu.
2020-05-17 06:36:20 -04:00
Jakub Rekowski
069fed73da
Added info about include X11 in ubuntu.
Added comment with X11 path in systems based on ubuntu.
2020-05-17 10:36:21 +02:00
Luke Smith
74b68b32fa
Merge pull request #208 from trissim/wal-osc
Pywal live reload with OSC patch and transparency fix
2020-05-13 18:10:29 -04:00
Tristan Simas
05708c89c3 Reverted bg opacity back to 0.8 for upstream merge 2020-05-13 17:10:44 -04:00
Tristan Simas
24fa39b861 added the xclearwin patch to fix dirty borders after changing colors 2020-05-13 17:06:41 -04:00
Tristan Simas
c6c7c8541d Added OSC patch and changes xsetcolorname for live reloading pywal colors while keeping transparency 2020-05-13 14:52:22 -04:00
mackarelfish
4edc7282ab Added ligatures patch 2020-05-12 03:46:52 +07:00
Luke Smith
fdf3989005
tmux fix, including compile-time errors 2020-05-06 14:01:46 -04:00
Luke Smith
4f44d2d13f
auto-sync patch 2020-05-06 13:58:09 -04:00
Luke Smith
b35e4f5727
boxdraw added 2020-05-05 13:55:37 -04:00
Luke Smith
b43e574fa6
cleanup 2020-05-05 13:52:44 -04:00
Luke Smith
7e01028f86
Merge branch 'pasbi-master' 2020-04-28 19:11:52 -04:00
Luke Smith
b7b9c54a10
less opaque to compensate for darker bg 2020-04-28 19:09:15 -04:00
Luke Smith
f2faf93fab
regex update 2020-04-28 18:48:43 -04:00
Luke Smith
ce7ef62c11
fix with upstream 2020-04-28 18:46:21 -04:00
Luke Smith
3f44e88d6e
no longer embed dmenu to prevent error if dmenu
has no alpha patch
2020-04-16 14:48:52 -04:00
Luke Smith
1d1fefcd7b
Merge branch 'master' of github.com:LukeSmithxyz/st 2020-04-15 16:43:26 -04:00
Luke Smith
baa9fa076a
following links now separate script
this avoids the effects of swallow in dwm

it also will not produce dmenu without found urls
2020-04-15 16:43:14 -04:00
Luke Smith
d9f3fd8a16
cleanup 2020-04-15 16:42:19 -04:00
Luke Smith
1832b84873
Merge pull request #190 from eGredius/patch-1
Get rid of NUL character in PS1
2020-04-10 12:14:25 -04:00
GregW
93dcba59de
Get rid of NUL character in PS1
The first grep in the original script will return "binary file matches" if there are NUL characters in PS1, e.g, emojis.
The added line gets rid of NUL characters.
2020-04-10 11:59:55 -04:00
Luke Smith
689add8aad
middle click pastes selection again 2020-04-01 09:40:53 -04:00
Luke Smith
e7db668a0a
Merge branch 'master' of github.com:LukeSmithxyz/st 2020-04-01 09:28:28 -04:00
Luke Smith
e248ef8c33
Merge pull request #183 from Fogapod/master
Do not copy text to clipboard after selecting
2020-04-01 09:24:32 -04:00
Eugene
7917ec930a Do not copy text to clipboard after selecting
This behaviour was introduced in 6833411400
Resolves: #177
2020-04-01 13:37:57 +03:00
georg3tom
9ce69b377a Changed flag to -z 2020-03-27 22:36:12 +05:30
georg3tom
26b57c7300 FIX bug in error and copy link
Apparently read only reads a single line so only one url was
    fed to dmenu.
2020-03-27 21:29:53 +05:30
georg3tom
8ba5325adb dmenu prompt is only shown if there's atleast one link 2020-03-25 15:06:03 +05:30
Luke Smith
72c555f605
Merge branch 'master' of github.com:LukeSmithxyz/st 2020-03-20 08:40:22 -04:00
Luke Smith
ec72bbe23e
adding @ to regex 2020-03-11 09:59:02 -04:00
Luke Smith
6725a2fde0
Merge pull request #85 from jbenden/xim_interval
Add interval timer to XIM spot updates
2020-03-11 09:43:27 -04:00
Luke Smith
e2a59d5521
backend color number changes 2020-02-09 15:48:07 -05:00
Luke Smith
66780d00e4
middle click pastes selection again 2020-02-09 15:46:13 -05:00
Luke Smith
4c05d1cef3
font display fixes 2020-02-07 22:44:19 -05:00
Luke Smith
f0b7aeeb53
minor regex improvement 2020-02-07 18:46:24 -05:00
Luke Smith
cd28e535f8
link 2020-02-07 18:46:12 -05:00
Luke Smith
6852d5ecfc
note on crashing error 2020-02-01 18:33:22 -05:00
Luke Smith
131bdf67fd
Merge pull request #126 from jcapiitao/handle_hash_based_urls
Add hash symbol in openurlcmd and copyurlcmd regexp
2019-09-10 07:26:18 -04:00
Joel Capitao
63849e346b Add hash symbol in openurlcmd and copyurlcmd regexp
This enables hash-based urls support.
2019-09-10 11:15:33 +02:00
Luke Smith
4a9b405ab0
Merge pull request #109 from sarpik/patch-1
Add background, foreground, cursor color example
2019-07-01 08:43:47 -04:00
Kipras Melnikovas
7150fd6b35
Add background, foreground, cursor color example
You might want to update every theme with different colors - I just didn't knew which ones to put there

(or maybe just mimic `color0` as `background` & `color15` as `foreground` and `cursorColor` (see the diff @ #108))

Fixes #108 and #97
2019-06-29 15:21:00 +03:00
Luke Smith
cad53235df
Merge pull request #102 from undx/undx/pr-fix-promtp-w-space
fix excessive slurping when prompt starts w/ space(s)
2019-06-21 14:48:05 -04:00
undx
1264ad0515 fix excessive slurping when prompt starts w/ space(s) 2019-06-21 20:35:04 +02:00
Luke Smith
7d5e65282e
Merge pull request #101 from undx/pr
fix prompt starting with space(s)
2019-06-21 12:02:07 -04:00
undx
bf29538fdd fix prompt starting with space(s) 2019-06-21 17:39:52 +02:00
Luke Smith
5c49ff8012
Merge pull request #99 from rjl6789/stluke-pull
additional Xresources item compatible with font2 patch
2019-06-18 09:01:24 -04:00
rjl6789
fb95bcb8a6 additional Xresources item compatible with font2 patch 2019-06-18 09:08:41 +01:00
Luke Smith
261652b42f
case insensitivity 2019-06-06 11:38:47 -04:00
Luke Smith
60506bfc82
Merge pull request #96 from jonbulica99/patch-font2
Apply font2 patch
2019-06-04 16:22:50 -04:00
Jon Bulica
5728d045eb apply font2 patch 2019-06-03 23:58:12 +02:00
Luke Smith
3c0a2e8d30
Merge pull request #95 from jonbulica99/master
Apply anysize patch so that the window size is not dependent of text size
2019-06-02 16:41:56 -04:00
Jon Bulica
9449c5787f apply anysize patch 2019-06-02 22:29:00 +02:00
Luke Smith
e2046555c0
Merge pull request #88 from lucaslugao/master
Premultiply background RGB values if alpha is used
2019-05-23 23:02:08 -04:00
Lucas Lugao
ffcacfa98d Premultiply background RGB values if alpha is used 2019-05-21 17:17:13 +02:00
Luke Smith
d06bf1fd7e
magnet links detectable 2019-05-19 20:16:13 -04:00
Joseph Benden
a96c33e81e Add interval timer to XIM updates
Signed-off-by: Joseph Benden <joe@benden.us>
2019-05-17 11:54:04 -07:00
Luke Smith
6c0c86191c
Merge pull request #79 from rjl6789/virgin
default fg, bg and cursor - modified so works with .Xresources
2019-05-12 09:14:18 -04:00
rjl6789
55405e17f1 correct fg,bg,cs defaults so will work with Xresources and default is gruvbox 2019-05-11 12:11:49 +01:00
rjl6789
6ecb8b1595 make config consistent with virgin lukesmith st repo 2019-05-11 12:05:30 +01:00
rjl6789
ea40e61a8d Merge remote-tracking branch 'upstream/master' into virgin 2019-05-11 12:01:58 +01:00
Luke Smith
da82328295
Merge pull request #77 from otlin100/luke
allow '%' in URLs
2019-05-10 12:54:26 -04:00
otlin100
3b6662093c allow '%' in URLs 2019-05-10 18:46:14 +02:00
Luke Smith
9fb50579c1
Merge pull request #75 from Lukeblanes/master
Include links with port numbers
2019-05-10 09:54:10 -04:00
Luke
5754699235 Include links with port numbers 2019-05-10 14:45:49 +02:00
rjl6789
9b18354de6 corrected fg and bg defaults again 2019-05-09 17:55:26 +01:00
Luke Smith
8c119155ba
original color 2019-05-09 07:38:23 -04:00
Luke Smith
be3ea16279
Merge pull request #72 from rjl6789/master
correct colorname declaration
2019-05-09 07:30:37 -04:00
rjl6789
e0005c695e corrected colorname declaration 2019-05-09 07:42:21 +01:00
rjl6789
9aa7f38187 Merge remote-tracking branch 'upstream/master' 2019-05-09 07:37:21 +01:00
Luke Smith
da13ef1246
external pipe eternal 2019-05-08 15:29:33 -04:00
Luke Smith
ca12440fa9
Merge pull request #70 from YusufAktepe/master
get version from config.mk
2019-05-08 15:24:47 -04:00
yusufaktepe
19c95dd96c
get version from config.mk 2019-05-08 22:03:05 +03:00
Luke Smith
2087ab9c6d
forgot which markdown 2019-05-08 11:38:15 -04:00
Luke Smith
84d49f527d
copy output of command with alt-o 2019-05-08 11:26:11 -04:00
Luke Smith
140c6b0a3f
Merge pull request #69 from YusufAktepe/master
Updated st to 0.8.2
2019-05-07 21:53:37 -04:00
yusufaktepe
3cd91894ec
Updated st to 0.8.2
Updated to latest git (20190414.f1546cf) & updated patches.

Changes:
. Upstream fixes.
. Alpha: Opacity value is now typed in float (0-1).
  Also "-A" cmd option added as alternative opacity changing method.
. Clipboard: middle click pastes from clipboard.
. Organized shortcuts.
2019-05-08 04:05:57 +03:00
rjl6789
e99aa29eef test2 2019-05-07 22:28:40 +01:00
rjl6789
25f59984da test 2019-05-07 22:28:04 +01:00
Luke Smith
35506b44ad
Merge pull request #68 from kajzersoze/master
include links with & in URLs
2019-05-06 08:25:49 -04:00
kajzersoze
8844764bc7
include links with & in URLs 2019-05-06 14:11:50 +02:00
Luke Smith
36eb185897
Merge pull request #66 from ijacquez/feature/set-install-prefix
Use conditional variable assignment for PREFIX
2019-05-04 18:48:01 -04:00
Israel Jacquez
252fba32be Use conditional variable assignment for PREFIX 2019-05-04 15:09:58 -07:00
Luke Smith
d9575acb88
copy urls with alt-y 2019-05-03 20:11:37 -04:00
Luke Smith
e196d09b86
Merge pull request #65 from g-mips/master
Added Xresource border to adjust the internal border.
2019-04-28 18:15:01 -04:00
g-mips
84480af682 Added Xresource border to adjust the internal border. 2019-04-27 12:59:14 -06:00
Luke Smith
05cc5be681
urls over lines 2019-04-26 20:40:39 -04:00
otlin100
f7c138b8cb read multiline URLs and URLs without 'http://' from mutt 2019-04-27 03:05:31 +02:00
Luke Smith
a36768bfa1
aur note 2019-04-23 12:45:03 -04:00
Rob
b919e7dde9
Merge pull request #1 from LukeSmithxyz/master
update april 2019
2019-04-22 19:55:52 +01:00
Luke Smith
30a6a001fe
dumb 2019-04-05 15:50:28 -04:00
Luke Smith
3b6bf70d87
gitignore and desc change for aur 2019-04-05 15:50:11 -04:00
Luke Smith
1cd0b79004
Merge pull request #57 from YusufAktepe/master
PKGBUILD added for easier management with pacman.
2019-04-04 22:58:09 -04:00
yusufaktepe
7923599f52
PKGBUILD added for easier management with pacman. 2019-04-05 04:38:48 +03:00
Luke Smith
7af0421674
xurls no longer required 2019-04-04 18:36:38 -04:00
Luke Smith
44a6c377b1
xdef example added 2019-04-02 12:29:17 -04:00
Rob
d6863bfede add simple script to uninstall->clean->rebuild->install 2019-03-31 18:52:07 +01:00
Rob
502c57de2f change bg and fg colors to 256 257 respectivly 2019-03-31 18:51:31 +01:00
Luke Smith
cd4a194063
readme updates 2019-02-02 11:10:43 -05:00
Luke Smith
99c9031b89
Merge pull request #43 from codingCoffee/ignore
chore: 🤖 added built files in .gitignore
2019-01-13 14:12:22 -05:00
Ameya Shenoy
5b039bacce
chore: 🤖 added built files in .gitignore 2019-01-14 00:37:03 +05:30
Luke Smith
661e82f937
Merge pull request #40 from iamdiogo/patch-1
Fixed typo in README.md
2019-01-08 20:22:14 -05:00
Diogo Silva
a839a90485
Fixed typo in README.md 2019-01-08 22:50:19 +00:00
Luke Smith
c5107954b2
cursorColor removed 2018-12-18 20:29:38 -05:00
Luke Smith
6863c0608a
just use xdg-open 2018-12-18 09:29:09 -05:00
Luke Smith
b8f48f3176
Merge pull request #33 from hexinal/patch-1
Updated shortcut for zoomreset
2018-12-18 07:47:58 -05:00
hexinal
93ea70adb2
Updated shortcut for zoomreset 2018-12-18 11:15:39 +00:00
Luke Smith
f9c152ab79
remove adjacent identical links from url picker 2018-12-16 22:50:23 -05:00
Luke Smith
edbc788d20
Merge pull request #31 from terriblephrases/master
Upstream updates
2018-12-16 20:10:20 -05:00
Hiltjo Posthuma
7a1a92ff3f small code-style fix 2018-12-16 02:20:16 +01:00
Lauri Tirkkonen
e651f31642 output child WEXITSTATUS/WTERMSIG on abnormal termination 2018-12-16 02:19:10 +01:00
Hiltjo Posthuma
3061ebd7e1 st: small typofix in comment 2018-12-16 02:18:36 +01:00
Hiltjo Posthuma
539e145e65 fix memory leak in xloadcols()
reported by Avi Halachmi (:avih)" <avihpit@yahoo.com>

patch slightly changed by me.
2018-12-16 02:18:16 +01:00
Jules Maselbas
62371f0b21 Fix crash on resize
Prevent to realloc xw.specbuc with a negative number of col.
Add proper hints for the minimal size, for one character.
2018-12-16 02:10:06 +01:00
Luke Smith
ee16dfb8f3
revert to normal size now just alt-home 2018-12-13 17:54:26 -05:00
Luke Smith
a2b1dfe1ba
ctrl-l chooses urls with xurls and dmenu 2018-12-13 17:23:38 -05:00
Luke Smith
6c93dd4520
Merge pull request #25 from terriblephrases/master
corrects color and font size info
2018-12-03 17:01:05 -05:00
terriblephrases
3fb4962375 corrects color and font size info 2018-12-03 20:53:04 +01:00
Luke Smith
7699e6d67c
Merge pull request #24 from terriblephrases/master
Correct gruvbox defaultfg and cursor colors
2018-12-03 12:58:50 -05:00
terriblephrases
313ecfec81 sets correct gruvbox defaultfg and cursor colors, restores poss. to use 257+ colors 2018-12-03 17:38:57 +01:00
Luke Smith
15c6321d87
gruvbox 2018-12-01 18:23:52 -05:00
Luke Smith
ec8887f0f2
openbsd compilation note 2018-11-24 09:17:12 -05:00
Luke Smith
1210133b4b
alpha/transparency read from xresources 2018-11-14 10:31:03 -05:00
Luke Smith
7186ee2ddd
mouse bindings and documentation 2018-10-16 15:21:02 -04:00
Luke Smith
07bfca3009
default font larger 2018-10-16 14:41:35 -04:00
Luke Smith
2e89d5f575
man fixes 2018-10-16 14:41:14 -04:00
Luke Smith
523d83e6ab copy/paste fixes 2018-10-04 16:53:12 -04:00
Luke Smith
53b4c270aa bgcolor to 0 2018-10-04 16:18:07 -04:00
Luke Smith
a8137b4541 readme color update 2018-09-14 07:57:35 -04:00
Luke Smith
059106186b Revert "Update LICENSE"
This reverts commit 85d8621d8c.
2018-09-01 00:16:58 -04:00
Luke Smith
0bd7a0bb0d Merge branch 'master' of github.com:LukeSmithxyz/st 2018-08-27 13:14:35 -04:00
Luke Smith
8148957553 bg fix on some graphical systems 2018-08-27 13:13:56 -04:00
Luke Smith
85d8621d8c
Update LICENSE 2018-08-02 00:28:17 -04:00
Luke Smith
f0f1621f40 junk cleanup 2018-08-02 00:11:23 -04:00
Luke Smith
075f8eee4a old patches removed 2018-08-01 21:28:49 -04:00
Luke Smith
ffe6670fe2 alt-shift-up/down for zooming 2018-08-01 09:57:41 -04:00
Luke Smith
02ebb37e50
Merge pull request #5 from cquijano/patched
fix defaultbg value, solve sigfault
2018-07-15 14:03:29 -04:00
Carlos Quijano
c49edb020e fix defaultbg value, solve sigfault 2018-07-15 19:40:51 +02:00
Luke Smith
43af5f7790 manual updates 2018-07-08 14:23:08 -04:00
Luke Smith
f9cd5efaa0 shift-insert now pastes from clipboard 2018-07-08 14:22:52 -04:00
Luke Smith
7f231a6b54 xresources patch now default 2018-07-07 03:28:01 -04:00
Luke Smith
195535facc wal compatibility added 2018-06-25 19:28:26 -04:00
Luke Smith
ae9739faed alt-shift-j/k zoom bindings b/c why not lmao 2018-05-01 15:01:58 -07:00
Luke Smith
f6ecf743ab cleaning 2018-05-01 14:42:15 -07:00
Luke Smith
cd357e5c67 Big cleanup and some redundant bindings added 2018-05-01 14:36:36 -07:00
Kornelije Sajler
60ea12d971 Updated few minor changes in README. 2018-04-25 22:58:56 +02:00
Kornelije Sajler
67940f05e5 Updated README with few more info. 2018-04-25 22:53:54 +02:00
Kornelije Sajler
582549f486 Updade README with more info no custom changes.
Updated config.def.h with my/luke preferences. Font=14px, alpha=0xcd, colorname[]=pop_os-inspired.
Changed values for bg,fg and cursor using 256, 257, 258 indexs from colorname[].
Patched with luke's keymapping's.
2018-04-25 22:49:04 +02:00
Kornelije Sajler
0ad3d4eddf Updated st 0.8.1. Used new patches, scrollblock and alpha fixed.
Created run-patches.sh, runs all patches on clean st 0.8.1 code.
All old patches remvoed, including trasparency diff.
Not including solarized theme, don't see value of it.
Commented colornames array with color indexs from 0-15, includes index 255, and afterwards bg, fg and cursor, change those for background, foreground and cursor color. Seems better than solarized toggle.
Updated README.
2018-04-25 22:15:11 +02:00
Luke Smith
efad574780 transparency more opaque 2018-03-12 10:57:47 -07:00
Luke Smith
8c0ade2c1e transparency now default 2018-03-10 19:52:41 -07:00
Luke
3ffde570e0 transparency explanation added 2018-02-05 21:33:39 -07:00
Luke Smith
23a6f74157
Merge pull request #1 from PhilipNelson5/patch-1
spelling
2018-01-30 15:04:20 -07:00
Philip Nelson
9ade6ae63a
spelling 2018-01-21 17:42:14 -07:00
Luke
f684e44e69 readme changes 2018-01-21 12:15:29 -07:00
Luke
858a34ade6 readme explains transparency installation 2018-01-19 14:32:00 -07:00
Luke
5d1d32f571 fixed transparency patch added 2018-01-19 14:22:14 -07:00
Luke
1cfd5953dc redundant readme line removed 2018-01-18 19:39:23 -07:00
Luke
167a334f2c alt-u & alt-d: up & down in history; readme update 2018-01-18 19:33:28 -07:00
Luke
8b29be268a fix of brainlet error, formatting fix too 2018-01-18 19:21:15 -07:00
Luke
4f508ec001 formatting 2018-01-18 19:17:13 -07:00
Luke
3cb5996688 alt-j/k for scrolling up one line at a time 2018-01-18 19:05:49 -07:00
Luke
61824fc462 key bindings stated in README 2018-01-18 08:51:08 -07:00
Luke
234972a077 readme now personalized 2018-01-18 00:01:16 -07:00
Luke
a9b51e4ec0 color toggle now Alt-Tab instead of F6 2018-01-17 23:55:00 -07:00
Luke
74e54e0ccc mono default font, 14pt 2018-01-17 23:53:56 -07:00
Shiva
c50850028b Enable travis build 2017-01-30 20:14:38 -08:00
Shiva
b1e1a6e993 Add badges 2017-01-30 20:11:57 -08:00
Shiva
5d52a549f9 Merge pull request #2 from gitter-badger/gitter-badge-1
Add a Gitter chat link to README
2017-01-30 19:53:26 -08:00
The Gitter Badger
778e1f0cf7 Add Gitter link 2017-01-31 03:51:55 +00:00
Shiva
97e27bc64d Update readme with details about patches 2017-01-29 21:59:15 -08:00
Shiva
efde1e896e Solarized support + switch with F6 2017-01-29 21:53:07 -08:00
Shiva
e0a07a9392 vertically center lines in space available 2017-01-29 21:40:45 -08:00
Shiva
10bf3c8507 Scrollback + wheel support 2017-01-29 21:39:12 -08:00
Shiva
6833411400 clipboard support 2017-01-29 21:35:17 -08:00
Shiva
7549ffd200 Clean generated config.h 2017-01-29 21:16:22 -08:00
23 changed files with 1604 additions and 507 deletions

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
patches/
.gitignore
*.o
st
*.orig

250
FAQ
View file

@ -1,250 +0,0 @@
## Why does st not handle utmp entries?
Use the excellent tool of [utmp](https://git.suckless.org/utmp/) for this task.
## Some _random program_ complains that st is unknown/not recognised/unsupported/whatever!
It means that st doesnt have any terminfo entry on your system. Chances are
you did not `make install`. If you just want to test it without installing it,
you can manually run `tic -sx st.info`.
## Nothing works, and nothing is said about an unknown terminal!
* Some programs just assume theyre running in xterm i.e. they dont rely on
terminfo. What you see is the current state of the “xterm compliance”.
* Some programs dont complain about the lacking st description and default to
another terminal. In that case see the question about terminfo.
## How do I scroll back up?
* Using a terminal multiplexer.
* `st -e tmux` using C-b [
* `st -e screen` using C-a ESC
* Using the excellent tool of [scroll](https://git.suckless.org/scroll/).
* Using the scrollback [patch](https://st.suckless.org/patches/scrollback/).
## I would like to have utmp and/or scroll functionality by default
You can add the absolute path of both programs in your config.h file. You only
have to modify the value of utmp and scroll variables.
## Why doesn't the Del key work in some programs?
Taken from the terminfo manpage:
If the terminal has a keypad that transmits codes when the keys
are pressed, this information can be given. Note that it is not
possible to handle terminals where the keypad only works in
local (this applies, for example, to the unshifted HP 2621 keys).
If the keypad can be set to transmit or not transmit, give these
codes as smkx and rmkx. Otherwise the keypad is assumed to
always transmit.
In the st case smkx=E[?1hE= and rmkx=E[?1lE>, so it is mandatory that
applications which want to test against keypad keys send these
sequences.
But buggy applications (like bash and irssi, for example) don't do this. A fast
solution for them is to use the following command:
$ printf '\033[?1h\033=' >/dev/tty
or
$ tput smkx
In the case of bash, readline is used. Readline has a different note in its
manpage about this issue:
enable-keypad (Off)
When set to On, readline will try to enable the
application keypad when it is called. Some systems
need this to enable arrow keys.
Adding this option to your .inputrc will fix the keypad problem for all
applications using readline.
If you are using zsh, then read the zsh FAQ
<http://zsh.sourceforge.net/FAQ/zshfaq03.html#l25>:
It should be noted that the O / [ confusion can occur with other keys
such as Home and End. Some systems let you query the key sequences
sent by these keys from the system's terminal database, terminfo.
Unfortunately, the key sequences given there typically apply to the
mode that is not the one zsh uses by default (it's the "application"
mode rather than the "raw" mode). Explaining the use of terminfo is
outside of the scope of this FAQ, but if you wish to use the key
sequences given there you can tell the line editor to turn on
"application" mode when it starts and turn it off when it stops:
function zle-line-init () { echoti smkx }
function zle-line-finish () { echoti rmkx }
zle -N zle-line-init
zle -N zle-line-finish
Putting these lines into your .zshrc will fix the problems.
## How can I use meta in 8bit mode?
St supports meta in 8bit mode, but the default terminfo entry doesn't
use this capability. If you want it, you have to use the 'st-meta' value
in TERM.
## I cannot compile st in OpenBSD
OpenBSD lacks librt, despite it being mandatory in POSIX
<http://pubs.opengroup.org/onlinepubs/9699919799/utilities/c99.html#tag_20_11_13>.
If you want to compile st for OpenBSD you have to remove -lrt from config.mk, and
st will compile without any loss of functionality, because all the functions are
included in libc on this platform.
## The Backspace Case
St is emulating the Linux way of handling backspace being delete and delete being
backspace.
This is an issue that was discussed in suckless mailing list
<https://lists.suckless.org/dev/1404/20697.html>. Here is why some old grumpy
terminal users wants its backspace to be how he feels it:
Well, I am going to comment why I want to change the behaviour
of this key. When ASCII was defined in 1968, communication
with computers was done using punched cards, or hardcopy
terminals (basically a typewriter machine connected with the
computer using a serial port). ASCII defines DELETE as 7F,
because, in punched-card terms, it means all the holes of the
card punched; it is thus a kind of 'physical delete'. In the
same way, the BACKSPACE key was a non-destructive backspace,
as on a typewriter. So, if you wanted to delete a character,
you had to BACKSPACE and then DELETE. Another use of BACKSPACE
was to type accented characters, for example 'a BACKSPACE `'.
The VT100 had no BACKSPACE key; it was generated using the
CONTROL key as another control character (CONTROL key sets to
0 b7 b6 b5, so it converts H (code 0x48) into BACKSPACE (code
0x08)), but it had a DELETE key in a similar position where
the BACKSPACE key is located today on common PC keyboards.
All the terminal emulators emulated the difference between
these keys correctly: the backspace key generated a BACKSPACE
(^H) and delete key generated a DELETE (^?).
But a problem arose when Linus Torvalds wrote Linux. Unlike
earlier terminals, the Linux virtual terminal (the terminal
emulator integrated in the kernel) returned a DELETE when
backspace was pressed, due to the VT100 having a DELETE key in
the same position. This created a lot of problems (see [1]
and [2]). Since Linux has become the king, a lot of terminal
emulators today generate a DELETE when the backspace key is
pressed in order to avoid problems with Linux. The result is
that the only way of generating a BACKSPACE on these systems
is by using CONTROL + H. (I also think that emacs had an
important point here because the CONTROL + H prefix is used
in emacs in some commands (help commands).)
From point of view of the kernel, you can change the key
for deleting a previous character with stty erase. When you
connect a real terminal into a machine you describe the type
of terminal, so getty configures the correct value of stty
erase for this terminal. In the case of terminal emulators,
however, you don't have any getty that can set the correct
value of stty erase, so you always get the default value.
For this reason, it is necessary to add 'stty erase ^H' to your
profile if you have changed the value of the backspace key.
Of course, another solution is for st itself to modify the
value of stty erase. I usually have the inverse problem:
when I connect to non-Unix machines, I have to press CONTROL +
h to get a BACKSPACE. The inverse problem occurs when a user
connects to my Unix machines from a different system with a
correct backspace key.
[1] http://www.ibb.net/~anne/keyboard.html
[2] http://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO-5.html
## But I really want the old grumpy behaviour of my terminal
Apply [1].
[1] https://st.suckless.org/patches/delkey
## Why do images not work in st using the w3m image hack?
w3mimg uses a hack that draws an image on top of the terminal emulator Drawable
window. The hack relies on the terminal to use a single buffer to draw its
contents directly.
st uses double-buffered drawing so the image is quickly replaced and may show a
short flicker effect.
Below is a patch example to change st double-buffering to a single Drawable
buffer.
diff --git a/x.c b/x.c
--- a/x.c
+++ b/x.c
@@ -732,10 +732,6 @@ xresize(int col, int row)
win.tw = col * win.cw;
win.th = row * win.ch;
- XFreePixmap(xw.dpy, xw.buf);
- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
- DefaultDepth(xw.dpy, xw.scr));
- XftDrawChange(xw.draw, xw.buf);
xclear(0, 0, win.w, win.h);
/* resize to new width */
@@ -1148,8 +1144,7 @@ xinit(int cols, int rows)
gcvalues.graphics_exposures = False;
dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
&gcvalues);
- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
- DefaultDepth(xw.dpy, xw.scr));
+ xw.buf = xw.win;
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
@@ -1632,8 +1627,6 @@ xdrawline(Line line, int x1, int y1, int x2)
void
xfinishdraw(void)
{
- XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w,
- win.h, 0, 0);
XSetForeground(xw.dpy, dc.gc,
dc.col[IS_SET(MODE_REVERSE)?
defaultfg : defaultbg].pixel);
## BadLength X error in Xft when trying to render emoji
Xft makes st crash when rendering color emojis with the following error:
"X Error of failed request: BadLength (poly request too large or internal Xlib length error)"
Major opcode of failed request: 139 (RENDER)
Minor opcode of failed request: 20 (RenderAddGlyphs)
Serial number of failed request: 1595
Current serial number in output stream: 1818"
This is a known bug in Xft (not st) which happens on some platforms and
combination of particular fonts and fontconfig settings.
See also:
https://gitlab.freedesktop.org/xorg/lib/libxft/issues/6
https://bugs.freedesktop.org/show_bug.cgi?id=107534
https://bugzilla.redhat.com/show_bug.cgi?id=1498269
The solution is to remove color emoji fonts or disable this in the fontconfig
XML configuration. As an ugly workaround (which may work only on newer
fontconfig versions (FC_COLOR)), the following code can be used to mask color
fonts:
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
Please don't bother reporting this bug to st, but notify the upstream Xft
developers about fixing this bug.

2
FUNDING.yml Normal file
View file

@ -0,0 +1,2 @@
custom: ["https://lukesmith.xyz/donate.html"]
github: lukesmithxyz

17
LEGACY
View file

@ -1,17 +0,0 @@
A STATEMENT ON LEGACY SUPPORT
In the terminal world there is much cruft that comes from old and unsup
ported terminals that inherit incompatible modes and escape sequences
which noone is able to know, except when he/she comes from that time and
developed a graphical vt100 emulator at that time.
One goal of st is to only support what is really needed. When you en
counter a sequence which you really need, implement it. But while you
are at it, do not add the other cruft you might encounter while sneek
ing at other terminal emulators. History has bloated them and there is
no real evidence that most of the sequences are used today.
Christoph Lohmann <20h@r-36.net>
2012-09-13T07:00:36.081271045+02:00

View file

@ -4,7 +4,7 @@
include config.mk
SRC = st.c x.c
SRC = st.c x.c boxdraw.c hb.c
OBJ = $(SRC:.c=.o)
all: options st
@ -15,14 +15,13 @@ options:
@echo "LDFLAGS = $(STLDFLAGS)"
@echo "CC = $(CC)"
config.h:
cp config.def.h config.h
.c.o:
$(CC) $(STCFLAGS) -c $<
st.o: config.h st.h win.h
x.o: arg.h config.h st.h win.h
x.o: arg.h config.h st.h win.h hb.h
hb.o: st.h
boxdraw.o: config.h st.h boxdraw_data.h
$(OBJ): config.h config.mk
@ -30,12 +29,12 @@ st: $(OBJ)
$(CC) -o $@ $(OBJ) $(STLDFLAGS)
clean:
rm -f st $(OBJ) st-$(VERSION).tar.gz
rm -f st $(OBJ) st-$(VERSION).tar.gz *.rej *.orig *.o
dist: clean
mkdir -p st-$(VERSION)
cp -R FAQ LEGACY TODO LICENSE Makefile README config.mk\
config.def.h st.info st.1 arg.h st.h win.h $(SRC)\
config.h st.info st.1 arg.h st.h win.h $(SRC)\
st-$(VERSION)
tar -cf - st-$(VERSION) | gzip > st-$(VERSION).tar.gz
rm -rf st-$(VERSION)
@ -43,7 +42,11 @@ dist: clean
install: st
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f st $(DESTDIR)$(PREFIX)/bin
cp -f st-copyout $(DESTDIR)$(PREFIX)/bin
cp -f st-urlhandler $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/st
chmod 755 $(DESTDIR)$(PREFIX)/bin/st-copyout
chmod 755 $(DESTDIR)$(PREFIX)/bin/st-urlhandler
mkdir -p $(DESTDIR)$(MANPREFIX)/man1
sed "s/VERSION/$(VERSION)/g" < st.1 > $(DESTDIR)$(MANPREFIX)/man1/st.1
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1
@ -52,6 +55,8 @@ install: st
uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/st
rm -f $(DESTDIR)$(PREFIX)/bin/st-copyout
rm -f $(DESTDIR)$(PREFIX)/bin/st-urlhandler
rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1
.PHONY: all options clean dist install uninstall

45
PKGBUILD Normal file
View file

@ -0,0 +1,45 @@
# Maintainer:
pkgname=st-luke-git
_pkgname=st
pkgver=0.8.2.r1062.2087ab9
pkgrel=1
epoch=1
pkgdesc="Luke's simple (suckless) terminal with vim-bindings, transparency, xresources, etc. "
url='https://github.com/LukeSmithxyz/st'
arch=('i686' 'x86_64')
license=('MIT')
options=('zipman')
depends=('libxft')
makedepends=('ncurses' 'libxext' 'git')
optdepends=('dmenu: feed urls to dmenu')
source=(git+https://github.com/LukeSmithxyz/st)
sha1sums=('SKIP')
provides=("${_pkgname}")
conflicts=("${_pkgname}")
pkgver() {
cd "${_pkgname}"
printf "%s.r%s.%s" "$(awk '/^VERSION =/ {print $3}' config.mk)" \
"$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd $srcdir/${_pkgname}
# skip terminfo which conflicts with ncurses
sed -i '/tic /d' Makefile
}
build() {
cd "${_pkgname}"
make X11INC=/usr/include/X11 X11LIB=/usr/lib/X11
}
package() {
cd "${_pkgname}"
make PREFIX=/usr DESTDIR="${pkgdir}" install
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
install -Dm644 README.md "${pkgdir}/usr/share/doc/${pkgname}/README.md"
install -Dm644 Xdefaults "${pkgdir}/usr/share/doc/${pkgname}/Xdefaults.example"
}

34
README
View file

@ -1,34 +0,0 @@
st - simple terminal
--------------------
st is a simple terminal emulator for X which sucks less.
Requirements
------------
In order to build st you need the Xlib header files.
Installation
------------
Edit config.mk to match your local setup (st is installed into
the /usr/local namespace by default).
Afterwards enter the following command to build and install st (if
necessary as root):
make clean install
Running st
----------
If you did not install st with make clean install, you must compile
the st terminfo entry with the following command:
tic -sx st.info
See the man page for additional details.
Credits
-------
Based on Aurélien APTEL <aurelien dot aptel at gmail dot com> bt source code.

89
README.md Normal file
View file

@ -0,0 +1,89 @@
# Luke's build of st - the simple (suckless) terminal
The [suckless terminal (st)](https://st.suckless.org/) with some additional
features that make it literally the best terminal emulator ever:
## Unique features (using dmenu)
+ **follow urls** by pressing `alt-l`
+ **copy urls** in the same way with `alt-y`
+ **copy the output of commands** with `alt-o`
## Bindings for
+ **scrollback** with `alt-↑/↓` or `alt-pageup/down` or `shift` while scrolling the
mouse.
+ OR **vim-bindings**: scroll up/down in history with `alt-k` and `alt-j`.
Faster with `alt-u`/`alt-d`.
+ **zoom/change font size**: same bindings as above, but holding down shift as
well. `alt-home` returns to default
+ **copy text** with `alt-c`, **paste** is `alt-v` or `shift-insert`
## Pretty stuff
+ Compatibility with `Xresources` and `pywal` for dynamic colors.
+ Default [gruvbox](https://github.com/morhetz/gruvbox) colors otherwise.
+ Transparency/alpha, which is also adjustable from your `Xresources`.
+ Default font is system "mono" at 14pt, meaning the font will match your
system font.
## Other st patches
+ Boxdraw
+ Ligatures
+ font2
+ updated to latest version 0.8.5
## Installation for newbs
You should have xlib header files and libharfbuzz build files installed.
```
git clone https://github.com/LukeSmithxyz/st
cd st
sudo make install
```
Obviously, `make` is required to build. `fontconfig` is required for the
default build, since it asks `fontconfig` for your system monospace font. It
might be obvious, but `libX11` and `libXft` are required as well. Chances are,
you have all of this installed already.
On OpenBSD, be sure to edit `config.mk` first and remove `-lrt` from the
`$LIBS` before compiling.
Be sure to have a composite manager (`xcompmgr`, `picom`, etc.) running if you
want transparency.
## How to configure dynamically with Xresources
For many key variables, this build of `st` will look for X settings set in
either `~/.Xdefaults` or `~/.Xresources`. You must run `xrdb` on one of these
files to load the settings.
For example, you can define your desired fonts, transparency or colors:
```
*.font: Liberation Mono:pixelsize=12:antialias=true:autohint=true;
*.alpha: 0.9
*.color0: #111
...
```
The `alpha` value (for transparency) goes from `0` (transparent) to `1`
(opaque). There is an example `Xdefaults` file in this respository.
### Colors
To be clear about the color settings:
- This build will use gruvbox colors by default and as a fallback.
- If there are Xresources colors defined, those will take priority.
- But if `wal` has run in your session, its colors will take priority.
Note that when you run `wal`, it will negate the transparency of existing windows, but new windows will continue with the previously defined transparency.
## Contact
- Luke Smith <luke@lukesmith.xyz>
- [https://lukesmith.xyz](https://lukesmith.xyz)

28
TODO
View file

@ -1,28 +0,0 @@
vt emulation
------------
* double-height support
code & interface
----------------
* add a simple way to do multiplexing
drawing
-------
* add diacritics support to xdraws()
* switch to a suckless font drawing library
* make the font cache simpler
* add better support for brightening of the upper colors
bugs
----
* fix shift up/down (shift selection in emacs)
* remove DEC test sequence when appropriate
misc
----
$ grep -nE 'XXX|TODO' st.c

128
Xdefaults Normal file
View file

@ -0,0 +1,128 @@
!! Transparency (0-1):
st.alpha: 0.92
st.alphaOffset: 0.3
!! Set a default font and font size as below:
st.font: Monospace-11;
! st.termname: st-256color
! st.borderpx: 2
!! Set the background, foreground and cursor colors as below:
!! gruvbox:
*.color0: #1d2021
*.color1: #cc241d
*.color2: #98971a
*.color3: #d79921
*.color4: #458588
*.color5: #b16286
*.color6: #689d6a
*.color7: #a89984
*.color8: #928374
*.color9: #fb4934
*.color10: #b8bb26
*.color11: #fabd2f
*.color12: #83a598
*.color13: #d3869b
*.color14: #8ec07c
*.color15: #ebdbb2
*.background: #282828
*.foreground: white
*.cursorColor: white
/* /1* !! gruvbox light: *1/ */
/* *.color0: #fbf1c7 */
/* *.color1: #cc241d */
/* *.color2: #98971a */
/* *.color3: #d79921 */
/* *.color4: #458588 */
/* *.color5: #b16286 */
/* *.color6: #689d6a */
/* *.color7: #7c6f64 */
/* *.color8: #928374 */
/* *.color9: #9d0006 */
/* *.color10: #79740e */
/* *.color11: #b57614 */
/* *.color12: #076678 */
/* *.color13: #8f3f71 */
/* *.color14: #427b58 */
/* *.color15: #3c3836 */
/* *.background: #fbf1c7 */
/* *.foreground: #282828 */
/* *.cursorColor: #282828 */
/* !! brogrammer: */
/* *.foreground: #d6dbe5 */
/* *.background: #131313 */
/* *.color0: #1f1f1f */
/* *.color8: #d6dbe5 */
/* *.color1: #f81118 */
/* *.color9: #de352e */
/* *.color2: #2dc55e */
/* *.color10: #1dd361 */
/* *.color3: #ecba0f */
/* *.color11: #f3bd09 */
/* *.color4: #2a84d2 */
/* *.color12: #1081d6 */
/* *.color5: #4e5ab7 */
/* *.color13: #5350b9 */
/* *.color6: #1081d6 */
/* *.color14: #0f7ddb */
/* *.color7: #d6dbe5 */
/* *.color15: #ffffff */
/* *.colorBD: #d6dbe5 */
/* ! base16 */
/* *.color0: #181818 */
/* *.color1: #ab4642 */
/* *.color2: #a1b56c */
/* *.color3: #f7ca88 */
/* *.color4: #7cafc2 */
/* *.color5: #ba8baf */
/* *.color6: #86c1b9 */
/* *.color7: #d8d8d8 */
/* *.color8: #585858 */
/* *.color9: #ab4642 */
/* *.color10: #a1b56c */
/* *.color11: #f7ca88 */
/* *.color12: #7cafc2 */
/* *.color13: #ba8baf */
/* *.color14: #86c1b9 */
/* *.color15: #f8f8f8 */
/* !! solarized */
/* *.color0: #073642 */
/* *.color1: #dc322f */
/* *.color2: #859900 */
/* *.color3: #b58900 */
/* *.color4: #268bd2 */
/* *.color5: #d33682 */
/* *.color6: #2aa198 */
/* *.color7: #eee8d5 */
/* *.color9: #cb4b16 */
/* *.color8: #fdf6e3 */
/* *.color10: #586e75 */
/* *.color11: #657b83 */
/* *.color12: #839496 */
/* *.color13: #6c71c4 */
/* *.color14: #93a1a1 */
/* *.color15: #fdf6e3 */
/* !! xterm */
/* *.color0: #000000 */
/* *.color1: #cd0000 */
/* *.color2: #00cd00 */
/* *.color3: #cdcd00 */
/* *.color4: #0000cd */
/* *.color5: #cd00cd */
/* *.color6: #00cdcd */
/* *.color7: #e5e5e5 */
/* *.color8: #4d4d4d */
/* *.color9: #ff0000 */
/* *.color10: #00ff00 */
/* *.color11: #ffff00 */
/* *.color12: #0000ff */
/* *.color13: #ff00ff */
/* *.color14: #00ffff */
/* *.color15: #aabac8 */

194
boxdraw.c Normal file
View file

@ -0,0 +1,194 @@
/*
* Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih
* MIT/X Consortium License
*/
#include <X11/Xft/Xft.h>
#include "st.h"
#include "boxdraw_data.h"
/* Rounded non-negative integers division of n / d */
#define DIV(n, d) (((n) + (d) / 2) / (d))
static Display *xdpy;
static Colormap xcmap;
static XftDraw *xd;
static Visual *xvis;
static void drawbox(int, int, int, int, XftColor *, XftColor *, ushort);
static void drawboxlines(int, int, int, int, XftColor *, ushort);
/* public API */
void
boxdraw_xinit(Display *dpy, Colormap cmap, XftDraw *draw, Visual *vis)
{
xdpy = dpy; xcmap = cmap; xd = draw, xvis = vis;
}
int
isboxdraw(Rune u)
{
Rune block = u & ~0xff;
return (boxdraw && block == 0x2500 && boxdata[(uint8_t)u]) ||
(boxdraw_braille && block == 0x2800);
}
/* the "index" is actually the entire shape data encoded as ushort */
ushort
boxdrawindex(const Glyph *g)
{
if (boxdraw_braille && (g->u & ~0xff) == 0x2800)
return BRL | (uint8_t)g->u;
if (boxdraw_bold && (g->mode & ATTR_BOLD))
return BDB | boxdata[(uint8_t)g->u];
return boxdata[(uint8_t)g->u];
}
void
drawboxes(int x, int y, int cw, int ch, XftColor *fg, XftColor *bg,
const XftGlyphFontSpec *specs, int len)
{
for ( ; len-- > 0; x += cw, specs++)
drawbox(x, y, cw, ch, fg, bg, (ushort)specs->glyph);
}
/* implementation */
void
drawbox(int x, int y, int w, int h, XftColor *fg, XftColor *bg, ushort bd)
{
ushort cat = bd & ~(BDB | 0xff); /* mask out bold and data */
if (bd & (BDL | BDA)) {
/* lines (light/double/heavy/arcs) */
drawboxlines(x, y, w, h, fg, bd);
} else if (cat == BBD) {
/* lower (8-X)/8 block */
int d = DIV((uint8_t)bd * h, 8);
XftDrawRect(xd, fg, x, y + d, w, h - d);
} else if (cat == BBU) {
/* upper X/8 block */
XftDrawRect(xd, fg, x, y, w, DIV((uint8_t)bd * h, 8));
} else if (cat == BBL) {
/* left X/8 block */
XftDrawRect(xd, fg, x, y, DIV((uint8_t)bd * w, 8), h);
} else if (cat == BBR) {
/* right (8-X)/8 block */
int d = DIV((uint8_t)bd * w, 8);
XftDrawRect(xd, fg, x + d, y, w - d, h);
} else if (cat == BBQ) {
/* Quadrants */
int w2 = DIV(w, 2), h2 = DIV(h, 2);
if (bd & TL)
XftDrawRect(xd, fg, x, y, w2, h2);
if (bd & TR)
XftDrawRect(xd, fg, x + w2, y, w - w2, h2);
if (bd & BL)
XftDrawRect(xd, fg, x, y + h2, w2, h - h2);
if (bd & BR)
XftDrawRect(xd, fg, x + w2, y + h2, w - w2, h - h2);
} else if (bd & BBS) {
/* Shades - data is 1/2/3 for 25%/50%/75% alpha, respectively */
int d = (uint8_t)bd;
XftColor xfc;
XRenderColor xrc = { .alpha = 0xffff };
xrc.red = DIV(fg->color.red * d + bg->color.red * (4 - d), 4);
xrc.green = DIV(fg->color.green * d + bg->color.green * (4 - d), 4);
xrc.blue = DIV(fg->color.blue * d + bg->color.blue * (4 - d), 4);
XftColorAllocValue(xdpy, xvis, xcmap, &xrc, &xfc);
XftDrawRect(xd, &xfc, x, y, w, h);
XftColorFree(xdpy, xvis, xcmap, &xfc);
} else if (cat == BRL) {
/* braille, each data bit corresponds to one dot at 2x4 grid */
int w1 = DIV(w, 2);
int h1 = DIV(h, 4), h2 = DIV(h, 2), h3 = DIV(3 * h, 4);
if (bd & 1) XftDrawRect(xd, fg, x, y, w1, h1);
if (bd & 2) XftDrawRect(xd, fg, x, y + h1, w1, h2 - h1);
if (bd & 4) XftDrawRect(xd, fg, x, y + h2, w1, h3 - h2);
if (bd & 8) XftDrawRect(xd, fg, x + w1, y, w - w1, h1);
if (bd & 16) XftDrawRect(xd, fg, x + w1, y + h1, w - w1, h2 - h1);
if (bd & 32) XftDrawRect(xd, fg, x + w1, y + h2, w - w1, h3 - h2);
if (bd & 64) XftDrawRect(xd, fg, x, y + h3, w1, h - h3);
if (bd & 128) XftDrawRect(xd, fg, x + w1, y + h3, w - w1, h - h3);
}
}
void
drawboxlines(int x, int y, int w, int h, XftColor *fg, ushort bd)
{
/* s: stem thickness. width/8 roughly matches underscore thickness. */
/* We draw bold as 1.5 * normal-stem and at least 1px thicker. */
/* doubles draw at least 3px, even when w or h < 3. bold needs 6px. */
int mwh = MIN(w, h);
int base_s = MAX(1, DIV(mwh, 8));
int bold = (bd & BDB) && mwh >= 6; /* possibly ignore boldness */
int s = bold ? MAX(base_s + 1, DIV(3 * base_s, 2)) : base_s;
int w2 = DIV(w - s, 2), h2 = DIV(h - s, 2);
/* the s-by-s square (x + w2, y + h2, s, s) is the center texel. */
/* The base length (per direction till edge) includes this square. */
int light = bd & (LL | LU | LR | LD);
int double_ = bd & (DL | DU | DR | DD);
if (light) {
/* d: additional (negative) length to not-draw the center */
/* texel - at arcs and avoid drawing inside (some) doubles */
int arc = bd & BDA;
int multi_light = light & (light - 1);
int multi_double = double_ & (double_ - 1);
/* light crosses double only at DH+LV, DV+LH (ref. shapes) */
int d = arc || (multi_double && !multi_light) ? -s : 0;
if (bd & LL)
XftDrawRect(xd, fg, x, y + h2, w2 + s + d, s);
if (bd & LU)
XftDrawRect(xd, fg, x + w2, y, s, h2 + s + d);
if (bd & LR)
XftDrawRect(xd, fg, x + w2 - d, y + h2, w - w2 + d, s);
if (bd & LD)
XftDrawRect(xd, fg, x + w2, y + h2 - d, s, h - h2 + d);
}
/* double lines - also align with light to form heavy when combined */
if (double_) {
/*
* going clockwise, for each double-ray: p is additional length
* to the single-ray nearer to the previous direction, and n to
* the next. p and n adjust from the base length to lengths
* which consider other doubles - shorter to avoid intersections
* (p, n), or longer to draw the far-corner texel (n).
*/
int dl = bd & DL, du = bd & DU, dr = bd & DR, dd = bd & DD;
if (dl) {
int p = dd ? -s : 0, n = du ? -s : dd ? s : 0;
XftDrawRect(xd, fg, x, y + h2 + s, w2 + s + p, s);
XftDrawRect(xd, fg, x, y + h2 - s, w2 + s + n, s);
}
if (du) {
int p = dl ? -s : 0, n = dr ? -s : dl ? s : 0;
XftDrawRect(xd, fg, x + w2 - s, y, s, h2 + s + p);
XftDrawRect(xd, fg, x + w2 + s, y, s, h2 + s + n);
}
if (dr) {
int p = du ? -s : 0, n = dd ? -s : du ? s : 0;
XftDrawRect(xd, fg, x + w2 - p, y + h2 - s, w - w2 + p, s);
XftDrawRect(xd, fg, x + w2 - n, y + h2 + s, w - w2 + n, s);
}
if (dd) {
int p = dr ? -s : 0, n = dl ? -s : dr ? s : 0;
XftDrawRect(xd, fg, x + w2 + s, y + h2 - p, s, h - h2 + p);
XftDrawRect(xd, fg, x + w2 - s, y + h2 - n, s, h - h2 + n);
}
}
}

214
boxdraw_data.h Normal file
View file

@ -0,0 +1,214 @@
/*
* Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih
* MIT/X Consortium License
*/
/*
* U+25XX codepoints data
*
* References:
* http://www.unicode.org/charts/PDF/U2500.pdf
* http://www.unicode.org/charts/PDF/U2580.pdf
*
* Test page:
* https://github.com/GNOME/vte/blob/master/doc/boxes.txt
*/
/* Each shape is encoded as 16-bits. Higher bits are category, lower are data */
/* Categories (mutually exclusive except BDB): */
/* For convenience, BDL/BDA/BBS/BDB are 1 bit each, the rest are enums */
#define BDL (1<<8) /* Box Draw Lines (light/double/heavy) */
#define BDA (1<<9) /* Box Draw Arc (light) */
#define BBD (1<<10) /* Box Block Down (lower) X/8 */
#define BBL (2<<10) /* Box Block Left X/8 */
#define BBU (3<<10) /* Box Block Upper X/8 */
#define BBR (4<<10) /* Box Block Right X/8 */
#define BBQ (5<<10) /* Box Block Quadrants */
#define BRL (6<<10) /* Box Braille (data is lower byte of U28XX) */
#define BBS (1<<14) /* Box Block Shades */
#define BDB (1<<15) /* Box Draw is Bold */
/* (BDL/BDA) Light/Double/Heavy x Left/Up/Right/Down/Horizontal/Vertical */
/* Heavy is light+double (literally drawing light+double align to form heavy) */
#define LL (1<<0)
#define LU (1<<1)
#define LR (1<<2)
#define LD (1<<3)
#define LH (LL+LR)
#define LV (LU+LD)
#define DL (1<<4)
#define DU (1<<5)
#define DR (1<<6)
#define DD (1<<7)
#define DH (DL+DR)
#define DV (DU+DD)
#define HL (LL+DL)
#define HU (LU+DU)
#define HR (LR+DR)
#define HD (LD+DD)
#define HH (HL+HR)
#define HV (HU+HD)
/* (BBQ) Quadrants Top/Bottom x Left/Right */
#define TL (1<<0)
#define TR (1<<1)
#define BL (1<<2)
#define BR (1<<3)
/* Data for U+2500 - U+259F except dashes/diagonals */
static const unsigned short boxdata[256] = {
/* light lines */
[0x00] = BDL + LH, /* light horizontal */
[0x02] = BDL + LV, /* light vertical */
[0x0c] = BDL + LD + LR, /* light down and right */
[0x10] = BDL + LD + LL, /* light down and left */
[0x14] = BDL + LU + LR, /* light up and right */
[0x18] = BDL + LU + LL, /* light up and left */
[0x1c] = BDL + LV + LR, /* light vertical and right */
[0x24] = BDL + LV + LL, /* light vertical and left */
[0x2c] = BDL + LH + LD, /* light horizontal and down */
[0x34] = BDL + LH + LU, /* light horizontal and up */
[0x3c] = BDL + LV + LH, /* light vertical and horizontal */
[0x74] = BDL + LL, /* light left */
[0x75] = BDL + LU, /* light up */
[0x76] = BDL + LR, /* light right */
[0x77] = BDL + LD, /* light down */
/* heavy [+light] lines */
[0x01] = BDL + HH,
[0x03] = BDL + HV,
[0x0d] = BDL + HR + LD,
[0x0e] = BDL + HD + LR,
[0x0f] = BDL + HD + HR,
[0x11] = BDL + HL + LD,
[0x12] = BDL + HD + LL,
[0x13] = BDL + HD + HL,
[0x15] = BDL + HR + LU,
[0x16] = BDL + HU + LR,
[0x17] = BDL + HU + HR,
[0x19] = BDL + HL + LU,
[0x1a] = BDL + HU + LL,
[0x1b] = BDL + HU + HL,
[0x1d] = BDL + HR + LV,
[0x1e] = BDL + HU + LD + LR,
[0x1f] = BDL + HD + LR + LU,
[0x20] = BDL + HV + LR,
[0x21] = BDL + HU + HR + LD,
[0x22] = BDL + HD + HR + LU,
[0x23] = BDL + HV + HR,
[0x25] = BDL + HL + LV,
[0x26] = BDL + HU + LD + LL,
[0x27] = BDL + HD + LU + LL,
[0x28] = BDL + HV + LL,
[0x29] = BDL + HU + HL + LD,
[0x2a] = BDL + HD + HL + LU,
[0x2b] = BDL + HV + HL,
[0x2d] = BDL + HL + LD + LR,
[0x2e] = BDL + HR + LL + LD,
[0x2f] = BDL + HH + LD,
[0x30] = BDL + HD + LH,
[0x31] = BDL + HD + HL + LR,
[0x32] = BDL + HR + HD + LL,
[0x33] = BDL + HH + HD,
[0x35] = BDL + HL + LU + LR,
[0x36] = BDL + HR + LU + LL,
[0x37] = BDL + HH + LU,
[0x38] = BDL + HU + LH,
[0x39] = BDL + HU + HL + LR,
[0x3a] = BDL + HU + HR + LL,
[0x3b] = BDL + HH + HU,
[0x3d] = BDL + HL + LV + LR,
[0x3e] = BDL + HR + LV + LL,
[0x3f] = BDL + HH + LV,
[0x40] = BDL + HU + LH + LD,
[0x41] = BDL + HD + LH + LU,
[0x42] = BDL + HV + LH,
[0x43] = BDL + HU + HL + LD + LR,
[0x44] = BDL + HU + HR + LD + LL,
[0x45] = BDL + HD + HL + LU + LR,
[0x46] = BDL + HD + HR + LU + LL,
[0x47] = BDL + HH + HU + LD,
[0x48] = BDL + HH + HD + LU,
[0x49] = BDL + HV + HL + LR,
[0x4a] = BDL + HV + HR + LL,
[0x4b] = BDL + HV + HH,
[0x78] = BDL + HL,
[0x79] = BDL + HU,
[0x7a] = BDL + HR,
[0x7b] = BDL + HD,
[0x7c] = BDL + HR + LL,
[0x7d] = BDL + HD + LU,
[0x7e] = BDL + HL + LR,
[0x7f] = BDL + HU + LD,
/* double [+light] lines */
[0x50] = BDL + DH,
[0x51] = BDL + DV,
[0x52] = BDL + DR + LD,
[0x53] = BDL + DD + LR,
[0x54] = BDL + DR + DD,
[0x55] = BDL + DL + LD,
[0x56] = BDL + DD + LL,
[0x57] = BDL + DL + DD,
[0x58] = BDL + DR + LU,
[0x59] = BDL + DU + LR,
[0x5a] = BDL + DU + DR,
[0x5b] = BDL + DL + LU,
[0x5c] = BDL + DU + LL,
[0x5d] = BDL + DL + DU,
[0x5e] = BDL + DR + LV,
[0x5f] = BDL + DV + LR,
[0x60] = BDL + DV + DR,
[0x61] = BDL + DL + LV,
[0x62] = BDL + DV + LL,
[0x63] = BDL + DV + DL,
[0x64] = BDL + DH + LD,
[0x65] = BDL + DD + LH,
[0x66] = BDL + DD + DH,
[0x67] = BDL + DH + LU,
[0x68] = BDL + DU + LH,
[0x69] = BDL + DH + DU,
[0x6a] = BDL + DH + LV,
[0x6b] = BDL + DV + LH,
[0x6c] = BDL + DH + DV,
/* (light) arcs */
[0x6d] = BDA + LD + LR,
[0x6e] = BDA + LD + LL,
[0x6f] = BDA + LU + LL,
[0x70] = BDA + LU + LR,
/* Lower (Down) X/8 block (data is 8 - X) */
[0x81] = BBD + 7, [0x82] = BBD + 6, [0x83] = BBD + 5, [0x84] = BBD + 4,
[0x85] = BBD + 3, [0x86] = BBD + 2, [0x87] = BBD + 1, [0x88] = BBD + 0,
/* Left X/8 block (data is X) */
[0x89] = BBL + 7, [0x8a] = BBL + 6, [0x8b] = BBL + 5, [0x8c] = BBL + 4,
[0x8d] = BBL + 3, [0x8e] = BBL + 2, [0x8f] = BBL + 1,
/* upper 1/2 (4/8), 1/8 block (X), right 1/2, 1/8 block (8-X) */
[0x80] = BBU + 4, [0x94] = BBU + 1,
[0x90] = BBR + 4, [0x95] = BBR + 7,
/* Quadrants */
[0x96] = BBQ + BL,
[0x97] = BBQ + BR,
[0x98] = BBQ + TL,
[0x99] = BBQ + TL + BL + BR,
[0x9a] = BBQ + TL + BR,
[0x9b] = BBQ + TL + TR + BL,
[0x9c] = BBQ + TL + TR + BR,
[0x9d] = BBQ + TR,
[0x9e] = BBQ + BL + TR,
[0x9f] = BBQ + BL + TR + BR,
/* Shades, data is an alpha value in 25% units (1/4, 1/2, 3/4) */
[0x91] = BBS + 1, [0x92] = BBS + 2, [0x93] = BBS + 3,
/* U+2504 - U+250B, U+254C - U+254F: unsupported (dashes) */
/* U+2571 - U+2573: unsupported (diagonals) */
};

View file

@ -5,7 +5,8 @@
*
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
*/
static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
static char *font = "mono:pixelsize=16:antialias=true:autohint=true";
static char *font2[] = { "NotoColorEmoji:pixelsize=16:antialias=true:autohint=true" };
static int borderpx = 2;
/*
@ -67,6 +68,18 @@ static unsigned int blinktimeout = 800;
*/
static unsigned int cursorthickness = 2;
/*
* 1: render most of the lines/blocks characters without using the font for
* perfect alignment between cells (U2500 - U259F except dashes/diagonals).
* Bold affects lines thickness if boxdraw_bold is not 0. Italic is ignored.
* 0: disable (render all U25XX glyphs normally from the font).
*/
const int boxdraw = 1;
const int boxdraw_bold = 0;
/* braille (U28XX): 1: render as adjacent "pixels", 0: use font */
const int boxdraw_braille = 0;
/*
* bell volume. It must be a value between -100 and 100. Use 0 for disabling
* it
@ -93,35 +106,35 @@ char *termname = "st-256color";
*/
unsigned int tabspaces = 8;
/* bg opacity */
float alpha = 0.8;
float alphaOffset = 0.0;
float alphaUnfocus;
/* Terminal colors (16 first used in escape sequence) */
static const char *colorname[] = {
/* 8 normal colors */
"black",
"red3",
"green3",
"yellow3",
"blue2",
"magenta3",
"cyan3",
"gray90",
/* 8 bright colors */
"gray50",
"red",
"green",
"yellow",
"#5c5cff",
"magenta",
"cyan",
"white",
"#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */
"#cc241d",
"#98971a",
"#d79921",
"#458588",
"#b16286",
"#689d6a",
"#a89984",
"#928374",
"#fb4934",
"#b8bb26",
"#fabd2f",
"#83a598",
"#d3869b",
"#8ec07c",
"#ebdbb2",
[255] = 0,
/* more colors can be added after 255 to use with DefaultXX */
"#cccccc",
"#555555",
"gray90", /* default foreground colour */
"black", /* default background colour */
"#add8e6", /* 256 -> cursor */
"#555555", /* 257 -> rev cursor*/
"#282828", /* 258 -> bg */
"#ebdbb2", /* 259 -> fg */
};
@ -129,10 +142,11 @@ static const char *colorname[] = {
* Default colors (colorname index)
* foreground, background, cursor, reverse cursor
*/
unsigned int defaultfg = 258;
unsigned int defaultbg = 259;
unsigned int defaultfg = 259;
unsigned int defaultbg = 258;
unsigned int defaultcs = 256;
static unsigned int defaultrcs = 257;
unsigned int defaultrcs = 257;
unsigned int background = 258;
/*
* Default shape of cursor
@ -170,12 +184,53 @@ static unsigned int defaultattr = 11;
*/
static uint forcemousemod = ShiftMask;
/*
* Xresources preferences to load at startup
*/
ResourcePref resources[] = {
{ "font", STRING, &font },
{ "fontalt0", STRING, &font2[0] },
{ "color0", STRING, &colorname[0] },
{ "color1", STRING, &colorname[1] },
{ "color2", STRING, &colorname[2] },
{ "color3", STRING, &colorname[3] },
{ "color4", STRING, &colorname[4] },
{ "color5", STRING, &colorname[5] },
{ "color6", STRING, &colorname[6] },
{ "color7", STRING, &colorname[7] },
{ "color8", STRING, &colorname[8] },
{ "color9", STRING, &colorname[9] },
{ "color10", STRING, &colorname[10] },
{ "color11", STRING, &colorname[11] },
{ "color12", STRING, &colorname[12] },
{ "color13", STRING, &colorname[13] },
{ "color14", STRING, &colorname[14] },
{ "color15", STRING, &colorname[15] },
{ "background", STRING, &colorname[258] },
{ "foreground", STRING, &colorname[259] },
{ "cursorColor", STRING, &colorname[256] },
{ "termname", STRING, &termname },
{ "shell", STRING, &shell },
{ "minlatency", INTEGER, &minlatency },
{ "maxlatency", INTEGER, &maxlatency },
{ "blinktimeout", INTEGER, &blinktimeout },
{ "bellvolume", INTEGER, &bellvolume },
{ "tabspaces", INTEGER, &tabspaces },
{ "borderpx", INTEGER, &borderpx },
{ "cwscale", FLOAT, &cwscale },
{ "chscale", FLOAT, &chscale },
{ "alpha", FLOAT, &alpha },
{ "alphaOffset", FLOAT, &alphaOffset },
};
/*
* Internal mouse shortcuts.
* Beware that overloading Button1 will disable the selection.
*/
static MouseShortcut mshortcuts[] = {
/* mask button function argument release */
{ XK_NO_MOD, Button4, kscrollup, {.i = 1} },
{ XK_NO_MOD, Button5, kscrolldown, {.i = 1} },
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
@ -185,7 +240,11 @@ static MouseShortcut mshortcuts[] = {
/* Internal keyboard shortcuts. */
#define MODKEY Mod1Mask
#define TERMMOD (ControlMask|ShiftMask)
#define TERMMOD (Mod1Mask|ShiftMask)
static char *openurlcmd[] = { "/bin/sh", "-c", "st-urlhandler -o", "externalpipe", NULL };
static char *copyurlcmd[] = { "/bin/sh", "-c", "st-urlhandler -c", "externalpipe", NULL };
static char *copyoutput[] = { "/bin/sh", "-c", "st-copyout", "externalpipe", NULL };
static Shortcut shortcuts[] = {
/* mask keysym function argument */
@ -198,9 +257,32 @@ static Shortcut shortcuts[] = {
{ TERMMOD, XK_Home, zoomreset, {.f = 0} },
{ TERMMOD, XK_C, clipcopy, {.i = 0} },
{ TERMMOD, XK_V, clippaste, {.i = 0} },
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
{ MODKEY, XK_c, clipcopy, {.i = 0} },
{ ShiftMask, XK_Insert, clippaste, {.i = 0} },
{ MODKEY, XK_v, clippaste, {.i = 0} },
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
{ ShiftMask, XK_Page_Up, kscrollup, {.i = -1} },
{ ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
{ MODKEY, XK_Page_Up, kscrollup, {.i = -1} },
{ MODKEY, XK_Page_Down, kscrolldown, {.i = -1} },
{ MODKEY, XK_k, kscrollup, {.i = 1} },
{ MODKEY, XK_j, kscrolldown, {.i = 1} },
{ MODKEY, XK_Up, kscrollup, {.i = 1} },
{ MODKEY, XK_Down, kscrolldown, {.i = 1} },
{ MODKEY, XK_u, kscrollup, {.i = -1} },
{ MODKEY, XK_d, kscrolldown, {.i = -1} },
{ MODKEY, XK_s, changealpha, {.f = -0.05} },
{ MODKEY, XK_a, changealpha, {.f = +0.05} },
{ TERMMOD, XK_Up, zoom, {.f = +1} },
{ TERMMOD, XK_Down, zoom, {.f = -1} },
{ TERMMOD, XK_K, zoom, {.f = +1} },
{ TERMMOD, XK_J, zoom, {.f = -1} },
{ TERMMOD, XK_U, zoom, {.f = +2} },
{ TERMMOD, XK_D, zoom, {.f = -2} },
{ MODKEY, XK_l, externalpipe, {.v = openurlcmd } },
{ MODKEY, XK_y, externalpipe, {.v = copyurlcmd } },
{ MODKEY, XK_o, externalpipe, {.v = copyoutput } },
};
/*
@ -472,3 +554,4 @@ static char ascii_printable[] =
" !\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
"`abcdefghijklmnopqrstuvwxyz{|}~";

View file

@ -15,10 +15,12 @@ PKG_CONFIG = pkg-config
# includes and libs
INCS = -I$(X11INC) \
`$(PKG_CONFIG) --cflags fontconfig` \
`$(PKG_CONFIG) --cflags freetype2`
LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \
`$(PKG_CONFIG) --cflags freetype2` \
`$(PKG_CONFIG) --cflags harfbuzz`
LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\
`$(PKG_CONFIG) --libs fontconfig` \
`$(PKG_CONFIG) --libs freetype2`
`$(PKG_CONFIG) --libs freetype2` \
`$(PKG_CONFIG) --libs harfbuzz`
# flags
STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600
@ -30,7 +32,6 @@ STLDFLAGS = $(LIBS) $(LDFLAGS)
#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \
# `$(PKG_CONFIG) --libs fontconfig` \
# `$(PKG_CONFIG) --libs freetype2`
#MANPREFIX = ${PREFIX}/man
# compiler and linker
# CC = c99

154
hb.c Normal file
View file

@ -0,0 +1,154 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <X11/Xft/Xft.h>
#include <X11/cursorfont.h>
#include <hb.h>
#include <hb-ft.h>
#include "st.h"
#define FEATURE(c1,c2,c3,c4) { .tag = HB_TAG(c1,c2,c3,c4), .value = 1, .start = HB_FEATURE_GLOBAL_START, .end = HB_FEATURE_GLOBAL_END }
/*
* Replace 0 with a list of font features, wrapped in FEATURE macro, e.g.
* FEATURE('c', 'a', 'l', 't'), FEATURE('d', 'l', 'i', 'g')
*
* Uncomment either one of the 2 lines below. Uncomment the prior to disable (any) font features. Uncomment the
* latter to enable the (selected) font features.
*/
hb_feature_t features[] = { 0 };
//hb_feature_t features[] = { FEATURE('s','s','0','1'), FEATURE('s','s','0','2'), FEATURE('s','s','0','3'), FEATURE('s','s','0','5'), FEATURE('s','s','0','6'), FEATURE('s','s','0','7'), FEATURE('s','s','0','8'), FEATURE('z','e','r','o') };
void hbtransformsegment(XftFont *xfont, const Glyph *string, hb_codepoint_t *codepoints, int start, int length);
hb_font_t *hbfindfont(XftFont *match);
typedef struct {
XftFont *match;
hb_font_t *font;
} HbFontMatch;
static int hbfontslen = 0;
static HbFontMatch *hbfontcache = NULL;
void
hbunloadfonts()
{
for (int i = 0; i < hbfontslen; i++) {
hb_font_destroy(hbfontcache[i].font);
XftUnlockFace(hbfontcache[i].match);
}
if (hbfontcache != NULL) {
free(hbfontcache);
hbfontcache = NULL;
}
hbfontslen = 0;
}
hb_font_t *
hbfindfont(XftFont *match)
{
for (int i = 0; i < hbfontslen; i++) {
if (hbfontcache[i].match == match)
return hbfontcache[i].font;
}
/* Font not found in cache, caching it now. */
hbfontcache = realloc(hbfontcache, sizeof(HbFontMatch) * (hbfontslen + 1));
FT_Face face = XftLockFace(match);
hb_font_t *font = hb_ft_font_create(face, NULL);
if (font == NULL)
die("Failed to load Harfbuzz font.");
hbfontcache[hbfontslen].match = match;
hbfontcache[hbfontslen].font = font;
hbfontslen += 1;
return font;
}
void
hbtransform(XftGlyphFontSpec *specs, const Glyph *glyphs, size_t len, int x, int y)
{
int start = 0, length = 1, gstart = 0;
hb_codepoint_t *codepoints = calloc((unsigned int)len, sizeof(hb_codepoint_t));
for (int idx = 1, specidx = 1; idx < len; idx++) {
if (glyphs[idx].mode & ATTR_WDUMMY) {
length += 1;
continue;
}
if (specs[specidx].font != specs[start].font || ATTRCMP(glyphs[gstart], glyphs[idx]) || selected(x + idx, y) != selected(x + gstart, y)) {
hbtransformsegment(specs[start].font, glyphs, codepoints, gstart, length);
/* Reset the sequence. */
length = 1;
start = specidx;
gstart = idx;
} else {
length += 1;
}
specidx++;
}
/* EOL. */
hbtransformsegment(specs[start].font, glyphs, codepoints, gstart, length);
/* Apply the transformation to glyph specs. */
for (int i = 0, specidx = 0; i < len; i++) {
if (glyphs[i].mode & ATTR_WDUMMY)
continue;
if (glyphs[i].mode & ATTR_BOXDRAW) {
specidx++;
continue;
}
if (codepoints[i] != specs[specidx].glyph)
((Glyph *)glyphs)[i].mode |= ATTR_LIGA;
specs[specidx++].glyph = codepoints[i];
}
free(codepoints);
}
void
hbtransformsegment(XftFont *xfont, const Glyph *string, hb_codepoint_t *codepoints, int start, int length)
{
hb_font_t *font = hbfindfont(xfont);
if (font == NULL)
return;
Rune rune;
ushort mode = USHRT_MAX;
hb_buffer_t *buffer = hb_buffer_create();
hb_buffer_set_direction(buffer, HB_DIRECTION_LTR);
/* Fill buffer with codepoints. */
for (int i = start; i < (start+length); i++) {
rune = string[i].u;
mode = string[i].mode;
if (mode & ATTR_WDUMMY)
rune = 0x0020;
hb_buffer_add_codepoints(buffer, &rune, 1, 0, 1);
}
/* Shape the segment. */
hb_shape(font, buffer, features, sizeof(features));
/* Get new glyph info. */
hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buffer, NULL);
/* Write new codepoints. */
for (int i = 0; i < length; i++) {
hb_codepoint_t gid = info[i].codepoint;
codepoints[start+i] = gid;
}
/* Cleanup. */
hb_buffer_destroy(buffer);
}

7
hb.h Normal file
View file

@ -0,0 +1,7 @@
#include <X11/Xft/Xft.h>
#include <hb.h>
#include <hb-ft.h>
void hbunloadfonts();
void hbtransform(XftGlyphFontSpec *, const Glyph *, size_t, int, int);

13
st-copyout Executable file
View file

@ -0,0 +1,13 @@
#!/bin/sh
# Using external pipe with st, give a dmenu prompt of recent commands,
# allowing the user to copy the output of one.
# xclip required for this script.
# By Jaywalker and Luke
tmpfile=$(mktemp /tmp/st-cmd-output.XXXXXX)
trap 'rm "$tmpfile"' 0 1 15
sed -n "w $tmpfile"
sed -i 's/\x0//g' "$tmpfile"
ps1="$(grep "\S" "$tmpfile" | tail -n 1 | sed 's/^\s*//' | cut -d' ' -f1)"
chosen="$(grep -F "$ps1" "$tmpfile" | sed '$ d' | tac | dmenu -p "Copy which command's output?" -i -l 10 | sed 's/[^^]/[&]/g; s/\^/\\^/g')"
eps1="$(echo "$ps1" | sed 's/[^^]/[&]/g; s/\^/\\^/g')"
awk "/^$chosen$/{p=1;print;next} p&&/$eps1/{p=0};p" "$tmpfile" | xclip -selection clipboard

19
st-urlhandler Executable file
View file

@ -0,0 +1,19 @@
#!/bin/sh
urlregex="(((http|https|gopher|gemini|ftp|ftps|git)://|www\\.)[a-zA-Z0-9.]*[:;a-zA-Z0-9./+@$&%?$\#=_~-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)"
urls="$(sed 's/.*│//g' | tr -d '\n' | # First remove linebreaks and mutt sidebars:
grep -aEo "$urlregex" | # grep only urls as defined above.
uniq | # Ignore neighboring duplicates.
sed "s/\(\.\|,\|;\|\!\\|\?\)$//;
s/^www./http:\/\/www\./")" # xdg-open will not detect url without http
[ -z "$urls" ] && exit 1
while getopts "hoc" o; do case "${o}" in
h) printf "Optional arguments for custom use:\\n -c: copy\\n -o: xdg-open\\n -h: Show this message\\n" && exit 1 ;;
o) chosen="$(echo "$urls" | dmenu -i -p 'Follow which url?' -l 10)"
setsid xdg-open "$chosen" >/dev/null 2>&1 & ;;
c) echo "$urls" | dmenu -i -p 'Copy which url?' -l 10 | tr -d '\n' | xclip -selection clipboard ;;
*) printf "Invalid option: -%s\\n" "$OPTARG" && exit 1 ;;
esac done

54
st.1
View file

@ -125,6 +125,41 @@ and all the remaining arguments are used as a command
even without it.
.SH SHORTCUTS
.TP
.B Alt-j/k or Alt-Up/Down or Alt-Mouse Wheel
Scroll up/down one line at a time.
.TP
.B Alt-u/d or Alt-Page Up/Page Down
Scroll up/down one screen at a time.
.TP
.B Alt-Shift-k/j or Alt-Shift-Page Up/Page Down or Alt-Shift-Mouse Wheel
Increase or decrease font size.
.TP
.B Alt-Home
Reset to default font size.
.TP
.B Shift-Insert or Alt-v
Paste from clipboard.
.TP
.B Alt-c
Copy to clipboard.
.TP
.B Alt-p
Paste/input primary selection.
.TP
.B Alt-l
Show dmenu menu of all URLs on screen and choose one to open.
.TP
.B Alt-y
Show dmenu menu of all URLs on screen and choose one to copy.
.TP
.B Alt-o
Show dmenu menu of all recently run commands and copy the output of the chosen command to the clipboard.
.I xclip
required.
.TP
.B Alt-a/s
Increase or decrease opacity/alpha value (make window more or less transparent).
.TP
.B Break
Send a break in the serial line.
Break key is obtained in PC keyboards
@ -141,24 +176,6 @@ Print the full screen to the
.B Print Screen
Print the selection to the
.I iofile.
.TP
.B Ctrl-Shift-Page Up
Increase font size.
.TP
.B Ctrl-Shift-Page Down
Decrease font size.
.TP
.B Ctrl-Shift-Home
Reset to default font size.
.TP
.B Ctrl-Shift-y
Paste from primary selection (middle mouse button).
.TP
.B Ctrl-Shift-c
Copy the selected text to the clipboard selection.
.TP
.B Ctrl-Shift-v
Paste from the clipboard selection.
.SH CUSTOMIZATION
.B st
can be customized by creating a custom config.h and (re)compiling the source
@ -174,4 +191,3 @@ See the LICENSE file for the terms of redistribution.
.BR scroll (1)
.SH BUGS
See the TODO file in the distribution.

228
st.c
View file

@ -35,6 +35,7 @@
#define ESC_ARG_SIZ 16
#define STR_BUF_SIZ ESC_BUF_SIZ
#define STR_ARG_SIZ ESC_ARG_SIZ
#define HISTSIZE 2000
/* macros */
#define IS_SET(flag) ((term.mode & (flag)) != 0)
@ -42,6 +43,10 @@
#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
#define ISDELIM(u) (u && wcschr(worddelimiters, u))
#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - \
term.scr + HISTSIZE + 1) % HISTSIZE] : \
term.line[(y) - term.scr])
#define TLINE_HIST(y) ((y) <= HISTSIZE-term.row+2 ? term.hist[(y)] : term.line[(y-HISTSIZE+term.row-3)])
enum term_mode {
MODE_WRAP = 1 << 0,
@ -113,8 +118,12 @@ typedef struct {
typedef struct {
int row; /* nb row */
int col; /* nb col */
int maxcol;
Line *line; /* screen */
Line *alt; /* alternate screen */
Line hist[HISTSIZE]; /* history buffer */
int histi; /* history index */
int scr; /* scroll back */
int *dirty; /* dirtyness of lines */
TCursor c; /* cursor */
int ocx; /* old cursor col */
@ -185,8 +194,8 @@ static void tnewline(int);
static void tputtab(int);
static void tputc(Rune);
static void treset(void);
static void tscrollup(int, int);
static void tscrolldown(int, int);
static void tscrollup(int, int, int);
static void tscrolldown(int, int, int);
static void tsetattr(const int *, int);
static void tsetchar(Rune, const Glyph *, int, int);
static void tsetdirt(int, int);
@ -194,7 +203,6 @@ static void tsetscroll(int, int);
static void tswapscreen(void);
static void tsetmode(int, int, const int *, int);
static int twrite(const char *, int, int);
static void tfulldirt(void);
static void tcontrolcode(uchar );
static void tdectest(char );
static void tdefutf8(char);
@ -272,6 +280,8 @@ xrealloc(void *p, size_t len)
char *
xstrdup(const char *s)
{
if ((s = strdup(s)) == NULL)
die("strdup: %s\n", strerror(errno));
char *p;
if ((p = strdup(s)) == NULL)
@ -409,10 +419,24 @@ tlinelen(int y)
{
int i = term.col;
if (term.line[y][i - 1].mode & ATTR_WRAP)
if (TLINE(y)[i - 1].mode & ATTR_WRAP)
return i;
while (i > 0 && term.line[y][i - 1].u == ' ')
while (i > 0 && TLINE(y)[i - 1].u == ' ')
--i;
return i;
}
int
tlinehistlen(int y)
{
int i = term.col;
if (TLINE_HIST(y)[i - 1].mode & ATTR_WRAP)
return i;
while (i > 0 && TLINE_HIST(y)[i - 1].u == ' ')
--i;
return i;
@ -464,6 +488,7 @@ selextend(int col, int row, int type, int done)
sel.mode = done ? SEL_IDLE : SEL_READY;
}
void
selnormalize(void)
{
@ -521,7 +546,7 @@ selsnap(int *x, int *y, int direction)
* Snap around if the word wraps around at the end or
* beginning of a line.
*/
prevgp = &term.line[*y][*x];
prevgp = &TLINE(*y)[*x];
prevdelim = ISDELIM(prevgp->u);
for (;;) {
newx = *x + direction;
@ -536,14 +561,14 @@ selsnap(int *x, int *y, int direction)
yt = *y, xt = *x;
else
yt = newy, xt = newx;
if (!(term.line[yt][xt].mode & ATTR_WRAP))
if (!(TLINE(yt)[xt].mode & ATTR_WRAP))
break;
}
if (newx >= tlinelen(newy))
break;
gp = &term.line[newy][newx];
gp = &TLINE(newy)[newx];
delim = ISDELIM(gp->u);
if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim
|| (delim && gp->u != prevgp->u)))
@ -564,14 +589,14 @@ selsnap(int *x, int *y, int direction)
*x = (direction < 0) ? 0 : term.col - 1;
if (direction < 0) {
for (; *y > 0; *y += direction) {
if (!(term.line[*y-1][term.col-1].mode
if (!(TLINE(*y-1)[term.col-1].mode
& ATTR_WRAP)) {
break;
}
}
} else if (direction > 0) {
for (; *y < term.row-1; *y += direction) {
if (!(term.line[*y][term.col-1].mode
if (!(TLINE(*y)[term.col-1].mode
& ATTR_WRAP)) {
break;
}
@ -602,13 +627,13 @@ getsel(void)
}
if (sel.type == SEL_RECTANGULAR) {
gp = &term.line[y][sel.nb.x];
gp = &TLINE(y)[sel.nb.x];
lastx = sel.ne.x;
} else {
gp = &term.line[y][sel.nb.y == y ? sel.nb.x : 0];
gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0];
lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1;
}
last = &term.line[y][MIN(lastx, linelen-1)];
last = &TLINE(y)[MIN(lastx, linelen-1)];
while (last >= gp && last->u == ' ')
--last;
@ -844,6 +869,9 @@ void
ttywrite(const char *s, size_t n, int may_echo)
{
const char *next;
Arg arg = (Arg) { .i = term.scr };
kscrolldown(&arg);
if (may_echo && IS_SET(MODE_ECHO))
twrite(s, n, 1);
@ -939,7 +967,7 @@ ttyresize(int tw, int th)
}
void
ttyhangup()
ttyhangup(void)
{
/* Send SIGHUP to shell */
kill(pid, SIGHUP);
@ -1055,13 +1083,53 @@ tswapscreen(void)
}
void
tscrolldown(int orig, int n)
kscrolldown(const Arg* a)
{
int n = a->i;
if (n < 0)
n = term.row + n;
if (n > term.scr)
n = term.scr;
if (term.scr > 0) {
term.scr -= n;
selscroll(0, -n);
tfulldirt();
}
}
void
kscrollup(const Arg* a)
{
int n = a->i;
if (n < 0)
n = term.row + n;
if (term.scr <= HISTSIZE-n) {
term.scr += n;
selscroll(0, n);
tfulldirt();
}
}
void
tscrolldown(int orig, int n, int copyhist)
{
int i;
Line temp;
LIMIT(n, 0, term.bot-orig+1);
if (copyhist) {
term.histi = (term.histi - 1 + HISTSIZE) % HISTSIZE;
temp = term.hist[term.histi];
term.hist[term.histi] = term.line[term.bot];
term.line[term.bot] = temp;
}
tsetdirt(orig, term.bot-n);
tclearregion(0, term.bot-n+1, term.col-1, term.bot);
@ -1071,17 +1139,28 @@ tscrolldown(int orig, int n)
term.line[i-n] = temp;
}
if (term.scr == 0)
selscroll(orig, n);
}
void
tscrollup(int orig, int n)
tscrollup(int orig, int n, int copyhist)
{
int i;
Line temp;
LIMIT(n, 0, term.bot-orig+1);
if (copyhist) {
term.histi = (term.histi + 1) % HISTSIZE;
temp = term.hist[term.histi];
term.hist[term.histi] = term.line[orig];
term.line[orig] = temp;
}
if (term.scr > 0 && term.scr < HISTSIZE)
term.scr = MIN(term.scr + n, HISTSIZE-1);
tclearregion(0, orig, term.col-1, orig+n-1);
tsetdirt(orig+n, term.bot);
@ -1091,6 +1170,7 @@ tscrollup(int orig, int n)
term.line[i+n] = temp;
}
if (term.scr == 0)
selscroll(orig, -n);
}
@ -1120,7 +1200,7 @@ tnewline(int first_col)
int y = term.c.y;
if (y == term.bot) {
tscrollup(term.top, 1);
tscrollup(term.top, 1, 1);
} else {
y++;
}
@ -1215,6 +1295,9 @@ tsetchar(Rune u, const Glyph *attr, int x, int y)
term.dirty[y] = 1;
term.line[y][x] = *attr;
term.line[y][x].u = u;
if (isboxdraw(u))
term.line[y][x].mode |= ATTR_BOXDRAW;
}
void
@ -1228,8 +1311,8 @@ tclearregion(int x1, int y1, int x2, int y2)
if (y1 > y2)
temp = y1, y1 = y2, y2 = temp;
LIMIT(x1, 0, term.col-1);
LIMIT(x2, 0, term.col-1);
LIMIT(x1, 0, term.maxcol-1);
LIMIT(x2, 0, term.maxcol-1);
LIMIT(y1, 0, term.row-1);
LIMIT(y2, 0, term.row-1);
@ -1285,14 +1368,14 @@ void
tinsertblankline(int n)
{
if (BETWEEN(term.c.y, term.top, term.bot))
tscrolldown(term.c.y, n);
tscrolldown(term.c.y, n, 0);
}
void
tdeleteline(int n)
{
if (BETWEEN(term.c.y, term.top, term.bot))
tscrollup(term.c.y, n);
tscrollup(term.c.y, n, 0);
}
int32_t
@ -1729,11 +1812,11 @@ csihandle(void)
break;
case 'S': /* SU -- Scroll <n> line up */
DEFAULT(csiescseq.arg[0], 1);
tscrollup(term.top, csiescseq.arg[0]);
tscrollup(term.top, csiescseq.arg[0], 0);
break;
case 'T': /* SD -- Scroll <n> line down */
DEFAULT(csiescseq.arg[0], 1);
tscrolldown(term.top, csiescseq.arg[0]);
tscrolldown(term.top, csiescseq.arg[0], 0);
break;
case 'L': /* IL -- Insert <n> blank lines */
DEFAULT(csiescseq.arg[0], 1);
@ -1981,6 +2064,61 @@ strparse(void)
}
}
void
externalpipe(const Arg *arg)
{
int to[2];
char buf[UTF_SIZ];
void (*oldsigpipe)(int);
Glyph *bp, *end;
int lastpos, n, newline;
if (pipe(to) == -1)
return;
switch (fork()) {
case -1:
close(to[0]);
close(to[1]);
return;
case 0:
dup2(to[0], STDIN_FILENO);
close(to[0]);
close(to[1]);
execvp(((char **)arg->v)[0], (char **)arg->v);
fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]);
perror("failed");
exit(0);
}
close(to[0]);
/* ignore sigpipe for now, in case child exists early */
oldsigpipe = signal(SIGPIPE, SIG_IGN);
newline = 0;
for (n = 0; n <= HISTSIZE + 2; n++) {
bp = TLINE_HIST(n);
lastpos = MIN(tlinehistlen(n) + 1, term.col) - 1;
if (lastpos < 0)
break;
if (lastpos == 0)
continue;
end = &bp[lastpos + 1];
for (; bp < end; ++bp)
if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0)
break;
if ((newline = TLINE_HIST(n)[lastpos].mode & ATTR_WRAP))
continue;
if (xwrite(to[1], "\n", 1) < 0)
break;
newline = 0;
}
if (newline)
(void)xwrite(to[1], "\n", 1);
close(to[1]);
/* restore */
signal(SIGPIPE, oldsigpipe);
}
void
strdump(void)
{
@ -2296,7 +2434,7 @@ eschandle(uchar ascii)
return 0;
case 'D': /* IND -- Linefeed */
if (term.c.y == term.bot) {
tscrollup(term.top, 1);
tscrollup(term.top, 1, 1);
} else {
tmoveto(term.c.x, term.c.y+1);
}
@ -2309,7 +2447,7 @@ eschandle(uchar ascii)
break;
case 'M': /* RI -- Reverse index */
if (term.c.y == term.top) {
tscrolldown(term.top, 1);
tscrolldown(term.top, 1, 1);
} else {
tmoveto(term.c.x, term.c.y-1);
}
@ -2523,12 +2661,19 @@ twrite(const char *buf, int buflen, int show_ctrl)
void
tresize(int col, int row)
{
int i;
int minrow = MIN(row, term.row);
int mincol = MIN(col, term.col);
int i, j;
int tmp;
int minrow, mincol;
int *bp;
TCursor c;
tmp = col;
if (!term.maxcol)
term.maxcol = term.col;
col = MAX(col, term.maxcol);
minrow = MIN(row, term.row);
mincol = MIN(col, term.maxcol);
if (col < 1 || row < 1) {
fprintf(stderr,
"tresize: error resizing to %dx%d\n", col, row);
@ -2560,6 +2705,14 @@ tresize(int col, int row)
term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty));
term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs));
for (i = 0; i < HISTSIZE; i++) {
term.hist[i] = xrealloc(term.hist[i], col * sizeof(Glyph));
for (j = mincol; j < col; j++) {
term.hist[i][j] = term.c.attr;
term.hist[i][j].u = ' ';
}
}
/* resize each row to new width, zero-pad if needed */
for (i = 0; i < minrow; i++) {
term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph));
@ -2571,17 +2724,18 @@ tresize(int col, int row)
term.line[i] = xmalloc(col * sizeof(Glyph));
term.alt[i] = xmalloc(col * sizeof(Glyph));
}
if (col > term.col) {
bp = term.tabs + term.col;
if (col > term.maxcol) {
bp = term.tabs + term.maxcol;
memset(bp, 0, sizeof(*term.tabs) * (col - term.col));
memset(bp, 0, sizeof(*term.tabs) * (col - term.maxcol));
while (--bp > term.tabs && !*bp)
/* nothing */ ;
for (bp += tabspaces; bp < term.tabs + col; bp += tabspaces)
*bp = 1;
}
/* update terminal size */
term.col = col;
term.col = tmp;
term.maxcol = col;
term.row = row;
/* reset scrolling region */
tsetscroll(0, row-1);
@ -2618,7 +2772,7 @@ drawregion(int x1, int y1, int x2, int y2)
continue;
term.dirty[y] = 0;
xdrawline(term.line[y], x1, y, x2);
xdrawline(TLINE(y), x1, y, x2);
}
}
@ -2639,8 +2793,13 @@ draw(void)
cx--;
drawregion(0, 0, term.col, term.row);
if (term.scr == 0)
xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
term.ocx, term.ocy, term.line[term.ocy][term.ocx],
term.line[term.ocy], term.col);
/* xdrawcursor(cx, term.c.y, term.line[term.c.y][cx], */
/* term.ocx, term.ocy, term.line[term.ocy][term.ocx], */
/* term.line[term.ocy], term.col); */
term.ocx = cx;
term.ocy = term.c.y;
xfinishdraw();
@ -2654,3 +2813,4 @@ redraw(void)
tfulldirt();
draw();
}

22
st.h
View file

@ -11,7 +11,8 @@
#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \
#define ATTRCMP(a, b) (((a).mode & (~ATTR_WRAP) & (~ATTR_LIGA)) != ((b).mode & (~ATTR_WRAP) & (~ATTR_LIGA)) || \
(a).fg != (b).fg || \
(a).bg != (b).bg)
#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \
(t1.tv_nsec-t2.tv_nsec)/1E6)
@ -33,6 +34,8 @@ enum glyph_attribute {
ATTR_WRAP = 1 << 8,
ATTR_WIDE = 1 << 9,
ATTR_WDUMMY = 1 << 10,
ATTR_BOXDRAW = 1 << 11,
ATTR_LIGA = 1 << 12,
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
};
@ -79,8 +82,13 @@ typedef union {
void die(const char *, ...);
void redraw(void);
void tfulldirt(void);
void draw(void);
void externalpipe(const Arg *);
void kscrolldown(const Arg *);
void kscrollup(const Arg *);
void printscreen(const Arg *);
void printsel(const Arg *);
void sendbreak(const Arg *);
@ -111,6 +119,14 @@ void *xmalloc(size_t);
void *xrealloc(void *, size_t);
char *xstrdup(const char *);
int isboxdraw(Rune);
ushort boxdrawindex(const Glyph *);
#ifdef XFT_VERSION
/* only exposed to x.c, otherwise we'll need Xft.h for the types */
void boxdraw_xinit(Display *, Colormap, XftDraw *, Visual *);
void drawboxes(int, int, int, int, XftColor *, XftColor *, const XftGlyphFontSpec *, int);
#endif
/* config.h globals */
extern char *utmp;
extern char *scroll;
@ -123,4 +139,8 @@ extern char *termname;
extern unsigned int tabspaces;
extern unsigned int defaultfg;
extern unsigned int defaultbg;
extern float alpha;
extern float alphaUnfocus;
extern const int boxdraw, boxdraw_bold, boxdraw_braille;
extern unsigned int defaultcs;

3
win.h
View file

@ -25,7 +25,7 @@ enum win_mode {
void xbell(void);
void xclipcopy(void);
void xdrawcursor(int, int, Glyph, int, int, Glyph);
void xdrawcursor(int, int, Glyph, int, int, Glyph, Line, int);
void xdrawline(Line, int, int, int);
void xfinishdraw(void);
void xloadcols(void);
@ -39,3 +39,4 @@ void xsetpointermotion(int);
void xsetsel(char *);
int xstartdraw(void);
void xximspot(int, int);

412
x.c
View file

@ -14,11 +14,13 @@
#include <X11/keysym.h>
#include <X11/Xft/Xft.h>
#include <X11/XKBlib.h>
#include <X11/Xresource.h>
char *argv0;
#include "arg.h"
#include "st.h"
#include "win.h"
#include "hb.h"
/* types used in config.h */
typedef struct {
@ -45,6 +47,19 @@ typedef struct {
signed char appcursor; /* application cursor */
} Key;
/* Xresources preferences */
enum resource_type {
STRING = 0,
INTEGER = 1,
FLOAT = 2
};
typedef struct {
char *name;
enum resource_type type;
void *dst;
} ResourcePref;
/* X modifiers */
#define XK_ANY_MOD UINT_MAX
#define XK_NO_MOD 0
@ -55,6 +70,7 @@ static void clipcopy(const Arg *);
static void clippaste(const Arg *);
static void numlock(const Arg *);
static void selpaste(const Arg *);
static void changealpha(const Arg *);
static void zoom(const Arg *);
static void zoomabs(const Arg *);
static void zoomreset(const Arg *);
@ -105,6 +121,7 @@ typedef struct {
XSetWindowAttributes attrs;
int scr;
int isfixed; /* is fixed geometry? */
int depth; /* bit depth */
int l, t; /* left and top offset */
int gm; /* geometry mask */
} XWindow;
@ -156,6 +173,8 @@ static void xresize(int, int);
static void xhints(void);
static int xloadcolor(int, const char *, Color *);
static int xloadfont(Font *, FcPattern *);
static int xloadsparefont(FcPattern *, int);
static void xloadsparefonts(void);
static void xloadfonts(const char *, double);
static void xunloadfont(Font *);
static void xunloadfonts(void);
@ -163,6 +182,7 @@ static void xsetenv(void);
static void xseturgency(int);
static int evcol(XEvent *);
static int evrow(XEvent *);
static float clamp(float, float, float);
static void expose(XEvent *);
static void visibility(XEvent *);
@ -243,6 +263,7 @@ static char *usedfont = NULL;
static double usedfontsize = 0;
static double defaultfontsize = 0;
static char *opt_alpha = NULL;
static char *opt_class = NULL;
static char **opt_cmd = NULL;
static char *opt_embed = NULL;
@ -252,6 +273,9 @@ static char *opt_line = NULL;
static char *opt_name = NULL;
static char *opt_title = NULL;
static int focused = 0;
static int oldbutton = 3; /* button event on startup: 3 = release */
static uint buttons; /* bit field of pressed buttons */
void
@ -292,6 +316,18 @@ numlock(const Arg *dummy)
win.mode ^= MODE_NUMLOCK;
}
void
changealpha(const Arg *arg)
{
if((alpha > 0 && arg->f < 0) || (alpha < 1 && arg->f > 0))
alpha += arg->f;
alpha = clamp(alpha, 0.0, 1.0);
alphaUnfocus = clamp(alpha-alphaOffset, 0.0, 1.0);
xloadcols();
redraw();
}
void
zoom(const Arg *arg)
{
@ -306,6 +342,7 @@ zoomabs(const Arg *arg)
{
xunloadfonts();
xloadfonts(usedfont, arg->f);
xloadsparefonts();
cresize(0, 0);
redraw();
xhints();
@ -344,6 +381,15 @@ evrow(XEvent *e)
return y / win.ch;
}
float
clamp(float value, float lower, float upper) {
if(value < lower)
return lower;
if(value > upper)
return upper;
return value;
}
void
mousesel(XEvent *e, int done)
{
@ -364,68 +410,59 @@ mousesel(XEvent *e, int done)
void
mousereport(XEvent *e)
{
int len, btn, code;
int x = evcol(e), y = evrow(e);
int state = e->xbutton.state;
int len, x = evcol(e), y = evrow(e),
button = e->xbutton.button, state = e->xbutton.state;
char buf[40];
static int ox, oy;
if (e->type == MotionNotify) {
/* from urxvt */
if (e->xbutton.type == MotionNotify) {
if (x == ox && y == oy)
return;
if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY))
return;
/* MODE_MOUSEMOTION: no reporting if no button is pressed */
if (IS_SET(MODE_MOUSEMOTION) && buttons == 0)
/* MOUSE_MOTION: no reporting if no button is pressed */
if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3)
return;
/* Set btn to lowest-numbered pressed button, or 12 if no
* buttons are pressed. */
for (btn = 1; btn <= 11 && !(buttons & (1<<(btn-1))); btn++)
;
code = 32;
button = oldbutton + 32;
ox = x;
oy = y;
} else {
btn = e->xbutton.button;
/* Only buttons 1 through 11 can be encoded */
if (btn < 1 || btn > 11)
return;
if (e->type == ButtonRelease) {
if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) {
button = 3;
} else {
button -= Button1;
if (button >= 3)
button += 64 - 3;
}
if (e->xbutton.type == ButtonPress) {
oldbutton = button;
ox = x;
oy = y;
} else if (e->xbutton.type == ButtonRelease) {
oldbutton = 3;
/* MODE_MOUSEX10: no button release reporting */
if (IS_SET(MODE_MOUSEX10))
return;
/* Don't send release events for the scroll wheel */
if (btn == 4 || btn == 5)
if (button == 64 || button == 65)
return;
}
code = 0;
}
ox = x;
oy = y;
/* Encode btn into code. If no button is pressed for a motion event in
* MODE_MOUSEMANY, then encode it as a release. */
if ((!IS_SET(MODE_MOUSESGR) && e->type == ButtonRelease) || btn == 12)
code += 3;
else if (btn >= 8)
code += 128 + btn - 8;
else if (btn >= 4)
code += 64 + btn - 4;
else
code += btn - 1;
if (!IS_SET(MODE_MOUSEX10)) {
code += ((state & ShiftMask ) ? 4 : 0)
+ ((state & Mod1Mask ) ? 8 : 0) /* meta key: alt */
button += ((state & ShiftMask ) ? 4 : 0)
+ ((state & Mod4Mask ) ? 8 : 0)
+ ((state & ControlMask) ? 16 : 0);
}
if (IS_SET(MODE_MOUSESGR)) {
len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c",
code, x+1, y+1,
button, x+1, y+1,
e->type == ButtonRelease ? 'm' : 'M');
} else if (x < 223 && y < 223) {
len = snprintf(buf, sizeof(buf), "\033[M%c%c%c",
32+code, 32+x+1, 32+y+1);
32+button, 32+x+1, 32+y+1);
} else {
return;
}
@ -752,7 +789,7 @@ xresize(int col, int row)
XFreePixmap(xw.dpy, xw.buf);
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
DefaultDepth(xw.dpy, xw.scr));
xw.depth);
XftDrawChange(xw.draw, xw.buf);
xclear(0, 0, win.w, win.h);
@ -790,6 +827,16 @@ xloadcolor(int i, const char *name, Color *ncolor)
return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor);
}
void
xloadalpha(void)
{
float const usedAlpha = focused ? alpha : alphaUnfocus;
if (opt_alpha) alpha = strtof(opt_alpha, NULL);
dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * usedAlpha);
dc.col[defaultbg].pixel &= 0x00FFFFFF;
dc.col[defaultbg].pixel |= (unsigned char)(0xff * usedAlpha) << 24;
}
void
xloadcols(void)
{
@ -797,21 +844,23 @@ xloadcols(void)
static int loaded;
Color *cp;
if (loaded) {
for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
} else {
dc.collen = MAX(LEN(colorname), 256);
if (!loaded) {
dc.collen = 1 + (defaultbg = MAX(LEN(colorname), 256));
dc.col = xmalloc(dc.collen * sizeof(Color));
}
for (i = 0; i < dc.collen; i++)
for (i = 0; i+1 < dc.collen; i++)
if (!xloadcolor(i, NULL, &dc.col[i])) {
if (colorname[i])
die("could not allocate color '%s'\n", colorname[i]);
else
die("could not allocate color %d\n", i);
}
if (dc.collen) // cannot die, as the color is already loaded.
xloadcolor(background, NULL, &dc.col[defaultbg]);
xloadalpha();
loaded = 1;
}
@ -859,8 +908,8 @@ xclear(int x1, int y1, int x2, int y2)
void
xhints(void)
{
XClassHint class = {opt_name ? opt_name : termname,
opt_class ? opt_class : termname};
XClassHint class = {opt_name ? opt_name : "st",
opt_class ? opt_class : "St"};
XWMHints wm = {.flags = InputHint, .input = 1};
XSizeHints *sizeh;
@ -1050,6 +1099,101 @@ xloadfonts(const char *fontstr, double fontsize)
FcPatternDestroy(pattern);
}
int
xloadsparefont(FcPattern *pattern, int flags)
{
FcPattern *match;
FcResult result;
match = FcFontMatch(NULL, pattern, &result);
if (!match) {
return 1;
}
if (!(frc[frclen].font = XftFontOpenPattern(xw.dpy, match))) {
FcPatternDestroy(match);
return 1;
}
frc[frclen].flags = flags;
/* Believe U+0000 glyph will present in each default font */
frc[frclen].unicodep = 0;
frclen++;
return 0;
}
void
xloadsparefonts(void)
{
FcPattern *pattern;
double sizeshift, fontval;
int fc;
char **fp;
if (frclen != 0)
die("can't embed spare fonts. cache isn't empty");
/* Calculate count of spare fonts */
fc = sizeof(font2) / sizeof(*font2);
if (fc == 0)
return;
/* Allocate memory for cache entries. */
if (frccap < 4 * fc) {
frccap += 4 * fc - frccap;
frc = xrealloc(frc, frccap * sizeof(Fontcache));
}
for (fp = font2; fp - font2 < fc; ++fp) {
if (**fp == '-')
pattern = XftXlfdParse(*fp, False, False);
else
pattern = FcNameParse((FcChar8 *)*fp);
if (!pattern)
die("can't open spare font %s\n", *fp);
if (defaultfontsize > 0) {
sizeshift = usedfontsize - defaultfontsize;
if (sizeshift != 0 &&
FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) ==
FcResultMatch) {
fontval += sizeshift;
FcPatternDel(pattern, FC_PIXEL_SIZE);
FcPatternDel(pattern, FC_SIZE);
FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval);
}
}
FcPatternAddBool(pattern, FC_SCALABLE, 1);
FcConfigSubstitute(NULL, pattern, FcMatchPattern);
XftDefaultSubstitute(xw.dpy, xw.scr, pattern);
if (xloadsparefont(pattern, FRC_NORMAL))
die("can't open spare font %s\n", *fp);
FcPatternDel(pattern, FC_SLANT);
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
if (xloadsparefont(pattern, FRC_ITALIC))
die("can't open spare font %s\n", *fp);
FcPatternDel(pattern, FC_WEIGHT);
FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
if (xloadsparefont(pattern, FRC_ITALICBOLD))
die("can't open spare font %s\n", *fp);
FcPatternDel(pattern, FC_SLANT);
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
if (xloadsparefont(pattern, FRC_BOLD))
die("can't open spare font %s\n", *fp);
FcPatternDestroy(pattern);
}
}
void
xunloadfont(Font *f)
{
@ -1062,6 +1206,9 @@ xunloadfont(Font *f)
void
xunloadfonts(void)
{
/* Clear Harfbuzz font cache. */
hbunloadfonts();
/* Free the loaded fonts in the font cache. */
while (frclen > 0)
XftFontClose(xw.dpy, frc[--frclen].font);
@ -1134,11 +1281,21 @@ xinit(int cols, int rows)
Window parent;
pid_t thispid = getpid();
XColor xmousefg, xmousebg;
XWindowAttributes attr;
XVisualInfo vis;
if (!(xw.dpy = XOpenDisplay(NULL)))
die("can't open display\n");
xw.scr = XDefaultScreen(xw.dpy);
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) {
parent = XRootWindow(xw.dpy, xw.scr);
xw.depth = 32;
} else {
XGetWindowAttributes(xw.dpy, parent, &attr);
xw.depth = attr.depth;
}
XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis);
xw.vis = vis.visual;
/* font */
if (!FcInit())
@ -1147,8 +1304,11 @@ xinit(int cols, int rows)
usedfont = (opt_font == NULL)? font : opt_font;
xloadfonts(usedfont, 0);
/* spare fonts */
xloadsparefonts();
/* colors */
xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None);
xloadcols();
/* adjust fixed window geometry */
@ -1168,19 +1328,15 @@ xinit(int cols, int rows)
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
xw.attrs.colormap = xw.cmap;
if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0))))
parent = XRootWindow(xw.dpy, xw.scr);
xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t,
win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
win.w, win.h, 0, xw.depth, InputOutput,
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
| CWEventMask | CWColormap, &xw.attrs);
memset(&gcvalues, 0, sizeof(gcvalues));
gcvalues.graphics_exposures = False;
dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
&gcvalues);
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
DefaultDepth(xw.dpy, xw.scr));
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth);
dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues);
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
@ -1237,6 +1393,8 @@ xinit(int cols, int rows)
xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0);
if (xsel.xtarget == None)
xsel.xtarget = XA_STRING;
boxdraw_xinit(xw.dpy, xw.cmap, xw.draw, xw.vis);
}
int
@ -1261,7 +1419,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
mode = glyphs[i].mode;
/* Skip dummy wide-character spacing. */
if (mode == ATTR_WDUMMY)
if (mode & ATTR_WDUMMY)
continue;
/* Determine font for glyph if different from previous glyph. */
@ -1283,8 +1441,13 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
yp = winy + font->ascent;
}
if (mode & ATTR_BOXDRAW) {
/* minor shoehorning: boxdraw uses only this ushort */
glyphidx = boxdrawindex(&glyphs[i]);
} else {
/* Lookup character index with default font. */
glyphidx = XftCharIndex(xw.dpy, font->match, rune);
}
if (glyphidx) {
specs[numspecs].font = font->match;
specs[numspecs].glyph = glyphidx;
@ -1368,6 +1531,9 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
numspecs++;
}
/* Harfbuzz transformation for ligatures. */
hbtransform(specs, glyphs, len, x, y);
return numspecs;
}
@ -1488,12 +1654,16 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
r.width = width;
XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
if (base.mode & ATTR_BOXDRAW) {
drawboxes(winx, winy, width / len, win.ch, fg, bg, specs, len);
} else {
/* Render the glyphs. */
XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
}
/* Render underline and strikethrough. */
if (base.mode & ATTR_UNDERLINE) {
XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1,
XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
width, 1);
}
@ -1517,14 +1687,17 @@ xdrawglyph(Glyph g, int x, int y)
}
void
xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int len)
{
Color drawcol;
/* remove the old cursor */
if (selected(ox, oy))
og.mode ^= ATTR_REVERSE;
xdrawglyph(og, ox, oy);
/* Redraw the line where cursor was previously.
* It will restore the ligatures broken by the cursor. */
xdrawline(line, 0, oy, len);
if (IS_SET(MODE_HIDE))
return;
@ -1532,7 +1705,7 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
/*
* Select the right color for the right mode.
*/
g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE;
g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE|ATTR_BOXDRAW;
if (IS_SET(MODE_REVERSE)) {
g.mode |= ATTR_REVERSE;
@ -1777,12 +1950,22 @@ focus(XEvent *ev)
xseturgency(0);
if (IS_SET(MODE_FOCUS))
ttywrite("\033[I", 3, 0);
if (!focused) {
focused = 1;
xloadcols();
tfulldirt();
}
} else {
if (xw.ime.xic)
XUnsetICFocus(xw.ime.xic);
win.mode &= ~MODE_FOCUSED;
if (IS_SET(MODE_FOCUS))
ttywrite("\033[O", 3, 0);
if (focused) {
focused = 0;
xloadcols();
tfulldirt();
}
}
}
@ -1834,8 +2017,10 @@ kpress(XEvent *ev)
{
XKeyEvent *e = &ev->xkey;
KeySym ksym;
char buf[64], *customkey;
int len;
char *buf = NULL, *customkey;
int len = 0;
int buf_size = 64;
int critical = - 1;
Rune c;
Status status;
Shortcut *bp;
@ -1843,27 +2028,44 @@ kpress(XEvent *ev)
if (IS_SET(MODE_KBDLOCK))
return;
if (xw.ime.xic)
len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
else
len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
reallocbuf:
if (critical > 0)
goto cleanup;
if (buf)
free(buf);
buf = xmalloc((buf_size) * sizeof(char));
critical += 1;
if (xw.ime.xic) {
len = XmbLookupString(xw.ime.xic, e, buf, buf_size, &ksym, &status);
if (status == XBufferOverflow) {
buf_size = len;
goto reallocbuf;
}
} else {
// Not sure how to fix this and if it is fixable
// but at least it does write something into the buffer
// so it is not as critical
len = XLookupString(e, buf, buf_size, &ksym, NULL);
}
/* 1. shortcuts */
for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
if (ksym == bp->keysym && match(bp->mod, e->state)) {
bp->func(&(bp->arg));
return;
goto cleanup;
}
}
/* 2. custom keys from config.h */
if ((customkey = kmap(ksym, e->state))) {
ttywrite(customkey, strlen(customkey), 1);
return;
goto cleanup;
}
/* 3. composed string from input method */
if (len == 0)
return;
goto cleanup;
if (len == 1 && e->state & Mod1Mask) {
if (IS_SET(MODE_8BIT)) {
if (*buf < 0177) {
@ -1876,7 +2078,11 @@ kpress(XEvent *ev)
len = 2;
}
}
if (len <= buf_size)
ttywrite(buf, len, 1);
cleanup:
if (buf)
free(buf);
}
void
@ -2011,6 +2217,59 @@ run(void)
}
}
int
resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
{
char **sdst = dst;
int *idst = dst;
float *fdst = dst;
char fullname[256];
char fullclass[256];
char *type;
XrmValue ret;
snprintf(fullname, sizeof(fullname), "%s.%s",
opt_name ? opt_name : "st", name);
snprintf(fullclass, sizeof(fullclass), "%s.%s",
opt_class ? opt_class : "St", name);
fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0';
XrmGetResource(db, fullname, fullclass, &type, &ret);
if (ret.addr == NULL || strncmp("String", type, 64))
return 1;
switch (rtype) {
case STRING:
*sdst = ret.addr;
break;
case INTEGER:
*idst = strtoul(ret.addr, NULL, 10);
break;
case FLOAT:
*fdst = strtof(ret.addr, NULL);
break;
}
return 0;
}
void
config_init(void)
{
char *resm;
XrmDatabase db;
ResourcePref *p;
XrmInitialize();
resm = XResourceManagerString(xw.dpy);
if (!resm)
return;
db = XrmGetStringDatabase(resm);
for (p = resources; p < resources + LEN(resources); p++)
resource_load(db, p->name, p->type, p->dst);
}
void
usage(void)
{
@ -2035,6 +2294,9 @@ main(int argc, char *argv[])
case 'a':
allowaltscreen = 0;
break;
case 'A':
opt_alpha = EARGF(usage());
break;
case 'c':
opt_class = EARGF(usage());
break;
@ -2084,8 +2346,15 @@ run:
setlocale(LC_CTYPE, "");
XSetLocaleModifiers("");
if(!(xw.dpy = XOpenDisplay(NULL)))
die("Can't open display\n");
config_init();
cols = MAX(cols, 1);
rows = MAX(rows, 1);
defaultbg = MAX(LEN(colorname), 256);
alphaUnfocus = alpha-alphaOffset;
tnew(cols, rows);
xinit(cols, rows);
xsetenv();
@ -2094,3 +2363,4 @@ run:
return 0;
}