Mercurial > vim
comparison src/sign.c @ 15418:51b3c36b0523 v8.1.0717
patch 8.1.0717: there is no function for the ":sign jump" command
commit https://github.com/vim/vim/commit/6b7b7190aa9e5c4f51bceaebf9275aa5097cfea1
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Jan 11 13:42:41 2019 +0100
patch 8.1.0717: there is no function for the ":sign jump" command
Problem: There is no function for the ":sign jump" command.
Solution: Add the sign_jump() function. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/3780)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 11 Jan 2019 13:45:06 +0100 |
parents | c17b5e30a0af |
children | 55ccc2d353bd |
comparison
equal
deleted
inserted
replaced
15417:50a5ad000845 | 15418:51b3c36b0523 |
---|---|
20 */ | 20 */ |
21 typedef struct sign sign_T; | 21 typedef struct sign sign_T; |
22 | 22 |
23 struct sign | 23 struct sign |
24 { | 24 { |
25 sign_T *sn_next; /* next sign in list */ | 25 sign_T *sn_next; // next sign in list |
26 int sn_typenr; /* type number of sign */ | 26 int sn_typenr; // type number of sign |
27 char_u *sn_name; /* name of sign */ | 27 char_u *sn_name; // name of sign |
28 char_u *sn_icon; /* name of pixmap */ | 28 char_u *sn_icon; // name of pixmap |
29 # ifdef FEAT_SIGN_ICONS | 29 # ifdef FEAT_SIGN_ICONS |
30 void *sn_image; /* icon image */ | 30 void *sn_image; // icon image |
31 # endif | 31 # endif |
32 char_u *sn_text; /* text used instead of pixmap */ | 32 char_u *sn_text; // text used instead of pixmap |
33 int sn_line_hl; /* highlight ID for line */ | 33 int sn_line_hl; // highlight ID for line |
34 int sn_text_hl; /* highlight ID for text */ | 34 int sn_text_hl; // highlight ID for text |
35 }; | 35 }; |
36 | 36 |
37 static sign_T *first_sign = NULL; | 37 static sign_T *first_sign = NULL; |
38 static int next_sign_typenr = 1; | 38 static int next_sign_typenr = 1; |
39 | 39 |
379 */ | 379 */ |
380 int | 380 int |
381 buf_getsigntype( | 381 buf_getsigntype( |
382 buf_T *buf, | 382 buf_T *buf, |
383 linenr_T lnum, | 383 linenr_T lnum, |
384 int type) /* SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL */ | 384 int type) // SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL |
385 { | 385 { |
386 signlist_T *sign; /* a sign in a b_signlist */ | 386 signlist_T *sign; // a sign in a b_signlist |
387 | 387 |
388 FOR_ALL_SIGNS_IN_BUF(buf, sign) | 388 FOR_ALL_SIGNS_IN_BUF(buf, sign) |
389 if (sign->lnum == lnum | 389 if (sign->lnum == lnum |
390 && (type == SIGN_ANY | 390 && (type == SIGN_ANY |
391 # ifdef FEAT_SIGN_ICONS | 391 # ifdef FEAT_SIGN_ICONS |
524 /* | 524 /* |
525 * See if a given type of sign exists on a specific line. | 525 * See if a given type of sign exists on a specific line. |
526 */ | 526 */ |
527 int | 527 int |
528 buf_findsigntype_id( | 528 buf_findsigntype_id( |
529 buf_T *buf, /* buffer whose sign we are searching for */ | 529 buf_T *buf, // buffer whose sign we are searching for |
530 linenr_T lnum, /* line number of sign */ | 530 linenr_T lnum, // line number of sign |
531 int typenr) /* sign type number */ | 531 int typenr) // sign type number |
532 { | 532 { |
533 signlist_T *sign; /* a sign in the signlist */ | 533 signlist_T *sign; // a sign in the signlist |
534 | 534 |
535 FOR_ALL_SIGNS_IN_BUF(buf, sign) | 535 FOR_ALL_SIGNS_IN_BUF(buf, sign) |
536 if (sign->lnum == lnum && sign->typenr == typenr) | 536 if (sign->lnum == lnum && sign->typenr == typenr) |
537 return sign->id; | 537 return sign->id; |
538 | 538 |
654 linenr_T line1, | 654 linenr_T line1, |
655 linenr_T line2, | 655 linenr_T line2, |
656 long amount, | 656 long amount, |
657 long amount_after) | 657 long amount_after) |
658 { | 658 { |
659 signlist_T *sign; /* a sign in a b_signlist */ | 659 signlist_T *sign; // a sign in a b_signlist |
660 | 660 |
661 FOR_ALL_SIGNS_IN_BUF(curbuf, sign) | 661 FOR_ALL_SIGNS_IN_BUF(curbuf, sign) |
662 { | 662 { |
663 if (sign->lnum >= line1 && sign->lnum <= line2) | 663 if (sign->lnum >= line1 && sign->lnum <= line2) |
664 { | 664 { |
676 * Find index of a ":sign" subcmd from its name. | 676 * Find index of a ":sign" subcmd from its name. |
677 * "*end_cmd" must be writable. | 677 * "*end_cmd" must be writable. |
678 */ | 678 */ |
679 static int | 679 static int |
680 sign_cmd_idx( | 680 sign_cmd_idx( |
681 char_u *begin_cmd, /* begin of sign subcmd */ | 681 char_u *begin_cmd, // begin of sign subcmd |
682 char_u *end_cmd) /* just after sign subcmd */ | 682 char_u *end_cmd) // just after sign subcmd |
683 { | 683 { |
684 int idx; | 684 int idx; |
685 char save = *end_cmd; | 685 char save = *end_cmd; |
686 | 686 |
687 *end_cmd = NUL; | 687 *end_cmd = NUL; |
982 else | 982 else |
983 EMSG(_("E159: Missing sign number")); | 983 EMSG(_("E159: Missing sign number")); |
984 } | 984 } |
985 | 985 |
986 /* | 986 /* |
987 * sign define command | 987 * Jump to a sign. |
988 * ":sign define {name} ..." | 988 */ |
989 linenr_T | |
990 sign_jump(int sign_id, char_u *sign_group, buf_T *buf) | |
991 { | |
992 linenr_T lnum; | |
993 | |
994 if ((lnum = buf_findsign(buf, sign_id, sign_group)) <= 0) | |
995 { | |
996 EMSGN(_("E157: Invalid sign ID: %ld"), sign_id); | |
997 return -1; | |
998 } | |
999 | |
1000 // goto a sign ... | |
1001 if (buf_jump_open_win(buf) != NULL) | |
1002 { // ... in a current window | |
1003 curwin->w_cursor.lnum = lnum; | |
1004 check_cursor_lnum(); | |
1005 beginline(BL_WHITE); | |
1006 } | |
1007 else | |
1008 { // ... not currently in a window | |
1009 char_u *cmd; | |
1010 | |
1011 if (buf->b_fname == NULL) | |
1012 { | |
1013 EMSG(_("E934: Cannot jump to a buffer that does not have a name")); | |
1014 return -1; | |
1015 } | |
1016 cmd = alloc((unsigned)STRLEN(buf->b_fname) + 25); | |
1017 if (cmd == NULL) | |
1018 return -1; | |
1019 sprintf((char *)cmd, "e +%ld %s", (long)lnum, buf->b_fname); | |
1020 do_cmdline_cmd(cmd); | |
1021 vim_free(cmd); | |
1022 } | |
1023 # ifdef FEAT_FOLDING | |
1024 foldOpenCursor(); | |
1025 # endif | |
1026 | |
1027 return lnum; | |
1028 } | |
1029 | |
1030 /* | |
1031 * ":sign define {name} ..." command | |
989 */ | 1032 */ |
990 static void | 1033 static void |
991 sign_define_cmd(char_u *sign_name, char_u *cmdline) | 1034 sign_define_cmd(char_u *sign_name, char_u *cmdline) |
992 { | 1035 { |
993 char_u *arg; | 1036 char_u *arg; |
1041 vim_free(linehl); | 1084 vim_free(linehl); |
1042 vim_free(texthl); | 1085 vim_free(texthl); |
1043 } | 1086 } |
1044 | 1087 |
1045 /* | 1088 /* |
1046 * :sign place command | 1089 * ":sign place" command |
1047 */ | 1090 */ |
1048 static void | 1091 static void |
1049 sign_place_cmd( | 1092 sign_place_cmd( |
1050 buf_T *buf, | 1093 buf_T *buf, |
1051 linenr_T lnum, | 1094 linenr_T lnum, |
1085 sign_place(&id, group, sign_name, buf, lnum, prio); | 1128 sign_place(&id, group, sign_name, buf, lnum, prio); |
1086 } | 1129 } |
1087 } | 1130 } |
1088 | 1131 |
1089 /* | 1132 /* |
1090 * :sign unplace command | 1133 * ":sign unplace" command |
1091 */ | 1134 */ |
1092 static void | 1135 static void |
1093 sign_unplace_cmd( | 1136 sign_unplace_cmd( |
1094 buf_T *buf, | 1137 buf_T *buf, |
1095 linenr_T lnum, | 1138 linenr_T lnum, |
1150 } | 1193 } |
1151 } | 1194 } |
1152 } | 1195 } |
1153 | 1196 |
1154 /* | 1197 /* |
1155 * Jump to a placed sign | 1198 * Jump to a placed sign commands: |
1156 * :sign jump {id} file={fname} | 1199 * :sign jump {id} file={fname} |
1157 * :sign jump {id} buffer={nr} | 1200 * :sign jump {id} buffer={nr} |
1158 * :sign jump {id} group={group} file={fname} | 1201 * :sign jump {id} group={group} file={fname} |
1159 * :sign jump {id} group={group} buffer={nr} | 1202 * :sign jump {id} group={group} buffer={nr} |
1160 */ | 1203 */ |
1178 // File or buffer is not specified or an empty group is used | 1221 // File or buffer is not specified or an empty group is used |
1179 // or a line number or a sign name is specified. | 1222 // or a line number or a sign name is specified. |
1180 EMSG(_(e_invarg)); | 1223 EMSG(_(e_invarg)); |
1181 return; | 1224 return; |
1182 } | 1225 } |
1183 | 1226 (void)sign_jump(id, group, buf); |
1184 if ((lnum = buf_findsign(buf, id, group)) <= 0) | |
1185 { | |
1186 EMSGN(_("E157: Invalid sign ID: %ld"), id); | |
1187 return; | |
1188 } | |
1189 | |
1190 // goto a sign ... | |
1191 if (buf_jump_open_win(buf) != NULL) | |
1192 { // ... in a current window | |
1193 curwin->w_cursor.lnum = lnum; | |
1194 check_cursor_lnum(); | |
1195 beginline(BL_WHITE); | |
1196 } | |
1197 else | |
1198 { // ... not currently in a window | |
1199 char_u *cmd; | |
1200 | |
1201 if (buf->b_fname == NULL) | |
1202 { | |
1203 EMSG(_("E934: Cannot jump to a buffer that does not have a name")); | |
1204 return; | |
1205 } | |
1206 cmd = alloc((unsigned)STRLEN(buf->b_fname) + 25); | |
1207 if (cmd == NULL) | |
1208 return; | |
1209 sprintf((char *)cmd, "e +%ld %s", (long)lnum, buf->b_fname); | |
1210 do_cmdline_cmd(cmd); | |
1211 vim_free(cmd); | |
1212 } | |
1213 # ifdef FEAT_FOLDING | |
1214 foldOpenCursor(); | |
1215 # endif | |
1216 } | 1227 } |
1217 | 1228 |
1218 /* | 1229 /* |
1219 * Parse the command line arguments for the ":sign place", ":sign unplace" and | 1230 * Parse the command line arguments for the ":sign place", ":sign unplace" and |
1220 * ":sign jump" commands. | 1231 * ":sign jump" commands. |
1683 } | 1694 } |
1684 | 1695 |
1685 # if defined(FEAT_SIGN_ICONS) || defined(PROTO) | 1696 # if defined(FEAT_SIGN_ICONS) || defined(PROTO) |
1686 void * | 1697 void * |
1687 sign_get_image( | 1698 sign_get_image( |
1688 int typenr) /* the attribute which may have a sign */ | 1699 int typenr) // the attribute which may have a sign |
1689 { | 1700 { |
1690 sign_T *sp; | 1701 sign_T *sp; |
1691 | 1702 |
1692 for (sp = first_sign; sp != NULL; sp = sp->sn_next) | 1703 for (sp = first_sign; sp != NULL; sp = sp->sn_next) |
1693 if (sp->sn_typenr == typenr) | 1704 if (sp->sn_typenr == typenr) |
1707 } | 1718 } |
1708 | 1719 |
1709 # if defined(FEAT_CMDL_COMPL) || defined(PROTO) | 1720 # if defined(FEAT_CMDL_COMPL) || defined(PROTO) |
1710 static enum | 1721 static enum |
1711 { | 1722 { |
1712 EXP_SUBCMD, /* expand :sign sub-commands */ | 1723 EXP_SUBCMD, // expand :sign sub-commands |
1713 EXP_DEFINE, /* expand :sign define {name} args */ | 1724 EXP_DEFINE, // expand :sign define {name} args |
1714 EXP_PLACE, /* expand :sign place {id} args */ | 1725 EXP_PLACE, // expand :sign place {id} args |
1715 EXP_UNPLACE, /* expand :sign unplace" */ | 1726 EXP_UNPLACE, // expand :sign unplace" |
1716 EXP_SIGN_NAMES /* expand with name of placed signs */ | 1727 EXP_SIGN_NAMES // expand with name of placed signs |
1717 } expand_what; | 1728 } expand_what; |
1718 | 1729 |
1719 /* | 1730 /* |
1720 * Function given to ExpandGeneric() to obtain the sign command | 1731 * Function given to ExpandGeneric() to obtain the sign command |
1721 * expansion. | 1732 * expansion. |
1751 { | 1762 { |
1752 char *unplace_arg[] = { "group=", "file=", "buffer=", NULL }; | 1763 char *unplace_arg[] = { "group=", "file=", "buffer=", NULL }; |
1753 return (char_u *)unplace_arg[idx]; | 1764 return (char_u *)unplace_arg[idx]; |
1754 } | 1765 } |
1755 case EXP_SIGN_NAMES: | 1766 case EXP_SIGN_NAMES: |
1756 /* Complete with name of signs already defined */ | 1767 // Complete with name of signs already defined |
1757 current_idx = 0; | 1768 current_idx = 0; |
1758 for (sp = first_sign; sp != NULL; sp = sp->sn_next) | 1769 for (sp = first_sign; sp != NULL; sp = sp->sn_next) |
1759 if (current_idx++ == idx) | 1770 if (current_idx++ == idx) |
1760 return sp->sn_name; | 1771 return sp->sn_name; |
1761 return NULL; | 1772 return NULL; |
1774 char_u *end_subcmd; | 1785 char_u *end_subcmd; |
1775 char_u *last; | 1786 char_u *last; |
1776 int cmd_idx; | 1787 int cmd_idx; |
1777 char_u *begin_subcmd_args; | 1788 char_u *begin_subcmd_args; |
1778 | 1789 |
1779 /* Default: expand subcommands. */ | 1790 // Default: expand subcommands. |
1780 xp->xp_context = EXPAND_SIGN; | 1791 xp->xp_context = EXPAND_SIGN; |
1781 expand_what = EXP_SUBCMD; | 1792 expand_what = EXP_SUBCMD; |
1782 xp->xp_pattern = arg; | 1793 xp->xp_pattern = arg; |
1783 | 1794 |
1784 end_subcmd = skiptowhite(arg); | 1795 end_subcmd = skiptowhite(arg); |
1785 if (*end_subcmd == NUL) | 1796 if (*end_subcmd == NUL) |
1786 /* expand subcmd name | 1797 // expand subcmd name |
1787 * :sign {subcmd}<CTRL-D>*/ | 1798 // :sign {subcmd}<CTRL-D> |
1788 return; | 1799 return; |
1789 | 1800 |
1790 cmd_idx = sign_cmd_idx(arg, end_subcmd); | 1801 cmd_idx = sign_cmd_idx(arg, end_subcmd); |
1791 | 1802 |
1792 /* :sign {subcmd} {subcmd_args} | 1803 // :sign {subcmd} {subcmd_args} |
1793 * | | 1804 // | |
1794 * begin_subcmd_args */ | 1805 // begin_subcmd_args |
1795 begin_subcmd_args = skipwhite(end_subcmd); | 1806 begin_subcmd_args = skipwhite(end_subcmd); |
1796 p = skiptowhite(begin_subcmd_args); | 1807 p = skiptowhite(begin_subcmd_args); |
1797 if (*p == NUL) | 1808 if (*p == NUL) |
1798 { | 1809 { |
1799 /* | 1810 // |
1800 * Expand first argument of subcmd when possible. | 1811 // Expand first argument of subcmd when possible. |
1801 * For ":jump {id}" and ":unplace {id}", we could | 1812 // For ":jump {id}" and ":unplace {id}", we could |
1802 * possibly expand the ids of all signs already placed. | 1813 // possibly expand the ids of all signs already placed. |
1803 */ | 1814 // |
1804 xp->xp_pattern = begin_subcmd_args; | 1815 xp->xp_pattern = begin_subcmd_args; |
1805 switch (cmd_idx) | 1816 switch (cmd_idx) |
1806 { | 1817 { |
1807 case SIGNCMD_LIST: | 1818 case SIGNCMD_LIST: |
1808 case SIGNCMD_UNDEFINE: | 1819 case SIGNCMD_UNDEFINE: |
1809 /* :sign list <CTRL-D> | 1820 // :sign list <CTRL-D> |
1810 * :sign undefine <CTRL-D> */ | 1821 // :sign undefine <CTRL-D> |
1811 expand_what = EXP_SIGN_NAMES; | 1822 expand_what = EXP_SIGN_NAMES; |
1812 break; | 1823 break; |
1813 default: | 1824 default: |
1814 xp->xp_context = EXPAND_NOTHING; | 1825 xp->xp_context = EXPAND_NOTHING; |
1815 } | 1826 } |
1816 return; | 1827 return; |
1817 } | 1828 } |
1818 | 1829 |
1819 /* expand last argument of subcmd */ | 1830 // expand last argument of subcmd |
1820 | 1831 |
1821 /* :sign define {name} {args}... | 1832 // :sign define {name} {args}... |
1822 * | | 1833 // | |
1823 * p */ | 1834 // p |
1824 | 1835 |
1825 /* Loop until reaching last argument. */ | 1836 // Loop until reaching last argument. |
1826 do | 1837 do |
1827 { | 1838 { |
1828 p = skipwhite(p); | 1839 p = skipwhite(p); |
1829 last = p; | 1840 last = p; |
1830 p = skiptowhite(p); | 1841 p = skiptowhite(p); |
1831 } while (*p != NUL); | 1842 } while (*p != NUL); |
1832 | 1843 |
1833 p = vim_strchr(last, '='); | 1844 p = vim_strchr(last, '='); |
1834 | 1845 |
1835 /* :sign define {name} {args}... {last}= | 1846 // :sign define {name} {args}... {last}= |
1836 * | | | 1847 // | | |
1837 * last p */ | 1848 // last p |
1838 if (p == NULL) | 1849 if (p == NULL) |
1839 { | 1850 { |
1840 /* Expand last argument name (before equal sign). */ | 1851 // Expand last argument name (before equal sign). |
1841 xp->xp_pattern = last; | 1852 xp->xp_pattern = last; |
1842 switch (cmd_idx) | 1853 switch (cmd_idx) |
1843 { | 1854 { |
1844 case SIGNCMD_DEFINE: | 1855 case SIGNCMD_DEFINE: |
1845 expand_what = EXP_DEFINE; | 1856 expand_what = EXP_DEFINE; |
1855 xp->xp_context = EXPAND_NOTHING; | 1866 xp->xp_context = EXPAND_NOTHING; |
1856 } | 1867 } |
1857 } | 1868 } |
1858 else | 1869 else |
1859 { | 1870 { |
1860 /* Expand last argument value (after equal sign). */ | 1871 // Expand last argument value (after equal sign). |
1861 xp->xp_pattern = p + 1; | 1872 xp->xp_pattern = p + 1; |
1862 switch (cmd_idx) | 1873 switch (cmd_idx) |
1863 { | 1874 { |
1864 case SIGNCMD_DEFINE: | 1875 case SIGNCMD_DEFINE: |
1865 if (STRNCMP(last, "texthl", p - last) == 0 | 1876 if (STRNCMP(last, "texthl", p - last) == 0 |