From 8d26df7b18add13c87065cafd838f80479290eaf Mon Sep 17 00:00:00 2001 From: purplerain Date: Sat, 5 Oct 2024 01:49:01 +0000 Subject: [PATCH] sync with OpenBSD -current --- sys/arch/amd64/amd64/locore0.S | 24 +- sys/arch/amd64/stand/efiboot/exec_i386.c | 32 +- sys/arch/arm/arm/genassym.cf | 3 +- sys/dev/ic/psp.c | 6 +- sys/dev/pci/if_ix.c | 22 +- sys/dev/pci/if_ix.h | 5 +- sys/dev/pci/if_mcx.c | 14 +- sys/dev/pci/if_qwx_pci.c | 45 +- usr.bin/tmux/cmd-choose-tree.c | 10 +- usr.bin/tmux/key-bindings.c | 36 +- usr.bin/tmux/options-table.c | 14 +- usr.bin/tmux/screen-write.c | 24 +- usr.bin/tmux/status.c | 18 +- usr.bin/tmux/tmux.1 | 44 +- usr.bin/tmux/tmux.h | 3 +- usr.bin/tmux/tty-keys.c | 4 +- usr.bin/tmux/window-copy.c | 516 ++++++++++------------- usr.bin/tmux/window-customize.c | 17 +- usr.bin/tmux/window-tree.c | 11 +- 19 files changed, 436 insertions(+), 412 deletions(-) diff --git a/sys/arch/amd64/amd64/locore0.S b/sys/arch/amd64/amd64/locore0.S index bc45eee7a..978821715 100644 --- a/sys/arch/amd64/amd64/locore0.S +++ b/sys/arch/amd64/amd64/locore0.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore0.S,v 1.25 2024/07/21 19:41:31 bluhm Exp $ */ +/* $OpenBSD: locore0.S,v 1.26 2024/10/04 21:15:52 bluhm Exp $ */ /* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */ /* @@ -269,37 +269,33 @@ cont: orl %edx, RELOC(cpu_feature) /* - * Determine AMD SME and SEV capabilities. + * Determine AMD SEV capability. */ movl $RELOC(cpu_vendor),%ebp cmpl $0x68747541, (%ebp) /* "Auth" */ - jne .Lno_smesev + jne .Lno_sev cmpl $0x69746e65, 4(%ebp) /* "enti" */ - jne .Lno_smesev + jne .Lno_sev cmpl $0x444d4163, 8(%ebp) /* "cAMD" */ - jne .Lno_smesev + jne .Lno_sev - /* AMD CPU, check for SME and SEV. */ + /* AMD CPU, check for SEV. */ movl $0x8000001f, %eax cpuid - pushl %eax - andl $CPUIDEAX_SME, %eax /* SME */ - popl %eax - jz .Lno_smesev andl $CPUIDEAX_SEV, %eax /* SEV */ - jz .Lno_smesev + jz .Lno_sev /* Are we in guest mode with SEV enabled? */ movl $MSR_SEV_STATUS, %ecx rdmsr andl $SEV_STAT_ENABLED, %eax - jz .Lno_smesev + jz .Lno_sev /* Determine C bit position */ movl %ebx, %ecx /* %ebx from previous cpuid */ andl $0x3f, %ecx cmpl $0x20, %ecx /* must be at least bit 32 (counting from 0) */ - jl .Lno_smesev + jl .Lno_sev xorl %eax, %eax movl %eax, RELOC(pg_crypt) subl $0x20, %ecx @@ -338,7 +334,7 @@ cont: movl $0x1, RELOC(cpu_sev_guestmode) /* we are a SEV guest */ -.Lno_smesev: +.Lno_sev: /* * Finished with old stack; load new %esp now instead of later so we diff --git a/sys/arch/amd64/stand/efiboot/exec_i386.c b/sys/arch/amd64/stand/efiboot/exec_i386.c index b84476a22..75451897a 100644 --- a/sys/arch/amd64/stand/efiboot/exec_i386.c +++ b/sys/arch/amd64/stand/efiboot/exec_i386.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exec_i386.c,v 1.11 2023/07/22 10:11:19 jsg Exp $ */ +/* $OpenBSD: exec_i386.c,v 1.12 2024/10/04 22:21:28 bluhm Exp $ */ /* * Copyright (c) 1997-1998 Michael Shalayeff @@ -239,6 +239,33 @@ ucode_load(void) } #ifdef __amd64__ +int +detect_sev(void) +{ + uint32_t max_ex_leaf, sev_feat; + uint32_t vendor[4]; + uint32_t sev_status, dummy; + + /* check whether we have SEV feature cpuid leaf */ + CPUID(0x80000000, max_ex_leaf, vendor[0], vendor[2], vendor[1]); + vendor[3] = 0; /* NULL-terminate */ + if (strcmp((char *)vendor, "AuthenticAMD") != 0 || + max_ex_leaf < 0x8000001F) + return -ENODEV; + + CPUID(0x8000001F, sev_feat, dummy, dummy, dummy); + /* check that SEV is supported */ + if ((sev_feat & CPUIDEAX_SEV) == 0) + return -ENODEV; + + __asm volatile ("rdmsr" : "=a" (sev_status), "=d"(dummy) : "c"(MSR_SEV_STATUS)); + /* check whether SEV is enabled */ + if ((sev_status & SEV_STAT_ENABLED) == 0) + return -ENODEV; + + return 0; +} + void protect_writeable(uint64_t addr, size_t len) { @@ -247,6 +274,9 @@ protect_writeable(uint64_t addr, size_t len) uint64_t cr0; size_t idx; + if (detect_sev() == 0) + return; + __asm volatile("movq %%cr0, %0;" : "=r"(cr0) : :); if ((cr0 & CR0_PG) == 0) return; diff --git a/sys/arch/arm/arm/genassym.cf b/sys/arch/arm/arm/genassym.cf index 269a4065d..c3c7d4f39 100644 --- a/sys/arch/arm/arm/genassym.cf +++ b/sys/arch/arm/arm/genassym.cf @@ -1,4 +1,4 @@ -# $OpenBSD: genassym.cf,v 1.18 2019/10/27 10:26:12 kettenis Exp $ +# $OpenBSD: genassym.cf,v 1.19 2024/10/04 19:00:27 miod Exp $ # $NetBSD: genassym.cf,v 1.27 2003/11/04 10:33:16 dsl Exp$ # Copyright (c) 1982, 1990 The Regents of the University of California. @@ -129,7 +129,6 @@ member pr_off member pr_scale export SIGTRAP -export SIGEMT struct sigframe member SIGF_SC sf_sc diff --git a/sys/dev/ic/psp.c b/sys/dev/ic/psp.c index 5bbbf2de5..95babb7d3 100644 --- a/sys/dev/ic/psp.c +++ b/sys/dev/ic/psp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: psp.c,v 1.4 2024/09/04 08:14:18 jsg Exp $ */ +/* $OpenBSD: psp.c,v 1.5 2024/10/04 16:58:26 bluhm Exp $ */ /* * Copyright (c) 2023, 2024 Hans-Joerg Hoexer @@ -199,7 +199,7 @@ ccp_wait(struct psp_softc *sc, uint32_t *status, int poll) if (poll) { count = 0; - while (count++ < 10) { + while (count++ < 100) { cmdword = bus_space_read_4(sc->sc_iot, sc->sc_ioh, PSP_REG_CMDRESP); if (cmdword & PSP_CMDRESP_RESPONSE) @@ -211,7 +211,7 @@ ccp_wait(struct psp_softc *sc, uint32_t *status, int poll) return (1); } - if (tsleep_nsec(sc, PWAIT, "psp", SEC_TO_NSEC(1)) == EWOULDBLOCK) + if (tsleep_nsec(sc, PWAIT, "psp", SEC_TO_NSEC(2)) == EWOULDBLOCK) return (1); done: diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c index 0adf47a79..0a996d045 100644 --- a/sys/dev/pci/if_ix.c +++ b/sys/dev/pci/if_ix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ix.c,v 1.217 2024/09/04 07:54:52 mglocker Exp $ */ +/* $OpenBSD: if_ix.c,v 1.218 2024/10/04 05:22:10 yasuoka Exp $ */ /****************************************************************************** @@ -508,8 +508,7 @@ ixgbe_start(struct ifqueue *ifq) * hardware that this frame is available to transmit. */ if (post) - IXGBE_WRITE_REG(&sc->hw, IXGBE_TDT(txr->me), - txr->next_avail_desc); + IXGBE_WRITE_REG(&sc->hw, txr->tail, txr->next_avail_desc); } /********************************************************************* @@ -706,7 +705,7 @@ ixgbe_watchdog(struct ifnet * ifp) for (i = 0; i < sc->num_queues; i++, txr++) { printf("%s: Queue(%d) tdh = %d, hw tdt = %d\n", ifp->if_xname, i, IXGBE_READ_REG(hw, IXGBE_TDH(i)), - IXGBE_READ_REG(hw, IXGBE_TDT(i))); + IXGBE_READ_REG(hw, sc->tx_rings[i].tail)); printf("%s: TX(%d) Next TX to Clean = %d\n", ifp->if_xname, i, txr->next_to_clean); } @@ -826,7 +825,7 @@ ixgbe_init(void *arg) msec_delay(1); } IXGBE_WRITE_FLUSH(&sc->hw); - IXGBE_WRITE_REG(&sc->hw, IXGBE_RDT(i), rxr->last_desc_filled); + IXGBE_WRITE_REG(&sc->hw, rxr[i].tail, rxr->last_desc_filled); } /* Set up VLAN support and filter */ @@ -2365,9 +2364,12 @@ ixgbe_initialize_transmit_units(struct ix_softc *sc) IXGBE_WRITE_REG(hw, IXGBE_TDLEN(i), sc->num_tx_desc * sizeof(struct ixgbe_legacy_tx_desc)); + /* Set Tx Tail register */ + txr->tail = IXGBE_TDT(i); + /* Setup the HW Tx Head and Tail descriptor pointers */ IXGBE_WRITE_REG(hw, IXGBE_TDH(i), 0); - IXGBE_WRITE_REG(hw, IXGBE_TDT(i), 0); + IXGBE_WRITE_REG(hw, txr->tail, 0); /* Setup Transmit Descriptor Cmd Settings */ txr->txd_cmd = IXGBE_TXD_CMD_IFCS; @@ -2844,8 +2846,7 @@ ixgbe_rxrefill(void *xrxr) if (ixgbe_rxfill(rxr)) { /* Advance the Rx Queue "Tail Pointer" */ - IXGBE_WRITE_REG(&sc->hw, IXGBE_RDT(rxr->me), - rxr->last_desc_filled); + IXGBE_WRITE_REG(&sc->hw, rxr->tail, rxr->last_desc_filled); } else if (if_rxr_inuse(&rxr->rx_ring) == 0) timeout_add(&rxr->rx_refill, 1); @@ -2940,6 +2941,9 @@ ixgbe_initialize_receive_units(struct ix_softc *sc) srrctl = bufsz | IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(i), srrctl); + /* Capture Rx Tail index */ + rxr->tail = IXGBE_RDT(i); + if (ISSET(ifp->if_xflags, IFXF_LRO)) { rdrxctl = IXGBE_READ_REG(&sc->hw, IXGBE_RSCCTL(i)); @@ -2952,7 +2956,7 @@ ixgbe_initialize_receive_units(struct ix_softc *sc) /* Setup the HW Rx Head and Tail Descriptor Pointers */ IXGBE_WRITE_REG(hw, IXGBE_RDH(i), 0); - IXGBE_WRITE_REG(hw, IXGBE_RDT(i), 0); + IXGBE_WRITE_REG(hw, rxr->tail, 0); } if (sc->hw.mac.type != ixgbe_mac_82598EB) { diff --git a/sys/dev/pci/if_ix.h b/sys/dev/pci/if_ix.h index c1fc256d9..2cf825193 100644 --- a/sys/dev/pci/if_ix.h +++ b/sys/dev/pci/if_ix.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ix.h,v 1.47 2024/05/21 11:19:39 bluhm Exp $ */ +/* $OpenBSD: if_ix.h,v 1.48 2024/10/04 05:22:10 yasuoka Exp $ */ /****************************************************************************** @@ -169,6 +169,7 @@ struct ix_txring { struct ix_softc *sc; struct ifqueue *ifq; uint32_t me; + uint32_t tail; uint32_t watchdog_timer; union ixgbe_adv_tx_desc *tx_base; struct ixgbe_tx_buf *tx_buffers; @@ -194,6 +195,7 @@ struct ix_rxring { struct ix_softc *sc; struct ifiqueue *ifiq; uint32_t me; + uint32_t tail; union ixgbe_adv_rx_desc *rx_base; struct ixgbe_dma_alloc rxdma; #if 0 @@ -244,6 +246,7 @@ struct ix_softc { uint16_t num_segs; uint32_t link_speed; bool link_up; + bool link_enabled; uint32_t linkvec; struct rwlock sfflock; diff --git a/sys/dev/pci/if_mcx.c b/sys/dev/pci/if_mcx.c index af957fbc5..cef354d2d 100644 --- a/sys/dev/pci/if_mcx.c +++ b/sys/dev/pci/if_mcx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mcx.c,v 1.115 2024/05/24 06:02:53 jsg Exp $ */ +/* $OpenBSD: if_mcx.c,v 1.116 2024/10/04 06:37:22 jmatthew Exp $ */ /* * Copyright (c) 2017 David Gwynne @@ -2927,23 +2927,25 @@ mcx_attach(struct device *parent, struct device *self, void *aux) goto teardown; } - printf(", %s, address %s\n", intrstr, - ether_sprintf(sc->sc_ac.ac_enaddr)); - msix--; /* admin ops took one */ sc->sc_intrmap = intrmap_create(&sc->sc_dev, msix, MCX_MAX_QUEUES, INTRMAP_POWEROF2); if (sc->sc_intrmap == NULL) { - printf("%s: unable to create interrupt map\n", DEVNAME(sc)); + printf(": unable to create interrupt map\n"); goto teardown; } sc->sc_queues = mallocarray(intrmap_count(sc->sc_intrmap), sizeof(*sc->sc_queues), M_DEVBUF, M_WAITOK|M_ZERO); if (sc->sc_queues == NULL) { - printf("%s: unable to create queues\n", DEVNAME(sc)); + printf(": unable to create queues\n"); goto intrunmap; } + printf(", %s, %d queue%s, address %s\n", intrstr, + intrmap_count(sc->sc_intrmap), + intrmap_count(sc->sc_intrmap) > 1 ? "s" : "", + ether_sprintf(sc->sc_ac.ac_enaddr)); + strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX; diff --git a/sys/dev/pci/if_qwx_pci.c b/sys/dev/pci/if_qwx_pci.c index 49ae7488c..3bcdf3606 100644 --- a/sys/dev/pci/if_qwx_pci.c +++ b/sys/dev/pci/if_qwx_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_qwx_pci.c,v 1.22 2024/07/06 05:34:35 patrick Exp $ */ +/* $OpenBSD: if_qwx_pci.c,v 1.23 2024/10/04 07:46:33 kevlo Exp $ */ /* * Copyright 2023 Stefan Sperling @@ -374,11 +374,9 @@ struct qwx_pci_softc { struct qwx_dmamem *cmd_ctxt; - struct qwx_pci_xfer_ring xfer_rings[4]; -#define QWX_PCI_XFER_RING_LOOPBACK_OUTBOUND 0 -#define QWX_PCI_XFER_RING_LOOPBACK_INBOUND 1 -#define QWX_PCI_XFER_RING_IPCR_OUTBOUND 2 -#define QWX_PCI_XFER_RING_IPCR_INBOUND 3 + struct qwx_pci_xfer_ring xfer_rings[2]; +#define QWX_PCI_XFER_RING_IPCR_OUTBOUND 0 +#define QWX_PCI_XFER_RING_IPCR_INBOUND 1 struct qwx_pci_event_ring event_rings[QWX_NUM_EVENT_CTX]; struct qwx_pci_cmd_ring cmd_ring; }; @@ -745,7 +743,6 @@ qwx_pci_attach(struct device *parent, struct device *self, void *aux) struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; uint32_t soc_hw_version_major, soc_hw_version_minor; - const struct qwx_pci_ops *pci_ops; struct pci_attach_args *pa = aux; pci_intr_handle_t ih; pcireg_t memtype, reg; @@ -884,6 +881,9 @@ qwx_pci_attach(struct device *parent, struct device *self, void *aux) pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0); + /* register PCI ops */ + psc->sc_pci_ops = &qwx_pci_ops_qca6390; + switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_QUALCOMM_QCA6390: qwx_pci_read_hw_version(sc, &soc_hw_version_major, @@ -898,11 +898,10 @@ qwx_pci_attach(struct device *parent, struct device *self, void *aux) return; } - pci_ops = &qwx_pci_ops_qca6390; psc->max_chan = QWX_MHI_CONFIG_QCA6390_MAX_CHANNELS; break; case PCI_PRODUCT_QUALCOMM_QCN9074: - pci_ops = &qwx_pci_ops_qcn9074; + psc->sc_pci_ops = &qwx_pci_ops_qcn9074; sc->sc_hw_rev = ATH11K_HW_QCN9074_HW10; psc->max_chan = QWX_MHI_CONFIG_QCA9074_MAX_CHANNELS; break; @@ -932,7 +931,6 @@ unsupported_wcn6855_soc: return; } - pci_ops = &qwx_pci_ops_qca6390; psc->max_chan = QWX_MHI_CONFIG_QCA6390_MAX_CHANNELS; break; default: @@ -940,9 +938,6 @@ unsupported_wcn6855_soc: return; } - /* register PCI ops */ - psc->sc_pci_ops = pci_ops; - error = qwx_pcic_init_msi_config(sc); if (error) goto err_pci_free_region; @@ -1296,18 +1291,6 @@ qwx_pci_alloc_xfer_rings_qca6390(struct qwx_pci_softc *psc) struct qwx_softc *sc = &psc->sc_sc; int ret; - ret = qwx_pci_alloc_xfer_ring(sc, - &psc->xfer_rings[QWX_PCI_XFER_RING_LOOPBACK_OUTBOUND], - 0, MHI_CHAN_TYPE_OUTBOUND, 0, 32); - if (ret) - goto fail; - - ret = qwx_pci_alloc_xfer_ring(sc, - &psc->xfer_rings[QWX_PCI_XFER_RING_LOOPBACK_INBOUND], - 1, MHI_CHAN_TYPE_INBOUND, 0, 32); - if (ret) - goto fail; - ret = qwx_pci_alloc_xfer_ring(sc, &psc->xfer_rings[QWX_PCI_XFER_RING_IPCR_OUTBOUND], 20, MHI_CHAN_TYPE_OUTBOUND, 1, 64); @@ -1332,18 +1315,6 @@ qwx_pci_alloc_xfer_rings_qcn9074(struct qwx_pci_softc *psc) struct qwx_softc *sc = &psc->sc_sc; int ret; - ret = qwx_pci_alloc_xfer_ring(sc, - &psc->xfer_rings[QWX_PCI_XFER_RING_LOOPBACK_OUTBOUND], - 0, MHI_CHAN_TYPE_OUTBOUND, 1, 32); - if (ret) - goto fail; - - ret = qwx_pci_alloc_xfer_ring(sc, - &psc->xfer_rings[QWX_PCI_XFER_RING_LOOPBACK_INBOUND], - 1, MHI_CHAN_TYPE_INBOUND, 1, 32); - if (ret) - goto fail; - ret = qwx_pci_alloc_xfer_ring(sc, &psc->xfer_rings[QWX_PCI_XFER_RING_IPCR_OUTBOUND], 20, MHI_CHAN_TYPE_OUTBOUND, 1, 32); diff --git a/usr.bin/tmux/cmd-choose-tree.c b/usr.bin/tmux/cmd-choose-tree.c index 59a63718d..dfd5c8add 100644 --- a/usr.bin/tmux/cmd-choose-tree.c +++ b/usr.bin/tmux/cmd-choose-tree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-choose-tree.c,v 1.51 2022/06/04 07:42:07 nicm Exp $ */ +/* $OpenBSD: cmd-choose-tree.c,v 1.52 2024/10/04 19:16:13 nicm Exp $ */ /* * Copyright (c) 2012 Thomas Adam @@ -33,7 +33,7 @@ const struct cmd_entry cmd_choose_tree_entry = { .name = "choose-tree", .alias = NULL, - .args = { "F:f:GK:NO:rst:wZ", 0, 1, cmd_choose_tree_args_parse }, + .args = { "F:f:GK:NO:rst:wyZ", 0, 1, cmd_choose_tree_args_parse }, .usage = "[-GNrswZ] [-F format] [-f filter] [-K key-format] " "[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]", @@ -47,7 +47,7 @@ const struct cmd_entry cmd_choose_client_entry = { .name = "choose-client", .alias = NULL, - .args = { "F:f:K:NO:rt:Z", 0, 1, cmd_choose_tree_args_parse }, + .args = { "F:f:K:NO:rt:yZ", 0, 1, cmd_choose_tree_args_parse }, .usage = "[-NrZ] [-F format] [-f filter] [-K key-format] " "[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]", @@ -61,7 +61,7 @@ const struct cmd_entry cmd_choose_buffer_entry = { .name = "choose-buffer", .alias = NULL, - .args = { "F:f:K:NO:rt:Z", 0, 1, cmd_choose_tree_args_parse }, + .args = { "F:f:K:NO:rt:yZ", 0, 1, cmd_choose_tree_args_parse }, .usage = "[-NrZ] [-F format] [-f filter] [-K key-format] " "[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]", @@ -75,7 +75,7 @@ const struct cmd_entry cmd_customize_mode_entry = { .name = "customize-mode", .alias = NULL, - .args = { "F:f:Nt:Z", 0, 0, NULL }, + .args = { "F:f:Nt:yZ", 0, 0, NULL }, .usage = "[-NZ] [-F format] [-f filter] " CMD_TARGET_PANE_USAGE, .target = { 't', CMD_FIND_PANE, 0 }, diff --git a/usr.bin/tmux/key-bindings.c b/usr.bin/tmux/key-bindings.c index c900084c7..5f14aa374 100644 --- a/usr.bin/tmux/key-bindings.c +++ b/usr.bin/tmux/key-bindings.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key-bindings.c,v 1.149 2024/08/21 05:03:13 nicm Exp $ */ +/* $OpenBSD: key-bindings.c,v 1.150 2024/10/04 07:03:08 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -49,7 +49,7 @@ " '#{?#{m/r:(copy|view)-mode,#{pane_mode}},Go To Top,}' '<' {send -X history-top}" \ " '#{?#{m/r:(copy|view)-mode,#{pane_mode}},Go To Bottom,}' '>' {send -X history-bottom}" \ " ''" \ - " '#{?mouse_word,Search For #[underscore]#{=/9/...:mouse_word},}' 'C-r' {if -F '#{?#{m/r:(copy|view)-mode,#{pane_mode}},0,1}' 'copy-mode -t='; send -Xt= search-backward \"#{q:mouse_word}\"}" \ + " '#{?mouse_word,Search For #[underscore]#{=/9/...:mouse_word},}' 'C-r' {if -F '#{?#{m/r:(copy|view)-mode,#{pane_mode}},0,1}' 'copy-mode -t='; send -Xt= search-backward -- \"#{q:mouse_word}\"}" \ " '#{?mouse_word,Type #[underscore]#{=/9/...:mouse_word},}' 'C-y' {copy-mode -q; send-keys -l -- \"#{q:mouse_word}\"}" \ " '#{?mouse_word,Copy #[underscore]#{=/9/...:mouse_word},}' 'c' {copy-mode -q; set-buffer -- \"#{q:mouse_word}\"}" \ " '#{?mouse_line,Copy Line,}' 'l' {copy-mode -q; set-buffer -- \"#{q:mouse_line}\"}" \ @@ -489,26 +489,26 @@ key_bindings_init(void) "bind -Tcopy-mode C-k { send -X copy-pipe-end-of-line-and-cancel }", "bind -Tcopy-mode C-n { send -X cursor-down }", "bind -Tcopy-mode C-p { send -X cursor-up }", - "bind -Tcopy-mode C-r { command-prompt -T search -ip'(search up)' -I'#{pane_search_string}' { send -X search-backward-incremental '%%' } }", - "bind -Tcopy-mode C-s { command-prompt -T search -ip'(search down)' -I'#{pane_search_string}' { send -X search-forward-incremental '%%' } }", + "bind -Tcopy-mode C-r { command-prompt -T search -ip'(search up)' -I'#{pane_search_string}' { send -X search-backward-incremental -- '%%' } }", + "bind -Tcopy-mode C-s { command-prompt -T search -ip'(search down)' -I'#{pane_search_string}' { send -X search-forward-incremental -- '%%' } }", "bind -Tcopy-mode C-v { send -X page-down }", "bind -Tcopy-mode C-w { send -X copy-pipe-and-cancel }", "bind -Tcopy-mode Escape { send -X cancel }", "bind -Tcopy-mode Space { send -X page-down }", "bind -Tcopy-mode , { send -X jump-reverse }", "bind -Tcopy-mode \\; { send -X jump-again }", - "bind -Tcopy-mode F { command-prompt -1p'(jump backward)' { send -X jump-backward '%%' } }", + "bind -Tcopy-mode F { command-prompt -1p'(jump backward)' { send -X jump-backward -- '%%' } }", "bind -Tcopy-mode N { send -X search-reverse }", "bind -Tcopy-mode P { send -X toggle-position }", "bind -Tcopy-mode R { send -X rectangle-toggle }", - "bind -Tcopy-mode T { command-prompt -1p'(jump to backward)' { send -X jump-to-backward '%%' } }", + "bind -Tcopy-mode T { command-prompt -1p'(jump to backward)' { send -X jump-to-backward -- '%%' } }", "bind -Tcopy-mode X { send -X set-mark }", - "bind -Tcopy-mode f { command-prompt -1p'(jump forward)' { send -X jump-forward '%%' } }", - "bind -Tcopy-mode g { command-prompt -p'(goto line)' { send -X goto-line '%%' } }", + "bind -Tcopy-mode f { command-prompt -1p'(jump forward)' { send -X jump-forward -- '%%' } }", + "bind -Tcopy-mode g { command-prompt -p'(goto line)' { send -X goto-line -- '%%' } }", "bind -Tcopy-mode n { send -X search-again }", "bind -Tcopy-mode q { send -X cancel }", "bind -Tcopy-mode r { send -X refresh-from-pane }", - "bind -Tcopy-mode t { command-prompt -1p'(jump to forward)' { send -X jump-to-forward '%%' } }", + "bind -Tcopy-mode t { command-prompt -1p'(jump to forward)' { send -X jump-to-forward -- '%%' } }", "bind -Tcopy-mode Home { send -X start-of-line }", "bind -Tcopy-mode End { send -X end-of-line }", "bind -Tcopy-mode MouseDown1Pane select-pane", @@ -553,8 +553,8 @@ key_bindings_init(void) "bind -Tcopy-mode C-Down { send -X scroll-down }", /* Copy mode (vi) keys. */ - "bind -Tcopy-mode-vi '#' { send -FX search-backward '#{copy_cursor_word}' }", - "bind -Tcopy-mode-vi * { send -FX search-forward '#{copy_cursor_word}' }", + "bind -Tcopy-mode-vi '#' { send -FX search-backward -- '#{copy_cursor_word}' }", + "bind -Tcopy-mode-vi * { send -FX search-forward -- '#{copy_cursor_word}' }", "bind -Tcopy-mode-vi C-c { send -X cancel }", "bind -Tcopy-mode-vi C-d { send -X halfpage-down }", "bind -Tcopy-mode-vi C-e { send -X scroll-down }", @@ -570,7 +570,7 @@ key_bindings_init(void) "bind -Tcopy-mode-vi Space { send -X begin-selection }", "bind -Tcopy-mode-vi '$' { send -X end-of-line }", "bind -Tcopy-mode-vi , { send -X jump-reverse }", - "bind -Tcopy-mode-vi / { command-prompt -T search -p'(search down)' { send -X search-forward '%%' } }", + "bind -Tcopy-mode-vi / { command-prompt -T search -p'(search down)' { send -X search-forward -- '%%' } }", "bind -Tcopy-mode-vi 0 { send -X start-of-line }", "bind -Tcopy-mode-vi 1 { command-prompt -Np'(repeat)' -I1 { send -N '%%' } }", "bind -Tcopy-mode-vi 2 { command-prompt -Np'(repeat)' -I2 { send -N '%%' } }", @@ -581,14 +581,14 @@ key_bindings_init(void) "bind -Tcopy-mode-vi 7 { command-prompt -Np'(repeat)' -I7 { send -N '%%' } }", "bind -Tcopy-mode-vi 8 { command-prompt -Np'(repeat)' -I8 { send -N '%%' } }", "bind -Tcopy-mode-vi 9 { command-prompt -Np'(repeat)' -I9 { send -N '%%' } }", - "bind -Tcopy-mode-vi : { command-prompt -p'(goto line)' { send -X goto-line '%%' } }", + "bind -Tcopy-mode-vi : { command-prompt -p'(goto line)' { send -X goto-line -- '%%' } }", "bind -Tcopy-mode-vi \\; { send -X jump-again }", - "bind -Tcopy-mode-vi ? { command-prompt -T search -p'(search up)' { send -X search-backward '%%' } }", + "bind -Tcopy-mode-vi ? { command-prompt -T search -p'(search up)' { send -X search-backward -- '%%' } }", "bind -Tcopy-mode-vi A { send -X append-selection-and-cancel }", "bind -Tcopy-mode-vi B { send -X previous-space }", "bind -Tcopy-mode-vi D { send -X copy-pipe-end-of-line-and-cancel }", "bind -Tcopy-mode-vi E { send -X next-space-end }", - "bind -Tcopy-mode-vi F { command-prompt -1p'(jump backward)' { send -X jump-backward '%%' } }", + "bind -Tcopy-mode-vi F { command-prompt -1p'(jump backward)' { send -X jump-backward -- '%%' } }", "bind -Tcopy-mode-vi G { send -X history-bottom }", "bind -Tcopy-mode-vi H { send -X top-line }", "bind -Tcopy-mode-vi J { send -X scroll-down }", @@ -597,14 +597,14 @@ key_bindings_init(void) "bind -Tcopy-mode-vi M { send -X middle-line }", "bind -Tcopy-mode-vi N { send -X search-reverse }", "bind -Tcopy-mode-vi P { send -X toggle-position }", - "bind -Tcopy-mode-vi T { command-prompt -1p'(jump to backward)' { send -X jump-to-backward '%%' } }", + "bind -Tcopy-mode-vi T { command-prompt -1p'(jump to backward)' { send -X jump-to-backward -- '%%' } }", "bind -Tcopy-mode-vi V { send -X select-line }", "bind -Tcopy-mode-vi W { send -X next-space }", "bind -Tcopy-mode-vi X { send -X set-mark }", "bind -Tcopy-mode-vi ^ { send -X back-to-indentation }", "bind -Tcopy-mode-vi b { send -X previous-word }", "bind -Tcopy-mode-vi e { send -X next-word-end }", - "bind -Tcopy-mode-vi f { command-prompt -1p'(jump forward)' { send -X jump-forward '%%' } }", + "bind -Tcopy-mode-vi f { command-prompt -1p'(jump forward)' { send -X jump-forward -- '%%' } }", "bind -Tcopy-mode-vi g { send -X history-top }", "bind -Tcopy-mode-vi h { send -X cursor-left }", "bind -Tcopy-mode-vi j { send -X cursor-down }", @@ -615,7 +615,7 @@ key_bindings_init(void) "bind -Tcopy-mode-vi o { send -X other-end }", "bind -Tcopy-mode-vi q { send -X cancel }", "bind -Tcopy-mode-vi r { send -X refresh-from-pane }", - "bind -Tcopy-mode-vi t { command-prompt -1p'(jump to forward)' { send -X jump-to-forward '%%' } }", + "bind -Tcopy-mode-vi t { command-prompt -1p'(jump to forward)' { send -X jump-to-forward -- '%%' } }", "bind -Tcopy-mode-vi v { send -X rectangle-toggle }", "bind -Tcopy-mode-vi w { send -X next-word }", "bind -Tcopy-mode-vi '{' { send -X previous-paragraph }", diff --git a/usr.bin/tmux/options-table.c b/usr.bin/tmux/options-table.c index 72b28c5f0..93c60b6bf 100644 --- a/usr.bin/tmux/options-table.c +++ b/usr.bin/tmux/options-table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options-table.c,v 1.179 2024/10/02 11:51:15 nicm Exp $ */ +/* $OpenBSD: options-table.c,v 1.180 2024/10/05 00:32:55 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott @@ -971,6 +971,18 @@ const struct options_table_entry options_table[] = { .text = "Style of the marked line in copy mode." }, + { .name = "copy-mode-position-format", + .type = OPTIONS_TABLE_STRING, + .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, + .default_str = "#[align=right]" + "#{t/p:top_line_time}#{?#{e|>:#{top_line_time},0}, ,}" + "[#{scroll_position}/#{history_size}]" + "#{?search_timed_out, (timed out)," + "#{?search_count, (#{search_count}" + "#{?search_count_partial,+,} results),}}", + .text = "Format of the position indicator in copy mode." + }, + { .name = "fill-character", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_WINDOW, diff --git a/usr.bin/tmux/screen-write.c b/usr.bin/tmux/screen-write.c index 17dfb1d33..66eb3fc72 100644 --- a/usr.bin/tmux/screen-write.c +++ b/usr.bin/tmux/screen-write.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen-write.c,v 1.226 2024/08/21 04:17:09 nicm Exp $ */ +/* $OpenBSD: screen-write.c,v 1.227 2024/10/05 00:32:55 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -567,9 +567,11 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src, u_int px, u_int py, u_int nx, u_int ny) { struct screen *s = ctx->s; + struct window_pane *wp = ctx->wp; + struct tty_ctx ttyctx; struct grid *gd = src->grid; struct grid_cell gc; - u_int xx, yy, cx, cy; + u_int xx, yy, cx = s->cx, cy = s->cy; if (nx == 0 || ny == 0) return; @@ -578,18 +580,28 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src, for (yy = py; yy < py + ny; yy++) { if (yy >= gd->hsize + gd->sy) break; - cx = s->cx; + s->cx = cx; + if (wp != NULL) + screen_write_initctx(ctx, &ttyctx, 0); for (xx = px; xx < px + nx; xx++) { if (xx >= grid_get_line(gd, yy)->cellsize) break; grid_get_cell(gd, xx, yy, &gc); if (xx + gc.data.width > px + nx) break; - grid_view_set_cell(ctx->s->grid, cx, cy, &gc); - cx++; + grid_view_set_cell(ctx->s->grid, s->cx, s->cy, &gc); + if (wp != NULL) { + ttyctx.cell = &gc; + tty_write(tty_cmd_cell, &ttyctx); + ttyctx.ocx++; + } + s->cx++; } - cy++; + s->cy++; } + + s->cx = cx; + s->cy = cy; } /* Select character set for drawing border lines. */ diff --git a/usr.bin/tmux/status.c b/usr.bin/tmux/status.c index ad7208ef1..65a5f84dd 100644 --- a/usr.bin/tmux/status.c +++ b/usr.bin/tmux/status.c @@ -1,4 +1,4 @@ -/* $OpenBSD: status.c,v 1.245 2024/08/22 09:05:51 nicm Exp $ */ +/* $OpenBSD: status.c,v 1.246 2024/10/04 19:16:13 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -598,6 +598,19 @@ status_message_redraw(struct client *c) return (1); } +/* Accept prompt immediately. */ +static enum cmd_retval +status_prompt_accept(__unused struct cmdq_item *item, void *data) +{ + struct client *c = data; + + if (c->prompt_string != NULL) { + c->prompt_inputcb(c, c->prompt_data, "y", 1); + status_prompt_clear(c); + } + return (CMD_RETURN_NORMAL); +} + /* Enable status line prompt. */ void status_prompt_set(struct client *c, struct cmd_find_state *fs, @@ -655,6 +668,9 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs, free(tmp); format_free(ft); + + if ((flags & PROMPT_SINGLE) && (flags & PROMPT_ACCEPT)) + cmdq_append(c, cmdq_get_callback(status_prompt_accept, c)); } /* Remove status line prompt. */ diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 418621a9f..3968f6760 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.958 2024/10/01 10:10:29 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.962 2024/10/05 00:32:55 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: October 1 2024 $ +.Dd $Mdocdate: October 5 2024 $ .Dt TMUX 1 .Os .Sh NAME @@ -1801,6 +1801,7 @@ Exit copy mode. Clear the current selection. .It Xo .Ic copy-end-of-line +.Op Fl CP .Op Ar prefix .Xc Copy from the cursor position to the end of the line. @@ -1808,11 +1809,13 @@ Copy from the cursor position to the end of the line. is used to name the new paste buffer. .It Xo .Ic copy-end-of-line-and-cancel +.Op Fl CP .Op Ar prefix .Xc Copy from the cursor position and exit copy mode. .It Xo .Ic copy-pipe-end-of-line +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1822,6 +1825,7 @@ Copy from the cursor position to the end of the line and pipe the text to is used to name the new paste buffer. .It Xo .Ic copy-pipe-end-of-line-and-cancel +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1830,16 +1834,19 @@ Same as but also exit copy mode. .It Xo .Ic copy-line +.Op Fl CP .Op Ar prefix .Xc Copy the entire line. .It Xo .Ic copy-line-and-cancel +.Op Fl CP .Op Ar prefix .Xc Copy the entire line and exit copy mode. .It Xo .Ic copy-pipe-line +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1849,6 +1856,7 @@ Copy the entire line and pipe the text to is used to name the new paste buffer. .It Xo .Ic copy-pipe-line-and-cancel +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1857,6 +1865,7 @@ Same as but also exit copy mode. .It Xo .Ic copy-pipe +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1866,6 +1875,7 @@ Copy the selection, clear it and pipe its text to is used to name the new paste buffer. .It Xo .Ic copy-pipe-no-clear +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1874,6 +1884,7 @@ Same as but do not clear the selection. .It Xo .Ic copy-pipe-and-cancel +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1882,11 +1893,13 @@ Same as but also exit copy mode. .It Xo .Ic copy-selection +.Op Fl CP .Op Ar prefix .Xc Copies the current selection. .It Xo .Ic copy-selection-no-clear +.Op Fl CP .Op Ar prefix .Xc Same as @@ -1894,6 +1907,7 @@ Same as but do not clear the selection. .It Xo .Ic copy-selection-and-cancel +.Op Fl CP .Op Ar prefix (vi: Enter) (emacs: M-w) @@ -2341,6 +2355,16 @@ variants of some commands exit copy mode after they have completed (for copy commands) or when the cursor reaches the bottom (for scrolling commands). .Ql -no-clear variants do not clear the selection. +All the copy commands can take the +.Fl C +and +.Fl P +flags. +The +.Fl C +flag suppresses setting the terminal clipboard when copying, while the +.Fl P +flag suppresses adding a paste buffer with the text. .Pp The next and previous word keys skip over whitespace and treat consecutive runs of either word separators or other letters as words. @@ -2557,7 +2581,7 @@ the end of the visible pane. The default is to capture only the visible contents of the pane. .It Xo .Ic choose-client -.Op Fl NrZ +.Op Fl NryZ .Op Fl F Ar format .Op Fl f Ar filter .Op Fl K Ar key-format @@ -2573,6 +2597,8 @@ or the list may be navigated and an item chosen or otherwise manipulated using the keys below. .Fl Z zooms the pane. +.Fl y +disables any confirmation prompts. The following keys may be used in client mode: .Bl -column "Key" "Function" -offset indent .It Sy "Key" Ta Sy "Function" @@ -2631,7 +2657,7 @@ starts without the preview or if given twice with the larger preview. This command works only if at least one client is attached. .It Xo .Ic choose-tree -.Op Fl GNrswZ +.Op Fl GNrswyZ .Op Fl F Ar format .Op Fl f Ar filter .Op Fl K Ar key-format @@ -2651,6 +2677,8 @@ starts with sessions collapsed and with windows collapsed. .Fl Z zooms the pane. +.Fl y +disables any confirmation prompts. The following keys may be used in tree mode: .Bl -column "Key" "Function" -offset indent .It Sy "Key" Ta Sy "Function" @@ -4805,6 +4833,8 @@ see the .Sx STYLES section. .Pp +.It Ic copy-mode-position-format Ar format +Format of the position indicator in copy mode. .It Xo Ic mode-keys .Op Ic vi | emacs .Xc @@ -5282,6 +5312,8 @@ Run when a new session created. Run when a session closed. .It session-renamed Run when a session is renamed. +.It window-layout-changed +Run when a window layout is changed. .It window-linked Run when a window is linked into a session. .It window-renamed @@ -6783,7 +6815,7 @@ The buffer commands are as follows: .Bl -tag -width Ds .It Xo .Ic choose-buffer -.Op Fl NZr +.Op Fl NryZ .Op Fl F Ar format .Op Fl f Ar filter .Op Fl K Ar key-format @@ -6799,6 +6831,8 @@ or the list may be navigated and an item chosen or otherwise manipulated using the keys below. .Fl Z zooms the pane. +.Fl y +disables any confirmation prompts. The following keys may be used in buffer mode: .Bl -column "Key" "Function" -offset indent .It Sy "Key" Ta Sy "Function" diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index e904e8e80..f8b52b278 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1232 2024/10/02 11:48:16 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1233 2024/10/04 19:16:13 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1935,6 +1935,7 @@ struct client { #define PROMPT_INCREMENTAL 0x4 #define PROMPT_NOFORMAT 0x8 #define PROMPT_KEY 0x10 +#define PROMPT_ACCEPT 0x20 int prompt_flags; enum prompt_type prompt_type; int prompt_cursor; diff --git a/usr.bin/tmux/tty-keys.c b/usr.bin/tmux/tty-keys.c index d95ded393..bc887f733 100644 --- a/usr.bin/tmux/tty-keys.c +++ b/usr.bin/tmux/tty-keys.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-keys.c,v 1.181 2024/10/03 05:41:59 nicm Exp $ */ +/* $OpenBSD: tty-keys.c,v 1.182 2024/10/04 14:55:17 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1069,7 +1069,7 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len, nkey = number; /* Convert UTF-32 codepoint into internal representation. */ - if (nkey & ~0x7f) { + if (nkey != KEYC_BSPACE && nkey & ~0x7f) { if (utf8_fromwc(nkey, &ud) == UTF8_DONE && utf8_from_data(&ud, &uc) == UTF8_DONE) nkey = uc; diff --git a/usr.bin/tmux/window-copy.c b/usr.bin/tmux/window-copy.c index 1e45db593..6e290315c 100644 --- a/usr.bin/tmux/window-copy.c +++ b/usr.bin/tmux/window-copy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-copy.c,v 1.354 2024/10/01 08:01:19 nicm Exp $ */ +/* $OpenBSD: window-copy.c,v 1.357 2024/10/05 00:35:35 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -94,13 +94,14 @@ static int window_copy_update_selection(struct window_mode_entry *, int, static void window_copy_synchronize_cursor(struct window_mode_entry *, int); static void *window_copy_get_selection(struct window_mode_entry *, size_t *); static void window_copy_copy_buffer(struct window_mode_entry *, - const char *, void *, size_t); + const char *, void *, size_t, int, int); static void window_copy_pipe(struct window_mode_entry *, struct session *, const char *); static void window_copy_copy_pipe(struct window_mode_entry *, - struct session *, const char *, const char *); + struct session *, const char *, const char *, + int, int); static void window_copy_copy_selection(struct window_mode_entry *, - const char *); + const char *, int, int); static void window_copy_append_selection(struct window_mode_entry *); static void window_copy_clear_selection(struct window_mode_entry *); static void window_copy_copy_line(struct window_mode_entry *, char **, @@ -132,7 +133,7 @@ static void window_copy_cursor_previous_word_pos(struct window_mode_entry *, static void window_copy_cursor_previous_word(struct window_mode_entry *, const char *, int); static void window_copy_cursor_prompt(struct window_mode_entry *, int, - const char *); + int); static void window_copy_scroll_up(struct window_mode_entry *, u_int); static void window_copy_scroll_down(struct window_mode_entry *, u_int); static void window_copy_rectangle_set(struct window_mode_entry *, int); @@ -198,6 +199,7 @@ enum window_copy_cmd_clear { struct window_copy_cmd_state { struct window_mode_entry *wme; struct args *args; + struct args *wargs; struct mouse_event *m; struct client *c; @@ -813,6 +815,11 @@ static void window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft) { struct window_copy_mode_data *data = wme->data; + u_int hsize = screen_hsize(data->backing); + struct grid_line *gl; + + gl = grid_get_line(data->backing->grid, hsize - data->oy); + format_add(ft, "top_line_time", "%llu", (unsigned long long)gl->time); format_add(ft, "scroll_position", "%d", data->oy); format_add(ft, "rectangle_toggle", "%d", data->rectflag); @@ -840,6 +847,7 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft) } format_add(ft, "search_present", "%d", data->searchmark != NULL); + format_add(ft, "search_timed_out", "%d", data->timeout); if (data->searchcount != -1) { format_add(ft, "search_count", "%d", data->searchcount); format_add(ft, "search_count_partial", "%d", data->searchmore); @@ -921,7 +929,7 @@ window_copy_expand_search_string(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; - const char *ss = args_string(cs->args, 1); + const char *ss = args_string(cs->wargs, 0); char *expanded; if (ss == NULL || *ss == '\0') @@ -1043,21 +1051,23 @@ window_copy_do_copy_end_of_line(struct window_copy_cmd_state *cs, int pipe, struct session *s = cs->s; struct winlink *wl = cs->wl; struct window_pane *wp = wme->wp; - u_int count = args_count(cs->args); + u_int count = args_count(cs->wargs); u_int np = wme->prefix, ocx, ocy, ooy; struct window_copy_mode_data *data = wme->data; char *prefix = NULL, *command = NULL; - const char *arg1 = args_string(cs->args, 1); - const char *arg2 = args_string(cs->args, 2); + const char *arg0 = args_string(cs->wargs, 0); + const char *arg1 = args_string(cs->wargs, 1); + int set_paste = !args_has(cs->wargs, 'P'); + int set_clip = !args_has(cs->wargs, 'C'); if (pipe) { - if (count == 3) - prefix = format_single(NULL, arg2, c, s, wl, wp); - if (s != NULL && count > 1 && *arg1 != '\0') - command = format_single(NULL, arg1, c, s, wl, wp); - } else { if (count == 2) prefix = format_single(NULL, arg1, c, s, wl, wp); + if (s != NULL && count > 0 && *arg0 != '\0') + command = format_single(NULL, arg0, c, s, wl, wp); + } else { + if (count == 1) + prefix = format_single(NULL, arg0, c, s, wl, wp); } ocx = data->cx; @@ -1071,9 +1081,11 @@ window_copy_do_copy_end_of_line(struct window_copy_cmd_state *cs, int pipe, if (s != NULL) { if (pipe) - window_copy_copy_pipe(wme, s, prefix, command); + window_copy_copy_pipe(wme, s, prefix, command, + set_paste, set_clip); else - window_copy_copy_selection(wme, prefix); + window_copy_copy_selection(wme, prefix, + set_paste, set_clip); if (cancel) { free(prefix); @@ -1126,20 +1138,22 @@ window_copy_do_copy_line(struct window_copy_cmd_state *cs, int pipe, int cancel) struct winlink *wl = cs->wl; struct window_pane *wp = wme->wp; struct window_copy_mode_data *data = wme->data; - u_int count = args_count(cs->args); + u_int count = args_count(cs->wargs); u_int np = wme->prefix, ocx, ocy, ooy; char *prefix = NULL, *command = NULL; - const char *arg1 = args_string(cs->args, 1); - const char *arg2 = args_string(cs->args, 2); + const char *arg0 = args_string(cs->wargs, 0); + const char *arg1 = args_string(cs->wargs, 1); + int set_paste = !args_has(cs->wargs, 'P'); + int set_clip = !args_has(cs->wargs, 'C'); if (pipe) { - if (count == 3) - prefix = format_single(NULL, arg2, c, s, wl, wp); - if (s != NULL && count > 1 && *arg1 != '\0') - command = format_single(NULL, arg1, c, s, wl, wp); - } else { if (count == 2) prefix = format_single(NULL, arg1, c, s, wl, wp); + if (s != NULL && count > 0 && *arg0 != '\0') + command = format_single(NULL, arg0, c, s, wl, wp); + } else { + if (count == 1) + prefix = format_single(NULL, arg0, c, s, wl, wp); } ocx = data->cx; @@ -1155,9 +1169,11 @@ window_copy_do_copy_line(struct window_copy_cmd_state *cs, int pipe, int cancel) if (s != NULL) { if (pipe) - window_copy_copy_pipe(wme, s, prefix, command); + window_copy_copy_pipe(wme, s, prefix, command, + set_paste, set_clip); else - window_copy_copy_selection(wme, prefix); + window_copy_copy_selection(wme, prefix, + set_paste, set_clip); if (cancel) { free(prefix); @@ -1209,13 +1225,15 @@ window_copy_cmd_copy_selection_no_clear(struct window_copy_cmd_state *cs) struct winlink *wl = cs->wl; struct window_pane *wp = wme->wp; char *prefix = NULL; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); + int set_paste = !args_has(cs->wargs, 'P'); + int set_clip = !args_has(cs->wargs, 'C'); - if (arg1 != NULL) - prefix = format_single(NULL, arg1, c, s, wl, wp); + if (arg0 != NULL) + prefix = format_single(NULL, arg0, c, s, wl, wp); if (s != NULL) - window_copy_copy_selection(wme, prefix); + window_copy_copy_selection(wme, prefix, set_paste, set_clip); free(prefix); return (WINDOW_COPY_CMD_NOTHING); @@ -2116,15 +2134,18 @@ window_copy_cmd_copy_pipe_no_clear(struct window_copy_cmd_state *cs) struct winlink *wl = cs->wl; struct window_pane *wp = wme->wp; char *command = NULL, *prefix = NULL; - const char *arg1 = args_string(cs->args, 1); - const char *arg2 = args_string(cs->args, 2); + const char *arg0 = args_string(cs->wargs, 0); + const char *arg1 = args_string(cs->wargs, 1); + int set_paste = !args_has(cs->wargs, 'P'); + int set_clip = !args_has(cs->wargs, 'C'); - if (arg2 != NULL) - prefix = format_single(NULL, arg2, c, s, wl, wp); + if (arg1 != NULL) + prefix = format_single(NULL, arg1, c, s, wl, wp); - if (s != NULL && arg1 != NULL && *arg1 != '\0') - command = format_single(NULL, arg1, c, s, wl, wp); - window_copy_copy_pipe(wme, s, prefix, command); + if (s != NULL && arg0 != NULL && *arg0 != '\0') + command = format_single(NULL, arg0, c, s, wl, wp); + window_copy_copy_pipe(wme, s, prefix, command, + set_paste, set_clip); free(command); free(prefix); @@ -2160,10 +2181,10 @@ window_copy_cmd_pipe_no_clear(struct window_copy_cmd_state *cs) struct winlink *wl = cs->wl; struct window_pane *wp = wme->wp; char *command = NULL; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); - if (s != NULL && arg1 != NULL && *arg1 != '\0') - command = format_single(NULL, arg1, c, s, wl, wp); + if (s != NULL && arg0 != NULL && *arg0 != '\0') + command = format_single(NULL, arg0, c, s, wl, wp); window_copy_pipe(wme, s, command); free(command); @@ -2194,10 +2215,10 @@ static enum window_copy_cmd_action window_copy_cmd_goto_line(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); - if (*arg1 != '\0') - window_copy_goto_line(wme, arg1); + if (*arg0 != '\0') + window_copy_goto_line(wme, arg0); return (WINDOW_COPY_CMD_NOTHING); } @@ -2207,12 +2228,12 @@ window_copy_cmd_jump_backward(struct window_copy_cmd_state *cs) struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); - if (*arg1 != '\0') { + if (*arg0 != '\0') { data->jumptype = WINDOW_COPY_JUMPBACKWARD; free(data->jumpchar); - data->jumpchar = utf8_fromcstr(arg1); + data->jumpchar = utf8_fromcstr(arg0); for (; np != 0; np--) window_copy_cursor_jump_back(wme); } @@ -2225,12 +2246,12 @@ window_copy_cmd_jump_forward(struct window_copy_cmd_state *cs) struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); - if (*arg1 != '\0') { + if (*arg0 != '\0') { data->jumptype = WINDOW_COPY_JUMPFORWARD; free(data->jumpchar); - data->jumpchar = utf8_fromcstr(arg1); + data->jumpchar = utf8_fromcstr(arg0); for (; np != 0; np--) window_copy_cursor_jump(wme); } @@ -2243,12 +2264,12 @@ window_copy_cmd_jump_to_backward(struct window_copy_cmd_state *cs) struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); - if (*arg1 != '\0') { + if (*arg0 != '\0') { data->jumptype = WINDOW_COPY_JUMPTOBACKWARD; free(data->jumpchar); - data->jumpchar = utf8_fromcstr(arg1); + data->jumpchar = utf8_fromcstr(arg0); for (; np != 0; np--) window_copy_cursor_jump_to_back(wme); } @@ -2261,12 +2282,12 @@ window_copy_cmd_jump_to_forward(struct window_copy_cmd_state *cs) struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); - if (*arg1 != '\0') { + if (*arg0 != '\0') { data->jumptype = WINDOW_COPY_JUMPTOFORWARD; free(data->jumpchar); - data->jumpchar = utf8_fromcstr(arg1); + data->jumpchar = utf8_fromcstr(arg0); for (; np != 0; np--) window_copy_cursor_jump_to(wme); } @@ -2286,9 +2307,8 @@ static enum window_copy_cmd_action window_copy_cmd_next_prompt(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; - const char *arg1 = args_string(cs->args, 1); - window_copy_cursor_prompt(wme, 1, arg1); + window_copy_cursor_prompt(wme, 1, args_has(cs->wargs, 'o')); return (WINDOW_COPY_CMD_NOTHING); } @@ -2296,9 +2316,8 @@ static enum window_copy_cmd_action window_copy_cmd_previous_prompt(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; - const char *arg1 = args_string(cs->args, 1); - window_copy_cursor_prompt(wme, 0, arg1); + window_copy_cursor_prompt(wme, 0, args_has(cs->wargs, 'o')); return (WINDOW_COPY_CMD_NOTHING); } @@ -2387,27 +2406,27 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); const char *ss = data->searchstr; char prefix; enum window_copy_cmd_action action = WINDOW_COPY_CMD_NOTHING; data->timeout = 0; - log_debug("%s: %s", __func__, arg1); + log_debug("%s: %s", __func__, arg0); - prefix = *arg1++; + prefix = *arg0++; if (data->searchx == -1 || data->searchy == -1) { data->searchx = data->cx; data->searchy = data->cy; data->searcho = data->oy; - } else if (ss != NULL && strcmp(arg1, ss) != 0) { + } else if (ss != NULL && strcmp(arg0, ss) != 0) { data->cx = data->searchx; data->cy = data->searchy; data->oy = data->searcho; action = WINDOW_COPY_CMD_REDRAW; } - if (*arg1 == '\0') { + if (*arg0 == '\0') { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); } @@ -2417,7 +2436,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) data->searchtype = WINDOW_COPY_SEARCHUP; data->searchregex = 0; free(data->searchstr); - data->searchstr = xstrdup(arg1); + data->searchstr = xstrdup(arg0); if (!window_copy_search_up(wme, 0)) { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); @@ -2427,7 +2446,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) data->searchtype = WINDOW_COPY_SEARCHDOWN; data->searchregex = 0; free(data->searchstr); - data->searchstr = xstrdup(arg1); + data->searchstr = xstrdup(arg0); if (!window_copy_search_down(wme, 0)) { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); @@ -2442,27 +2461,27 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); const char *ss = data->searchstr; char prefix; enum window_copy_cmd_action action = WINDOW_COPY_CMD_NOTHING; data->timeout = 0; - log_debug("%s: %s", __func__, arg1); + log_debug("%s: %s", __func__, arg0); - prefix = *arg1++; + prefix = *arg0++; if (data->searchx == -1 || data->searchy == -1) { data->searchx = data->cx; data->searchy = data->cy; data->searcho = data->oy; - } else if (ss != NULL && strcmp(arg1, ss) != 0) { + } else if (ss != NULL && strcmp(arg0, ss) != 0) { data->cx = data->searchx; data->cy = data->searchy; data->oy = data->searcho; action = WINDOW_COPY_CMD_REDRAW; } - if (*arg1 == '\0') { + if (*arg0 == '\0') { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); } @@ -2472,7 +2491,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) data->searchtype = WINDOW_COPY_SEARCHDOWN; data->searchregex = 0; free(data->searchstr); - data->searchstr = xstrdup(arg1); + data->searchstr = xstrdup(arg0); if (!window_copy_search_down(wme, 0)) { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); @@ -2482,7 +2501,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) data->searchtype = WINDOW_COPY_SEARCHUP; data->searchregex = 0; free(data->searchstr); - data->searchstr = xstrdup(arg1); + data->searchstr = xstrdup(arg0); if (!window_copy_search_up(wme, 0)) { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); @@ -2514,516 +2533,432 @@ static const struct { const char *command; u_int minargs; u_int maxargs; + struct args_parse args; enum window_copy_cmd_clear clear; enum window_copy_cmd_action (*f)(struct window_copy_cmd_state *); } window_copy_cmd_table[] = { { .command = "append-selection", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_append_selection }, { .command = "append-selection-and-cancel", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_append_selection_and_cancel }, { .command = "back-to-indentation", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_back_to_indentation }, { .command = "begin-selection", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_begin_selection }, { .command = "bottom-line", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_bottom_line }, { .command = "cancel", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_cancel }, { .command = "clear-selection", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_clear_selection }, { .command = "copy-end-of-line", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_end_of_line }, { .command = "copy-end-of-line-and-cancel", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_end_of_line_and_cancel }, { .command = "copy-pipe-end-of-line", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_pipe_end_of_line }, { .command = "copy-pipe-end-of-line-and-cancel", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_pipe_end_of_line_and_cancel }, { .command = "copy-line", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_line }, { .command = "copy-line-and-cancel", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_line_and_cancel }, { .command = "copy-pipe-line", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_pipe_line }, { .command = "copy-pipe-line-and-cancel", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_pipe_line_and_cancel }, { .command = "copy-pipe-no-clear", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_NEVER, .f = window_copy_cmd_copy_pipe_no_clear }, { .command = "copy-pipe", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_pipe }, { .command = "copy-pipe-and-cancel", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_pipe_and_cancel }, { .command = "copy-selection-no-clear", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_NEVER, .f = window_copy_cmd_copy_selection_no_clear }, { .command = "copy-selection", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_selection }, { .command = "copy-selection-and-cancel", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_selection_and_cancel }, { .command = "cursor-down", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_cursor_down }, { .command = "cursor-down-and-cancel", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_cursor_down_and_cancel }, { .command = "cursor-left", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_cursor_left }, { .command = "cursor-right", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_cursor_right }, { .command = "cursor-up", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_cursor_up }, { .command = "end-of-line", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_end_of_line }, { .command = "goto-line", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_goto_line }, { .command = "halfpage-down", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_halfpage_down }, { .command = "halfpage-down-and-cancel", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_halfpage_down_and_cancel }, { .command = "halfpage-up", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_halfpage_up }, { .command = "history-bottom", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_history_bottom }, { .command = "history-top", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_history_top }, { .command = "jump-again", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_jump_again }, { .command = "jump-backward", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_jump_backward }, { .command = "jump-forward", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_jump_forward }, { .command = "jump-reverse", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_jump_reverse }, { .command = "jump-to-backward", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_jump_to_backward }, { .command = "jump-to-forward", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_jump_to_forward }, { .command = "jump-to-mark", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_jump_to_mark }, { .command = "next-prompt", - .minargs = 0, - .maxargs = 1, + .args = { "o", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_next_prompt }, { .command = "previous-prompt", - .minargs = 0, - .maxargs = 1, + .args = { "o", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_previous_prompt }, { .command = "middle-line", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_middle_line }, { .command = "next-matching-bracket", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_next_matching_bracket }, { .command = "next-paragraph", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_next_paragraph }, { .command = "next-space", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_next_space }, { .command = "next-space-end", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_next_space_end }, { .command = "next-word", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_next_word }, { .command = "next-word-end", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_next_word_end }, { .command = "other-end", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_other_end }, { .command = "page-down", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_page_down }, { .command = "page-down-and-cancel", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_page_down_and_cancel }, { .command = "page-up", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_page_up }, { .command = "pipe-no-clear", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_NEVER, .f = window_copy_cmd_pipe_no_clear }, { .command = "pipe", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_pipe }, { .command = "pipe-and-cancel", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_pipe_and_cancel }, { .command = "previous-matching-bracket", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_previous_matching_bracket }, { .command = "previous-paragraph", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_previous_paragraph }, { .command = "previous-space", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_previous_space }, { .command = "previous-word", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_previous_word }, { .command = "rectangle-on", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_rectangle_on }, { .command = "rectangle-off", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_rectangle_off }, { .command = "rectangle-toggle", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_rectangle_toggle }, { .command = "refresh-from-pane", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_refresh_from_pane }, { .command = "scroll-bottom", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_scroll_bottom }, { .command = "scroll-down", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_scroll_down }, { .command = "scroll-down-and-cancel", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_scroll_down_and_cancel }, { .command = "scroll-middle", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_scroll_middle }, { .command = "scroll-top", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_scroll_top }, { .command = "scroll-up", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_scroll_up }, { .command = "search-again", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_again }, { .command = "search-backward", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_backward }, { .command = "search-backward-text", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_backward_text }, { .command = "search-backward-incremental", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_backward_incremental }, { .command = "search-forward", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_forward }, { .command = "search-forward-text", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_forward_text }, { .command = "search-forward-incremental", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_forward_incremental }, { .command = "search-reverse", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_reverse }, { .command = "select-line", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_select_line }, { .command = "select-word", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_select_word }, { .command = "set-mark", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_set_mark }, { .command = "start-of-line", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_start_of_line }, { .command = "stop-selection", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_stop_selection }, { .command = "toggle-position", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_NEVER, .f = window_copy_cmd_toggle_position }, { .command = "top-line", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_top_line } @@ -3035,12 +2970,14 @@ window_copy_command(struct window_mode_entry *wme, struct client *c, struct mouse_event *m) { struct window_copy_mode_data *data = wme->data; + struct window_pane *wp = wme->wp; struct window_copy_cmd_state cs; enum window_copy_cmd_action action; enum window_copy_cmd_clear clear = WINDOW_COPY_CMD_CLEAR_NEVER; const char *command; u_int i, count = args_count(args); int keys; + char *error = NULL; if (count == 0) return; @@ -3051,6 +2988,7 @@ window_copy_command(struct window_mode_entry *wme, struct client *c, cs.wme = wme; cs.args = args; + cs.wargs = NULL; cs.m = m; cs.c = c; @@ -3060,17 +2998,26 @@ window_copy_command(struct window_mode_entry *wme, struct client *c, action = WINDOW_COPY_CMD_NOTHING; for (i = 0; i < nitems(window_copy_cmd_table); i++) { if (strcmp(window_copy_cmd_table[i].command, command) == 0) { - if (count - 1 < window_copy_cmd_table[i].minargs || - count - 1 > window_copy_cmd_table[i].maxargs) + cs.wargs = args_parse(&window_copy_cmd_table[i].args, + args_values(args), count, &error); + + if (error != NULL) { + free(error); + error = NULL; + } + if (cs.wargs == NULL) break; + clear = window_copy_cmd_table[i].clear; action = window_copy_cmd_table[i].f(&cs); + args_free(cs.wargs); + cs.wargs = NULL; break; } } if (strncmp(command, "search-", 7) != 0 && data->searchmark != NULL) { - keys = options_get_number(wme->wp->window->options, "mode-keys"); + keys = options_get_number(wp->window->options, "mode-keys"); if (clear == WINDOW_COPY_CMD_CLEAR_EMACS_ONLY && keys == MODEKEY_VI) clear = WINDOW_COPY_CMD_CLEAR_NEVER; @@ -3084,7 +3031,7 @@ window_copy_command(struct window_mode_entry *wme, struct client *c, wme->prefix = 1; if (action == WINDOW_COPY_CMD_CANCEL) - window_pane_reset_mode(wme->wp); + window_pane_reset_mode(wp); else if (action == WINDOW_COPY_CMD_REDRAW) window_copy_redraw_screen(wme); } @@ -4249,11 +4196,12 @@ window_copy_write_line(struct window_mode_entry *wme, struct window_copy_mode_data *data = wme->data; struct screen *s = &data->screen; struct options *oo = wp->window->options; - struct grid_line *gl; struct grid_cell gc, mgc, cgc, mkgc; - char hdr[512], tmp[256], *t; - size_t size = 0; + u_int sx = screen_size_x(s); u_int hsize = screen_hsize(data->backing); + const char *value; + char *expanded; + struct format_tree *ft; style_apply(&gc, oo, "mode-style", NULL); gc.flags |= GRID_FLAG_NOPALETTE; @@ -4264,42 +4212,21 @@ window_copy_write_line(struct window_mode_entry *wme, style_apply(&mkgc, oo, "copy-mode-mark-style", NULL); mkgc.flags |= GRID_FLAG_NOPALETTE; + window_copy_write_one(wme, ctx, py, hsize - data->oy + py, + screen_size_x(s), &mgc, &cgc, &mkgc); + if (py == 0 && s->rupper < s->rlower && !data->hide_position) { - gl = grid_get_line(data->backing->grid, hsize - data->oy); - if (gl->time == 0) - xsnprintf(tmp, sizeof tmp, "[%u/%u]", data->oy, hsize); - else { - t = format_pretty_time(gl->time, 1); - xsnprintf(tmp, sizeof tmp, "%s [%u/%u]", t, data->oy, - hsize); - free(t); - } - - if (data->searchmark == NULL) { - if (data->timeout) { - size = xsnprintf(hdr, sizeof hdr, - "(timed out) %s", tmp); - } else - size = xsnprintf(hdr, sizeof hdr, "%s", tmp); - } else { - if (data->searchcount == -1) - size = xsnprintf(hdr, sizeof hdr, "%s", tmp); - else { - size = xsnprintf(hdr, sizeof hdr, - "(%d%s results) %s", data->searchcount, - data->searchmore ? "+" : "", tmp); + value = options_get_string(oo, "copy-mode-position-format"); + if (*value != '\0') { + ft = format_create_defaults(NULL, NULL, NULL, NULL, wp); + expanded = format_expand(ft, value); + if (*expanded != '\0') { + screen_write_cursormove(ctx, 0, 0, 0); + format_draw(ctx, &gc, sx, expanded, NULL, 0); } + free(expanded); + format_free(ft); } - if (size > screen_size_x(s)) - size = screen_size_x(s); - screen_write_cursormove(ctx, screen_size_x(s) - size, 0, 0); - screen_write_puts(ctx, &gc, "%s", hdr); - } else - size = 0; - - if (size < screen_size_x(s)) { - window_copy_write_one(wme, ctx, py, hsize - data->oy + py, - screen_size_x(s) - size, &mgc, &cgc, &mkgc); } if (py == data->cy && data->cx == screen_size_x(s)) { @@ -4727,19 +4654,21 @@ window_copy_get_selection(struct window_mode_entry *wme, size_t *len) static void window_copy_copy_buffer(struct window_mode_entry *wme, const char *prefix, - void *buf, size_t len) + void *buf, size_t len, int set_paste, int set_clip) { struct window_pane *wp = wme->wp; struct screen_write_ctx ctx; - if (options_get_number(global_options, "set-clipboard") != 0) { + if (set_clip && + options_get_number(global_options, "set-clipboard") != 0) { screen_write_start_pane(&ctx, wp, NULL); screen_write_setselection(&ctx, "", buf, len); screen_write_stop(&ctx); notify_pane("pane-set-clipboard", wp); } - paste_add(prefix, buf, len); + if (set_paste) + paste_add(prefix, buf, len); } static void * @@ -4771,25 +4700,28 @@ window_copy_pipe(struct window_mode_entry *wme, struct session *s, static void window_copy_copy_pipe(struct window_mode_entry *wme, struct session *s, - const char *prefix, const char *cmd) + const char *prefix, const char *cmd, int set_paste, int set_clip) { void *buf; size_t len; buf = window_copy_pipe_run(wme, s, cmd, &len); if (buf != NULL) - window_copy_copy_buffer(wme, prefix, buf, len); + window_copy_copy_buffer(wme, prefix, buf, len, set_paste, + set_clip); } static void -window_copy_copy_selection(struct window_mode_entry *wme, const char *prefix) +window_copy_copy_selection(struct window_mode_entry *wme, const char *prefix, + int set_paste, int set_clip) { char *buf; size_t len; buf = window_copy_get_selection(wme, &len); if (buf != NULL) - window_copy_copy_buffer(wme, prefix, buf, len); + window_copy_copy_buffer(wme, prefix, buf, len, set_paste, + set_clip); } static void @@ -5436,7 +5368,7 @@ window_copy_cursor_previous_word(struct window_mode_entry *wme, static void window_copy_cursor_prompt(struct window_mode_entry *wme, int direction, - const char *args) + int start_output) { struct window_copy_mode_data *data = wme->data; struct screen *s = data->backing; @@ -5445,7 +5377,7 @@ window_copy_cursor_prompt(struct window_mode_entry *wme, int direction, u_int line = gd->hsize - data->oy + data->cy; int add, line_flag; - if (args != NULL && strcmp(args, "-o") == 0) + if (start_output) line_flag = GRID_LINE_START_OUTPUT; else line_flag = GRID_LINE_START_PROMPT; diff --git a/usr.bin/tmux/window-customize.c b/usr.bin/tmux/window-customize.c index cc5dbd552..5cd6fc6ad 100644 --- a/usr.bin/tmux/window-customize.c +++ b/usr.bin/tmux/window-customize.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-customize.c,v 1.14 2022/03/24 12:07:25 nicm Exp $ */ +/* $OpenBSD: window-customize.c,v 1.15 2024/10/04 19:16:13 nicm Exp $ */ /* * Copyright (c) 2020 Nicholas Marriott @@ -101,6 +101,7 @@ struct window_customize_modedata { struct mode_tree_data *data; char *format; int hide_global; + int prompt_flags; struct window_customize_itemdata **item_list; u_int item_size; @@ -885,6 +886,8 @@ window_customize_init(struct window_mode_entry *wme, struct cmd_find_state *fs, data->format = xstrdup(WINDOW_CUSTOMIZE_DEFAULT_FORMAT); else data->format = xstrdup(args_get(args, 'F')); + if (args_has(args, 'y')) + data->prompt_flags = PROMPT_ACCEPT; data->data = mode_tree_start(wp, args, window_customize_build, window_customize_draw, NULL, window_customize_menu, @@ -1453,7 +1456,8 @@ window_customize_key(struct window_mode_entry *wme, struct client *c, status_prompt_set(c, NULL, prompt, "", window_customize_change_current_callback, window_customize_free_callback, data, - PROMPT_SINGLE|PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND); + PROMPT_SINGLE|PROMPT_NOFORMAT|data->prompt_flags, + PROMPT_TYPE_COMMAND); free(prompt); break; case 'D': @@ -1466,7 +1470,8 @@ window_customize_key(struct window_mode_entry *wme, struct client *c, status_prompt_set(c, NULL, prompt, "", window_customize_change_tagged_callback, window_customize_free_callback, data, - PROMPT_SINGLE|PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND); + PROMPT_SINGLE|PROMPT_NOFORMAT|data->prompt_flags, + PROMPT_TYPE_COMMAND); free(prompt); break; case 'u': @@ -1482,7 +1487,8 @@ window_customize_key(struct window_mode_entry *wme, struct client *c, status_prompt_set(c, NULL, prompt, "", window_customize_change_current_callback, window_customize_free_callback, data, - PROMPT_SINGLE|PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND); + PROMPT_SINGLE|PROMPT_NOFORMAT|data->prompt_flags, + PROMPT_TYPE_COMMAND); free(prompt); break; case 'U': @@ -1495,7 +1501,8 @@ window_customize_key(struct window_mode_entry *wme, struct client *c, status_prompt_set(c, NULL, prompt, "", window_customize_change_tagged_callback, window_customize_free_callback, data, - PROMPT_SINGLE|PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND); + PROMPT_SINGLE|PROMPT_NOFORMAT|data->prompt_flags, + PROMPT_TYPE_COMMAND); free(prompt); break; case 'H': diff --git a/usr.bin/tmux/window-tree.c b/usr.bin/tmux/window-tree.c index 6af832642..ba4f40aaa 100644 --- a/usr.bin/tmux/window-tree.c +++ b/usr.bin/tmux/window-tree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-tree.c,v 1.63 2023/06/30 21:55:09 nicm Exp $ */ +/* $OpenBSD: window-tree.c,v 1.64 2024/10/04 19:16:13 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott @@ -131,6 +131,7 @@ struct window_tree_modedata { char *key_format; char *command; int squash_groups; + int prompt_flags; struct window_tree_itemdata **item_list; u_int item_size; @@ -934,6 +935,8 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs, else data->command = xstrdup(args_string(args, 0)); data->squash_groups = !args_has(args, 'G'); + if (args_has(args, 'y')) + data->prompt_flags = PROMPT_ACCEPT; data->data = mode_tree_start(wp, args, window_tree_build, window_tree_draw, window_tree_search, window_tree_menu, NULL, @@ -1305,7 +1308,8 @@ again: data->references++; status_prompt_set(c, NULL, prompt, "", window_tree_kill_current_callback, window_tree_command_free, - data, PROMPT_SINGLE|PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND); + data, PROMPT_SINGLE|PROMPT_NOFORMAT|data->prompt_flags, + PROMPT_TYPE_COMMAND); free(prompt); break; case 'X': @@ -1316,7 +1320,8 @@ again: data->references++; status_prompt_set(c, NULL, prompt, "", window_tree_kill_tagged_callback, window_tree_command_free, - data, PROMPT_SINGLE|PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND); + data, PROMPT_SINGLE|PROMPT_NOFORMAT|data->prompt_flags, + PROMPT_TYPE_COMMAND); free(prompt); break; case ':':