aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2022-10-08 15:48:07 +0100
committerLewis Russell <lewis6991@gmail.com>2022-10-13 16:37:23 +0100
commit288208257c8d6b3c8dcce7ee6c7b6c7bb7bafb27 (patch)
tree8a4d8f0d54a98d87bb219f54def43a5f0aa5d402
parenteb123b565e201418dd135d2602dc20eea3cead39 (diff)
downloadrneovim-288208257c8d6b3c8dcce7ee6c7b6c7bb7bafb27.tar.gz
rneovim-288208257c8d6b3c8dcce7ee6c7b6c7bb7bafb27.tar.bz2
rneovim-288208257c8d6b3c8dcce7ee6c7b6c7bb7bafb27.zip
feat(cscope)!: remove
-rw-r--r--.github/workflows/ci.yml2
-rw-r--r--.github/workflows/codeql-analysis.yml2
-rw-r--r--cmake.config/CMakeLists.txt5
-rw-r--r--runtime/doc/autocmd.txt2
-rw-r--r--runtime/doc/builtin.txt44
-rw-r--r--runtime/doc/cmdline.txt4
-rw-r--r--runtime/doc/deprecated.txt1
-rw-r--r--runtime/doc/help.txt1
-rw-r--r--runtime/doc/if_cscop.txt374
-rw-r--r--runtime/doc/index.txt4
-rw-r--r--runtime/doc/map.txt1
-rw-r--r--runtime/doc/news.txt21
-rw-r--r--runtime/doc/options.txt37
-rw-r--r--runtime/doc/quickref.txt6
-rw-r--r--runtime/doc/usr_29.txt3
-rw-r--r--runtime/doc/usr_41.txt1
-rw-r--r--runtime/doc/vim_diff.txt17
-rw-r--r--runtime/lua/man.lua5
-rw-r--r--runtime/optwin.vim16
-rwxr-xr-xscripts/vim-patch.sh6
-rw-r--r--src/nvim/cmdexpand.c12
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/eval/funcs.c25
-rw-r--r--src/nvim/ex_cmds.lua24
-rw-r--r--src/nvim/ex_docmd.c5
-rwxr-xr-xsrc/nvim/generators/gen_declarations.lua3
-rw-r--r--src/nvim/if_cscope.c2027
-rw-r--r--src/nvim/if_cscope.h10
-rw-r--r--src/nvim/if_cscope_defs.h64
-rw-r--r--src/nvim/main.c2
-rw-r--r--src/nvim/normal.c6
-rw-r--r--src/nvim/option_defs.h9
-rw-r--r--src/nvim/options.lua52
-rw-r--r--src/nvim/optionstr.c17
-rw-r--r--src/nvim/tag.c226
-rw-r--r--src/nvim/tag.h2
-rw-r--r--src/nvim/testdir/test_cscope.vim344
-rw-r--r--src/nvim/usercmd.c1
-rw-r--r--src/nvim/vim.h1
39 files changed, 132 insertions, 3251 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 992c59454b..f4731e2b32 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -254,7 +254,7 @@ jobs:
if: matrix.os == 'linux'
run: |
sudo apt-get update
- sudo apt-get install -y autoconf automake build-essential cmake cpanminus cscope gcc-multilib gdb gettext language-pack-tr libtool-bin locales ninja-build pkg-config python3 python3-pip python3-setuptools unzip valgrind xclip
+ sudo apt-get install -y autoconf automake build-essential cmake cpanminus gcc-multilib gdb gettext language-pack-tr libtool-bin locales ninja-build pkg-config python3 python3-pip python3-setuptools unzip valgrind xclip
- name: Install minimum required version of cmake
if: matrix.cmake == 'minimum_required'
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index b31382af37..d0f04553f2 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -28,7 +28,7 @@ jobs:
- name: Install apt packages
run: |
sudo apt-get update
- sudo apt-get install -y autoconf automake build-essential cmake cpanminus cscope gcc-multilib gdb gettext language-pack-tr libtool-bin locales ninja-build pkg-config python3 python3-pip python3-setuptools unzip valgrind xclip
+ sudo apt-get install -y autoconf automake build-essential cmake cpanminus gcc-multilib gdb gettext language-pack-tr libtool-bin locales ninja-build pkg-config python3 python3-pip python3-setuptools unzip valgrind xclip
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
diff --git a/cmake.config/CMakeLists.txt b/cmake.config/CMakeLists.txt
index 8c86b89e43..b11ee2d969 100644
--- a/cmake.config/CMakeLists.txt
+++ b/cmake.config/CMakeLists.txt
@@ -20,11 +20,6 @@ check_include_files(langinfo.h HAVE_LANGINFO_H)
check_include_files(locale.h HAVE_LOCALE_H)
check_include_files(pwd.h HAVE_PWD_H)
check_include_files(strings.h HAVE_STRINGS_H)
-check_include_files(sys/wait.h HAVE_SYS_WAIT_H)
-if(NOT HAVE_SYS_WAIT_H AND UNIX)
- # See if_cscope.c
- message(SEND_ERROR "header sys/wait.h is required for Unix")
-endif()
check_include_files(sys/utsname.h HAVE_SYS_UTSNAME_H)
check_include_files(termios.h HAVE_TERMIOS_H)
check_include_files(sys/uio.h HAVE_SYS_UIO_H)
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index e27f191e0d..da41c92df6 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -806,7 +806,7 @@ OptionSet After setting an option (except during
QuickFixCmdPre Before a quickfix command is run (|:make|,
|:lmake|, |:grep|, |:lgrep|, |:grepadd|,
|:lgrepadd|, |:vimgrep|, |:lvimgrep|,
- |:vimgrepadd|, |:lvimgrepadd|, |:cscope|,
+ |:vimgrepadd|, |:lvimgrepadd|,
|:cfile|, |:cgetfile|, |:caddfile|, |:lfile|,
|:lgetfile|, |:laddfile|, |:helpgrep|,
|:lhelpgrep|, |:cexpr|, |:cgetexpr|,
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 89f3dafa85..b0484b7ffe 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -96,8 +96,6 @@ cos({expr}) Float cosine of {expr}
cosh({expr}) Float hyperbolic cosine of {expr}
count({comp}, {expr} [, {ic} [, {start}]])
Number count how many {expr} are in {comp}
-cscope_connection([{num}, {dbpath} [, {prepend}]])
- Number checks existence of cscope connection
ctxget([{index}]) Dict return the |context| dict at {index}
ctxpop() none pop and restore |context| from the
|context-stack|
@@ -1436,47 +1434,6 @@ count({comp}, {expr} [, {ic} [, {start}]]) *count()*
Can also be used as a |method|: >
mylist->count(val)
<
- *cscope_connection()*
-cscope_connection([{num} , {dbpath} [, {prepend}]])
- Checks for the existence of a |cscope| connection. If no
- parameters are specified, then the function returns:
- 0, if there are no cscope connections;
- 1, if there is at least one cscope connection.
-
- If parameters are specified, then the value of {num}
- determines how existence of a cscope connection is checked:
-
- {num} Description of existence check
- ----- ------------------------------
- 0 Same as no parameters (e.g., "cscope_connection()").
- 1 Ignore {prepend}, and use partial string matches for
- {dbpath}.
- 2 Ignore {prepend}, and use exact string matches for
- {dbpath}.
- 3 Use {prepend}, use partial string matches for both
- {dbpath} and {prepend}.
- 4 Use {prepend}, use exact string matches for both
- {dbpath} and {prepend}.
-
- Note: All string comparisons are case sensitive!
-
- Examples. Suppose we had the following (from ":cs show"): >
-
- # pid database name prepend path
- 0 27664 cscope.out /usr/local
-<
- Invocation Return Val ~
- ---------- ---------- >
- cscope_connection() 1
- cscope_connection(1, "out") 1
- cscope_connection(2, "out") 0
- cscope_connection(3, "out") 0
- cscope_connection(3, "out", "local") 1
- cscope_connection(4, "out") 0
- cscope_connection(4, "out", "local") 0
- cscope_connection(4, "cscope.out", "/usr/local") 1
-<
-
ctxget([{index}]) *ctxget()*
Returns a |Dictionary| representing the |context| at {index}
from the top of the |context-stack| (see |context-dict|).
@@ -2981,7 +2938,6 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
color color schemes
command Ex command
compiler compilers
- cscope |:cscope| suboptions
diff_buffer |:diffget| and |:diffput| completion
dir directory names
environment environment variable names
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt
index b1013420fa..a6458adb77 100644
--- a/runtime/doc/cmdline.txt
+++ b/runtime/doc/cmdline.txt
@@ -524,7 +524,6 @@ that see the '"' as part of their argument:
:cexpr (and the like)
:cdo (and the like)
:command
- :cscope (and the like)
:debug
:display
:echo (and the like)
@@ -566,7 +565,6 @@ followed by another Vim command:
:cdo
:cfdo
:command
- :cscope
:debug
:eval
:folddoopen
@@ -575,7 +573,6 @@ followed by another Vim command:
:global
:help
:helpgrep
- :lcscope
:ldo
:lfdo
:lhelpgrep
@@ -586,7 +583,6 @@ followed by another Vim command:
:python
:registers
:read !
- :scscope
:sign
:terminal
:vglobal
diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt
index d00f309826..5e6bc957a1 100644
--- a/runtime/doc/deprecated.txt
+++ b/runtime/doc/deprecated.txt
@@ -128,7 +128,6 @@ NORMAL COMMANDS
OPTIONS
- *cpo-<* *:menu-<special>* *:menu-special* *:map-<special>* *:map-special*
`<>` notation is always enabled.
-- *'cscopeverbose'* Enabled by default. Use |:silent| instead.
- *'exrc'* *'ex'* Security risk: downloaded files could include
a malicious .nvimrc or .exrc file. See 'secure'.
Recommended alternative: define an autocommand in your
diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt
index a1bedfa500..21bee24171 100644
--- a/runtime/doc/help.txt
+++ b/runtime/doc/help.txt
@@ -168,7 +168,6 @@ GUI ~
|gui.txt| Graphical User Interface (GUI)
Interfaces ~
-|if_cscop.txt| using Cscope with Vim
|if_perl.txt| Perl interface
|if_pyth.txt| Python interface
|if_ruby.txt| Ruby interface
diff --git a/runtime/doc/if_cscop.txt b/runtime/doc/if_cscop.txt
deleted file mode 100644
index 8947aefc1b..0000000000
--- a/runtime/doc/if_cscop.txt
+++ /dev/null
@@ -1,374 +0,0 @@
-*if_cscop.txt* Nvim
-
-
- VIM REFERENCE MANUAL by Andy Kahn
-
- *cscope* *Cscope*
-Cscope is a "code intelligence" tool that helps you navigate C programs. It
-can also perform some refactoring tasks, such as renaming a global variable in
-all source files. Think of it as "ctags on steroids".
-
-See |cscope-usage| for a quickstart.
-
- Type |gO| to see the table of contents.
-
-==============================================================================
-Cscope introduction *cscope-intro*
-
-
-Cscope is designed to answer questions like:
- Where is this symbol used?
- Where is it defined?
- Where did this variable get its value?
- What is this global symbol's definition?
- Where is this function in the source files?
- What functions call this function?
- What functions are called by this function?
- Where does the message "out of space" come from?
- Where is this source file in the directory structure?
- What files include this header file?
-
-Cscope answers these questions from a symbol database that it builds the first
-time it is used on the source files. On a subsequent call, cscope rebuilds
-the database only if a source file has changed or the list of source files is
-different. When the database is rebuilt the data for the unchanged files is
-copied from the old database, which makes rebuilding much faster than the
-initial build.
-
-See |cscope-usage| to get started.
-
-==============================================================================
-Cscope commands *cscope-commands*
-
- *:cscope* *:cs* *:scs* *:scscope* *E259* *E262* *E560* *E561*
-All cscope commands are accessed through suboptions to the cscope commands.
- `:cscope` or `:cs` is the main command
- `:scscope` or `:scs` does the same and splits the window
- `:lcscope` or `:lcs` uses the location list, see |:lcscope|
-
-The available subcommands are:
-
- *E563* *E564* *E566* *E568* *E622* *E623* *E625*
- *E626* *E609*
- add : Add a new cscope database/connection.
-
- USAGE :cs add {file|dir} [pre-path] [flags]
-
- [pre-path] is the pathname used with the -P command to cscope.
-
- [flags] are any additional flags you want to pass to cscope.
-
- EXAMPLES >
- :cscope add /usr/local/cdb/cscope.out
- :cscope add /projects/vim/cscope.out /usr/local/vim
- :cscope add cscope.out /usr/local/vim -C
-<
- *cscope-find* *cs-find* *E567*
- find : Query cscope. All cscope query options are available
- except option #5 ("Change this grep pattern").
-
- USAGE :cs find {querytype} {name}
-
- {querytype} corresponds to the actual cscope line
- interface numbers as well as default nvi commands:
-
- 0 or s: Find this C symbol
- 1 or g: Find this definition
- 2 or d: Find functions called by this function
- 3 or c: Find functions calling this function
- 4 or t: Find this text string
- 6 or e: Find this egrep pattern
- 7 or f: Find this file
- 8 or i: Find files #including this file
- 9 or a: Find places where this symbol is assigned a value
-
- For all types, except 4 and 6, leading white space for {name} is
- removed. For 4 and 6 there is exactly one space between {querytype}
- and {name}. Further white space is included in {name}.
-
- EXAMPLES >
- :cscope find c vim_free
- :cscope find 3 vim_free
-<
- These two examples perform the same query: functions calling
- "vim_free". >
-
- :cscope find t initOnce
- :cscope find t initOnce
-<
- The first one searches for the text "initOnce", the second one for
- " initOnce". >
-
- :cscope find 0 DEFAULT_TERM
-<
- Executing this example on the source code for Vim 5.1 produces the
- following output:
-
- Cscope tag: DEFAULT_TERM
- # line filename / context / line
- 1 1009 vim-5.1-gtk/src/term.c <<GLOBAL>>
- #define DEFAULT_TERM (char_u *)"amiga"
- 2 1013 vim-5.1-gtk/src/term.c <<GLOBAL>>
- #define DEFAULT_TERM (char_u *)"win32"
- 3 1017 vim-5.1-gtk/src/term.c <<GLOBAL>>
- #define DEFAULT_TERM (char_u *)"pcterm"
- 4 1021 vim-5.1-gtk/src/term.c <<GLOBAL>>
- #define DEFAULT_TERM (char_u *)"ansi"
- 5 1025 vim-5.1-gtk/src/term.c <<GLOBAL>>
- #define DEFAULT_TERM (char_u *)"vt52"
- 6 1029 vim-5.1-gtk/src/term.c <<GLOBAL>>
- #define DEFAULT_TERM (char_u *)"os2ansi"
- 7 1033 vim-5.1-gtk/src/term.c <<GLOBAL>>
- #define DEFAULT_TERM (char_u *)"ansi"
- 8 1037 vim-5.1-gtk/src/term.c <<GLOBAL>>
- # undef DEFAULT_TERM
- 9 1038 vim-5.1-gtk/src/term.c <<GLOBAL>>
- #define DEFAULT_TERM (char_u *)"beos-ansi"
- 10 1042 vim-5.1-gtk/src/term.c <<GLOBAL>>
- #define DEFAULT_TERM (char_u *)"mac-ansi"
- 11 1335 vim-5.1-gtk/src/term.c <<set_termname>>
- term = DEFAULT_TERM;
- 12 1459 vim-5.1-gtk/src/term.c <<set_termname>>
- if (STRCMP(term, DEFAULT_TERM))
- 13 1826 vim-5.1-gtk/src/term.c <<termcapinit>>
- term = DEFAULT_TERM;
- 14 1833 vim-5.1-gtk/src/term.c <<termcapinit>>
- term = DEFAULT_TERM;
- 15 3635 vim-5.1-gtk/src/term.c <<update_tcap>>
- p = find_builtin_term(DEFAULT_TERM);
- Enter nr of choice (<CR> to abort):
-
- The output shows several pieces of information:
- 1. The tag number (there are 15 in this example).
- 2. The line number where the tag occurs.
- 3. The filename where the tag occurs.
- 4. The context of the tag (e.g., global, or the function name).
- 5. The line from the file itself.
-
- help : Show a brief synopsis.
-
- USAGE :cs help
-
- *E261*
- kill : Kill a cscope connection (or kill all cscope connections).
-
- USAGE :cs kill {num|partial_name}
-
- To kill a cscope connection, the connection number or a partial
- name must be specified. The partial name is simply any part of
- the pathname of the cscope database. Kill a cscope connection
- using the partial name with caution!
-
- If the specified connection number is -1, then _ALL_ cscope
- connections will be killed.
-
- reset : Reinit all cscope connections.
-
- USAGE :cs reset
-
- show : Show cscope connections.
-
- USAGE :cs show
-
- *:lcscope* *:lcs*
-This command is same as the ":cscope" command, except when the
-'cscopequickfix' option is set, the location list for the current window is
-used instead of the quickfix list to show the cscope results.
-
- *:cstag* *E257* *E562*
-If you use cscope as well as ctags, |:cstag| allows you to search one or
-the other before making a jump. For example, you can choose to first
-search your cscope database(s) for a match, and if one is not found, then
-your tags file(s) will be searched. The order in which this happens
-is determined by the value of |csto|. See |cscope-options| for more
-details.
-
-|:cstag| performs the equivalent of ":cs find g" on the identifier when
-searching through the cscope database(s).
-
-|:cstag| performs the equivalent of |:tjump| on the identifier when searching
-through your tags file(s).
-
-
-==============================================================================
-Cscope options *cscope-options*
-
-Use the |:set| command to set all cscope options. Ideally, you would do
-this in one of your startup files (e.g., vimrc). Some cscope related
-variables are only valid within |init.vim|. Setting them after vim has
-started will have no effect!
-
- *cscopeprg* *csprg*
-'cscopeprg' specifies the command to execute cscope. The default is
-"cscope". For example: >
- :set csprg=/usr/local/bin/cscope
-<
- *cscopequickfix* *csqf* *E469*
-'cscopequickfix' specifies whether to use quickfix window to show cscope
-results. This is a list of comma-separated values. Each item consists of
-|cscope-find| command (s, g, d, c, t, e, f, i or a) and flag (+, - or 0).
-'+' indicates that results must be appended to quickfix window,
-'-' implies previous results clearance, '0' or command absence - don't use
-quickfix. Search is performed from start until first command occurrence.
-The default value is "" (don't use quickfix anyway). The following value
-seems to be useful: >
- :set cscopequickfix=s-,c-,d-,i-,t-,e-,a-
-<
- *cscopetag* *cst*
-If 'cscopetag' is set, the commands ":tag" and CTRL-] as well as "vim -t"
-will always use |:cstag| instead of the default :tag behavior. Effectively,
-by setting 'cst', you will always search your cscope databases as well as
-your tag files. The default is off.
-
- *cscoperelative* *csre*
-If 'cscoperelative' is set, then in absence of a prefix given to cscope
-(prefix is the argument of -P option of cscope), basename of cscope.out
-location (usually the project root directory) will be used as the prefix
-to construct an absolute path. The default is off. Note: This option is
-only effective when cscope (cscopeprg) is initialized without a prefix
-path (-P).
-
- *cscopetagorder* *csto*
-The value of 'csto' determines the order in which |:cstag| performs a search.
-If 'csto' is set to zero, cscope database(s) are searched first, followed
-by tag file(s) if cscope did not return any matches. If 'csto' is set to
-one, tag file(s) are searched before cscope database(s). The default is zero.
-
- *cscopepathcomp* *cspc*
-'cscopepathcomp' determines how many components of a file's path to display.
-With the default value of zero the entire path will be displayed.
-The value one will display only the filename with no path. Other values
-display that many components. For example: >
- :set cscopepathcomp=3
-will display the last 3 components of the file's path, including the file
-name itself.
-
-==============================================================================
-Using cscope in Nvim *cscope-usage* *cscope-howtouse*
-
-To get started, build the cscope database in your project root directory: >
- cscope -bcqR
-
-See the cscope manpage for details: >
- :Man cscope
-
-By default the cscope database file is named "cscope.out". After building the
-database, connect to it from Nvim: >
- :cscope add cscope.out
-
-That establishes a cscope connection for Nvim to use. You can check the
-result with ":cs show". It will show something like:
-
- # pid database name prepend path
- 0 28806 cscope.out <none>
-
-Once a cscope connection is established, you can make queries to cscope and
-the results will be printed. Queries are made using the command ":cs find".
-For example: >
- :cs find g ALIGN_SIZE
-
-To make this easier you can configure mappings, see |cscope-suggestions|.
-
-If the results return only one match, you will automatically be taken to it.
-If there is more than one match, you will be given a selection screen to pick
-the match you want to go to. After you have jumped to the new location,
-simply hit Ctrl-T to get back to the previous one.
-
-
-==============================================================================
-Limitations *cscope-limitations*
-
-Hard-coded limitation: doing a |:tjump| when |:cstag| searches the tag files
-is not configurable (e.g., you can't do a tselect instead).
-
-
-==============================================================================
-Sample config *cscope-suggestions*
-
-Copy this into your init.vim (adjust paths for your system): >
-
- if has("cscope")
- set csprg=/usr/local/bin/cscope
- set csto=0
- set cst
- " add any database in current directory
- if filereadable("cscope.out")
- silent cs add cscope.out
- " else add database pointed to by environment
- elseif $CSCOPE_DB != ""
- silent cs add $CSCOPE_DB
- endif
- endif
-
-By setting 'cscopetag', we have effectively replaced all instances of the :tag
-command with :cstag. This includes :tag, Ctrl-], and "vim -t". In doing
-this, the regular tag command not only searches your ctags generated tag
-files, but your cscope databases as well.
-
-Some users may want to keep the regular tag behavior and have a different
-shortcut to access :cstag. For example, one could map Ctrl-_ (underscore)
-to :cstag with the following command: >
-
- map <C-_> :cstag <C-R>=expand("<cword>")<CR><CR>
-
-A couple of very commonly used cscope queries (using ":cs find") is to
-find all functions calling a certain function and to find all occurrences
-of a particular C symbol. To do this, you can use these mappings as an
-example: >
-
- map g<C-]> :cs find 3 <C-R>=expand("<cword>")<CR><CR>
- map g<C-\> :cs find 0 <C-R>=expand("<cword>")<CR><CR>
-
-These mappings for Ctrl-] (right bracket) and Ctrl-\ (backslash) allow you to
-place your cursor over the function name or C symbol and quickly query cscope
-for any matches.
-
-Or you may use the following scheme, inspired by Vim/Cscope tutorial from
-Cscope Home Page (http://cscope.sourceforge.net/): >
-
- nmap <C-_>s :cs find s <C-R>=expand("<cword>")<CR><CR>
- nmap <C-_>g :cs find g <C-R>=expand("<cword>")<CR><CR>
- nmap <C-_>c :cs find c <C-R>=expand("<cword>")<CR><CR>
- nmap <C-_>t :cs find t <C-R>=expand("<cword>")<CR><CR>
- nmap <C-_>e :cs find e <C-R>=expand("<cword>")<CR><CR>
- nmap <C-_>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
- nmap <C-_>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
- nmap <C-_>d :cs find d <C-R>=expand("<cword>")<CR><CR>
- nmap <C-_>a :cs find a <C-R>=expand("<cword>")<CR><CR>
-
- " Using 'CTRL-spacebar' then a search type makes the vim window
- " split horizontally, with search result displayed in
- " the new window.
-
- nmap <C-Space>s :scs find s <C-R>=expand("<cword>")<CR><CR>
- nmap <C-Space>g :scs find g <C-R>=expand("<cword>")<CR><CR>
- nmap <C-Space>c :scs find c <C-R>=expand("<cword>")<CR><CR>
- nmap <C-Space>t :scs find t <C-R>=expand("<cword>")<CR><CR>
- nmap <C-Space>e :scs find e <C-R>=expand("<cword>")<CR><CR>
- nmap <C-Space>f :scs find f <C-R>=expand("<cfile>")<CR><CR>
- nmap <C-Space>i :scs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
- nmap <C-Space>d :scs find d <C-R>=expand("<cword>")<CR><CR>
- nmap <C-Space>a :scs find a <C-R>=expand("<cword>")<CR><CR>
-
- " Hitting CTRL-space *twice* before the search type does a vertical
- " split instead of a horizontal one
-
- nmap <C-Space><C-Space>s
- \:vert scs find s <C-R>=expand("<cword>")<CR><CR>
- nmap <C-Space><C-Space>g
- \:vert scs find g <C-R>=expand("<cword>")<CR><CR>
- nmap <C-Space><C-Space>c
- \:vert scs find c <C-R>=expand("<cword>")<CR><CR>
- nmap <C-Space><C-Space>t
- \:vert scs find t <C-R>=expand("<cword>")<CR><CR>
- nmap <C-Space><C-Space>e
- \:vert scs find e <C-R>=expand("<cword>")<CR><CR>
- nmap <C-Space><C-Space>i
- \:vert scs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
- nmap <C-Space><C-Space>d
- \:vert scs find d <C-R>=expand("<cword>")<CR><CR>
- nmap <C-Space><C-Space>a
- \:vert scs find a <C-R>=expand("<cword>")<CR><CR>
-<
-
- vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt
index 7318bc7f34..e7c4c37f7d 100644
--- a/runtime/doc/index.txt
+++ b/runtime/doc/index.txt
@@ -1250,8 +1250,6 @@ tag command action ~
|:cpfile| :cpf[ile] go to last error in previous file
|:cquit| :cq[uit] quit Vim with an error code
|:crewind| :cr[ewind] go to the specified error, default first one
-|:cscope| :cs[cope] execute cscope command
-|:cstag| :cst[ag] use cscope to jump to a tag
|:cunmap| :cu[nmap] like ":unmap" but for Command-line mode
|:cunabbrev| :cuna[bbrev] like ":unabbrev" but for Command-line mode
|:cunmenu| :cunme[nu] remove menu for Command-line mode
@@ -1375,7 +1373,6 @@ tag command action ~
|:lcd| :lc[d] change directory locally
|:lchdir| :lch[dir] change directory locally
|:lclose| :lcl[ose] close location window
-|:lcscope| :lcs[cope] like ":cscope" but uses location list
|:ldo| :ld[o] execute command in valid location list entries
|:lfdo| :lfd[o] execute command in each file in location list
|:left| :le[ft] left align lines
@@ -1556,7 +1553,6 @@ tag command action ~
buffer list
|:scriptnames| :scr[iptnames] list names of all sourced Vim scripts
|:scriptencoding| :scripte[ncoding] encoding used in sourced Vim script
-|:scscope| :scs[cope] split window and execute cscope command
|:set| :se[t] show or set options
|:setfiletype| :setf[iletype] set 'filetype', unless it was set already
|:setglobal| :setg[lobal] show global values of options
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index cbc92a8cb5..60cc915a4a 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -1336,7 +1336,6 @@ completion can be enabled:
-complete=color color schemes
-complete=command Ex command (and arguments)
-complete=compiler compilers
- -complete=cscope |:cscope| suboptions
-complete=dir directory names
-complete=environment environment variable names
-complete=event autocommand events
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index 0fdd7aaaf9..41d47f7a90 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -13,6 +13,27 @@ BREAKING CHANGES *news-breaking*
The following changes may require adaptations in user config or plugins.
+Cscope is now removed (see |cscope| and |nvim-features-removed|):
+ - Commands removed:
+ - `:cscope`
+ - `:lcscope`
+ - `:scscope`
+ - `:cstag`
+ - Options removed:
+ - `cscopepathcomp`
+ - `cscopeprg`
+ - `cscopequickfix`
+ - `cscoperelative`
+ - `cscopetag`
+ - `cscopetagorder`
+ - `cscopeverbose`
+ - Eval functions removed:
+ - `cscope_connection()`
+
+Note: support for |ctags| remains with no plans to remove.
+
+See https://github.com/neovim/neovim/pull/20545 for more information.
+
==============================================================================
NEW FEATURES *news-features*
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index e9dda06df9..4f07b78264 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1792,43 +1792,6 @@ A jump table for the options with a short description can be found at |Q_op|.
_ When using |cw| on a word, do not include the
whitespace following the word in the motion.
- *'cscopepathcomp'* *'cspc'*
-'cscopepathcomp' 'cspc' number (default 0)
- global
- Determines how many components of the path to show in a list of tags.
- See |cscopepathcomp|.
-
- *'cscopeprg'* *'csprg'*
-'cscopeprg' 'csprg' string (default "cscope")
- global
- Specifies the command to execute cscope. See |cscopeprg|.
- This option cannot be set from a |modeline| or in the |sandbox|, for
- security reasons.
-
- *'cscopequickfix'* *'csqf'*
-'cscopequickfix' 'csqf' string (default "")
- global
- Specifies whether to use quickfix window to show cscope results.
- See |cscopequickfix|.
-
- *'cscoperelative'* *'csre'* *'nocscoperelative'* *'nocsre'*
-'cscoperelative' 'csre' boolean (default off)
- global
- In the absence of a prefix (-P) for cscope. setting this option enables
- to use the basename of cscope.out path as the prefix.
- See |cscoperelative|.
-
- *'cscopetag'* *'cst'* *'nocscopetag'* *'nocst'*
-'cscopetag' 'cst' boolean (default off)
- global
- Use cscope for tag commands. See |cscope-options|.
-
- *'cscopetagorder'* *'csto'*
-'cscopetagorder' 'csto' number (default 0)
- global
- Determines the order in which ":cstag" performs a search. See
- |cscopetagorder|.
-
*'cursorbind'* *'crb'* *'nocursorbind'* *'nocrb'*
'cursorbind' 'crb' boolean (default off)
local to window
diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt
index 5b100c73a9..f1261b18ff 100644
--- a/runtime/doc/quickref.txt
+++ b/runtime/doc/quickref.txt
@@ -673,12 +673,6 @@ Short explanation of each option: *option-list*
'confirm' 'cf' ask what to do about unsaved/read-only files
'copyindent' 'ci' make 'autoindent' use existing indent structure
'cpoptions' 'cpo' flags for Vi-compatible behavior
-'cscopepathcomp' 'cspc' how many components of the path to show
-'cscopeprg' 'csprg' command to execute cscope
-'cscopequickfix' 'csqf' use quickfix window for cscope results
-'cscoperelative' 'csre' Use cscope.out path basename as prefix
-'cscopetag' 'cst' use cscope for tag commands
-'cscopetagorder' 'csto' determines ":cstag" search order
'cursorbind' 'crb' move cursor in window as it moves in other windows
'cursorcolumn' 'cuc' highlight the screen column of the cursor
'cursorline' 'cul' highlight the screen line of the cursor
diff --git a/runtime/doc/usr_29.txt b/runtime/doc/usr_29.txt
index d8c556c281..3b7b0d0ea1 100644
--- a/runtime/doc/usr_29.txt
+++ b/runtime/doc/usr_29.txt
@@ -268,9 +268,6 @@ doesn't work if the tags file isn't sorted.
The 'taglength' option can be used to tell Vim the number of significant
characters in a tag.
-Cscope is a free program. It does not only find places where an identifier is
-declared, but also where it is used. See |cscope|.
-
==============================================================================
*29.2* The preview window
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 6690dad4a7..808e3a6378 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -1051,7 +1051,6 @@ Various: *various-functions*
exists() check if a variable, function, etc. exists
has() check if a feature is supported in Vim
changenr() return number of most recent change
- cscope_connection() check if a cscope connection exists
did_filetype() check if a FileType autocommand was used
eventhandler() check if invoked by an event handler
getpid() get process ID of Vim
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index 62b755d64b..76a45166a1 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -36,7 +36,6 @@ centralized reference of the differences.
- 'belloff' defaults to "all"
- 'compatible' is always disabled
- 'complete' excludes "i"
-- 'cscopeverbose' is enabled
- 'directory' defaults to ~/.local/state/nvim/swap// (|xdg|), auto-created
- 'display' defaults to "lastline"
- 'encoding' is UTF-8 (cf. 'fileencoding' for file-content encoding)
@@ -541,6 +540,10 @@ Commands:
:sleep! (does not hide the cursor; same as :sleep)
:smile
:tearoff
+ :cstag
+ :cscope
+ :lcscope
+ :scscope
Compile-time features:
Emacs tags support
@@ -548,6 +551,7 @@ Compile-time features:
Eval:
Vim9script
+ *cscope_connection()*
*js_encode()*
*js_decode()*
*v:none* (used by Vim to represent JavaScript "undefined"); use |v:null| instead.
@@ -579,6 +583,13 @@ Options:
*'cp'* *'nocompatible'* *'nocp'* *'compatible'* (Nvim is always "nocompatible".)
'cpoptions' (gjkHw<*- and all POSIX flags were removed)
*'cryptmethod'* *'cm'* *'key'* (Vim encryption implementation)
+ cscopepathcomp
+ cscopeprg
+ cscopequickfix
+ cscoperelative
+ cscopetag
+ cscopetagorder
+ cscopeverbose
*'ed'* *'edcompatible'* *'noed'* *'noedcompatible'*
'encoding' ("utf-8" is always used)
esckeys
@@ -694,5 +705,9 @@ TUI:
at how the terminal is sending CSI. Nvim does not issue such a sequence and
always uses 7-bit control sequences.
+Cscope:
+ *cscope*
+ Cscope has been removed in favour of LSP based solutions.
+
==============================================================================
vim:tw=78:ts=8:sw=2:et:ft=help:norl:
diff --git a/runtime/lua/man.lua b/runtime/lua/man.lua
index 6477786dbb..18d08ad1a8 100644
--- a/runtime/lua/man.lua
+++ b/runtime/lua/man.lua
@@ -604,11 +604,6 @@ function M.goto_tag(pattern, _, _)
end
end
- if vim.o.cscopetag then
- -- return only a single entry so we work well with :cstag (#11675)
- structured = { structured[1] }
- end
-
return vim.tbl_map(function(entry)
return {
name = entry.name,
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index 5f0bee6be4..382322cfe2 100644
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -319,22 +319,6 @@ if has("eval")
call append("$", "\t(local to buffer)")
call <SID>OptionL("tfu")
endif
-if has("cscope")
- call append("$", "cscopeprg\tcommand for executing cscope")
- call <SID>OptionG("csprg", &csprg)
- call append("$", "cscopetag\tuse cscope for tag commands")
- call <SID>BinOptionG("cst", &cst)
- call append("$", "cscopetagorder\t0 or 1; the order in which \":cstag\" performs a search")
- call append("$", " \tset csto=" . &csto)
- call append("$", "cscopeverbose\tgive messages when adding a cscope database")
- call <SID>BinOptionG("csverb", &csverb)
- call append("$", "cscopepathcomp\thow many components of the path to show")
- call append("$", " \tset cspc=" . &cspc)
- call append("$", "cscopequickfix\twhen to open a quickfix window for cscope")
- call <SID>OptionG("csqf", &csqf)
- call append("$", "cscoperelative\tfile names in a cscope file are relative to that file")
- call <SID>BinOptionG("csre", &csre)
-endif
call <SID>Header("displaying text")
diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh
index ad1973603e..f824feb856 100755
--- a/scripts/vim-patch.sh
+++ b/scripts/vim-patch.sh
@@ -192,11 +192,11 @@ preprocess_patch() {
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/\<\%('"${na_files}"'\)\>@norm! d/\v(^diff)|%$ ' +w +q "$file"
# Remove *.proto, Make*, INSTALL*, gui_*, beval.*, some if_*, gvim, libvterm, tee, VisVim, xpm, xxd
- local na_src='auto\|configure.*\|GvimExt\|libvterm\|proto\|tee\|VisVim\|xpm\|xxd\|Make.*\|INSTALL.*\|beval.*\|gui.*\|if_lua\|if_mzsch\|if_olepp\|if_ole\|if_perl\|if_py\|if_ruby\|if_tcl\|if_xcmdsrv'
+ local na_src='auto\|configure.*\|GvimExt\|libvterm\|proto\|tee\|VisVim\|xpm\|xxd\|Make.*\|INSTALL.*\|beval.*\|gui.*\|if_cscop\|if_lua\|if_mzsch\|if_olepp\|if_ole\|if_perl\|if_py\|if_ruby\|if_tcl\|if_xcmdsrv'
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/\S*\<\%(testdir/\)\@<!\%('"${na_src}"'\)\>@norm! d/\v(^diff)|%$ ' +w +q "$file"
# Remove unwanted Vim doc files.
- local na_doc='channel\.txt\|netbeans\.txt\|os_\w\+\.txt\|term\.txt\|todo\.txt\|version\d\.txt\|vim9\.txt\|sponsor\.txt\|intro\.txt\|tags'
+ local na_doc='channel\.txt\|if_cscop\.txt\|netbeans\.txt\|os_\w\+\.txt\|term\.txt\|todo\.txt\|version\d\.txt\|vim9\.txt\|sponsor\.txt\|intro\.txt\|tags'
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/runtime/doc/\<\%('"${na_doc}"'\)\>@norm! d/\v(^diff)|%$ ' +w +q "$file"
# Remove "Last change ..." changes in doc files.
@@ -207,7 +207,7 @@ preprocess_patch() {
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/testdir/\<\%('"${na_src_testdir}"'\)\>@norm! d/\v(^diff)|%$ ' +w +q "$file"
# Remove testdir/test_*.vim files
- local na_src_testdir='balloon.*\|channel.*\|crypt\.vim\|gui.*\|job_fails\.vim\|json\.vim\|mzscheme\.vim\|netbeans.*\|paste\.vim\|popupwin.*\|restricted\.vim\|shortpathname\.vim\|tcl\.vim\|terminal.*\|xxd\.vim'
+ local na_src_testdir='balloon.*\|channel.*\|crypt\.vim\|cscope\.vim\|gui.*\|job_fails\.vim\|json\.vim\|mzscheme\.vim\|netbeans.*\|paste\.vim\|popupwin.*\|restricted\.vim\|shortpathname\.vim\|tcl\.vim\|terminal.*\|xxd\.vim'
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/testdir/\<test_\%('"${na_src_testdir}"'\)\>@norm! d/\v(^diff)|%$ ' +w +q "$file"
# Remove version.c #7555
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c
index a29d022606..e728bd6967 100644
--- a/src/nvim/cmdexpand.c
+++ b/src/nvim/cmdexpand.c
@@ -22,7 +22,6 @@
#include "nvim/getchar.h"
#include "nvim/help.h"
#include "nvim/highlight_group.h"
-#include "nvim/if_cscope.h"
#include "nvim/locale.h"
#include "nvim/lua/executor.h"
#include "nvim/mapping.h"
@@ -1419,11 +1418,6 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, cons
case CMD_highlight:
set_context_in_highlight_cmd(xp, arg);
break;
- case CMD_cscope:
- case CMD_lcscope:
- case CMD_scscope:
- set_context_in_cscope_cmd(xp, arg, cmdidx);
- break;
case CMD_sign:
set_context_in_sign_cmd(xp, (char *)arg);
break;
@@ -2063,7 +2057,6 @@ static int ExpandOther(expand_T *xp, regmatch_T *rmp, int *num_file, char ***fil
{ EXPAND_HIGHLIGHT, (ExpandFunc)get_highlight_name, true, false },
{ EXPAND_EVENTS, expand_get_event_name, true, false },
{ EXPAND_AUGROUP, expand_get_augroup_name, true, false },
- { EXPAND_CSCOPE, get_cscope_name, true, true },
{ EXPAND_SIGN, get_sign_name, true, true },
{ EXPAND_PROFILE, get_profile_name, true, true },
#ifdef HAVE_WORKING_LIBINTL
@@ -2883,11 +2876,6 @@ void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
xpc.xp_pattern_len = strlen(xpc.xp_pattern);
}
- if (xpc.xp_context == EXPAND_CSCOPE) {
- set_context_in_cscope_cmd(&xpc, (const char *)xpc.xp_pattern, CMD_cscope);
- xpc.xp_pattern_len = strlen(xpc.xp_pattern);
- }
-
if (xpc.xp_context == EXPAND_SIGN) {
set_context_in_sign_cmd(&xpc, xpc.xp_pattern);
xpc.xp_pattern_len = strlen(xpc.xp_pattern);
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 837fef23f4..cc26bbf1a8 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -88,7 +88,6 @@ return {
cos={args=1, base=1, float_func="cos"},
cosh={args=1, base=1, float_func="cosh"},
count={args={2, 4}, base=1},
- cscope_connection={args={0, 3}},
ctxget={args={0, 1}},
ctxpop={},
ctxpush={args={0, 1}},
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index a326c44371..861f68993a 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -39,7 +39,6 @@
#include "nvim/getchar.h"
#include "nvim/globals.h"
#include "nvim/highlight_group.h"
-#include "nvim/if_cscope.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
#include "nvim/input.h"
@@ -1132,29 +1131,6 @@ static void f_count(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
rettv->vval.v_number = n;
}
-/// "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
-///
-/// Checks the existence of a cscope connection.
-static void f_cscope_connection(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
-{
- int num = 0;
- const char *dbpath = NULL;
- const char *prepend = NULL;
- char buf[NUMBUFLEN];
-
- if (argvars[0].v_type != VAR_UNKNOWN
- && argvars[1].v_type != VAR_UNKNOWN) {
- num = (int)tv_get_number(&argvars[0]);
- dbpath = tv_get_string(&argvars[1]);
- if (argvars[2].v_type != VAR_UNKNOWN) {
- prepend = tv_get_string_buf(&argvars[2], buf);
- }
- }
-
- rettv->vval.v_number = cs_connection(num, (char_u *)dbpath,
- (char_u *)prepend);
-}
-
/// "ctxget([{index}])" function
static void f_ctxget(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
@@ -3565,7 +3541,6 @@ static void f_has(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
"cmdwin",
"comments",
"conceal",
- "cscope",
"cursorbind",
"cursorshape",
#ifdef DEBUG
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index 04b8832428..e3eea884c4 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -673,18 +673,6 @@ module.cmds = {
func='ex_cc',
},
{
- command='cscope',
- flags=bit.bor(EXTRA, NOTRLCOM, XFILE),
- addr_type='ADDR_NONE',
- func='ex_cscope',
- },
- {
- command='cstag',
- flags=bit.bor(BANG, TRLBAR, WORD1),
- addr_type='ADDR_NONE',
- func='ex_cstag',
- },
- {
command='cunmap',
flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK),
addr_type='ADDR_NONE',
@@ -1405,12 +1393,6 @@ module.cmds = {
func='ex_cclose',
},
{
- command='lcscope',
- flags=bit.bor(EXTRA, NOTRLCOM, XFILE),
- addr_type='ADDR_NONE',
- func='ex_cscope',
- },
- {
command='ldo',
flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL),
addr_type='ADDR_QUICKFIX_VALID',
@@ -2422,12 +2404,6 @@ module.cmds = {
func='ex_scriptencoding',
},
{
- command='scscope',
- flags=bit.bor(EXTRA, NOTRLCOM),
- addr_type='ADDR_NONE',
- func='ex_scscope',
- },
- {
command='set',
flags=bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, LOCK_OK, SBOXOK),
addr_type='ADDR_NONE',
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 5591b5f55d..77d310e338 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -44,7 +44,6 @@
#include "nvim/hardcopy.h"
#include "nvim/help.h"
#include "nvim/highlight_group.h"
-#include "nvim/if_cscope.h"
#include "nvim/input.h"
#include "nvim/keycodes.h"
#include "nvim/locale.h"
@@ -6589,10 +6588,6 @@ static void ex_tag_cmd(exarg_T *eap, char *name)
cmd = DT_LAST; // ":tlast"
break;
default: // ":tag"
- if (p_cst && *eap->arg != NUL) {
- ex_cstag(eap);
- return;
- }
cmd = DT_TAG;
break;
}
diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua
index bf1adaeee3..4097ff7dc5 100755
--- a/src/nvim/generators/gen_declarations.lua
+++ b/src/nvim/generators/gen_declarations.lua
@@ -182,8 +182,7 @@ Additionally uses the following environment variables:
If set to 1 then all generated declarations receive a comment with file
name and line number after the declaration. This may be useful for
debugging gen_declarations script, but not much beyond that with
- configured development environment (i.e. with ctags/cscope/finding
- definitions with clang/etc).
+ configured development environment (i.e. with with clang/etc).
WARNING: setting this to 1 will cause extensive rebuilds: declarations
generator script will not regenerate non-static.h file if its
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c
deleted file mode 100644
index bc31d702f4..0000000000
--- a/src/nvim/if_cscope.c
+++ /dev/null
@@ -1,2027 +0,0 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
-// CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
-// Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
-//
-// The basic idea/structure of cscope for Vim was borrowed from Nvi. There
-// might be a few lines of code that look similar to what Nvi has.
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdbool.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "nvim/ascii.h"
-#include "nvim/autocmd.h"
-#include "nvim/buffer.h"
-#include "nvim/charset.h"
-#include "nvim/eval.h"
-#include "nvim/event/stream.h"
-#include "nvim/ex_eval.h"
-#include "nvim/fileio.h"
-#include "nvim/if_cscope.h"
-#include "nvim/memory.h"
-#include "nvim/message.h"
-#include "nvim/os/input.h"
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/path.h"
-#include "nvim/quickfix.h"
-#include "nvim/strings.h"
-#include "nvim/tag.h"
-#include "nvim/window.h"
-#if defined(UNIX)
-# include <sys/wait.h>
-#endif
-#include "nvim/if_cscope_defs.h"
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "if_cscope.c.generated.h"
-#endif
-
-static csinfo_T *csinfo = NULL;
-static size_t csinfo_size = 0; // number of items allocated in csinfo[]
-
-static int eap_arg_len; // length of eap->arg, set in cs_lookup_cmd()
-static cscmd_T cs_cmds[] =
-{
- { "add", cs_add,
- N_("Add a new database"), "add file|dir [pre-path] [flags]", 0 },
- { "find", cs_find,
- N_("Query for a pattern"), "find a|c|d|e|f|g|i|s|t name", 1 },
- { "help", cs_help,
- N_("Show this message"), "help", 0 },
- { "kill", cs_kill,
- N_("Kill a connection"), "kill #", 0 },
- { "reset", cs_reset,
- N_("Reinit all connections"), "reset", 0 },
- { "show", cs_show,
- N_("Show connections"), "show", 0 },
- { NULL, NULL, NULL, NULL, 0 }
-};
-
-static void cs_usage_msg(csid_e x)
-{
- (void)semsg(_("E560: Usage: cs[cope] %s"), cs_cmds[(int)x].usage);
-}
-
-static enum {
- EXP_CSCOPE_SUBCMD, // expand ":cscope" sub-commands
- EXP_SCSCOPE_SUBCMD, // expand ":scscope" sub-commands
- EXP_CSCOPE_FIND, // expand ":cscope find" arguments
- EXP_CSCOPE_KILL, // expand ":cscope kill" arguments
-} expand_what;
-
-// Function given to ExpandGeneric() to obtain the cscope command
-// expansion.
-char *get_cscope_name(expand_T *xp, int idx)
-{
- int current_idx;
-
- switch (expand_what) {
- case EXP_CSCOPE_SUBCMD:
- // Complete with sub-commands of ":cscope":
- // add, find, help, kill, reset, show
- return cs_cmds[idx].name;
- case EXP_SCSCOPE_SUBCMD: {
- // Complete with sub-commands of ":scscope": same sub-commands as
- // ":cscope" but skip commands which don't support split windows
- int i;
- for (i = 0, current_idx = 0; cs_cmds[i].name != NULL; i++) {
- if (cs_cmds[i].cansplit) {
- if (current_idx++ == idx) {
- break;
- }
- }
- }
- return cs_cmds[i].name;
- }
- case EXP_CSCOPE_FIND: {
- const char *query_type[] =
- {
- "a", "c", "d", "e", "f", "g", "i", "s", "t", NULL
- };
-
- // Complete with query type of ":cscope find {query_type}".
- // {query_type} can be letters (c, d, ... a) or numbers (0, 1,
- // ..., 9) but only complete with letters, since numbers are
- // redundant.
- return (char *)query_type[idx];
- }
- case EXP_CSCOPE_KILL: {
- static char connection[5];
-
- // ":cscope kill" accepts connection numbers or partial names of
- // the pathname of the cscope database as argument. Only complete
- // with connection numbers. -1 can also be used to kill all
- // connections.
- size_t i;
- for (i = 0, current_idx = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname == NULL) {
- continue;
- }
- if (current_idx++ == idx) {
- vim_snprintf(connection, sizeof(connection), "%zu", i);
- return connection;
- }
- }
- return (current_idx == idx && idx > 0) ? "-1" : NULL;
- }
- default:
- return NULL;
- }
-}
-
-// Handle command line completion for :cscope command.
-void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx)
-{
- // Default: expand subcommands.
- xp->xp_context = EXPAND_CSCOPE;
- xp->xp_pattern = (char *)arg;
- expand_what = ((cmdidx == CMD_scscope)
- ? EXP_SCSCOPE_SUBCMD : EXP_CSCOPE_SUBCMD);
-
- // (part of) subcommand already typed
- if (*arg != NUL) {
- const char *p = (const char *)skiptowhite(arg);
- if (*p != NUL) { // Past first word.
- xp->xp_pattern = skipwhite(p);
- if (*skiptowhite(xp->xp_pattern) != NUL) {
- xp->xp_context = EXPAND_NOTHING;
- } else if (STRNICMP(arg, "add", p - arg) == 0) {
- xp->xp_context = EXPAND_FILES;
- } else if (STRNICMP(arg, "kill", p - arg) == 0) {
- expand_what = EXP_CSCOPE_KILL;
- } else if (STRNICMP(arg, "find", p - arg) == 0) {
- expand_what = EXP_CSCOPE_FIND;
- } else {
- xp->xp_context = EXPAND_NOTHING;
- }
- }
- }
-}
-
-/// Find the command, print help if invalid, and then call the corresponding
-/// command function.
-///
-/// @param make_split whether to split window
-static void do_cscope_general(exarg_T *eap, int make_split)
-{
- cscmd_T *cmdp;
-
- if ((cmdp = cs_lookup_cmd(eap)) == NULL) {
- cs_help(eap);
- return;
- }
-
- if (make_split) {
- if (!cmdp->cansplit) {
- (void)msg_puts(_("This cscope command does not support splitting the window.\n"));
- return;
- }
- postponed_split = -1;
- postponed_split_flags = cmdmod.cmod_split;
- postponed_split_tab = cmdmod.cmod_tab;
- }
-
- cmdp->func(eap);
-
- postponed_split_flags = 0;
- postponed_split_tab = 0;
-}
-
-/// Implementation of ":cscope" and ":lcscope"
-void ex_cscope(exarg_T *eap)
-{
- do_cscope_general(eap, false);
-}
-
-/// Implementation of ":scscope". Same as ex_cscope(), but splits window, too.
-void ex_scscope(exarg_T *eap)
-{
- do_cscope_general(eap, true);
-}
-
-/// Implementation of ":cstag"
-void ex_cstag(exarg_T *eap)
-{
- int ret = false;
-
- if (*eap->arg == NUL) {
- (void)emsg(_("E562: Usage: cstag <ident>"));
- return;
- }
-
- switch (p_csto) {
- case 0:
- if (cs_check_for_connections()) {
- ret = cs_find_common("g", eap->arg, eap->forceit, false,
- false, (char_u *)(*eap->cmdlinep));
- if (ret == false) {
- cs_free_tags();
- if (msg_col) {
- msg_putchar('\n');
- }
-
- if (cs_check_for_tags()) {
- ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, false);
- }
- }
- } else if (cs_check_for_tags()) {
- ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, false);
- }
- break;
- case 1:
- if (cs_check_for_tags()) {
- ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, false);
- if (ret == false) {
- if (msg_col) {
- msg_putchar('\n');
- }
-
- if (cs_check_for_connections()) {
- ret = cs_find_common("g", eap->arg, eap->forceit,
- false, false, (char_u *)(*eap->cmdlinep));
- if (ret == false) {
- cs_free_tags();
- }
- }
- }
- } else if (cs_check_for_connections()) {
- ret = cs_find_common("g", eap->arg, eap->forceit, false,
- false, (char_u *)(*eap->cmdlinep));
- if (ret == false) {
- cs_free_tags();
- }
- }
- break;
- default:
- break;
- }
-
- if (!ret) {
- (void)emsg(_("E257: cstag: tag not found"));
- g_do_tagpreview = 0;
- }
-}
-
-/// This simulates a vim_fgets(), but for cscope, returns the next line
-/// from the cscope output. should only be called from find_tags()
-///
-/// @return true if eof, false otherwise
-bool cs_fgets(char_u *buf, int size)
- FUNC_ATTR_NONNULL_ALL
-{
- char *p;
-
- if ((p = cs_manage_matches(NULL, NULL, 0, Get)) == NULL) {
- return true;
- }
- STRLCPY(buf, p, size);
-
- return false;
-}
-
-/// Called only from do_tag(), when popping the tag stack.
-void cs_free_tags(void)
-{
- cs_manage_matches(NULL, NULL, 0, Free);
-}
-
-/// Called from do_tag().
-void cs_print_tags(void)
-{
- cs_manage_matches(NULL, NULL, 0, Print);
-}
-
-// "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
-//
-// Checks for the existence of a |cscope| connection. If no
-// parameters are specified, then the function returns:
-//
-// 0, if cscope was not available (not compiled in), or if there
-// are no cscope connections; or
-// 1, if there is at least one cscope connection.
-//
-// If parameters are specified, then the value of {num}
-// determines how existence of a cscope connection is checked:
-//
-// {num} Description of existence check
-// ----- ------------------------------
-// 0 Same as no parameters (e.g., "cscope_connection()").
-// 1 Ignore {prepend}, and use partial string matches for
-// {dbpath}.
-// 2 Ignore {prepend}, and use exact string matches for
-// {dbpath}.
-// 3 Use {prepend}, use partial string matches for both
-// {dbpath} and {prepend}.
-// 4 Use {prepend}, use exact string matches for both
-// {dbpath} and {prepend}.
-//
-// Note: All string comparisons are case sensitive!
-bool cs_connection(int num, char_u *dbpath, char_u *ppath)
-{
- if (num < 0 || num > 4 || (num > 0 && !dbpath)) {
- return false;
- }
-
- for (size_t i = 0; i < csinfo_size; i++) {
- if (!csinfo[i].fname) {
- continue;
- }
- if (num == 0) {
- return true;
- }
- switch (num) {
- case 1:
- if (strstr(csinfo[i].fname, (char *)dbpath)) {
- return true;
- }
- break;
- case 2:
- if (strcmp(csinfo[i].fname, (char *)dbpath) == 0) {
- return true;
- }
- break;
- case 3:
- if (strstr(csinfo[i].fname, (char *)dbpath)
- && ((!ppath && !csinfo[i].ppath)
- || (ppath
- && csinfo[i].ppath
- && strstr(csinfo[i].ppath, (char *)ppath)))) {
- return true;
- }
- break;
- case 4:
- if ((strcmp(csinfo[i].fname, (char *)dbpath) == 0)
- && ((!ppath && !csinfo[i].ppath)
- || (ppath
- && csinfo[i].ppath
- && (strcmp(csinfo[i].ppath, (char *)ppath) == 0)))) {
- return true;
- }
- break;
- }
- }
-
- return false;
-} // cs_connection
-
-// PRIVATE functions
-// **************************************************************************
-
-/// Add cscope database or a directory name (to look for cscope.out)
-/// to the cscope connection list.
-static int cs_add(exarg_T *eap)
-{
- char *fname, *ppath, *flags = NULL;
-
- if ((fname = strtok((char *)NULL, (const char *)" ")) == NULL) {
- cs_usage_msg(Add);
- return CSCOPE_FAILURE;
- }
- if ((ppath = strtok((char *)NULL, (const char *)" ")) != NULL) {
- flags = strtok((char *)NULL, (const char *)" ");
- }
-
- return cs_add_common(fname, ppath, flags);
-}
-
-static void cs_stat_emsg(char *fname)
-{
- int err = errno;
- (void)semsg(_("E563: stat(%s) error: %d"), fname, err);
-}
-
-/// The common routine to add a new cscope connection. Called by
-/// cs_add() and cs_reset(). I really don't like to do this, but this
-/// routine uses a number of goto statements.
-///
-/// @param arg1 filename - may contain environment variables
-/// @param arg2 prepend path - may contain environment variables
-static int cs_add_common(char *arg1, char *arg2, char *flags)
-{
- char *fname = NULL;
- char *fname2 = NULL;
- char *ppath = NULL;
- size_t usedlen = 0;
- char *fbuf = NULL;
-
- // get the filename (arg1), expand it, and try to stat it
- fname = xmalloc(MAXPATHL + 1);
-
- expand_env(arg1, fname, MAXPATHL);
- size_t len = strlen(fname);
- fbuf = fname;
- (void)modify_fname(":p", false, &usedlen, &fname, &fbuf, &len);
- if (fname == NULL) {
- goto add_err;
- }
- fname = xstrnsave(fname, len);
- xfree(fbuf);
- FileInfo file_info;
- bool file_info_ok = os_fileinfo(fname, &file_info);
- if (!file_info_ok) {
-staterr:
- if (p_csverbose) {
- cs_stat_emsg(fname);
- }
- goto add_err;
- }
-
- // get the prepend path (arg2), expand it, and see if it exists
- if (arg2 != NULL) {
- ppath = xmalloc(MAXPATHL + 1);
- expand_env(arg2, ppath, MAXPATHL);
- if (!os_path_exists(ppath)) {
- goto staterr;
- }
- }
-
- int i;
- // if filename is a directory, append the cscope database name to it
- if (S_ISDIR(file_info.stat.st_mode)) {
- fname2 = (char *)xmalloc(strlen(CSCOPE_DBFILE) + strlen(fname) + 2);
-
- while (fname[strlen(fname) - 1] == '/'
- ) {
- fname[strlen(fname) - 1] = '\0';
- if (fname[0] == '\0') {
- break;
- }
- }
- if (fname[0] == '\0') {
- (void)sprintf(fname2, "/%s", CSCOPE_DBFILE);
- } else {
- (void)sprintf(fname2, "%s/%s", fname, CSCOPE_DBFILE);
- }
-
- file_info_ok = os_fileinfo(fname2, &file_info);
- if (!file_info_ok) {
- if (p_csverbose) {
- cs_stat_emsg(fname2);
- }
- goto add_err;
- }
-
- i = cs_insert_filelist(fname2, ppath, flags, &file_info);
- } else if (S_ISREG(file_info.stat.st_mode) || S_ISLNK(file_info.stat.st_mode)) {
- i = cs_insert_filelist(fname, ppath, flags, &file_info);
- } else {
- if (p_csverbose) {
- (void)semsg(_("E564: %s is not a directory or a valid cscope database"),
- fname);
- }
- goto add_err;
- }
-
- if (i != -1) {
- assert(i >= 0);
- if (cs_create_connection((size_t)i) == CSCOPE_FAILURE
- || cs_read_prompt((size_t)i) == CSCOPE_FAILURE) {
- cs_release_csp((size_t)i, true);
- goto add_err;
- }
-
- if (p_csverbose) {
- msg_clr_eos();
- (void)smsg_attr(HL_ATTR(HLF_R),
- _("Added cscope database %s"),
- csinfo[i].fname);
- }
- }
-
- xfree(fname);
- xfree(fname2);
- xfree(ppath);
- return CSCOPE_SUCCESS;
-
-add_err:
- xfree(fname2);
- xfree(fname);
- xfree(ppath);
- return CSCOPE_FAILURE;
-}
-
-static bool cs_check_for_connections(void)
-{
- return cs_cnt_connections() > 0;
-}
-
-static int cs_check_for_tags(void)
-{
- return p_tags[0] != NUL && curbuf->b_p_tags != NULL;
-}
-
-/// Count the number of cscope connections.
-static size_t cs_cnt_connections(void)
-{
- size_t cnt = 0;
-
- for (size_t i = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname != NULL) {
- cnt++;
- }
- }
- return cnt;
-}
-
-/// @param idx connection index
-static void cs_reading_emsg(size_t idx)
-{
- semsg(_("E262: error reading cscope connection %" PRIu64), (uint64_t)idx);
-}
-
-#define CSREAD_BUFSIZE 2048
-/// Count the number of matches for a given cscope connection.
-static int cs_cnt_matches(size_t idx)
-{
- char *stok;
- int nlines = 0;
-
- char *buf = xmalloc(CSREAD_BUFSIZE);
- for (;;) {
- errno = 0;
- if (!fgets(buf, CSREAD_BUFSIZE, csinfo[idx].fr_fp)) {
- if (errno == EINTR) {
- continue;
- }
-
- if (feof(csinfo[idx].fr_fp)) {
- errno = EIO;
- }
-
- cs_reading_emsg(idx);
-
- xfree(buf);
- return CSCOPE_FAILURE;
- }
-
- // If the database is out of date, or there's some other problem,
- // cscope will output error messages before the number-of-lines output.
- // Display/discard any output that doesn't match what we want.
- // Accept "\S*cscope: X lines", also matches "mlcscope".
- // Bail out for the "Unable to search" error.
- if (strstr((const char *)buf, "Unable to search database") != NULL) {
- break;
- }
- if ((stok = strtok(buf, (const char *)" ")) == NULL) {
- continue;
- }
- if (strstr((const char *)stok, "cscope:") == NULL) {
- continue;
- }
-
- if ((stok = strtok(NULL, (const char *)" ")) == NULL) {
- continue;
- }
- nlines = atoi(stok);
- if (nlines < 0) {
- nlines = 0;
- break;
- }
-
- if ((stok = strtok(NULL, (const char *)" ")) == NULL) {
- continue;
- }
- if (strncmp(stok, "lines", 5)) {
- continue;
- }
-
- break;
- }
-
- xfree(buf);
- return nlines;
-}
-
-/// Creates the actual cscope command query from what the user entered.
-static char *cs_create_cmd(char *csoption, char *pattern)
-{
- char *cmd;
- short search;
- char *pat;
-
- switch (csoption[0]) {
- case '0':
- case 's':
- search = 0;
- break;
- case '1':
- case 'g':
- search = 1;
- break;
- case '2':
- case 'd':
- search = 2;
- break;
- case '3':
- case 'c':
- search = 3;
- break;
- case '4':
- case 't':
- search = 4;
- break;
- case '6':
- case 'e':
- search = 6;
- break;
- case '7':
- case 'f':
- search = 7;
- break;
- case '8':
- case 'i':
- search = 8;
- break;
- case '9':
- case 'a':
- search = 9;
- break;
- default:
- (void)emsg(_("E561: unknown cscope search type"));
- cs_usage_msg(Find);
- return NULL;
- }
-
- // Skip white space before the pattern, except for text and pattern search,
- // they may want to use the leading white space.
- pat = pattern;
- if (search != 4 && search != 6) {
- while (ascii_iswhite(*pat)) {
- pat++;
- }
- }
-
- cmd = xmalloc(strlen(pat) + 2);
-
- (void)sprintf(cmd, "%d%s", search, pat);
-
- return cmd;
-}
-
-/// This piece of code was taken/adapted from nvi. do we need to add
-/// the BSD license notice?
-static int cs_create_connection(size_t i)
-{
-#ifdef UNIX
- int to_cs[2], from_cs[2];
-#endif
- char *prog, *cmd, *ppath = NULL;
-
-#if defined(UNIX)
- // Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from
- // from_cs[0] and writes to to_cs[1].
- to_cs[0] = to_cs[1] = from_cs[0] = from_cs[1] = -1;
- if (pipe(to_cs) < 0 || pipe(from_cs) < 0) {
- (void)emsg(_("E566: Could not create cscope pipes"));
-err_closing:
- if (to_cs[0] != -1) {
- (void)close(to_cs[0]);
- }
- if (to_cs[1] != -1) {
- (void)close(to_cs[1]);
- }
- if (from_cs[0] != -1) {
- (void)close(from_cs[0]);
- }
- if (from_cs[1] != -1) {
- (void)close(from_cs[1]);
- }
- return CSCOPE_FAILURE;
- }
-
- switch (csinfo[i].pid = fork()) {
- case -1:
- (void)emsg(_("E622: Could not fork for cscope"));
- goto err_closing;
- case 0: // child: run cscope.
- if (dup2(to_cs[0], STDIN_FILENO) == -1) {
- PERROR("cs_create_connection 1");
- }
- if (dup2(from_cs[1], STDOUT_FILENO) == -1) {
- PERROR("cs_create_connection 2");
- }
- if (dup2(from_cs[1], STDERR_FILENO) == -1) {
- PERROR("cs_create_connection 3");
- }
-
- // close unused
- (void)close(to_cs[1]);
- (void)close(from_cs[0]);
-#else
- // Create pipes to communicate with cscope
- int fd;
- SECURITY_ATTRIBUTES sa;
- PROCESS_INFORMATION pi;
- BOOL pipe_stdin = FALSE, pipe_stdout = FALSE; // NOLINT(readability/bool)
- STARTUPINFO si;
- HANDLE stdin_rd, stdout_rd;
- HANDLE stdout_wr, stdin_wr;
- BOOL created;
-
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.bInheritHandle = TRUE;
- sa.lpSecurityDescriptor = NULL;
-
- if (!(pipe_stdin = CreatePipe(&stdin_rd, &stdin_wr, &sa, 0))
- || !(pipe_stdout = CreatePipe(&stdout_rd, &stdout_wr, &sa, 0))) {
- (void)emsg(_("E566: Could not create cscope pipes"));
-err_closing:
- if (pipe_stdin) {
- CloseHandle(stdin_rd);
- CloseHandle(stdin_wr);
- }
- if (pipe_stdout) {
- CloseHandle(stdout_rd);
- CloseHandle(stdout_wr);
- }
- return CSCOPE_FAILURE;
- }
-#endif
- // expand the cscope exec for env var's
- prog = xmalloc(MAXPATHL + 1);
- expand_env(p_csprg, prog, MAXPATHL);
-
- // alloc space to hold the cscope command
- size_t len = strlen(prog) + strlen(csinfo[i].fname) + 32;
- if (csinfo[i].ppath) {
- // expand the prepend path for env var's
- ppath = xmalloc(MAXPATHL + 1);
- expand_env(csinfo[i].ppath, ppath, MAXPATHL);
-
- len += strlen(ppath);
- }
-
- if (csinfo[i].flags) {
- len += strlen(csinfo[i].flags);
- }
-
- cmd = xmalloc(len);
-
- // run the cscope command; is there execl for non-unix systems?
-#if defined(UNIX)
- (void)snprintf(cmd, len, "exec %s -dl -f %s", prog, csinfo[i].fname);
-#else
- // MS-Windows
- (void)snprintf(cmd, len, "%s -dl -f %s", prog, csinfo[i].fname);
-#endif
- if (csinfo[i].ppath != NULL) {
- (void)strcat(cmd, " -P");
- (void)strcat(cmd, csinfo[i].ppath);
- }
- if (csinfo[i].flags != NULL) {
- (void)strcat(cmd, " ");
- (void)strcat(cmd, csinfo[i].flags);
- }
-#ifdef UNIX
- // on Win32 we still need prog
- xfree(prog);
-#endif
- xfree(ppath);
-
-#if defined(UNIX)
-# if defined(HAVE_SETSID) || defined(HAVE_SETPGID)
- // Change our process group to avoid cscope receiving SIGWINCH.
-# if defined(HAVE_SETSID)
- (void)setsid();
-# else
- if (setpgid(0, 0) == -1) {
- PERROR(_("cs_create_connection setpgid failed"));
- }
-# endif
-# endif
- if (execl("/bin/sh", "sh", "-c", cmd, (char *)NULL) == -1) {
- PERROR(_("cs_create_connection exec failed"));
- }
-
- exit(127);
- // NOTREACHED
- default: // parent.
- // Save the file descriptors for later duplication, and
- // reopen as streams.
- if ((csinfo[i].to_fp = fdopen(to_cs[1], "w")) == NULL) {
- PERROR(_("cs_create_connection: fdopen for to_fp failed"));
- }
- if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) {
- PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
- }
-
- // close unused
- (void)close(to_cs[0]);
- (void)close(from_cs[1]);
-
- break;
- }
-
-#else
- // MS-Windows
- // Create a new process to run cscope and use pipes to talk with it
- GetStartupInfo(&si);
- si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_HIDE; // Hide child application window
- si.hStdOutput = stdout_wr;
- si.hStdError = stdout_wr;
- si.hStdInput = stdin_rd;
- created = CreateProcess(NULL, cmd, NULL, NULL, true, CREATE_NEW_CONSOLE,
- NULL, NULL, &si, &pi);
- xfree(prog);
- xfree(cmd);
-
- if (!created) {
- PERROR(_("cs_create_connection exec failed"));
- (void)emsg(_("E623: Could not spawn cscope process"));
- goto err_closing;
- }
- // else
- csinfo[i].pid = pi.dwProcessId;
- csinfo[i].hProc = pi.hProcess;
- CloseHandle(pi.hThread);
-
- // TODO(neovim): tidy up after failure to create files on pipe handles.
- if (((fd = _open_osfhandle((intptr_t)stdin_wr, _O_TEXT|_O_APPEND)) < 0)
- || ((csinfo[i].to_fp = _fdopen(fd, "w")) == NULL)) {
- PERROR(_("cs_create_connection: fdopen for to_fp failed"));
- }
- if (((fd = _open_osfhandle((intptr_t)stdout_rd, _O_TEXT|_O_RDONLY)) < 0)
- || ((csinfo[i].fr_fp = _fdopen(fd, "r")) == NULL)) {
- PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
- }
- // Close handles for file descriptors inherited by the cscope process.
- CloseHandle(stdin_rd);
- CloseHandle(stdout_wr);
-
-#endif // !UNIX
-
- return CSCOPE_SUCCESS;
-}
-
-/// Query cscope using command line interface. Parse the output and use tselect
-/// to allow choices. Like Nvi, creates a pipe to send to/from query/cscope.
-///
-/// @return true if we jump to a tag or abort, false if not.
-static int cs_find(exarg_T *eap)
-{
- char *opt, *pat;
-
- if (cs_check_for_connections() == false) {
- (void)emsg(_("E567: no cscope connections"));
- return false;
- }
-
- if ((opt = strtok((char *)NULL, (const char *)" ")) == NULL) {
- cs_usage_msg(Find);
- return false;
- }
-
- pat = opt + strlen(opt) + 1;
- if (pat >= eap->arg + eap_arg_len) {
- cs_usage_msg(Find);
- return false;
- }
-
- // Let's replace the NULs written by strtok() with spaces - we need the
- // spaces to correctly display the quickfix/location list window's title.
- for (int i = 0; i < eap_arg_len; i++) {
- if (NUL == eap->arg[i]) {
- eap->arg[i] = ' ';
- }
- }
-
- return cs_find_common(opt, pat, eap->forceit, true,
- eap->cmdidx == CMD_lcscope, (char_u *)(*eap->cmdlinep));
-}
-
-/// Common code for cscope find, shared by cs_find() and ex_cstag().
-static bool cs_find_common(char *opt, char *pat, int forceit, int verbose, bool use_ll,
- char_u *cmdline)
-{
- char *cmd;
- int *nummatches;
- size_t totmatches;
- char cmdletter;
- char *qfpos;
-
- // get cmd letter
- switch (opt[0]) {
- case '0':
- cmdletter = 's';
- break;
- case '1':
- cmdletter = 'g';
- break;
- case '2':
- cmdletter = 'd';
- break;
- case '3':
- cmdletter = 'c';
- break;
- case '4':
- cmdletter = 't';
- break;
- case '6':
- cmdletter = 'e';
- break;
- case '7':
- cmdletter = 'f';
- break;
- case '8':
- cmdletter = 'i';
- break;
- case '9':
- cmdletter = 'a';
- break;
- default:
- cmdletter = opt[0];
- }
-
- qfpos = vim_strchr(p_csqf, cmdletter);
- if (qfpos != NULL) {
- qfpos++;
- // next symbol must be + or -
- if (strchr(CSQF_FLAGS, *qfpos) == NULL) {
- (void)semsg(_("E469: invalid cscopequickfix flag %c for %c"), *qfpos, *(qfpos - 1));
- return false;
- }
-
- if (*qfpos != '0'
- && apply_autocmds(EVENT_QUICKFIXCMDPRE, "cscope", curbuf->b_fname, true, curbuf)) {
- if (aborting()) {
- return false;
- }
- }
- }
-
- // create the actual command to send to cscope
- cmd = cs_create_cmd(opt, pat);
- if (cmd == NULL) {
- return false;
- }
-
- nummatches = xmalloc(sizeof(int) * csinfo_size);
-
- // Send query to all open connections, then count the total number
- // of matches so we can alloc all in one swell foop.
- for (size_t i = 0; i < csinfo_size; i++) {
- nummatches[i] = 0;
- }
- totmatches = 0;
- for (size_t i = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL) {
- continue;
- }
-
- // send cmd to cscope
- (void)fprintf(csinfo[i].to_fp, "%s\n", cmd);
- (void)fflush(csinfo[i].to_fp);
-
- nummatches[i] = cs_cnt_matches(i);
-
- if (nummatches[i] > -1) {
- totmatches += (size_t)nummatches[i];
- }
-
- if (nummatches[i] == 0) {
- (void)cs_read_prompt(i);
- }
- }
- xfree(cmd);
-
- if (totmatches == 0) {
- if (verbose) {
- (void)semsg(_("E259: no matches found for cscope query %s of %s"), opt, pat);
- }
- xfree(nummatches);
- return false;
- }
-
- if (qfpos != NULL && *qfpos != '0') {
- // Fill error list.
- FILE *f;
- char_u *tmp = (char_u *)vim_tempname();
- qf_info_T *qi = NULL;
- win_T *wp = NULL;
-
- f = os_fopen((char *)tmp, "w");
- if (f == NULL) {
- semsg(_(e_notopen), tmp);
- } else {
- cs_file_results(f, nummatches);
- fclose(f);
- if (use_ll) { // Use location list
- wp = curwin;
- }
- // '-' starts a new error list
- if (qf_init(wp, (char *)tmp, "%f%*\\t%l%*\\t%m",
- *qfpos == '-', (char *)cmdline, NULL) > 0) {
- if (postponed_split != 0) {
- (void)win_split(postponed_split > 0 ? postponed_split : 0,
- postponed_split_flags);
- RESET_BINDING(curwin);
- postponed_split = 0;
- }
-
- apply_autocmds(EVENT_QUICKFIXCMDPOST, "cscope", curbuf->b_fname, true, curbuf);
- if (use_ll) {
- // In the location list window, use the displayed location
- // list. Otherwise, use the location list for the window.
- qi = (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)
- ? wp->w_llist_ref : wp->w_llist;
- }
- qf_jump(qi, 0, 0, forceit);
- }
- }
- os_remove((char *)tmp);
- xfree(tmp);
- xfree(nummatches);
- return true;
- } else {
- char **matches = NULL, **contexts = NULL;
- size_t matched = 0;
-
- // read output
- cs_fill_results(pat, totmatches, nummatches, &matches, &contexts, &matched);
- xfree(nummatches);
- if (matches == NULL) {
- return false;
- }
-
- (void)cs_manage_matches(matches, contexts, matched, Store);
-
- return do_tag(pat, DT_CSCOPE, 0, forceit, verbose);
- }
-}
-
-/// Print help.
-static int cs_help(exarg_T *eap)
-{
- cscmd_T *cmdp = cs_cmds;
-
- (void)msg_puts(_("cscope commands:\n"));
- while (cmdp->name != NULL) {
- char *help = _(cmdp->help);
- int space_cnt = 30 - vim_strsize(help);
-
- // Use %*s rather than %30s to ensure proper alignment in utf-8
- if (space_cnt < 0) {
- space_cnt = 0;
- }
- (void)smsg(_("%-5s: %s%*s (Usage: %s)"),
- cmdp->name,
- help, space_cnt, " ",
- cmdp->usage);
- if (strcmp(cmdp->name, "find") == 0) {
- msg_puts(_("\n"
- " a: Find assignments to this symbol\n"
- " c: Find functions calling this function\n"
- " d: Find functions called by this function\n"
- " e: Find this egrep pattern\n"
- " f: Find this file\n"
- " g: Find this definition\n"
- " i: Find files #including this file\n"
- " s: Find this C symbol\n"
- " t: Find this text string\n"));
- }
-
- cmdp++;
- }
-
- wait_return(true);
- return CSCOPE_SUCCESS;
-}
-
-static void clear_csinfo(size_t i)
-{
- csinfo[i].fname = NULL;
- csinfo[i].ppath = NULL;
- csinfo[i].flags = NULL;
- csinfo[i].file_id = FILE_ID_EMPTY;
- csinfo[i].pid = 0;
- csinfo[i].fr_fp = NULL;
- csinfo[i].to_fp = NULL;
-}
-
-/// Insert a new cscope database filename into the filelist.
-static int cs_insert_filelist(char *fname, char *ppath, char *flags, FileInfo *file_info)
-{
- size_t i = 0;
- bool empty_found = false;
-
- for (size_t j = 0; j < csinfo_size; j++) {
- if (csinfo[j].fname != NULL
- && os_fileid_equal_fileinfo(&(csinfo[j].file_id), file_info)) {
- if (p_csverbose) {
- (void)emsg(_("E568: duplicate cscope database not added"));
- }
- return CSCOPE_FAILURE;
- }
-
- if (csinfo[j].fname == NULL && !empty_found) {
- i = j; // remember first empty entry
- empty_found = true;
- }
- }
-
- if (!empty_found) {
- i = csinfo_size;
- if (csinfo_size == 0) {
- // First time allocation: allocate only 1 connection. It should
- // be enough for most users. If more is needed, csinfo will be
- // reallocated.
- csinfo_size = 1;
- csinfo = xcalloc(1, sizeof(csinfo_T));
- } else {
- // Reallocate space for more connections.
- csinfo_size *= 2;
- csinfo = xrealloc(csinfo, sizeof(csinfo_T)*csinfo_size);
- }
- for (size_t j = csinfo_size/2; j < csinfo_size; j++) {
- clear_csinfo(j);
- }
- }
-
- csinfo[i].fname = xmalloc(strlen(fname) + 1);
-
- (void)strcpy(csinfo[i].fname, (const char *)fname);
-
- if (ppath != NULL) {
- csinfo[i].ppath = xmalloc(strlen(ppath) + 1);
- (void)strcpy(csinfo[i].ppath, (const char *)ppath);
- } else {
- csinfo[i].ppath = NULL;
- }
-
- if (flags != NULL) {
- csinfo[i].flags = xmalloc(strlen(flags) + 1);
- (void)strcpy(csinfo[i].flags, (const char *)flags);
- } else {
- csinfo[i].flags = NULL;
- }
-
- os_fileinfo_id(file_info, &(csinfo[i].file_id));
- assert(i <= INT_MAX);
- return (int)i;
-}
-
-/// Find cscope command in command table.
-static cscmd_T *cs_lookup_cmd(exarg_T *eap)
-{
- cscmd_T *cmdp;
- char *stok;
- size_t len;
-
- if (eap->arg == NULL) {
- return NULL;
- }
-
- // Store length of eap->arg before it gets modified by strtok().
- eap_arg_len = (int)strlen(eap->arg);
-
- if ((stok = strtok(eap->arg, (const char *)" ")) == NULL) { // NOLINT(runtime/threadsafe_fn)
- return NULL;
- }
-
- len = strlen(stok);
- for (cmdp = cs_cmds; cmdp->name != NULL; cmdp++) {
- if (strncmp(stok, cmdp->name, len) == 0) {
- return cmdp;
- }
- }
- return NULL;
-}
-
-/// Nuke em.
-static int cs_kill(exarg_T *eap)
-{
- char *stok;
- int num;
- size_t i = 0;
- bool killall = false;
-
- if ((stok = strtok((char *)NULL, (const char *)" ")) == NULL) {
- cs_usage_msg(Kill);
- return CSCOPE_FAILURE;
- }
-
- // Check if string is a number, only single digit
- // positive and negative integers are allowed
- if ((strlen(stok) < 2 && ascii_isdigit((int)(stok[0])))
- || (strlen(stok) < 3 && stok[0] == '-'
- && ascii_isdigit((int)(stok[1])))) {
- num = atoi(stok);
- if (num == -1) {
- killall = true;
- } else if (num >= 0) {
- i = (size_t)num;
- } else { // All negative values besides -1 are invalid.
- if (p_csverbose) {
- (void)semsg(_("E261: cscope connection %s not found"), stok);
- }
- return CSCOPE_FAILURE;
- }
- } else {
- // Else it must be part of a name. We will try to find a match
- // within all the names in the csinfo data structure
- for (i = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname != NULL && strstr(csinfo[i].fname, stok)) {
- break;
- }
- }
- }
-
- if (!killall && (i >= csinfo_size || csinfo[i].fname == NULL)) {
- if (p_csverbose) {
- (void)semsg(_("E261: cscope connection %s not found"), stok);
- }
- return CSCOPE_FAILURE;
- } else {
- if (killall) {
- for (i = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname) {
- cs_kill_execute(i, csinfo[i].fname);
- }
- }
- } else {
- cs_kill_execute(i, stok);
- }
- }
-
- return CSCOPE_SUCCESS;
-}
-
-/// Actually kills a specific cscope connection.
-///
-/// @param i cscope table index
-/// @param cname cscope database name
-static void cs_kill_execute(size_t i, char *cname)
-{
- if (p_csverbose) {
- msg_clr_eos();
- (void)smsg_attr(HL_ATTR(HLF_R) | MSG_HIST,
- _("cscope connection %s closed"), cname);
- }
- cs_release_csp(i, true);
-}
-
-/// Convert the cscope output into a ctags style entry (as might be found
-/// in a ctags tags file). there's one catch though: cscope doesn't tell you
-/// the type of the tag you are looking for. for example, in Darren Hiebert's
-/// ctags (the one that comes with vim), #define's use a line number to find the
-/// tag in a file while function definitions use a regexp search pattern.
-///
-/// I'm going to always use the line number because cscope does something
-/// quirky (and probably other things i don't know about):
-///
-/// if you have "# define" in your source file, which is
-/// perfectly legal, cscope thinks you have "#define". this
-/// will result in a failed regexp search. :(
-///
-/// Besides, even if this particular case didn't happen, the search pattern
-/// would still have to be modified to escape all the special regular expression
-/// characters to comply with ctags formatting.
-static char *cs_make_vim_style_matches(char *fname, char *slno, char *search, char *tagstr)
-{
- // vim style is ctags:
- //
- // <tagstr>\t<filename>\t<linenum_or_search>"\t<extra>
- //
- // but as mentioned above, we'll always use the line number and
- // put the search pattern (if one exists) as "extra"
- //
- // buf is used as part of vim's method of handling tags, and
- // (i think) vim frees it when you pop your tags and get replaced
- // by new ones on the tag stack.
- char *buf;
- size_t amt;
-
- if (search != NULL) {
- amt = strlen(fname) + strlen(slno) + strlen(tagstr) + strlen(search) + 6;
- buf = xmalloc(amt);
-
- (void)sprintf(buf, "%s\t%s\t%s;\"\t%s", tagstr, fname, slno, search);
- } else {
- amt = strlen(fname) + strlen(slno) + strlen(tagstr) + 5;
- buf = xmalloc(amt);
-
- (void)sprintf(buf, "%s\t%s\t%s;\"", tagstr, fname, slno);
- }
-
- return buf;
-}
-
-/// This is kind of hokey, but i don't see an easy way round this.
-///
-/// Store: keep a ptr to the (malloc'd) memory of matches originally
-/// generated from cs_find(). the matches are originally lines directly
-/// from cscope output, but transformed to look like something out of a
-/// ctags. see cs_make_vim_style_matches for more details.
-///
-/// Get: used only from cs_fgets(), this simulates a vim_fgets() to return
-/// the next line from the cscope output. it basically keeps track of which
-/// lines have been "used" and returns the next one.
-///
-/// Free: frees up everything and resets
-///
-/// Print: prints the tags
-static char *cs_manage_matches(char **matches, char **contexts, size_t totmatches, mcmd_e cmd)
-{
- static char **mp = NULL;
- static char **cp = NULL;
- static size_t cnt = 0;
- static size_t next = 0;
- char *p = NULL;
-
- switch (cmd) {
- case Store:
- assert(matches != NULL);
- assert(totmatches > 0);
- if (mp != NULL || cp != NULL) {
- (void)cs_manage_matches(NULL, NULL, 0, Free);
- }
- mp = matches;
- cp = contexts;
- cnt = totmatches;
- next = 0;
- break;
- case Get:
- if (next >= cnt) {
- return NULL;
- }
-
- p = mp[next];
- next++;
- break;
- case Free:
- if (mp != NULL) {
- while (cnt--) {
- xfree(mp[cnt]);
- if (cp != NULL) {
- xfree(cp[cnt]);
- }
- }
- xfree(mp);
- xfree(cp);
- }
- mp = NULL;
- cp = NULL;
- cnt = 0;
- next = 0;
- break;
- case Print:
- assert(mp != NULL);
- assert(cp != NULL);
- cs_print_tags_priv(mp, cp, cnt);
- break;
- default: // should not reach here
- iemsg(_("E570: fatal error in cs_manage_matches"));
- return NULL;
- }
-
- return p;
-}
-
-/// Parse cscope output.
-static char *cs_parse_results(size_t cnumber, char *buf, int bufsize, char **context,
- char **linenumber, char **search)
-{
- int ch;
- char *p;
- char *name;
-
-retry:
- errno = 0;
- if (fgets(buf, bufsize, csinfo[cnumber].fr_fp) == NULL) {
- if (errno == EINTR) {
- goto retry;
- }
-
- if (feof(csinfo[cnumber].fr_fp)) {
- errno = EIO;
- }
-
- cs_reading_emsg(cnumber);
-
- return NULL;
- }
-
- // If the line's too long for the buffer, discard it.
- if ((p = strchr(buf, '\n')) == NULL) {
- while ((ch = getc(csinfo[cnumber].fr_fp)) != EOF && ch != '\n') {}
- return NULL;
- }
- *p = '\0';
-
- // cscope output is in the following format:
- //
- // <filename> <context> <line number> <pattern>
- char *saveptr = NULL;
- if ((name = os_strtok(buf, (const char *)" ", &saveptr)) == NULL) {
- return NULL;
- }
- if ((*context = os_strtok(NULL, (const char *)" ", &saveptr)) == NULL) {
- return NULL;
- }
- if ((*linenumber = os_strtok(NULL, (const char *)" ", &saveptr)) == NULL) {
- return NULL;
- }
- *search = *linenumber + strlen(*linenumber) + 1; // +1 to skip \0
-
- // --- nvi ---
- // If the file is older than the cscope database, that is,
- // the database was built since the file was last modified,
- // or there wasn't a search string, use the line number.
- if (strcmp(*search, "<unknown>") == 0) {
- *search = NULL;
- }
-
- name = cs_resolve_file(cnumber, name);
- return name;
-}
-
-/// Write cscope find results to file.
-static void cs_file_results(FILE *f, int *nummatches_a)
-{
- char *search, *slno;
- char *fullname;
- char *cntx;
- char *context;
-
- char *buf = xmalloc(CSREAD_BUFSIZE);
-
- for (size_t i = 0; i < csinfo_size; i++) {
- if (nummatches_a[i] < 1) {
- continue;
- }
-
- for (int j = 0; j < nummatches_a[i]; j++) {
- if ((fullname = cs_parse_results(i, buf, CSREAD_BUFSIZE, &cntx,
- &slno, &search)) == NULL) {
- continue;
- }
-
- size_t context_len = strlen(cntx) + 5;
- context = xmalloc(context_len);
-
- if (strcmp(cntx, "<global>") == 0) {
- xstrlcpy(context, "<<global>>", context_len);
- } else {
- snprintf(context, context_len, "<<%s>>", cntx);
- }
-
- if (search == NULL) {
- fprintf(f, "%s\t%s\t%s\n", fullname, slno, context);
- } else {
- fprintf(f, "%s\t%s\t%s %s\n", fullname, slno, context, search);
- }
-
- xfree(context);
- xfree(fullname);
- } // for all matches
-
- (void)cs_read_prompt(i);
- } // for all cscope connections
- xfree(buf);
-}
-
-/// Get parsed cscope output and calls cs_make_vim_style_matches to convert
-/// into ctags format.
-/// When there are no matches sets "*matches_p" to NULL.
-static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a, char ***matches_p,
- char ***cntxts_p, size_t *matched)
-{
- char *buf;
- char *search, *slno;
- size_t totsofar = 0;
- char **matches = NULL;
- char **cntxts = NULL;
- char *fullname;
- char *cntx;
-
- assert(totmatches > 0);
-
- buf = xmalloc(CSREAD_BUFSIZE);
- matches = xmalloc(sizeof(char *) * totmatches);
- cntxts = xmalloc(sizeof(char *) * totmatches);
-
- for (size_t i = 0; i < csinfo_size; i++) {
- if (nummatches_a[i] < 1) {
- continue;
- }
-
- for (int j = 0; j < nummatches_a[i]; j++) {
- if ((fullname = cs_parse_results(i, buf, CSREAD_BUFSIZE, &cntx,
- &slno, &search)) == NULL) {
- continue;
- }
-
- matches[totsofar] = cs_make_vim_style_matches(fullname, slno, search,
- tagstr);
-
- xfree(fullname);
-
- if (strcmp(cntx, "<global>") == 0) {
- cntxts[totsofar] = NULL;
- } else {
- cntxts[totsofar] = xstrdup(cntx);
- }
-
- totsofar++;
- } // for all matches
-
- (void)cs_read_prompt(i);
- } // for all cscope connections
-
- if (totsofar == 0) {
- // No matches, free the arrays and return NULL in "*matches_p".
- XFREE_CLEAR(matches);
- XFREE_CLEAR(cntxts);
- }
- *matched = totsofar;
- *matches_p = matches;
- *cntxts_p = cntxts;
-
- xfree(buf);
-}
-
-// get the requested path components
-static char *cs_pathcomponents(char *path)
-{
- if (p_cspc == 0) {
- return path;
- }
-
- char *s = path + strlen(path) - 1;
- for (int i = 0; i < p_cspc; i++) {
- while (s > path && *--s != '/') {}
- }
- if ((s > path && *s == '/')) {
- s++;
- }
- return s;
-}
-
-/// Print cscope output that was converted into ctags style entries.
-///
-/// Only called from cs_manage_matches().
-///
-/// @param matches Array of cscope lines in ctags style. Every entry was
-// produced with a format string of the form
-// "%s\t%s\t%s;\"\t%s" or
-// "%s\t%s\t%s;\""
-// by cs_make_vim_style_matches().
-/// @param cntxts Context for matches.
-/// @param num_matches Number of entries in matches/cntxts, always greater 0.
-static void cs_print_tags_priv(char **matches, char **cntxts,
- size_t num_matches) FUNC_ATTR_NONNULL_ALL
-{
- char *globalcntx = "GLOBAL";
- char *cstag_msg = _("Cscope tag: %s");
-
- assert(num_matches > 0);
- assert(strcnt(matches[0], '\t') >= 2);
-
- char *ptag = matches[0];
- char *ptag_end = strchr(ptag, '\t');
- assert(ptag_end >= ptag);
- // NUL terminate tag string in matches[0].
- *ptag_end = NUL;
-
- // The "%s" in cstag_msg won't appear in the result string, so we don't need
- // extra memory for terminating NUL.
- size_t newsize = strlen(cstag_msg) + (size_t)(ptag_end - ptag);
- char *buf = xmalloc(newsize);
- size_t bufsize = newsize; // Track available bufsize
- (void)snprintf(buf, bufsize, cstag_msg, ptag);
- msg_puts_attr(buf, HL_ATTR(HLF_T));
- msg_clr_eos();
-
- // restore matches[0]
- *ptag_end = '\t';
-
- // Column headers for match number, line number and filename.
- msg_puts_attr(_("\n # line"), HL_ATTR(HLF_T));
- msg_advance(msg_col + 2);
- msg_puts_attr(_("filename / context / line\n"), HL_ATTR(HLF_T));
-
- for (size_t i = 0; i < num_matches; i++) {
- assert(strcnt(matches[i], '\t') >= 2);
-
- // Parse filename, line number and optional part.
- char *fname = strchr(matches[i], '\t') + 1;
- char *fname_end = strchr(fname, '\t');
- // Replace second '\t' in matches[i] with NUL to terminate fname.
- *fname_end = NUL;
-
- char *lno = fname_end + 1;
- char *extra = xstrchrnul(lno, '\t');
- // Ignore ;" at the end of lno.
- char *lno_end = extra - 2;
- *lno_end = NUL;
- // Do we have an optional part?
- extra = *extra ? extra + 1 : NULL;
-
- const char *csfmt_str = "%4zu %6s ";
- // hopefully num_matches will be less than 10^16
- newsize = strlen(csfmt_str) + 16 + (size_t)(lno_end - lno);
- if (bufsize < newsize) {
- buf = xrealloc(buf, newsize);
- bufsize = newsize;
- }
- (void)snprintf(buf, bufsize, csfmt_str, i + 1, lno);
- msg_puts_attr(buf, HL_ATTR(HLF_CM));
- msg_outtrans_long_attr(cs_pathcomponents(fname), HL_ATTR(HLF_CM));
-
- // compute the required space for the context
- char *context = cntxts[i] ? cntxts[i] : globalcntx;
-
- const char *cntxformat = " <<%s>>";
- // '%s' won't appear in result string, so:
- // newsize = len(cntxformat) - 2 + len(context) + 1 (for NUL).
- newsize = strlen(context) + strlen(cntxformat) - 1;
-
- if (bufsize < newsize) {
- buf = xrealloc(buf, newsize);
- bufsize = newsize;
- }
- int buf_len = snprintf(buf, bufsize, cntxformat, context);
- assert(buf_len >= 0);
-
- // Print the context only if it fits on the same line.
- if (msg_col + buf_len >= Columns) {
- msg_putchar('\n');
- }
- msg_advance(12);
- msg_outtrans_long_attr(buf, 0);
- msg_putchar('\n');
- if (extra != NULL) {
- msg_advance(13);
- msg_outtrans_long_attr(extra, 0);
- }
-
- // restore matches[i]
- *fname_end = '\t';
- *lno_end = ';';
-
- if (msg_col) {
- msg_putchar('\n');
- }
-
- os_breakcheck();
- if (got_int) {
- got_int = false; // don't print any more matches
- break;
- }
- }
-
- xfree(buf);
-}
-
-/// Read a cscope prompt (basically, skip over the ">> ").
-static int cs_read_prompt(size_t i)
-{
- int ch;
- char *buf = NULL; // buffer for possible error message from cscope
- size_t bufpos = 0;
- char *cs_emsg = _("E609: Cscope error: %s");
- size_t cs_emsg_len = strlen(cs_emsg);
- static char *eprompt = "Press the RETURN key to continue:";
- size_t epromptlen = strlen(eprompt);
-
- // compute maximum allowed len for Cscope error message
- assert(IOSIZE >= cs_emsg_len);
- size_t maxlen = IOSIZE - cs_emsg_len;
-
- while (1) {
- while (1) {
- do {
- errno = 0;
- ch = fgetc(csinfo[i].fr_fp);
- } while (ch == EOF && errno == EINTR && ferror(csinfo[i].fr_fp));
- if (ch == EOF || ch == CSCOPE_PROMPT[0]) {
- break;
- }
- // if there is room and char is printable
- if (bufpos < maxlen - 1 && vim_isprintc(ch)) {
- // lazy buffer allocation
- if (buf == NULL) {
- buf = xmalloc(maxlen);
- }
- // append character to the message
- buf[bufpos++] = (char)ch;
- buf[bufpos] = NUL;
- if (bufpos >= epromptlen
- && strcmp(&buf[bufpos - epromptlen], eprompt) == 0) {
- // remove eprompt from buf
- buf[bufpos - epromptlen] = NUL;
-
- // print message to user
- (void)semsg(cs_emsg, buf);
-
- // send RETURN to cscope
- (void)putc('\n', csinfo[i].to_fp);
- (void)fflush(csinfo[i].to_fp);
-
- // clear buf
- bufpos = 0;
- buf[bufpos] = NUL;
- }
- }
- }
-
- for (size_t n = 0; n < strlen(CSCOPE_PROMPT); n++) {
- if (n > 0) {
- do {
- errno = 0;
- ch = fgetc(csinfo[i].fr_fp);
- } while (ch == EOF && errno == EINTR && ferror(csinfo[i].fr_fp));
- }
- if (ch == EOF) {
- PERROR("cs_read_prompt EOF");
- if (buf != NULL && buf[0] != NUL) {
- (void)semsg(cs_emsg, buf);
- } else if (p_csverbose) {
- cs_reading_emsg(i); // don't have additional information
- }
- cs_release_csp(i, true);
- xfree(buf);
- return CSCOPE_FAILURE;
- }
-
- if (ch != CSCOPE_PROMPT[n]) {
- ch = EOF;
- break;
- }
- }
-
- if (ch == EOF) {
- continue; // didn't find the prompt
- }
- break; // did find the prompt
- }
-
- xfree(buf);
- return CSCOPE_SUCCESS;
-}
-
-#if defined(UNIX) && defined(SIGALRM)
-// Used to catch and ignore SIGALRM below.
-static void sig_handler(int s)
-{
- // do nothing
-}
-
-#endif
-
-/// Does the actual free'ing for the cs ptr with an optional flag of whether
-/// or not to free the filename. Called by cs_kill and cs_reset.
-static void cs_release_csp(size_t i, bool freefnpp)
-{
- // Trying to exit normally (not sure whether it is fit to Unix cscope)
- if (csinfo[i].to_fp != NULL) {
- (void)fputs("q\n", csinfo[i].to_fp);
- (void)fflush(csinfo[i].to_fp);
- }
-#if defined(UNIX)
- {
- int waitpid_errno;
- int pstat;
- pid_t pid;
-
-# if defined(HAVE_SIGACTION)
- struct sigaction sa, old;
-
- // Use sigaction() to limit the waiting time to two seconds.
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = sig_handler;
-# ifdef SA_NODEFER
- sa.sa_flags = SA_NODEFER;
-# else
- sa.sa_flags = 0;
-# endif
- sigaction(SIGALRM, &sa, &old);
- alarm(2); // 2 sec timeout
-
- // Block until cscope exits or until timer expires
- pid = waitpid(csinfo[i].pid, &pstat, 0);
- waitpid_errno = errno;
-
- // cancel pending alarm if still there and restore signal
- alarm(0);
- sigaction(SIGALRM, &old, NULL);
-# else
- int waited;
-
- // Can't use sigaction(), loop for two seconds. First yield the CPU
- // to give cscope a chance to exit quickly.
- sleep(0);
- for (waited = 0; waited < 40; waited++) {
- pid = waitpid(csinfo[i].pid, &pstat, WNOHANG);
- waitpid_errno = errno;
- if (pid != 0) {
- break; // break unless the process is still running
- }
- os_delay(50L, false); // sleep 50 ms
- }
-# endif
- // If the cscope process is still running: kill it.
- // Safety check: If the PID would be zero here, the entire X session
- // would be killed. -1 and 1 are dangerous as well.
- if (pid < 0 && csinfo[i].pid > 1) {
-# ifdef ECHILD
- bool alive = true;
-
- if (waitpid_errno == ECHILD) {
- // When using 'vim -g', vim is forked and cscope process is
- // no longer a child process but a sibling. So waitpid()
- // fails with errno being ECHILD (No child processes).
- // Don't send SIGKILL to cscope immediately but wait
- // (polling) for it to exit normally as result of sending
- // the "q" command, hence giving it a chance to clean up
- // its temporary files.
- int waited;
-
- sleep(0);
- for (waited = 0; waited < 40; waited++) {
- // Check whether cscope process is still alive
- if (kill(csinfo[i].pid, 0) != 0) {
- alive = false; // cscope process no longer exists
- break;
- }
- os_delay(50L, false); // sleep 50 ms
- }
- }
- if (alive)
-# endif
- {
- kill(csinfo[i].pid, SIGKILL);
- (void)waitpid(csinfo[i].pid, &pstat, 0);
- }
- }
- }
-#else // !UNIX
- if (csinfo[i].hProc != NULL) {
- // Give cscope a chance to exit normally
- if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) {
- TerminateProcess(csinfo[i].hProc, 0);
- }
- CloseHandle(csinfo[i].hProc);
- }
-#endif
-
- if (csinfo[i].fr_fp != NULL) {
- (void)fclose(csinfo[i].fr_fp);
- }
- if (csinfo[i].to_fp != NULL) {
- (void)fclose(csinfo[i].to_fp);
- }
-
- if (freefnpp) {
- xfree(csinfo[i].fname);
- xfree(csinfo[i].ppath);
- xfree(csinfo[i].flags);
- }
-
- clear_csinfo(i);
-}
-
-/// Calls cs_kill on all cscope connections then reinits.
-static int cs_reset(exarg_T *eap)
-{
- char **dblist = NULL, **pplist = NULL, **fllist = NULL;
- char buf[25]; // for snprintf " (#%zu)"
-
- if (csinfo_size == 0) {
- return CSCOPE_SUCCESS;
- }
-
- // malloc our db and ppath list
- dblist = xmalloc(csinfo_size * sizeof(char *));
- pplist = xmalloc(csinfo_size * sizeof(char *));
- fllist = xmalloc(csinfo_size * sizeof(char *));
-
- for (size_t i = 0; i < csinfo_size; i++) {
- dblist[i] = csinfo[i].fname;
- pplist[i] = csinfo[i].ppath;
- fllist[i] = csinfo[i].flags;
- if (csinfo[i].fname != NULL) {
- cs_release_csp(i, false);
- }
- }
-
- // rebuild the cscope connection list
- for (size_t i = 0; i < csinfo_size; i++) {
- if (dblist[i] != NULL) {
- cs_add_common(dblist[i], pplist[i], fllist[i]);
- if (p_csverbose) {
- // don't use smsg_attr() because we want to display the
- // connection number in the same line as
- // "Added cscope database..."
- snprintf(buf, ARRAY_SIZE(buf), " (#%zu)", i);
- msg_puts_attr(buf, HL_ATTR(HLF_R));
- }
- }
- xfree(dblist[i]);
- xfree(pplist[i]);
- xfree(fllist[i]);
- }
- xfree(dblist);
- xfree(pplist);
- xfree(fllist);
-
- if (p_csverbose) {
- msg_attr(_("All cscope databases reset"), HL_ATTR(HLF_R) | MSG_HIST);
- }
- return CSCOPE_SUCCESS;
-}
-
-/// Construct the full pathname to a file found in the cscope database.
-/// (Prepends ppath, if there is one and if it's not already prepended,
-/// otherwise just uses the name found.)
-///
-/// We need to prepend the prefix because on some cscope's (e.g., the one that
-/// ships with Solaris 2.6), the output never has the prefix prepended.
-/// Contrast this with my development system (Digital Unix), which does.
-static char *cs_resolve_file(size_t i, char *name)
-{
- char *fullname;
- char_u *csdir = NULL;
-
- // Ppath is freed when we destroy the cscope connection.
- // Fullname is freed after cs_make_vim_style_matches, after it's been
- // copied into the tag buffer used by Vim.
- size_t len = strlen(name) + 2;
- if (csinfo[i].ppath != NULL) {
- len += strlen(csinfo[i].ppath);
- } else if (p_csre && csinfo[i].fname != NULL) {
- // If 'cscoperelative' is set and ppath is not set, use cscope.out
- // path in path resolution.
- csdir = xmalloc(MAXPATHL);
- STRLCPY(csdir, csinfo[i].fname,
- path_tail(csinfo[i].fname)
- - csinfo[i].fname + 1);
- len += STRLEN(csdir);
- }
-
- // Note/example: this won't work if the cscope output already starts
- // "../.." and the prefix path is also "../..". if something like this
- // happens, you are screwed up and need to fix how you're using cscope.
- if (csinfo[i].ppath != NULL
- && (strncmp(name, csinfo[i].ppath, strlen(csinfo[i].ppath)) != 0)
- && (name[0] != '/')) {
- fullname = xmalloc(len);
- (void)sprintf(fullname, "%s/%s", csinfo[i].ppath, name);
- } else if (csdir != NULL && csinfo[i].fname != NULL && *csdir != NUL) {
- // Check for csdir to be non empty to avoid empty path concatenated to
- // cscope output.
- fullname = concat_fnames((char *)csdir, name, true);
- } else {
- fullname = xstrdup(name);
- }
-
- xfree(csdir);
- return fullname;
-}
-
-/// Show all cscope connections.
-static int cs_show(exarg_T *eap)
-{
- if (cs_cnt_connections() == 0) {
- msg_puts(_("no cscope connections\n"));
- } else {
- msg_puts_attr(_(" # pid database name prepend path\n"),
- HL_ATTR(HLF_T));
- for (size_t i = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname == NULL) {
- continue;
- }
-
- if (csinfo[i].ppath != NULL) {
- (void)smsg("%2zu %-5" PRId64 " %-34s %-32s", i,
- (int64_t)csinfo[i].pid, csinfo[i].fname, csinfo[i].ppath);
- } else {
- (void)smsg("%2zu %-5" PRId64 " %-34s <none>", i,
- (int64_t)csinfo[i].pid, csinfo[i].fname);
- }
- }
- }
-
- wait_return(false);
- return CSCOPE_SUCCESS;
-}
-
-/// Only called when VIM exits to quit any cscope sessions.
-void cs_end(void)
-{
- for (size_t i = 0; i < csinfo_size; i++) {
- cs_release_csp(i, true);
- }
- xfree(csinfo);
- csinfo_size = 0;
-}
-
-// the end
diff --git a/src/nvim/if_cscope.h b/src/nvim/if_cscope.h
deleted file mode 100644
index 8dbc78943f..0000000000
--- a/src/nvim/if_cscope.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef NVIM_IF_CSCOPE_H
-#define NVIM_IF_CSCOPE_H
-
-#include "nvim/ex_cmds_defs.h" // for exarg_T
-#include "nvim/types.h" // for char_u and expand_T
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "if_cscope.h.generated.h"
-#endif
-#endif // NVIM_IF_CSCOPE_H
diff --git a/src/nvim/if_cscope_defs.h b/src/nvim/if_cscope_defs.h
deleted file mode 100644
index 6ded89fa0b..0000000000
--- a/src/nvim/if_cscope_defs.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef NVIM_IF_CSCOPE_DEFS_H
-#define NVIM_IF_CSCOPE_DEFS_H
-
-// CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
-// Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
-//
-// The basic idea/structure of cscope for Vim was borrowed from Nvi.
-// There might be a few lines of code that look similar to what Nvi
-// has. If this is a problem and requires inclusion of the annoying
-// BSD license, then sue me; I'm not worth much anyway.
-
-#if defined(UNIX)
-# include <sys/types.h> // pid_t
-#endif
-
-#include "nvim/ex_cmds_defs.h"
-#include "nvim/os/fs_defs.h"
-#include "nvim/os/os_defs.h"
-
-#define CSCOPE_SUCCESS 0
-#define CSCOPE_FAILURE -1
-
-#define CSCOPE_DBFILE "cscope.out"
-#define CSCOPE_PROMPT ">> "
-
-// See ":help cscope-find" for the possible queries.
-
-typedef struct {
- char *name;
- int (*func)(exarg_T *eap);
- char *help;
- char *usage;
- int cansplit; // if supports splitting window
-} cscmd_T;
-
-typedef struct csi {
- char *fname; // cscope db name
- char *ppath; // path to prepend (the -P option)
- char *flags; // additional cscope flags/options (e.g, -p2)
-#if defined(UNIX)
- pid_t pid; // PID of the connected cscope process
-#else
- DWORD pid; // PID of the connected cscope process
- HANDLE hProc; // cscope process handle
- DWORD nVolume; // Volume serial number, instead of st_dev
- DWORD nIndexHigh; // st_ino has no meaning on Windows
- DWORD nIndexLow;
-#endif
- FileID file_id;
-
- FILE *fr_fp; // from cscope: FILE.
- FILE *to_fp; // to cscope: FILE.
-} csinfo_T;
-
-typedef enum { Add, Find, Help, Kill, Reset, Show, } csid_e;
-
-typedef enum {
- Store,
- Get,
- Free,
- Print,
-} mcmd_e;
-
-#endif // NVIM_IF_CSCOPE_DEFS_H
diff --git a/src/nvim/main.c b/src/nvim/main.c
index f6ec08c8e0..82c32f8e25 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -31,7 +31,6 @@
#include "nvim/highlight.h"
#include "nvim/highlight_group.h"
#include "nvim/iconv.h"
-#include "nvim/if_cscope.h"
#include "nvim/insexpand.h"
#include "nvim/locale.h"
#include "nvim/log.h"
@@ -772,7 +771,6 @@ void getout(int exitval)
ui_call_set_title(cstr_as_string((char *)p_titleold));
}
- cs_end();
if (garbage_collect_at_exit) {
garbage_collect(false);
}
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index e058be9135..01a062d000 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -4310,11 +4310,7 @@ static void nv_ident(cmdarg_T *cap)
case ']':
tag_cmd = true;
- if (p_cst) {
- STRCPY(buf, "cstag ");
- } else {
- STRCPY(buf, "ts ");
- }
+ STRCPY(buf, "ts ");
break;
default:
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 5470b66d6d..e5bd065aef 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -471,15 +471,6 @@ EXTERN long p_ph; // 'pumheight'
EXTERN long p_pw; // 'pumwidth'
EXTERN char *p_com; ///< 'comments'
EXTERN char *p_cpo; // 'cpoptions'
-EXTERN char *p_csprg; // 'cscopeprg'
-EXTERN int p_csre; // 'cscoperelative'
-EXTERN char *p_csqf; // 'cscopequickfix'
-#define CSQF_CMDS "sgdctefia"
-#define CSQF_FLAGS "+-0"
-EXTERN int p_cst; // 'cscopetag'
-EXTERN long p_csto; // 'cscopetagorder'
-EXTERN long p_cspc; // 'cscopepathcomp'
-EXTERN int p_csverbose; // 'cscopeverbose'
EXTERN char *p_debug; // 'debug'
EXTERN char *p_def; // 'define'
EXTERN char *p_inc;
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 149d0bace4..f4d6c808fa 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -496,58 +496,6 @@ return {
defaults={if_true=macros('CPO_VIM')}
},
{
- full_name='cscopepathcomp', abbreviation='cspc',
- short_desc=N_("how many components of the path to show"),
- type='number', scope={'global'},
- varname='p_cspc',
- defaults={if_true=0}
- },
- {
- full_name='cscopeprg', abbreviation='csprg',
- short_desc=N_("command to execute cscope"),
- type='string', scope={'global'},
- secure=true,
- expand=true,
- varname='p_csprg',
- defaults={if_true="cscope"}
- },
- {
- full_name='cscopequickfix', abbreviation='csqf',
- short_desc=N_("use quickfix window for cscope results"),
- type='string', list='onecomma', scope={'global'},
- deny_duplicates=true,
- varname='p_csqf',
- defaults={if_true=""}
- },
- {
- full_name='cscoperelative', abbreviation='csre',
- short_desc=N_("Use cscope.out path basename as prefix"),
- type='bool', scope={'global'},
- varname='p_csre',
- defaults={if_true=0}
- },
- {
- full_name='cscopetag', abbreviation='cst',
- short_desc=N_("use cscope for tag commands"),
- type='bool', scope={'global'},
- varname='p_cst',
- defaults={if_true=0}
- },
- {
- full_name='cscopetagorder', abbreviation='csto',
- short_desc=N_("determines \":cstag\" search order"),
- type='number', scope={'global'},
- varname='p_csto',
- defaults={if_true=0}
- },
- {
- full_name='cscopeverbose', abbreviation='csverb',
- short_desc=N_("give messages when adding a cscope database"),
- type='bool', scope={'global'},
- varname='p_csverbose',
- defaults={if_true=1}
- },
- {
full_name='cursorbind', abbreviation='crb',
short_desc=N_("move cursor in window as it moves in other windows"),
type='bool', scope={'window'},
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 24ee0a1f69..be3e137b69 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -1375,23 +1375,6 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
coladvance(curwin->w_virtcol);
}
}
- } else if (varp == &p_csqf) {
- if (p_csqf != NULL) {
- p = p_csqf;
- while (*p != NUL) {
- if (vim_strchr(CSQF_CMDS, *p) == NULL
- || p[1] == NUL
- || vim_strchr(CSQF_FLAGS, p[1]) == NULL
- || (p[2] != NUL && p[2] != ',')) {
- errmsg = e_invarg;
- break;
- } else if (p[2] == NUL) {
- break;
- } else {
- p += 3;
- }
- }
- }
} else if (gvarp == &p_cino) { // 'cinoptions'
// TODO(vim): recognize errors
parse_cino(curbuf);
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index 4658aed235..19519c5402 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -24,7 +24,6 @@
#include "nvim/fold.h"
#include "nvim/garray.h"
#include "nvim/help.h"
-#include "nvim/if_cscope.h"
#include "nvim/input.h"
#include "nvim/insexpand.h"
#include "nvim/mark.h"
@@ -132,12 +131,9 @@ static int tfu_in_use = false; // disallow recursive call of tagfunc
/// type == DT_LAST: jump to last match of same tag
/// type == DT_SELECT: ":tselect [tag]", select tag from a list of all matches
/// type == DT_JUMP: ":tjump [tag]", jump to tag or select tag from a list
-/// type == DT_CSCOPE: use cscope to find the tag
/// type == DT_LTAG: use location list for displaying tag matches
/// type == DT_FREE: free cached matches
///
-/// for cscope, returns true if we jumped to tag or aborted, false otherwise
-///
/// @param tag tag (pattern) to jump to
/// @param forceit :ta with !
/// @param verbose print "tag not found" message
@@ -181,7 +177,6 @@ bool do_tag(char *tag, int type, int count, int forceit, int verbose)
if (type == DT_FREE) {
// remove the list of matches
FreeWild(num_matches, matches);
- cs_free_tags();
num_matches = 0;
return false;
}
@@ -219,8 +214,7 @@ bool do_tag(char *tag, int type, int count, int forceit, int verbose)
// new pattern, add to the tag stack
if (*tag != NUL
&& (type == DT_TAG || type == DT_SELECT || type == DT_JUMP
- || type == DT_LTAG
- || type == DT_CSCOPE)) {
+ || type == DT_LTAG)) {
if (g_do_tagpreview != 0) {
if (ptag_entry.tagname != NULL
&& strcmp(ptag_entry.tagname, tag) == 0) {
@@ -311,7 +305,6 @@ bool do_tag(char *tag, int type, int count, int forceit, int verbose)
// remove the old list of matches
FreeWild(num_matches, matches);
- cs_free_tags();
num_matches = 0;
tag_freematch();
goto end_do_tag;
@@ -360,7 +353,6 @@ bool do_tag(char *tag, int type, int count, int forceit, int verbose)
cur_match = count - 1; break;
case DT_SELECT:
case DT_JUMP:
- case DT_CSCOPE:
case DT_LAST:
cur_match = MAXCOL - 1; break;
case DT_NEXT:
@@ -454,9 +446,6 @@ bool do_tag(char *tag, int type, int count, int forceit, int verbose)
flags = TAG_NOIC;
}
- if (type == DT_CSCOPE) {
- flags = TAG_CSCOPE;
- }
if (verbose) {
flags |= TAG_VERBOSE;
}
@@ -509,10 +498,7 @@ bool do_tag(char *tag, int type, int count, int forceit, int verbose)
} else {
bool ask_for_selection = false;
- if (type == DT_CSCOPE && num_matches > 1) {
- cs_print_tags();
- ask_for_selection = true;
- } else if (type == DT_TAG && *tag != NUL) {
+ if (type == DT_TAG && *tag != NUL) {
// If a count is supplied to the ":tag <name>" command, then
// jump to count'th matching tag.
cur_match = count > 0 ? count - 1 : 0;
@@ -536,7 +522,6 @@ bool do_tag(char *tag, int type, int count, int forceit, int verbose)
tagstack[tagstackidx].fmark = saved_fmark;
tagstackidx = prevtagstackidx;
}
- cs_free_tags();
jumped_to_tag = true;
break;
}
@@ -586,7 +571,6 @@ bool do_tag(char *tag, int type, int count, int forceit, int verbose)
ic = (matches[cur_match][0] & MT_IC_OFF);
if (type != DT_TAG && type != DT_SELECT && type != DT_JUMP
- && type != DT_CSCOPE
&& (num_matches > 1 || ic)
&& !skip_msg) {
// Give an indication of the number of matching tags
@@ -619,7 +603,7 @@ bool do_tag(char *tag, int type, int count, int forceit, int verbose)
set_vim_var_string(VV_SWAPCOMMAND, (char *)IObuff, -1);
// Jump to the desired match.
- i = jumpto_tag((char_u *)matches[cur_match], forceit, type != DT_CSCOPE);
+ i = jumpto_tag((char_u *)matches[cur_match], forceit, true);
set_vim_var_string(VV_SWAPCOMMAND, NULL, -1);
@@ -1324,7 +1308,6 @@ static int find_tagfunc_tags(char_u *pat, garray_T *ga, int *match_count, int fl
/// TAG_REGEXP use "pat" as a regexp
/// TAG_NOIC don't always ignore case
/// TAG_KEEP_LANG keep language
-/// TAG_CSCOPE use cscope results for tags
/// TAG_NO_TAGFUNC do not call the 'tagfunc' function
///
/// @param pat pattern to search for
@@ -1409,7 +1392,6 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
int name_only = (flags & TAG_NAMES);
int noic = (flags & TAG_NOIC);
int get_it_again = false;
- int use_cscope = (flags & TAG_CSCOPE);
int verbose = (flags & TAG_VERBOSE);
int use_tfu = ((flags & TAG_NO_TAGFUNC) == 0);
int save_p_ic = p_ic;
@@ -1448,15 +1430,9 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
hash_init(&ht_match[mtt]);
}
- STRCPY(tag_fname, "from cscope"); // for error messages
-
// Initialize a few variables
if (help_only) { // want tags from help file
curbuf->b_help = true; // will be restored later
- } else if (use_cscope) {
- // Make sure we don't mix help and cscope, confuses Coverity.
- help_only = false;
- curbuf->b_help = false;
}
orgpat.len = (int)strlen(pat);
@@ -1522,77 +1498,74 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
// Try tag file names from tags option one by one.
for (first_file = true;
- use_cscope || get_tagfname(&tn, first_file, (char *)tag_fname) == OK;
+ get_tagfname(&tn, first_file, (char *)tag_fname) == OK;
first_file = false) {
// A file that doesn't exist is silently ignored. Only when not a
// single file is found, an error message is given (further on).
- if (use_cscope) {
- fp = NULL; // avoid GCC warning
- } else {
- if (curbuf->b_help) {
- // Keep en if the file extension is .txt
- if (is_txt) {
- STRCPY(help_lang, "en");
+ if (curbuf->b_help) {
+ // Keep en if the file extension is .txt
+ if (is_txt) {
+ STRCPY(help_lang, "en");
+ } else {
+ // Prefer help tags according to 'helplang'. Put the
+ // two-letter language name in help_lang[].
+ i = (int)STRLEN(tag_fname);
+ if (i > 3 && tag_fname[i - 3] == '-') {
+ STRCPY(help_lang, tag_fname + i - 2);
} else {
- // Prefer help tags according to 'helplang'. Put the
- // two-letter language name in help_lang[].
- i = (int)STRLEN(tag_fname);
- if (i > 3 && tag_fname[i - 3] == '-') {
- STRCPY(help_lang, tag_fname + i - 2);
- } else {
- STRCPY(help_lang, "en");
- }
+ STRCPY(help_lang, "en");
}
+ }
- // When searching for a specific language skip tags files
- // for other languages.
- if (help_lang_find != NULL
- && STRICMP(help_lang, help_lang_find) != 0) {
- continue;
- }
+ // When searching for a specific language skip tags files
+ // for other languages.
+ if (help_lang_find != NULL
+ && STRICMP(help_lang, help_lang_find) != 0) {
+ continue;
+ }
- // For CTRL-] in a help file prefer a match with the same
- // language.
- if ((flags & TAG_KEEP_LANG)
- && help_lang_find == NULL
- && curbuf->b_fname != NULL
- && (i = (int)strlen(curbuf->b_fname)) > 4
- && curbuf->b_fname[i - 1] == 'x'
- && curbuf->b_fname[i - 4] == '.'
- && STRNICMP(curbuf->b_fname + i - 3, help_lang, 2) == 0) {
- help_pri = 0;
- } else {
- help_pri = 1;
- for (s = p_hlg; *s != NUL; s++) {
- if (STRNICMP(s, help_lang, 2) == 0) {
- break;
- }
- help_pri++;
- if ((s = (char_u *)vim_strchr((char *)s, ',')) == NULL) {
- break;
- }
+ // For CTRL-] in a help file prefer a match with the same
+ // language.
+ if ((flags & TAG_KEEP_LANG)
+ && help_lang_find == NULL
+ && curbuf->b_fname != NULL
+ && (i = (int)strlen(curbuf->b_fname)) > 4
+ && curbuf->b_fname[i - 1] == 'x'
+ && curbuf->b_fname[i - 4] == '.'
+ && STRNICMP(curbuf->b_fname + i - 3, help_lang, 2) == 0) {
+ help_pri = 0;
+ } else {
+ help_pri = 1;
+ for (s = p_hlg; *s != NUL; s++) {
+ if (STRNICMP(s, help_lang, 2) == 0) {
+ break;
+ }
+ help_pri++;
+ if ((s = (char_u *)vim_strchr((char *)s, ',')) == NULL) {
+ break;
}
- if (s == NULL || *s == NUL) {
- // Language not in 'helplang': use last, prefer English,
- // unless found already.
+ }
+ if (s == NULL || *s == NUL) {
+ // Language not in 'helplang': use last, prefer English,
+ // unless found already.
+ help_pri++;
+ if (STRICMP(help_lang, "en") != 0) {
help_pri++;
- if (STRICMP(help_lang, "en") != 0) {
- help_pri++;
- }
}
}
}
+ }
- if ((fp = os_fopen((char *)tag_fname, "r")) == NULL) {
- continue;
- }
+ if ((fp = os_fopen((char *)tag_fname, "r")) == NULL) {
+ continue;
+ }
- if (p_verbose >= 5) {
- verbose_enter();
- smsg(_("Searching tags file %s"), tag_fname);
- verbose_leave();
- }
+ if (p_verbose >= 5) {
+ verbose_enter();
+ smsg(_("Searching tags file %s"), tag_fname);
+ verbose_leave();
}
+
did_open = true; // remember that we found at least one file
state = TS_START; // we're at the start of the file
@@ -1676,9 +1649,7 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
// skip empty and blank lines
do {
- eof = use_cscope
- ? cs_fgets(lbuf, lbuf_size)
- : vim_fgets(lbuf, lbuf_size, fp);
+ eof = vim_fgets(lbuf, lbuf_size, fp);
} while (!eof && vim_isblankline((char *)lbuf));
if (eof) {
@@ -1745,8 +1716,7 @@ line_read_in:
// the tag file isn't sorted, the second loop will find it.
// When "!_TAG_FILE_SORTED" found: start binary search if
// flag set.
- // For cscope, it's always linear.
- if (linear || use_cscope) {
+ if (linear) {
state = TS_LINEAR;
} else if (tag_file_sorted == NUL) {
state = TS_BINARY;
@@ -1797,7 +1767,7 @@ parse_line:
// last-but-one byte (see vim_fgets()).
// Has been reported for Mozilla JS with extremely long names.
// In that case we need to increase lbuf_size.
- if (lbuf[lbuf_size - 2] != NUL && !use_cscope) {
+ if (lbuf[lbuf_size - 2] != NUL) {
lbuf_size *= 2;
xfree(lbuf);
lbuf = xmalloc((size_t)lbuf_size);
@@ -1985,37 +1955,32 @@ parse_line:
if (match) {
size_t len = 0;
- if (use_cscope) {
- // Don't change the ordering, always use the same table.
- mtt = MT_GL_OTH;
- } else {
- // Decide in which array to store this match.
- is_current = test_for_current((char *)tagp.fname, (char *)tagp.fname_end,
- (char *)tag_fname,
- buf_ffname);
- is_static = test_for_static(&tagp);
-
- // Decide in which of the sixteen tables to store this match.
- if (is_static) {
- if (is_current) {
- mtt = MT_ST_CUR;
- } else {
- mtt = MT_ST_OTH;
- }
+ // Decide in which array to store this match.
+ is_current = test_for_current((char *)tagp.fname, (char *)tagp.fname_end,
+ (char *)tag_fname,
+ buf_ffname);
+ is_static = test_for_static(&tagp);
+
+ // Decide in which of the sixteen tables to store this match.
+ if (is_static) {
+ if (is_current) {
+ mtt = MT_ST_CUR;
} else {
- if (is_current) {
- mtt = MT_GL_CUR;
- } else {
- mtt = MT_GL_OTH;
- }
- }
- if (orgpat.regmatch.rm_ic && !match_no_ic) {
- mtt += MT_IC_OFF;
+ mtt = MT_ST_OTH;
}
- if (match_re) {
- mtt += MT_RE_OFF;
+ } else {
+ if (is_current) {
+ mtt = MT_GL_CUR;
+ } else {
+ mtt = MT_GL_OTH;
}
}
+ if (orgpat.regmatch.rm_ic && !match_no_ic) {
+ mtt += MT_IC_OFF;
+ }
+ if (match_re) {
+ mtt += MT_RE_OFF;
+ }
// Add the found match in ht_match[mtt] and ga_match[mtt].
// Store the info we need later, which depends on the kind of
@@ -2098,16 +2063,11 @@ parse_line:
hashitem_T *hi;
// Don't add identical matches.
- // Add all cscope tags, because they are all listed.
// "mfp" is used as a hash key, there is a NUL byte to end
// the part that matters for comparing, more bytes may
// follow after it. E.g. help tags store the priority
// after the NUL.
- if (use_cscope) {
- hash++;
- } else {
- hash = hash_hash((char_u *)mfp);
- }
+ hash = hash_hash((char_u *)mfp);
hi = hash_lookup(&ht_match[mtt], (const char *)mfp,
strlen(mfp), hash);
if (HASHITEM_EMPTY(hi)) {
@@ -2121,23 +2081,16 @@ parse_line:
}
}
}
- if (use_cscope && eof) {
- break;
- }
} // forever
if (line_error) {
semsg(_("E431: Format error in tags file \"%s\""), tag_fname);
- if (!use_cscope) {
- semsg(_("Before byte %" PRId64), (int64_t)vim_ftell(fp));
- }
+ semsg(_("Before byte %" PRId64), (int64_t)vim_ftell(fp));
stop_searching = true;
line_error = false;
}
- if (!use_cscope) {
- fclose(fp);
- }
+ fclose(fp);
if (vimconv.vc_type != CONV_NONE) {
convert_setup(&vimconv, NULL, NULL);
}
@@ -2154,23 +2107,18 @@ parse_line:
stop_searching = true;
}
- if (stop_searching || use_cscope) {
+ if (stop_searching) {
break;
}
} // end of for-each-file loop
- if (!use_cscope) {
- tagname_free(&tn);
- }
+ tagname_free(&tn);
// stop searching when already did a linear search, or when TAG_NOIC
// used, and 'ignorecase' not set or already did case-ignore search
if (stop_searching || linear || (!p_ic && noic) || orgpat.regmatch.rm_ic) {
break;
}
- if (use_cscope) {
- break;
- }
orgpat.regmatch.rm_ic = true; // try another time while ignoring case
}
@@ -2559,7 +2507,7 @@ static char_u *tag_full_fname(tagptrs_T *tagp)
///
/// @param lbuf_arg line from the tags file for this tag
/// @param forceit :ta with !
-/// @param keep_help keep help flag (false for cscope)
+/// @param keep_help keep help flag
///
/// @return OK for success, NOTAGFILE when file not found, FAIL otherwise.
static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help)
diff --git a/src/nvim/tag.h b/src/nvim/tag.h
index 7f2ef8d6d7..e08145f727 100644
--- a/src/nvim/tag.h
+++ b/src/nvim/tag.h
@@ -14,7 +14,6 @@
#define DT_SELECT 7 // jump to selection from list
#define DT_HELP 8 // like DT_TAG, but no wildcards
#define DT_JUMP 9 // jump to new tag or selection from list
-#define DT_CSCOPE 10 // cscope find command (like tjump)
#define DT_LTAG 11 // tag using location list
#define DT_FREE 99 // free cached matches
@@ -23,7 +22,6 @@
#define TAG_NAMES 2 // only return name of tag
#define TAG_REGEXP 4 // use tag pattern as regexp
#define TAG_NOIC 8 // don't always ignore case
-#define TAG_CSCOPE 16 // cscope tag
#define TAG_VERBOSE 32 // message verbosity
#define TAG_INS_COMP 64 // Currently doing insert completion
#define TAG_KEEP_LANG 128 // keep current language
diff --git a/src/nvim/testdir/test_cscope.vim b/src/nvim/testdir/test_cscope.vim
deleted file mode 100644
index 76ea35fa10..0000000000
--- a/src/nvim/testdir/test_cscope.vim
+++ /dev/null
@@ -1,344 +0,0 @@
-" Test for cscope commands.
-
-source check.vim
-CheckFeature cscope
-CheckFeature quickfix
-
-if !executable('cscope')
- throw 'Skipped: cscope program missing'
-endif
-
-func CscopeSetupOrClean(setup)
- if a:setup
- noa sp samples/memfile_test.c
- saveas! Xmemfile_test.c
- call system('cscope -bk -fXcscope.out Xmemfile_test.c')
- call system('cscope -bk -fXcscope2.out Xmemfile_test.c')
- cscope add Xcscope.out
- set cscopequickfix=s-,g-,d-,c-,t-,e-,f-,i-,a-
- else
- cscope kill -1
- for file in ['Xcscope.out', 'Xcscope2.out', 'Xmemfile_test.c']
- call delete(file)
- endfo
- endif
-endfunc
-
-func Test_cscopeWithCscopeConnections()
- call CscopeSetupOrClean(1)
- " Test: E568: duplicate cscope database not added
- try
- set nocscopeverbose
- cscope add Xcscope.out
- set cscopeverbose
- catch
- call assert_report('exception thrown')
- endtry
- call assert_fails('cscope add', 'E560')
- call assert_fails('cscope add Xcscope.out', 'E568')
- call assert_fails('cscope add doesnotexist.out', 'E563')
- if has('unix')
- call assert_fails('cscope add /dev/null', 'E564:')
- endif
-
- " Test: Find this C-Symbol
- for cmd in ['cs find s main', 'cs find 0 main']
- let a = execute(cmd)
- " Test where it moves the cursor
- call assert_equal('main(void)', getline('.'))
- " Test the output of the :cs command
- call assert_match('\n(1 of 1): <<main>> main(void )', a)
- endfor
-
- " Test: Find this definition
- for cmd in ['cs find g test_mf_hash',
- \ 'cs find 1 test_mf_hash',
- \ 'cs find 1 test_mf_hash'] " leading space ignored.
- exe cmd
- call assert_equal(['', '/*', ' * Test mf_hash_*() functions.', ' */', ' static void', 'test_mf_hash(void)', '{'], getline(line('.')-5, line('.')+1))
- endfor
-
- " Test: Find functions called by this function
- for cmd in ['cs find d test_mf_hash', 'cs find 2 test_mf_hash']
- let a = execute(cmd)
- call assert_match('\n(1 of 42): <<mf_hash_init>> mf_hash_init(&ht);', a)
- call assert_equal(' mf_hash_init(&ht);', getline('.'))
- endfor
-
- " Test: Find functions calling this function
- for cmd in ['cs find c test_mf_hash', 'cs find 3 test_mf_hash']
- let a = execute(cmd)
- call assert_match('\n(1 of 1): <<main>> test_mf_hash();', a)
- call assert_equal(' test_mf_hash();', getline('.'))
- endfor
-
- " Test: Find this text string
- for cmd in ['cs find t Bram', 'cs find 4 Bram']
- let a = execute(cmd)
- call assert_match('(1 of 1): <<<unknown>>> \* VIM - Vi IMproved^Iby Bram Moolenaar', a)
- call assert_equal(' * VIM - Vi IMproved by Bram Moolenaar', getline('.'))
- endfor
-
- " Test: Find this egrep pattern
- " test all matches returned by cscope
- for cmd in ['cs find e ^\#includ.', 'cs find 6 ^\#includ.']
- let a = execute(cmd)
- call assert_match('\n(1 of 3): <<<unknown>>> #include <assert.h>', a)
- call assert_equal('#include <assert.h>', getline('.'))
- cnext
- call assert_equal('#include "main.c"', getline('.'))
- cnext
- call assert_equal('#include "memfile.c"', getline('.'))
- call assert_fails('cnext', 'E553:')
- endfor
-
- " Test: Find the same egrep pattern using lcscope this time.
- let a = execute('lcs find e ^\#includ.')
- call assert_match('\n(1 of 3): <<<unknown>>> #include <assert.h>', a)
- call assert_equal('#include <assert.h>', getline('.'))
- lnext
- call assert_equal('#include "main.c"', getline('.'))
- lnext
- call assert_equal('#include "memfile.c"', getline('.'))
- call assert_fails('lnext', 'E553:')
-
- " Test: Find this file
- for cmd in ['cs find f Xmemfile_test.c', 'cs find 7 Xmemfile_test.c']
- enew
- let a = execute(cmd)
- call assert_true(a =~ '"Xmemfile_test.c" \d\+L, \d\+B')
- call assert_equal('Xmemfile_test.c', @%)
- endfor
-
- " Test: Find files #including this file
- for cmd in ['cs find i assert.h', 'cs find 8 assert.h']
- enew
- let a = execute(cmd)
- let alines = split(a, '\n', 1)
- call assert_equal('', alines[0])
- call assert_true(alines[1] =~ '"Xmemfile_test.c" \d\+L, \d\+B')
- call assert_equal('(1 of 1): <<global>> #include <assert.h>', alines[2])
- call assert_equal('#include <assert.h>', getline('.'))
- endfor
-
- " Test: Invalid find command
- call assert_fails('cs find', 'E560:')
- call assert_fails('cs find x', 'E560:')
-
- if has('float')
- " Test: Find places where this symbol is assigned a value
- " this needs a cscope >= 15.8
- " unfortunately, Travis has cscope version 15.7
- let cscope_version = systemlist('cscope --version')[0]
- let cs_version = str2float(matchstr(cscope_version, '\d\+\(\.\d\+\)\?'))
- if cs_version >= 15.8
- for cmd in ['cs find a item', 'cs find 9 item']
- let a = execute(cmd)
- call assert_equal(['', '(1 of 4): <<test_mf_hash>> item = (mf_hashitem_T *)lalloc_clear(sizeof(*item), FALSE);'], split(a, '\n', 1))
- call assert_equal(' item = (mf_hashitem_T *)lalloc_clear(sizeof(*item), FALSE);', getline('.'))
- cnext
- call assert_equal(' item = mf_hash_find(&ht, key);', getline('.'))
- cnext
- call assert_equal(' item = mf_hash_find(&ht, key);', getline('.'))
- cnext
- call assert_equal(' item = mf_hash_find(&ht, key);', getline('.'))
- endfor
- endif
- endif
-
- " Test: leading whitespace is not removed for cscope find text
- let a = execute('cscope find t test_mf_hash')
- call assert_equal(['', '(1 of 1): <<<unknown>>> test_mf_hash();'], split(a, '\n', 1))
- call assert_equal(' test_mf_hash();', getline('.'))
-
- " Test: test with scscope
- let a = execute('scs find t Bram')
- call assert_match('(1 of 1): <<<unknown>>> \* VIM - Vi IMproved^Iby Bram Moolenaar', a)
- call assert_equal(' * VIM - Vi IMproved by Bram Moolenaar', getline('.'))
-
- " Test: cscope help
- for cmd in ['cs', 'cs help', 'cs xxx']
- let a = execute(cmd)
- call assert_match('^cscope commands:\n', a)
- call assert_match('\nadd :', a)
- call assert_match('\nfind :', a)
- call assert_match('\nhelp : Show this message', a)
- call assert_match('\nkill : Kill a connection', a)
- call assert_match('\nreset: Reinit all connections', a)
- call assert_match('\nshow : Show connections', a)
- endfor
- let a = execute('scscope help')
- call assert_match('This cscope command does not support splitting the window\.', a)
-
- " Test: reset connections
- let a = execute('cscope reset')
- call assert_match('\nAdded cscope database.*Xcscope.out (#0)', a)
- call assert_match('\nAll cscope databases reset', a)
-
- " Test: cscope show
- let a = execute('cscope show')
- call assert_match('\n 0 \d\+.*Xcscope.out\s*<none>', a)
-
- " Test: cstag and 'csto' option
- set csto=0
- let a = execute('cstag TEST_COUNT')
- call assert_match('(1 of 1): <<TEST_COUNT>> #define TEST_COUNT 50000', a)
- call assert_equal('#define TEST_COUNT 50000', getline('.'))
- call assert_fails('cstag DOES_NOT_EXIST', 'E257:')
- set csto=1
- let a = execute('cstag index_to_key')
- call assert_match('(1 of 1): <<index_to_key>> #define index_to_key(i) ((i) ^ 15167)', a)
- call assert_equal('#define index_to_key(i) ((i) ^ 15167)', getline('.'))
- call assert_fails('cstag DOES_NOT_EXIST', 'E257:')
- call assert_fails('cstag', 'E562:')
- let save_tags = &tags
- set tags=
- call assert_fails('cstag DOES_NOT_EXIST', 'E257:')
- let a = execute('cstag index_to_key')
- call assert_match('(1 of 1): <<index_to_key>> #define index_to_key(i) ((i) ^ 15167)', a)
- let &tags = save_tags
-
- " Test: 'cst' option
- set nocst
- call assert_fails('tag TEST_COUNT', 'E426:')
- set cst
- let a = execute('tag TEST_COUNT')
- call assert_match('(1 of 1): <<TEST_COUNT>> #define TEST_COUNT 50000', a)
- call assert_equal('#define TEST_COUNT 50000', getline('.'))
- let a = execute('tags')
- call assert_match('1 1 TEST_COUNT\s\+\d\+\s\+#define index_to_key', a)
-
- " Test: 'cscoperelative'
- call mkdir('Xcscoperelative')
- cd Xcscoperelative
- let a = execute('cs find g test_mf_hash')
- call assert_notequal('test_mf_hash(void)', getline('.'))
- set cscoperelative
- let a = execute('cs find g test_mf_hash')
- call assert_equal('test_mf_hash(void)', getline('.'))
- set nocscoperelative
- cd ..
- call delete('Xcscoperelative', 'd')
-
- " Test: E259: no match found
- call assert_fails('cscope find g DOES_NOT_EXIST', 'E259:')
-
- " Test: this should trigger call to cs_print_tags()
- " Unclear how to check result though, we just exercise the code.
- set cst cscopequickfix=s0
- call feedkeys(":cs find s main\<CR>", 't')
-
- " Test: cscope kill
- call assert_fails('cscope kill', 'E560:')
- call assert_fails('cscope kill 2', 'E261:')
- call assert_fails('cscope kill xxx', 'E261:')
-
- let a = execute('cscope kill 0')
- call assert_match('cscope connection 0 closed', a)
-
- cscope add Xcscope.out
- let a = execute('cscope kill Xcscope.out')
- call assert_match('cscope connection Xcscope.out closed', a)
-
- cscope add Xcscope.out .
- let a = execute('cscope kill -1')
- call assert_match('cscope connection .*Xcscope.out closed', a)
- let a = execute('cscope kill -1')
- call assert_equal('', a)
-
- " Test: 'csprg' option
- call assert_equal('cscope', &csprg)
- set csprg=doesnotexist
- call assert_fails('cscope add Xcscope2.out', 'E609:')
- set csprg=cscope
-
- " Test: multiple cscope connections
- cscope add Xcscope.out
- cscope add Xcscope2.out . -C
- let a = execute('cscope show')
- call assert_match('\n 0 \d\+.*Xcscope.out\s*<none>', a)
- call assert_match('\n 1 \d\+.*Xcscope2.out\s*\.', a)
-
- " Test: test Ex command line completion
- call feedkeys(":cs \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_equal('"cs add find help kill reset show', @:)
-
- call feedkeys(":scs \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_equal('"scs find', @:)
-
- call feedkeys(":cs find \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_equal('"cs find a c d e f g i s t', @:)
-
- call feedkeys(":cs kill \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_equal('"cs kill -1 0 1', @:)
-
- call feedkeys(":cs add Xcscope\<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_equal('"cs add Xcscope.out Xcscope2.out', @:)
-
- " Test: cscope_connection()
- call assert_equal(cscope_connection(), 1)
- call assert_equal(cscope_connection(0, 'out'), 1)
- call assert_equal(cscope_connection(0, 'xxx'), 1)
-
- call assert_equal(cscope_connection(1, 'out'), 1)
- call assert_equal(cscope_connection(1, 'xxx'), 0)
-
- call assert_equal(cscope_connection(2, 'out'), 0)
- call assert_equal(cscope_connection(2, getcwd() .. '/Xcscope.out', 1), 1)
-
- call assert_equal(cscope_connection(3, 'xxx', '..'), 0)
- call assert_equal(cscope_connection(3, 'out', 'xxx'), 0)
- call assert_equal(cscope_connection(3, 'out', '.'), 1)
-
- call assert_equal(cscope_connection(4, 'out', '.'), 0)
-
- call assert_equal(cscope_connection(5, 'out'), 0)
- call assert_equal(cscope_connection(-1, 'out'), 0)
-
- call CscopeSetupOrClean(0)
-endfunc
-
-" Test ":cs add {dir}" (add the {dir}/cscope.out database)
-func Test_cscope_add_dir()
- call mkdir('Xcscopedir', 'p')
-
- " Cscope doesn't handle symlinks, so this needs to be resolved in case a
- " shadow directory is being used.
- let memfile = resolve('./samples/memfile_test.c')
- call system('cscope -bk -fXcscopedir/cscope.out ' . memfile)
-
- cs add Xcscopedir
- let a = execute('cscope show')
- let lines = split(a, "\n", 1)
- call assert_equal(3, len(lines))
- call assert_equal(' # pid database name prepend path', lines[0])
- call assert_equal('', lines[1])
- call assert_match('^ 0 \d\+.*Xcscopedir/cscope.out\s\+<none>$', lines[2])
-
- cs kill -1
- call delete('Xcscopedir/cscope.out')
- call assert_fails('cs add Xcscopedir', 'E563:')
-
- call delete('Xcscopedir', 'd')
-endfunc
-
-func Test_cscopequickfix()
- set cscopequickfix=s-,g-,d+,c-,t+,e-,f0,i-,a-
- call assert_equal('s-,g-,d+,c-,t+,e-,f0,i-,a-', &cscopequickfix)
-
- call assert_fails('set cscopequickfix=x-', 'E474:')
- call assert_fails('set cscopequickfix=s', 'E474:')
- call assert_fails('set cscopequickfix=s7', 'E474:')
- call assert_fails('set cscopequickfix=s-a', 'E474:')
-endfunc
-
-func Test_withoutCscopeConnection()
- call assert_equal(cscope_connection(), 0)
-
- call assert_fails('cscope find s main', 'E567:')
- let a = execute('cscope show')
- call assert_match('no cscope connections', a)
-endfunc
-
-
-" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c
index c3cf0b6df8..0e045c773f 100644
--- a/src/nvim/usercmd.c
+++ b/src/nvim/usercmd.c
@@ -46,7 +46,6 @@ static const char *command_complete[] =
[EXPAND_COLORS] = "color",
[EXPAND_COMMANDS] = "command",
[EXPAND_COMPILER] = "compiler",
- [EXPAND_CSCOPE] = "cscope",
[EXPAND_USER_DEFINED] = "custom",
[EXPAND_USER_LIST] = "customlist",
[EXPAND_USER_LUA] = "<Lua function>",
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index 5b7ff7ba52..4bcda9fc4f 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -138,7 +138,6 @@ enum {
EXPAND_USER_LIST,
EXPAND_USER_LUA,
EXPAND_SHELLCMD,
- EXPAND_CSCOPE,
EXPAND_SIGN,
EXPAND_PROFILE,
EXPAND_BEHAVE,