📄 vim.c
字号:
/** $Id: vim.c 485 2006-10-24 12:06:19Z dfishburn $** Copyright (c) 2000-2003, Darren Hiebert** This source code is released for free distribution under the terms of the* GNU General Public License.** Thanks are due to Jay Glanville for significant improvements.** This module contains functions for generating tags for user-defined* functions for the Vim editor.*//** INCLUDE FILES*/#include "general.h" /* must always come first */#include <string.h>#include <setjmp.h>#ifdef DEBUG#include <stdio.h>#endif#include "parse.h"#include "read.h"#include "vstring.h"#if 0typedef struct sLineInfo { tokenType type; keywordId keyword; vString * string; vString * scope; unsigned long lineNumber; fpos_t filePosition;} lineInfo;#endif/** DATA DEFINITIONS*/typedef enum { K_AUGROUP, K_COMMAND, K_FUNCTION, K_MAP, K_VARIABLE} vimKind;static kindOption VimKinds [] = { { TRUE, 'a', "augroup", "autocommand groups" }, { TRUE, 'c', "command", "user-defined commands" }, { TRUE, 'f', "function", "function definitions" }, { TRUE, 'm', "map", "maps" }, { TRUE, 'v', "variable", "variable definitions" },};/* * DATA DECLARATIONS */#if 0typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;#endif/* * DATA DEFINITIONS */#if 0static jmp_buf Exception;#endif/* * FUNCTION DEFINITIONS *//* This function takes a char pointer, tries to find a scope separator in the * string, and if it does, returns a pointer to the character after the colon, * and the character defining the scope. * If a colon is not found, it returns the original pointer. */static const unsigned char* skipPrefix (const unsigned char* name, int *scope){ const unsigned char* result = name; int counter; size_t length; length = strlen((const char*)name); if (scope != NULL) *scope = '\0'; if (length > 3 && name[1] == ':') { if (scope != NULL) *scope = *name; result = name + 2; } else if (length > 5 && strncasecmp ((const char*) name, "<SID>", (size_t) 5) == 0) { if (scope != NULL) *scope = *name; result = name + 5; } else { /* * Vim7 check for dictionaries or autoload function names */ counter = 0; do { switch ( name[counter] ) { case '.': /* Set the scope to d - Dictionary */ *scope = 'd'; break; case '#': /* Set the scope to a - autoload */ *scope = 'a'; break; } ++counter; } while (isalnum ((int) name[counter]) || name[counter] == '_' || name[counter] == '.' || name[counter] == '#' ); } return result;}static boolean isMap (const unsigned char* line){ /* * There are many different short cuts for specifying a map. * This routine should capture all the permutations. */ if ( strncmp ((const char*) line, "map", (size_t) 3) == 0 || strncmp ((const char*) line, "nm", (size_t) 2) == 0 || strncmp ((const char*) line, "nma", (size_t) 3) == 0 || strncmp ((const char*) line, "nmap", (size_t) 4) == 0 || strncmp ((const char*) line, "vm", (size_t) 2) == 0 || strncmp ((const char*) line, "vma", (size_t) 3) == 0 || strncmp ((const char*) line, "vmap", (size_t) 4) == 0 || strncmp ((const char*) line, "om", (size_t) 2) == 0 || strncmp ((const char*) line, "oma", (size_t) 3) == 0 || strncmp ((const char*) line, "omap", (size_t) 4) == 0 || strncmp ((const char*) line, "im", (size_t) 2) == 0 || strncmp ((const char*) line, "ima", (size_t) 3) == 0 || strncmp ((const char*) line, "imap", (size_t) 4) == 0 || strncmp ((const char*) line, "lm", (size_t) 2) == 0 || strncmp ((const char*) line, "lma", (size_t) 3) == 0 || strncmp ((const char*) line, "lmap", (size_t) 4) == 0 || strncmp ((const char*) line, "cm", (size_t) 2) == 0 || strncmp ((const char*) line, "cma", (size_t) 3) == 0 || strncmp ((const char*) line, "cmap", (size_t) 4) == 0 || strncmp ((const char*) line, "no", (size_t) 2) == 0 || strncmp ((const char*) line, "nor", (size_t) 3) == 0 || strncmp ((const char*) line, "nore", (size_t) 4) == 0 || strncmp ((const char*) line, "norem", (size_t) 5) == 0 || strncmp ((const char*) line, "norema", (size_t) 6) == 0 || strncmp ((const char*) line, "noremap", (size_t) 7) == 0 || strncmp ((const char*) line, "nno", (size_t) 3) == 0 || strncmp ((const char*) line, "nnor", (size_t) 4) == 0 || strncmp ((const char*) line, "nnore", (size_t) 5) == 0 || strncmp ((const char*) line, "nnorem", (size_t) 6) == 0 || strncmp ((const char*) line, "nnorema", (size_t) 7) == 0 || strncmp ((const char*) line, "nnoremap", (size_t) 8) == 0 || strncmp ((const char*) line, "vno", (size_t) 3) == 0 || strncmp ((const char*) line, "vnor", (size_t) 4) == 0 || strncmp ((const char*) line, "vnore", (size_t) 5) == 0 || strncmp ((const char*) line, "vnorem", (size_t) 6) == 0 || strncmp ((const char*) line, "vnorema", (size_t) 7) == 0 || strncmp ((const char*) line, "vnoremap", (size_t) 8) == 0 || strncmp ((const char*) line, "ono", (size_t) 3) == 0 || strncmp ((const char*) line, "onor", (size_t) 4) == 0 || strncmp ((const char*) line, "onore", (size_t) 5) == 0 || strncmp ((const char*) line, "onorem", (size_t) 6) == 0 || strncmp ((const char*) line, "onorema", (size_t) 7) == 0 || strncmp ((const char*) line, "onoremap", (size_t) 8) == 0 || strncmp ((const char*) line, "ino", (size_t) 3) == 0 || strncmp ((const char*) line, "inor", (size_t) 4) == 0 || strncmp ((const char*) line, "inore", (size_t) 5) == 0 || strncmp ((const char*) line, "inorem", (size_t) 6) == 0 || strncmp ((const char*) line, "inorema", (size_t) 7) == 0 || strncmp ((const char*) line, "inoremap", (size_t) 8) == 0 || strncmp ((const char*) line, "lno", (size_t) 3) == 0 || strncmp ((const char*) line, "lnor", (size_t) 4) == 0 || strncmp ((const char*) line, "lnore", (size_t) 5) == 0 || strncmp ((const char*) line, "lnorem", (size_t) 6) == 0 || strncmp ((const char*) line, "lnorema", (size_t) 7) == 0 || strncmp ((const char*) line, "lnoremap", (size_t) 8) == 0 || strncmp ((const char*) line, "cno", (size_t) 3) == 0 || strncmp ((const char*) line, "cnor", (size_t) 4) == 0 || strncmp ((const char*) line, "cnore", (size_t) 5) == 0 || strncmp ((const char*) line, "cnorem", (size_t) 6) == 0 || strncmp ((const char*) line, "cnorema", (size_t) 7) == 0 || strncmp ((const char*) line, "cnoremap", (size_t) 8) == 0 ) return TRUE; return FALSE;}static const unsigned char * readVimLine (void){ const unsigned char *line; while ((line = fileReadLine ()) != NULL) { while (isspace ((int) *line)) ++line; if ((int) *line == '"') continue; /* skip comment */ break; } return line;}static void parseFunction (const unsigned char *line){ vString *name = vStringNew (); /* boolean inFunction = FALSE; */ int scope; const unsigned char *cp = line + 1; if ((int) *++cp == 'n' && (int) *++cp == 'c' && (int) *++cp == 't' && (int) *++cp == 'i' && (int) *++cp == 'o' && (int) *++cp == 'n') ++cp; if ((int) *cp == '!') ++cp; if (isspace ((int) *cp)) { while (*cp && isspace ((int) *cp)) ++cp; if (*cp) { cp = skipPrefix (cp, &scope); if (isupper ((int) *cp) || scope == 's' || /* script scope */ scope == '<' || /* script scope */ scope == 'd' || /* dictionary */ scope == 'a') /* autoload */ { do { vStringPut (name, (int) *cp); ++cp; } while (isalnum ((int) *cp) || *cp == '_' || *cp == '.' || *cp == '#'); vStringTerminate (name); makeSimpleTag (name, VimKinds, K_FUNCTION); vStringClear (name); } } } /* TODO - update struct to indicate inside function */ while ((line = readVimLine ()) != NULL) { /* * Vim7 added the for/endfo[r] construct, so we must first * check for an "endfo", before a "endf" */ if ( (!strncmp ((const char*) line, "endfo", (size_t) 5) == 0) && (strncmp ((const char*) line, "endf", (size_t) 4) == 0) ) break; /* TODO - call parseVimLine */ } vStringDelete (name);}static void parseAutogroup (const unsigned char *line){ vString *name = vStringNew (); /* Found Autocommand Group (augroup) */ const unsigned char *cp = line + 2; if ((int) *++cp == 'r' && (int) *++cp == 'o' && (int) *++cp == 'u' && (int) *++cp == 'p') ++cp; if (isspace ((int) *cp)) { while (*cp && isspace ((int) *cp)) ++cp; if (*cp) { if (strncasecmp ((const char*) cp, "end", (size_t) 3) != 0) { do { vStringPut (name, (int) *cp); ++cp; } while (isalnum ((int) *cp) || *cp == '_'); vStringTerminate (name); makeSimpleTag (name, VimKinds, K_AUGROUP); vStringClear (name); } } } vStringDelete (name);}static boolean parseCommand (const unsigned char *line){ vString *name = vStringNew (); boolean cmdProcessed = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -